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
24 #include "wine/test.h"
28 #define PSAPI_GET_PROC(func) \
29 p ## func = (void*)GetProcAddress(hpsapi, #func); \
31 ok(0, "GetProcAddress(%s) failed\n", #func); \
32 FreeLibrary(hpsapi); \
36 /* All PSAPI functions return non-zero and call SetLastError()
37 * on failure so we can use some macros for convenience */
40 (SetLastError(0xdeadbeef), \
42 ? (ok(1, "succeeded\n"), 1) \
43 : GetLastError() == 0xdeadbeef \
44 ? (ok(0, "failed without error code\n"), 0) \
45 : (ok(0, "failed with %d\n", GetLastError()), 0))
47 #define w32_err(x, e) \
48 (SetLastError(0xdeadbeef), \
50 ? (ok(0, "expected error=%d but succeeded\n", e), 0) \
51 : GetLastError() == e \
52 ? (ok(1, "failed with %d\n", e), 1) \
53 : GetLastError() == 0xdeadbeef \
54 ? (ok(0, "failed without error code\n"), 0) \
55 : (ok(0, "expected error=%d but failed with %d\n", \
56 e, GetLastError()), 0))
58 static BOOL (WINAPI
*pEmptyWorkingSet
)(HANDLE
);
59 static BOOL (WINAPI
*pEnumProcesses
)(DWORD
*, DWORD
, DWORD
*);
60 static BOOL (WINAPI
*pEnumProcessModules
)(HANDLE
, HMODULE
*, DWORD
, LPDWORD
);
61 static DWORD (WINAPI
*pGetModuleBaseNameA
)(HANDLE
, HMODULE
, LPSTR
, DWORD
);
62 static DWORD (WINAPI
*pGetModuleFileNameExA
)(HANDLE
, HMODULE
, LPSTR
, DWORD
);
63 static BOOL (WINAPI
*pGetModuleInformation
)(HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
);
64 static DWORD (WINAPI
*pGetMappedFileNameA
)(HANDLE
, LPVOID
, LPSTR
, DWORD
);
65 static DWORD (WINAPI
*pGetProcessImageFileNameA
)(HANDLE
, LPSTR
, DWORD
);
66 static BOOL (WINAPI
*pGetProcessMemoryInfo
)(HANDLE
, PPROCESS_MEMORY_COUNTERS
, DWORD
);
67 static BOOL (WINAPI
*pGetWsChanges
)(HANDLE
, PPSAPI_WS_WATCH_INFORMATION
, DWORD
);
68 static BOOL (WINAPI
*pInitializeProcessForWsWatch
)(HANDLE
);
69 static BOOL (WINAPI
*pQueryWorkingSet
)(HANDLE
, PVOID
, DWORD
);
71 static BOOL
InitFunctionPtrs(HMODULE hpsapi
)
73 PSAPI_GET_PROC(EmptyWorkingSet
);
74 PSAPI_GET_PROC(EnumProcessModules
);
75 PSAPI_GET_PROC(EnumProcesses
);
76 PSAPI_GET_PROC(GetModuleBaseNameA
);
77 PSAPI_GET_PROC(GetModuleFileNameExA
);
78 PSAPI_GET_PROC(GetModuleInformation
);
79 PSAPI_GET_PROC(GetMappedFileNameA
);
80 PSAPI_GET_PROC(GetProcessMemoryInfo
);
81 PSAPI_GET_PROC(GetWsChanges
);
82 PSAPI_GET_PROC(InitializeProcessForWsWatch
);
83 PSAPI_GET_PROC(QueryWorkingSet
);
84 /* GetProcessImageFileName is not exported on NT4 */
85 pGetProcessImageFileNameA
=
86 (void *)GetProcAddress(hpsapi
, "GetProcessImageFileNameA");
90 static HANDLE hpSR
, hpQI
, hpVR
, hpQV
, hpAA
;
91 static const HANDLE hBad
= (HANDLE
)0xdeadbeef;
93 static void test_EnumProcesses(void)
95 DWORD pid
, cbUsed
= 0xdeadbeef;
97 if(w32_suc(pEnumProcesses(NULL
, 0, &cbUsed
)))
98 ok(cbUsed
== 0, "cbUsed=%d\n", cbUsed
);
99 if(w32_suc(pEnumProcesses(&pid
, 4, &cbUsed
)))
100 ok(cbUsed
== 4, "cbUsed=%d\n", cbUsed
);
103 static void test_EnumProcessModules(void)
105 HMODULE hMod
= GetModuleHandle(NULL
);
106 DWORD cbNeeded
= 0xdeadbeef;
108 w32_err(pEnumProcessModules(NULL
, NULL
, 0, &cbNeeded
), ERROR_INVALID_HANDLE
);
109 w32_err(pEnumProcessModules(hpQI
, NULL
, 0, &cbNeeded
), ERROR_ACCESS_DENIED
);
110 w32_suc(pEnumProcessModules(hpQV
, NULL
, 0, &cbNeeded
));
111 if(!w32_suc(pEnumProcessModules(hpQV
, &hMod
, sizeof(HMODULE
), &cbNeeded
)))
113 ok(cbNeeded
/ sizeof(HMODULE
) >= 3 && cbNeeded
/ sizeof(HMODULE
) <= 5 * sizeof(HMODULE
),
114 "cbNeeded=%d\n", cbNeeded
);
115 ok(hMod
== GetModuleHandle(NULL
),
116 "hMod=%p GetModuleHandle(NULL)=%p\n", hMod
, GetModuleHandle(NULL
));
119 static void test_GetModuleInformation(void)
121 HMODULE hMod
= GetModuleHandle(NULL
);
124 w32_err(pGetModuleInformation(NULL
, hMod
, &info
, sizeof(info
)), ERROR_INVALID_HANDLE
);
125 w32_err(pGetModuleInformation(hpQI
, hMod
, &info
, sizeof(info
)), ERROR_ACCESS_DENIED
);
126 w32_err(pGetModuleInformation(hpQV
, hBad
, &info
, sizeof(info
)), ERROR_INVALID_HANDLE
);
127 w32_err(pGetModuleInformation(hpQV
, hMod
, &info
, sizeof(info
)-1), ERROR_INSUFFICIENT_BUFFER
);
128 if(w32_suc(pGetModuleInformation(hpQV
, hMod
, &info
, sizeof(info
))))
129 ok(info
.lpBaseOfDll
== hMod
, "lpBaseOfDll=%p hMod=%p\n", info
.lpBaseOfDll
, hMod
);
132 static void test_GetProcessMemoryInfo(void)
134 PROCESS_MEMORY_COUNTERS pmc
;
136 w32_err(pGetProcessMemoryInfo(NULL
, &pmc
, sizeof(pmc
)), ERROR_INVALID_HANDLE
);
137 todo_wine
w32_err(pGetProcessMemoryInfo(hpSR
, &pmc
, sizeof(pmc
)), ERROR_ACCESS_DENIED
);
138 w32_err(pGetProcessMemoryInfo(hpQI
, &pmc
, sizeof(pmc
)-1), ERROR_INSUFFICIENT_BUFFER
);
139 w32_suc(pGetProcessMemoryInfo(hpQI
, &pmc
, sizeof(pmc
)));
142 static void test_GetMappedFileName(void)
144 HMODULE hMod
= GetModuleHandle(NULL
);
145 char szMapPath
[MAX_PATH
], szModPath
[MAX_PATH
], *szMapBaseName
;
148 w32_err(pGetMappedFileNameA(NULL
, hMod
, szMapPath
, sizeof(szMapPath
)), ERROR_INVALID_HANDLE
);
149 w32_err(pGetMappedFileNameA(hpSR
, hMod
, szMapPath
, sizeof(szMapPath
)), ERROR_ACCESS_DENIED
);
150 if(!w32_suc(ret
= pGetMappedFileNameA(hpQI
, hMod
, szMapPath
, sizeof(szMapPath
))))
152 ok(ret
== strlen(szMapPath
), "szMapPath=\"%s\" ret=%d\n", szMapPath
, ret
);
153 ok(szMapPath
[0] == '\\', "szMapPath=\"%s\"\n", szMapPath
);
154 szMapBaseName
= strrchr(szMapPath
, '\\'); /* That's close enough for us */
155 if(!szMapBaseName
|| !*szMapBaseName
)
157 ok(0, "szMapPath=\"%s\"\n", szMapPath
);
160 GetModuleFileNameA(NULL
, szModPath
, sizeof(szModPath
));
161 ok(!strcmp(strrchr(szModPath
, '\\'), szMapBaseName
),
162 "szModPath=\"%s\" szMapBaseName=\"%s\"\n", szModPath
, szMapBaseName
);
165 static void test_GetProcessImageFileName(void)
167 HMODULE hMod
= GetModuleHandle(NULL
);
168 char szImgPath
[MAX_PATH
], szMapPath
[MAX_PATH
];
171 if(pGetProcessImageFileNameA
== NULL
)
174 /* This function is available on WinXP+ only */
175 SetLastError(0xdeadbeef);
176 if(!pGetProcessImageFileNameA(hpQI
, szImgPath
, sizeof(szImgPath
)))
178 if(GetLastError() == ERROR_INVALID_FUNCTION
)
179 win_skip("GetProcessImageFileName not implemented\n");
180 else if(GetLastError() == 0xdeadbeef)
181 ok(0, "failed without error code\n");
183 ok(0, "failed with %d\n", GetLastError());
188 w32_err(pGetProcessImageFileNameA(NULL
, szImgPath
, sizeof(szImgPath
)), ERROR_INVALID_HANDLE
);
189 w32_err(pGetProcessImageFileNameA(hpSR
, szImgPath
, sizeof(szImgPath
)), ERROR_ACCESS_DENIED
);
190 w32_err(pGetProcessImageFileNameA(hpQI
, szImgPath
, 0), ERROR_INSUFFICIENT_BUFFER
);
191 if(!w32_suc(ret
= pGetProcessImageFileNameA(hpQI
, szImgPath
, sizeof(szImgPath
))) ||
192 !w32_suc(pGetMappedFileNameA(hpQV
, hMod
, szMapPath
, sizeof(szMapPath
))))
194 /* Windows returns 2*strlen-1 */
195 ok(ret
>= strlen(szImgPath
), "szImgPath=\"%s\" ret=%d\n", szImgPath
, ret
);
196 ok(!strcmp(szImgPath
, szMapPath
),
197 "szImgPath=\"%s\" szMapPath=\"%s\"\n", szImgPath
, szMapPath
);
200 static void test_GetModuleFileNameEx(void)
202 HMODULE hMod
= GetModuleHandle(NULL
);
203 char szModExPath
[MAX_PATH
+1], szModPath
[MAX_PATH
+1];
206 w32_err(pGetModuleFileNameExA(NULL
, hMod
, szModExPath
, sizeof(szModExPath
)), ERROR_INVALID_HANDLE
);
207 w32_err(pGetModuleFileNameExA(hpQI
, hMod
, szModExPath
, sizeof(szModExPath
)), ERROR_ACCESS_DENIED
);
208 w32_err(pGetModuleFileNameExA(hpQV
, hBad
, szModExPath
, sizeof(szModExPath
)), ERROR_INVALID_HANDLE
);
209 if(!w32_suc(ret
= pGetModuleFileNameExA(hpQV
, NULL
, szModExPath
, sizeof(szModExPath
))))
211 ok(ret
== strlen(szModExPath
), "szModExPath=\"%s\" ret=%d\n", szModExPath
, ret
);
212 GetModuleFileNameA(NULL
, szModPath
, sizeof(szModPath
));
213 ok(!strncmp(szModExPath
, szModPath
, MAX_PATH
),
214 "szModExPath=\"%s\" szModPath=\"%s\"\n", szModExPath
, szModPath
);
217 static void test_GetModuleBaseName(void)
219 HMODULE hMod
= GetModuleHandle(NULL
);
220 char szModPath
[MAX_PATH
], szModBaseName
[MAX_PATH
];
223 w32_err(pGetModuleBaseNameA(NULL
, hMod
, szModBaseName
, sizeof(szModBaseName
)), ERROR_INVALID_HANDLE
);
224 w32_err(pGetModuleBaseNameA(hpQI
, hMod
, szModBaseName
, sizeof(szModBaseName
)), ERROR_ACCESS_DENIED
);
225 w32_err(pGetModuleBaseNameA(hpQV
, hBad
, szModBaseName
, sizeof(szModBaseName
)), ERROR_INVALID_HANDLE
);
226 if(!w32_suc(ret
= pGetModuleBaseNameA(hpQV
, NULL
, szModBaseName
, sizeof(szModBaseName
))))
228 ok(ret
== strlen(szModBaseName
), "szModBaseName=\"%s\" ret=%d\n", szModBaseName
, ret
);
229 GetModuleFileNameA(NULL
, szModPath
, sizeof(szModPath
));
230 ok(!strcmp(strrchr(szModPath
, '\\') + 1, szModBaseName
),
231 "szModPath=\"%s\" szModBaseName=\"%s\"\n", szModPath
, szModBaseName
);
234 static void test_ws_functions(void)
236 PSAPI_WS_WATCH_INFORMATION wswi
[4096];
237 ULONG_PTR pages
[4096];
241 todo_wine
w32_err(pEmptyWorkingSet(NULL
), ERROR_INVALID_HANDLE
);
242 todo_wine
w32_err(pEmptyWorkingSet(hpSR
), ERROR_ACCESS_DENIED
);
243 w32_suc(pEmptyWorkingSet(hpAA
));
245 todo_wine
w32_err(pInitializeProcessForWsWatch(NULL
), ERROR_INVALID_HANDLE
);
246 w32_suc(pInitializeProcessForWsWatch(hpAA
));
248 if(!w32_suc(addr
= VirtualAlloc(NULL
, 1, MEM_COMMIT
, PAGE_READWRITE
)))
251 if(!VirtualLock(addr
, 1))
253 trace("locking failed (error=%d) - skipping test\n", GetLastError());
257 todo_wine
if(w32_suc(pQueryWorkingSet(hpQI
, pages
, 4096 * sizeof(ULONG_PTR
))))
259 for(i
= 0; i
< pages
[0]; i
++)
260 if((pages
[i
+1] & ~0xfffL
) == (ULONG_PTR
)addr
)
262 ok(1, "QueryWorkingSet found our page\n");
266 ok(0, "QueryWorkingSet didn't find our page\n");
270 todo_wine
if(w32_suc(pGetWsChanges(hpQI
, wswi
, sizeof(wswi
))))
272 for(i
= 0; wswi
[i
].FaultingVa
; i
++)
273 if(((ULONG_PTR
)wswi
[i
].FaultingVa
& ~0xfffL
) == (ULONG_PTR
)addr
)
275 ok(1, "GetWsChanges found our page\n");
279 ok(0, "GetWsChanges didn't find our page\n");
283 VirtualFree(addr
, 0, MEM_RELEASE
);
286 START_TEST(psapi_main
)
288 HMODULE hpsapi
= LoadLibraryA("psapi.dll");
292 trace("Could not load psapi.dll\n");
296 if(InitFunctionPtrs(hpsapi
))
298 DWORD pid
= GetCurrentProcessId();
300 w32_suc(hpSR
= OpenProcess(STANDARD_RIGHTS_REQUIRED
, FALSE
, pid
));
301 w32_suc(hpQI
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, pid
));
302 w32_suc(hpVR
= OpenProcess(PROCESS_VM_READ
, FALSE
, pid
));
303 w32_suc(hpQV
= OpenProcess(PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, pid
));
304 w32_suc(hpAA
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, pid
));
305 if(hpSR
&& hpQI
&& hpVR
&& hpQV
&& hpAA
)
307 test_EnumProcesses();
308 test_EnumProcessModules();
309 test_GetModuleInformation();
310 test_GetProcessMemoryInfo();
311 todo_wine
test_GetMappedFileName();
312 todo_wine
test_GetProcessImageFileName();
313 test_GetModuleFileNameEx();
314 test_GetModuleBaseName();