4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2003 Eric Pouech
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wine/server.h"
28 #include "wine/unicode.h"
29 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(psapi);
36 /***********************************************************************
37 * EmptyWorkingSet (PSAPI.@)
39 BOOL WINAPI EmptyWorkingSet(HANDLE hProcess)
41 return SetProcessWorkingSetSize(hProcess, 0xFFFFFFFF, 0xFFFFFFFF);
44 /***********************************************************************
45 * EnumDeviceDrivers (PSAPI.@)
47 BOOL WINAPI EnumDeviceDrivers(LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeeded)
49 FIXME("(%p, %ld, %p): stub\n", lpImageBase, cb, lpcbNeeded);
57 /***********************************************************************
58 * EnumPageFilesA (PSAPI.@)
60 BOOL WINAPI EnumPageFilesA( PENUM_PAGE_FILE_CALLBACKA callback, LPVOID context )
62 FIXME("(%p, %p) stub\n", callback, context );
66 /***********************************************************************
67 * EnumPageFilesW (PSAPI.@)
69 BOOL WINAPI EnumPageFilesW( PENUM_PAGE_FILE_CALLBACKW callback, LPVOID context )
71 FIXME("(%p, %p) stub\n", callback, context );
75 /***********************************************************************
76 * EnumProcesses (PSAPI.@)
78 BOOL WINAPI EnumProcesses(DWORD *lpidProcess, DWORD cb, DWORD *lpcbNeeded)
86 TRACE("(%p, %ld, %p)\n", lpidProcess,cb, lpcbNeeded);
88 if ( lpidProcess == NULL )
90 if ( lpcbNeeded != NULL )
93 SERVER_START_REQ( create_snapshot )
95 req->flags = SNAP_PROCESS;
98 wine_server_call_err( req );
99 hSnapshot = reply->handle;
103 if ( hSnapshot == 0 )
105 FIXME("cannot create snapshot\n");
109 countMax = cb / sizeof(DWORD);
112 SERVER_START_REQ( next_process )
114 req->handle = hSnapshot;
115 req->reset = (count == 0);
116 if ((ret = !wine_server_call_err( req )))
121 TRACE("process 0x%08lx\n", pid);
122 if ( count < countMax )
123 lpidProcess[count] = pid;
126 CloseHandle( hSnapshot );
128 if ( lpcbNeeded != NULL )
129 *lpcbNeeded = sizeof(DWORD) * count;
131 TRACE("return %lu processes\n", count);
136 /***********************************************************************
137 * EnumProcessModules (PSAPI.@)
139 BOOL WINAPI EnumProcessModules(HANDLE hProcess, HMODULE *lphModule,
140 DWORD cb, LPDWORD lpcbNeeded)
149 TRACE("(hProcess=%p, %p, %ld, %p)\n",
150 hProcess, lphModule, cb, lpcbNeeded );
152 if ( lphModule == NULL )
154 if ( lpcbNeeded != NULL )
157 SERVER_START_REQ( get_process_info )
159 req->handle = hProcess;
160 if ( !wine_server_call_err( req ) )
161 pid = (DWORD)reply->pid;
169 FIXME("no pid for hProcess %p\n" ,hProcess);
173 SERVER_START_REQ( create_snapshot )
175 req->flags = SNAP_MODULE;
176 req->inherit = FALSE;
178 wine_server_call_err( req );
179 hSnapshot = reply->handle;
182 if ( hSnapshot == 0 )
184 FIXME("cannot create snapshot\n");
188 countMax = cb / sizeof(HMODULE);
191 SERVER_START_REQ( next_module )
193 req->handle = hSnapshot;
194 req->reset = (count == 0);
195 if ((ret = !wine_server_call_err( req )))
197 hModule = (HMODULE)reply->base;
202 TRACE("module 0x%p\n", hModule);
203 if ( count < countMax )
204 lphModule[count] = hModule;
207 CloseHandle( hSnapshot );
209 if ( lpcbNeeded != NULL )
210 *lpcbNeeded = sizeof(HMODULE) * count;
212 TRACE("return %lu modules\n", count);
217 /***********************************************************************
218 * GetDeviceDriverBaseNameA (PSAPI.@)
220 DWORD WINAPI GetDeviceDriverBaseNameA(LPVOID ImageBase, LPSTR lpBaseName,
223 FIXME("(%p, %s, %ld): stub\n",
224 ImageBase, debugstr_a(lpBaseName), nSize);
226 if (lpBaseName && nSize)
227 lpBaseName[0] = '\0';
232 /***********************************************************************
233 * GetDeviceDriverBaseNameW (PSAPI.@)
235 DWORD WINAPI GetDeviceDriverBaseNameW(LPVOID ImageBase, LPWSTR lpBaseName,
238 FIXME("(%p, %s, %ld): stub\n",
239 ImageBase, debugstr_w(lpBaseName), nSize);
241 if (lpBaseName && nSize)
242 lpBaseName[0] = '\0';
247 /***********************************************************************
248 * GetDeviceDriverFileNameA (PSAPI.@)
250 DWORD WINAPI GetDeviceDriverFileNameA(LPVOID ImageBase, LPSTR lpFilename,
253 FIXME("(%p, %s, %ld): stub\n",
254 ImageBase, debugstr_a(lpFilename), nSize);
256 if (lpFilename && nSize)
257 lpFilename[0] = '\0';
262 /***********************************************************************
263 * GetDeviceDriverFileNameW (PSAPI.@)
265 DWORD WINAPI GetDeviceDriverFileNameW(LPVOID ImageBase, LPWSTR lpFilename,
268 FIXME("(%p, %s, %ld): stub\n",
269 ImageBase, debugstr_w(lpFilename), nSize);
271 if (lpFilename && nSize)
272 lpFilename[0] = '\0';
277 /***********************************************************************
278 * GetMappedFileNameA (PSAPI.@)
280 DWORD WINAPI GetMappedFileNameA(HANDLE hProcess, LPVOID lpv, LPSTR lpFilename,
283 FIXME("(hProcess=%p, %p, %s, %ld): stub\n",
284 hProcess, lpv, debugstr_a(lpFilename), nSize);
286 if (lpFilename && nSize)
287 lpFilename[0] = '\0';
292 /***********************************************************************
293 * GetMappedFileNameW (PSAPI.@)
295 DWORD WINAPI GetMappedFileNameW(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename,
298 FIXME("(hProcess=%p, %p, %s, %ld): stub\n",
299 hProcess, lpv, debugstr_w(lpFilename), nSize);
301 if (lpFilename && nSize)
302 lpFilename[0] = '\0';
307 /***********************************************************************
308 * GetModuleBaseNameA (PSAPI.@)
310 DWORD WINAPI GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule,
311 LPSTR lpBaseName, DWORD nSize)
314 DWORD buflenW, ret = 0;
316 if(!lpBaseName || !nSize) {
317 SetLastError(ERROR_INVALID_PARAMETER);
320 lpBaseNameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * nSize);
321 buflenW = GetModuleBaseNameW(hProcess, hModule, lpBaseNameW, nSize);
322 TRACE("%ld, %s\n", buflenW, debugstr_w(lpBaseNameW));
325 ret = WideCharToMultiByte(CP_ACP, 0, lpBaseNameW, buflenW,
326 lpBaseName, nSize, NULL, NULL);
327 if (ret < nSize) lpBaseName[ret] = 0;
329 HeapFree(GetProcessHeap(), 0, lpBaseNameW);
333 /***********************************************************************
334 * GetModuleBaseNameW (PSAPI.@)
336 DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess, HMODULE hModule,
337 LPWSTR lpBaseName, DWORD nSize)
342 if(!lpBaseName || !nSize) {
343 SetLastError(ERROR_INVALID_PARAMETER);
347 if (!GetModuleFileNameExW(hProcess, hModule, tmp,
348 sizeof(tmp)/sizeof(WCHAR)))
350 TRACE("%s\n", debugstr_w(tmp));
351 if ((ptr = strrchrW(tmp, '\\')) != NULL) ptr++; else ptr = tmp;
352 strncpyW(lpBaseName, ptr, nSize);
353 return min(strlenW(ptr), nSize);
356 /***********************************************************************
357 * GetModuleFileNameExA (PSAPI.@)
359 DWORD WINAPI GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule,
360 LPSTR lpFileName, DWORD nSize)
364 TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
365 hProcess, hModule, lpFileName, nSize);
367 if (!lpFileName || !nSize) return 0;
369 if ( hProcess == GetCurrentProcess() )
371 DWORD len = GetModuleFileNameA( hModule, lpFileName, nSize );
372 if (nSize) lpFileName[nSize - 1] = '\0';
376 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, nSize * sizeof(WCHAR)))) return 0;
378 if (!GetModuleFileNameExW(hProcess, hModule, ptr, nSize))
380 lpFileName[0] = '\0';
384 if (!WideCharToMultiByte( CP_ACP, 0, ptr, -1, lpFileName, nSize, NULL, NULL ))
385 lpFileName[nSize - 1] = 0;
388 HeapFree(GetProcessHeap(), 0, ptr);
389 return strlen(lpFileName);
392 /***********************************************************************
393 * GetModuleFileNameExW (PSAPI.@)
395 DWORD WINAPI GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule,
396 LPWSTR lpFileName, DWORD nSize)
400 TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
401 hProcess, hModule, lpFileName, nSize);
403 if (!lpFileName || !nSize) return 0;
405 if ( hProcess == GetCurrentProcess() )
407 DWORD len = GetModuleFileNameW( hModule, lpFileName, nSize );
408 if (nSize) lpFileName[nSize - 1] = '\0';
409 TRACE("return (cur) %s (%lu)\n", debugstr_w(lpFileName), len);
415 SERVER_START_REQ( get_dll_info )
417 req->handle = hProcess;
418 req->base_address = hModule;
419 wine_server_set_reply( req, lpFileName, (nSize - 1) * sizeof(WCHAR) );
420 if (!wine_server_call_err( req ))
422 len = wine_server_reply_size(reply) / sizeof(WCHAR);
428 TRACE("return %s (%lu)\n", debugstr_w(lpFileName), len);
433 /***********************************************************************
434 * GetModuleInformation (PSAPI.@)
436 BOOL WINAPI GetModuleInformation(HANDLE hProcess, HMODULE hModule,
437 LPMODULEINFO lpmodinfo, DWORD cb)
441 TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
442 hProcess, hModule, lpmodinfo, cb);
444 if (cb < sizeof(MODULEINFO)) return FALSE;
446 SERVER_START_REQ( get_dll_info )
448 req->handle = hProcess;
449 req->base_address = (void*)hModule;
450 if (!wine_server_call_err( req ))
453 lpmodinfo->lpBaseOfDll = (void*)hModule;
454 lpmodinfo->SizeOfImage = reply->size;
455 lpmodinfo->EntryPoint = reply->entry_point;
463 /***********************************************************************
464 * GetPerformanceInfo (PSAPI.@)
466 BOOL WINAPI GetPerformanceInfo( PPERFORMANCE_INFORMATION info, DWORD size )
470 TRACE( "(%p, %ld)\n", info, size );
472 status = NtQueryInformationProcess( GetCurrentProcess(), SystemPerformanceInformation, info, size, NULL );
476 SetLastError( RtlNtStatusToDosError( status ) );
482 /***********************************************************************
483 * GetProcessImageFileNameA (PSAPI.@)
485 DWORD WINAPI GetProcessImageFileNameA( HANDLE process, LPSTR file, DWORD size )
487 FIXME("(%p, %p, %ld) stub\n", process, file, size );
491 /***********************************************************************
492 * GetProcessImageFileNameW (PSAPI.@)
494 DWORD WINAPI GetProcessImageFileNameW( HANDLE process, LPWSTR file, DWORD size )
496 FIXME("(%p, %p, %ld) stub\n", process, file, size );
500 /***********************************************************************
501 * GetProcessMemoryInfo (PSAPI.@)
503 * Retrieve memory usage information for a given process
506 BOOL WINAPI GetProcessMemoryInfo( HANDLE process, PPROCESS_MEMORY_COUNTERS counters, DWORD size )
511 TRACE( "(%p, %p, %ld)\n", process, counters, size );
513 status = NtQueryInformationProcess( process, ProcessVmCounters, &vmc, sizeof(vmc), NULL );
517 SetLastError( RtlNtStatusToDosError( status ) );
521 /* FIXME: check size */
523 counters->cb = sizeof(PROCESS_MEMORY_COUNTERS);
524 counters->PageFaultCount = vmc.PageFaultCount;
525 counters->PeakWorkingSetSize = vmc.PeakWorkingSetSize;
526 counters->WorkingSetSize = vmc.WorkingSetSize;
527 counters->QuotaPeakPagedPoolUsage = vmc.QuotaPeakPagedPoolUsage;
528 counters->QuotaPagedPoolUsage = vmc.QuotaPagedPoolUsage;
529 counters->QuotaPeakNonPagedPoolUsage = vmc.QuotaPeakNonPagedPoolUsage;
530 counters->QuotaNonPagedPoolUsage = vmc.QuotaNonPagedPoolUsage;
531 counters->PagefileUsage = vmc.PagefileUsage;
532 counters->PeakPagefileUsage = vmc.PeakPagefileUsage;
537 /***********************************************************************
538 * GetWsChanges (PSAPI.@)
540 BOOL WINAPI GetWsChanges( HANDLE process, PPSAPI_WS_WATCH_INFORMATION watchinfo, DWORD size )
544 TRACE( "(%p, %p, %ld)\n", process, watchinfo, size );
546 status = NtQueryVirtualMemory( process, NULL, ProcessWorkingSetWatch, watchinfo, size, NULL );
550 SetLastError( RtlNtStatusToDosError( status ) );
556 /***********************************************************************
557 * InitializeProcessForWsWatch (PSAPI.@)
559 BOOL WINAPI InitializeProcessForWsWatch(HANDLE hProcess)
561 FIXME("(hProcess=%p): stub\n", hProcess);
566 /***********************************************************************
567 * QueryWorkingSet (PSAPI.@)
569 BOOL WINAPI QueryWorkingSet( HANDLE process, LPVOID buffer, DWORD size )
573 TRACE( "(%p, %p, %ld)\n", process, buffer, size );
575 status = NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer, size, NULL );
579 SetLastError( RtlNtStatusToDosError( status ) );
585 /***********************************************************************
586 * QueryWorkingSetEx (PSAPI.@)
588 BOOL WINAPI QueryWorkingSetEx( HANDLE process, LPVOID buffer, DWORD size )
592 TRACE( "(%p, %p, %ld)\n", process, buffer, size );
594 status = NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer, size, NULL );
598 SetLastError( RtlNtStatusToDosError( status ) );