1 /* Unit test suite for *Information* Registry API functions
3 * Copyright 2005 Paul Vriens
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.
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.
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
21 #include "ntdll_test.h"
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
*);
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.
48 static DWORD one_before_last_pid
= 0;
50 #define NTDLL_GET_PROC(func) do { \
51 p ## func = (void*)GetProcAddress(hntdll, #func); \
53 trace("GetProcAddress(%s) failed\n", #func); \
58 static BOOL
InitFunctionPtrs(void)
60 /* All needed functions are NT based, so using GetModuleHandle is a good check */
61 HMODULE hntdll
= GetModuleHandleA("ntdll");
62 HMODULE hkernel32
= GetModuleHandleA("kernel32");
66 win_skip("Not running on NT\n");
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
);
84 /* not present before XP */
85 pNtGetCurrentProcessorNumber
= (void *) GetProcAddress(hntdll
, "NtGetCurrentProcessorNumber");
87 pIsWow64Process
= (void *)GetProcAddress(hkernel32
, "IsWow64Process");
88 if (!pIsWow64Process
|| !pIsWow64Process( GetCurrentProcess(), &is_wow64
)) is_wow64
= FALSE
;
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");
95 pGetLogicalProcessorInformationEx
= (void *) GetProcAddress(hkernel32
, "GetLogicalProcessorInformationEx");
100 static void test_query_basic(void)
104 SYSTEM_BASIC_INFORMATION sbi
;
106 /* This test also covers some basic parameter testing that should be the same for
107 * every information class
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
);
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
);
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
);
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
);
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
);
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
);
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
);
148 static void test_query_cpu(void)
152 SYSTEM_CPU_INFORMATION sci
;
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
);
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
);
163 static void test_query_performance(void)
167 ULONGLONG buffer
[sizeof(SYSTEM_PERFORMANCE_INFORMATION
)/sizeof(ULONGLONG
) + 5];
168 DWORD size
= sizeof(SYSTEM_PERFORMANCE_INFORMATION
);
170 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, 0, &ReturnLength
);
171 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
173 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
174 if (status
== STATUS_INFO_LENGTH_MISMATCH
&& is_wow64
)
176 /* size is larger on wow64 under w2k8/win7 */
178 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
180 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
181 ok( ReturnLength
== size
, "Inconsistent length %d\n", ReturnLength
);
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
);
188 /* Not return values yet, as struct members are unknown */
191 static void test_query_timeofday(void)
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
;
203 } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
;
205 SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti
;
207 /* The struct size for NT (32 bytes) and Win2K/XP (48 bytes) differ.
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
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
219 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
221 if (status
== STATUS_INFO_LENGTH_MISMATCH
)
223 trace("Windows version is NT, we have to cater for differences with W2K/WinXP\n");
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
);
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");
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
);
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
);
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");
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");
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
);
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
);
266 /* Check if we have some return values */
267 trace("uCurrentTimeZoneId : (%d)\n", sti
.uCurrentTimeZoneId
);
270 static void test_query_process(void)
277 SYSTEM_BASIC_INFORMATION sbi
;
279 /* Copy of our winternl.h structure turned into a private one */
280 typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE
{
281 ULONG NextEntryOffset
;
284 FILETIME ftCreationTime
;
286 FILETIME ftKernelTime
;
287 UNICODE_STRING ProcessName
;
288 DWORD dwBasePriority
;
289 HANDLE UniqueProcessId
;
290 HANDLE ParentProcessId
;
294 VM_COUNTERS vmCounters
;
295 IO_COUNTERS ioCounters
;
296 SYSTEM_THREAD_INFORMATION ti
[1];
297 } SYSTEM_PROCESS_INFORMATION_PRIVATE
;
299 ULONG SystemInformationLength
= sizeof(SYSTEM_PROCESS_INFORMATION_PRIVATE
);
300 SYSTEM_PROCESS_INFORMATION_PRIVATE
*spi
, *spi_buf
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
302 /* test ReturnLength */
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");
309 /* W2K3 and later returns the needed length, the rest returns 0, so we have to loop */
312 status
= pNtQuerySystemInformation(SystemProcessInformation
, spi_buf
, SystemInformationLength
, &ReturnLength
);
314 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) break;
316 spi_buf
= HeapReAlloc(GetProcessHeap(), 0, spi_buf
, SystemInformationLength
*= 2);
318 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
321 /* Get the first NextEntryOffset, from this we can deduce the OS version we're running
324 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
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
333 * Note : On windows the first process is in fact the Idle 'process' with a thread for every processor
336 pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
338 is_nt
= ( spi
->NextEntryOffset
- (sbi
.NumberOfProcessors
* sizeof(SYSTEM_THREAD_INFORMATION
)) == 136);
340 if (is_nt
) win_skip("Windows version is NT, we will skip thread tests\n");
342 /* Check if we have some return values
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)
348 /* Loop through the processes */
354 last_pid
= (DWORD_PTR
)spi
->UniqueProcessId
;
356 ok( spi
->dwThreadCount
> 0, "Expected some threads for this process, got 0\n");
358 /* Loop through the threads, skip NT4 for now */
363 for ( j
= 0; j
< spi
->dwThreadCount
; j
++)
366 ok ( spi
->ti
[j
].ClientId
.UniqueProcess
== spi
->UniqueProcessId
,
367 "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n",
368 spi
->ti
[j
].ClientId
.UniqueProcess
, spi
->UniqueProcessId
);
372 if (!spi
->NextEntryOffset
) break;
374 one_before_last_pid
= last_pid
;
376 spi
= (SYSTEM_PROCESS_INFORMATION_PRIVATE
*)((char*)spi
+ spi
->NextEntryOffset
);
378 trace("Total number of running processes : %d\n", i
);
379 if (!is_nt
) trace("Total number of running threads : %d\n", k
);
381 if (one_before_last_pid
== 0) one_before_last_pid
= last_pid
;
383 HeapFree( GetProcessHeap(), 0, spi_buf
);
386 static void test_query_procperf(void)
391 SYSTEM_BASIC_INFORMATION sbi
;
392 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
* sppi
;
394 /* Find out the number of processors */
395 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
396 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
397 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
399 sppi
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
401 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, 0, &ReturnLength
);
402 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
404 /* Try it for 1 processor */
405 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
406 sppi
->UserTime
.QuadPart
= 0xdeaddead;
407 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
408 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
,
409 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
), &ReturnLength
);
410 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
411 ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) == ReturnLength
,
412 "Inconsistent length %d\n", ReturnLength
);
413 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
414 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
415 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
417 /* Try it for all processors */
418 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
419 sppi
->UserTime
.QuadPart
= 0xdeaddead;
420 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
421 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
, &ReturnLength
);
422 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
423 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
424 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
425 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
426 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
428 /* A too large given buffer size */
429 sppi
= HeapReAlloc(GetProcessHeap(), 0, sppi
, NeededLength
+ 2);
430 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
431 sppi
->UserTime
.QuadPart
= 0xdeaddead;
432 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
433 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
+ 2, &ReturnLength
);
434 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INFO_LENGTH_MISMATCH
/* vista */,
435 "Expected STATUS_SUCCESS or STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
436 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
437 if (status
== STATUS_SUCCESS
)
439 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
440 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
441 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
443 else /* vista and 2008 */
445 ok (sppi
->KernelTime
.QuadPart
== 0xdeaddead, "KernelTime changed\n");
446 ok (sppi
->UserTime
.QuadPart
== 0xdeaddead, "UserTime changed\n");
447 ok (sppi
->IdleTime
.QuadPart
== 0xdeaddead, "IdleTime changed\n");
450 HeapFree( GetProcessHeap(), 0, sppi
);
453 static void test_query_module(void)
457 ULONG ModuleCount
, i
;
459 ULONG SystemInformationLength
= sizeof(SYSTEM_MODULE_INFORMATION
);
460 SYSTEM_MODULE_INFORMATION
* smi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
463 /* Request the needed length */
464 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, 0, &ReturnLength
);
465 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
466 ok( ReturnLength
> 0, "Expected a ReturnLength to show the needed length\n");
468 SystemInformationLength
= ReturnLength
;
469 smi
= HeapReAlloc(GetProcessHeap(), 0, smi
, SystemInformationLength
);
470 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, SystemInformationLength
, &ReturnLength
);
471 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
473 ModuleCount
= smi
->ModulesCount
;
474 sm
= &smi
->Modules
[0];
475 /* our implementation is a stub for now */
476 ok( ModuleCount
> 0, "Expected some modules to be loaded\n");
478 /* Loop through all the modules/drivers, Wine doesn't get here (yet) */
479 for (i
= 0; i
< ModuleCount
; i
++)
481 ok( i
== sm
->Id
, "Id (%d) should have matched %u\n", sm
->Id
, i
);
485 HeapFree( GetProcessHeap(), 0, smi
);
488 static void test_query_handle(void)
491 ULONG ExpectedLength
, ReturnLength
;
492 ULONG SystemInformationLength
= sizeof(SYSTEM_HANDLE_INFORMATION
);
493 SYSTEM_HANDLE_INFORMATION
* shi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
498 EventHandle
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
499 ok( EventHandle
!= NULL
, "CreateEventA failed %u\n", GetLastError() );
501 /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
502 ReturnLength
= 0xdeadbeef;
503 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
504 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
505 ok( ReturnLength
!= 0xdeadbeef, "Expected valid ReturnLength\n" );
507 SystemInformationLength
= ReturnLength
;
508 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
509 memset(shi
, 0x55, SystemInformationLength
);
511 ReturnLength
= 0xdeadbeef;
512 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
513 while (status
== STATUS_INFO_LENGTH_MISMATCH
) /* Vista / 2008 */
515 SystemInformationLength
*= 2;
516 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
517 memset(shi
, 0x55, SystemInformationLength
);
518 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
520 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
521 ExpectedLength
= FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION
, Handle
[shi
->Count
]);
522 ok( ReturnLength
== ExpectedLength
|| broken(ReturnLength
== ExpectedLength
- sizeof(DWORD
)), /* Vista / 2008 */
523 "Expected length %u, got %u\n", ExpectedLength
, ReturnLength
);
524 ok( shi
->Count
> 1, "Expected more than 1 handle, got %u\n", shi
->Count
);
525 ok( shi
->Handle
[1].HandleValue
!= 0x5555 || broken( shi
->Handle
[1].HandleValue
== 0x5555 ), /* Vista / 2008 */
526 "Uninitialized second handle\n" );
527 if (shi
->Handle
[1].HandleValue
== 0x5555)
529 win_skip("Skipping broken SYSTEM_HANDLE_INFORMATION\n");
530 CloseHandle(EventHandle
);
534 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
535 found
= (shi
->Handle
[i
].OwnerPid
== GetCurrentProcessId()) &&
536 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
537 ok( found
, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle
, GetCurrentProcessId() );
540 for (i
= 0; i
< shi
->Count
; i
++)
541 trace( "%d: handle %x pid %x\n", i
, shi
->Handle
[i
].HandleValue
, shi
->Handle
[i
].OwnerPid
);
543 CloseHandle(EventHandle
);
545 ReturnLength
= 0xdeadbeef;
546 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
547 while (status
== STATUS_INFO_LENGTH_MISMATCH
) /* Vista / 2008 */
549 SystemInformationLength
*= 2;
550 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
551 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
553 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
554 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
555 found
= (shi
->Handle
[i
].OwnerPid
== GetCurrentProcessId()) &&
556 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
557 ok( !found
, "Unexpectedly found event handle in handle list\n" );
559 status
= pNtQuerySystemInformation(SystemHandleInformation
, NULL
, SystemInformationLength
, &ReturnLength
);
560 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
563 HeapFree( GetProcessHeap(), 0, shi
);
566 static void test_query_handle_ex(void)
569 ULONG ExpectedLength
, ReturnLength
;
570 ULONG SystemInformationLength
= sizeof(SYSTEM_HANDLE_INFORMATION_EX
);
571 SYSTEM_HANDLE_INFORMATION_EX
* shi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
576 EventHandle
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
577 ok( EventHandle
!= NULL
, "CreateEventA failed %u\n", GetLastError() );
579 ReturnLength
= 0xdeadbeef;
580 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
581 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
582 ok( ReturnLength
!= 0xdeadbeef, "Expected valid ReturnLength\n" );
584 SystemInformationLength
= ReturnLength
;
585 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
586 memset(shi
, 0x55, SystemInformationLength
);
588 ReturnLength
= 0xdeadbeef;
589 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
590 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
591 ExpectedLength
= FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX
, Handle
[shi
->Count
]);
592 ok( ReturnLength
== ExpectedLength
, "Expected length %u, got %u\n", ExpectedLength
, ReturnLength
);
593 ok( shi
->Count
> 1, "Expected more than 1 handle, got %u\n", (DWORD
)shi
->Count
);
595 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
596 found
= (shi
->Handle
[i
].UniqueProcessId
== GetCurrentProcessId()) &&
597 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
598 ok( found
, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle
, GetCurrentProcessId() );
602 for (i
= 0; i
< shi
->Count
; i
++)
603 trace( "%d: handle %x pid %x\n", i
, (DWORD
)shi
->Handle
[i
].HandleValue
, (DWORD
)shi
->Handle
[i
].UniqueProcessId
);
606 CloseHandle(EventHandle
);
608 ReturnLength
= 0xdeadbeef;
609 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
610 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
611 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
612 found
= (shi
->Handle
[i
].UniqueProcessId
== GetCurrentProcessId()) &&
613 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
614 ok( !found
, "Unexpectedly found event handle in handle list\n" );
616 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, NULL
, SystemInformationLength
, &ReturnLength
);
617 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
619 HeapFree( GetProcessHeap(), 0, shi
);
622 static void test_query_cache(void)
627 SYSTEM_CACHE_INFORMATION
*sci
= (SYSTEM_CACHE_INFORMATION
*) buffer
;
631 /* the large SYSTEM_CACHE_INFORMATION on WIN64 is not documented */
632 expected
= sizeof(SYSTEM_CACHE_INFORMATION
);
633 for (i
= sizeof(buffer
); i
>= expected
; i
--)
635 ReturnLength
= 0xdeadbeef;
636 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
637 ok(!status
&& (ReturnLength
== expected
),
638 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i
, status
, ReturnLength
, expected
);
641 /* buffer too small for the full result.
642 Up to win7, the function succeeds with a partial result. */
643 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
646 expected
= offsetof(SYSTEM_CACHE_INFORMATION
, MinimumWorkingSet
);
647 for (; i
>= expected
; i
--)
649 ReturnLength
= 0xdeadbeef;
650 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
651 ok(!status
&& (ReturnLength
== expected
),
652 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i
, status
, ReturnLength
, expected
);
656 /* buffer too small for the result, this call will always fail */
657 ReturnLength
= 0xdeadbeef;
658 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
659 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
660 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
661 "%d: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", i
, status
, ReturnLength
, expected
);
664 /* this crashes on some vista / win7 machines */
665 ReturnLength
= 0xdeadbeef;
666 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, 0, &ReturnLength
);
667 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
668 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
669 "0: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", status
, ReturnLength
, expected
);
673 static void test_query_interrupt(void)
678 SYSTEM_BASIC_INFORMATION sbi
;
679 SYSTEM_INTERRUPT_INFORMATION
* sii
;
681 /* Find out the number of processors */
682 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
683 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
684 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
);
686 sii
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
688 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, 0, &ReturnLength
);
689 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
691 /* Try it for all processors */
692 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, NeededLength
, &ReturnLength
);
693 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
695 /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength
696 * No test added for this as it's highly unlikely that an app depends on this
699 HeapFree( GetProcessHeap(), 0, sii
);
702 static void test_query_kerndebug(void)
706 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi
;
708 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, 0, &ReturnLength
);
709 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
711 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
), &ReturnLength
);
712 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
713 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
715 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
) + 2, &ReturnLength
);
716 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
717 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
720 static void test_query_regquota(void)
724 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi
;
726 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, 0, &ReturnLength
);
727 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
729 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
), &ReturnLength
);
730 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
731 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
733 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
) + 2, &ReturnLength
);
734 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
735 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
738 static void test_query_logicalproc(void)
741 ULONG len
, i
, proc_no
;
742 SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*slpi
;
747 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, NULL
, 0, &len
);
748 if(status
== STATUS_INVALID_INFO_CLASS
)
750 win_skip("SystemLogicalProcessorInformation is not supported\n");
753 if(status
== STATUS_NOT_IMPLEMENTED
)
755 todo_wine
ok(0, "SystemLogicalProcessorInformation is not implemented\n");
758 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
759 ok(len
%sizeof(*slpi
) == 0, "Incorrect length %d\n", len
);
761 slpi
= HeapAlloc(GetProcessHeap(), 0, len
);
762 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, slpi
, len
, &len
);
763 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
766 for(i
=0; i
<len
/sizeof(*slpi
); i
++) {
767 switch(slpi
[i
].Relationship
) {
768 case RelationProcessorCore
:
769 /* Get number of logical processors */
770 for(; slpi
[i
].ProcessorMask
; slpi
[i
].ProcessorMask
/= 2)
771 proc_no
+= slpi
[i
].ProcessorMask
%2;
777 ok(proc_no
> 0, "No processors were found\n");
778 if(si
.dwNumberOfProcessors
<= 32)
779 ok(proc_no
== si
.dwNumberOfProcessors
, "Incorrect number of logical processors: %d, expected %d\n",
780 proc_no
, si
.dwNumberOfProcessors
);
782 HeapFree(GetProcessHeap(), 0, slpi
);
785 static void test_query_logicalprocex(void)
787 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*infoex
, *infoex2
;
788 DWORD relationship
, len2
, len
;
792 if (!pNtQuerySystemInformationEx
)
796 relationship
= RelationProcessorCore
;
797 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len
);
798 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08x\n", status
);
799 ok(len
> 0, "got %u\n", len
);
802 relationship
= RelationAll
;
803 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len
);
804 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08x\n", status
);
805 ok(len
> 0, "got %u\n", len
);
808 ret
= pGetLogicalProcessorInformationEx(RelationAll
, NULL
, &len2
);
809 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %d, error %d\n", ret
, GetLastError());
810 ok(len
== len2
, "got %u, expected %u\n", len2
, len
);
812 if (len
&& len
== len2
) {
815 infoex
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
816 infoex2
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
818 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex
, len
, &len
);
819 ok(status
== STATUS_SUCCESS
, "got 0x%08x\n", status
);
821 ret
= pGetLogicalProcessorInformationEx(RelationAll
, infoex2
, &len2
);
822 ok(ret
, "got %d, error %d\n", ret
, GetLastError());
823 ok(!memcmp(infoex
, infoex2
, len
), "returned info data mismatch\n");
825 for(i
= 0; status
== STATUS_SUCCESS
&& i
< len
; ){
826 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*ex
= (void*)(((char *)infoex
) + i
);
828 ok(ex
->Relationship
>= RelationProcessorCore
&& ex
->Relationship
<= RelationGroup
,
829 "Got invalid relationship value: 0x%x\n", ex
->Relationship
);
832 ok(0, "got infoex[%u].Size=0\n", i
);
836 trace("infoex[%u].Size: %u\n", i
, ex
->Size
);
837 switch(ex
->Relationship
){
838 case RelationProcessorCore
:
839 case RelationProcessorPackage
:
840 trace("infoex[%u].Relationship: 0x%x (Core == 0x0 or Package == 0x3)\n", i
, ex
->Relationship
);
841 trace("infoex[%u].Processor.Flags: 0x%x\n", i
, ex
->Processor
.Flags
);
843 trace("infoex[%u].Processor.EfficiencyClass: 0x%x\n", i
, ex
->Processor
.EfficiencyClass
);
845 trace("infoex[%u].Processor.GroupCount: 0x%x\n", i
, ex
->Processor
.GroupCount
);
846 for(j
= 0; j
< ex
->Processor
.GroupCount
; ++j
){
847 trace("infoex[%u].Processor.GroupMask[%u].Mask: 0x%lx\n", i
, j
, ex
->Processor
.GroupMask
[j
].Mask
);
848 trace("infoex[%u].Processor.GroupMask[%u].Group: 0x%x\n", i
, j
, ex
->Processor
.GroupMask
[j
].Group
);
851 case RelationNumaNode
:
852 trace("infoex[%u].Relationship: 0x%x (NumaNode)\n", i
, ex
->Relationship
);
853 trace("infoex[%u].NumaNode.NodeNumber: 0x%x\n", i
, ex
->NumaNode
.NodeNumber
);
854 trace("infoex[%u].NumaNode.GroupMask.Mask: 0x%lx\n", i
, ex
->NumaNode
.GroupMask
.Mask
);
855 trace("infoex[%u].NumaNode.GroupMask.Group: 0x%x\n", i
, ex
->NumaNode
.GroupMask
.Group
);
858 trace("infoex[%u].Relationship: 0x%x (Cache)\n", i
, ex
->Relationship
);
859 trace("infoex[%u].Cache.Level: 0x%x\n", i
, ex
->Cache
.Level
);
860 trace("infoex[%u].Cache.Associativity: 0x%x\n", i
, ex
->Cache
.Associativity
);
861 trace("infoex[%u].Cache.LineSize: 0x%x\n", i
, ex
->Cache
.LineSize
);
862 trace("infoex[%u].Cache.CacheSize: 0x%x\n", i
, ex
->Cache
.CacheSize
);
863 trace("infoex[%u].Cache.Type: 0x%x\n", i
, ex
->Cache
.Type
);
864 trace("infoex[%u].Cache.GroupMask.Mask: 0x%lx\n", i
, ex
->Cache
.GroupMask
.Mask
);
865 trace("infoex[%u].Cache.GroupMask.Group: 0x%x\n", i
, ex
->Cache
.GroupMask
.Group
);
868 trace("infoex[%u].Relationship: 0x%x (Group)\n", i
, ex
->Relationship
);
869 trace("infoex[%u].Group.MaximumGroupCount: 0x%x\n", i
, ex
->Group
.MaximumGroupCount
);
870 trace("infoex[%u].Group.ActiveGroupCount: 0x%x\n", i
, ex
->Group
.ActiveGroupCount
);
871 for(j
= 0; j
< ex
->Group
.ActiveGroupCount
; ++j
){
872 trace("infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].MaximumProcessorCount
);
873 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorCount
);
874 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%lx\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorMask
);
884 HeapFree(GetProcessHeap(), 0, infoex
);
885 HeapFree(GetProcessHeap(), 0, infoex2
);
889 static void test_query_processor_power_info(void)
892 PROCESSOR_POWER_INFORMATION
* ppi
;
898 size
= si
.dwNumberOfProcessors
* sizeof(PROCESSOR_POWER_INFORMATION
);
899 ppi
= HeapAlloc(GetProcessHeap(), 0, size
);
901 /* If size < (sizeof(PROCESSOR_POWER_INFORMATION) * NumberOfProcessors), Win7 returns
902 * STATUS_BUFFER_TOO_SMALL. WinXP returns STATUS_SUCCESS for any value of size. It copies as
903 * many whole PROCESSOR_POWER_INFORMATION structures that there is room for. Even if there is
904 * not enough room for one structure, WinXP still returns STATUS_SUCCESS having done nothing.
906 * If ppi == NULL, Win7 returns STATUS_INVALID_PARAMETER while WinXP returns STATUS_SUCCESS
909 * The same behavior is seen with CallNtPowerInformation (in powrprof.dll).
912 if (si
.dwNumberOfProcessors
> 1)
914 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
915 ppi
[i
].Number
= 0xDEADBEEF;
917 /* Call with a buffer size that is large enough to hold at least one but not large
918 * enough to hold them all. This will be STATUS_SUCCESS on WinXP but not on Win7 */
919 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
- sizeof(PROCESSOR_POWER_INFORMATION
));
920 if (status
== STATUS_SUCCESS
)
922 /* lax version found on older Windows like WinXP */
923 ok( (ppi
[si
.dwNumberOfProcessors
- 2].Number
!= 0xDEADBEEF) &&
924 (ppi
[si
.dwNumberOfProcessors
- 1].Number
== 0xDEADBEEF),
925 "Expected all but the last record to be overwritten.\n");
927 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
928 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
930 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
931 ppi
[i
].Number
= 0xDEADBEEF;
932 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, sizeof(PROCESSOR_POWER_INFORMATION
) - 1);
933 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
934 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
935 if (ppi
[i
].Number
!= 0xDEADBEEF) break;
936 ok( i
== si
.dwNumberOfProcessors
, "Expected untouched buffer\n");
940 /* picky version found on newer Windows like Win7 */
941 ok( ppi
[1].Number
== 0xDEADBEEF, "Expected untouched buffer.\n");
942 ok( status
== STATUS_BUFFER_TOO_SMALL
, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status
);
944 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
945 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, "Got %08x\n", status
);
947 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, 0);
948 ok( status
== STATUS_BUFFER_TOO_SMALL
|| status
== STATUS_INVALID_PARAMETER
, "Got %08x\n", status
);
953 skip("Test needs more than one processor.\n");
956 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
);
957 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
959 HeapFree(GetProcessHeap(), 0, ppi
);
962 static void test_query_process_wow64(void)
966 ULONG_PTR pbi
[2], dummy
;
968 memset(&dummy
, 0xcc, sizeof(dummy
));
970 /* Do not give a handle and buffer */
971 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, 0, NULL
);
972 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
974 /* Use a correct info class and buffer size, but still no handle and buffer */
975 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
976 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
977 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE, got %08x\n", status
);
979 /* Use a correct info class, buffer size and handle, but no buffer */
980 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
981 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
983 /* Use a correct info class, buffer and buffer size, but no handle */
984 pbi
[0] = pbi
[1] = dummy
;
985 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
986 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
987 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
988 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
990 /* Use a greater buffer size */
991 pbi
[0] = pbi
[1] = dummy
;
992 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, NULL
);
993 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
994 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
995 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
997 /* Use no ReturnLength */
998 pbi
[0] = pbi
[1] = dummy
;
999 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
1000 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1001 trace( "Platform is_wow64 %d, ProcessInformation of ProcessWow64Information %lx\n", is_wow64
, pbi
[0]);
1002 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64
, pbi
[0]);
1003 ok( pbi
[0] != dummy
, "pbi[0] %lx\n", pbi
[0]);
1004 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1005 /* Test written size on 64 bit by checking high 32 bit buffer */
1006 if (sizeof(ULONG_PTR
) > sizeof(DWORD
))
1008 DWORD
*ptr
= (DWORD
*)pbi
;
1009 ok( ptr
[1] != (DWORD
)dummy
, "ptr[1] unchanged!\n");
1012 /* Finally some correct calls */
1013 pbi
[0] = pbi
[1] = dummy
;
1014 ReturnLength
= 0xdeadbeef;
1015 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), &ReturnLength
);
1016 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1017 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64
, pbi
[0]);
1018 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1019 ok( ReturnLength
== sizeof(ULONG_PTR
), "Inconsistent length %d\n", ReturnLength
);
1021 /* Everything is correct except a too small buffer size */
1022 pbi
[0] = pbi
[1] = dummy
;
1023 ReturnLength
= 0xdeadbeef;
1024 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) - 1, &ReturnLength
);
1025 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1026 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
1027 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1028 todo_wine
ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength
);
1030 /* Everything is correct except a too large buffer size */
1031 pbi
[0] = pbi
[1] = dummy
;
1032 ReturnLength
= 0xdeadbeef;
1033 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, &ReturnLength
);
1034 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1035 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
1036 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1037 todo_wine
ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength
);
1040 static void test_query_process_basic(void)
1045 typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE
{
1046 DWORD_PTR ExitStatus
;
1047 PPEB PebBaseAddress
;
1048 DWORD_PTR AffinityMask
;
1049 DWORD_PTR BasePriority
;
1050 ULONG_PTR UniqueProcessId
;
1051 ULONG_PTR InheritedFromUniqueProcessId
;
1052 } PROCESS_BASIC_INFORMATION_PRIVATE
;
1054 PROCESS_BASIC_INFORMATION_PRIVATE pbi
;
1056 /* This test also covers some basic parameter testing that should be the same for
1057 * every information class
1060 /* Use a nonexistent info class */
1061 trace("Check nonexistent info class\n");
1062 status
= pNtQueryInformationProcess(NULL
, -1, NULL
, 0, NULL
);
1063 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
1064 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
1066 /* Do not give a handle and buffer */
1067 trace("Check NULL handle and buffer and zero-length buffersize\n");
1068 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, 0, NULL
);
1069 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1071 /* Use a correct info class and buffer size, but still no handle and buffer */
1072 trace("Check NULL handle and buffer\n");
1073 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, sizeof(pbi
), NULL
);
1074 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1075 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1077 /* Use a correct info class and buffer size, but still no handle */
1078 trace("Check NULL handle\n");
1079 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1080 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1082 /* Use a greater buffer size */
1083 trace("Check NULL handle and too large buffersize\n");
1084 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, NULL
);
1085 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1087 /* Use no ReturnLength */
1088 trace("Check NULL ReturnLength\n");
1089 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1090 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1092 /* Finally some correct calls */
1093 trace("Check with correct parameters\n");
1094 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), &ReturnLength
);
1095 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1096 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1098 /* Everything is correct except a too large buffersize */
1099 trace("Too large buffersize\n");
1100 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, &ReturnLength
);
1101 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1102 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1104 /* Check if we have some return values */
1105 trace("ProcessID : %lx\n", pbi
.UniqueProcessId
);
1106 ok( pbi
.UniqueProcessId
> 0, "Expected a ProcessID > 0, got 0\n");
1109 static void dump_vm_counters(const char *header
, const VM_COUNTERS
*pvi
)
1111 trace("%s:\n", header
);
1112 trace("PeakVirtualSize : %lu\n", pvi
->PeakVirtualSize
);
1113 trace("VirtualSize : %lu\n", pvi
->VirtualSize
);
1114 trace("PageFaultCount : %u\n", pvi
->PageFaultCount
);
1115 trace("PeakWorkingSetSize : %lu\n", pvi
->PeakWorkingSetSize
);
1116 trace("WorkingSetSize : %lu\n", pvi
->WorkingSetSize
);
1117 trace("QuotaPeakPagedPoolUsage : %lu\n", pvi
->QuotaPeakPagedPoolUsage
);
1118 trace("QuotaPagedPoolUsage : %lu\n", pvi
->QuotaPagedPoolUsage
);
1119 trace("QuotaPeakNonPagePoolUsage : %lu\n", pvi
->QuotaPeakNonPagedPoolUsage
);
1120 trace("QuotaNonPagePoolUsage : %lu\n", pvi
->QuotaNonPagedPoolUsage
);
1121 trace("PagefileUsage : %lu\n", pvi
->PagefileUsage
);
1122 trace("PeakPagefileUsage : %lu\n", pvi
->PeakPagefileUsage
);
1125 static void test_query_process_vm(void)
1130 ULONG old_size
= FIELD_OFFSET(VM_COUNTERS
,PrivatePageCount
);
1133 const SIZE_T alloc_size
= 16 * 1024 * 1024;
1136 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, NULL
, sizeof(pvi
), NULL
);
1137 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1138 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1140 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, &pvi
, old_size
, NULL
);
1141 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1143 /* Windows XP and W2K3 will report success for a size of 44 AND 48 !
1144 Windows W2K will only report success for 44.
1145 For now we only care for 44, which is FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
1148 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 24, &ReturnLength
);
1149 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1151 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, old_size
, &ReturnLength
);
1152 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1153 ok( old_size
== ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1155 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 46, &ReturnLength
);
1156 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1157 ok( ReturnLength
== old_size
|| ReturnLength
== sizeof(pvi
), "Inconsistent length %d\n", ReturnLength
);
1159 /* Check if we have some return values */
1160 dump_vm_counters("VM counters for GetCurrentProcess", &pvi
);
1161 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1162 ok( pvi
.PagefileUsage
> 0, "Expected a PagefileUsage > 0\n");
1164 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1165 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1166 ok( status
== STATUS_ACCESS_DENIED
, "Expected STATUS_ACCESS_DENIED, got %08x\n", status
);
1167 CloseHandle(process
);
1169 process
= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION
, FALSE
, GetCurrentProcessId());
1170 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1171 ok( status
== STATUS_SUCCESS
|| broken(!process
) /* XP */, "Expected STATUS_SUCCESS, got %08x\n", status
);
1172 CloseHandle(process
);
1174 memset(&pvi
, 0, sizeof(pvi
));
1175 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, GetCurrentProcessId());
1176 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1177 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1179 /* Check if we have some return values */
1180 dump_vm_counters("VM counters for GetCurrentProcessId", &pvi
);
1181 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1182 ok( pvi
.PagefileUsage
> 0, "Expected a PagefileUsage > 0\n");
1184 CloseHandle(process
);
1186 /* Check if we have real counters */
1187 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1188 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1189 prev_size
= pvi
.VirtualSize
;
1190 if (winetest_debug
> 1)
1191 dump_vm_counters("VM counters before VirtualAlloc", &pvi
);
1192 ptr
= VirtualAlloc(NULL
, alloc_size
, MEM_COMMIT
| MEM_RESERVE
, PAGE_READWRITE
);
1193 ok( ptr
!= NULL
, "VirtualAlloc failed, err %u\n", GetLastError());
1194 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1195 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1196 if (winetest_debug
> 1)
1197 dump_vm_counters("VM counters after VirtualAlloc", &pvi
);
1198 todo_wine
ok( pvi
.VirtualSize
>= prev_size
+ alloc_size
,
1199 "Expected to be greater than %lu, got %lu\n", prev_size
+ alloc_size
, pvi
.VirtualSize
);
1200 VirtualFree( ptr
, 0, MEM_RELEASE
);
1202 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1203 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1204 prev_size
= pvi
.VirtualSize
;
1205 if (winetest_debug
> 1)
1206 dump_vm_counters("VM counters before VirtualAlloc", &pvi
);
1207 ptr
= VirtualAlloc(NULL
, alloc_size
, MEM_RESERVE
, PAGE_READWRITE
);
1208 ok( ptr
!= NULL
, "VirtualAlloc failed, err %u\n", GetLastError());
1209 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1210 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1211 if (winetest_debug
> 1)
1212 dump_vm_counters("VM counters after VirtualAlloc(MEM_RESERVE)", &pvi
);
1213 todo_wine
ok( pvi
.VirtualSize
>= prev_size
+ alloc_size
,
1214 "Expected to be greater than %lu, got %lu\n", prev_size
+ alloc_size
, pvi
.VirtualSize
);
1215 prev_size
= pvi
.VirtualSize
;
1217 ptr
= VirtualAlloc(ptr
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
1218 ok( ptr
!= NULL
, "VirtualAlloc failed, err %u\n", GetLastError());
1219 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1220 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1221 if (winetest_debug
> 1)
1222 dump_vm_counters("VM counters after VirtualAlloc(MEM_COMMIT)", &pvi
);
1223 ok( pvi
.VirtualSize
== prev_size
,
1224 "Expected to equal to %lu, got %lu\n", prev_size
, pvi
.VirtualSize
);
1225 VirtualFree( ptr
, 0, MEM_RELEASE
);
1228 static void test_query_process_io(void)
1234 /* NT4 doesn't support this information class, so check for it */
1235 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
1236 if (status
== STATUS_NOT_SUPPORTED
)
1238 win_skip("ProcessIoCounters information class is not supported\n");
1242 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, NULL
, sizeof(pii
), NULL
);
1243 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1244 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1246 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, &pii
, sizeof(pii
), NULL
);
1247 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1249 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, 24, &ReturnLength
);
1250 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1252 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
1253 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1254 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1256 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
) * 2, &ReturnLength
);
1257 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1258 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1260 /* Check if we have some return values */
1261 trace("OtherOperationCount : 0x%s\n", wine_dbgstr_longlong(pii
.OtherOperationCount
));
1264 ok( pii
.OtherOperationCount
> 0, "Expected an OtherOperationCount > 0\n");
1268 static void test_query_process_times(void)
1273 SYSTEMTIME UTC
, Local
;
1274 KERNEL_USER_TIMES spti
;
1276 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, NULL
, sizeof(spti
), NULL
);
1277 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1278 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1280 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, &spti
, sizeof(spti
), NULL
);
1281 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1283 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, 24, &ReturnLength
);
1284 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1286 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
1289 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
1290 process
= GetCurrentProcess();
1291 trace("ProcessTimes for current process\n");
1294 trace("ProcessTimes for process with ID : %d\n", one_before_last_pid
);
1296 status
= pNtQueryInformationProcess( process
, ProcessTimes
, &spti
, sizeof(spti
), &ReturnLength
);
1297 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1298 ok( sizeof(spti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1299 CloseHandle(process
);
1301 FileTimeToSystemTime((const FILETIME
*)&spti
.CreateTime
, &UTC
);
1302 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
1303 trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
1304 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
1306 FileTimeToSystemTime((const FILETIME
*)&spti
.ExitTime
, &UTC
);
1307 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
1308 trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
1309 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
1311 FileTimeToSystemTime((const FILETIME
*)&spti
.KernelTime
, &Local
);
1312 trace("KernelTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
1314 FileTimeToSystemTime((const FILETIME
*)&spti
.UserTime
, &Local
);
1315 trace("UserTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
1317 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, sizeof(spti
) * 2, &ReturnLength
);
1318 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1319 ok( sizeof(spti
) == ReturnLength
||
1320 ReturnLength
== 0 /* vista */ ||
1321 broken(is_wow64
), /* returns garbage on wow64 */
1322 "Inconsistent length %d\n", ReturnLength
);
1325 static void test_query_process_debug_port(int argc
, char **argv
)
1327 DWORD_PTR debug_port
= 0xdeadbeef;
1328 char cmdline
[MAX_PATH
];
1329 PROCESS_INFORMATION pi
;
1330 STARTUPINFOA si
= { 0 };
1334 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1337 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
, NULL
, &si
, &pi
);
1338 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
1341 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1343 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1345 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1346 NULL
, sizeof(debug_port
), NULL
);
1347 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
,
1348 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1350 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1351 NULL
, sizeof(debug_port
), NULL
);
1352 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1354 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1355 &debug_port
, sizeof(debug_port
), NULL
);
1356 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1358 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1359 &debug_port
, sizeof(debug_port
) - 1, NULL
);
1360 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1362 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1363 &debug_port
, sizeof(debug_port
) + 1, NULL
);
1364 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1366 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1367 &debug_port
, sizeof(debug_port
), NULL
);
1368 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1369 ok(debug_port
== 0, "Expected port 0, got %#lx.\n", debug_port
);
1371 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugPort
,
1372 &debug_port
, sizeof(debug_port
), NULL
);
1373 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1374 ok(debug_port
== ~(DWORD_PTR
)0, "Expected port %#lx, got %#lx.\n", ~(DWORD_PTR
)0, debug_port
);
1380 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1381 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1384 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1386 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1387 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1391 ret
= CloseHandle(pi
.hThread
);
1392 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1393 ret
= CloseHandle(pi
.hProcess
);
1394 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1397 static void test_query_process_priority(void)
1399 PROCESS_PRIORITY_CLASS priority
[2];
1401 DWORD orig_priority
;
1405 status
= pNtQueryInformationProcess(NULL
, ProcessPriorityClass
, NULL
, sizeof(priority
[0]), NULL
);
1406 ok(status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_HANDLE
) /* w2k3 */,
1407 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
1409 status
= pNtQueryInformationProcess(NULL
, ProcessPriorityClass
, &priority
, sizeof(priority
[0]), NULL
);
1410 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1412 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, 1, &ReturnLength
);
1413 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1415 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, sizeof(priority
), &ReturnLength
);
1416 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1418 orig_priority
= GetPriorityClass(GetCurrentProcess());
1419 ret
= SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS
);
1420 ok(ret
, "Failed to set priority class: %u\n", GetLastError());
1422 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, sizeof(priority
[0]), &ReturnLength
);
1423 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1424 ok(priority
[0].PriorityClass
== PROCESS_PRIOCLASS_BELOW_NORMAL
,
1425 "Expected PROCESS_PRIOCLASS_BELOW_NORMAL, got %u\n", priority
[0].PriorityClass
);
1427 ret
= SetPriorityClass(GetCurrentProcess(), orig_priority
);
1428 ok(ret
, "Failed to reset priority class: %u\n", GetLastError());
1431 static void test_query_process_handlecount(void)
1436 BYTE buffer
[2 * sizeof(DWORD
)];
1439 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, NULL
, sizeof(handlecount
), NULL
);
1440 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1441 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1443 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), NULL
);
1444 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1446 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, &handlecount
, 2, &ReturnLength
);
1447 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1449 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
1452 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
1453 process
= GetCurrentProcess();
1454 trace("ProcessHandleCount for current process\n");
1457 trace("ProcessHandleCount for process with ID : %d\n", one_before_last_pid
);
1459 status
= pNtQueryInformationProcess( process
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), &ReturnLength
);
1460 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1461 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1462 CloseHandle(process
);
1464 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, buffer
, sizeof(buffer
), &ReturnLength
);
1465 ok( status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_SUCCESS
,
1466 "Expected STATUS_INFO_LENGTH_MISMATCH or STATUS_SUCCESS, got %08x\n", status
);
1467 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1469 /* Check if we have some return values */
1470 trace("HandleCount : %d\n", handlecount
);
1473 ok( handlecount
> 0, "Expected some handles, got 0\n");
1477 static void test_query_process_image_file_name(void)
1481 UNICODE_STRING image_file_name
;
1486 status
= pNtQueryInformationProcess(NULL
, ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), NULL
);
1487 if (status
== STATUS_INVALID_INFO_CLASS
)
1489 win_skip("ProcessImageFileName is not supported\n");
1492 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1494 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, 2, &ReturnLength
);
1495 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1497 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), &ReturnLength
);
1498 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1500 buffer
= HeapAlloc(GetProcessHeap(), 0, ReturnLength
);
1501 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, buffer
, ReturnLength
, &ReturnLength
);
1502 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1503 memcpy(&image_file_name
, buffer
, sizeof(image_file_name
));
1504 len
= WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), NULL
, 0, NULL
, NULL
);
1505 file_nameA
= HeapAlloc(GetProcessHeap(), 0, len
+ 1);
1506 WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), file_nameA
, len
, NULL
, NULL
);
1507 file_nameA
[len
] = '\0';
1508 HeapFree(GetProcessHeap(), 0, buffer
);
1509 trace("process image file name: %s\n", file_nameA
);
1510 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
);
1511 HeapFree(GetProcessHeap(), 0, file_nameA
);
1514 static void test_query_process_debug_object_handle(int argc
, char **argv
)
1516 char cmdline
[MAX_PATH
];
1517 STARTUPINFOA si
= {0};
1518 PROCESS_INFORMATION pi
;
1520 HANDLE debug_object
;
1523 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1526 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
,
1528 ok(ret
, "CreateProcess failed with last error %u\n", GetLastError());
1531 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
1533 if (status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
)
1535 win_skip("ProcessDebugObjectHandle is not supported\n");
1538 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1539 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n",
1542 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
1543 sizeof(debug_object
), NULL
);
1544 ok(status
== STATUS_INVALID_HANDLE
||
1545 status
== STATUS_ACCESS_VIOLATION
, /* XP */
1546 "Expected NtQueryInformationProcess to return STATUS_INVALID_HANDLE, got 0x%08x\n", status
);
1548 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1549 ProcessDebugObjectHandle
, NULL
, sizeof(debug_object
), NULL
);
1550 ok(status
== STATUS_ACCESS_VIOLATION
,
1551 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
1553 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
,
1554 &debug_object
, sizeof(debug_object
), NULL
);
1555 ok(status
== STATUS_INVALID_HANDLE
,
1556 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
1558 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1559 ProcessDebugObjectHandle
, &debug_object
,
1560 sizeof(debug_object
) - 1, NULL
);
1561 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1562 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
1564 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1565 ProcessDebugObjectHandle
, &debug_object
,
1566 sizeof(debug_object
) + 1, NULL
);
1567 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1568 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
1570 debug_object
= (HANDLE
)0xdeadbeef;
1571 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1572 ProcessDebugObjectHandle
, &debug_object
,
1573 sizeof(debug_object
), NULL
);
1574 ok(status
== STATUS_PORT_NOT_SET
,
1575 "Expected NtQueryInformationProcess to return STATUS_PORT_NOT_SET, got 0x%08x\n", status
);
1576 ok(debug_object
== NULL
||
1577 broken(debug_object
== (HANDLE
)0xdeadbeef), /* Wow64 */
1578 "Expected debug object handle to be NULL, got %p\n", debug_object
);
1580 debug_object
= (HANDLE
)0xdeadbeef;
1581 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugObjectHandle
,
1582 &debug_object
, sizeof(debug_object
), NULL
);
1584 ok(status
== STATUS_SUCCESS
,
1585 "Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08x\n", status
);
1587 ok(debug_object
!= NULL
,
1588 "Expected debug object handle to be non-NULL, got %p\n", debug_object
);
1594 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1595 ok(ret
, "WaitForDebugEvent failed with last error %u\n", GetLastError());
1598 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1600 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1601 ok(ret
, "ContinueDebugEvent failed with last error %u\n", GetLastError());
1605 ret
= CloseHandle(pi
.hThread
);
1606 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1607 ret
= CloseHandle(pi
.hProcess
);
1608 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1611 static void test_query_process_debug_flags(int argc
, char **argv
)
1613 static const DWORD test_flags
[] = { DEBUG_PROCESS
,
1614 DEBUG_ONLY_THIS_PROCESS
,
1615 DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
,
1617 DWORD debug_flags
= 0xdeadbeef;
1618 char cmdline
[MAX_PATH
];
1619 PROCESS_INFORMATION pi
;
1620 STARTUPINFOA si
= { 0 };
1627 /* test invalid arguments */
1628 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, 0, NULL
);
1629 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1630 "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1632 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, sizeof(debug_flags
), NULL
);
1633 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1634 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1636 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1637 NULL
, sizeof(debug_flags
), NULL
);
1638 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1640 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
,
1641 &debug_flags
, sizeof(debug_flags
), NULL
);
1642 ok(status
== STATUS_INVALID_HANDLE
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1643 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1645 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1646 &debug_flags
, sizeof(debug_flags
) - 1, NULL
);
1647 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1649 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1650 &debug_flags
, sizeof(debug_flags
) + 1, NULL
);
1651 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1653 /* test ProcessDebugFlags of current process */
1654 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1655 &debug_flags
, sizeof(debug_flags
), NULL
);
1656 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1657 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %x.\n", debug_flags
);
1659 for (i
= 0; i
< sizeof(test_flags
)/sizeof(test_flags
[0]); i
++)
1661 DWORD expected_flags
= !(test_flags
[i
] & DEBUG_ONLY_THIS_PROCESS
);
1662 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1665 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, test_flags
[i
], NULL
, NULL
, &si
, &pi
);
1666 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
1668 if (!(test_flags
[i
] & (DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
)))
1670 /* test ProcessDebugFlags before attaching with debugger */
1671 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1672 &debug_flags
, sizeof(debug_flags
), NULL
);
1673 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1674 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %x.\n", debug_flags
);
1676 ret
= DebugActiveProcess(pi
.dwProcessId
);
1677 ok(ret
, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1678 expected_flags
= FALSE
;
1681 /* test ProcessDebugFlags after attaching with debugger */
1682 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1683 &debug_flags
, sizeof(debug_flags
), NULL
);
1684 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1685 ok(debug_flags
== expected_flags
, "Expected flag %x, got %x.\n", expected_flags
, debug_flags
);
1687 if (!(test_flags
[i
] & CREATE_SUSPENDED
))
1689 /* Continue a couple of times to make sure the process is fully initialized,
1690 * otherwise Windows XP deadlocks in the following DebugActiveProcess(). */
1693 ret
= WaitForDebugEvent(&ev
, 1000);
1694 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1697 if (ev
.dwDebugEventCode
== LOAD_DLL_DEBUG_EVENT
) break;
1699 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1700 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1704 result
= SuspendThread(pi
.hThread
);
1705 ok(result
== 0, "Expected 0, got %u.\n", result
);
1708 ret
= DebugActiveProcessStop(pi
.dwProcessId
);
1709 ok(ret
, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError());
1711 /* test ProcessDebugFlags after detaching debugger */
1712 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1713 &debug_flags
, sizeof(debug_flags
), NULL
);
1714 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1715 ok(debug_flags
== expected_flags
, "Expected flag %x, got %x.\n", expected_flags
, debug_flags
);
1717 ret
= DebugActiveProcess(pi
.dwProcessId
);
1718 ok(ret
, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1720 /* test ProcessDebugFlags after re-attaching debugger */
1721 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1722 &debug_flags
, sizeof(debug_flags
), NULL
);
1723 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1724 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %x.\n", debug_flags
);
1726 result
= ResumeThread(pi
.hThread
);
1727 todo_wine
ok(result
== 2, "Expected 2, got %u.\n", result
);
1729 /* Wait until the process is terminated. On Windows XP the process randomly
1730 * gets stuck in a non-continuable exception, so stop after 100 iterations.
1731 * On Windows 2003, the debugged process disappears (or stops?) without
1732 * any EXIT_PROCESS_DEBUG_EVENT after a couple of events. */
1733 for (j
= 0; j
< 100; j
++)
1735 ret
= WaitForDebugEvent(&ev
, 1000);
1736 ok(ret
|| broken(GetLastError() == ERROR_SEM_TIMEOUT
),
1737 "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1740 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1742 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1743 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1746 ok(j
< 100 || broken(j
>= 100) /* Win XP */, "Expected less than 100 debug events.\n");
1748 /* test ProcessDebugFlags after process has terminated */
1749 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1750 &debug_flags
, sizeof(debug_flags
), NULL
);
1751 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1752 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %x.\n", debug_flags
);
1754 ret
= CloseHandle(pi
.hThread
);
1755 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1756 ret
= CloseHandle(pi
.hProcess
);
1757 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1761 static void test_readvirtualmemory(void)
1766 static const char teststring
[] = "test string";
1769 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1770 ok(process
!= 0, "Expected to be able to open own process for reading memory\n");
1772 /* normal operation */
1773 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, &readcount
);
1774 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1775 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1776 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1778 /* no number of bytes */
1779 memset(buffer
, 0, 12);
1780 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, NULL
);
1781 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1782 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1784 /* illegal remote address */
1786 status
= pNtReadVirtualMemory(process
, (void *) 0x1234, buffer
, 12, &readcount
);
1787 ok( status
== STATUS_PARTIAL_COPY
|| broken(status
== STATUS_ACCESS_VIOLATION
), "Expected STATUS_PARTIAL_COPY, got %08x\n", status
);
1788 if (status
== STATUS_PARTIAL_COPY
)
1789 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1793 status
= pNtReadVirtualMemory(0, teststring
, buffer
, 12, &readcount
);
1794 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1795 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1797 /* pseudo handle for current process*/
1798 memset(buffer
, 0, 12);
1799 status
= pNtReadVirtualMemory((HANDLE
)-1, teststring
, buffer
, 12, &readcount
);
1800 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1801 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1802 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1804 /* illegal local address */
1805 status
= pNtReadVirtualMemory(process
, teststring
, (void *)0x1234, 12, &readcount
);
1806 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
1807 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1809 CloseHandle(process
);
1812 static void test_mapprotection(void)
1816 MEMORY_BASIC_INFORMATION info
;
1817 ULONG oldflags
, flagsize
, flags
= MEM_EXECUTE_OPTION_ENABLE
;
1818 LARGE_INTEGER size
, offset
;
1820 SIZE_T retlen
, count
;
1824 skip("No NtClose ... Win98\n");
1827 /* Switch to being a noexec unaware process */
1828 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof (oldflags
), &flagsize
);
1829 if (status
== STATUS_INVALID_PARAMETER
) {
1830 skip("Invalid Parameter on ProcessExecuteFlags query?\n");
1833 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1834 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &flags
, sizeof(flags
) );
1835 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1837 size
.u
.LowPart
= 0x2000;
1838 size
.u
.HighPart
= 0;
1839 status
= pNtCreateSection ( &h
,
1840 STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
,
1844 SEC_COMMIT
| SEC_NOCACHE
,
1847 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1849 offset
.u
.LowPart
= 0;
1850 offset
.u
.HighPart
= 0;
1853 status
= pNtMapViewOfSection ( h
, GetCurrentProcess(), &addr
, 0, 0, &offset
, &count
, ViewShare
, 0, PAGE_READWRITE
);
1854 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1856 #if defined(__x86_64__) || defined(__i386__)
1857 *(unsigned char*)addr
= 0xc3; /* lret ... in both i386 and x86_64 */
1858 #elif defined(__arm__)
1859 *(unsigned long*)addr
= 0xe12fff1e; /* bx lr */
1860 #elif defined(__aarch64__)
1861 *(unsigned long*)addr
= 0xd65f03c0; /* ret */
1863 ok(0, "Add a return opcode for your architecture or expect a crash in this test\n");
1865 trace("trying to execute code in the readwrite only mapped anon file...\n");
1867 trace("...done.\n");
1869 status
= pNtQueryVirtualMemory( GetCurrentProcess(), addr
, MemoryBasicInformation
, &info
, sizeof(info
), &retlen
);
1870 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1871 ok( retlen
== sizeof(info
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1872 ok((info
.Protect
& ~PAGE_NOCACHE
) == PAGE_READWRITE
, "addr.Protect is not PAGE_READWRITE, but 0x%x\n", info
.Protect
);
1874 status
= pNtUnmapViewOfSection( GetCurrentProcess(), (char *)addr
+ 0x1050 );
1875 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1879 pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof(oldflags
) );
1882 static void test_queryvirtualmemory(void)
1886 static const WCHAR windowsW
[] = {'w','i','n','d','o','w','s'};
1887 static const char teststring
[] = "test string";
1888 static char datatestbuf
[42] = "abc";
1889 static char rwtestbuf
[42];
1890 MEMORY_BASIC_INFORMATION mbi
;
1893 char buffer_name
[sizeof(MEMORY_SECTION_NAME
) + MAX_PATH
* sizeof(WCHAR
)];
1894 MEMORY_SECTION_NAME
*msn
= (MEMORY_SECTION_NAME
*)buffer_name
;
1898 module
= GetModuleHandleA( "ntdll.dll" );
1899 trace("Check flags of the PE header of NTDLL.DLL at %p\n", module
);
1900 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1901 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1902 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1903 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1904 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1905 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1906 ok (mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READONLY
);
1907 ok (mbi
.Type
== MEM_IMAGE
, "mbi.Type is 0x%x, expected 0x%x\n", mbi
.Type
, MEM_IMAGE
);
1909 trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory
);
1910 module
= GetModuleHandleA( "ntdll.dll" );
1911 status
= pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory
, 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_EXECUTE_READ
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_EXECUTE_READ
);
1919 trace("Check flags of heap at %p\n", GetProcessHeap());
1920 status
= pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1921 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1922 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1923 ok (mbi
.AllocationProtect
== PAGE_READWRITE
|| mbi
.AllocationProtect
== PAGE_EXECUTE_READWRITE
,
1924 "mbi.AllocationProtect is 0x%x\n", mbi
.AllocationProtect
);
1925 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1926 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_EXECUTE_READWRITE
,
1927 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1929 trace("Check flags of stack at %p\n", stackbuf
);
1930 status
= pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1931 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1932 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1933 ok (mbi
.AllocationProtect
== PAGE_READWRITE
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_READWRITE
);
1934 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1935 ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READWRITE
);
1937 trace("Check flags of read-only data at %p\n", teststring
);
1938 module
= GetModuleHandleA( NULL
);
1939 status
= pNtQueryVirtualMemory(NtCurrentProcess(), teststring
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1940 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1941 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1942 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1943 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1944 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1945 if (mbi
.Protect
!= PAGE_READONLY
)
1946 todo_wine
ok( mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%X\n", mbi
.Protect
, PAGE_READONLY
);
1948 trace("Check flags of read-write data at %p\n", datatestbuf
);
1949 status
= pNtQueryVirtualMemory(NtCurrentProcess(), datatestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1950 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1951 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1952 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1953 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1954 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1955 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
1956 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1958 trace("Check flags of read-write uninitialized data (.bss) at %p\n", rwtestbuf
);
1959 status
= pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1960 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1961 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1962 if (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
);
1969 else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
1971 trace("Check section name of NTDLL.DLL with invalid size\n");
1972 module
= GetModuleHandleA( "ntdll.dll" );
1973 memset(msn
, 0, sizeof(*msn
));
1975 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemorySectionName
, msn
, sizeof(*msn
), &readcount
);
1976 ok( status
== STATUS_BUFFER_OVERFLOW
, "Expected STATUS_BUFFER_OVERFLOW, got %08x\n", status
);
1977 ok( readcount
> 0, "Expected readcount to be > 0\n");
1979 trace("Check section name of NTDLL.DLL with invalid size\n");
1980 module
= GetModuleHandleA( "ntdll.dll" );
1981 memset(msn
, 0, sizeof(*msn
));
1983 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemorySectionName
, msn
, sizeof(*msn
) - 1, &readcount
);
1984 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1985 ok( readcount
> 0, "Expected readcount to be > 0\n");
1987 trace("Check section name of NTDLL.DLL\n");
1988 module
= GetModuleHandleA( "ntdll.dll" );
1989 memset(msn
, 0x55, sizeof(*msn
));
1990 memset(buffer_name
, 0x77, sizeof(buffer_name
));
1992 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemorySectionName
, msn
, sizeof(buffer_name
), &readcount
);
1993 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1994 ok( readcount
> 0, "Expected readcount to be > 0\n");
1995 trace ("Section Name: %s\n", wine_dbgstr_w(msn
->SectionFileName
.Buffer
));
1996 pRtlDowncaseUnicodeString( &msn
->SectionFileName
, &msn
->SectionFileName
, FALSE
);
1997 for (found
= FALSE
, i
= (msn
->SectionFileName
.Length
- sizeof(windowsW
)) / sizeof(WCHAR
); i
>= 0; i
--)
1998 found
|= !memcmp( &msn
->SectionFileName
.Buffer
[i
], windowsW
, sizeof(windowsW
) );
1999 ok( found
, "Section name does not contain \"Windows\"\n");
2001 trace("Check section name of non mapped memory\n");
2002 memset(msn
, 0, sizeof(*msn
));
2004 status
= pNtQueryVirtualMemory(NtCurrentProcess(), &buffer_name
, MemorySectionName
, msn
, sizeof(buffer_name
), &readcount
);
2005 ok( status
== STATUS_INVALID_ADDRESS
, "Expected STATUS_INVALID_ADDRESS, got %08x\n", status
);
2006 ok( readcount
== 0 || broken(readcount
!= 0) /* wow64 */, "Expected readcount to be 0\n");
2009 static void test_affinity(void)
2012 PROCESS_BASIC_INFORMATION pbi
;
2013 DWORD_PTR proc_affinity
, thread_affinity
;
2014 THREAD_BASIC_INFORMATION tbi
;
2018 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
2019 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2020 proc_affinity
= pbi
.AffinityMask
;
2021 ok( proc_affinity
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected process affinity\n" );
2022 proc_affinity
= 1 << si
.dwNumberOfProcessors
;
2023 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2024 ok( status
== STATUS_INVALID_PARAMETER
,
2025 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2028 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2029 ok( status
== STATUS_INVALID_PARAMETER
,
2030 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2032 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2033 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2034 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected thread affinity\n" );
2035 thread_affinity
= 1 << si
.dwNumberOfProcessors
;
2036 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2037 ok( status
== STATUS_INVALID_PARAMETER
,
2038 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2039 thread_affinity
= 0;
2040 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2041 ok( status
== STATUS_INVALID_PARAMETER
,
2042 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2044 thread_affinity
= 1;
2045 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2046 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2047 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2048 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2049 ok( tbi
.AffinityMask
== 1, "Unexpected thread affinity\n" );
2051 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
2052 thread_affinity
= ~(DWORD_PTR
)0;
2053 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2054 ok( broken(status
== STATUS_INVALID_PARAMETER
) || status
== STATUS_SUCCESS
,
2055 "Expected STATUS_SUCCESS, got %08x\n", status
);
2057 if (si
.dwNumberOfProcessors
<= 1)
2059 skip("only one processor, skipping affinity testing\n");
2063 /* Test thread affinity mask resulting from "all processors" flag */
2064 if (status
== STATUS_SUCCESS
)
2066 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2067 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2068 ok( broken(tbi
.AffinityMask
== 1) || tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
2069 "Unexpected thread affinity\n" );
2072 skip("Cannot test thread affinity mask for 'all processors' flag\n");
2075 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2076 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2077 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
2078 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2079 proc_affinity
= pbi
.AffinityMask
;
2080 ok( proc_affinity
== 2, "Unexpected process affinity\n" );
2081 /* Setting the process affinity changes the thread affinity to match */
2082 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2083 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2084 ok( tbi
.AffinityMask
== 2, "Unexpected thread affinity\n" );
2085 /* The thread affinity is restricted to the process affinity */
2086 thread_affinity
= 1;
2087 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2088 ok( status
== STATUS_INVALID_PARAMETER
,
2089 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2091 proc_affinity
= (1 << si
.dwNumberOfProcessors
) - 1;
2092 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2093 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2094 /* Resetting the process affinity also resets the thread affinity */
2095 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2096 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2097 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
2098 "Unexpected thread affinity\n" );
2101 static void test_NtGetCurrentProcessorNumber(void)
2105 PROCESS_BASIC_INFORMATION pbi
;
2106 THREAD_BASIC_INFORMATION tbi
;
2107 DWORD_PTR old_process_mask
;
2108 DWORD_PTR old_thread_mask
;
2113 if (!pNtGetCurrentProcessorNumber
) {
2114 win_skip("NtGetCurrentProcessorNumber not available\n");
2119 current_cpu
= pNtGetCurrentProcessorNumber();
2120 trace("dwNumberOfProcessors: %d, current processor: %d\n", si
.dwNumberOfProcessors
, current_cpu
);
2122 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
2123 old_process_mask
= pbi
.AffinityMask
;
2124 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2126 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2127 old_thread_mask
= tbi
.AffinityMask
;
2128 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2130 /* allow the test to run on all processors */
2131 new_mask
= (1 << si
.dwNumberOfProcessors
) - 1;
2132 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &new_mask
, sizeof(new_mask
));
2133 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2135 for (i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
2138 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &new_mask
, sizeof(new_mask
));
2139 ok(status
== STATUS_SUCCESS
, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i
, status
);
2141 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2142 ok(status
== STATUS_SUCCESS
, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i
, status
);
2144 current_cpu
= pNtGetCurrentProcessorNumber();
2145 ok((current_cpu
== i
), "%d (new_mask 0x%lx): running on processor %d (AffinityMask: 0x%lx)\n",
2146 i
, new_mask
, current_cpu
, tbi
.AffinityMask
);
2149 /* restore old values */
2150 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &old_process_mask
, sizeof(old_process_mask
));
2151 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2153 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &old_thread_mask
, sizeof(old_thread_mask
));
2154 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2157 static DWORD WINAPI
start_address_thread(void *arg
)
2159 PRTL_THREAD_START_ROUTINE entry
;
2165 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2166 &entry
, sizeof(entry
), &ret
);
2167 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2168 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2169 ok(entry
== (void *)start_address_thread
, "expected %p, got %p\n", start_address_thread
, entry
);
2173 static void test_thread_start_address(void)
2175 PRTL_THREAD_START_ROUTINE entry
, expected_entry
;
2176 IMAGE_NT_HEADERS
*nt
;
2182 module
= GetModuleHandleA(0);
2183 ok(module
!= NULL
, "expected non-NULL address for module\n");
2184 nt
= RtlImageNtHeader(module
);
2185 ok(nt
!= NULL
, "expected non-NULL address for NT header\n");
2189 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2190 &entry
, sizeof(entry
), &ret
);
2191 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2192 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2193 expected_entry
= (void *)((char *)module
+ nt
->OptionalHeader
.AddressOfEntryPoint
);
2194 ok(entry
== expected_entry
, "expected %p, got %p\n", expected_entry
, entry
);
2196 entry
= (void *)0xdeadbeef;
2197 status
= pNtSetInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2198 &entry
, sizeof(entry
));
2199 ok(status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, /* >= Vista */
2200 "expected STATUS_SUCCESS or STATUS_INVALID_PARAMETER, got %08x\n", status
);
2202 if (status
== STATUS_SUCCESS
)
2206 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2207 &entry
, sizeof(entry
), &ret
);
2208 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2209 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2210 ok(entry
== (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", entry
);
2213 thread
= CreateThread(NULL
, 0, start_address_thread
, NULL
, 0, NULL
);
2214 ok(thread
!= INVALID_HANDLE_VALUE
, "CreateThread failed with %d\n", GetLastError());
2215 ret
= WaitForSingleObject(thread
, 1000);
2216 ok(ret
== WAIT_OBJECT_0
, "expected WAIT_OBJECT_0, got %u\n", ret
);
2217 CloseHandle(thread
);
2220 static void test_query_data_alignment(void)
2227 status
= pNtQuerySystemInformation(SystemRecommendedSharedDataAlignment
, &value
, sizeof(value
), &ReturnLength
);
2228 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2229 ok(sizeof(value
) == ReturnLength
, "Inconsistent length %u\n", ReturnLength
);
2230 ok(value
== 64, "Expected 64, got %u\n", value
);
2233 static void test_working_set_limit(void)
2235 DWORD_PTR lower
= 0, upper
= ~(DWORD_PTR
)0;
2236 MEMORY_BASIC_INFORMATION mbi
;
2240 while (lower
!= upper
)
2242 DWORD_PTR check
= (lower
>> 1) + (upper
>> 1) + (lower
& upper
& 1);
2243 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (void *)check
, MemoryBasicInformation
,
2244 &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
2245 if (status
== STATUS_INVALID_PARAMETER
) upper
= check
;
2246 else lower
= check
+ 1;
2249 trace("working set limit is %p\n", (void *)upper
);
2250 ok(upper
!= ~(DWORD_PTR
)0, "expected != ~(DWORD_PTR)0\n");
2258 if(!InitFunctionPtrs())
2261 argc
= winetest_get_mainargs(&argv
);
2262 if (argc
>= 3) return; /* Child */
2264 /* NtQuerySystemInformation */
2266 /* 0x0 SystemBasicInformation */
2267 trace("Starting test_query_basic()\n");
2270 /* 0x1 SystemCpuInformation */
2271 trace("Starting test_query_cpu()\n");
2274 /* 0x2 SystemPerformanceInformation */
2275 trace("Starting test_query_performance()\n");
2276 test_query_performance();
2278 /* 0x3 SystemTimeOfDayInformation */
2279 trace("Starting test_query_timeofday()\n");
2280 test_query_timeofday();
2282 /* 0x5 SystemProcessInformation */
2283 trace("Starting test_query_process()\n");
2284 test_query_process();
2286 /* 0x8 SystemProcessorPerformanceInformation */
2287 trace("Starting test_query_procperf()\n");
2288 test_query_procperf();
2290 /* 0xb SystemModuleInformation */
2291 trace("Starting test_query_module()\n");
2292 test_query_module();
2294 /* 0x10 SystemHandleInformation */
2295 trace("Starting test_query_handle()\n");
2296 test_query_handle();
2298 /* 0x40 SystemHandleInformation */
2299 trace("Starting test_query_handle_ex()\n");
2300 test_query_handle_ex();
2302 /* 0x15 SystemCacheInformation */
2303 trace("Starting test_query_cache()\n");
2306 /* 0x17 SystemInterruptInformation */
2307 trace("Starting test_query_interrupt()\n");
2308 test_query_interrupt();
2310 /* 0x23 SystemKernelDebuggerInformation */
2311 trace("Starting test_query_kerndebug()\n");
2312 test_query_kerndebug();
2314 /* 0x25 SystemRegistryQuotaInformation */
2315 trace("Starting test_query_regquota()\n");
2316 test_query_regquota();
2318 /* 0x49 SystemLogicalProcessorInformation */
2319 trace("Starting test_query_logicalproc()\n");
2320 test_query_logicalproc();
2321 test_query_logicalprocex();
2323 /* NtPowerInformation */
2325 /* 0xb ProcessorInformation */
2326 trace("Starting test_query_processor_power_info()\n");
2327 test_query_processor_power_info();
2329 /* NtQueryInformationProcess */
2331 /* 0x0 ProcessBasicInformation */
2332 trace("Starting test_query_process_basic()\n");
2333 test_query_process_basic();
2335 /* 0x2 ProcessIoCounters */
2336 trace("Starting test_query_process_io()\n");
2337 test_query_process_io();
2339 /* 0x3 ProcessVmCounters */
2340 trace("Starting test_query_process_vm()\n");
2341 test_query_process_vm();
2343 /* 0x4 ProcessTimes */
2344 trace("Starting test_query_process_times()\n");
2345 test_query_process_times();
2347 /* 0x7 ProcessDebugPort */
2348 trace("Starting test_process_debug_port()\n");
2349 test_query_process_debug_port(argc
, argv
);
2351 /* 0x12 ProcessPriorityClass */
2352 trace("Starting test_query_process_priority()\n");
2353 test_query_process_priority();
2355 /* 0x14 ProcessHandleCount */
2356 trace("Starting test_query_process_handlecount()\n");
2357 test_query_process_handlecount();
2359 /* 0x1A ProcessWow64Information */
2360 trace("Starting test_query_process_wow64()\n");
2361 test_query_process_wow64();
2363 /* 0x1B ProcessImageFileName */
2364 trace("Starting test_query_process_image_file_name()\n");
2365 test_query_process_image_file_name();
2367 /* 0x1E ProcessDebugObjectHandle */
2368 trace("Starting test_query_process_debug_object_handle()\n");
2369 test_query_process_debug_object_handle(argc
, argv
);
2371 /* 0x1F ProcessDebugFlags */
2372 trace("Starting test_process_debug_flags()\n");
2373 test_query_process_debug_flags(argc
, argv
);
2375 /* belongs to its own file */
2376 trace("Starting test_readvirtualmemory()\n");
2377 test_readvirtualmemory();
2379 trace("Starting test_queryvirtualmemory()\n");
2380 test_queryvirtualmemory();
2382 trace("Starting test_mapprotection()\n");
2383 test_mapprotection();
2385 trace("Starting test_affinity()\n");
2388 trace("Starting test_NtGetCurrentProcessorNumber()\n");
2389 test_NtGetCurrentProcessorNumber();
2391 trace("Starting test_thread_start_address()\n");
2392 test_thread_start_address();
2394 trace("Starting test_query_data_alignment()\n");
2395 test_query_data_alignment();
2397 trace("Starting test_working_set_limit()\n");
2398 test_working_set_limit();