Skip tests without error if psapi.dll could not be loaded.
[wine] / dlls / psapi / psapi_main.c
1 /*
2  *      PSAPI library
3  *
4  * Copyright 1998 Patrik Stridvall
5  * Copyright 2003 Eric Pouech
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include <stdarg.h>
23
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 "psapi.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(psapi);
34
35 /***********************************************************************
36  *           EmptyWorkingSet (PSAPI.@)
37  */
38 BOOL WINAPI EmptyWorkingSet(HANDLE hProcess)
39 {
40     return SetProcessWorkingSetSize(hProcess, 0xFFFFFFFF, 0xFFFFFFFF);
41 }
42
43 /***********************************************************************
44  *           EnumDeviceDrivers (PSAPI.@)
45  */
46 BOOL WINAPI EnumDeviceDrivers(LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeeded)
47 {
48     FIXME("(%p, %ld, %p): stub\n", lpImageBase, cb, lpcbNeeded);
49
50     if (lpcbNeeded)
51         *lpcbNeeded = 0;
52
53     return TRUE;
54 }
55
56
57 /***********************************************************************
58  *           EnumProcesses (PSAPI.@)
59  */
60 BOOL WINAPI EnumProcesses(DWORD *lpidProcess, DWORD cb, DWORD *lpcbNeeded)
61 {
62     HANDLE      hSnapshot;
63     DWORD       count;
64     DWORD       countMax;
65     DWORD       pid;
66     int         ret;
67
68     TRACE("(%p, %ld, %p)\n", lpidProcess,cb, lpcbNeeded);
69
70     if ( lpidProcess == NULL )
71         cb = 0;
72     if ( lpcbNeeded != NULL )
73         *lpcbNeeded = 0;
74
75     SERVER_START_REQ( create_snapshot )
76     {
77         req->flags   = SNAP_PROCESS;
78         req->inherit = FALSE;
79         req->pid     = 0;
80         wine_server_call_err( req );
81         hSnapshot = reply->handle;
82     }
83     SERVER_END_REQ;
84
85     if ( hSnapshot == 0 )
86     {
87         FIXME("cannot create snapshot\n");
88         return FALSE;
89     }
90     count = 0;
91     countMax = cb / sizeof(DWORD);
92     for (;;)
93     {
94         SERVER_START_REQ( next_process )
95         {
96             req->handle = hSnapshot;
97             req->reset = (count == 0);
98             if ((ret = !wine_server_call_err( req )))
99                 pid = reply->pid;
100         }
101         SERVER_END_REQ;
102         if (!ret) break;
103         TRACE("process 0x%08lx\n", pid);
104         if ( count < countMax )
105             lpidProcess[count] = pid;
106         count++;
107     }
108     CloseHandle( hSnapshot );
109
110     if ( lpcbNeeded != NULL )
111         *lpcbNeeded = sizeof(DWORD) * count;
112
113     TRACE("return %lu processes\n", count);
114
115     return TRUE;
116 }
117
118 /***********************************************************************
119  *           EnumProcessModules (PSAPI.@)
120  */
121 BOOL WINAPI EnumProcessModules(HANDLE hProcess, HMODULE *lphModule, 
122                                DWORD cb, LPDWORD lpcbNeeded)
123 {
124     HANDLE      hSnapshot;
125     DWORD       pid;
126     DWORD       count;
127     DWORD       countMax;
128     int         ret;
129     HMODULE     hModule;
130
131     TRACE("(hProcess=%p, %p, %ld, %p)\n",
132           hProcess, lphModule, cb, lpcbNeeded );
133
134     if ( lphModule == NULL )
135         cb = 0;
136     if ( lpcbNeeded != NULL )
137         *lpcbNeeded = 0;
138
139     SERVER_START_REQ( get_process_info )
140     {
141         req->handle = hProcess;
142         if ( !wine_server_call_err( req ) )
143             pid = (DWORD)reply->pid;
144         else
145             pid = 0;
146     }
147     SERVER_END_REQ;
148
149     if ( pid == 0 )
150     {
151         FIXME("no pid for hProcess %p\n" ,hProcess);
152         return FALSE;
153     }
154
155     SERVER_START_REQ( create_snapshot )
156     {
157         req->flags   = SNAP_MODULE;
158         req->inherit = FALSE;
159         req->pid     = pid;
160         wine_server_call_err( req );
161         hSnapshot = reply->handle;
162     }
163     SERVER_END_REQ;
164     if ( hSnapshot == 0 )
165     {
166         FIXME("cannot create snapshot\n");
167         return FALSE;
168     }
169     count = 0;
170     countMax = cb / sizeof(HMODULE);
171     for (;;)
172     {
173         SERVER_START_REQ( next_module )
174         {
175             req->handle = hSnapshot;
176             req->reset = (count == 0);
177             if ((ret = !wine_server_call_err( req )))
178             {
179                 hModule = (HMODULE)reply->base;
180             }
181         }
182         SERVER_END_REQ;
183         if ( !ret ) break;
184         TRACE("module 0x%p\n", hModule);
185         if ( count < countMax )
186             lphModule[count] = hModule;
187         count++;
188     }
189     CloseHandle( hSnapshot );
190
191     if ( lpcbNeeded != NULL )
192         *lpcbNeeded = sizeof(HMODULE) * count;
193
194     TRACE("return %lu modules\n", count);
195
196     return TRUE;
197 }
198
199 /***********************************************************************
200  *          GetDeviceDriverBaseNameA (PSAPI.@)
201  */
202 DWORD WINAPI GetDeviceDriverBaseNameA(LPVOID ImageBase, LPSTR lpBaseName, 
203                                       DWORD nSize)
204 {
205     FIXME("(%p, %s, %ld): stub\n",
206           ImageBase, debugstr_a(lpBaseName), nSize);
207
208     if (lpBaseName && nSize)
209         lpBaseName[0] = '\0';
210
211     return 0;
212 }
213
214 /***********************************************************************
215  *           GetDeviceDriverBaseNameW (PSAPI.@)
216  */
217 DWORD WINAPI GetDeviceDriverBaseNameW(LPVOID ImageBase, LPWSTR lpBaseName, 
218                                       DWORD nSize)
219 {
220     FIXME("(%p, %s, %ld): stub\n",
221           ImageBase, debugstr_w(lpBaseName), nSize);
222
223     if (lpBaseName && nSize)
224         lpBaseName[0] = '\0';
225
226     return 0;
227 }
228
229 /***********************************************************************
230  *           GetDeviceDriverFileNameA (PSAPI.@)
231  */
232 DWORD WINAPI GetDeviceDriverFileNameA(LPVOID ImageBase, LPSTR lpFilename, 
233                                       DWORD nSize)
234 {
235     FIXME("(%p, %s, %ld): stub\n",
236           ImageBase, debugstr_a(lpFilename), nSize);
237
238     if (lpFilename && nSize)
239         lpFilename[0] = '\0';
240
241     return 0;
242 }
243
244 /***********************************************************************
245  *           GetDeviceDriverFileNameW (PSAPI.@)
246  */
247 DWORD WINAPI GetDeviceDriverFileNameW(LPVOID ImageBase, LPWSTR lpFilename, 
248                                       DWORD nSize)
249 {
250     FIXME("(%p, %s, %ld): stub\n",
251           ImageBase, debugstr_w(lpFilename), nSize);
252
253     if (lpFilename && nSize)
254         lpFilename[0] = '\0';
255
256     return 0;
257 }
258
259 /***********************************************************************
260  *           GetMappedFileNameA (PSAPI.@)
261  */
262 DWORD WINAPI GetMappedFileNameA(HANDLE hProcess, LPVOID lpv, LPSTR lpFilename, 
263                                 DWORD nSize)
264 {
265     FIXME("(hProcess=%p, %p, %s, %ld): stub\n",
266           hProcess, lpv, debugstr_a(lpFilename), nSize);
267
268     if (lpFilename && nSize)
269         lpFilename[0] = '\0';
270
271     return 0;
272 }
273
274 /***********************************************************************
275  *           GetMappedFileNameW (PSAPI.@)
276  */
277 DWORD WINAPI GetMappedFileNameW(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, 
278                                 DWORD nSize)
279 {
280     FIXME("(hProcess=%p, %p, %s, %ld): stub\n",
281           hProcess, lpv, debugstr_w(lpFilename), nSize);
282
283     if (lpFilename && nSize)
284         lpFilename[0] = '\0';
285
286     return 0;
287 }
288
289 /***********************************************************************
290  *           GetModuleBaseNameA (PSAPI.@)
291  */
292 DWORD WINAPI GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule, 
293                                 LPSTR lpBaseName, DWORD nSize)
294 {
295     WCHAR *lpBaseNameW;
296     DWORD buflenW, ret = 0;
297
298     if(!lpBaseName || !nSize) {
299         SetLastError(ERROR_INVALID_PARAMETER);
300         return 0;
301     }
302     lpBaseNameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * nSize);
303     buflenW = GetModuleBaseNameW(hProcess, hModule, lpBaseNameW, nSize);
304     TRACE("%ld, %s\n", buflenW, debugstr_w(lpBaseNameW));
305     if (buflenW)
306     {
307         ret = WideCharToMultiByte(CP_ACP, 0, lpBaseNameW, buflenW,
308                                   lpBaseName, nSize, NULL, NULL);
309         if (ret < nSize) lpBaseName[ret] = 0;
310     }
311     HeapFree(GetProcessHeap(), 0, lpBaseNameW);
312     return ret;
313 }
314
315 /***********************************************************************
316  *           GetModuleBaseNameW (PSAPI.@)
317  */
318 DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess, HMODULE hModule, 
319                                 LPWSTR lpBaseName, DWORD nSize)
320 {
321     WCHAR  tmp[MAX_PATH];
322     WCHAR* ptr;
323
324     if(!lpBaseName || !nSize) {
325         SetLastError(ERROR_INVALID_PARAMETER);
326         return 0;
327     }
328
329     if (!GetModuleFileNameExW(hProcess, hModule, tmp,
330                               sizeof(tmp)/sizeof(WCHAR)))
331         return 0;
332     TRACE("%s\n", debugstr_w(tmp));
333     if ((ptr = strrchrW(tmp, '\\')) != NULL) ptr++; else ptr = tmp;
334     strncpyW(lpBaseName, ptr, nSize);
335     return min(strlenW(ptr), nSize);
336 }
337
338 /***********************************************************************
339  *           GetModuleFileNameExA (PSAPI.@)
340  */
341 DWORD WINAPI GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, 
342                                   LPSTR lpFileName, DWORD nSize)
343 {
344     WCHAR *ptr;
345
346     TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
347           hProcess, hModule, lpFileName, nSize);
348
349     if (!lpFileName || !nSize) return 0;
350
351     if ( hProcess == GetCurrentProcess() )
352     {
353         DWORD len = GetModuleFileNameA( hModule, lpFileName, nSize );
354         if (nSize) lpFileName[nSize - 1] = '\0';
355         return len;
356     }
357
358     if (!(ptr = HeapAlloc(GetProcessHeap(), 0, nSize * sizeof(WCHAR)))) return 0;
359
360     if (!GetModuleFileNameExW(hProcess, hModule, ptr, nSize))
361     {
362         lpFileName[0] = '\0';
363     }
364     else
365     {
366         if (!WideCharToMultiByte( CP_ACP, 0, ptr, -1, lpFileName, nSize, NULL, NULL ))
367             lpFileName[nSize - 1] = 0;
368     }
369
370     HeapFree(GetProcessHeap(), 0, ptr);
371     return strlen(lpFileName);
372 }
373
374 /***********************************************************************
375  *           GetModuleFileNameExW (PSAPI.@)
376  */
377 DWORD WINAPI GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule, 
378                                   LPWSTR lpFileName, DWORD nSize)
379 {
380     DWORD len = 0;
381
382     TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
383           hProcess, hModule, lpFileName, nSize);
384
385     if (!lpFileName || !nSize) return 0;
386
387     if ( hProcess == GetCurrentProcess() )
388     {
389         DWORD len = GetModuleFileNameW( hModule, lpFileName, nSize );
390         if (nSize) lpFileName[nSize - 1] = '\0';
391         TRACE("return (cur) %s (%lu)\n", debugstr_w(lpFileName), len);
392         return len;
393     }
394
395     lpFileName[0] = 0;
396
397     SERVER_START_REQ( get_dll_info )
398     {
399         req->handle       = hProcess;
400         req->base_address = hModule;
401         wine_server_set_reply( req, lpFileName, (nSize - 1) * sizeof(WCHAR) );
402         if (!wine_server_call_err( req ))
403         {
404             len = wine_server_reply_size(reply) / sizeof(WCHAR);
405             lpFileName[len] = 0;
406         }
407     }
408     SERVER_END_REQ;
409
410     TRACE("return %s (%lu)\n", debugstr_w(lpFileName), len);
411
412     return len;
413 }
414
415 /***********************************************************************
416  *           GetModuleInformation (PSAPI.@)
417  */
418 BOOL WINAPI GetModuleInformation(HANDLE hProcess, HMODULE hModule, 
419                                  LPMODULEINFO lpmodinfo, DWORD cb)
420 {
421     BOOL ret = FALSE;
422
423     TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
424           hProcess, hModule, lpmodinfo, cb);
425
426     if (cb < sizeof(MODULEINFO)) return FALSE;
427
428     SERVER_START_REQ( get_dll_info )
429     {
430         req->handle       = hProcess;
431         req->base_address = (void*)hModule;
432         if (!wine_server_call_err( req ))
433         {
434             ret = TRUE;
435             lpmodinfo->lpBaseOfDll = (void*)hModule;
436             lpmodinfo->SizeOfImage = reply->size;
437             lpmodinfo->EntryPoint  = reply->entry_point;
438         }
439     }
440     SERVER_END_REQ;
441
442     return TRUE;
443 }
444
445 /***********************************************************************
446  *           GetProcessMemoryInfo (PSAPI.@)
447  */
448 BOOL WINAPI GetProcessMemoryInfo(HANDLE Process, 
449                                  PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb)
450 {
451     FIXME("(hProcess=%p, %p, %ld): stub\n",
452           Process, ppsmemCounters, cb);
453     
454     memset(ppsmemCounters, 0, cb);
455
456     return TRUE;
457 }
458
459 /***********************************************************************
460  *           GetWsChanges (PSAPI.@)
461  */
462 BOOL WINAPI GetWsChanges(HANDLE hProcess, 
463                          PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, DWORD cb)
464 {
465     FIXME("(hProcess=%p, %p, %ld): stub\n",
466           hProcess, lpWatchInfo, cb);
467
468     memset(lpWatchInfo, 0, cb);
469
470     return TRUE;
471 }
472
473 /***********************************************************************
474  *           InitializeProcessForWsWatch (PSAPI.@)
475  */
476 BOOL WINAPI InitializeProcessForWsWatch(HANDLE hProcess)
477 {
478     FIXME("(hProcess=%p): stub\n", hProcess);
479
480     return TRUE;
481 }
482
483 /***********************************************************************
484  *           QueryWorkingSet (PSAPI.@)
485  */
486 BOOL WINAPI QueryWorkingSet(HANDLE hProcess, LPVOID pv, DWORD cb)
487 {
488     FIXME("(hProcess=%p, %p, %ld)\n", hProcess, pv, cb);
489
490     if (pv && cb)
491         ((DWORD *) pv)[0] = 0; /* Empty WorkingSet */
492
493     return TRUE;
494 }