9b6b61b3bb08182756283d09d46618c45a2bb0ca
[reactos.git] / reactos / lib / psapi / misc / win32.c
1 /* $Id: win32.c,v 1.2 2002/08/29 23:57:54 hyperion Exp $
2 */
3 /*
4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS system libraries
6 * FILE: reactos/lib/psapi/misc/win32.c
7 * PURPOSE: Win32 interfaces for PSAPI
8 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
9 * UPDATE HISTORY:
10 * 10/06/2002: Created
11 */
12
13 #include <windows.h>
14 #include <psapi.h>
15 #include <stdlib.h>
16 #include <ddk/ntddk.h>
17 #include <internal/psapi.h>
18
19 /* Memory allocators for PSAPI */
20 PVOID STDCALL PsaMalloc(IN OUT PVOID Context, IN ULONG Size)
21 {
22 return malloc(Size);
23 }
24
25 PVOID STDCALL PsaRealloc(IN OUT PVOID Context, IN PVOID Addr, IN ULONG Size)
26 {
27 return realloc(Addr, Size);
28 }
29
30 VOID STDCALL PsaFree(IN OUT PVOID Context, IN PVOID Addr)
31 {
32 free(Addr);
33 }
34
35 /* EmptyWorkingSet */
36 BOOL STDCALL EmptyWorkingSet(HANDLE hProcess)
37 {
38 NTSTATUS nErrCode;
39 QUOTA_LIMITS qlProcessQuota;
40
41 /* query the working set */
42 nErrCode = NtQueryInformationProcess
43 (
44 hProcess,
45 ProcessQuotaLimits,
46 &qlProcessQuota,
47 sizeof(qlProcessQuota),
48 NULL
49 );
50
51 /* failure */
52 if(!NT_SUCCESS(nErrCode))
53 goto fail;
54
55 /* empty the working set */
56 qlProcessQuota.MinimumWorkingSetSize = -1;
57 qlProcessQuota.MaximumWorkingSetSize = -1;
58
59 /* set the working set */
60 nErrCode = NtSetInformationProcess
61 (
62 hProcess,
63 ProcessQuotaLimits,
64 &qlProcessQuota,
65 sizeof(qlProcessQuota)
66 );
67
68 /* success */
69 if(NT_SUCCESS(nErrCode))
70 return (TRUE);
71
72 fail:
73 /* failure */
74 SetLastError(RtlNtStatusToDosError(nErrCode));
75 return (FALSE);
76 }
77
78 /* EnumDeviceDrivers */
79 /* callback context */
80 typedef struct _ENUM_DEVICE_DRIVERS_CONTEXT
81 {
82 LPVOID *lpImageBase;
83 DWORD nCount;
84 } ENUM_DEVICE_DRIVERS_CONTEXT, *PENUM_DEVICE_DRIVERS_CONTEXT;
85
86 /* callback routine */
87 NTSTATUS STDCALL EnumDeviceDriversCallback
88 (
89 IN ULONG ModuleCount,
90 IN PSYSTEM_MODULE_ENTRY CurrentModule,
91 IN OUT PVOID CallbackContext
92 )
93 {
94 register PENUM_DEVICE_DRIVERS_CONTEXT peddcContext =
95 (PENUM_DEVICE_DRIVERS_CONTEXT)CallbackContext;
96
97 /* no more buffer space */
98 if(peddcContext->nCount == 0)
99 return STATUS_INFO_LENGTH_MISMATCH;
100
101 /* return current module */
102 *(peddcContext->lpImageBase) = CurrentModule->BaseAddress;
103
104 /* go to next array slot */
105 (peddcContext->lpImageBase) ++;
106 (peddcContext->nCount) --;
107
108 return STATUS_SUCCESS;
109 }
110
111 /* exported interface */
112 BOOL STDCALL EnumDeviceDrivers
113 (
114 LPVOID *lpImageBase,
115 DWORD cb,
116 LPDWORD lpcbNeeded
117 )
118 {
119 register NTSTATUS nErrCode;
120 ENUM_DEVICE_DRIVERS_CONTEXT eddcContext = {lpImageBase, cb / sizeof(PVOID)};
121
122 cb /= sizeof(PVOID);
123
124 /* do nothing if the buffer is empty */
125 if(cb == 0 || lpImageBase == NULL)
126 {
127 *lpcbNeeded = 0;
128 return (TRUE);
129 }
130
131 /* enumerate the system modules */
132 nErrCode = PsaEnumerateSystemModules
133 (
134 &EnumDeviceDriversCallback,
135 &eddcContext,
136 NULL
137 );
138
139 /* return the count of bytes returned */
140 *lpcbNeeded = (cb - eddcContext.nCount) * sizeof(PVOID);
141
142 /* success */
143 if(NT_SUCCESS(nErrCode) || nErrCode == STATUS_INFO_LENGTH_MISMATCH)
144 return (TRUE);
145 else
146 {
147 /* failure */
148 SetLastError(RtlNtStatusToDosError(nErrCode));
149 return (FALSE);
150 }
151 }
152
153 /* EnumProcesses */
154 /* callback context */
155 typedef struct _ENUM_PROCESSES_CONTEXT
156 {
157 DWORD *lpidProcess;
158 DWORD nCount;
159 } ENUM_PROCESSES_CONTEXT, *PENUM_PROCESSES_CONTEXT;
160
161 /* callback routine */
162 NTSTATUS STDCALL EnumProcessesCallback
163 (
164 IN PSYSTEM_PROCESS_INFORMATION CurrentProcess,
165 IN OUT PVOID CallbackContext
166 )
167 {
168 register PENUM_PROCESSES_CONTEXT pepcContext =
169 (PENUM_PROCESSES_CONTEXT)CallbackContext;
170
171 /* no more buffer space */
172 if(pepcContext->nCount == 0)
173 return STATUS_INFO_LENGTH_MISMATCH;
174
175 /* return current process */
176 *(pepcContext->lpidProcess) = CurrentProcess->ProcessId;
177
178 /* go to next array slot */
179 (pepcContext->lpidProcess) ++;
180 (pepcContext->nCount) --;
181
182 return STATUS_SUCCESS;
183 }
184
185 /* exported interface */
186 BOOL STDCALL EnumProcesses
187 (
188 DWORD *lpidProcess,
189 DWORD cb,
190 LPDWORD lpcbNeeded
191 )
192 {
193 register NTSTATUS nErrCode;
194 ENUM_PROCESSES_CONTEXT epcContext = {lpidProcess, cb / sizeof(DWORD)};
195
196 cb /= sizeof(DWORD);
197
198 /* do nothing if the buffer is empty */
199 if(cb == 0 || lpidProcess == NULL)
200 {
201 *lpcbNeeded = 0;
202 return (TRUE);
203 }
204
205 /* enumerate the process ids */
206 nErrCode = PsaEnumerateProcesses(&EnumProcessesCallback, &epcContext, NULL);
207
208 *lpcbNeeded = (cb - epcContext.nCount) * sizeof(DWORD);
209
210 /* success */
211 if(NT_SUCCESS(nErrCode) || nErrCode == STATUS_INFO_LENGTH_MISMATCH)
212 return (TRUE);
213 else
214 {
215 /* failure */
216 SetLastError(RtlNtStatusToDosError(nErrCode));
217 return (FALSE);
218 }
219 }
220
221 /* EnumProcessModules */
222 /* callback context */
223 typedef struct _ENUM_PROCESS_MODULES_CONTEXT
224 {
225 HMODULE *lphModule;
226 DWORD nCount;
227 } ENUM_PROCESS_MODULES_CONTEXT, *PENUM_PROCESS_MODULES_CONTEXT;
228
229 /* callback routine */
230 NTSTATUS STDCALL EnumProcessModulesCallback
231 (
232 IN HANDLE ProcessHandle,
233 IN PLDR_MODULE CurrentModule,
234 IN OUT PVOID CallbackContext
235 )
236 {
237 register PENUM_PROCESS_MODULES_CONTEXT pepmcContext =
238 (PENUM_PROCESS_MODULES_CONTEXT)CallbackContext;
239
240 /* no more buffer space */
241 if(pepmcContext->nCount == 0)
242 return STATUS_INFO_LENGTH_MISMATCH;
243
244 /* return current process */
245 *(pepmcContext->lphModule) = CurrentModule->BaseAddress;
246
247 /* go to next array slot */
248 (pepmcContext->lphModule) ++;
249 (pepmcContext->nCount) --;
250
251 return STATUS_SUCCESS;
252 }
253
254 /* exported interface */
255 BOOL STDCALL EnumProcessModules(
256 HANDLE hProcess, // handle to process
257 HMODULE *lphModule, // array of module handles
258 DWORD cb, // size of array
259 LPDWORD lpcbNeeded // number of bytes required
260 )
261 {
262 register NTSTATUS nErrCode;
263 ENUM_PROCESS_MODULES_CONTEXT epmcContext = {lphModule, cb / sizeof(HMODULE)};
264
265 cb /= sizeof(DWORD);
266
267 /* do nothing if the buffer is empty */
268 if(cb == 0 || lphModule == NULL)
269 {
270 *lpcbNeeded = 0;
271 return (TRUE);
272 }
273
274 /* enumerate the process modules */
275 nErrCode = PsaEnumerateProcessModules
276 (
277 hProcess,
278 &EnumProcessModulesCallback,
279 &epmcContext
280 );
281
282 *lpcbNeeded = (cb - epmcContext.nCount) * sizeof(DWORD);
283
284 /* success */
285 if(NT_SUCCESS(nErrCode) || nErrCode == STATUS_INFO_LENGTH_MISMATCH)
286 return (TRUE);
287 else
288 {
289 /* failure */
290 SetLastError(RtlNtStatusToDosError(nErrCode));
291 return (FALSE);
292 }
293 }
294
295 /* EOF */
296