1c2c66affSColin Finck /*
2c2c66affSColin Finck * Unit test suite for PSAPI
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright (C) 2005 Felix Nawothnig
5c2c66affSColin Finck * Copyright (C) 2012 Dmitry Timoshkov
6c2c66affSColin Finck *
7c2c66affSColin Finck * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck * License as published by the Free Software Foundation; either
10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck *
12c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15c2c66affSColin Finck * Lesser General Public License for more details.
16c2c66affSColin Finck *
17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck */
21c2c66affSColin Finck
22c2c66affSColin Finck #include <stdarg.h>
23c2c66affSColin Finck
24c2c66affSColin Finck #include "ntstatus.h"
25c2c66affSColin Finck #define WIN32_NO_STATUS
26c2c66affSColin Finck
27c2c66affSColin Finck #include "windef.h"
28c2c66affSColin Finck #include "winbase.h"
29c2c66affSColin Finck #include "winreg.h"
30c2c66affSColin Finck #include "winnt.h"
31c2c66affSColin Finck #include "wine/winternl.h"
32c2c66affSColin Finck #include "winnls.h"
33*4567e13eSAmine Khaldi #include "winuser.h"
34*4567e13eSAmine Khaldi #define PSAPI_VERSION 1
35c2c66affSColin Finck #include "psapi.h"
36c2c66affSColin Finck #include "wine/test.h"
37c2c66affSColin Finck
38c2c66affSColin Finck static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
39c2c66affSColin Finck static NTSTATUS (WINAPI *pNtQueryVirtualMemory)(HANDLE, LPCVOID, ULONG, PVOID, SIZE_T, SIZE_T *);
40*4567e13eSAmine Khaldi static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *);
41*4567e13eSAmine Khaldi static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(void **);
42*4567e13eSAmine Khaldi static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(void *);
43c2c66affSColin Finck
44*4567e13eSAmine Khaldi static BOOL wow64;
45*4567e13eSAmine Khaldi
init_func_ptrs(void)46*4567e13eSAmine Khaldi static BOOL init_func_ptrs(void)
47c2c66affSColin Finck {
48c2c66affSColin Finck pNtQuerySystemInformation = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");
49c2c66affSColin Finck pNtQueryVirtualMemory = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryVirtualMemory");
50*4567e13eSAmine Khaldi pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
51*4567e13eSAmine Khaldi pWow64DisableWow64FsRedirection = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "Wow64DisableWow64FsRedirection");
52*4567e13eSAmine Khaldi pWow64RevertWow64FsRedirection = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "Wow64RevertWow64FsRedirection");
53c2c66affSColin Finck return TRUE;
54c2c66affSColin Finck }
55c2c66affSColin Finck
56*4567e13eSAmine Khaldi static HANDLE hpSR, hpQI, hpVR, hpQV;
57c2c66affSColin Finck static const HANDLE hBad = (HANDLE)0xdeadbeef;
58c2c66affSColin Finck
test_EnumProcesses(void)59c2c66affSColin Finck static void test_EnumProcesses(void)
60c2c66affSColin Finck {
61c2c66affSColin Finck DWORD pid, ret, cbUsed = 0xdeadbeef;
62c2c66affSColin Finck
63c2c66affSColin Finck SetLastError(0xdeadbeef);
64*4567e13eSAmine Khaldi ret = EnumProcesses(NULL, 0, &cbUsed);
65c2c66affSColin Finck ok(ret == 1, "failed with %d\n", GetLastError());
66c2c66affSColin Finck ok(cbUsed == 0, "cbUsed=%d\n", cbUsed);
67c2c66affSColin Finck
68c2c66affSColin Finck SetLastError(0xdeadbeef);
69*4567e13eSAmine Khaldi ret = EnumProcesses(&pid, 4, &cbUsed);
70c2c66affSColin Finck ok(ret == 1, "failed with %d\n", GetLastError());
71c2c66affSColin Finck ok(cbUsed == 4, "cbUsed=%d\n", cbUsed);
72c2c66affSColin Finck }
73c2c66affSColin Finck
test_EnumProcessModules(void)74c2c66affSColin Finck static void test_EnumProcessModules(void)
75c2c66affSColin Finck {
76*4567e13eSAmine Khaldi char buffer[200] = "C:\\windows\\system32\\notepad.exe";
77*4567e13eSAmine Khaldi PROCESS_INFORMATION pi = {0};
78*4567e13eSAmine Khaldi STARTUPINFOA si = {0};
79*4567e13eSAmine Khaldi void *cookie;
804a7f3bdbSAmine Khaldi HMODULE hMod;
81c2c66affSColin Finck DWORD ret, cbNeeded = 0xdeadbeef;
82c2c66affSColin Finck
83c2c66affSColin Finck SetLastError(0xdeadbeef);
84*4567e13eSAmine Khaldi EnumProcessModules(NULL, NULL, 0, &cbNeeded);
85c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
86c2c66affSColin Finck
87c2c66affSColin Finck SetLastError(0xdeadbeef);
88*4567e13eSAmine Khaldi EnumProcessModules(hpQI, NULL, 0, &cbNeeded);
89c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
90c2c66affSColin Finck
91c2c66affSColin Finck SetLastError(0xdeadbeef);
924a7f3bdbSAmine Khaldi hMod = (void *)0xdeadbeef;
93*4567e13eSAmine Khaldi ret = EnumProcessModules(hpQI, &hMod, sizeof(HMODULE), NULL);
94c2c66affSColin Finck ok(!ret, "succeeded\n");
95c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
96c2c66affSColin Finck
97c2c66affSColin Finck SetLastError(0xdeadbeef);
984a7f3bdbSAmine Khaldi hMod = (void *)0xdeadbeef;
99*4567e13eSAmine Khaldi ret = EnumProcessModules(hpQV, &hMod, sizeof(HMODULE), NULL);
100c2c66affSColin Finck ok(!ret, "succeeded\n");
101c2c66affSColin Finck ok(GetLastError() == ERROR_NOACCESS, "expected error=ERROR_NOACCESS but got %d\n", GetLastError());
1020623a6f8SAmine Khaldi ok(hMod == GetModuleHandleA(NULL),
1034a7f3bdbSAmine Khaldi "hMod=%p GetModuleHandleA(NULL)=%p\n", hMod, GetModuleHandleA(NULL));
104c2c66affSColin Finck
105c2c66affSColin Finck SetLastError(0xdeadbeef);
106*4567e13eSAmine Khaldi ret = EnumProcessModules(hpQV, NULL, 0, &cbNeeded);
107c2c66affSColin Finck ok(ret == 1, "failed with %d\n", GetLastError());
108c2c66affSColin Finck
109c2c66affSColin Finck SetLastError(0xdeadbeef);
110*4567e13eSAmine Khaldi ret = EnumProcessModules(hpQV, NULL, sizeof(HMODULE), &cbNeeded);
111c2c66affSColin Finck ok(!ret, "succeeded\n");
112c2c66affSColin Finck ok(GetLastError() == ERROR_NOACCESS, "expected error=ERROR_NOACCESS but got %d\n", GetLastError());
113c2c66affSColin Finck
114c2c66affSColin Finck SetLastError(0xdeadbeef);
1154a7f3bdbSAmine Khaldi hMod = (void *)0xdeadbeef;
116*4567e13eSAmine Khaldi ret = EnumProcessModules(hpQV, &hMod, sizeof(HMODULE), &cbNeeded);
1174a7f3bdbSAmine Khaldi ok(ret == 1, "got %d, failed with %d\n", ret, GetLastError());
118c2c66affSColin Finck ok(hMod == GetModuleHandleA(NULL),
119c2c66affSColin Finck "hMod=%p GetModuleHandleA(NULL)=%p\n", hMod, GetModuleHandleA(NULL));
120c2c66affSColin Finck ok(cbNeeded % sizeof(hMod) == 0, "not a multiple of sizeof(HMODULE) cbNeeded=%d\n", cbNeeded);
121*4567e13eSAmine Khaldi
122*4567e13eSAmine Khaldi ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
123*4567e13eSAmine Khaldi ok(ret, "CreateProcess failed: %u\n", GetLastError());
124*4567e13eSAmine Khaldi
125*4567e13eSAmine Khaldi ret = WaitForInputIdle(pi.hProcess, 1000);
126*4567e13eSAmine Khaldi ok(!ret, "wait timed out\n");
127*4567e13eSAmine Khaldi
128*4567e13eSAmine Khaldi SetLastError(0xdeadbeef);
129*4567e13eSAmine Khaldi hMod = NULL;
130*4567e13eSAmine Khaldi ret = EnumProcessModules(pi.hProcess, &hMod, sizeof(HMODULE), &cbNeeded);
131*4567e13eSAmine Khaldi ok(ret == 1, "got %d, error %u\n", ret, GetLastError());
132*4567e13eSAmine Khaldi ok(!!hMod, "expected non-NULL module\n");
133*4567e13eSAmine Khaldi ok(cbNeeded % sizeof(hMod) == 0, "got %u\n", cbNeeded);
134*4567e13eSAmine Khaldi
135*4567e13eSAmine Khaldi TerminateProcess(pi.hProcess, 0);
136*4567e13eSAmine Khaldi
137*4567e13eSAmine Khaldi if (sizeof(void *) == 8)
138*4567e13eSAmine Khaldi {
139*4567e13eSAmine Khaldi MODULEINFO info;
140*4567e13eSAmine Khaldi char name[40];
141*4567e13eSAmine Khaldi
142*4567e13eSAmine Khaldi strcpy(buffer, "C:\\windows\\syswow64\\notepad.exe");
143*4567e13eSAmine Khaldi ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
144*4567e13eSAmine Khaldi ok(ret, "CreateProcess failed: %u\n", GetLastError());
145*4567e13eSAmine Khaldi
146*4567e13eSAmine Khaldi ret = WaitForInputIdle(pi.hProcess, 1000);
147*4567e13eSAmine Khaldi ok(!ret, "wait timed out\n");
148*4567e13eSAmine Khaldi
149*4567e13eSAmine Khaldi SetLastError(0xdeadbeef);
150*4567e13eSAmine Khaldi hMod = NULL;
151*4567e13eSAmine Khaldi ret = EnumProcessModules(pi.hProcess, &hMod, sizeof(HMODULE), &cbNeeded);
152*4567e13eSAmine Khaldi ok(ret == 1, "got %d, error %u\n", ret, GetLastError());
153*4567e13eSAmine Khaldi ok(!!hMod, "expected non-NULL module\n");
154*4567e13eSAmine Khaldi ok(cbNeeded % sizeof(hMod) == 0, "got %u\n", cbNeeded);
155*4567e13eSAmine Khaldi
156*4567e13eSAmine Khaldi ret = GetModuleBaseNameA(pi.hProcess, hMod, name, sizeof(name));
157*4567e13eSAmine Khaldi ok(ret, "got error %u\n", GetLastError());
158*4567e13eSAmine Khaldi ok(!strcmp(name, "notepad.exe"), "got %s\n", name);
159*4567e13eSAmine Khaldi
160*4567e13eSAmine Khaldi ret = GetModuleFileNameExA(pi.hProcess, hMod, name, sizeof(name));
161*4567e13eSAmine Khaldi ok(ret, "got error %u\n", GetLastError());
162*4567e13eSAmine Khaldi todo_wine
163*4567e13eSAmine Khaldi ok(!strcmp(name, buffer), "got %s\n", name);
164*4567e13eSAmine Khaldi
165*4567e13eSAmine Khaldi ret = GetModuleInformation(pi.hProcess, hMod, &info, sizeof(info));
166*4567e13eSAmine Khaldi ok(ret, "got error %u\n", GetLastError());
167*4567e13eSAmine Khaldi ok(info.lpBaseOfDll == hMod, "expected %p, got %p\n", hMod, info.lpBaseOfDll);
168*4567e13eSAmine Khaldi ok(info.SizeOfImage, "image size was 0\n");
169*4567e13eSAmine Khaldi ok(info.EntryPoint >= info.lpBaseOfDll, "got entry point %p\n", info.EntryPoint);
170*4567e13eSAmine Khaldi
171*4567e13eSAmine Khaldi TerminateProcess(pi.hProcess, 0);
172*4567e13eSAmine Khaldi }
173*4567e13eSAmine Khaldi else if (wow64)
174*4567e13eSAmine Khaldi {
175*4567e13eSAmine Khaldi pWow64DisableWow64FsRedirection(&cookie);
176*4567e13eSAmine Khaldi ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
177*4567e13eSAmine Khaldi pWow64RevertWow64FsRedirection(cookie);
178*4567e13eSAmine Khaldi ok(ret, "CreateProcess failed: %u\n", GetLastError());
179*4567e13eSAmine Khaldi
180*4567e13eSAmine Khaldi ret = WaitForInputIdle(pi.hProcess, 1000);
181*4567e13eSAmine Khaldi ok(!ret, "wait timed out\n");
182*4567e13eSAmine Khaldi
183*4567e13eSAmine Khaldi SetLastError(0xdeadbeef);
184*4567e13eSAmine Khaldi ret = EnumProcessModules(pi.hProcess, &hMod, sizeof(HMODULE), &cbNeeded);
185*4567e13eSAmine Khaldi ok(!ret, "got %d\n", ret);
186*4567e13eSAmine Khaldi todo_wine
187*4567e13eSAmine Khaldi ok(GetLastError() == ERROR_PARTIAL_COPY, "got error %u\n", GetLastError());
188*4567e13eSAmine Khaldi
189*4567e13eSAmine Khaldi TerminateProcess(pi.hProcess, 0);
190*4567e13eSAmine Khaldi }
191c2c66affSColin Finck }
192c2c66affSColin Finck
test_GetModuleInformation(void)193c2c66affSColin Finck static void test_GetModuleInformation(void)
194c2c66affSColin Finck {
195c2c66affSColin Finck HMODULE hMod = GetModuleHandleA(NULL);
1960623a6f8SAmine Khaldi DWORD *tmp, counter = 0;
197c2c66affSColin Finck MODULEINFO info;
198c2c66affSColin Finck DWORD ret;
199c2c66affSColin Finck
200c2c66affSColin Finck SetLastError(0xdeadbeef);
201*4567e13eSAmine Khaldi GetModuleInformation(NULL, hMod, &info, sizeof(info));
202c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
203c2c66affSColin Finck
204c2c66affSColin Finck SetLastError(0xdeadbeef);
205*4567e13eSAmine Khaldi GetModuleInformation(hpQI, hMod, &info, sizeof(info));
206c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
207c2c66affSColin Finck
208c2c66affSColin Finck SetLastError(0xdeadbeef);
209*4567e13eSAmine Khaldi GetModuleInformation(hpQV, hBad, &info, sizeof(info));
210c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
211c2c66affSColin Finck
212c2c66affSColin Finck SetLastError(0xdeadbeef);
213*4567e13eSAmine Khaldi GetModuleInformation(hpQV, hMod, &info, sizeof(info)-1);
214c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected error=ERROR_INSUFFICIENT_BUFFER but got %d\n", GetLastError());
215c2c66affSColin Finck
216*4567e13eSAmine Khaldi ret = GetModuleInformation(hpQV, hMod, &info, sizeof(info));
217c2c66affSColin Finck ok(ret == 1, "failed with %d\n", GetLastError());
218c2c66affSColin Finck ok(info.lpBaseOfDll == hMod, "lpBaseOfDll=%p hMod=%p\n", info.lpBaseOfDll, hMod);
2190623a6f8SAmine Khaldi
2200623a6f8SAmine Khaldi hMod = LoadLibraryA("shell32.dll");
2210623a6f8SAmine Khaldi ok(hMod != NULL, "Failed to load shell32.dll, error: %u\n", GetLastError());
2220623a6f8SAmine Khaldi
223*4567e13eSAmine Khaldi ret = GetModuleInformation(hpQV, hMod, &info, sizeof(info));
2240623a6f8SAmine Khaldi ok(ret == 1, "failed with %d\n", GetLastError());
2250623a6f8SAmine Khaldi info.SizeOfImage /= sizeof(DWORD);
2260623a6f8SAmine Khaldi for (tmp = (DWORD *)hMod; info.SizeOfImage; info.SizeOfImage--)
2270623a6f8SAmine Khaldi counter ^= *tmp++;
2280623a6f8SAmine Khaldi trace("xor of shell32: %08x\n", counter);
2290623a6f8SAmine Khaldi
2300623a6f8SAmine Khaldi FreeLibrary(hMod);
231c2c66affSColin Finck }
232c2c66affSColin Finck
check_with_margin(SIZE_T perf,SIZE_T sysperf,int margin)233c2c66affSColin Finck static BOOL check_with_margin(SIZE_T perf, SIZE_T sysperf, int margin)
234c2c66affSColin Finck {
235c2c66affSColin Finck return (perf >= max(sysperf, margin) - margin && perf <= sysperf + margin);
236c2c66affSColin Finck }
237c2c66affSColin Finck
test_GetPerformanceInfo(void)238c2c66affSColin Finck static void test_GetPerformanceInfo(void)
239c2c66affSColin Finck {
240c2c66affSColin Finck PERFORMANCE_INFORMATION info;
241c2c66affSColin Finck NTSTATUS status;
242c2c66affSColin Finck DWORD size;
243c2c66affSColin Finck BOOL ret;
244c2c66affSColin Finck
245c2c66affSColin Finck SetLastError(0xdeadbeef);
246*4567e13eSAmine Khaldi ret = GetPerformanceInfo(&info, sizeof(info)-1);
247c2c66affSColin Finck ok(!ret, "GetPerformanceInfo unexpectedly succeeded\n");
248c2c66affSColin Finck ok(GetLastError() == ERROR_BAD_LENGTH, "expected error=ERROR_BAD_LENGTH but got %d\n", GetLastError());
249c2c66affSColin Finck
250c2c66affSColin Finck if (!pNtQuerySystemInformation)
251c2c66affSColin Finck win_skip("NtQuerySystemInformation not found, skipping tests\n");
252c2c66affSColin Finck else
253c2c66affSColin Finck {
254c2c66affSColin Finck char performance_buffer[sizeof(SYSTEM_PERFORMANCE_INFORMATION) + 16]; /* larger on w2k8/win7 */
255c2c66affSColin Finck SYSTEM_PERFORMANCE_INFORMATION *sys_performance_info = (SYSTEM_PERFORMANCE_INFORMATION *)performance_buffer;
256c2c66affSColin Finck SYSTEM_PROCESS_INFORMATION *sys_process_info = NULL, *spi;
257c2c66affSColin Finck SYSTEM_BASIC_INFORMATION sys_basic_info;
258c2c66affSColin Finck DWORD process_count, handle_count, thread_count;
259c2c66affSColin Finck
260c2c66affSColin Finck /* compare with values from SYSTEM_PERFORMANCE_INFORMATION */
261c2c66affSColin Finck size = 0;
262c2c66affSColin Finck status = pNtQuerySystemInformation(SystemPerformanceInformation, sys_performance_info, sizeof(performance_buffer), &size);
263c2c66affSColin Finck ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
264c2c66affSColin Finck ok(size >= sizeof(SYSTEM_PERFORMANCE_INFORMATION), "incorrect length %d\n", size);
265c2c66affSColin Finck
266*4567e13eSAmine Khaldi SetLastError(0xdeadbeef);
267*4567e13eSAmine Khaldi ret = GetPerformanceInfo(&info, sizeof(info));
268*4567e13eSAmine Khaldi ok(ret, "GetPerformanceInfo failed with %d\n", GetLastError());
269*4567e13eSAmine Khaldi ok(info.cb == sizeof(PERFORMANCE_INFORMATION), "got %d\n", info.cb);
270c2c66affSColin Finck
271c2c66affSColin Finck ok(check_with_margin(info.CommitTotal, sys_performance_info->TotalCommittedPages, 288),
272c2c66affSColin Finck "expected approximately %ld but got %d\n", info.CommitTotal, sys_performance_info->TotalCommittedPages);
273c2c66affSColin Finck
274c2c66affSColin Finck ok(check_with_margin(info.CommitLimit, sys_performance_info->TotalCommitLimit, 32),
275c2c66affSColin Finck "expected approximately %ld but got %d\n", info.CommitLimit, sys_performance_info->TotalCommitLimit);
276c2c66affSColin Finck
277c2c66affSColin Finck ok(check_with_margin(info.CommitPeak, sys_performance_info->PeakCommitment, 32),
278c2c66affSColin Finck "expected approximately %ld but got %d\n", info.CommitPeak, sys_performance_info->PeakCommitment);
279c2c66affSColin Finck
2804a7f3bdbSAmine Khaldi ok(check_with_margin(info.PhysicalAvailable, sys_performance_info->AvailablePages, 512),
281c2c66affSColin Finck "expected approximately %ld but got %d\n", info.PhysicalAvailable, sys_performance_info->AvailablePages);
282c2c66affSColin Finck
283c2c66affSColin Finck /* TODO: info.SystemCache not checked yet - to which field(s) does this value correspond to? */
284c2c66affSColin Finck
2854a7f3bdbSAmine Khaldi ok(check_with_margin(info.KernelTotal, sys_performance_info->PagedPoolUsage + sys_performance_info->NonPagedPoolUsage, 256),
286c2c66affSColin Finck "expected approximately %ld but got %d\n", info.KernelTotal,
287c2c66affSColin Finck sys_performance_info->PagedPoolUsage + sys_performance_info->NonPagedPoolUsage);
288c2c66affSColin Finck
2894a7f3bdbSAmine Khaldi ok(check_with_margin(info.KernelPaged, sys_performance_info->PagedPoolUsage, 256),
290c2c66affSColin Finck "expected approximately %ld but got %d\n", info.KernelPaged, sys_performance_info->PagedPoolUsage);
291c2c66affSColin Finck
2924a7f3bdbSAmine Khaldi ok(check_with_margin(info.KernelNonpaged, sys_performance_info->NonPagedPoolUsage, 16),
293c2c66affSColin Finck "expected approximately %ld but got %d\n", info.KernelNonpaged, sys_performance_info->NonPagedPoolUsage);
294c2c66affSColin Finck
295c2c66affSColin Finck /* compare with values from SYSTEM_BASIC_INFORMATION */
296c2c66affSColin Finck size = 0;
297c2c66affSColin Finck status = pNtQuerySystemInformation(SystemBasicInformation, &sys_basic_info, sizeof(sys_basic_info), &size);
298c2c66affSColin Finck ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
299c2c66affSColin Finck ok(size >= sizeof(SYSTEM_BASIC_INFORMATION), "incorrect length %d\n", size);
300c2c66affSColin Finck
301c2c66affSColin Finck ok(info.PhysicalTotal == sys_basic_info.MmNumberOfPhysicalPages,
302c2c66affSColin Finck "expected info.PhysicalTotal=%u but got %u\n",
303c2c66affSColin Finck sys_basic_info.MmNumberOfPhysicalPages, (ULONG)info.PhysicalTotal);
304c2c66affSColin Finck
305c2c66affSColin Finck ok(info.PageSize == sys_basic_info.PageSize,
306c2c66affSColin Finck "expected info.PageSize=%u but got %u\n",
307c2c66affSColin Finck sys_basic_info.PageSize, (ULONG)info.PageSize);
308c2c66affSColin Finck
309c2c66affSColin Finck /* compare with values from SYSTEM_PROCESS_INFORMATION */
310c2c66affSColin Finck size = 0;
311c2c66affSColin Finck status = pNtQuerySystemInformation(SystemProcessInformation, NULL, 0, &size);
312c2c66affSColin Finck ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
313c2c66affSColin Finck ok(size > 0, "incorrect length %d\n", size);
314c2c66affSColin Finck while (status == STATUS_INFO_LENGTH_MISMATCH)
315c2c66affSColin Finck {
316c2c66affSColin Finck sys_process_info = HeapAlloc(GetProcessHeap(), 0, size);
317c2c66affSColin Finck ok(sys_process_info != NULL, "failed to allocate memory\n");
318c2c66affSColin Finck status = pNtQuerySystemInformation(SystemProcessInformation, sys_process_info, size, &size);
319c2c66affSColin Finck if (status == STATUS_SUCCESS) break;
320c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sys_process_info);
321c2c66affSColin Finck }
322c2c66affSColin Finck ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
323c2c66affSColin Finck
324c2c66affSColin Finck process_count = handle_count = thread_count = 0;
325c2c66affSColin Finck for (spi = sys_process_info;; spi = (SYSTEM_PROCESS_INFORMATION *)(((char *)spi) + spi->NextEntryOffset))
326c2c66affSColin Finck {
327c2c66affSColin Finck process_count++;
328c2c66affSColin Finck handle_count += spi->HandleCount;
329c2c66affSColin Finck thread_count += spi->dwThreadCount;
330c2c66affSColin Finck if (spi->NextEntryOffset == 0) break;
331c2c66affSColin Finck }
332c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sys_process_info);
333c2c66affSColin Finck
334*4567e13eSAmine Khaldi ok(check_with_margin(info.HandleCount, handle_count, 256),
335c2c66affSColin Finck "expected approximately %d but got %d\n", info.HandleCount, handle_count);
336c2c66affSColin Finck
337c2c66affSColin Finck ok(check_with_margin(info.ProcessCount, process_count, 4),
338c2c66affSColin Finck "expected approximately %d but got %d\n", info.ProcessCount, process_count);
339c2c66affSColin Finck
340c2c66affSColin Finck ok(check_with_margin(info.ThreadCount, thread_count, 4),
341c2c66affSColin Finck "expected approximately %d but got %d\n", info.ThreadCount, thread_count);
342c2c66affSColin Finck }
343c2c66affSColin Finck }
344c2c66affSColin Finck
345c2c66affSColin Finck
test_GetProcessMemoryInfo(void)346c2c66affSColin Finck static void test_GetProcessMemoryInfo(void)
347c2c66affSColin Finck {
348c2c66affSColin Finck PROCESS_MEMORY_COUNTERS pmc;
349c2c66affSColin Finck DWORD ret;
350c2c66affSColin Finck
351c2c66affSColin Finck SetLastError(0xdeadbeef);
352*4567e13eSAmine Khaldi ret = GetProcessMemoryInfo(NULL, &pmc, sizeof(pmc));
353c2c66affSColin Finck ok(!ret, "GetProcessMemoryInfo should fail\n");
354c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
355c2c66affSColin Finck
356c2c66affSColin Finck SetLastError(0xdeadbeef);
357*4567e13eSAmine Khaldi ret = GetProcessMemoryInfo(hpSR, &pmc, sizeof(pmc));
358c2c66affSColin Finck ok(!ret, "GetProcessMemoryInfo should fail\n");
359c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
360c2c66affSColin Finck
361c2c66affSColin Finck SetLastError(0xdeadbeef);
362*4567e13eSAmine Khaldi ret = GetProcessMemoryInfo(hpQI, &pmc, sizeof(pmc)-1);
363c2c66affSColin Finck ok(!ret, "GetProcessMemoryInfo should fail\n");
364c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected error=ERROR_INSUFFICIENT_BUFFER but got %d\n", GetLastError());
365c2c66affSColin Finck
366c2c66affSColin Finck SetLastError(0xdeadbeef);
367*4567e13eSAmine Khaldi ret = GetProcessMemoryInfo(hpQI, &pmc, sizeof(pmc));
368c2c66affSColin Finck ok(ret == 1, "failed with %d\n", GetLastError());
369c2c66affSColin Finck }
370c2c66affSColin Finck
nt_get_mapped_file_name(HANDLE process,LPVOID addr,LPWSTR name,DWORD len)371c2c66affSColin Finck static BOOL nt_get_mapped_file_name(HANDLE process, LPVOID addr, LPWSTR name, DWORD len)
372c2c66affSColin Finck {
373c2c66affSColin Finck MEMORY_SECTION_NAME *section_name;
374c2c66affSColin Finck WCHAR *buf;
375c2c66affSColin Finck SIZE_T buf_len, ret_len;
376c2c66affSColin Finck NTSTATUS status;
377c2c66affSColin Finck
378c2c66affSColin Finck if (!pNtQueryVirtualMemory) return FALSE;
379c2c66affSColin Finck
380c2c66affSColin Finck buf_len = len * sizeof(WCHAR) + sizeof(MEMORY_SECTION_NAME);
381c2c66affSColin Finck buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf_len);
382c2c66affSColin Finck
383c2c66affSColin Finck ret_len = 0xdeadbeef;
384c2c66affSColin Finck status = pNtQueryVirtualMemory(process, addr, MemorySectionName, buf, buf_len, &ret_len);
385c2c66affSColin Finck ok(!status, "NtQueryVirtualMemory error %x\n", status);
386c2c66affSColin Finck
387c2c66affSColin Finck section_name = (MEMORY_SECTION_NAME *)buf;
388c2c66affSColin Finck ok(ret_len == section_name->SectionFileName.MaximumLength + sizeof(*section_name), "got %lu, %u\n",
389c2c66affSColin Finck ret_len, section_name->SectionFileName.MaximumLength);
390c2c66affSColin Finck ok((char *)section_name->SectionFileName.Buffer == (char *)section_name + sizeof(*section_name), "got %p, %p\n",
391c2c66affSColin Finck section_name, section_name->SectionFileName.Buffer);
392c2c66affSColin Finck ok(section_name->SectionFileName.MaximumLength == section_name->SectionFileName.Length + sizeof(WCHAR), "got %u, %u\n",
393c2c66affSColin Finck section_name->SectionFileName.MaximumLength, section_name->SectionFileName.Length);
394c2c66affSColin Finck ok(section_name->SectionFileName.Length == lstrlenW(section_name->SectionFileName.Buffer) * sizeof(WCHAR), "got %u, %u\n",
395c2c66affSColin Finck section_name->SectionFileName.Length, lstrlenW(section_name->SectionFileName.Buffer));
396c2c66affSColin Finck
397c2c66affSColin Finck memcpy(name, section_name->SectionFileName.Buffer, section_name->SectionFileName.MaximumLength);
398c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, buf);
399c2c66affSColin Finck return TRUE;
400c2c66affSColin Finck }
401c2c66affSColin Finck
test_GetMappedFileName(void)402c2c66affSColin Finck static void test_GetMappedFileName(void)
403c2c66affSColin Finck {
404c2c66affSColin Finck HMODULE hMod = GetModuleHandleA(NULL);
405c2c66affSColin Finck char szMapPath[MAX_PATH], szModPath[MAX_PATH], *szMapBaseName;
406c2c66affSColin Finck DWORD ret;
407c2c66affSColin Finck char *base;
408c2c66affSColin Finck char temp_path[MAX_PATH], file_name[MAX_PATH], map_name[MAX_PATH], device_name[MAX_PATH], drive[3];
409c2c66affSColin Finck WCHAR map_nameW[MAX_PATH], nt_map_name[MAX_PATH];
410c2c66affSColin Finck HANDLE hfile, hmap;
4110623a6f8SAmine Khaldi HANDLE current_process;
4120623a6f8SAmine Khaldi
4130623a6f8SAmine Khaldi DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(),
4140623a6f8SAmine Khaldi GetCurrentProcess(), ¤t_process, 0, 0, DUPLICATE_SAME_ACCESS );
415c2c66affSColin Finck
416c2c66affSColin Finck SetLastError(0xdeadbeef);
417*4567e13eSAmine Khaldi ret = GetMappedFileNameA(NULL, hMod, szMapPath, sizeof(szMapPath));
418c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
419c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
420c2c66affSColin Finck
421c2c66affSColin Finck SetLastError(0xdeadbeef);
422*4567e13eSAmine Khaldi ret = GetMappedFileNameA(hpSR, hMod, szMapPath, sizeof(szMapPath));
423c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
424c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
425c2c66affSColin Finck
426c2c66affSColin Finck SetLastError( 0xdeadbeef );
427*4567e13eSAmine Khaldi ret = GetMappedFileNameA(hpQI, hMod, szMapPath, sizeof(szMapPath));
428c2c66affSColin Finck ok( ret || broken(GetLastError() == ERROR_UNEXP_NET_ERR), /* win2k */
429c2c66affSColin Finck "GetMappedFileNameA failed with error %u\n", GetLastError() );
430c2c66affSColin Finck if (ret)
431c2c66affSColin Finck {
432c2c66affSColin Finck ok(ret == strlen(szMapPath), "szMapPath=\"%s\" ret=%d\n", szMapPath, ret);
433c2c66affSColin Finck ok(szMapPath[0] == '\\', "szMapPath=\"%s\"\n", szMapPath);
434c2c66affSColin Finck szMapBaseName = strrchr(szMapPath, '\\'); /* That's close enough for us */
435c2c66affSColin Finck ok(szMapBaseName && *szMapBaseName, "szMapPath=\"%s\"\n", szMapPath);
436c2c66affSColin Finck if (szMapBaseName)
437c2c66affSColin Finck {
438c2c66affSColin Finck GetModuleFileNameA(NULL, szModPath, sizeof(szModPath));
439c2c66affSColin Finck ok(!strcmp(strrchr(szModPath, '\\'), szMapBaseName),
440c2c66affSColin Finck "szModPath=\"%s\" szMapBaseName=\"%s\"\n", szModPath, szMapBaseName);
441c2c66affSColin Finck }
442c2c66affSColin Finck }
443c2c66affSColin Finck
444c2c66affSColin Finck GetTempPathA(MAX_PATH, temp_path);
445c2c66affSColin Finck GetTempFileNameA(temp_path, "map", 0, file_name);
446c2c66affSColin Finck
447c2c66affSColin Finck drive[0] = file_name[0];
448c2c66affSColin Finck drive[1] = ':';
449c2c66affSColin Finck drive[2] = 0;
450c2c66affSColin Finck SetLastError(0xdeadbeef);
451c2c66affSColin Finck ret = QueryDosDeviceA(drive, device_name, sizeof(device_name));
452c2c66affSColin Finck ok(ret, "QueryDosDeviceA error %d\n", GetLastError());
453c2c66affSColin Finck trace("%s -> %s\n", drive, device_name);
454c2c66affSColin Finck
455c2c66affSColin Finck SetLastError(0xdeadbeef);
456c2c66affSColin Finck hfile = CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
457c2c66affSColin Finck ok(hfile != INVALID_HANDLE_VALUE, "CreateFileA(%s) error %d\n", file_name, GetLastError());
458c2c66affSColin Finck SetFilePointer(hfile, 0x4000, NULL, FILE_BEGIN);
459c2c66affSColin Finck SetEndOfFile(hfile);
460c2c66affSColin Finck
461c2c66affSColin Finck SetLastError(0xdeadbeef);
462c2c66affSColin Finck hmap = CreateFileMappingA(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
463c2c66affSColin Finck ok(hmap != 0, "CreateFileMappingA error %d\n", GetLastError());
464c2c66affSColin Finck
465c2c66affSColin Finck SetLastError(0xdeadbeef);
466c2c66affSColin Finck base = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0);
467c2c66affSColin Finck ok(base != NULL, "MapViewOfFile error %d\n", GetLastError());
468c2c66affSColin Finck
469c2c66affSColin Finck SetLastError(0xdeadbeef);
470*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, 0);
471c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
472c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INSUFFICIENT_BUFFER,
473c2c66affSColin Finck "wrong error %d\n", GetLastError());
474c2c66affSColin Finck
475c2c66affSColin Finck SetLastError(0xdeadbeef);
476*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), base, 0, sizeof(map_name));
477c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
478c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
479c2c66affSColin Finck
480c2c66affSColin Finck SetLastError(0xdeadbeef);
481*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, 1);
482c2c66affSColin Finck ok(ret == 1, "GetMappedFileName error %d\n", GetLastError());
483c2c66affSColin Finck ok(!map_name[0] || broken(map_name[0] == device_name[0]) /* before win2k */, "expected 0, got %c\n", map_name[0]);
484c2c66affSColin Finck
485c2c66affSColin Finck SetLastError(0xdeadbeef);
486*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name));
487c2c66affSColin Finck ok(ret, "GetMappedFileName error %d\n", GetLastError());
488c2c66affSColin Finck ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
489c2c66affSColin Finck ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
490c2c66affSColin Finck
491c2c66affSColin Finck SetLastError(0xdeadbeef);
492*4567e13eSAmine Khaldi ret = GetMappedFileNameW(GetCurrentProcess(), base, map_nameW, ARRAY_SIZE(map_nameW));
493*4567e13eSAmine Khaldi todo_wine {
494c2c66affSColin Finck ok(ret, "GetMappedFileNameW error %d\n", GetLastError());
495c2c66affSColin Finck ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
496*4567e13eSAmine Khaldi }
497*4567e13eSAmine Khaldi if (nt_get_mapped_file_name(GetCurrentProcess(), base, nt_map_name, ARRAY_SIZE(nt_map_name)))
498c2c66affSColin Finck {
499c2c66affSColin Finck ok(memcmp(map_nameW, nt_map_name, lstrlenW(map_nameW)) == 0, "map name does not start with a device name: %s\n", map_name);
500c2c66affSColin Finck WideCharToMultiByte(CP_ACP, 0, map_nameW, -1, map_name, MAX_PATH, NULL, NULL);
501c2c66affSColin Finck ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
502c2c66affSColin Finck }
503c2c66affSColin Finck
504c2c66affSColin Finck SetLastError(0xdeadbeef);
505*4567e13eSAmine Khaldi ret = GetMappedFileNameW(current_process, base, map_nameW, sizeof(map_nameW)/sizeof(map_nameW[0]));
5060623a6f8SAmine Khaldi ok(ret, "GetMappedFileNameW error %d\n", GetLastError());
507c2c66affSColin Finck ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
5080623a6f8SAmine Khaldi
5090623a6f8SAmine Khaldi if (nt_get_mapped_file_name(current_process, base, nt_map_name, sizeof(nt_map_name)/sizeof(nt_map_name[0])))
5100623a6f8SAmine Khaldi {
5110623a6f8SAmine Khaldi ok(memcmp(map_nameW, nt_map_name, lstrlenW(map_nameW)) == 0, "map name does not start with a device name: %s\n", map_name);
5120623a6f8SAmine Khaldi WideCharToMultiByte(CP_ACP, 0, map_nameW, -1, map_name, MAX_PATH, NULL, NULL);
513c2c66affSColin Finck ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
514c2c66affSColin Finck }
515c2c66affSColin Finck
516c2c66affSColin Finck SetLastError(0xdeadbeef);
517*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name));
5180623a6f8SAmine Khaldi ok(ret, "GetMappedFileName error %d\n", GetLastError());
5190623a6f8SAmine Khaldi ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
5200623a6f8SAmine Khaldi ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
5210623a6f8SAmine Khaldi
5220623a6f8SAmine Khaldi SetLastError(0xdeadbeef);
523*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), base + 0x4000, map_name, sizeof(map_name));
524c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
525c2c66affSColin Finck ok(GetLastError() == ERROR_UNEXP_NET_ERR, "expected ERROR_UNEXP_NET_ERR, got %d\n", GetLastError());
526c2c66affSColin Finck
527c2c66affSColin Finck SetLastError(0xdeadbeef);
528*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), NULL, map_name, sizeof(map_name));
529c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
530c2c66affSColin Finck todo_wine
531c2c66affSColin Finck ok(GetLastError() == ERROR_UNEXP_NET_ERR, "expected ERROR_UNEXP_NET_ERR, got %d\n", GetLastError());
532c2c66affSColin Finck
533c2c66affSColin Finck SetLastError(0xdeadbeef);
534*4567e13eSAmine Khaldi ret = GetMappedFileNameA(0, base, map_name, sizeof(map_name));
535c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
536c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
537c2c66affSColin Finck
538c2c66affSColin Finck UnmapViewOfFile(base);
539c2c66affSColin Finck CloseHandle(hmap);
540c2c66affSColin Finck CloseHandle(hfile);
541c2c66affSColin Finck DeleteFileA(file_name);
542c2c66affSColin Finck
543c2c66affSColin Finck SetLastError(0xdeadbeef);
544c2c66affSColin Finck hmap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READONLY | SEC_COMMIT, 0, 4096, NULL);
545c2c66affSColin Finck ok(hmap != 0, "CreateFileMappingA error %d\n", GetLastError());
546c2c66affSColin Finck
547c2c66affSColin Finck SetLastError(0xdeadbeef);
548c2c66affSColin Finck base = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0);
549c2c66affSColin Finck ok(base != NULL, "MapViewOfFile error %d\n", GetLastError());
550c2c66affSColin Finck
551c2c66affSColin Finck SetLastError(0xdeadbeef);
552*4567e13eSAmine Khaldi ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name));
553c2c66affSColin Finck ok(!ret, "GetMappedFileName should fail\n");
554c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_INVALID, "expected ERROR_FILE_INVALID, got %d\n", GetLastError());
555c2c66affSColin Finck
5560623a6f8SAmine Khaldi CloseHandle(current_process);
557c2c66affSColin Finck UnmapViewOfFile(base);
558c2c66affSColin Finck CloseHandle(hmap);
559c2c66affSColin Finck }
560c2c66affSColin Finck
test_GetProcessImageFileName(void)561c2c66affSColin Finck static void test_GetProcessImageFileName(void)
562c2c66affSColin Finck {
563c2c66affSColin Finck HMODULE hMod = GetModuleHandleA(NULL);
564c2c66affSColin Finck char szImgPath[MAX_PATH], szMapPath[MAX_PATH];
565c2c66affSColin Finck WCHAR szImgPathW[MAX_PATH];
566c2c66affSColin Finck DWORD ret, ret1;
567c2c66affSColin Finck
568c2c66affSColin Finck /* This function is available on WinXP+ only */
569c2c66affSColin Finck SetLastError(0xdeadbeef);
570*4567e13eSAmine Khaldi if(!GetProcessImageFileNameA(hpQI, szImgPath, sizeof(szImgPath)))
571c2c66affSColin Finck {
572c2c66affSColin Finck if(GetLastError() == ERROR_INVALID_FUNCTION) {
573c2c66affSColin Finck win_skip("GetProcessImageFileName not implemented\n");
574c2c66affSColin Finck return;
575c2c66affSColin Finck }
576c2c66affSColin Finck
577c2c66affSColin Finck if(GetLastError() == 0xdeadbeef)
578c2c66affSColin Finck todo_wine ok(0, "failed without error code\n");
579c2c66affSColin Finck else
580c2c66affSColin Finck todo_wine ok(0, "failed with %d\n", GetLastError());
581c2c66affSColin Finck }
582c2c66affSColin Finck
583c2c66affSColin Finck SetLastError(0xdeadbeef);
584*4567e13eSAmine Khaldi GetProcessImageFileNameA(NULL, szImgPath, sizeof(szImgPath));
585c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
586c2c66affSColin Finck
587c2c66affSColin Finck SetLastError(0xdeadbeef);
588*4567e13eSAmine Khaldi GetProcessImageFileNameA(hpSR, szImgPath, sizeof(szImgPath));
589c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
590c2c66affSColin Finck
591c2c66affSColin Finck SetLastError(0xdeadbeef);
592*4567e13eSAmine Khaldi GetProcessImageFileNameA(hpQI, szImgPath, 0);
593c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected error=ERROR_INSUFFICIENT_BUFFER but got %d\n", GetLastError());
594c2c66affSColin Finck
595*4567e13eSAmine Khaldi ret = GetProcessImageFileNameA(hpQI, szImgPath, sizeof(szImgPath));
596*4567e13eSAmine Khaldi ret1 = GetMappedFileNameA(hpQV, hMod, szMapPath, sizeof(szMapPath));
597c2c66affSColin Finck if(ret && ret1)
598c2c66affSColin Finck {
599c2c66affSColin Finck /* Windows returns 2*strlen-1 */
6000623a6f8SAmine Khaldi ok(ret >= strlen(szImgPath), "szImgPath=\"%s\" ret=%d\n", szImgPath, ret);
6010623a6f8SAmine Khaldi ok(!strcmp(szImgPath, szMapPath), "szImgPath=\"%s\" szMapPath=\"%s\"\n", szImgPath, szMapPath);
602c2c66affSColin Finck }
603c2c66affSColin Finck
604c2c66affSColin Finck SetLastError(0xdeadbeef);
605*4567e13eSAmine Khaldi GetProcessImageFileNameW(NULL, szImgPathW, ARRAY_SIZE(szImgPathW));
606c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
607c2c66affSColin Finck
608c2c66affSColin Finck /* no information about correct buffer size returned: */
609c2c66affSColin Finck SetLastError(0xdeadbeef);
610*4567e13eSAmine Khaldi GetProcessImageFileNameW(hpQI, szImgPathW, 0);
611c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected error=ERROR_INSUFFICIENT_BUFFER but got %d\n", GetLastError());
612c2c66affSColin Finck
613c2c66affSColin Finck SetLastError(0xdeadbeef);
614*4567e13eSAmine Khaldi GetProcessImageFileNameW(hpQI, NULL, 0);
615c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected error=ERROR_INSUFFICIENT_BUFFER but got %d\n", GetLastError());
616c2c66affSColin Finck
617c2c66affSColin Finck /* correct call */
618c2c66affSColin Finck memset(szImgPathW, 0xff, sizeof(szImgPathW));
619*4567e13eSAmine Khaldi ret = GetProcessImageFileNameW(hpQI, szImgPathW, ARRAY_SIZE(szImgPathW));
620c2c66affSColin Finck ok(ret > 0, "GetProcessImageFileNameW should have succeeded.\n");
621c2c66affSColin Finck ok(szImgPathW[0] == '\\', "GetProcessImageFileNameW should have returned an NT path.\n");
622c2c66affSColin Finck ok(lstrlenW(szImgPathW) == ret, "Expected length to be %d, got %d\n", ret, lstrlenW(szImgPathW));
623c2c66affSColin Finck
624c2c66affSColin Finck /* boundary values of 'size' */
625c2c66affSColin Finck SetLastError(0xdeadbeef);
626*4567e13eSAmine Khaldi GetProcessImageFileNameW(hpQI, szImgPathW, ret);
627c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected error=ERROR_INSUFFICIENT_BUFFER but got %d\n", GetLastError());
628c2c66affSColin Finck
629c2c66affSColin Finck memset(szImgPathW, 0xff, sizeof(szImgPathW));
630*4567e13eSAmine Khaldi ret = GetProcessImageFileNameW(hpQI, szImgPathW, ret + 1);
631c2c66affSColin Finck ok(ret > 0, "GetProcessImageFileNameW should have succeeded.\n");
632c2c66affSColin Finck ok(szImgPathW[0] == '\\', "GetProcessImageFileNameW should have returned an NT path.\n");
633c2c66affSColin Finck ok(lstrlenW(szImgPathW) == ret, "Expected length to be %d, got %d\n", ret, lstrlenW(szImgPathW));
634c2c66affSColin Finck }
635c2c66affSColin Finck
test_GetModuleFileNameEx(void)636c2c66affSColin Finck static void test_GetModuleFileNameEx(void)
637c2c66affSColin Finck {
638c2c66affSColin Finck HMODULE hMod = GetModuleHandleA(NULL);
639c2c66affSColin Finck char szModExPath[MAX_PATH+1], szModPath[MAX_PATH+1];
640c2c66affSColin Finck WCHAR buffer[MAX_PATH];
641c2c66affSColin Finck DWORD ret;
642c2c66affSColin Finck
643c2c66affSColin Finck SetLastError(0xdeadbeef);
644*4567e13eSAmine Khaldi ret = GetModuleFileNameExA(NULL, hMod, szModExPath, sizeof(szModExPath));
645c2c66affSColin Finck ok( !ret, "GetModuleFileNameExA succeeded\n" );
646c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
647c2c66affSColin Finck
648c2c66affSColin Finck SetLastError(0xdeadbeef);
649*4567e13eSAmine Khaldi ret = GetModuleFileNameExA(hpQI, hMod, szModExPath, sizeof(szModExPath));
650c2c66affSColin Finck ok( !ret, "GetModuleFileNameExA succeeded\n" );
651c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
652c2c66affSColin Finck
653c2c66affSColin Finck SetLastError(0xdeadbeef);
654*4567e13eSAmine Khaldi ret = GetModuleFileNameExA(hpQV, hBad, szModExPath, sizeof(szModExPath));
655c2c66affSColin Finck ok( !ret, "GetModuleFileNameExA succeeded\n" );
656c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
657c2c66affSColin Finck
658*4567e13eSAmine Khaldi ret = GetModuleFileNameExA(hpQV, NULL, szModExPath, sizeof(szModExPath));
659c2c66affSColin Finck if(!ret)
660c2c66affSColin Finck return;
661c2c66affSColin Finck ok(ret == strlen(szModExPath), "szModExPath=\"%s\" ret=%d\n", szModExPath, ret);
662c2c66affSColin Finck GetModuleFileNameA(NULL, szModPath, sizeof(szModPath));
663c2c66affSColin Finck ok(!strncmp(szModExPath, szModPath, MAX_PATH),
664c2c66affSColin Finck "szModExPath=\"%s\" szModPath=\"%s\"\n", szModExPath, szModPath);
665c2c66affSColin Finck
666c2c66affSColin Finck SetLastError(0xdeadbeef);
667c2c66affSColin Finck memset( szModExPath, 0xcc, sizeof(szModExPath) );
668*4567e13eSAmine Khaldi ret = GetModuleFileNameExA(hpQV, NULL, szModExPath, 4 );
669c2c66affSColin Finck ok( ret == 4 || ret == strlen(szModExPath), "wrong length %u\n", ret );
670c2c66affSColin Finck ok( broken(szModExPath[3]) /*w2kpro*/ || strlen(szModExPath) == 3,
671c2c66affSColin Finck "szModExPath=\"%s\" ret=%d\n", szModExPath, ret );
672c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError());
673c2c66affSColin Finck
674c2c66affSColin Finck if (0) /* crashes on Windows 10 */
675c2c66affSColin Finck {
676c2c66affSColin Finck SetLastError(0xdeadbeef);
677*4567e13eSAmine Khaldi ret = GetModuleFileNameExA(hpQV, NULL, szModExPath, 0 );
678c2c66affSColin Finck ok( ret == 0, "wrong length %u\n", ret );
679c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %d\n", GetLastError());
680c2c66affSColin Finck }
681c2c66affSColin Finck
682c2c66affSColin Finck SetLastError(0xdeadbeef);
683c2c66affSColin Finck memset( buffer, 0xcc, sizeof(buffer) );
684*4567e13eSAmine Khaldi ret = GetModuleFileNameExW(hpQV, NULL, buffer, 4 );
685c2c66affSColin Finck ok( ret == 4 || ret == lstrlenW(buffer), "wrong length %u\n", ret );
686c2c66affSColin Finck ok( broken(buffer[3]) /*w2kpro*/ || lstrlenW(buffer) == 3,
687c2c66affSColin Finck "buffer=%s ret=%d\n", wine_dbgstr_w(buffer), ret );
688c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError());
689c2c66affSColin Finck
690c2c66affSColin Finck if (0) /* crashes on Windows 10 */
691c2c66affSColin Finck {
692c2c66affSColin Finck SetLastError(0xdeadbeef);
693c2c66affSColin Finck buffer[0] = 0xcc;
694*4567e13eSAmine Khaldi ret = GetModuleFileNameExW(hpQV, NULL, buffer, 0 );
695c2c66affSColin Finck ok( ret == 0, "wrong length %u\n", ret );
696c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError());
697c2c66affSColin Finck ok( buffer[0] == 0xcc, "buffer modified %s\n", wine_dbgstr_w(buffer) );
698c2c66affSColin Finck }
699c2c66affSColin Finck }
700c2c66affSColin Finck
test_GetModuleBaseName(void)701c2c66affSColin Finck static void test_GetModuleBaseName(void)
702c2c66affSColin Finck {
703c2c66affSColin Finck HMODULE hMod = GetModuleHandleA(NULL);
704c2c66affSColin Finck char szModPath[MAX_PATH], szModBaseName[MAX_PATH];
705c2c66affSColin Finck DWORD ret;
706c2c66affSColin Finck
707c2c66affSColin Finck SetLastError(0xdeadbeef);
708*4567e13eSAmine Khaldi GetModuleBaseNameA(NULL, hMod, szModBaseName, sizeof(szModBaseName));
709c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
710c2c66affSColin Finck
711c2c66affSColin Finck SetLastError(0xdeadbeef);
712*4567e13eSAmine Khaldi GetModuleBaseNameA(hpQI, hMod, szModBaseName, sizeof(szModBaseName));
713c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
714c2c66affSColin Finck
715c2c66affSColin Finck SetLastError(0xdeadbeef);
716*4567e13eSAmine Khaldi GetModuleBaseNameA(hpQV, hBad, szModBaseName, sizeof(szModBaseName));
717c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
718c2c66affSColin Finck
719*4567e13eSAmine Khaldi ret = GetModuleBaseNameA(hpQV, NULL, szModBaseName, sizeof(szModBaseName));
720c2c66affSColin Finck if(!ret)
721c2c66affSColin Finck return;
722c2c66affSColin Finck ok(ret == strlen(szModBaseName), "szModBaseName=\"%s\" ret=%d\n", szModBaseName, ret);
723c2c66affSColin Finck GetModuleFileNameA(NULL, szModPath, sizeof(szModPath));
724c2c66affSColin Finck ok(!strcmp(strrchr(szModPath, '\\') + 1, szModBaseName),
725c2c66affSColin Finck "szModPath=\"%s\" szModBaseName=\"%s\"\n", szModPath, szModBaseName);
726c2c66affSColin Finck }
727c2c66affSColin Finck
test_ws_functions(void)728c2c66affSColin Finck static void test_ws_functions(void)
729c2c66affSColin Finck {
730c2c66affSColin Finck PSAPI_WS_WATCH_INFORMATION wswi[4096];
731c2c66affSColin Finck ULONG_PTR pages[4096];
732*4567e13eSAmine Khaldi HANDLE ws_handle;
733c2c66affSColin Finck char *addr;
734c2c66affSColin Finck unsigned int i;
735c2c66affSColin Finck BOOL ret;
736c2c66affSColin Finck
737*4567e13eSAmine Khaldi ws_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_QUOTA |
738*4567e13eSAmine Khaldi PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId());
739*4567e13eSAmine Khaldi ok(!!ws_handle, "got error %u\n", GetLastError());
740*4567e13eSAmine Khaldi
741c2c66affSColin Finck SetLastError(0xdeadbeef);
742*4567e13eSAmine Khaldi EmptyWorkingSet(NULL);
743c2c66affSColin Finck todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
744c2c66affSColin Finck
745c2c66affSColin Finck SetLastError(0xdeadbeef);
746*4567e13eSAmine Khaldi EmptyWorkingSet(hpSR);
747c2c66affSColin Finck todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
748c2c66affSColin Finck
749c2c66affSColin Finck SetLastError(0xdeadbeef);
750*4567e13eSAmine Khaldi ret = EmptyWorkingSet(ws_handle);
751c2c66affSColin Finck ok(ret == 1, "failed with %d\n", GetLastError());
752c2c66affSColin Finck
753c2c66affSColin Finck SetLastError( 0xdeadbeef );
754*4567e13eSAmine Khaldi ret = InitializeProcessForWsWatch( NULL );
755c2c66affSColin Finck todo_wine ok( !ret, "InitializeProcessForWsWatch succeeded\n" );
756c2c66affSColin Finck if (!ret)
757c2c66affSColin Finck {
758c2c66affSColin Finck if (GetLastError() == ERROR_INVALID_FUNCTION) /* not supported on xp in wow64 mode */
759c2c66affSColin Finck {
760c2c66affSColin Finck trace( "InitializeProcessForWsWatch not supported\n" );
761c2c66affSColin Finck return;
762c2c66affSColin Finck }
763c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
764c2c66affSColin Finck }
765c2c66affSColin Finck SetLastError(0xdeadbeef);
766*4567e13eSAmine Khaldi ret = InitializeProcessForWsWatch(ws_handle);
767c2c66affSColin Finck ok(ret == 1, "failed with %d\n", GetLastError());
768c2c66affSColin Finck
769c2c66affSColin Finck addr = VirtualAlloc(NULL, 1, MEM_COMMIT, PAGE_READWRITE);
770c2c66affSColin Finck if(!addr)
771c2c66affSColin Finck return;
772c2c66affSColin Finck
773c2c66affSColin Finck *addr = 0; /* make sure it's paged in (needed on wow64) */
774c2c66affSColin Finck if(!VirtualLock(addr, 1))
775c2c66affSColin Finck {
776c2c66affSColin Finck trace("locking failed (error=%d) - skipping test\n", GetLastError());
777c2c66affSColin Finck goto free_page;
778c2c66affSColin Finck }
779c2c66affSColin Finck
780c2c66affSColin Finck SetLastError(0xdeadbeef);
781*4567e13eSAmine Khaldi ret = QueryWorkingSet(hpQI, pages, 4096 * sizeof(ULONG_PTR));
782c2c66affSColin Finck todo_wine ok(ret == 1, "failed with %d\n", GetLastError());
783c2c66affSColin Finck if(ret == 1)
784c2c66affSColin Finck {
785c2c66affSColin Finck for(i = 0; i < pages[0]; i++)
786c2c66affSColin Finck if((pages[i+1] & ~0xfffL) == (ULONG_PTR)addr)
787c2c66affSColin Finck {
788c2c66affSColin Finck todo_wine ok(ret == 1, "QueryWorkingSet found our page\n");
789c2c66affSColin Finck goto test_gwsc;
790c2c66affSColin Finck }
791c2c66affSColin Finck
792c2c66affSColin Finck todo_wine ok(0, "QueryWorkingSet didn't find our page\n");
793c2c66affSColin Finck }
794c2c66affSColin Finck
795c2c66affSColin Finck test_gwsc:
796c2c66affSColin Finck SetLastError(0xdeadbeef);
797*4567e13eSAmine Khaldi ret = GetWsChanges(hpQI, wswi, sizeof(wswi));
798c2c66affSColin Finck todo_wine ok(ret == 1, "failed with %d\n", GetLastError());
799c2c66affSColin Finck if(ret == 1)
800c2c66affSColin Finck {
801c2c66affSColin Finck for(i = 0; wswi[i].FaultingVa; i++)
802c2c66affSColin Finck if(((ULONG_PTR)wswi[i].FaultingVa & ~0xfffL) == (ULONG_PTR)addr)
803c2c66affSColin Finck {
804c2c66affSColin Finck todo_wine ok(ret == 1, "GetWsChanges found our page\n");
805c2c66affSColin Finck goto free_page;
806c2c66affSColin Finck }
807c2c66affSColin Finck
808c2c66affSColin Finck todo_wine ok(0, "GetWsChanges didn't find our page\n");
809c2c66affSColin Finck }
810c2c66affSColin Finck
811c2c66affSColin Finck free_page:
812c2c66affSColin Finck VirtualFree(addr, 0, MEM_RELEASE);
813c2c66affSColin Finck }
814c2c66affSColin Finck
START_TEST(psapi_main)815c2c66affSColin Finck START_TEST(psapi_main)
816c2c66affSColin Finck {
817c2c66affSColin Finck DWORD pid = GetCurrentProcessId();
818c2c66affSColin Finck
819*4567e13eSAmine Khaldi init_func_ptrs();
820c2c66affSColin Finck
821*4567e13eSAmine Khaldi if (pIsWow64Process)
822*4567e13eSAmine Khaldi IsWow64Process(GetCurrentProcess(), &wow64);
823*4567e13eSAmine Khaldi
824*4567e13eSAmine Khaldi hpSR = OpenProcess(STANDARD_RIGHTS_REQUIRED, FALSE, pid);
825*4567e13eSAmine Khaldi ok(!!hpSR, "got error %u\n", GetLastError());
826*4567e13eSAmine Khaldi hpQI = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
827*4567e13eSAmine Khaldi ok(!!hpQI, "got error %u\n", GetLastError());
828*4567e13eSAmine Khaldi hpVR = OpenProcess(PROCESS_VM_READ, FALSE, pid);
829*4567e13eSAmine Khaldi ok(!!hpVR, "got error %u\n", GetLastError());
830*4567e13eSAmine Khaldi hpQV = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
831*4567e13eSAmine Khaldi ok(!!hpQV, "got error %u\n", GetLastError());
832*4567e13eSAmine Khaldi
833c2c66affSColin Finck test_EnumProcesses();
834c2c66affSColin Finck test_EnumProcessModules();
835c2c66affSColin Finck test_GetModuleInformation();
836c2c66affSColin Finck test_GetPerformanceInfo();
837c2c66affSColin Finck test_GetProcessMemoryInfo();
838c2c66affSColin Finck test_GetMappedFileName();
839c2c66affSColin Finck test_GetProcessImageFileName();
840c2c66affSColin Finck test_GetModuleFileNameEx();
841c2c66affSColin Finck test_GetModuleBaseName();
842c2c66affSColin Finck test_ws_functions();
843*4567e13eSAmine Khaldi
844c2c66affSColin Finck CloseHandle(hpSR);
845c2c66affSColin Finck CloseHandle(hpQI);
846c2c66affSColin Finck CloseHandle(hpVR);
847c2c66affSColin Finck CloseHandle(hpQV);
848c2c66affSColin Finck }
849