Copy the vsnprintfW implementation from libunicode.so to msvcrt and
[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     {
352         DWORD len = GetModuleFileNameA( hModule, lpFileName, nSize );
353         if (nSize) lpFileName[nSize - 1] = '\0';
354         return len;
355     }
356
357     if (!(ptr = HeapAlloc(GetProcessHeap(), 0, nSize * sizeof(WCHAR)))) return 0;
358
359     if (!GetModuleFileNameExW(hProcess, hModule, ptr, nSize))
360     {
361         lpFileName[0] = '\0';
362     }
363     else
364     {
365         if (!WideCharToMultiByte( CP_ACP, 0, ptr, -1, lpFileName, nSize, NULL, NULL ))
366             lpFileName[nSize - 1] = 0;
367     }
368
369     HeapFree(GetProcessHeap(), 0, ptr);
370     return strlen(lpFileName);
371 }
372
373 /***********************************************************************
374  *           GetModuleFileNameExW (PSAPI.@)
375  */
376 DWORD WINAPI GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule, 
377                                   LPWSTR lpFileName, DWORD nSize)
378 {
379     DWORD len = 0;
380
381     TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
382           hProcess, hModule, lpFileName, nSize);
383
384     if (!lpFileName || !nSize) return 0;
385
386     if ( hProcess == GetCurrentProcess() )
387     {
388         DWORD len = GetModuleFileNameW( hModule, lpFileName, nSize );
389         if (nSize) lpFileName[nSize - 1] = '\0';
390         return len;
391     }
392
393     lpFileName[0] = 0;
394
395     SERVER_START_REQ( get_dll_info )
396     {
397         req->handle       = hProcess;
398         req->base_address = hModule;
399         wine_server_set_reply( req, lpFileName, (nSize - 1) * sizeof(WCHAR) );
400         if (!wine_server_call_err( req ))
401         {
402             len = wine_server_reply_size(reply) / sizeof(WCHAR);
403             lpFileName[len] = 0;
404         }
405     }
406     SERVER_END_REQ;
407
408     TRACE("return %s (%lu)\n", debugstr_w(lpFileName), len);
409
410     return len;
411 }
412
413 /***********************************************************************
414  *           GetModuleInformation (PSAPI.@)
415  */
416 BOOL WINAPI GetModuleInformation(HANDLE hProcess, HMODULE hModule, 
417                                  LPMODULEINFO lpmodinfo, DWORD cb)
418 {
419     BOOL ret = FALSE;
420
421     TRACE("(hProcess=%p, hModule=%p, %p, %ld)\n",
422           hProcess, hModule, lpmodinfo, cb);
423
424     if (cb < sizeof(MODULEINFO)) return FALSE;
425
426     SERVER_START_REQ( get_dll_info )
427     {
428         req->handle       = hProcess;
429         req->base_address = (void*)hModule;
430         if (!wine_server_call_err( req ))
431         {
432             ret = TRUE;
433             lpmodinfo->lpBaseOfDll = (void*)hModule;
434             lpmodinfo->SizeOfImage = reply->size;
435             lpmodinfo->EntryPoint  = reply->entry_point;
436         }
437     }
438     SERVER_END_REQ;
439
440     return TRUE;
441 }
442
443 /***********************************************************************
444  *           GetProcessMemoryInfo (PSAPI.@)
445  */
446 BOOL WINAPI GetProcessMemoryInfo(HANDLE Process, 
447                                  PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb)
448 {
449     FIXME("(hProcess=%p, %p, %ld): stub\n",
450           Process, ppsmemCounters, cb);
451     
452     memset(ppsmemCounters, 0, cb);
453
454     return TRUE;
455 }
456
457 /***********************************************************************
458  *           GetWsChanges (PSAPI.@)
459  */
460 BOOL WINAPI GetWsChanges(HANDLE hProcess, 
461                          PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, DWORD cb)
462 {
463     FIXME("(hProcess=%p, %p, %ld): stub\n",
464           hProcess, lpWatchInfo, cb);
465
466     memset(lpWatchInfo, 0, cb);
467
468     return TRUE;
469 }
470
471 /***********************************************************************
472  *           InitializeProcessForWsWatch (PSAPI.@)
473  */
474 BOOL WINAPI InitializeProcessForWsWatch(HANDLE hProcess)
475 {
476     FIXME("(hProcess=%p): stub\n", hProcess);
477
478     return TRUE;
479 }
480
481 /***********************************************************************
482  *           QueryWorkingSet (PSAPI.@)
483  */
484 BOOL WINAPI QueryWorkingSet(HANDLE hProcess, LPVOID pv, DWORD cb)
485 {
486     FIXME("(hProcess=%p, %p, %ld)\n", hProcess, pv, cb);
487
488     if (pv && cb)
489         ((DWORD *) pv)[0] = 0; /* Empty WorkingSet */
490
491     return TRUE;
492 }