4 * COPYRIGHT: See COPYING in the top level directory
5 * LICENSE: See LGPL.txt in the top level directory
6 * PROJECT: ReactOS system libraries
7 * FILE: reactos/lib/epsapi/enum/module.c
8 * PURPOSE: Enumerate process modules
9 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
12 * 29/08/2002: Generalized the interface to improve reusability,
13 * more efficient use of memory operations
14 * 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
15 * for better reusability
16 * 02/04/2003: System modules enumeration moved into its own file
17 * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
18 * isolated in its own library to clear the confusion
19 * and improve reusability
28 PsaEnumerateProcessModules(IN HANDLE ProcessHandle
,
29 IN PPROCMOD_ENUM_ROUTINE Callback
,
30 IN OUT PVOID CallbackContext
)
34 /* current process - use direct memory copy */
35 /* FIXME - compare process id instead of a handle */
36 if(ProcessHandle
== NtCurrentProcess())
38 PLIST_ENTRY ListHead
, Current
;
44 ListHead
= &(NtCurrentPeb()->Ldr
->InLoadOrderModuleList
);
45 Current
= ListHead
->Flink
;
47 while(Current
!= ListHead
)
49 PLDR_DATA_TABLE_ENTRY LoaderModule
= CONTAINING_RECORD(Current
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
51 /* return the current module to the callback */
52 Status
= Callback(ProcessHandle
, LoaderModule
, CallbackContext
);
54 if(!NT_SUCCESS(Status
))
59 Current
= LoaderModule
->InLoadOrderLinks
.Flink
;
63 __except(EXCEPTION_EXECUTE_HANDLER
)
65 return GetExceptionCode();
71 PROCESS_BASIC_INFORMATION BasicInformation
;
72 PPEB_LDR_DATA LoaderData
;
73 LDR_DATA_TABLE_ENTRY LoaderModule
;
74 PLIST_ENTRY ListHead
, Current
;
76 /* query the process basic information (includes the PEB address) */
77 Status
= NtQueryInformationProcess(ProcessHandle
,
78 ProcessBasicInformation
,
80 sizeof(BasicInformation
),
83 if(!NT_SUCCESS(Status
))
85 DPRINT(FAILED_WITH_STATUS
, "NtQueryInformationProcess", Status
);
89 /* get the address of the PE Loader data */
90 Status
= NtReadVirtualMemory(ProcessHandle
,
91 &(BasicInformation
.PebBaseAddress
->Ldr
),
96 if(!NT_SUCCESS(Status
))
98 DPRINT(FAILED_WITH_STATUS
, "NtReadVirtualMemory", Status
);
102 /* head of the module list: the last element in the list will point to this */
103 ListHead
= &LoaderData
->InLoadOrderModuleList
;
105 /* get the address of the first element in the list */
106 Status
= NtReadVirtualMemory(ProcessHandle
,
107 &(LoaderData
->InLoadOrderModuleList
.Flink
),
112 while(Current
!= ListHead
)
114 /* read the current module */
115 Status
= NtReadVirtualMemory(ProcessHandle
,
116 CONTAINING_RECORD(Current
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
),
118 sizeof(LoaderModule
),
121 if(!NT_SUCCESS(Status
))
123 DPRINT(FAILED_WITH_STATUS
, "NtReadVirtualMemory", Status
);
127 /* return the current module to the callback */
128 Status
= Callback(ProcessHandle
, &LoaderModule
, CallbackContext
);
130 if(!NT_SUCCESS(Status
))
135 /* address of the next module in the list */
136 Current
= LoaderModule
.InLoadOrderLinks
.Flink
;
140 return STATUS_SUCCESS
;