/* $Id$ */ /* * 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/module.c * PURPOSE: Enumerate process modules * PROGRAMMER: KJK::Hyperion * UPDATE HISTORY: * 10/06/2002: Created * 29/08/2002: Generalized the interface to improve reusability, * more efficient use of memory operations * 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree, * for better reusability * 02/04/2003: System modules enumeration moved into its own file * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and * isolated in its own library to clear the confusion * and improve reusability */ #define NTOS_MODE_USER #include #define NDEBUG #include #include NTSTATUS NTAPI PsaEnumerateProcessModules ( IN HANDLE ProcessHandle, IN PPROCMOD_ENUM_ROUTINE Callback, IN OUT PVOID CallbackContext ) { register NTSTATUS nErrCode; /* current process - use direct memory copy */ if(ProcessHandle == NtCurrentProcess()) { register PLIST_ENTRY pleListHead; register PLIST_ENTRY pleCurEntry; #if 0 /* FIXME: activate this when GCC supports SEH */ __try { #endif pleListHead = &(NtCurrentPeb()->Ldr->InLoadOrderModuleList); pleCurEntry = pleListHead->Flink; while(pleCurEntry != pleListHead) { register PLDR_MODULE plmModule = CONTAINING_RECORD ( pleCurEntry, LDR_MODULE, InLoadOrderModuleList ); /* return the current module to the callback */ nErrCode = Callback(ProcessHandle, plmModule, CallbackContext); if(!NT_SUCCESS(nErrCode)) /* failure */ goto epm_Failure; pleCurEntry = plmModule->InLoadOrderModuleList.Flink; } #if 0 /* FIXME: activate this when GCC supports SEH */ } __except(EXCEPTION_EXECUTE_HANDLER) { return GetExceptionCode(); } #endif } /* another process */ else { PROCESS_BASIC_INFORMATION pbiInfo; PPEB_LDR_DATA ppldLdrData; LDR_MODULE lmModule; PLIST_ENTRY pleListHead; PLIST_ENTRY pleCurEntry; /* query the process basic information (includes the PEB address) */ nErrCode = NtQueryInformationProcess ( ProcessHandle, ProcessBasicInformation, &pbiInfo, sizeof(pbiInfo), NULL ); if(!NT_SUCCESS(nErrCode)) { /* failure */ DPRINT(FAILED_WITH_STATUS, "NtQueryInformationProcess", nErrCode); goto epm_Failure; } /* get the address of the PE Loader data */ nErrCode = NtReadVirtualMemory ( ProcessHandle, &(pbiInfo.PebBaseAddress->Ldr), &ppldLdrData, sizeof(ppldLdrData), NULL ); if(!NT_SUCCESS(nErrCode)) { /* failure */ DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode); goto epm_Failure; } /* head of the module list: the last element in the list will point to this */ pleListHead = &ppldLdrData->InLoadOrderModuleList; /* get the address of the first element in the list */ nErrCode = NtReadVirtualMemory ( ProcessHandle, &(ppldLdrData->InLoadOrderModuleList.Flink), &pleCurEntry, sizeof(pleCurEntry), NULL ); while(pleCurEntry != pleListHead) { /* read the current module */ nErrCode = NtReadVirtualMemory ( ProcessHandle, CONTAINING_RECORD(pleCurEntry, LDR_MODULE, InLoadOrderModuleList), &lmModule, sizeof(lmModule), NULL ); if(!NT_SUCCESS(nErrCode)) { /* failure */ DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode); goto epm_Failure; } /* return the current module to the callback */ nErrCode = Callback(ProcessHandle, &lmModule, CallbackContext); if(!NT_SUCCESS(nErrCode)) /* failure */ goto epm_Failure; /* address of the next module in the list */ pleCurEntry = lmModule.InLoadOrderModuleList.Flink; } } /* success */ return (STATUS_SUCCESS); epm_Failure: /* failure */ return (nErrCode); } /* EOF */