Implement NtAccessCheck.
[wine/gsoc-2012-control.git] / dlls / psapi / psapi_main.c
blob09573a1fb7182a6faf1a640566ea2bddf2005dcb
1 /*
2 * PSAPI library
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
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wine/server.h"
28 #include "wine/unicode.h"
29 #include "wine/debug.h"
30 #include "winnls.h"
31 #include "ntstatus.h"
32 #include "psapi.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);
51 if (lpcbNeeded)
52 *lpcbNeeded = 0;
54 return TRUE;
57 /***********************************************************************
58 * EnumPageFilesA (PSAPI.@)
60 BOOL WINAPI EnumPageFilesA( PENUM_PAGE_FILE_CALLBACKA callback, LPVOID context )
62 FIXME("(%p, %p) stub\n", callback, context );
63 return FALSE;
66 /***********************************************************************
67 * EnumPageFilesW (PSAPI.@)
69 BOOL WINAPI EnumPageFilesW( PENUM_PAGE_FILE_CALLBACKW callback, LPVOID context )
71 FIXME("(%p, %p) stub\n", callback, context );
72 return FALSE;
75 /***********************************************************************
76 * EnumProcesses (PSAPI.@)
78 BOOL WINAPI EnumProcesses(DWORD *lpidProcess, DWORD cb, DWORD *lpcbNeeded)
80 HANDLE hSnapshot;
81 DWORD count;
82 DWORD countMax;
83 DWORD pid;
84 int ret;
86 TRACE("(%p, %ld, %p)\n", lpidProcess,cb, lpcbNeeded);
88 if ( lpidProcess == NULL )
89 cb = 0;
90 if ( lpcbNeeded != NULL )
91 *lpcbNeeded = 0;
93 SERVER_START_REQ( create_snapshot )
95 req->flags = SNAP_PROCESS;
96 req->inherit = FALSE;
97 req->pid = 0;
98 wine_server_call_err( req );
99 hSnapshot = reply->handle;
101 SERVER_END_REQ;
103 if ( hSnapshot == 0 )
105 FIXME("cannot create snapshot\n");
106 return FALSE;
108 count = 0;
109 countMax = cb / sizeof(DWORD);
110 for (;;)
112 SERVER_START_REQ( next_process )
114 req->handle = hSnapshot;
115 req->reset = (count == 0);
116 if ((ret = !wine_server_call_err( req )))
117 pid = reply->pid;
119 SERVER_END_REQ;
120 if (!ret) break;
121 TRACE("process 0x%08lx\n", pid);
122 if ( count < countMax )
123 lpidProcess[count] = pid;
124 count++;
126 CloseHandle( hSnapshot );
128 if ( lpcbNeeded != NULL )
129 *lpcbNeeded = sizeof(DWORD) * count;
131 TRACE("return %lu processes\n", count);
133 return TRUE;
136 /***********************************************************************
137 * EnumProcessModules (PSAPI.@)
139 BOOL WINAPI EnumProcessModules(HANDLE hProcess, HMODULE *lphModule,
140 DWORD cb, LPDWORD lpcbNeeded)
142 HANDLE hSnapshot;
143 DWORD pid;
144 DWORD count;
145 DWORD countMax;
146 int ret;
147 HMODULE hModule;
149 TRACE("(hProcess=%p, %p, %ld, %p)\n",
150 hProcess, lphModule, cb, lpcbNeeded );
152 if ( lphModule == NULL )
153 cb = 0;
154 if ( lpcbNeeded != NULL )
155 *lpcbNeeded = 0;
157 SERVER_START_REQ( get_process_info )
159 req->handle = hProcess;
160 if ( !wine_server_call_err( req ) )
161 pid = (DWORD)reply->pid;
162 else
163 pid = 0;
165 SERVER_END_REQ;
167 if ( pid == 0 )
169 FIXME("no pid for hProcess %p\n" ,hProcess);
170 return FALSE;
173 SERVER_START_REQ( create_snapshot )
175 req->flags = SNAP_MODULE;
176 req->inherit = FALSE;
177 req->pid = pid;
178 wine_server_call_err( req );
179 hSnapshot = reply->handle;
181 SERVER_END_REQ;
182 if ( hSnapshot == 0 )
184 FIXME("cannot create snapshot\n");
185 return FALSE;
187 count = 0;
188 countMax = cb / sizeof(HMODULE);
189 for (;;)
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;
200 SERVER_END_REQ;
201 if ( !ret ) break;
202 TRACE("module 0x%p\n", hModule);
203 if ( count < countMax )
204 lphModule[count] = hModule;
205 count++;
207 CloseHandle( hSnapshot );
209 if ( lpcbNeeded != NULL )
210 *lpcbNeeded = sizeof(HMODULE) * count;
212 TRACE("return %lu modules\n", count);
214 return TRUE;
217 /***********************************************************************
218 * GetDeviceDriverBaseNameA (PSAPI.@)
220 DWORD WINAPI GetDeviceDriverBaseNameA(LPVOID ImageBase, LPSTR lpBaseName,
221 DWORD nSize)
223 FIXME("(%p, %s, %ld): stub\n",
224 ImageBase, debugstr_a(lpBaseName), nSize);
226 if (lpBaseName && nSize)
227 lpBaseName[0] = '\0';
229 return 0;
232 /***********************************************************************
233 * GetDeviceDriverBaseNameW (PSAPI.@)
235 DWORD WINAPI GetDeviceDriverBaseNameW(LPVOID ImageBase, LPWSTR lpBaseName,
236 DWORD nSize)
238 FIXME("(%p, %s, %ld): stub\n",
239 ImageBase, debugstr_w(lpBaseName), nSize);
241 if (lpBaseName && nSize)
242 lpBaseName[0] = '\0';
244 return 0;
247 /***********************************************************************
248 * GetDeviceDriverFileNameA (PSAPI.@)
250 DWORD WINAPI GetDeviceDriverFileNameA(LPVOID ImageBase, LPSTR lpFilename,
251 DWORD nSize)
253 FIXME("(%p, %s, %ld): stub\n",
254 ImageBase, debugstr_a(lpFilename), nSize);
256 if (lpFilename && nSize)
257 lpFilename[0] = '\0';
259 return 0;
262 /***********************************************************************
263 * GetDeviceDriverFileNameW (PSAPI.@)
265 DWORD WINAPI GetDeviceDriverFileNameW(LPVOID ImageBase, LPWSTR lpFilename,
266 DWORD nSize)
268 FIXME("(%p, %s, %ld): stub\n",
269 ImageBase, debugstr_w(lpFilename), nSize);
271 if (lpFilename && nSize)
272 lpFilename[0] = '\0';
274 return 0;
277 /***********************************************************************
278 * GetMappedFileNameA (PSAPI.@)
280 DWORD WINAPI GetMappedFileNameA(HANDLE hProcess, LPVOID lpv, LPSTR lpFilename,
281 DWORD nSize)
283 FIXME("(hProcess=%p, %p, %s, %ld): stub\n",
284 hProcess, lpv, debugstr_a(lpFilename), nSize);
286 if (lpFilename && nSize)
287 lpFilename[0] = '\0';
289 return 0;
292 /***********************************************************************
293 * GetMappedFileNameW (PSAPI.@)
295 DWORD WINAPI GetMappedFileNameW(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename,
296 DWORD nSize)
298 FIXME("(hProcess=%p, %p, %s, %ld): stub\n",
299 hProcess, lpv, debugstr_w(lpFilename), nSize);
301 if (lpFilename && nSize)
302 lpFilename[0] = '\0';
304 return 0;
307 /***********************************************************************
308 * GetModuleBaseNameA (PSAPI.@)
310 DWORD WINAPI GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule,
311 LPSTR lpBaseName, DWORD nSize)
313 WCHAR *lpBaseNameW;
314 DWORD buflenW, ret = 0;
316 if(!lpBaseName || !nSize) {
317 SetLastError(ERROR_INVALID_PARAMETER);
318 return 0;
320 lpBaseNameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * nSize);
321 buflenW = GetModuleBaseNameW(hProcess, hModule, lpBaseNameW, nSize);
322 TRACE("%ld, %s\n", buflenW, debugstr_w(lpBaseNameW));
323 if (buflenW)
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);
330 return ret;
333 /***********************************************************************
334 * GetModuleBaseNameW (PSAPI.@)
336 DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess, HMODULE hModule,
337 LPWSTR lpBaseName, DWORD nSize)
339 WCHAR tmp[MAX_PATH];
340 WCHAR* ptr;
341 int ptrlen;
343 if(!lpBaseName || !nSize) {
344 SetLastError(ERROR_INVALID_PARAMETER);
345 return 0;
348 if (!GetModuleFileNameExW(hProcess, hModule, tmp,
349 sizeof(tmp)/sizeof(WCHAR)))
350 return 0;
351 TRACE("%s\n", debugstr_w(tmp));
352 if ((ptr = strrchrW(tmp, '\\')) != NULL) ptr++; else ptr = tmp;
353 ptrlen = strlenW(ptr);
354 memcpy(lpBaseName, ptr, min(ptrlen+1,nSize) * sizeof(WCHAR));
355 return min(ptrlen, nSize);
358 /***********************************************************************
359 * GetModuleFileNameExA (PSAPI.@)
361 DWORD WINAPI GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule,
362 LPSTR lpFileName, DWORD nSize)
364 WCHAR *ptr;
366 TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
367 hProcess, hModule, lpFileName, nSize);
369 if (!lpFileName || !nSize) return 0;
371 if ( hProcess == GetCurrentProcess() )
373 DWORD len = GetModuleFileNameA( hModule, lpFileName, nSize );
374 if (nSize) lpFileName[nSize - 1] = '\0';
375 return len;
378 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, nSize * sizeof(WCHAR)))) return 0;
380 if (!GetModuleFileNameExW(hProcess, hModule, ptr, nSize))
382 lpFileName[0] = '\0';
384 else
386 if (!WideCharToMultiByte( CP_ACP, 0, ptr, -1, lpFileName, nSize, NULL, NULL ))
387 lpFileName[nSize - 1] = 0;
390 HeapFree(GetProcessHeap(), 0, ptr);
391 return strlen(lpFileName);
394 /***********************************************************************
395 * GetModuleFileNameExW (PSAPI.@)
397 DWORD WINAPI GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule,
398 LPWSTR lpFileName, DWORD nSize)
400 DWORD len = 0;
402 TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
403 hProcess, hModule, lpFileName, nSize);
405 if (!lpFileName || !nSize) return 0;
407 if ( hProcess == GetCurrentProcess() )
409 DWORD len = GetModuleFileNameW( hModule, lpFileName, nSize );
410 if (nSize) lpFileName[nSize - 1] = '\0';
411 TRACE("return (cur) %s (%lu)\n", debugstr_w(lpFileName), len);
412 return len;
415 lpFileName[0] = 0;
417 SERVER_START_REQ( get_dll_info )
419 req->handle = hProcess;
420 req->base_address = hModule;
421 wine_server_set_reply( req, lpFileName, (nSize - 1) * sizeof(WCHAR) );
422 if (!wine_server_call_err( req ))
424 len = wine_server_reply_size(reply) / sizeof(WCHAR);
425 lpFileName[len] = 0;
428 SERVER_END_REQ;
430 TRACE("return %s (%lu)\n", debugstr_w(lpFileName), len);
432 return len;
435 /***********************************************************************
436 * GetModuleInformation (PSAPI.@)
438 BOOL WINAPI GetModuleInformation(HANDLE hProcess, HMODULE hModule,
439 LPMODULEINFO lpmodinfo, DWORD cb)
441 BOOL ret = FALSE;
443 TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
444 hProcess, hModule, lpmodinfo, cb);
446 if (cb < sizeof(MODULEINFO)) return FALSE;
448 SERVER_START_REQ( get_dll_info )
450 req->handle = hProcess;
451 req->base_address = (void*)hModule;
452 if (!wine_server_call_err( req ))
454 ret = TRUE;
455 lpmodinfo->lpBaseOfDll = (void*)hModule;
456 lpmodinfo->SizeOfImage = reply->size;
457 lpmodinfo->EntryPoint = reply->entry_point;
460 SERVER_END_REQ;
462 return TRUE;
465 /***********************************************************************
466 * GetPerformanceInfo (PSAPI.@)
468 BOOL WINAPI GetPerformanceInfo( PPERFORMANCE_INFORMATION info, DWORD size )
470 NTSTATUS status;
472 TRACE( "(%p, %ld)\n", info, size );
474 status = NtQueryInformationProcess( GetCurrentProcess(), SystemPerformanceInformation, info, size, NULL );
476 if (status)
478 SetLastError( RtlNtStatusToDosError( status ) );
479 return FALSE;
481 return TRUE;
484 /***********************************************************************
485 * GetProcessImageFileNameA (PSAPI.@)
487 DWORD WINAPI GetProcessImageFileNameA( HANDLE process, LPSTR file, DWORD size )
489 FIXME("(%p, %p, %ld) stub\n", process, file, size );
490 return 0;
493 /***********************************************************************
494 * GetProcessImageFileNameW (PSAPI.@)
496 DWORD WINAPI GetProcessImageFileNameW( HANDLE process, LPWSTR file, DWORD size )
498 FIXME("(%p, %p, %ld) stub\n", process, file, size );
499 return 0;
502 /***********************************************************************
503 * GetProcessMemoryInfo (PSAPI.@)
505 * Retrieve memory usage information for a given process
508 BOOL WINAPI GetProcessMemoryInfo( HANDLE process, PPROCESS_MEMORY_COUNTERS counters, DWORD size )
510 NTSTATUS status;
511 VM_COUNTERS vmc;
513 TRACE( "(%p, %p, %ld)\n", process, counters, size );
515 status = NtQueryInformationProcess( process, ProcessVmCounters, &vmc, sizeof(vmc), NULL );
517 if (status)
519 SetLastError( RtlNtStatusToDosError( status ) );
520 return FALSE;
523 /* FIXME: check size */
525 counters->cb = sizeof(PROCESS_MEMORY_COUNTERS);
526 counters->PageFaultCount = vmc.PageFaultCount;
527 counters->PeakWorkingSetSize = vmc.PeakWorkingSetSize;
528 counters->WorkingSetSize = vmc.WorkingSetSize;
529 counters->QuotaPeakPagedPoolUsage = vmc.QuotaPeakPagedPoolUsage;
530 counters->QuotaPagedPoolUsage = vmc.QuotaPagedPoolUsage;
531 counters->QuotaPeakNonPagedPoolUsage = vmc.QuotaPeakNonPagedPoolUsage;
532 counters->QuotaNonPagedPoolUsage = vmc.QuotaNonPagedPoolUsage;
533 counters->PagefileUsage = vmc.PagefileUsage;
534 counters->PeakPagefileUsage = vmc.PeakPagefileUsage;
536 return TRUE;
539 /***********************************************************************
540 * GetWsChanges (PSAPI.@)
542 BOOL WINAPI GetWsChanges( HANDLE process, PPSAPI_WS_WATCH_INFORMATION watchinfo, DWORD size )
544 NTSTATUS status;
546 TRACE( "(%p, %p, %ld)\n", process, watchinfo, size );
548 status = NtQueryVirtualMemory( process, NULL, ProcessWorkingSetWatch, watchinfo, size, NULL );
550 if (status)
552 SetLastError( RtlNtStatusToDosError( status ) );
553 return FALSE;
555 return TRUE;
558 /***********************************************************************
559 * InitializeProcessForWsWatch (PSAPI.@)
561 BOOL WINAPI InitializeProcessForWsWatch(HANDLE hProcess)
563 FIXME("(hProcess=%p): stub\n", hProcess);
565 return TRUE;
568 /***********************************************************************
569 * QueryWorkingSet (PSAPI.@)
571 BOOL WINAPI QueryWorkingSet( HANDLE process, LPVOID buffer, DWORD size )
573 NTSTATUS status;
575 TRACE( "(%p, %p, %ld)\n", process, buffer, size );
577 status = NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer, size, NULL );
579 if (status)
581 SetLastError( RtlNtStatusToDosError( status ) );
582 return FALSE;
584 return TRUE;
587 /***********************************************************************
588 * QueryWorkingSetEx (PSAPI.@)
590 BOOL WINAPI QueryWorkingSetEx( HANDLE process, LPVOID buffer, DWORD size )
592 NTSTATUS status;
594 TRACE( "(%p, %p, %ld)\n", process, buffer, size );
596 status = NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer, size, NULL );
598 if (status)
600 SetLastError( RtlNtStatusToDosError( status ) );
601 return FALSE;
603 return TRUE;