2 * Unit test suite for PSAPI
4 * Copyright (C) 2005 Felix Nawothnig
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
28 #define expect_eq_d(expected, actual) \
30 int value = (actual); \
31 ok((expected) == value, "Expected " #actual " to be %d (" #expected ") is %d\n", \
35 #define PSAPI_GET_PROC(func) \
36 p ## func = (void*)GetProcAddress(hpsapi, #func); \
38 ok(0, "GetProcAddress(%s) failed\n", #func); \
39 FreeLibrary(hpsapi); \
43 /* All PSAPI functions return non-zero and call SetLastError()
44 * on failure so we can use some macros for convenience */
47 (SetLastError(0xdeadbeef), \
49 ? (ok(1, "succeeded\n"), 1) \
50 : GetLastError() == 0xdeadbeef \
51 ? (ok(0, "failed without error code\n"), 0) \
52 : (ok(0, "failed with %d\n", GetLastError()), 0))
54 #define w32_err(x, e) \
55 (SetLastError(0xdeadbeef), \
57 ? (ok(0, "expected error=%d but succeeded\n", e), 0) \
58 : GetLastError() == e \
59 ? (ok(1, "failed with %d\n", e), 1) \
60 : GetLastError() == 0xdeadbeef \
61 ? (ok(0, "failed without error code\n"), 0) \
62 : (ok(0, "expected error=%d but failed with %d\n", \
63 e, GetLastError()), 0))
65 static BOOL (WINAPI
*pEmptyWorkingSet
)(HANDLE
);
66 static BOOL (WINAPI
*pEnumProcesses
)(DWORD
*, DWORD
, DWORD
*);
67 static BOOL (WINAPI
*pEnumProcessModules
)(HANDLE
, HMODULE
*, DWORD
, LPDWORD
);
68 static DWORD (WINAPI
*pGetModuleBaseNameA
)(HANDLE
, HMODULE
, LPSTR
, DWORD
);
69 static DWORD (WINAPI
*pGetModuleFileNameExA
)(HANDLE
, HMODULE
, LPSTR
, DWORD
);
70 static BOOL (WINAPI
*pGetModuleInformation
)(HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
);
71 static DWORD (WINAPI
*pGetMappedFileNameA
)(HANDLE
, LPVOID
, LPSTR
, DWORD
);
72 static DWORD (WINAPI
*pGetProcessImageFileNameA
)(HANDLE
, LPSTR
, DWORD
);
73 static DWORD (WINAPI
*pGetProcessImageFileNameW
)(HANDLE
, LPWSTR
, DWORD
);
74 static BOOL (WINAPI
*pGetProcessMemoryInfo
)(HANDLE
, PPROCESS_MEMORY_COUNTERS
, DWORD
);
75 static BOOL (WINAPI
*pGetWsChanges
)(HANDLE
, PPSAPI_WS_WATCH_INFORMATION
, DWORD
);
76 static BOOL (WINAPI
*pInitializeProcessForWsWatch
)(HANDLE
);
77 static BOOL (WINAPI
*pQueryWorkingSet
)(HANDLE
, PVOID
, DWORD
);
79 static BOOL
InitFunctionPtrs(HMODULE hpsapi
)
81 PSAPI_GET_PROC(EmptyWorkingSet
);
82 PSAPI_GET_PROC(EnumProcessModules
);
83 PSAPI_GET_PROC(EnumProcesses
);
84 PSAPI_GET_PROC(GetModuleBaseNameA
);
85 PSAPI_GET_PROC(GetModuleFileNameExA
);
86 PSAPI_GET_PROC(GetModuleInformation
);
87 PSAPI_GET_PROC(GetMappedFileNameA
);
88 PSAPI_GET_PROC(GetProcessMemoryInfo
);
89 PSAPI_GET_PROC(GetWsChanges
);
90 PSAPI_GET_PROC(InitializeProcessForWsWatch
);
91 PSAPI_GET_PROC(QueryWorkingSet
);
92 /* GetProcessImageFileName is not exported on NT4 */
93 pGetProcessImageFileNameA
=
94 (void *)GetProcAddress(hpsapi
, "GetProcessImageFileNameA");
95 pGetProcessImageFileNameW
=
96 (void *)GetProcAddress(hpsapi
, "GetProcessImageFileNameW");
100 static HANDLE hpSR
, hpQI
, hpVR
, hpQV
, hpAA
;
101 static const HANDLE hBad
= (HANDLE
)0xdeadbeef;
103 static void test_EnumProcesses(void)
105 DWORD pid
, cbUsed
= 0xdeadbeef;
107 if(w32_suc(pEnumProcesses(NULL
, 0, &cbUsed
)))
108 ok(cbUsed
== 0, "cbUsed=%d\n", cbUsed
);
109 if(w32_suc(pEnumProcesses(&pid
, 4, &cbUsed
)))
110 ok(cbUsed
== 4, "cbUsed=%d\n", cbUsed
);
113 static void test_EnumProcessModules(void)
115 HMODULE hMod
= GetModuleHandle(NULL
);
116 DWORD cbNeeded
= 0xdeadbeef;
118 w32_err(pEnumProcessModules(NULL
, NULL
, 0, &cbNeeded
), ERROR_INVALID_HANDLE
);
119 w32_err(pEnumProcessModules(hpQI
, NULL
, 0, &cbNeeded
), ERROR_ACCESS_DENIED
);
120 w32_suc(pEnumProcessModules(hpQV
, NULL
, 0, &cbNeeded
));
121 if(!w32_suc(pEnumProcessModules(hpQV
, &hMod
, sizeof(HMODULE
), &cbNeeded
)))
123 ok(cbNeeded
/ sizeof(HMODULE
) >= 3 && cbNeeded
/ sizeof(HMODULE
) <= 5 * sizeof(HMODULE
),
124 "cbNeeded=%d\n", cbNeeded
);
125 ok(hMod
== GetModuleHandle(NULL
),
126 "hMod=%p GetModuleHandle(NULL)=%p\n", hMod
, GetModuleHandle(NULL
));
129 static void test_GetModuleInformation(void)
131 HMODULE hMod
= GetModuleHandle(NULL
);
134 w32_err(pGetModuleInformation(NULL
, hMod
, &info
, sizeof(info
)), ERROR_INVALID_HANDLE
);
135 w32_err(pGetModuleInformation(hpQI
, hMod
, &info
, sizeof(info
)), ERROR_ACCESS_DENIED
);
136 w32_err(pGetModuleInformation(hpQV
, hBad
, &info
, sizeof(info
)), ERROR_INVALID_HANDLE
);
137 w32_err(pGetModuleInformation(hpQV
, hMod
, &info
, sizeof(info
)-1), ERROR_INSUFFICIENT_BUFFER
);
138 if(w32_suc(pGetModuleInformation(hpQV
, hMod
, &info
, sizeof(info
))))
139 ok(info
.lpBaseOfDll
== hMod
, "lpBaseOfDll=%p hMod=%p\n", info
.lpBaseOfDll
, hMod
);
142 static void test_GetProcessMemoryInfo(void)
144 PROCESS_MEMORY_COUNTERS pmc
;
146 w32_err(pGetProcessMemoryInfo(NULL
, &pmc
, sizeof(pmc
)), ERROR_INVALID_HANDLE
);
147 todo_wine
w32_err(pGetProcessMemoryInfo(hpSR
, &pmc
, sizeof(pmc
)), ERROR_ACCESS_DENIED
);
148 w32_err(pGetProcessMemoryInfo(hpQI
, &pmc
, sizeof(pmc
)-1), ERROR_INSUFFICIENT_BUFFER
);
149 w32_suc(pGetProcessMemoryInfo(hpQI
, &pmc
, sizeof(pmc
)));
152 static void test_GetMappedFileName(void)
154 HMODULE hMod
= GetModuleHandle(NULL
);
155 char szMapPath
[MAX_PATH
], szModPath
[MAX_PATH
], *szMapBaseName
;
158 w32_err(pGetMappedFileNameA(NULL
, hMod
, szMapPath
, sizeof(szMapPath
)), ERROR_INVALID_HANDLE
);
159 w32_err(pGetMappedFileNameA(hpSR
, hMod
, szMapPath
, sizeof(szMapPath
)), ERROR_ACCESS_DENIED
);
161 SetLastError( 0xdeadbeef );
162 ret
= pGetMappedFileNameA(hpQI
, hMod
, szMapPath
, sizeof(szMapPath
));
163 ok( ret
|| broken(GetLastError() == ERROR_UNEXP_NET_ERR
), /* win2k */
164 "GetMappedFileNameA failed with error %u\n", GetLastError() );
166 ok(ret
== strlen(szMapPath
), "szMapPath=\"%s\" ret=%d\n", szMapPath
, ret
);
167 ok(szMapPath
[0] == '\\', "szMapPath=\"%s\"\n", szMapPath
);
168 szMapBaseName
= strrchr(szMapPath
, '\\'); /* That's close enough for us */
169 if(!szMapBaseName
|| !*szMapBaseName
)
171 ok(0, "szMapPath=\"%s\"\n", szMapPath
);
174 GetModuleFileNameA(NULL
, szModPath
, sizeof(szModPath
));
175 ok(!strcmp(strrchr(szModPath
, '\\'), szMapBaseName
),
176 "szModPath=\"%s\" szMapBaseName=\"%s\"\n", szModPath
, szMapBaseName
);
179 static void test_GetProcessImageFileName(void)
181 HMODULE hMod
= GetModuleHandle(NULL
);
182 char szImgPath
[MAX_PATH
], szMapPath
[MAX_PATH
];
183 WCHAR szImgPathW
[MAX_PATH
];
186 if(pGetProcessImageFileNameA
== NULL
)
189 /* This function is available on WinXP+ only */
190 SetLastError(0xdeadbeef);
191 if(!pGetProcessImageFileNameA(hpQI
, szImgPath
, sizeof(szImgPath
)))
193 if(GetLastError() == ERROR_INVALID_FUNCTION
) {
194 win_skip("GetProcessImageFileName not implemented\n");
198 if(GetLastError() == 0xdeadbeef)
199 todo_wine
ok(0, "failed without error code\n");
201 todo_wine
ok(0, "failed with %d\n", GetLastError());
204 todo_wine
w32_err(pGetProcessImageFileNameA(NULL
, szImgPath
, sizeof(szImgPath
)), ERROR_INVALID_HANDLE
);
205 todo_wine
w32_err(pGetProcessImageFileNameA(hpSR
, szImgPath
, sizeof(szImgPath
)), ERROR_ACCESS_DENIED
);
206 todo_wine
w32_err(pGetProcessImageFileNameA(hpQI
, szImgPath
, 0), ERROR_INSUFFICIENT_BUFFER
);
208 if(w32_suc(ret
= pGetProcessImageFileNameA(hpQI
, szImgPath
, sizeof(szImgPath
))) &&
209 w32_suc(pGetMappedFileNameA(hpQV
, hMod
, szMapPath
, sizeof(szMapPath
)))) {
210 /* Windows returns 2*strlen-1 */
211 ok(ret
>= strlen(szImgPath
), "szImgPath=\"%s\" ret=%d\n", szImgPath
, ret
);
212 ok(!strcmp(szImgPath
, szMapPath
),
213 "szImgPath=\"%s\" szMapPath=\"%s\"\n", szImgPath
, szMapPath
);
216 w32_err(pGetProcessImageFileNameW(NULL
, szImgPathW
, sizeof(szImgPathW
)), ERROR_INVALID_HANDLE
);
217 /* no information about correct buffer size returned: */
218 w32_err(pGetProcessImageFileNameW(hpQI
, szImgPathW
, 0), ERROR_INSUFFICIENT_BUFFER
);
219 w32_err(pGetProcessImageFileNameW(hpQI
, NULL
, 0), ERROR_INSUFFICIENT_BUFFER
);
222 memset(szImgPathW
, 0xff, sizeof(szImgPathW
));
223 ret
= pGetProcessImageFileNameW(hpQI
, szImgPathW
, sizeof(szImgPathW
)/sizeof(WCHAR
));
224 ok(ret
> 0, "GetProcessImageFileNameW should have succeeded.\n");
225 ok(szImgPathW
[0] == '\\', "GetProcessImageFileNameW should have returned an NT path.\n");
226 expect_eq_d(lstrlenW(szImgPathW
), ret
);
228 /* boundary values of 'size' */
229 w32_err(pGetProcessImageFileNameW(hpQI
, szImgPathW
, ret
), ERROR_INSUFFICIENT_BUFFER
);
231 memset(szImgPathW
, 0xff, sizeof(szImgPathW
));
232 ret
= pGetProcessImageFileNameW(hpQI
, szImgPathW
, ret
+ 1);
233 ok(ret
> 0, "GetProcessImageFileNameW should have succeeded.\n");
234 ok(szImgPathW
[0] == '\\', "GetProcessImageFileNameW should have returned an NT path.\n");
235 expect_eq_d(lstrlenW(szImgPathW
), ret
);
238 static void test_GetModuleFileNameEx(void)
240 HMODULE hMod
= GetModuleHandle(NULL
);
241 char szModExPath
[MAX_PATH
+1], szModPath
[MAX_PATH
+1];
244 w32_err(pGetModuleFileNameExA(NULL
, hMod
, szModExPath
, sizeof(szModExPath
)), ERROR_INVALID_HANDLE
);
245 w32_err(pGetModuleFileNameExA(hpQI
, hMod
, szModExPath
, sizeof(szModExPath
)), ERROR_ACCESS_DENIED
);
246 w32_err(pGetModuleFileNameExA(hpQV
, hBad
, szModExPath
, sizeof(szModExPath
)), ERROR_INVALID_HANDLE
);
247 if(!w32_suc(ret
= pGetModuleFileNameExA(hpQV
, NULL
, szModExPath
, sizeof(szModExPath
))))
249 ok(ret
== strlen(szModExPath
), "szModExPath=\"%s\" ret=%d\n", szModExPath
, ret
);
250 GetModuleFileNameA(NULL
, szModPath
, sizeof(szModPath
));
251 ok(!strncmp(szModExPath
, szModPath
, MAX_PATH
),
252 "szModExPath=\"%s\" szModPath=\"%s\"\n", szModExPath
, szModPath
);
255 static void test_GetModuleBaseName(void)
257 HMODULE hMod
= GetModuleHandle(NULL
);
258 char szModPath
[MAX_PATH
], szModBaseName
[MAX_PATH
];
261 w32_err(pGetModuleBaseNameA(NULL
, hMod
, szModBaseName
, sizeof(szModBaseName
)), ERROR_INVALID_HANDLE
);
262 w32_err(pGetModuleBaseNameA(hpQI
, hMod
, szModBaseName
, sizeof(szModBaseName
)), ERROR_ACCESS_DENIED
);
263 w32_err(pGetModuleBaseNameA(hpQV
, hBad
, szModBaseName
, sizeof(szModBaseName
)), ERROR_INVALID_HANDLE
);
264 if(!w32_suc(ret
= pGetModuleBaseNameA(hpQV
, NULL
, szModBaseName
, sizeof(szModBaseName
))))
266 ok(ret
== strlen(szModBaseName
), "szModBaseName=\"%s\" ret=%d\n", szModBaseName
, ret
);
267 GetModuleFileNameA(NULL
, szModPath
, sizeof(szModPath
));
268 ok(!strcmp(strrchr(szModPath
, '\\') + 1, szModBaseName
),
269 "szModPath=\"%s\" szModBaseName=\"%s\"\n", szModPath
, szModBaseName
);
272 static void test_ws_functions(void)
274 PSAPI_WS_WATCH_INFORMATION wswi
[4096];
275 ULONG_PTR pages
[4096];
279 todo_wine
w32_err(pEmptyWorkingSet(NULL
), ERROR_INVALID_HANDLE
);
280 todo_wine
w32_err(pEmptyWorkingSet(hpSR
), ERROR_ACCESS_DENIED
);
281 w32_suc(pEmptyWorkingSet(hpAA
));
283 todo_wine
w32_err(pInitializeProcessForWsWatch(NULL
), ERROR_INVALID_HANDLE
);
284 w32_suc(pInitializeProcessForWsWatch(hpAA
));
286 if(!w32_suc(addr
= VirtualAlloc(NULL
, 1, MEM_COMMIT
, PAGE_READWRITE
)))
289 if(!VirtualLock(addr
, 1))
291 trace("locking failed (error=%d) - skipping test\n", GetLastError());
295 todo_wine
if(w32_suc(pQueryWorkingSet(hpQI
, pages
, 4096 * sizeof(ULONG_PTR
))))
297 for(i
= 0; i
< pages
[0]; i
++)
298 if((pages
[i
+1] & ~0xfffL
) == (ULONG_PTR
)addr
)
300 ok(1, "QueryWorkingSet found our page\n");
304 ok(0, "QueryWorkingSet didn't find our page\n");
308 todo_wine
if(w32_suc(pGetWsChanges(hpQI
, wswi
, sizeof(wswi
))))
310 for(i
= 0; wswi
[i
].FaultingVa
; i
++)
311 if(((ULONG_PTR
)wswi
[i
].FaultingVa
& ~0xfffL
) == (ULONG_PTR
)addr
)
313 ok(1, "GetWsChanges found our page\n");
317 ok(0, "GetWsChanges didn't find our page\n");
321 VirtualFree(addr
, 0, MEM_RELEASE
);
324 START_TEST(psapi_main
)
326 HMODULE hpsapi
= LoadLibraryA("psapi.dll");
330 trace("Could not load psapi.dll\n");
334 if(InitFunctionPtrs(hpsapi
))
336 DWORD pid
= GetCurrentProcessId();
338 w32_suc(hpSR
= OpenProcess(STANDARD_RIGHTS_REQUIRED
, FALSE
, pid
));
339 w32_suc(hpQI
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, pid
));
340 w32_suc(hpVR
= OpenProcess(PROCESS_VM_READ
, FALSE
, pid
));
341 w32_suc(hpQV
= OpenProcess(PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, pid
));
342 w32_suc(hpAA
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, pid
));
343 if(hpSR
&& hpQI
&& hpVR
&& hpQV
&& hpAA
)
345 test_EnumProcesses();
346 test_EnumProcessModules();
347 test_GetModuleInformation();
348 test_GetProcessMemoryInfo();
349 todo_wine
test_GetMappedFileName();
350 test_GetProcessImageFileName();
351 test_GetModuleFileNameEx();
352 test_GetModuleBaseName();