[DELAYIMP] Fix 2 Clang-Cl warnings about __pfnDliNotifyHook2Default and __pfnDliFailu...
[reactos.git] / sdk / lib / epsapi / enum / modules.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * LICENSE: See LGPL.txt in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: reactos/lib/epsapi/enum/module.c
6 * PURPOSE: Enumerate process modules
7 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
8 * UPDATE HISTORY:
9 * 10/06/2002: Created
10 * 29/08/2002: Generalized the interface to improve reusability,
11 * more efficient use of memory operations
12 * 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
13 * for better reusability
14 * 02/04/2003: System modules enumeration moved into its own file
15 * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
16 * isolated in its own library to clear the confusion
17 * and improve reusability
18 */
19
20 #include "precomp.h"
21
22 #include <ndk/mmfuncs.h>
23 #include <ndk/psfuncs.h>
24 #include <ndk/rtlfuncs.h>
25
26 #define NDEBUG
27 #include <debug.h>
28
29 NTSTATUS NTAPI
30 PsaEnumerateProcessModules(IN HANDLE ProcessHandle,
31 IN PPROCMOD_ENUM_ROUTINE Callback,
32 IN OUT PVOID CallbackContext)
33 {
34 NTSTATUS Status;
35
36 /* current process - use direct memory copy */
37 /* FIXME - compare process id instead of a handle */
38 if(ProcessHandle == NtCurrentProcess())
39 {
40 PLIST_ENTRY ListHead, Current;
41
42 #if 0
43 __try
44 {
45 #endif
46 ListHead = &(NtCurrentPeb()->Ldr->InLoadOrderModuleList);
47 Current = ListHead->Flink;
48
49 while(Current != ListHead)
50 {
51 PLDR_DATA_TABLE_ENTRY LoaderModule = CONTAINING_RECORD(Current, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
52
53 /* return the current module to the callback */
54 Status = Callback(ProcessHandle, LoaderModule, CallbackContext);
55
56 if(!NT_SUCCESS(Status))
57 {
58 goto Failure;
59 }
60
61 Current = LoaderModule->InLoadOrderLinks.Flink;
62 }
63 #if 0
64 }
65 __except(EXCEPTION_EXECUTE_HANDLER)
66 {
67 return GetExceptionCode();
68 }
69 #endif
70 }
71 else
72 {
73 PROCESS_BASIC_INFORMATION BasicInformation;
74 PPEB_LDR_DATA LoaderData;
75 LDR_DATA_TABLE_ENTRY LoaderModule;
76 PLIST_ENTRY ListHead, Current;
77
78 /* query the process basic information (includes the PEB address) */
79 Status = NtQueryInformationProcess(ProcessHandle,
80 ProcessBasicInformation,
81 &BasicInformation,
82 sizeof(BasicInformation),
83 NULL);
84
85 if(!NT_SUCCESS(Status))
86 {
87 DPRINT(FAILED_WITH_STATUS, "NtQueryInformationProcess", Status);
88 goto Failure;
89 }
90
91 /* get the address of the PE Loader data */
92 Status = NtReadVirtualMemory(ProcessHandle,
93 &(BasicInformation.PebBaseAddress->Ldr),
94 &LoaderData,
95 sizeof(LoaderData),
96 NULL);
97
98 if(!NT_SUCCESS(Status))
99 {
100 DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", Status);
101 goto Failure;
102 }
103
104 /* head of the module list: the last element in the list will point to this */
105 ListHead = &LoaderData->InLoadOrderModuleList;
106
107 /* get the address of the first element in the list */
108 Status = NtReadVirtualMemory(ProcessHandle,
109 &(LoaderData->InLoadOrderModuleList.Flink),
110 &Current,
111 sizeof(Current),
112 NULL);
113
114 while(Current != ListHead)
115 {
116 /* read the current module */
117 Status = NtReadVirtualMemory(ProcessHandle,
118 CONTAINING_RECORD(Current, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks),
119 &LoaderModule,
120 sizeof(LoaderModule),
121 NULL);
122
123 if(!NT_SUCCESS(Status))
124 {
125 DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", Status);
126 goto Failure;
127 }
128
129 /* return the current module to the callback */
130 Status = Callback(ProcessHandle, &LoaderModule, CallbackContext);
131
132 if(!NT_SUCCESS(Status))
133 {
134 goto Failure;
135 }
136
137 /* address of the next module in the list */
138 Current = LoaderModule.InLoadOrderLinks.Flink;
139 }
140 }
141
142 return STATUS_SUCCESS;
143
144 Failure:
145 return Status;
146 }
147
148 /* EOF */