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