Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191/* * COPYRIGHT: See COPYING in the top level directory * LICENSE: See LGPL.txt in the top level directory * PROJECT: ReactOS system libraries * FILE: reactos/lib/epsapi/enum/drivers.c * PURPOSE: Enumerate system modules * PROGRAMMER: KJK::Hyperion <noog@libero.it> * UPDATE HISTORY: * 02/04/2003: Created * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and * isolated in its own library to clear the confusion * and improve reusability */
#include "precomp.h"
#define NDEBUG#include <debug.h>
NTSTATUS NTAPIPsaEnumerateSystemModules(IN PSYSMOD_ENUM_ROUTINE Callback, IN OUT PVOID CallbackContext){ PRTL_PROCESS_MODULES psmModules; NTSTATUS Status = STATUS_SUCCESS;
#if 0 __try {#else do {#endif /* capture the system modules */ Status = PsaCaptureSystemModules(&psmModules);
if(!NT_SUCCESS(Status)) { break; }
/* walk the system modules */ Status = PsaWalkSystemModules(psmModules, Callback, CallbackContext);#if 0 } __finally {#else } while(0);#endif /* free the capture */ PsaFreeCapture(psmModules);#if 0 }#endif
return Status;}
NTSTATUS NTAPIPsaCaptureSystemModules(OUT PRTL_PROCESS_MODULES *SystemModules){ SIZE_T nSize = 0; PRTL_PROCESS_MODULES psmModules = NULL; NTSTATUS Status;
#if 0 __try {#else do {#endif /* initial probe. We just get the count of system modules */ Status = NtQuerySystemInformation(SystemModuleInformation, &nSize, sizeof(nSize), NULL);
if(!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH)) { DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", Status); break; }
/* RATIONALE: the loading of a system module is a rare occurrence. To minimize memory operations that could be expensive, or fragment the pool/heap, we try to determine the buffer size in advance, knowing that the number of elements is unlikely to change */ nSize = sizeof(RTL_PROCESS_MODULES) + (nSize * sizeof(RTL_PROCESS_MODULES));
psmModules = NULL;
do { PVOID pTmp;
/* free the buffer, and reallocate it to the new size. RATIONALE: since we ignore the buffer's content at this point, there's no point in a realloc, that could end up copying a large chunk of data we'd discard anyway */ PsaiFree(psmModules); psmModules = NULL; pTmp = PsaiMalloc(nSize);
if(pTmp == NULL) { Status = STATUS_NO_MEMORY; DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", Status); break; }
psmModules = pTmp;
/* query the information */ Status = NtQuerySystemInformation(SystemModuleInformation, psmModules, nSize, NULL);
/* double the buffer for the next loop */ nSize *= 2; } while(Status == STATUS_INFO_LENGTH_MISMATCH);
if(!NT_SUCCESS(Status)) { DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", Status); break; }
*SystemModules = psmModules;
Status = STATUS_SUCCESS;#if 0 } __finally {#else } while(0);#endif /* in case of failure, free the buffer */ if(!NT_SUCCESS(Status) && psmModules != NULL) { PsaiFree(psmModules); }#if 0 }#endif
return Status;}
NTSTATUS NTAPIPsaWalkSystemModules(IN PRTL_PROCESS_MODULES SystemModules, IN PSYSMOD_ENUM_ROUTINE Callback, IN OUT PVOID CallbackContext){ ULONG i; NTSTATUS Status;
/* repeat until all modules have been returned */ for(i = 0; i < SystemModules->NumberOfModules; i++) { /* return current module to the callback */ Status = Callback(&(SystemModules->Modules[i]), CallbackContext);
if(!NT_SUCCESS(Status)) { return Status; } }
return STATUS_SUCCESS;}
PRTL_PROCESS_MODULE_INFORMATION FASTCALLPsaWalkFirstSystemModule(IN PRTL_PROCESS_MODULES SystemModules){ return &(SystemModules->Modules[0]);}
PRTL_PROCESS_MODULE_INFORMATION FASTCALLPsaWalkNextSystemModule(IN PRTL_PROCESS_MODULES CurrentSystemModule){ return (PRTL_PROCESS_MODULE_INFORMATION)((ULONG_PTR)CurrentSystemModule + (FIELD_OFFSET(RTL_PROCESS_MODULES, Modules[1]) - FIELD_OFFSET(RTL_PROCESS_MODULES, Modules[0])));}
/* EOF */