1 /* Unit test suite for *Information* Registry API functions
2 *
3 * Copyright 2005 Paul Vriens
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 */
20
21 #include "ntdll_test.h"
22 #include <winnls.h>
23 #include <stdio.h>
24
25 static NTSTATUS (WINAPI * pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
26 static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
27 static NTSTATUS (WINAPI * pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*);
28 static NTSTATUS (WINAPI * pNtPowerInformation)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG);
29 static NTSTATUS (WINAPI * pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
30 static NTSTATUS (WINAPI * pNtQueryInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG);
31 static NTSTATUS (WINAPI * pNtSetInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG);
32 static NTSTATUS (WINAPI * pNtSetInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG);
33 static NTSTATUS (WINAPI * pNtReadVirtualMemory)(HANDLE, const void*, void*, SIZE_T, SIZE_T*);
34 static NTSTATUS (WINAPI * pNtQueryVirtualMemory)(HANDLE, LPCVOID, MEMORY_INFORMATION_CLASS , PVOID , SIZE_T , SIZE_T *);
35 static NTSTATUS (WINAPI * pNtCreateSection)(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const LARGE_INTEGER*,ULONG,ULONG,HANDLE);
36 static NTSTATUS (WINAPI * pNtMapViewOfSection)(HANDLE,HANDLE,PVOID*,ULONG,SIZE_T,const LARGE_INTEGER*,SIZE_T*,SECTION_INHERIT,ULONG,ULONG);
37 static NTSTATUS (WINAPI * pNtUnmapViewOfSection)(HANDLE,PVOID);
38 static NTSTATUS (WINAPI * pNtClose)(HANDLE);
39 static ULONG (WINAPI * pNtGetCurrentProcessorNumber)(void);
40 static BOOL (WINAPI * pIsWow64Process)(HANDLE, PBOOL);
41 static BOOL (WINAPI * pGetLogicalProcessorInformationEx)(LOGICAL_PROCESSOR_RELATIONSHIP,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*,DWORD*);
42
43 static BOOL is_wow64;
44
45 /* one_before_last_pid is used to be able to compare values of a still running process
46 with the output of the test_query_process_times and test_query_process_handlecount tests.
47 */
48 static DWORD one_before_last_pid = 0;
49
50 #define NTDLL_GET_PROC(func) do { \
51 p ## func = (void*)GetProcAddress(hntdll, #func); \
52 if(!p ## func) { \
53 trace("GetProcAddress(%s) failed\n", #func); \
54 return FALSE; \
55 } \
56 } while(0)
57
InitFunctionPtrs(void)58 static BOOL InitFunctionPtrs(void)
59 {
60 /* All needed functions are NT based, so using GetModuleHandle is a good check */
61 HMODULE hntdll = GetModuleHandleA("ntdll");
62 HMODULE hkernel32 = GetModuleHandleA("kernel32");
63
64 if (!hntdll)
65 {
66 win_skip("Not running on NT\n");
67 return FALSE;
68 }
69
70 NTDLL_GET_PROC(RtlDowncaseUnicodeString);
71 NTDLL_GET_PROC(NtQuerySystemInformation);
72 NTDLL_GET_PROC(NtPowerInformation);
73 NTDLL_GET_PROC(NtQueryInformationProcess);
74 NTDLL_GET_PROC(NtQueryInformationThread);
75 NTDLL_GET_PROC(NtSetInformationProcess);
76 NTDLL_GET_PROC(NtSetInformationThread);
77 NTDLL_GET_PROC(NtReadVirtualMemory);
78 NTDLL_GET_PROC(NtQueryVirtualMemory);
79 NTDLL_GET_PROC(NtClose);
80 NTDLL_GET_PROC(NtCreateSection);
81 NTDLL_GET_PROC(NtMapViewOfSection);
82 NTDLL_GET_PROC(NtUnmapViewOfSection);
83
84 /* not present before XP */
85 pNtGetCurrentProcessorNumber = (void *) GetProcAddress(hntdll, "NtGetCurrentProcessorNumber");
86
87 pIsWow64Process = (void *)GetProcAddress(hkernel32, "IsWow64Process");
88 if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
89
90 /* starting with Win7 */
91 pNtQuerySystemInformationEx = (void *) GetProcAddress(hntdll, "NtQuerySystemInformationEx");
92 if (!pNtQuerySystemInformationEx)
93 win_skip("NtQuerySystemInformationEx() is not supported, some tests will be skipped.\n");
94
95 pGetLogicalProcessorInformationEx = (void *) GetProcAddress(hkernel32, "GetLogicalProcessorInformationEx");
96
97 return TRUE;
98 }
99
test_query_basic(void)100 static void test_query_basic(void)
101 {
102 NTSTATUS status;
103 ULONG ReturnLength;
104 SYSTEM_BASIC_INFORMATION sbi;
105
106 /* This test also covers some basic parameter testing that should be the same for
107 * every information class
108 */
109
110 /* Use a nonexistent info class */
111 trace("Check nonexistent info class\n");
112 status = pNtQuerySystemInformation(-1, NULL, 0, NULL);
113 ok( status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* vista */,
114 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status);
115
116 /* Use an existing class but with a zero-length buffer */
117 trace("Check zero-length buffer\n");
118 status = pNtQuerySystemInformation(SystemBasicInformation, NULL, 0, NULL);
119 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
120
121 /* Use an existing class, correct length but no SystemInformation buffer */
122 trace("Check no SystemInformation buffer\n");
123 status = pNtQuerySystemInformation(SystemBasicInformation, NULL, sizeof(sbi), NULL);
124 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* vista */,
125 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got %08x\n", status);
126
127 /* Use an existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
128 trace("Check no ReturnLength pointer\n");
129 status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL);
130 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
131
132 /* Check a too large buffer size */
133 trace("Check a too large buffer size\n");
134 status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi) * 2, &ReturnLength);
135 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
136
137 /* Finally some correct calls */
138 trace("Check with correct parameters\n");
139 status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength);
140 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
141 ok( sizeof(sbi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
142
143 /* Check if we have some return values */
144 trace("Number of Processors : %d\n", sbi.NumberOfProcessors);
145 ok( sbi.NumberOfProcessors > 0, "Expected more than 0 processors, got %d\n", sbi.NumberOfProcessors);
146 }
147
test_query_cpu(void)148 static void test_query_cpu(void)
149 {
150 DWORD status;
151 ULONG ReturnLength;
152 SYSTEM_CPU_INFORMATION sci;
153
154 status = pNtQuerySystemInformation(SystemCpuInformation, &sci, sizeof(sci), &ReturnLength);
155 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
156 ok( sizeof(sci) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
157
158 /* Check if we have some return values */
159 trace("Processor FeatureSet : %08x\n", sci.FeatureSet);
160 ok( sci.FeatureSet != 0, "Expected some features for this processor, got %08x\n", sci.FeatureSet);
161 }
162
test_query_performance(void)163 static void test_query_performance(void)
164 {
165 NTSTATUS status;
166 ULONG ReturnLength;
167 ULONGLONG buffer[sizeof(SYSTEM_PERFORMANCE_INFORMATION)/sizeof(ULONGLONG) + 5];
168 DWORD size = sizeof(SYSTEM_PERFORMANCE_INFORMATION);
169
170 status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, 0, &ReturnLength);
171 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
172
173 status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, size, &ReturnLength);
174 if (status == STATUS_INFO_LENGTH_MISMATCH && is_wow64)
175 {
176 /* size is larger on wow64 under w2k8/win7 */
177 size += 16;
178 status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, size, &ReturnLength);
179 }
180 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
181 ok( ReturnLength == size, "Inconsistent length %d\n", ReturnLength);
182
183 status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, size + 2, &ReturnLength);
184 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
185 ok( ReturnLength == size || ReturnLength == size + 2,
186 "Inconsistent length %d\n", ReturnLength);
187
188 /* Not return values yet, as struct members are unknown */
189 }
190
test_query_timeofday(void)191 static void test_query_timeofday(void)
192 {
193 NTSTATUS status;
194 ULONG ReturnLength;
195
196 /* Copy of our winternl.h structure turned into a private one */
197 typedef struct _SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE {
198 LARGE_INTEGER liKeBootTime;
199 LARGE_INTEGER liKeSystemTime;
200 LARGE_INTEGER liExpTimeZoneBias;
201 ULONG uCurrentTimeZoneId;
202 DWORD dwUnknown1[5];
203 } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE;
204
205 SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti;
206
207 /* The struct size for NT (32 bytes) and Win2K/XP (48 bytes) differ.
208 *
209 * Windows 2000 and XP return STATUS_INFO_LENGTH_MISMATCH if the given buffer size is greater
210 * then 48 and 0 otherwise
211 * Windows NT returns STATUS_INFO_LENGTH_MISMATCH when the given buffer size is not correct
212 * and 0 otherwise
213 *
214 * Windows 2000 and XP copy the given buffer size into the provided buffer, if the return code is STATUS_SUCCESS
215 * NT only fills the buffer if the return code is STATUS_SUCCESS
216 *
217 */
218
219 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, sizeof(sti), &ReturnLength);
220
221 if (status == STATUS_INFO_LENGTH_MISMATCH)
222 {
223 trace("Windows version is NT, we have to cater for differences with W2K/WinXP\n");
224
225 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 0, &ReturnLength);
226 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
227 ok( 0 == ReturnLength, "ReturnLength should be 0, it is (%d)\n", ReturnLength);
228
229 sti.uCurrentTimeZoneId = 0xdeadbeef;
230 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 28, &ReturnLength);
231 ok(status == STATUS_SUCCESS || broken(status == STATUS_INFO_LENGTH_MISMATCH /* NT4 */), "Expected STATUS_SUCCESS, got %08x\n", status);
232 ok( 0xdeadbeef == sti.uCurrentTimeZoneId, "This part of the buffer should not have been filled\n");
233
234 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 32, &ReturnLength);
235 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
236 ok( 32 == ReturnLength, "ReturnLength should be 0, it is (%d)\n", ReturnLength);
237 }
238 else
239 {
240 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 0, &ReturnLength);
241 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
242 ok( 0 == ReturnLength, "ReturnLength should be 0, it is (%d)\n", ReturnLength);
243
244 sti.uCurrentTimeZoneId = 0xdeadbeef;
245 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 24, &ReturnLength);
246 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
247 ok( 24 == ReturnLength, "ReturnLength should be 24, it is (%d)\n", ReturnLength);
248 ok( 0xdeadbeef == sti.uCurrentTimeZoneId, "This part of the buffer should not have been filled\n");
249
250 sti.uCurrentTimeZoneId = 0xdeadbeef;
251 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 32, &ReturnLength);
252 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
253 ok( 32 == ReturnLength, "ReturnLength should be 32, it is (%d)\n", ReturnLength);
254 ok( 0xdeadbeef != sti.uCurrentTimeZoneId, "Buffer should have been partially filled\n");
255
256 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 49, &ReturnLength);
257 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
258 ok( ReturnLength == 0 || ReturnLength == sizeof(sti) /* vista */,
259 "ReturnLength should be 0, it is (%d)\n", ReturnLength);
260
261 status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, sizeof(sti), &ReturnLength);
262 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
263 ok( sizeof(sti) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
264 }
265
266 /* Check if we have some return values */
267 trace("uCurrentTimeZoneId : (%d)\n", sti.uCurrentTimeZoneId);
268 }
269
test_query_process(void)270 static void test_query_process(void)
271 {
272 NTSTATUS status;
273 DWORD last_pid;
274 ULONG ReturnLength;
275 int i = 0, k = 0;
276 BOOL is_nt = FALSE;
277 SYSTEM_BASIC_INFORMATION sbi;
278
279 /* Copy of our winternl.h structure turned into a private one */
280 typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE {
281 ULONG NextEntryOffset;
282 DWORD dwThreadCount;
283 DWORD dwUnknown1[6];
284 FILETIME ftCreationTime;
285 FILETIME ftUserTime;
286 FILETIME ftKernelTime;
287 UNICODE_STRING ProcessName;
288 DWORD dwBasePriority;
289 HANDLE UniqueProcessId;
290 HANDLE ParentProcessId;
291 ULONG HandleCount;
292 DWORD dwUnknown3;
293 DWORD dwUnknown4;
294 VM_COUNTERS vmCounters;
295 IO_COUNTERS ioCounters;
296 SYSTEM_THREAD_INFORMATION ti[1];
297 } SYSTEM_PROCESS_INFORMATION_PRIVATE;
298
299 ULONG SystemInformationLength = sizeof(SYSTEM_PROCESS_INFORMATION_PRIVATE);
300 SYSTEM_PROCESS_INFORMATION_PRIVATE *spi, *spi_buf = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength);
301
302 /* test ReturnLength */
303 ReturnLength = 0;
304 status = pNtQuerySystemInformation(SystemProcessInformation, NULL, 0, &ReturnLength);
305 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH got %08x\n", status);
306 ok( ReturnLength > 0 || broken(ReturnLength == 0) /* NT4, Win2K */,
307 "Expected a ReturnLength to show the needed length\n");
308
309 /* W2K3 and later returns the needed length, the rest returns 0, so we have to loop */
310 for (;;)
311 {
312 status = pNtQuerySystemInformation(SystemProcessInformation, spi_buf, SystemInformationLength, &ReturnLength);
313
314 if (status != STATUS_INFO_LENGTH_MISMATCH) break;
315
316 spi_buf = HeapReAlloc(GetProcessHeap(), 0, spi_buf , SystemInformationLength *= 2);
317 }
318 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
319 spi = spi_buf;
320
321 /* Get the first NextEntryOffset, from this we can deduce the OS version we're running
322 *
323 * W2K/WinXP/W2K3:
324 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
325 * NT:
326 * NextEntryOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
327 * Wine (with every windows version):
328 * NextEntryOffset for a process is 0 if just this test is running
329 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) +
330 * ProcessName.MaximumLength
331 * if more wine processes are running
332 *
333 * Note : On windows the first process is in fact the Idle 'process' with a thread for every processor
334 */
335
336 pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength);
337
338 is_nt = ( spi->NextEntryOffset - (sbi.NumberOfProcessors * sizeof(SYSTEM_THREAD_INFORMATION)) == 136);
339
340 if (is_nt) win_skip("Windows version is NT, we will skip thread tests\n");
341
342 /* Check if we have some return values
343 *
344 * On windows there will be several processes running (Including the always present Idle and System)
345 * On wine we only have one (if this test is the only wine process running)
346 */
347
348 /* Loop through the processes */
349
350 for (;;)
351 {
352 i++;
353
354 last_pid = (DWORD_PTR)spi->UniqueProcessId;
355
356 disable_success_count
357 ok( spi->dwThreadCount > 0, "Expected some threads for this process, got 0\n");
358
359 /* Loop through the threads, skip NT4 for now */
360
361 if (!is_nt)
362 {
363 DWORD j;
364 for ( j = 0; j < spi->dwThreadCount; j++)
365 {
366 k++;
367 disable_success_count
368 ok ( spi->ti[j].ClientId.UniqueProcess == spi->UniqueProcessId,
369 "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n",
370 spi->ti[j].ClientId.UniqueProcess, spi->UniqueProcessId);
371 }
372 }
373
374 if (!spi->NextEntryOffset) break;
375
376 one_before_last_pid = last_pid;
377
378 spi = (SYSTEM_PROCESS_INFORMATION_PRIVATE*)((char*)spi + spi->NextEntryOffset);
379 }
380 trace("Total number of running processes : %d\n", i);
381 if (!is_nt) trace("Total number of running threads : %d\n", k);
382
383 if (one_before_last_pid == 0) one_before_last_pid = last_pid;
384
385 HeapFree( GetProcessHeap(), 0, spi_buf);
386 }
387
test_query_procperf(void)388 static void test_query_procperf(void)
389 {
390 NTSTATUS status;
391 ULONG ReturnLength;
392 ULONG NeededLength;
393 SYSTEM_BASIC_INFORMATION sbi;
394 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
395
396 /* Find out the number of processors */
397 status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength);
398 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
399 NeededLength = sbi.NumberOfProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
400
401 sppi = HeapAlloc(GetProcessHeap(), 0, NeededLength);
402
403 status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, 0, &ReturnLength);
404 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
405
406 /* Try it for 1 processor */
407 sppi->KernelTime.QuadPart = 0xdeaddead;
408 sppi->UserTime.QuadPart = 0xdeaddead;
409 sppi->IdleTime.QuadPart = 0xdeaddead;
410 status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi,
411 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), &ReturnLength);
412 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
413 ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) == ReturnLength,
414 "Inconsistent length %d\n", ReturnLength);
415 ok (sppi->KernelTime.QuadPart != 0xdeaddead, "KernelTime unchanged\n");
416 ok (sppi->UserTime.QuadPart != 0xdeaddead, "UserTime unchanged\n");
417 ok (sppi->IdleTime.QuadPart != 0xdeaddead, "IdleTime unchanged\n");
418
419 /* Try it for all processors */
420 sppi->KernelTime.QuadPart = 0xdeaddead;
421 sppi->UserTime.QuadPart = 0xdeaddead;
422 sppi->IdleTime.QuadPart = 0xdeaddead;
423 status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, NeededLength, &ReturnLength);
424 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
425 ok( NeededLength == ReturnLength, "Inconsistent length (%d) <-> (%d)\n", NeededLength, ReturnLength);
426 ok (sppi->KernelTime.QuadPart != 0xdeaddead, "KernelTime unchanged\n");
427 ok (sppi->UserTime.QuadPart != 0xdeaddead, "UserTime unchanged\n");
428 ok (sppi->IdleTime.QuadPart != 0xdeaddead, "IdleTime unchanged\n");
429
430 /* A too large given buffer size */
431 sppi = HeapReAlloc(GetProcessHeap(), 0, sppi , NeededLength + 2);
432 sppi->KernelTime.QuadPart = 0xdeaddead;
433 sppi->UserTime.QuadPart = 0xdeaddead;
434 sppi->IdleTime.QuadPart = 0xdeaddead;
435 status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, NeededLength + 2, &ReturnLength);
436 ok( status == STATUS_SUCCESS || status == STATUS_INFO_LENGTH_MISMATCH /* vista */,
437 "Expected STATUS_SUCCESS or STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
438 ok( NeededLength == ReturnLength, "Inconsistent length (%d) <-> (%d)\n", NeededLength, ReturnLength);
439 if (status == STATUS_SUCCESS)
440 {
441 ok (sppi->KernelTime.QuadPart != 0xdeaddead, "KernelTime unchanged\n");
442 ok (sppi->UserTime.QuadPart != 0xdeaddead, "UserTime unchanged\n");
443 ok (sppi->IdleTime.QuadPart != 0xdeaddead, "IdleTime unchanged\n");
444 }
445 else /* vista and 2008 */
446 {
447 ok (sppi->KernelTime.QuadPart == 0xdeaddead, "KernelTime changed\n");
448 ok (sppi->UserTime.QuadPart == 0xdeaddead, "UserTime changed\n");
449 ok (sppi->IdleTime.QuadPart == 0xdeaddead, "IdleTime changed\n");
450 }
451
452 HeapFree( GetProcessHeap(), 0, sppi);
453 }
454
test_query_module(void)455 static void test_query_module(void)
456 {
457 NTSTATUS status;
458 ULONG ReturnLength;
459 ULONG ModuleCount, i;
460
461 ULONG SystemInformationLength = sizeof(SYSTEM_MODULE_INFORMATION);
462 SYSTEM_MODULE_INFORMATION* smi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength);
463 SYSTEM_MODULE* sm;
464
465 /* Request the needed length */
466 status = pNtQuerySystemInformation(SystemModuleInformation, smi, 0, &ReturnLength);
467 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
468 ok( ReturnLength > 0, "Expected a ReturnLength to show the needed length\n");
469
470 SystemInformationLength = ReturnLength;
471 smi = HeapReAlloc(GetProcessHeap(), 0, smi , SystemInformationLength);
472 status = pNtQuerySystemInformation(SystemModuleInformation, smi, SystemInformationLength, &ReturnLength);
473 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
474
475 ModuleCount = smi->ModulesCount;
476 sm = &smi->Modules[0];
477 /* our implementation is a stub for now */
478 ok( ModuleCount > 0, "Expected some modules to be loaded\n");
479
480 /* Loop through all the modules/drivers, Wine doesn't get here (yet) */
481 for (i = 0; i < ModuleCount ; i++)
482 {
483 ok( i == sm->Id, "Id (%d) should have matched %u\n", sm->Id, i);
484 sm++;
485 }
486
487 HeapFree( GetProcessHeap(), 0, smi);
488 }
489
test_query_handle(void)490 static void test_query_handle(void)
491 {
492 NTSTATUS status;
493 ULONG ExpectedLength, ReturnLength;
494 ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION);
495 SYSTEM_HANDLE_INFORMATION* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength);
496 HANDLE EventHandle;
497 BOOL found;
498 INT i;
499
500 EventHandle = CreateEventA(NULL, FALSE, FALSE, NULL);
501 ok( EventHandle != NULL, "CreateEventA failed %u\n", GetLastError() );
502
503 /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
504 ReturnLength = 0xdeadbeef;
505 status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
506 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
507 ok( ReturnLength != 0xdeadbeef, "Expected valid ReturnLength\n" );
508
509 SystemInformationLength = ReturnLength;
510 shi = HeapReAlloc(GetProcessHeap(), 0, shi , SystemInformationLength);
511 memset(shi, 0x55, SystemInformationLength);
512
513 ReturnLength = 0xdeadbeef;
514 status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
515 while (status == STATUS_INFO_LENGTH_MISMATCH) /* Vista / 2008 */
516 {
517 SystemInformationLength *= 2;
518 shi = HeapReAlloc(GetProcessHeap(), 0, shi, SystemInformationLength);
519 memset(shi, 0x55, SystemInformationLength);
520 status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
521 }
522 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
523 ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handle[shi->Count]);
524 ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */
525 "Expected length %u, got %u\n", ExpectedLength, ReturnLength );
526 ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count );
527 ok( shi->Handle[1].HandleValue != 0x5555 || broken( shi->Handle[1].HandleValue == 0x5555 ), /* Vista / 2008 */
528 "Uninitialized second handle\n" );
529 if (shi->Handle[1].HandleValue == 0x5555)
530 {
531 win_skip("Skipping broken SYSTEM_HANDLE_INFORMATION\n");
532 CloseHandle(EventHandle);
533 goto done;
534 }
535
536 for (i = 0, found = FALSE; i < shi->Count && !found; i++)
537 found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) &&
538 ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle);
539 ok( found, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle, GetCurrentProcessId() );
540
541 if (!found)
542 for (i = 0; i < shi->Count; i++)
543 trace( "%d: handle %x pid %x\n", i, shi->Handle[i].HandleValue, shi->Handle[i].OwnerPid );
544
545 CloseHandle(EventHandle);
546
547 ReturnLength = 0xdeadbeef;
548 status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
549 while (status == STATUS_INFO_LENGTH_MISMATCH) /* Vista / 2008 */
550 {
551 SystemInformationLength *= 2;
552 shi = HeapReAlloc(GetProcessHeap(), 0, shi, SystemInformationLength);
553 status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
554 }
555 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
556 for (i = 0, found = FALSE; i < shi->Count && !found; i++)
557 found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) &&
558 ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle);
559 ok( !found, "Unexpectedly found event handle in handle list\n" );
560
561 status = pNtQuerySystemInformation(SystemHandleInformation, NULL, SystemInformationLength, &ReturnLength);
562 ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status );
563
564 done:
565 HeapFree( GetProcessHeap(), 0, shi);
566 }
567
test_query_handle_ex(void)568 static void test_query_handle_ex(void)
569 {
570 NTSTATUS status;
571 ULONG ExpectedLength, ReturnLength;
572 ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION_EX);
573 SYSTEM_HANDLE_INFORMATION_EX* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength);
574 HANDLE EventHandle;
575 BOOL found;
576 INT i;
577
578 EventHandle = CreateEventA(NULL, FALSE, FALSE, NULL);
579 ok( EventHandle != NULL, "CreateEventA failed %u\n", GetLastError() );
580
581 ReturnLength = 0xdeadbeef;
582 status = pNtQuerySystemInformation(SystemExtendedHandleInformation, shi, SystemInformationLength, &ReturnLength);
583 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
584 ok( ReturnLength != 0xdeadbeef, "Expected valid ReturnLength\n" );
585
586 SystemInformationLength = ReturnLength;
587 shi = HeapReAlloc(GetProcessHeap(), 0, shi , SystemInformationLength);
588 memset(shi, 0x55, SystemInformationLength);
589
590 ReturnLength = 0xdeadbeef;
591 status = pNtQuerySystemInformation(SystemExtendedHandleInformation, shi, SystemInformationLength, &ReturnLength);
592 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
593 ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handle[shi->Count]);
594 ok( ReturnLength == ExpectedLength, "Expected length %u, got %u\n", ExpectedLength, ReturnLength );
595 ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", (DWORD)shi->Count );
596
597 for (i = 0, found = FALSE; i < shi->Count && !found; i++)
598 found = (shi->Handle[i].UniqueProcessId == GetCurrentProcessId()) &&
599 ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle);
600 ok( found, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle, GetCurrentProcessId() );
601
602 if (!found)
603 {
604 for (i = 0; i < shi->Count; i++)
605 trace( "%d: handle %x pid %x\n", i, (DWORD)shi->Handle[i].HandleValue, (DWORD)shi->Handle[i].UniqueProcessId );
606 }
607
608 CloseHandle(EventHandle);
609
610 ReturnLength = 0xdeadbeef;
611 status = pNtQuerySystemInformation(SystemExtendedHandleInformation, shi, SystemInformationLength, &ReturnLength);
612 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
613 for (i = 0, found = FALSE; i < shi->Count && !found; i++)
614 found = (shi->Handle[i].UniqueProcessId == GetCurrentProcessId()) &&
615 ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle);
616 ok( !found, "Unexpectedly found event handle in handle list\n" );
617
618 status = pNtQuerySystemInformation(SystemExtendedHandleInformation, NULL, SystemInformationLength, &ReturnLength);
619 ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status );
620
621 HeapFree( GetProcessHeap(), 0, shi);
622 }
623
test_query_cache(void)624 static void test_query_cache(void)
625 {
626 NTSTATUS status;
627 ULONG ReturnLength;
628 BYTE buffer[128];
629 SYSTEM_CACHE_INFORMATION *sci = (SYSTEM_CACHE_INFORMATION *) buffer;
630 ULONG expected;
631 INT i;
632
633 /* the large SYSTEM_CACHE_INFORMATION on WIN64 is not documented */
634 expected = sizeof(SYSTEM_CACHE_INFORMATION);
635 for (i = sizeof(buffer); i>= expected; i--)
636 {
637 ReturnLength = 0xdeadbeef;
638 status = pNtQuerySystemInformation(SystemCacheInformation, sci, i, &ReturnLength);
639 ok(!status && (ReturnLength == expected),
640 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i, status, ReturnLength, expected);
641 }
642
643 /* buffer too small for the full result.
644 Up to win7, the function succeeds with a partial result. */
645 status = pNtQuerySystemInformation(SystemCacheInformation, sci, i, &ReturnLength);
646 if (!status)
647 {
648 expected = offsetof(SYSTEM_CACHE_INFORMATION, MinimumWorkingSet);
649 for (; i>= expected; i--)
650 {
651 ReturnLength = 0xdeadbeef;
652 status = pNtQuerySystemInformation(SystemCacheInformation, sci, i, &ReturnLength);
653 ok(!status && (ReturnLength == expected),
654 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i, status, ReturnLength, expected);
655 }
656 }
657
658 /* buffer too small for the result, this call will always fail */
659 ReturnLength = 0xdeadbeef;
660 status = pNtQuerySystemInformation(SystemCacheInformation, sci, i, &ReturnLength);
661 ok( status == STATUS_INFO_LENGTH_MISMATCH &&
662 ((ReturnLength == expected) || broken(!ReturnLength) || broken(ReturnLength == 0xfffffff0)),
663 "%d: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", i, status, ReturnLength, expected);
664
665 if (0) {
666 /* this crashes on some vista / win7 machines */
667 ReturnLength = 0xdeadbeef;
668 status = pNtQuerySystemInformation(SystemCacheInformation, sci, 0, &ReturnLength);
669 ok( status == STATUS_INFO_LENGTH_MISMATCH &&
670 ((ReturnLength == expected) || broken(!ReturnLength) || broken(ReturnLength == 0xfffffff0)),
671 "0: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", status, ReturnLength, expected);
672 }
673 }
674
test_query_interrupt(void)675 static void test_query_interrupt(void)
676 {
677 NTSTATUS status;
678 ULONG ReturnLength;
679 ULONG NeededLength;
680 SYSTEM_BASIC_INFORMATION sbi;
681 SYSTEM_INTERRUPT_INFORMATION* sii;
682
683 /* Find out the number of processors */
684 status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength);
685 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
686 NeededLength = sbi.NumberOfProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION);
687
688 sii = HeapAlloc(GetProcessHeap(), 0, NeededLength);
689
690 status = pNtQuerySystemInformation(SystemInterruptInformation, sii, 0, &ReturnLength);
691 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
692
693 /* Try it for all processors */
694 status = pNtQuerySystemInformation(SystemInterruptInformation, sii, NeededLength, &ReturnLength);
695 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
696
697 /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength
698 * No test added for this as it's highly unlikely that an app depends on this
699 */
700
701 HeapFree( GetProcessHeap(), 0, sii);
702 }
703
test_query_kerndebug(void)704 static void test_query_kerndebug(void)
705 {
706 NTSTATUS status;
707 ULONG ReturnLength;
708 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi;
709
710 status = pNtQuerySystemInformation(SystemKernelDebuggerInformation, &skdi, 0, &ReturnLength);
711 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
712
713 status = pNtQuerySystemInformation(SystemKernelDebuggerInformation, &skdi, sizeof(skdi), &ReturnLength);
714 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
715 ok( sizeof(skdi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
716
717 status = pNtQuerySystemInformation(SystemKernelDebuggerInformation, &skdi, sizeof(skdi) + 2, &ReturnLength);
718 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
719 ok( sizeof(skdi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
720 }
721
test_query_regquota(void)722 static void test_query_regquota(void)
723 {
724 NTSTATUS status;
725 ULONG ReturnLength;
726 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi;
727
728 status = pNtQuerySystemInformation(SystemRegistryQuotaInformation, &srqi, 0, &ReturnLength);
729 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
730
731 status = pNtQuerySystemInformation(SystemRegistryQuotaInformation, &srqi, sizeof(srqi), &ReturnLength);
732 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
733 ok( sizeof(srqi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
734
735 status = pNtQuerySystemInformation(SystemRegistryQuotaInformation, &srqi, sizeof(srqi) + 2, &ReturnLength);
736 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
737 ok( sizeof(srqi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
738 }
739
test_query_logicalproc(void)740 static void test_query_logicalproc(void)
741 {
742 NTSTATUS status;
743 ULONG len, i, proc_no;
744 SYSTEM_LOGICAL_PROCESSOR_INFORMATION *slpi;
745 SYSTEM_INFO si;
746
747 GetSystemInfo(&si);
748
749 status = pNtQuerySystemInformation(SystemLogicalProcessorInformation, NULL, 0, &len);
750 if(status == STATUS_INVALID_INFO_CLASS)
751 {
752 win_skip("SystemLogicalProcessorInformation is not supported\n");
753 return;
754 }
755 if(status == STATUS_NOT_IMPLEMENTED)
756 {
757 todo_wine ok(0, "SystemLogicalProcessorInformation is not implemented\n");
758 return;
759 }
760 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
761 ok(len%sizeof(*slpi) == 0, "Incorrect length %d\n", len);
762
763 slpi = HeapAlloc(GetProcessHeap(), 0, len);
764 status = pNtQuerySystemInformation(SystemLogicalProcessorInformation, slpi, len, &len);
765 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
766
767 proc_no = 0;
768 for(i=0; i<len/sizeof(*slpi); i++) {
769 switch(slpi[i].Relationship) {
770 case RelationProcessorCore:
771 /* Get number of logical processors */
772 for(; slpi[i].ProcessorMask; slpi[i].ProcessorMask /= 2)
773 proc_no += slpi[i].ProcessorMask%2;
774 break;
775 default:
776 break;
777 }
778 }
779 ok(proc_no > 0, "No processors were found\n");
780 if(si.dwNumberOfProcessors <= 32)
781 ok(proc_no == si.dwNumberOfProcessors, "Incorrect number of logical processors: %d, expected %d\n",
782 proc_no, si.dwNumberOfProcessors);
783
784 HeapFree(GetProcessHeap(), 0, slpi);
785 }
786
test_query_logicalprocex(void)787 static void test_query_logicalprocex(void)
788 {
789 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex, *infoex2;
790 DWORD relationship, len2, len;
791 NTSTATUS status;
792 BOOL ret;
793
794 if (!pNtQuerySystemInformationEx)
795 return;
796
797 len = 0;
798 relationship = RelationProcessorCore;
799 status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), NULL, 0, &len);
800 ok(status == STATUS_INFO_LENGTH_MISMATCH, "got 0x%08x\n", status);
801 ok(len > 0, "got %u\n", len);
802
803 len = 0;
804 relationship = RelationAll;
805 status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), NULL, 0, &len);
806 ok(status == STATUS_INFO_LENGTH_MISMATCH, "got 0x%08x\n", status);
807 ok(len > 0, "got %u\n", len);
808
809 len2 = 0;
810 ret = pGetLogicalProcessorInformationEx(RelationAll, NULL, &len2);
811 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d, error %d\n", ret, GetLastError());
812 ok(len == len2, "got %u, expected %u\n", len2, len);
813
814 if (len && len == len2) {
815 int j, i;
816
817 infoex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
818 infoex2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
819
820 status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), infoex, len, &len);
821 ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
822
823 ret = pGetLogicalProcessorInformationEx(RelationAll, infoex2, &len2);
824 ok(ret, "got %d, error %d\n", ret, GetLastError());
825 ok(!memcmp(infoex, infoex2, len), "returned info data mismatch\n");
826
827 for(i = 0; status == STATUS_SUCCESS && i < len; ){
828 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *ex = (void*)(((char *)infoex) + i);
829
830 ok(ex->Relationship >= RelationProcessorCore && ex->Relationship <= RelationGroup,
831 "Got invalid relationship value: 0x%x\n", ex->Relationship);
832 if (!ex->Size)
833 {
834 ok(0, "got infoex[%u].Size=0\n", i);
835 break;
836 }
837
838 trace("infoex[%u].Size: %u\n", i, ex->Size);
839 switch(ex->Relationship){
840 case RelationProcessorCore:
841 case RelationProcessorPackage:
842 trace("infoex[%u].Relationship: 0x%x (Core == 0x0 or Package == 0x3)\n", i, ex->Relationship);
843 trace("infoex[%u].Processor.Flags: 0x%x\n", i, ex->Processor.Flags);
844 #ifndef __REACTOS__
845 trace("infoex[%u].Processor.EfficiencyClass: 0x%x\n", i, ex->Processor.EfficiencyClass);
846 #endif
847 trace("infoex[%u].Processor.GroupCount: 0x%x\n", i, ex->Processor.GroupCount);
848 for(j = 0; j < ex->Processor.GroupCount; ++j){
849 trace("infoex[%u].Processor.GroupMask[%u].Mask: 0x%lx\n", i, j, ex->Processor.GroupMask[j].Mask);
850 trace("infoex[%u].Processor.GroupMask[%u].Group: 0x%x\n", i, j, ex->Processor.GroupMask[j].Group);
851 }
852 break;
853 case RelationNumaNode:
854 trace("infoex[%u].Relationship: 0x%x (NumaNode)\n", i, ex->Relationship);
855 trace("infoex[%u].NumaNode.NodeNumber: 0x%x\n", i, ex->NumaNode.NodeNumber);
856 trace("infoex[%u].NumaNode.GroupMask.Mask: 0x%lx\n", i, ex->NumaNode.GroupMask.Mask);
857 trace("infoex[%u].NumaNode.GroupMask.Group: 0x%x\n", i, ex->NumaNode.GroupMask.Group);
858 break;
859 case RelationCache:
860 trace("infoex[%u].Relationship: 0x%x (Cache)\n", i, ex->Relationship);
861 trace("infoex[%u].Cache.Level: 0x%x\n", i, ex->Cache.Level);
862 trace("infoex[%u].Cache.Associativity: 0x%x\n", i, ex->Cache.Associativity);
863 trace("infoex[%u].Cache.LineSize: 0x%x\n", i, ex->Cache.LineSize);
864 trace("infoex[%u].Cache.CacheSize: 0x%x\n", i, ex->Cache.CacheSize);
865 trace("infoex[%u].Cache.Type: 0x%x\n", i, ex->Cache.Type);
866 trace("infoex[%u].Cache.GroupMask.Mask: 0x%lx\n", i, ex->Cache.GroupMask.Mask);
867 trace("infoex[%u].Cache.GroupMask.Group: 0x%x\n", i, ex->Cache.GroupMask.Group);
868 break;
869 case RelationGroup:
870 trace("infoex[%u].Relationship: 0x%x (Group)\n", i, ex->Relationship);
871 trace("infoex[%u].Group.MaximumGroupCount: 0x%x\n", i, ex->Group.MaximumGroupCount);
872 trace("infoex[%u].Group.ActiveGroupCount: 0x%x\n", i, ex->Group.ActiveGroupCount);
873 for(j = 0; j < ex->Group.ActiveGroupCount; ++j){
874 trace("infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x\n", i, j, ex->Group.GroupInfo[j].MaximumProcessorCount);
875 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x\n", i, j, ex->Group.GroupInfo[j].ActiveProcessorCount);
876 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%lx\n", i, j, ex->Group.GroupInfo[j].ActiveProcessorMask);
877 }
878 break;
879 default:
880 break;
881 }
882
883 i += ex->Size;
884 }
885
886 HeapFree(GetProcessHeap(), 0, infoex);
887 HeapFree(GetProcessHeap(), 0, infoex2);
888 }
889 }
890
test_query_processor_power_info(void)891 static void test_query_processor_power_info(void)
892 {
893 NTSTATUS status;
894 PROCESSOR_POWER_INFORMATION* ppi;
895 ULONG size;
896 SYSTEM_INFO si;
897 int i;
898
899 GetSystemInfo(&si);
900 size = si.dwNumberOfProcessors * sizeof(PROCESSOR_POWER_INFORMATION);
901 ppi = HeapAlloc(GetProcessHeap(), 0, size);
902
903 /* If size < (sizeof(PROCESSOR_POWER_INFORMATION) * NumberOfProcessors), Win7 returns
904 * STATUS_BUFFER_TOO_SMALL. WinXP returns STATUS_SUCCESS for any value of size. It copies as
905 * many whole PROCESSOR_POWER_INFORMATION structures that there is room for. Even if there is
906 * not enough room for one structure, WinXP still returns STATUS_SUCCESS having done nothing.
907 *
908 * If ppi == NULL, Win7 returns STATUS_INVALID_PARAMETER while WinXP returns STATUS_SUCCESS
909 * and does nothing.
910 *
911 * The same behavior is seen with CallNtPowerInformation (in powrprof.dll).
912 */
913
914 if (si.dwNumberOfProcessors > 1)
915 {
916 for(i = 0; i < si.dwNumberOfProcessors; i++)
917 ppi[i].Number = 0xDEADBEEF;
918
919 /* Call with a buffer size that is large enough to hold at least one but not large
920 * enough to hold them all. This will be STATUS_SUCCESS on WinXP but not on Win7 */
921 status = pNtPowerInformation(ProcessorInformation, 0, 0, ppi, size - sizeof(PROCESSOR_POWER_INFORMATION));
922 if (status == STATUS_SUCCESS)
923 {
924 /* lax version found on older Windows like WinXP */
925 ok( (ppi[si.dwNumberOfProcessors - 2].Number != 0xDEADBEEF) &&
926 (ppi[si.dwNumberOfProcessors - 1].Number == 0xDEADBEEF),
927 "Expected all but the last record to be overwritten.\n");
928
929 status = pNtPowerInformation(ProcessorInformation, 0, 0, 0, size);
930 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
931
932 for(i = 0; i < si.dwNumberOfProcessors; i++)
933 ppi[i].Number = 0xDEADBEEF;
934 status = pNtPowerInformation(ProcessorInformation, 0, 0, ppi, sizeof(PROCESSOR_POWER_INFORMATION) - 1);
935 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
936 for(i = 0; i < si.dwNumberOfProcessors; i++)
937 if (ppi[i].Number != 0xDEADBEEF) break;
938 ok( i == si.dwNumberOfProcessors, "Expected untouched buffer\n");
939 }
940 else
941 {
942 /* picky version found on newer Windows like Win7 */
943 ok( ppi[1].Number == 0xDEADBEEF, "Expected untouched buffer.\n");
944 ok( status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status);
945
946 status = pNtPowerInformation(ProcessorInformation, 0, 0, 0, size);
947 ok( status == STATUS_SUCCESS || status == STATUS_INVALID_PARAMETER, "Got %08x\n", status);
948
949 status = pNtPowerInformation(ProcessorInformation, 0, 0, ppi, 0);
950 ok( status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INVALID_PARAMETER, "Got %08x\n", status);
951 }
952 }
953 else
954 {
955 skip("Test needs more than one processor.\n");
956 }
957
958 status = pNtPowerInformation(ProcessorInformation, 0, 0, ppi, size);
959 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
960
961 HeapFree(GetProcessHeap(), 0, ppi);
962 }
963
test_query_process_wow64(void)964 static void test_query_process_wow64(void)
965 {
966 NTSTATUS status;
967 ULONG ReturnLength;
968 ULONG_PTR pbi[2], dummy;
969
970 memset(&dummy, 0xcc, sizeof(dummy));
971
972 /* Do not give a handle and buffer */
973 status = pNtQueryInformationProcess(NULL, ProcessWow64Information, NULL, 0, NULL);
974 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
975
976 /* Use a correct info class and buffer size, but still no handle and buffer */
977 status = pNtQueryInformationProcess(NULL, ProcessWow64Information, NULL, sizeof(ULONG_PTR), NULL);
978 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
979 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE, got %08x\n", status);
980
981 /* Use a correct info class, buffer size and handle, but no buffer */
982 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, NULL, sizeof(ULONG_PTR), NULL);
983 ok( status == STATUS_ACCESS_VIOLATION , "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
984
985 /* Use a correct info class, buffer and buffer size, but no handle */
986 pbi[0] = pbi[1] = dummy;
987 status = pNtQueryInformationProcess(NULL, ProcessWow64Information, pbi, sizeof(ULONG_PTR), NULL);
988 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
989 ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
990 ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
991
992 /* Use a greater buffer size */
993 pbi[0] = pbi[1] = dummy;
994 status = pNtQueryInformationProcess(NULL, ProcessWow64Information, pbi, sizeof(ULONG_PTR) + 1, NULL);
995 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
996 ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
997 ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
998
999 /* Use no ReturnLength */
1000 pbi[0] = pbi[1] = dummy;
1001 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR), NULL);
1002 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1003 trace( "Platform is_wow64 %d, ProcessInformation of ProcessWow64Information %lx\n", is_wow64, pbi[0]);
1004 ok( is_wow64 == (pbi[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64, pbi[0]);
1005 ok( pbi[0] != dummy, "pbi[0] %lx\n", pbi[0]);
1006 ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
1007 /* Test written size on 64 bit by checking high 32 bit buffer */
1008 if (sizeof(ULONG_PTR) > sizeof(DWORD))
1009 {
1010 DWORD *ptr = (DWORD *)pbi;
1011 ok( ptr[1] != (DWORD)dummy, "ptr[1] unchanged!\n");
1012 }
1013
1014 /* Finally some correct calls */
1015 pbi[0] = pbi[1] = dummy;
1016 ReturnLength = 0xdeadbeef;
1017 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR), &ReturnLength);
1018 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1019 ok( is_wow64 == (pbi[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64, pbi[0]);
1020 ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
1021 ok( ReturnLength == sizeof(ULONG_PTR), "Inconsistent length %d\n", ReturnLength);
1022
1023 /* Everything is correct except a too small buffer size */
1024 pbi[0] = pbi[1] = dummy;
1025 ReturnLength = 0xdeadbeef;
1026 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR) - 1, &ReturnLength);
1027 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1028 ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
1029 ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
1030 todo_wine ok( ReturnLength == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength);
1031
1032 /* Everything is correct except a too large buffer size */
1033 pbi[0] = pbi[1] = dummy;
1034 ReturnLength = 0xdeadbeef;
1035 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR) + 1, &ReturnLength);
1036 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1037 ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
1038 ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
1039 todo_wine ok( ReturnLength == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength);
1040 }
1041
test_query_process_basic(void)1042 static void test_query_process_basic(void)
1043 {
1044 NTSTATUS status;
1045 ULONG ReturnLength;
1046
1047 typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE {
1048 DWORD_PTR ExitStatus;
1049 PPEB PebBaseAddress;
1050 DWORD_PTR AffinityMask;
1051 DWORD_PTR BasePriority;
1052 ULONG_PTR UniqueProcessId;
1053 ULONG_PTR InheritedFromUniqueProcessId;
1054 } PROCESS_BASIC_INFORMATION_PRIVATE;
1055
1056 PROCESS_BASIC_INFORMATION_PRIVATE pbi;
1057
1058 /* This test also covers some basic parameter testing that should be the same for
1059 * every information class
1060 */
1061
1062 /* Use a nonexistent info class */
1063 trace("Check nonexistent info class\n");
1064 status = pNtQueryInformationProcess(NULL, -1, NULL, 0, NULL);
1065 ok( status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* vista */,
1066 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status);
1067
1068 /* Do not give a handle and buffer */
1069 trace("Check NULL handle and buffer and zero-length buffersize\n");
1070 status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, NULL, 0, NULL);
1071 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1072
1073 /* Use a correct info class and buffer size, but still no handle and buffer */
1074 trace("Check NULL handle and buffer\n");
1075 status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, NULL, sizeof(pbi), NULL);
1076 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
1077 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status);
1078
1079 /* Use a correct info class and buffer size, but still no handle */
1080 trace("Check NULL handle\n");
1081 status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
1082 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1083
1084 /* Use a greater buffer size */
1085 trace("Check NULL handle and too large buffersize\n");
1086 status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, &pbi, sizeof(pbi) * 2, NULL);
1087 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1088
1089 /* Use no ReturnLength */
1090 trace("Check NULL ReturnLength\n");
1091 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
1092 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1093
1094 /* Finally some correct calls */
1095 trace("Check with correct parameters\n");
1096 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &ReturnLength);
1097 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1098 ok( sizeof(pbi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1099
1100 /* Everything is correct except a too large buffersize */
1101 trace("Too large buffersize\n");
1102 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi) * 2, &ReturnLength);
1103 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1104 ok( sizeof(pbi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1105
1106 /* Check if we have some return values */
1107 trace("ProcessID : %lx\n", pbi.UniqueProcessId);
1108 ok( pbi.UniqueProcessId > 0, "Expected a ProcessID > 0, got 0\n");
1109 }
1110
dump_vm_counters(const char * header,const VM_COUNTERS * pvi)1111 static void dump_vm_counters(const char *header, const VM_COUNTERS *pvi)
1112 {
1113 trace("%s:\n", header);
1114 trace("PeakVirtualSize : %lu\n", pvi->PeakVirtualSize);
1115 trace("VirtualSize : %lu\n", pvi->VirtualSize);
1116 trace("PageFaultCount : %u\n", pvi->PageFaultCount);
1117 trace("PeakWorkingSetSize : %lu\n", pvi->PeakWorkingSetSize);
1118 trace("WorkingSetSize : %lu\n", pvi->WorkingSetSize);
1119 trace("QuotaPeakPagedPoolUsage : %lu\n", pvi->QuotaPeakPagedPoolUsage);
1120 trace("QuotaPagedPoolUsage : %lu\n", pvi->QuotaPagedPoolUsage);
1121 trace("QuotaPeakNonPagePoolUsage : %lu\n", pvi->QuotaPeakNonPagedPoolUsage);
1122 trace("QuotaNonPagePoolUsage : %lu\n", pvi->QuotaNonPagedPoolUsage);
1123 trace("PagefileUsage : %lu\n", pvi->PagefileUsage);
1124 trace("PeakPagefileUsage : %lu\n", pvi->PeakPagefileUsage);
1125 }
1126
test_query_process_vm(void)1127 static void test_query_process_vm(void)
1128 {
1129 NTSTATUS status;
1130 ULONG ReturnLength;
1131 VM_COUNTERS pvi;
1132 ULONG old_size = FIELD_OFFSET(VM_COUNTERS,PrivatePageCount);
1133 HANDLE process;
1134 SIZE_T prev_size;
1135 const SIZE_T alloc_size = 16 * 1024 * 1024;
1136 void *ptr;
1137
1138 status = pNtQueryInformationProcess(NULL, ProcessVmCounters, NULL, sizeof(pvi), NULL);
1139 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
1140 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status);
1141
1142 status = pNtQueryInformationProcess(NULL, ProcessVmCounters, &pvi, old_size, NULL);
1143 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1144
1145 /* Windows XP and W2K3 will report success for a size of 44 AND 48 !
1146 Windows W2K will only report success for 44.
1147 For now we only care for 44, which is FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
1148 */
1149
1150 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, 24, &ReturnLength);
1151 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1152
1153 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, old_size, &ReturnLength);
1154 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1155 ok( old_size == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1156
1157 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, 46, &ReturnLength);
1158 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1159 ok( ReturnLength == old_size || ReturnLength == sizeof(pvi), "Inconsistent length %d\n", ReturnLength);
1160
1161 /* Check if we have some return values */
1162 dump_vm_counters("VM counters for GetCurrentProcess", &pvi);
1163 ok( pvi.WorkingSetSize > 0, "Expected a WorkingSetSize > 0\n");
1164 ok( pvi.PagefileUsage > 0, "Expected a PagefileUsage > 0\n");
1165
1166 process = OpenProcess(PROCESS_VM_READ, FALSE, GetCurrentProcessId());
1167 status = pNtQueryInformationProcess(process, ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1168 ok( status == STATUS_ACCESS_DENIED, "Expected STATUS_ACCESS_DENIED, got %08x\n", status);
1169 CloseHandle(process);
1170
1171 process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCurrentProcessId());
1172 status = pNtQueryInformationProcess(process, ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1173 ok( status == STATUS_SUCCESS || broken(!process) /* XP */, "Expected STATUS_SUCCESS, got %08x\n", status);
1174 CloseHandle(process);
1175
1176 memset(&pvi, 0, sizeof(pvi));
1177 process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
1178 status = pNtQueryInformationProcess(process, ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1179 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1180
1181 /* Check if we have some return values */
1182 dump_vm_counters("VM counters for GetCurrentProcessId", &pvi);
1183 ok( pvi.WorkingSetSize > 0, "Expected a WorkingSetSize > 0\n");
1184 ok( pvi.PagefileUsage > 0, "Expected a PagefileUsage > 0\n");
1185
1186 CloseHandle(process);
1187
1188 /* Check if we have real counters */
1189 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1190 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1191 prev_size = pvi.VirtualSize;
1192 if (winetest_debug > 1)
1193 dump_vm_counters("VM counters before VirtualAlloc", &pvi);
1194 ptr = VirtualAlloc(NULL, alloc_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
1195 ok( ptr != NULL, "VirtualAlloc failed, err %u\n", GetLastError());
1196 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1197 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1198 if (winetest_debug > 1)
1199 dump_vm_counters("VM counters after VirtualAlloc", &pvi);
1200 todo_wine ok( pvi.VirtualSize >= prev_size + alloc_size,
1201 "Expected to be greater than %lu, got %lu\n", prev_size + alloc_size, pvi.VirtualSize);
1202 VirtualFree( ptr, 0, MEM_RELEASE);
1203
1204 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1205 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1206 prev_size = pvi.VirtualSize;
1207 if (winetest_debug > 1)
1208 dump_vm_counters("VM counters before VirtualAlloc", &pvi);
1209 ptr = VirtualAlloc(NULL, alloc_size, MEM_RESERVE, PAGE_READWRITE);
1210 ok( ptr != NULL, "VirtualAlloc failed, err %u\n", GetLastError());
1211 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1212 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1213 if (winetest_debug > 1)
1214 dump_vm_counters("VM counters after VirtualAlloc(MEM_RESERVE)", &pvi);
1215 todo_wine ok( pvi.VirtualSize >= prev_size + alloc_size,
1216 "Expected to be greater than %lu, got %lu\n", prev_size + alloc_size, pvi.VirtualSize);
1217 prev_size = pvi.VirtualSize;
1218
1219 ptr = VirtualAlloc(ptr, alloc_size, MEM_COMMIT, PAGE_READWRITE);
1220 ok( ptr != NULL, "VirtualAlloc failed, err %u\n", GetLastError());
1221 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters, &pvi, sizeof(pvi), NULL);
1222 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1223 if (winetest_debug > 1)
1224 dump_vm_counters("VM counters after VirtualAlloc(MEM_COMMIT)", &pvi);
1225 ok( pvi.VirtualSize == prev_size,
1226 "Expected to equal to %lu, got %lu\n", prev_size, pvi.VirtualSize);
1227 VirtualFree( ptr, 0, MEM_RELEASE);
1228 }
1229
test_query_process_io(void)1230 static void test_query_process_io(void)
1231 {
1232 NTSTATUS status;
1233 ULONG ReturnLength;
1234 IO_COUNTERS pii;
1235
1236 /* NT4 doesn't support this information class, so check for it */
1237 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, sizeof(pii), &ReturnLength);
1238 if (status == STATUS_NOT_SUPPORTED)
1239 {
1240 win_skip("ProcessIoCounters information class is not supported\n");
1241 return;
1242 }
1243
1244 status = pNtQueryInformationProcess(NULL, ProcessIoCounters, NULL, sizeof(pii), NULL);
1245 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
1246 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status);
1247
1248 status = pNtQueryInformationProcess(NULL, ProcessIoCounters, &pii, sizeof(pii), NULL);
1249 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1250
1251 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, 24, &ReturnLength);
1252 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1253
1254 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, sizeof(pii), &ReturnLength);
1255 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1256 ok( sizeof(pii) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1257
1258 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, sizeof(pii) * 2, &ReturnLength);
1259 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1260 ok( sizeof(pii) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1261
1262 /* Check if we have some return values */
1263 trace("OtherOperationCount : 0x%s\n", wine_dbgstr_longlong(pii.OtherOperationCount));
1264 todo_wine
1265 {
1266 ok( pii.OtherOperationCount > 0, "Expected an OtherOperationCount > 0\n");
1267 }
1268 }
1269
test_query_process_times(void)1270 static void test_query_process_times(void)
1271 {
1272 NTSTATUS status;
1273 ULONG ReturnLength;
1274 HANDLE process;
1275 SYSTEMTIME UTC, Local;
1276 KERNEL_USER_TIMES spti;
1277
1278 status = pNtQueryInformationProcess(NULL, ProcessTimes, NULL, sizeof(spti), NULL);
1279 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
1280 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status);
1281
1282 status = pNtQueryInformationProcess(NULL, ProcessTimes, &spti, sizeof(spti), NULL);
1283 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1284
1285 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes, &spti, 24, &ReturnLength);
1286 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1287
1288 process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, one_before_last_pid);
1289 if (!process)
1290 {
1291 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid, GetLastError());
1292 process = GetCurrentProcess();
1293 trace("ProcessTimes for current process\n");
1294 }
1295 else
1296 trace("ProcessTimes for process with ID : %d\n", one_before_last_pid);
1297
1298 status = pNtQueryInformationProcess( process, ProcessTimes, &spti, sizeof(spti), &ReturnLength);
1299 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1300 ok( sizeof(spti) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1301 CloseHandle(process);
1302
1303 FileTimeToSystemTime((const FILETIME *)&spti.CreateTime, &UTC);
1304 SystemTimeToTzSpecificLocalTime(NULL, &UTC, &Local);
1305 trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local.wMonth, Local.wDay, Local.wYear,
1306 Local.wHour, Local.wMinute, Local.wSecond);
1307
1308 FileTimeToSystemTime((const FILETIME *)&spti.ExitTime, &UTC);
1309 SystemTimeToTzSpecificLocalTime(NULL, &UTC, &Local);
1310 trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local.wMonth, Local.wDay, Local.wYear,
1311 Local.wHour, Local.wMinute, Local.wSecond);
1312
1313 FileTimeToSystemTime((const FILETIME *)&spti.KernelTime, &Local);
1314 trace("KernelTime : %02d:%02d:%02d.%03d\n", Local.wHour, Local.wMinute, Local.wSecond, Local.wMilliseconds);
1315
1316 FileTimeToSystemTime((const FILETIME *)&spti.UserTime, &Local);
1317 trace("UserTime : %02d:%02d:%02d.%03d\n", Local.wHour, Local.wMinute, Local.wSecond, Local.wMilliseconds);
1318
1319 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes, &spti, sizeof(spti) * 2, &ReturnLength);
1320 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1321 ok( sizeof(spti) == ReturnLength ||
1322 ReturnLength == 0 /* vista */ ||
1323 broken(is_wow64), /* returns garbage on wow64 */
1324 "Inconsistent length %d\n", ReturnLength);
1325 }
1326
test_query_process_debug_port(int argc,char ** argv)1327 static void test_query_process_debug_port(int argc, char **argv)
1328 {
1329 DWORD_PTR debug_port = 0xdeadbeef;
1330 char cmdline[MAX_PATH];
1331 PROCESS_INFORMATION pi;
1332 STARTUPINFOA si = { 0 };
1333 NTSTATUS status;
1334 BOOL ret;
1335
1336 sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
1337
1338 si.cb = sizeof(si);
1339 ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
1340 ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
1341 if (!ret) return;
1342
1343 status = pNtQueryInformationProcess(NULL, ProcessDebugPort,
1344 NULL, 0, NULL);
1345 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
1346
1347 status = pNtQueryInformationProcess(NULL, ProcessDebugPort,
1348 NULL, sizeof(debug_port), NULL);
1349 ok(status == STATUS_INVALID_HANDLE || status == STATUS_ACCESS_VIOLATION,
1350 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status);
1351
1352 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
1353 NULL, sizeof(debug_port), NULL);
1354 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
1355
1356 status = pNtQueryInformationProcess(NULL, ProcessDebugPort,
1357 &debug_port, sizeof(debug_port), NULL);
1358 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %#x.\n", status);
1359
1360 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
1361 &debug_port, sizeof(debug_port) - 1, NULL);
1362 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
1363
1364 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
1365 &debug_port, sizeof(debug_port) + 1, NULL);
1366 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
1367
1368 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
1369 &debug_port, sizeof(debug_port), NULL);
1370 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1371 ok(debug_port == 0, "Expected port 0, got %#lx.\n", debug_port);
1372
1373 status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugPort,
1374 &debug_port, sizeof(debug_port), NULL);
1375 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1376 ok(debug_port == ~(DWORD_PTR)0, "Expected port %#lx, got %#lx.\n", ~(DWORD_PTR)0, debug_port);
1377
1378 for (;;)
1379 {
1380 DEBUG_EVENT ev;
1381
1382 ret = WaitForDebugEvent(&ev, INFINITE);
1383 ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1384 if (!ret) break;
1385
1386 if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
1387
1388 ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
1389 ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1390 if (!ret) break;
1391 }
1392
1393 ret = CloseHandle(pi.hThread);
1394 ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
1395 ret = CloseHandle(pi.hProcess);
1396 ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
1397 }
1398
test_query_process_priority(void)1399 static void test_query_process_priority(void)
1400 {
1401 PROCESS_PRIORITY_CLASS priority[2];
1402 ULONG ReturnLength;
1403 DWORD orig_priority;
1404 NTSTATUS status;
1405 BOOL ret;
1406
1407 status = pNtQueryInformationProcess(NULL, ProcessPriorityClass, NULL, sizeof(priority[0]), NULL);
1408 ok(status == STATUS_ACCESS_VIOLATION || broken(status == STATUS_INVALID_HANDLE) /* w2k3 */,
1409 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
1410
1411 status = pNtQueryInformationProcess(NULL, ProcessPriorityClass, &priority, sizeof(priority[0]), NULL);
1412 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1413
1414 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass, &priority, 1, &ReturnLength);
1415 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1416
1417 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass, &priority, sizeof(priority), &ReturnLength);
1418 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1419
1420 orig_priority = GetPriorityClass(GetCurrentProcess());
1421 ret = SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
1422 ok(ret, "Failed to set priority class: %u\n", GetLastError());
1423
1424 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass, &priority, sizeof(priority[0]), &ReturnLength);
1425 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1426 ok(priority[0].PriorityClass == PROCESS_PRIOCLASS_BELOW_NORMAL,
1427 "Expected PROCESS_PRIOCLASS_BELOW_NORMAL, got %u\n", priority[0].PriorityClass);
1428
1429 ret = SetPriorityClass(GetCurrentProcess(), orig_priority);
1430 ok(ret, "Failed to reset priority class: %u\n", GetLastError());
1431 }
1432
test_query_process_handlecount(void)1433 static void test_query_process_handlecount(void)
1434 {
1435 NTSTATUS status;
1436 ULONG ReturnLength;
1437 DWORD handlecount;
1438 BYTE buffer[2 * sizeof(DWORD)];
1439 HANDLE process;
1440
1441 status = pNtQueryInformationProcess(NULL, ProcessHandleCount, NULL, sizeof(handlecount), NULL);
1442 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
1443 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status);
1444
1445 status = pNtQueryInformationProcess(NULL, ProcessHandleCount, &handlecount, sizeof(handlecount), NULL);
1446 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1447
1448 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount, &handlecount, 2, &ReturnLength);
1449 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1450
1451 process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, one_before_last_pid);
1452 if (!process)
1453 {
1454 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid, GetLastError());
1455 process = GetCurrentProcess();
1456 trace("ProcessHandleCount for current process\n");
1457 }
1458 else
1459 trace("ProcessHandleCount for process with ID : %d\n", one_before_last_pid);
1460
1461 status = pNtQueryInformationProcess( process, ProcessHandleCount, &handlecount, sizeof(handlecount), &ReturnLength);
1462 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1463 ok( sizeof(handlecount) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1464 CloseHandle(process);
1465
1466 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount, buffer, sizeof(buffer), &ReturnLength);
1467 ok( status == STATUS_INFO_LENGTH_MISMATCH || status == STATUS_SUCCESS,
1468 "Expected STATUS_INFO_LENGTH_MISMATCH or STATUS_SUCCESS, got %08x\n", status);
1469 ok( sizeof(handlecount) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
1470
1471 /* Check if we have some return values */
1472 trace("HandleCount : %d\n", handlecount);
1473 todo_wine
1474 {
1475 ok( handlecount > 0, "Expected some handles, got 0\n");
1476 }
1477 }
1478
test_query_process_image_file_name(void)1479 static void test_query_process_image_file_name(void)
1480 {
1481 NTSTATUS status;
1482 ULONG ReturnLength;
1483 UNICODE_STRING image_file_name;
1484 void *buffer;
1485 char *file_nameA;
1486 INT len;
1487
1488 status = pNtQueryInformationProcess(NULL, ProcessImageFileName, &image_file_name, sizeof(image_file_name), NULL);
1489 if (status == STATUS_INVALID_INFO_CLASS)
1490 {
1491 win_skip("ProcessImageFileName is not supported\n");
1492 return;
1493 }
1494 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1495
1496 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName, &image_file_name, 2, &ReturnLength);
1497 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1498
1499 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName, &image_file_name, sizeof(image_file_name), &ReturnLength);
1500 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
1501
1502 buffer = HeapAlloc(GetProcessHeap(), 0, ReturnLength);
1503 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName, buffer, ReturnLength, &ReturnLength);
1504 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1505 memcpy(&image_file_name, buffer, sizeof(image_file_name));
1506 len = WideCharToMultiByte(CP_ACP, 0, image_file_name.Buffer, image_file_name.Length/sizeof(WCHAR), NULL, 0, NULL, NULL);
1507 file_nameA = HeapAlloc(GetProcessHeap(), 0, len + 1);
1508 WideCharToMultiByte(CP_ACP, 0, image_file_name.Buffer, image_file_name.Length/sizeof(WCHAR), file_nameA, len, NULL, NULL);
1509 file_nameA[len] = '\0';
1510 HeapFree(GetProcessHeap(), 0, buffer);
1511 trace("process image file name: %s\n", file_nameA);
1512 todo_wine ok(strncmp(file_nameA, "\\Device\\", 8) == 0, "Process image name should be an NT path beginning with \\Device\\ (is %s)\n", file_nameA);
1513 HeapFree(GetProcessHeap(), 0, file_nameA);
1514 }
1515
test_query_process_debug_object_handle(int argc,char ** argv)1516 static void test_query_process_debug_object_handle(int argc, char **argv)
1517 {
1518 char cmdline[MAX_PATH];
1519 STARTUPINFOA si = {0};
1520 PROCESS_INFORMATION pi;
1521 BOOL ret;
1522 HANDLE debug_object;
1523 NTSTATUS status;
1524
1525 sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
1526
1527 si.cb = sizeof(si);
1528 ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL,
1529 NULL, &si, &pi);
1530 ok(ret, "CreateProcess failed with last error %u\n", GetLastError());
1531 if (!ret) return;
1532
1533 status = pNtQueryInformationProcess(NULL, ProcessDebugObjectHandle, NULL,
1534 0, NULL);
1535 if (status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED)
1536 {
1537 win_skip("ProcessDebugObjectHandle is not supported\n");
1538 return;
1539 }
1540 ok(status == STATUS_INFO_LENGTH_MISMATCH,
1541 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n",
1542 status);
1543
1544 status = pNtQueryInformationProcess(NULL, ProcessDebugObjectHandle, NULL,
1545 sizeof(debug_object), NULL);
1546 ok(status == STATUS_INVALID_HANDLE ||
1547 status == STATUS_ACCESS_VIOLATION, /* XP */
1548 "Expected NtQueryInformationProcess to return STATUS_INVALID_HANDLE, got 0x%08x\n", status);
1549
1550 status = pNtQueryInformationProcess(GetCurrentProcess(),
1551 ProcessDebugObjectHandle, NULL, sizeof(debug_object), NULL);
1552 ok(status == STATUS_ACCESS_VIOLATION,
1553 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status);
1554
1555 status = pNtQueryInformationProcess(NULL, ProcessDebugObjectHandle,
1556 &debug_object, sizeof(debug_object), NULL);
1557 ok(status == STATUS_INVALID_HANDLE,
1558 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status);
1559
1560 status = pNtQueryInformationProcess(GetCurrentProcess(),
1561 ProcessDebugObjectHandle, &debug_object,
1562 sizeof(debug_object) - 1, NULL);
1563 ok(status == STATUS_INFO_LENGTH_MISMATCH,
1564 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status);
1565
1566 status = pNtQueryInformationProcess(GetCurrentProcess(),
1567 ProcessDebugObjectHandle, &debug_object,
1568 sizeof(debug_object) + 1, NULL);
1569 ok(status == STATUS_INFO_LENGTH_MISMATCH,
1570 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status);
1571
1572 debug_object = (HANDLE)0xdeadbeef;
1573 status = pNtQueryInformationProcess(GetCurrentProcess(),
1574 ProcessDebugObjectHandle, &debug_object,
1575 sizeof(debug_object), NULL);
1576 ok(status == STATUS_PORT_NOT_SET,
1577 "Expected NtQueryInformationProcess to return STATUS_PORT_NOT_SET, got 0x%08x\n", status);
1578 ok(debug_object == NULL ||
1579 broken(debug_object == (HANDLE)0xdeadbeef), /* Wow64 */
1580 "Expected debug object handle to be NULL, got %p\n", debug_object);
1581
1582 debug_object = (HANDLE)0xdeadbeef;
1583 status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugObjectHandle,
1584 &debug_object, sizeof(debug_object), NULL);
1585 todo_wine
1586 ok(status == STATUS_SUCCESS,
1587 "Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08x\n", status);
1588 todo_wine
1589 ok(debug_object != NULL,
1590 "Expected debug object handle to be non-NULL, got %p\n", debug_object);
1591
1592 for (;;)
1593 {
1594 DEBUG_EVENT ev;
1595
1596 ret = WaitForDebugEvent(&ev, INFINITE);
1597 ok(ret, "WaitForDebugEvent failed with last error %u\n", GetLastError());
1598 if (!ret) break;
1599
1600 if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
1601
1602 ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
1603 ok(ret, "ContinueDebugEvent failed with last error %u\n", GetLastError());
1604 if (!ret) break;
1605 }
1606
1607 ret = CloseHandle(pi.hThread);
1608 ok(ret, "CloseHandle failed with last error %u\n", GetLastError());
1609 ret = CloseHandle(pi.hProcess);
1610 ok(ret, "CloseHandle failed with last error %u\n", GetLastError());
1611 }
1612
test_query_process_debug_flags(int argc,char ** argv)1613 static void test_query_process_debug_flags(int argc, char **argv)
1614 {
1615 static const DWORD test_flags[] = { DEBUG_PROCESS,
1616 DEBUG_ONLY_THIS_PROCESS,
1617 DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS,
1618 CREATE_SUSPENDED };
1619 DWORD debug_flags = 0xdeadbeef;
1620 char cmdline[MAX_PATH];
1621 PROCESS_INFORMATION pi;
1622 STARTUPINFOA si = { 0 };
1623 NTSTATUS status;
1624 DEBUG_EVENT ev;
1625 DWORD result;
1626 BOOL ret;
1627 int i, j;
1628
1629 /* test invalid arguments */
1630 status = pNtQueryInformationProcess(NULL, ProcessDebugFlags, NULL, 0, NULL);
1631 ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* WOW64 */,
1632 "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
1633
1634 status = pNtQueryInformationProcess(NULL, ProcessDebugFlags, NULL, sizeof(debug_flags), NULL);
1635 ok(status == STATUS_INVALID_HANDLE || status == STATUS_ACCESS_VIOLATION || broken(status == STATUS_INVALID_INFO_CLASS) /* WOW64 */,
1636 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status);
1637
1638 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
1639 NULL, sizeof(debug_flags), NULL);
1640 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
1641
1642 status = pNtQueryInformationProcess(NULL, ProcessDebugFlags,
1643 &debug_flags, sizeof(debug_flags), NULL);
1644 ok(status == STATUS_INVALID_HANDLE || broken(status == STATUS_INVALID_INFO_CLASS) /* WOW64 */,
1645 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status);
1646
1647 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
1648 &debug_flags, sizeof(debug_flags) - 1, NULL);
1649 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
1650
1651 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
1652 &debug_flags, sizeof(debug_flags) + 1, NULL);
1653 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
1654
1655 /* test ProcessDebugFlags of current process */
1656 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
1657 &debug_flags, sizeof(debug_flags), NULL);
1658 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1659 ok(debug_flags == TRUE, "Expected flag TRUE, got %x.\n", debug_flags);
1660
1661 for (i = 0; i < sizeof(test_flags)/sizeof(test_flags[0]); i++)
1662 {
1663 DWORD expected_flags = !(test_flags[i] & DEBUG_ONLY_THIS_PROCESS);
1664 sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
1665
1666 si.cb = sizeof(si);
1667 ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, test_flags[i], NULL, NULL, &si, &pi);
1668 ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
1669
1670 if (!(test_flags[i] & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)))
1671 {
1672 /* test ProcessDebugFlags before attaching with debugger */
1673 status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags,
1674 &debug_flags, sizeof(debug_flags), NULL);
1675 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1676 ok(debug_flags == TRUE, "Expected flag TRUE, got %x.\n", debug_flags);
1677
1678 ret = DebugActiveProcess(pi.dwProcessId);
1679 ok(ret, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1680 expected_flags = FALSE;
1681 }
1682
1683 /* test ProcessDebugFlags after attaching with debugger */
1684 status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags,
1685 &debug_flags, sizeof(debug_flags), NULL);
1686 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1687 ok(debug_flags == expected_flags, "Expected flag %x, got %x.\n", expected_flags, debug_flags);
1688
1689 if (!(test_flags[i] & CREATE_SUSPENDED))
1690 {
1691 /* Continue a couple of times to make sure the process is fully initialized,
1692 * otherwise Windows XP deadlocks in the following DebugActiveProcess(). */
1693 for (;;)
1694 {
1695 ret = WaitForDebugEvent(&ev, 1000);
1696 disable_success_count
1697 ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1698 if (!ret) break;
1699
1700 if (ev.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) break;
1701
1702 ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
1703 disable_success_count
1704 ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1705 if (!ret) break;
1706 }
1707
1708 result = SuspendThread(pi.hThread);
1709 ok(result == 0, "Expected 0, got %u.\n", result);
1710 }
1711
1712 ret = DebugActiveProcessStop(pi.dwProcessId);
1713 ok(ret, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError());
1714
1715 /* test ProcessDebugFlags after detaching debugger */
1716 status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags,
1717 &debug_flags, sizeof(debug_flags), NULL);
1718 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1719 ok(debug_flags == expected_flags, "Expected flag %x, got %x.\n", expected_flags, debug_flags);
1720
1721 ret = DebugActiveProcess(pi.dwProcessId);
1722 ok(ret, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1723
1724 /* test ProcessDebugFlags after re-attaching debugger */
1725 status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags,
1726 &debug_flags, sizeof(debug_flags), NULL);
1727 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1728 ok(debug_flags == FALSE, "Expected flag FALSE, got %x.\n", debug_flags);
1729
1730 result = ResumeThread(pi.hThread);
1731 todo_wine ok(result == 2, "Expected 2, got %u.\n", result);
1732
1733 /* Wait until the process is terminated. On Windows XP the process randomly
1734 * gets stuck in a non-continuable exception, so stop after 100 iterations.
1735 * On Windows 2003, the debugged process disappears (or stops?) without
1736 * any EXIT_PROCESS_DEBUG_EVENT after a couple of events. */
1737 for (j = 0; j < 100; j++)
1738 {
1739 ret = WaitForDebugEvent(&ev, 1000);
1740 disable_success_count
1741 ok(ret || broken(GetLastError() == ERROR_SEM_TIMEOUT),
1742 "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1743 if (!ret) break;
1744
1745 if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
1746
1747 ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
1748 disable_success_count
1749 ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1750 if (!ret) break;
1751 }
1752 ok(j < 100 || broken(j >= 100) /* Win XP */, "Expected less than 100 debug events.\n");
1753
1754 /* test ProcessDebugFlags after process has terminated */
1755 status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags,
1756 &debug_flags, sizeof(debug_flags), NULL);
1757 ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
1758 ok(debug_flags == FALSE, "Expected flag FALSE, got %x.\n", debug_flags);
1759
1760 ret = CloseHandle(pi.hThread);
1761 ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
1762 ret = CloseHandle(pi.hProcess);
1763 ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
1764 }
1765 }
1766
test_readvirtualmemory(void)1767 static void test_readvirtualmemory(void)
1768 {
1769 HANDLE process;
1770 NTSTATUS status;
1771 SIZE_T readcount;
1772 static const char teststring[] = "test string";
1773 char buffer[12];
1774
1775 process = OpenProcess(PROCESS_VM_READ, FALSE, GetCurrentProcessId());
1776 ok(process != 0, "Expected to be able to open own process for reading memory\n");
1777
1778 /* normal operation */
1779 status = pNtReadVirtualMemory(process, teststring, buffer, 12, &readcount);
1780 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1781 ok( readcount == 12, "Expected to read 12 bytes, got %ld\n",readcount);
1782 ok( strcmp(teststring, buffer) == 0, "Expected read memory to be the same as original memory\n");
1783
1784 /* no number of bytes */
1785 memset(buffer, 0, 12);
1786 status = pNtReadVirtualMemory(process, teststring, buffer, 12, NULL);
1787 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1788 ok( strcmp(teststring, buffer) == 0, "Expected read memory to be the same as original memory\n");
1789
1790 /* illegal remote address */
1791 todo_wine{
1792 status = pNtReadVirtualMemory(process, (void *) 0x1234, buffer, 12, &readcount);
1793 ok( status == STATUS_PARTIAL_COPY || broken(status == STATUS_ACCESS_VIOLATION), "Expected STATUS_PARTIAL_COPY, got %08x\n", status);
1794 if (status == STATUS_PARTIAL_COPY)
1795 ok( readcount == 0, "Expected to read 0 bytes, got %ld\n",readcount);
1796 }
1797
1798 /* 0 handle */
1799 status = pNtReadVirtualMemory(0, teststring, buffer, 12, &readcount);
1800 ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
1801 ok( readcount == 0, "Expected to read 0 bytes, got %ld\n",readcount);
1802
1803 /* pseudo handle for current process*/
1804 memset(buffer, 0, 12);
1805 status = pNtReadVirtualMemory((HANDLE)-1, teststring, buffer, 12, &readcount);
1806 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1807 ok( readcount == 12, "Expected to read 12 bytes, got %ld\n",readcount);
1808 ok( strcmp(teststring, buffer) == 0, "Expected read memory to be the same as original memory\n");
1809
1810 /* illegal local address */
1811 status = pNtReadVirtualMemory(process, teststring, (void *)0x1234, 12, &readcount);
1812 ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
1813 ok( readcount == 0, "Expected to read 0 bytes, got %ld\n",readcount);
1814
1815 CloseHandle(process);
1816 }
1817
test_mapprotection(void)1818 static void test_mapprotection(void)
1819 {
1820 HANDLE h;
1821 void* addr;
1822 MEMORY_BASIC_INFORMATION info;
1823 ULONG oldflags, flagsize, flags = MEM_EXECUTE_OPTION_ENABLE;
1824 LARGE_INTEGER size, offset;
1825 NTSTATUS status;
1826 SIZE_T retlen, count;
1827 void (*f)(void);
1828
1829 if (!pNtClose) {
1830 skip("No NtClose ... Win98\n");
1831 return;
1832 }
1833 /* Switch to being a noexec unaware process */
1834 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &oldflags, sizeof (oldflags), &flagsize);
1835 if (status == STATUS_INVALID_PARAMETER) {
1836 skip("Invalid Parameter on ProcessExecuteFlags query?\n");
1837 return;
1838 }
1839 ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status);
1840 status = pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &flags, sizeof(flags) );
1841 ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status);
1842
1843 size.u.LowPart = 0x2000;
1844 size.u.HighPart = 0;
1845 status = pNtCreateSection ( &h,
1846 STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
1847 NULL,
1848 &size,
1849 PAGE_READWRITE,
1850 SEC_COMMIT | SEC_NOCACHE,
1851 0
1852 );
1853 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1854
1855 offset.u.LowPart = 0;
1856 offset.u.HighPart = 0;
1857 count = 0x2000;
1858 addr = NULL;
1859 status = pNtMapViewOfSection ( h, GetCurrentProcess(), &addr, 0, 0, &offset, &count, ViewShare, 0, PAGE_READWRITE);
1860 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1861
1862 #if defined(__x86_64__) || defined(__i386__)
1863 *(unsigned char*)addr = 0xc3; /* lret ... in both i386 and x86_64 */
1864 #elif defined(__arm__)
1865 *(unsigned long*)addr = 0xe12fff1e; /* bx lr */
1866 #elif defined(__aarch64__)
1867 *(unsigned long*)addr = 0xd65f03c0; /* ret */
1868 #else
1869 ok(0, "Add a return opcode for your architecture or expect a crash in this test\n");
1870 #endif
1871 trace("trying to execute code in the readwrite only mapped anon file...\n");
1872 f = addr;f();
1873 trace("...done.\n");
1874
1875 status = pNtQueryVirtualMemory( GetCurrentProcess(), addr, MemoryBasicInformation, &info, sizeof(info), &retlen );
1876 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1877 ok( retlen == sizeof(info), "Expected STATUS_SUCCESS, got %08x\n", status);
1878 ok((info.Protect & ~PAGE_NOCACHE) == PAGE_READWRITE, "addr.Protect is not PAGE_READWRITE, but 0x%x\n", info.Protect);
1879
1880 status = pNtUnmapViewOfSection( GetCurrentProcess(), (char *)addr + 0x1050 );
1881 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1882 pNtClose (h);
1883
1884 /* Switch back */
1885 pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &oldflags, sizeof(oldflags) );
1886 }
1887
test_queryvirtualmemory(void)1888 static void test_queryvirtualmemory(void)
1889 {
1890 NTSTATUS status;
1891 SIZE_T readcount;
1892 static const WCHAR windowsW[] = {'w','i','n','d','o','w','s'};
1893 static const char teststring[] = "test string";
1894 static char datatestbuf[42] = "abc";
1895 static char rwtestbuf[42];
1896 MEMORY_BASIC_INFORMATION mbi;
1897 char stackbuf[42];
1898 HMODULE module;
1899 char buffer_name[sizeof(MEMORY_SECTION_NAME) + MAX_PATH * sizeof(WCHAR)];
1900 #ifndef __REACTOS__
1901 MEMORY_SECTION_NAME *msn = (MEMORY_SECTION_NAME *)buffer_name;
1902 #endif
1903 BOOL found;
1904 int i;
1905 #ifdef __REACTOS__
1906 MEMORY_SECTION_NAME *msn = HeapAlloc(GetProcessHeap(), 0, sizeof(buffer_name));
1907 #endif
1908
1909 module = GetModuleHandleA( "ntdll.dll" );
1910 trace("Check flags of the PE header of NTDLL.DLL at %p\n", module);
1911 status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
1912 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1913 ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
1914 ok (mbi.AllocationBase == module, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi.AllocationBase, module);
1915 ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
1916 ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
1917 ok (mbi.Protect == PAGE_READONLY, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_READONLY);
1918 ok (mbi.Type == MEM_IMAGE, "mbi.Type is 0x%x, expected 0x%x\n", mbi.Type, MEM_IMAGE);
1919
1920 trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory);
1921 module = GetModuleHandleA( "ntdll.dll" );
1922 status = pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
1923 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1924 ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
1925 ok (mbi.AllocationBase == module, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi.AllocationBase, module);
1926 ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
1927 ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
1928 ok (mbi.Protect == PAGE_EXECUTE_READ, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_EXECUTE_READ);
1929
1930 trace("Check flags of heap at %p\n", GetProcessHeap());
1931 status = pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
1932 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1933 ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
1934 ok (mbi.AllocationProtect == PAGE_READWRITE || mbi.AllocationProtect == PAGE_EXECUTE_READWRITE,
1935 "mbi.AllocationProtect is 0x%x\n", mbi.AllocationProtect);
1936 ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
1937 ok (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE,
1938 "mbi.Protect is 0x%x\n", mbi.Protect);
1939
1940 trace("Check flags of stack at %p\n", stackbuf);
1941 status = pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
1942 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1943 ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
1944 ok (mbi.AllocationProtect == PAGE_READWRITE, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_READWRITE);
1945 ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
1946 ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_READWRITE);
1947
1948 trace("Check flags of read-only data at %p\n", teststring);
1949 module = GetModuleHandleA( NULL );
1950 status = pNtQueryVirtualMemory(NtCurrentProcess(), teststring, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
1951 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1952 ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
1953 ok (mbi.AllocationBase == module, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi.AllocationBase, module);
1954 ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
1955 ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%X\n", mbi.State, MEM_COMMIT);
1956 if (mbi.Protect != PAGE_READONLY)
1957 todo_wine ok( mbi.Protect == PAGE_READONLY, "mbi.Protect is 0x%x, expected 0x%X\n", mbi.Protect, PAGE_READONLY);
1958
1959 trace("Check flags of read-write data at %p\n", datatestbuf);
1960 status = pNtQueryVirtualMemory(NtCurrentProcess(), datatestbuf, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
1961 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1962 ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
1963 ok (mbi.AllocationBase == module, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi.AllocationBase, module);
1964 ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
1965 ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%X\n", mbi.State, MEM_COMMIT);
1966 ok (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_WRITECOPY,
1967 "mbi.Protect is 0x%x\n", mbi.Protect);
1968
1969 trace("Check flags of read-write uninitialized data (.bss) at %p\n", rwtestbuf);
1970 status = pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
1971 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
1972 ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
1973 if (mbi.AllocationBase == module)
1974 {
1975 ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
1976 ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%X\n", mbi.State, MEM_COMMIT);
1977 ok (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_WRITECOPY,
1978 "mbi.Protect is 0x%x\n", mbi.Protect);
1979 }
1980 else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
1981
1982 /* check error code when addr is higher than working set limit */
1983 status = pNtQueryVirtualMemory(NtCurrentProcess(), (void *)~0, MemoryBasicInformation, &mbi, sizeof(mbi), &readcount);
1984 ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %08x\n", status);
1985
1986 trace("Check section name of NTDLL.DLL with invalid size\n");
1987 module = GetModuleHandleA( "ntdll.dll" );
1988 memset(msn, 0, sizeof(*msn));
1989 readcount = 0;
1990 status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemorySectionName, msn, sizeof(*msn), &readcount);
1991 ok( status == STATUS_BUFFER_OVERFLOW, "Expected STATUS_BUFFER_OVERFLOW, got %08x\n", status);
1992 ok( readcount > 0, "Expected readcount to be > 0\n");
1993
1994 trace("Check section name of NTDLL.DLL with invalid size\n");
1995 module = GetModuleHandleA( "ntdll.dll" );
1996 memset(msn, 0, sizeof(*msn));
1997 readcount = 0;
1998 status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemorySectionName, msn, sizeof(*msn) - 1, &readcount);
1999 ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
2000 ok( readcount > 0, "Expected readcount to be > 0\n");
2001
2002 trace("Check section name of NTDLL.DLL\n");
2003 module = GetModuleHandleA( "ntdll.dll" );
2004 memset(msn, 0x55, sizeof(*msn));
2005 memset(buffer_name, 0x77, sizeof(buffer_name));
2006 readcount = 0;
2007 status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemorySectionName, msn, sizeof(buffer_name), &readcount);
2008 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2009 ok( readcount > 0, "Expected readcount to be > 0\n");
2010 trace ("Section Name: %s\n", wine_dbgstr_w(msn->SectionFileName.Buffer));
2011 pRtlDowncaseUnicodeString( &msn->SectionFileName, &msn->SectionFileName, FALSE );
2012 for (found = FALSE, i = (msn->SectionFileName.Length - sizeof(windowsW)) / sizeof(WCHAR); i >= 0; i--)
2013 found |= !memcmp( &msn->SectionFileName.Buffer[i], windowsW, sizeof(windowsW) );
2014 ok( found, "Section name does not contain \"Windows\"\n");
2015
2016 trace("Check section name of non mapped memory\n");
2017 memset(msn, 0, sizeof(buffer_name));
2018 readcount = 0;
2019 status = pNtQueryVirtualMemory(NtCurrentProcess(), &buffer_name, MemorySectionName, msn, sizeof(buffer_name), &readcount);
2020 ok( status == STATUS_INVALID_ADDRESS, "Expected STATUS_INVALID_ADDRESS, got %08x\n", status);
2021 ok( readcount == 0 || broken(readcount != 0) /* wow64 */, "Expected readcount to be 0\n");
2022
2023 #ifdef __REACTOS__
2024 HeapFree(GetProcessHeap(), 0, msn);
2025 #endif
2026 }
2027
test_affinity(void)2028 static void test_affinity(void)
2029 {
2030 NTSTATUS status;
2031 PROCESS_BASIC_INFORMATION pbi;
2032 DWORD_PTR proc_affinity, thread_affinity;
2033 THREAD_BASIC_INFORMATION tbi;
2034 SYSTEM_INFO si;
2035
2036 GetSystemInfo(&si);
2037 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL );
2038 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2039 proc_affinity = pbi.AffinityMask;
2040 ok( proc_affinity == (1 << si.dwNumberOfProcessors) - 1, "Unexpected process affinity\n" );
2041 proc_affinity = 1 << si.dwNumberOfProcessors;
2042 status = pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask, &proc_affinity, sizeof(proc_affinity) );
2043 ok( status == STATUS_INVALID_PARAMETER,
2044 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status);
2045
2046 proc_affinity = 0;
2047 status = pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask, &proc_affinity, sizeof(proc_affinity) );
2048 ok( status == STATUS_INVALID_PARAMETER,
2049 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status);
2050
2051 status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
2052 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2053 ok( tbi.AffinityMask == (1 << si.dwNumberOfProcessors) - 1, "Unexpected thread affinity\n" );
2054 thread_affinity = 1 << si.dwNumberOfProcessors;
2055 status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
2056 ok( status == STATUS_INVALID_PARAMETER,
2057 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status);
2058 thread_affinity = 0;
2059 status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
2060 ok( status == STATUS_INVALID_PARAMETER,
2061 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status);
2062
2063 thread_affinity = 1;
2064 status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
2065 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2066 status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
2067 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2068 ok( tbi.AffinityMask == 1, "Unexpected thread affinity\n" );
2069
2070 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
2071 thread_affinity = ~(DWORD_PTR)0;
2072 status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
2073 ok( broken(status == STATUS_INVALID_PARAMETER) || status == STATUS_SUCCESS,
2074 "Expected STATUS_SUCCESS, got %08x\n", status);
2075
2076 if (si.dwNumberOfProcessors <= 1)
2077 {
2078 skip("only one processor, skipping affinity testing\n");
2079 return;
2080 }
2081
2082 /* Test thread affinity mask resulting from "all processors" flag */
2083 if (status == STATUS_SUCCESS)
2084 {
2085 status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
2086 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2087 ok( broken(tbi.AffinityMask == 1) || tbi.AffinityMask == (1 << si.dwNumberOfProcessors) - 1,
2088 "Unexpected thread affinity\n" );
2089 }
2090 else
2091 skip("Cannot test thread affinity mask for 'all processors' flag\n");
2092
2093 proc_affinity = 2;
2094 status = pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask, &proc_affinity, sizeof(proc_affinity) );
2095 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2096 status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL );
2097 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2098 proc_affinity = pbi.AffinityMask;
2099 ok( proc_affinity == 2, "Unexpected process affinity\n" );
2100 /* Setting the process affinity changes the thread affinity to match */
2101 status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
2102 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2103 ok( tbi.AffinityMask == 2, "Unexpected thread affinity\n" );
2104 /* The thread affinity is restricted to the process affinity */
2105 thread_affinity = 1;
2106 status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
2107 ok( status == STATUS_INVALID_PARAMETER,
2108 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status);
2109
2110 proc_affinity = (1 << si.dwNumberOfProcessors) - 1;
2111 status = pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask, &proc_affinity, sizeof(proc_affinity) );
2112 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2113 /* Resetting the process affinity also resets the thread affinity */
2114 status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
2115 ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2116 ok( tbi.AffinityMask == (1 << si.dwNumberOfProcessors) - 1,
2117 "Unexpected thread affinity\n" );
2118 }
2119
test_NtGetCurrentProcessorNumber(void)2120 static void test_NtGetCurrentProcessorNumber(void)
2121 {
2122 NTSTATUS status;
2123 SYSTEM_INFO si;
2124 PROCESS_BASIC_INFORMATION pbi;
2125 THREAD_BASIC_INFORMATION tbi;
2126 DWORD_PTR old_process_mask;
2127 DWORD_PTR old_thread_mask;
2128 DWORD_PTR new_mask;
2129 ULONG current_cpu;
2130 ULONG i;
2131
2132 if (!pNtGetCurrentProcessorNumber) {
2133 win_skip("NtGetCurrentProcessorNumber not available\n");
2134 return;
2135 }
2136
2137 GetSystemInfo(&si);
2138 current_cpu = pNtGetCurrentProcessorNumber();
2139 trace("dwNumberOfProcessors: %d, current processor: %d\n", si.dwNumberOfProcessors, current_cpu);
2140
2141 status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
2142 old_process_mask = pbi.AffinityMask;
2143 ok(status == STATUS_SUCCESS, "got 0x%x (expected STATUS_SUCCESS)\n", status);
2144
2145 status = pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL);
2146 old_thread_mask = tbi.AffinityMask;
2147 ok(status == STATUS_SUCCESS, "got 0x%x (expected STATUS_SUCCESS)\n", status);
2148
2149 /* allow the test to run on all processors */
2150 new_mask = (1 << si.dwNumberOfProcessors) - 1;
2151 status = pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask, &new_mask, sizeof(new_mask));
2152 ok(status == STATUS_SUCCESS, "got 0x%x (expected STATUS_SUCCESS)\n", status);
2153
2154 for (i = 0; i < si.dwNumberOfProcessors; i++)
2155 {
2156 new_mask = 1 << i;
2157 status = pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask, &new_mask, sizeof(new_mask));
2158 ok(status == STATUS_SUCCESS, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i, status);
2159
2160 status = pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL);
2161 ok(status == STATUS_SUCCESS, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i, status);
2162
2163 current_cpu = pNtGetCurrentProcessorNumber();
2164 ok((current_cpu == i), "%d (new_mask 0x%lx): running on processor %d (AffinityMask: 0x%lx)\n",
2165 i, new_mask, current_cpu, tbi.AffinityMask);
2166 }
2167
2168 /* restore old values */
2169 status = pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask, &old_process_mask, sizeof(old_process_mask));
2170 ok(status == STATUS_SUCCESS, "got 0x%x (expected STATUS_SUCCESS)\n", status);
2171
2172 status = pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask, &old_thread_mask, sizeof(old_thread_mask));
2173 ok(status == STATUS_SUCCESS, "got 0x%x (expected STATUS_SUCCESS)\n", status);
2174 }
2175
start_address_thread(void * arg)2176 static DWORD WINAPI start_address_thread(void *arg)
2177 {
2178 PRTL_THREAD_START_ROUTINE entry;
2179 NTSTATUS status;
2180 DWORD ret;
2181
2182 entry = NULL;
2183 ret = 0xdeadbeef;
2184 status = pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress,
2185 &entry, sizeof(entry), &ret);
2186 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
2187 ok(ret == sizeof(entry), "NtQueryInformationThread returned %u bytes\n", ret);
2188 ok(entry == (void *)start_address_thread, "expected %p, got %p\n", start_address_thread, entry);
2189 return 0;
2190 }
2191
test_thread_start_address(void)2192 static void test_thread_start_address(void)
2193 {
2194 PRTL_THREAD_START_ROUTINE entry, expected_entry;
2195 IMAGE_NT_HEADERS *nt;
2196 NTSTATUS status;
2197 HANDLE thread;
2198 void *module;
2199 DWORD ret;
2200
2201 module = GetModuleHandleA(0);
2202 ok(module != NULL, "expected non-NULL address for module\n");
2203 nt = RtlImageNtHeader(module);
2204 ok(nt != NULL, "expected non-NULL address for NT header\n");
2205
2206 entry = NULL;
2207 ret = 0xdeadbeef;
2208 status = pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress,
2209 &entry, sizeof(entry), &ret);
2210 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
2211 ok(ret == sizeof(entry), "NtQueryInformationThread returned %u bytes\n", ret);
2212 expected_entry = (void *)((char *)module + nt->OptionalHeader.AddressOfEntryPoint);
2213 ok(entry == expected_entry, "expected %p, got %p\n", expected_entry, entry);
2214
2215 entry = (void *)0xdeadbeef;
2216 status = pNtSetInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress,
2217 &entry, sizeof(entry));
2218 ok(status == STATUS_SUCCESS || status == STATUS_INVALID_PARAMETER, /* >= Vista */
2219 "expected STATUS_SUCCESS or STATUS_INVALID_PARAMETER, got %08x\n", status);
2220
2221 if (status == STATUS_SUCCESS)
2222 {
2223 entry = NULL;
2224 ret = 0xdeadbeef;
2225 status = pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress,
2226 &entry, sizeof(entry), &ret);
2227 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
2228 ok(ret == sizeof(entry), "NtQueryInformationThread returned %u bytes\n", ret);
2229 ok(entry == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", entry);
2230 }
2231
2232 thread = CreateThread(NULL, 0, start_address_thread, NULL, 0, NULL);
2233 ok(thread != INVALID_HANDLE_VALUE, "CreateThread failed with %d\n", GetLastError());
2234 ret = WaitForSingleObject(thread, 1000);
2235 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", ret);
2236 CloseHandle(thread);
2237 }
2238
test_query_data_alignment(void)2239 static void test_query_data_alignment(void)
2240 {
2241 ULONG ReturnLength;
2242 NTSTATUS status;
2243 DWORD value;
2244
2245 value = 0xdeadbeef;
2246 status = pNtQuerySystemInformation(SystemRecommendedSharedDataAlignment, &value, sizeof(value), &ReturnLength);
2247 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
2248 ok(sizeof(value) == ReturnLength, "Inconsistent length %u\n", ReturnLength);
2249 ok(value == 64, "Expected 64, got %u\n", value);
2250 }
2251
START_TEST(info)2252 START_TEST(info)
2253 {
2254 char **argv;
2255 int argc;
2256
2257 argc = winetest_get_mainargs(&argv);
2258 if (argc >= 3) return; /* Child */
2259
2260 if (!InitFunctionPtrs())
2261 return;
2262
2263 /* NtQuerySystemInformation */
2264
2265 /* 0x0 SystemBasicInformation */
2266 trace("Starting test_query_basic()\n");
2267 test_query_basic();
2268
2269 /* 0x1 SystemCpuInformation */
2270 trace("Starting test_query_cpu()\n");
2271 test_query_cpu();
2272
2273 /* 0x2 SystemPerformanceInformation */
2274 trace("Starting test_query_performance()\n");
2275 test_query_performance();
2276
2277 /* 0x3 SystemTimeOfDayInformation */
2278 trace("Starting test_query_timeofday()\n");
2279 test_query_timeofday();
2280
2281 /* 0x5 SystemProcessInformation */
2282 trace("Starting test_query_process()\n");
2283 test_query_process();
2284
2285 /* 0x8 SystemProcessorPerformanceInformation */
2286 trace("Starting test_query_procperf()\n");
2287 test_query_procperf();
2288
2289 /* 0xb SystemModuleInformation */
2290 trace("Starting test_query_module()\n");
2291 test_query_module();
2292
2293 /* 0x10 SystemHandleInformation */
2294 trace("Starting test_query_handle()\n");
2295 test_query_handle();
2296
2297 /* 0x40 SystemHandleInformation */
2298 trace("Starting test_query_handle_ex()\n");
2299 test_query_handle_ex();
2300
2301 /* 0x15 SystemCacheInformation */
2302 trace("Starting test_query_cache()\n");
2303 test_query_cache();
2304
2305 /* 0x17 SystemInterruptInformation */
2306 trace("Starting test_query_interrupt()\n");
2307 test_query_interrupt();
2308
2309 /* 0x23 SystemKernelDebuggerInformation */
2310 trace("Starting test_query_kerndebug()\n");
2311 test_query_kerndebug();
2312
2313 /* 0x25 SystemRegistryQuotaInformation */
2314 trace("Starting test_query_regquota()\n");
2315 test_query_regquota();
2316
2317 /* 0x49 SystemLogicalProcessorInformation */
2318 trace("Starting test_query_logicalproc()\n");
2319 test_query_logicalproc();
2320 test_query_logicalprocex();
2321
2322 /* NtPowerInformation */
2323
2324 /* 0xb ProcessorInformation */
2325 trace("Starting test_query_processor_power_info()\n");
2326 test_query_processor_power_info();
2327
2328 /* NtQueryInformationProcess */
2329
2330 /* 0x0 ProcessBasicInformation */
2331 trace("Starting test_query_process_basic()\n");
2332 test_query_process_basic();
2333
2334 /* 0x2 ProcessIoCounters */
2335 trace("Starting test_query_process_io()\n");
2336 test_query_process_io();
2337
2338 /* 0x3 ProcessVmCounters */
2339 trace("Starting test_query_process_vm()\n");
2340 test_query_process_vm();
2341
2342 /* 0x4 ProcessTimes */
2343 trace("Starting test_query_process_times()\n");
2344 test_query_process_times();
2345
2346 /* 0x7 ProcessDebugPort */
2347 trace("Starting test_process_debug_port()\n");
2348 test_query_process_debug_port(argc, argv);
2349
2350 /* 0x12 ProcessPriorityClass */
2351 trace("Starting test_query_process_priority()\n");
2352 test_query_process_priority();
2353
2354 /* 0x14 ProcessHandleCount */
2355 trace("Starting test_query_process_handlecount()\n");
2356 test_query_process_handlecount();
2357
2358 /* 0x1A ProcessWow64Information */
2359 trace("Starting test_query_process_wow64()\n");
2360 test_query_process_wow64();
2361
2362 /* 0x1B ProcessImageFileName */
2363 trace("Starting test_query_process_image_file_name()\n");
2364 test_query_process_image_file_name();
2365
2366 /* 0x1E ProcessDebugObjectHandle */
2367 trace("Starting test_query_process_debug_object_handle()\n");
2368 test_query_process_debug_object_handle(argc, argv);
2369
2370 /* 0x1F ProcessDebugFlags */
2371 trace("Starting test_process_debug_flags()\n");
2372 test_query_process_debug_flags(argc, argv);
2373
2374 /* belongs to its own file */
2375 trace("Starting test_readvirtualmemory()\n");
2376 test_readvirtualmemory();
2377
2378 trace("Starting test_queryvirtualmemory()\n");
2379 test_queryvirtualmemory();
2380
2381 trace("Starting test_mapprotection()\n");
2382 test_mapprotection();
2383
2384 trace("Starting test_affinity()\n");
2385 test_affinity();
2386
2387 trace("Starting test_NtGetCurrentProcessorNumber()\n");
2388 test_NtGetCurrentProcessorNumber();
2389
2390 trace("Starting test_thread_start_address()\n");
2391 test_thread_start_address();
2392
2393 trace("Starting test_query_data_alignment()\n");
2394 test_query_data_alignment();
2395 }
2396