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"
23 static NTSTATUS (WINAPI
* pRtlDowncaseUnicodeString
)(UNICODE_STRING
*, const UNICODE_STRING
*, BOOLEAN
);
24 static NTSTATUS (WINAPI
* pNtQuerySystemInformation
)(SYSTEM_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
25 static NTSTATUS (WINAPI
* pNtQuerySystemInformationEx
)(SYSTEM_INFORMATION_CLASS
, void*, ULONG
, void*, ULONG
, ULONG
*);
26 static NTSTATUS (WINAPI
* pNtPowerInformation
)(POWER_INFORMATION_LEVEL
, PVOID
, ULONG
, PVOID
, ULONG
);
27 static NTSTATUS (WINAPI
* pNtQueryInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
, PULONG
);
28 static NTSTATUS (WINAPI
* pNtQueryInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
, PULONG
);
29 static NTSTATUS (WINAPI
* pNtSetInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
);
30 static NTSTATUS (WINAPI
* pNtSetInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
);
31 static NTSTATUS (WINAPI
* pNtReadVirtualMemory
)(HANDLE
, const void*, void*, SIZE_T
, SIZE_T
*);
32 static NTSTATUS (WINAPI
* pNtQueryVirtualMemory
)(HANDLE
, LPCVOID
, MEMORY_INFORMATION_CLASS
, PVOID
, SIZE_T
, SIZE_T
*);
33 static NTSTATUS (WINAPI
* pNtCreateSection
)(HANDLE
*,ACCESS_MASK
,const OBJECT_ATTRIBUTES
*,const LARGE_INTEGER
*,ULONG
,ULONG
,HANDLE
);
34 static NTSTATUS (WINAPI
* pNtMapViewOfSection
)(HANDLE
,HANDLE
,PVOID
*,ULONG
,SIZE_T
,const LARGE_INTEGER
*,SIZE_T
*,SECTION_INHERIT
,ULONG
,ULONG
);
35 static NTSTATUS (WINAPI
* pNtUnmapViewOfSection
)(HANDLE
,PVOID
);
36 static NTSTATUS (WINAPI
* pNtClose
)(HANDLE
);
37 static ULONG (WINAPI
* pNtGetCurrentProcessorNumber
)(void);
38 static BOOL (WINAPI
* pIsWow64Process
)(HANDLE
, PBOOL
);
39 static BOOL (WINAPI
* pGetLogicalProcessorInformationEx
)(LOGICAL_PROCESSOR_RELATIONSHIP
,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*,DWORD
*);
43 /* one_before_last_pid is used to be able to compare values of a still running process
44 with the output of the test_query_process_times and test_query_process_handlecount tests.
46 static DWORD one_before_last_pid
= 0;
48 #define NTDLL_GET_PROC(func) do { \
49 p ## func = (void*)GetProcAddress(hntdll, #func); \
51 trace("GetProcAddress(%s) failed\n", #func); \
56 static BOOL
InitFunctionPtrs(void)
58 /* All needed functions are NT based, so using GetModuleHandle is a good check */
59 HMODULE hntdll
= GetModuleHandleA("ntdll");
60 HMODULE hkernel32
= GetModuleHandleA("kernel32");
64 win_skip("Not running on NT\n");
68 NTDLL_GET_PROC(RtlDowncaseUnicodeString
);
69 NTDLL_GET_PROC(NtQuerySystemInformation
);
70 NTDLL_GET_PROC(NtPowerInformation
);
71 NTDLL_GET_PROC(NtQueryInformationProcess
);
72 NTDLL_GET_PROC(NtQueryInformationThread
);
73 NTDLL_GET_PROC(NtSetInformationProcess
);
74 NTDLL_GET_PROC(NtSetInformationThread
);
75 NTDLL_GET_PROC(NtReadVirtualMemory
);
76 NTDLL_GET_PROC(NtQueryVirtualMemory
);
77 NTDLL_GET_PROC(NtClose
);
78 NTDLL_GET_PROC(NtCreateSection
);
79 NTDLL_GET_PROC(NtMapViewOfSection
);
80 NTDLL_GET_PROC(NtUnmapViewOfSection
);
82 /* not present before XP */
83 pNtGetCurrentProcessorNumber
= (void *) GetProcAddress(hntdll
, "NtGetCurrentProcessorNumber");
85 pIsWow64Process
= (void *)GetProcAddress(hkernel32
, "IsWow64Process");
86 if (!pIsWow64Process
|| !pIsWow64Process( GetCurrentProcess(), &is_wow64
)) is_wow64
= FALSE
;
88 /* starting with Win7 */
89 pNtQuerySystemInformationEx
= (void *) GetProcAddress(hntdll
, "NtQuerySystemInformationEx");
90 if (!pNtQuerySystemInformationEx
)
91 win_skip("NtQuerySystemInformationEx() is not supported, some tests will be skipped.\n");
93 pGetLogicalProcessorInformationEx
= (void *) GetProcAddress(hkernel32
, "GetLogicalProcessorInformationEx");
98 static void test_query_basic(void)
102 SYSTEM_BASIC_INFORMATION sbi
;
104 /* This test also covers some basic parameter testing that should be the same for
105 * every information class
108 /* Use a nonexistent info class */
109 trace("Check nonexistent info class\n");
110 status
= pNtQuerySystemInformation(-1, NULL
, 0, NULL
);
111 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
112 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
114 /* Use an existing class but with a zero-length buffer */
115 trace("Check zero-length buffer\n");
116 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, 0, NULL
);
117 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
119 /* Use an existing class, correct length but no SystemInformation buffer */
120 trace("Check no SystemInformation buffer\n");
121 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, sizeof(sbi
), NULL
);
122 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
/* vista */,
123 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got %08x\n", status
);
125 /* Use an existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
126 trace("Check no ReturnLength pointer\n");
127 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), NULL
);
128 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
130 /* Check a too large buffer size */
131 trace("Check a too large buffer size\n");
132 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
) * 2, &ReturnLength
);
133 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
135 /* Finally some correct calls */
136 trace("Check with correct parameters\n");
137 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
138 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
139 ok( sizeof(sbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
141 /* Check if we have some return values */
142 trace("Number of Processors : %d\n", sbi
.NumberOfProcessors
);
143 ok( sbi
.NumberOfProcessors
> 0, "Expected more than 0 processors, got %d\n", sbi
.NumberOfProcessors
);
146 static void test_query_cpu(void)
150 SYSTEM_CPU_INFORMATION sci
;
152 status
= pNtQuerySystemInformation(SystemCpuInformation
, &sci
, sizeof(sci
), &ReturnLength
);
153 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
154 ok( sizeof(sci
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
156 /* Check if we have some return values */
157 trace("Processor FeatureSet : %08x\n", sci
.FeatureSet
);
158 ok( sci
.FeatureSet
!= 0, "Expected some features for this processor, got %08x\n", sci
.FeatureSet
);
161 static void test_query_performance(void)
165 ULONGLONG buffer
[sizeof(SYSTEM_PERFORMANCE_INFORMATION
)/sizeof(ULONGLONG
) + 5];
166 DWORD size
= sizeof(SYSTEM_PERFORMANCE_INFORMATION
);
168 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, 0, &ReturnLength
);
169 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
171 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
172 if (status
== STATUS_INFO_LENGTH_MISMATCH
&& is_wow64
)
174 /* size is larger on wow64 under w2k8/win7 */
176 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
178 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
179 ok( ReturnLength
== size
, "Inconsistent length %d\n", ReturnLength
);
181 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
+ 2, &ReturnLength
);
182 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
183 ok( ReturnLength
== size
|| ReturnLength
== size
+ 2,
184 "Inconsistent length %d\n", ReturnLength
);
186 /* Not return values yet, as struct members are unknown */
189 static void test_query_timeofday(void)
194 /* Copy of our winternl.h structure turned into a private one */
195 typedef struct _SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
{
196 LARGE_INTEGER liKeBootTime
;
197 LARGE_INTEGER liKeSystemTime
;
198 LARGE_INTEGER liExpTimeZoneBias
;
199 ULONG uCurrentTimeZoneId
;
201 } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
;
203 SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti
;
205 /* The struct size for NT (32 bytes) and Win2K/XP (48 bytes) differ.
207 * Windows 2000 and XP return STATUS_INFO_LENGTH_MISMATCH if the given buffer size is greater
208 * then 48 and 0 otherwise
209 * Windows NT returns STATUS_INFO_LENGTH_MISMATCH when the given buffer size is not correct
212 * Windows 2000 and XP copy the given buffer size into the provided buffer, if the return code is STATUS_SUCCESS
213 * NT only fills the buffer if the return code is STATUS_SUCCESS
217 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
219 if (status
== STATUS_INFO_LENGTH_MISMATCH
)
221 trace("Windows version is NT, we have to cater for differences with W2K/WinXP\n");
223 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 0, &ReturnLength
);
224 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
225 ok( 0 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
227 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
228 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 28, &ReturnLength
);
229 ok(status
== STATUS_SUCCESS
|| broken(status
== STATUS_INFO_LENGTH_MISMATCH
/* NT4 */), "Expected STATUS_SUCCESS, got %08x\n", status
);
230 ok( 0xdeadbeef == sti
.uCurrentTimeZoneId
, "This part of the buffer should not have been filled\n");
232 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 32, &ReturnLength
);
233 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
234 ok( 32 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
238 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 0, &ReturnLength
);
239 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
240 ok( 0 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
242 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
243 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 24, &ReturnLength
);
244 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
245 ok( 24 == ReturnLength
, "ReturnLength should be 24, it is (%d)\n", ReturnLength
);
246 ok( 0xdeadbeef == sti
.uCurrentTimeZoneId
, "This part of the buffer should not have been filled\n");
248 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
249 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 32, &ReturnLength
);
250 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
251 ok( 32 == ReturnLength
, "ReturnLength should be 32, it is (%d)\n", ReturnLength
);
252 ok( 0xdeadbeef != sti
.uCurrentTimeZoneId
, "Buffer should have been partially filled\n");
254 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 49, &ReturnLength
);
255 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
256 ok( ReturnLength
== 0 || ReturnLength
== sizeof(sti
) /* vista */,
257 "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
259 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
260 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
261 ok( sizeof(sti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
264 /* Check if we have some return values */
265 trace("uCurrentTimeZoneId : (%d)\n", sti
.uCurrentTimeZoneId
);
268 static void test_query_process(void)
275 SYSTEM_BASIC_INFORMATION sbi
;
277 /* Copy of our winternl.h structure turned into a private one */
278 typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE
{
279 ULONG NextEntryOffset
;
282 FILETIME ftCreationTime
;
284 FILETIME ftKernelTime
;
285 UNICODE_STRING ProcessName
;
286 DWORD dwBasePriority
;
287 HANDLE UniqueProcessId
;
288 HANDLE ParentProcessId
;
292 VM_COUNTERS vmCounters
;
293 IO_COUNTERS ioCounters
;
294 SYSTEM_THREAD_INFORMATION ti
[1];
295 } SYSTEM_PROCESS_INFORMATION_PRIVATE
;
297 ULONG SystemInformationLength
= sizeof(SYSTEM_PROCESS_INFORMATION_PRIVATE
);
298 SYSTEM_PROCESS_INFORMATION_PRIVATE
*spi
, *spi_buf
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
300 /* test ReturnLength */
302 status
= pNtQuerySystemInformation(SystemProcessInformation
, NULL
, 0, &ReturnLength
);
303 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH got %08x\n", status
);
304 ok( ReturnLength
> 0 || broken(ReturnLength
== 0) /* NT4, Win2K */,
305 "Expected a ReturnLength to show the needed length\n");
307 /* W2K3 and later returns the needed length, the rest returns 0, so we have to loop */
310 status
= pNtQuerySystemInformation(SystemProcessInformation
, spi_buf
, SystemInformationLength
, &ReturnLength
);
312 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) break;
314 spi_buf
= HeapReAlloc(GetProcessHeap(), 0, spi_buf
, SystemInformationLength
*= 2);
316 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
319 /* Get the first NextEntryOffset, from this we can deduce the OS version we're running
322 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
324 * NextEntryOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
325 * Wine (with every windows version):
326 * NextEntryOffset for a process is 0 if just this test is running
327 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) +
328 * ProcessName.MaximumLength
329 * if more wine processes are running
331 * Note : On windows the first process is in fact the Idle 'process' with a thread for every processor
334 pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
336 is_nt
= ( spi
->NextEntryOffset
- (sbi
.NumberOfProcessors
* sizeof(SYSTEM_THREAD_INFORMATION
)) == 136);
338 if (is_nt
) win_skip("Windows version is NT, we will skip thread tests\n");
340 /* Check if we have some return values
342 * On windows there will be several processes running (Including the always present Idle and System)
343 * On wine we only have one (if this test is the only wine process running)
346 /* Loop through the processes */
352 last_pid
= (DWORD_PTR
)spi
->UniqueProcessId
;
354 ok( spi
->dwThreadCount
> 0, "Expected some threads for this process, got 0\n");
356 /* Loop through the threads, skip NT4 for now */
361 for ( j
= 0; j
< spi
->dwThreadCount
; j
++)
364 ok ( spi
->ti
[j
].ClientId
.UniqueProcess
== spi
->UniqueProcessId
,
365 "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n",
366 spi
->ti
[j
].ClientId
.UniqueProcess
, spi
->UniqueProcessId
);
370 if (!spi
->NextEntryOffset
) break;
372 one_before_last_pid
= last_pid
;
374 spi
= (SYSTEM_PROCESS_INFORMATION_PRIVATE
*)((char*)spi
+ spi
->NextEntryOffset
);
376 trace("Total number of running processes : %d\n", i
);
377 if (!is_nt
) trace("Total number of running threads : %d\n", k
);
379 if (one_before_last_pid
== 0) one_before_last_pid
= last_pid
;
381 HeapFree( GetProcessHeap(), 0, spi_buf
);
384 static void test_query_procperf(void)
389 SYSTEM_BASIC_INFORMATION sbi
;
390 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
* sppi
;
392 /* Find out the number of processors */
393 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
394 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
395 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
397 sppi
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
399 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, 0, &ReturnLength
);
400 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
402 /* Try it for 1 processor */
403 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
404 sppi
->UserTime
.QuadPart
= 0xdeaddead;
405 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
406 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
,
407 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
), &ReturnLength
);
408 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
409 ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) == ReturnLength
,
410 "Inconsistent length %d\n", ReturnLength
);
411 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
412 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
413 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
415 /* Try it for all processors */
416 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
417 sppi
->UserTime
.QuadPart
= 0xdeaddead;
418 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
419 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
, &ReturnLength
);
420 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
421 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
422 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
423 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
424 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
426 /* A too large given buffer size */
427 sppi
= HeapReAlloc(GetProcessHeap(), 0, sppi
, NeededLength
+ 2);
428 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
429 sppi
->UserTime
.QuadPart
= 0xdeaddead;
430 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
431 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
+ 2, &ReturnLength
);
432 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INFO_LENGTH_MISMATCH
/* vista */,
433 "Expected STATUS_SUCCESS or STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
434 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
435 if (status
== STATUS_SUCCESS
)
437 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
438 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
439 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
441 else /* vista and 2008 */
443 ok (sppi
->KernelTime
.QuadPart
== 0xdeaddead, "KernelTime changed\n");
444 ok (sppi
->UserTime
.QuadPart
== 0xdeaddead, "UserTime changed\n");
445 ok (sppi
->IdleTime
.QuadPart
== 0xdeaddead, "IdleTime changed\n");
448 HeapFree( GetProcessHeap(), 0, sppi
);
451 static void test_query_module(void)
455 ULONG ModuleCount
, i
;
457 ULONG SystemInformationLength
= sizeof(SYSTEM_MODULE_INFORMATION
);
458 SYSTEM_MODULE_INFORMATION
* smi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
461 /* Request the needed length */
462 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, 0, &ReturnLength
);
463 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
464 ok( ReturnLength
> 0, "Expected a ReturnLength to show the needed length\n");
466 SystemInformationLength
= ReturnLength
;
467 smi
= HeapReAlloc(GetProcessHeap(), 0, smi
, SystemInformationLength
);
468 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, SystemInformationLength
, &ReturnLength
);
469 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
471 ModuleCount
= smi
->ModulesCount
;
472 sm
= &smi
->Modules
[0];
473 /* our implementation is a stub for now */
474 ok( ModuleCount
> 0, "Expected some modules to be loaded\n");
476 /* Loop through all the modules/drivers, Wine doesn't get here (yet) */
477 for (i
= 0; i
< ModuleCount
; i
++)
479 ok( i
== sm
->Id
, "Id (%d) should have matched %u\n", sm
->Id
, i
);
483 HeapFree( GetProcessHeap(), 0, smi
);
486 static void test_query_handle(void)
489 ULONG ExpectedLength
, ReturnLength
;
490 ULONG SystemInformationLength
= sizeof(SYSTEM_HANDLE_INFORMATION
);
491 SYSTEM_HANDLE_INFORMATION
* shi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
496 EventHandle
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
497 ok( EventHandle
!= NULL
, "CreateEventA failed %u\n", GetLastError() );
499 /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
500 ReturnLength
= 0xdeadbeef;
501 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
502 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
503 ok( ReturnLength
!= 0xdeadbeef, "Expected valid ReturnLength\n" );
505 SystemInformationLength
= ReturnLength
;
506 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
507 memset(shi
, 0x55, SystemInformationLength
);
509 ReturnLength
= 0xdeadbeef;
510 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
511 while (status
== STATUS_INFO_LENGTH_MISMATCH
) /* Vista / 2008 */
513 SystemInformationLength
*= 2;
514 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
515 memset(shi
, 0x55, SystemInformationLength
);
516 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
518 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
519 ExpectedLength
= FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION
, Handle
[shi
->Count
]);
520 ok( ReturnLength
== ExpectedLength
|| broken(ReturnLength
== ExpectedLength
- sizeof(DWORD
)), /* Vista / 2008 */
521 "Expected length %u, got %u\n", ExpectedLength
, ReturnLength
);
522 ok( shi
->Count
> 1, "Expected more than 1 handle, got %u\n", shi
->Count
);
523 ok( shi
->Handle
[1].HandleValue
!= 0x5555 || broken( shi
->Handle
[1].HandleValue
== 0x5555 ), /* Vista / 2008 */
524 "Uninitialized second handle\n" );
525 if (shi
->Handle
[1].HandleValue
== 0x5555)
527 win_skip("Skipping broken SYSTEM_HANDLE_INFORMATION\n");
528 CloseHandle(EventHandle
);
532 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
533 found
= (shi
->Handle
[i
].OwnerPid
== GetCurrentProcessId()) &&
534 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
535 ok( found
, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle
, GetCurrentProcessId() );
538 for (i
= 0; i
< shi
->Count
; i
++)
539 trace( "%d: handle %x pid %x\n", i
, shi
->Handle
[i
].HandleValue
, shi
->Handle
[i
].OwnerPid
);
541 CloseHandle(EventHandle
);
543 ReturnLength
= 0xdeadbeef;
544 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
545 while (status
== STATUS_INFO_LENGTH_MISMATCH
) /* Vista / 2008 */
547 SystemInformationLength
*= 2;
548 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
549 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
551 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
552 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
553 found
= (shi
->Handle
[i
].OwnerPid
== GetCurrentProcessId()) &&
554 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
555 ok( !found
, "Unexpectedly found event handle in handle list\n" );
557 status
= pNtQuerySystemInformation(SystemHandleInformation
, NULL
, SystemInformationLength
, &ReturnLength
);
558 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
561 HeapFree( GetProcessHeap(), 0, shi
);
564 static void test_query_handle_ex(void)
567 ULONG ExpectedLength
, ReturnLength
;
568 ULONG SystemInformationLength
= sizeof(SYSTEM_HANDLE_INFORMATION_EX
);
569 SYSTEM_HANDLE_INFORMATION_EX
* shi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
574 EventHandle
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
575 ok( EventHandle
!= NULL
, "CreateEventA failed %u\n", GetLastError() );
577 ReturnLength
= 0xdeadbeef;
578 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
579 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
580 ok( ReturnLength
!= 0xdeadbeef, "Expected valid ReturnLength\n" );
582 SystemInformationLength
= ReturnLength
;
583 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
584 memset(shi
, 0x55, SystemInformationLength
);
586 ReturnLength
= 0xdeadbeef;
587 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
588 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
589 ExpectedLength
= FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX
, Handle
[shi
->Count
]);
590 ok( ReturnLength
== ExpectedLength
, "Expected length %u, got %u\n", ExpectedLength
, ReturnLength
);
591 ok( shi
->Count
> 1, "Expected more than 1 handle, got %u\n", (DWORD
)shi
->Count
);
593 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
594 found
= (shi
->Handle
[i
].UniqueProcessId
== GetCurrentProcessId()) &&
595 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
596 ok( found
, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle
, GetCurrentProcessId() );
600 for (i
= 0; i
< shi
->Count
; i
++)
601 trace( "%d: handle %x pid %x\n", i
, (DWORD
)shi
->Handle
[i
].HandleValue
, (DWORD
)shi
->Handle
[i
].UniqueProcessId
);
604 CloseHandle(EventHandle
);
606 ReturnLength
= 0xdeadbeef;
607 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
608 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
609 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
610 found
= (shi
->Handle
[i
].UniqueProcessId
== GetCurrentProcessId()) &&
611 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
612 ok( !found
, "Unexpectedly found event handle in handle list\n" );
614 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, NULL
, SystemInformationLength
, &ReturnLength
);
615 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
617 HeapFree( GetProcessHeap(), 0, shi
);
620 static void test_query_cache(void)
625 SYSTEM_CACHE_INFORMATION
*sci
= (SYSTEM_CACHE_INFORMATION
*) buffer
;
629 /* the large SYSTEM_CACHE_INFORMATION on WIN64 is not documented */
630 expected
= sizeof(SYSTEM_CACHE_INFORMATION
);
631 for (i
= sizeof(buffer
); i
>= expected
; i
--)
633 ReturnLength
= 0xdeadbeef;
634 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
635 ok(!status
&& (ReturnLength
== expected
),
636 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i
, status
, ReturnLength
, expected
);
639 /* buffer too small for the full result.
640 Up to win7, the function succeeds with a partial result. */
641 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
644 expected
= offsetof(SYSTEM_CACHE_INFORMATION
, MinimumWorkingSet
);
645 for (; i
>= expected
; i
--)
647 ReturnLength
= 0xdeadbeef;
648 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
649 ok(!status
&& (ReturnLength
== expected
),
650 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i
, status
, ReturnLength
, expected
);
654 /* buffer too small for the result, this call will always fail */
655 ReturnLength
= 0xdeadbeef;
656 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
657 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
658 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
659 "%d: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", i
, status
, ReturnLength
, expected
);
662 /* this crashes on some vista / win7 machines */
663 ReturnLength
= 0xdeadbeef;
664 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, 0, &ReturnLength
);
665 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
666 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
667 "0: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", status
, ReturnLength
, expected
);
671 static void test_query_interrupt(void)
676 SYSTEM_BASIC_INFORMATION sbi
;
677 SYSTEM_INTERRUPT_INFORMATION
* sii
;
679 /* Find out the number of processors */
680 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
681 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
682 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
);
684 sii
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
686 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, 0, &ReturnLength
);
687 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
689 /* Try it for all processors */
690 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, NeededLength
, &ReturnLength
);
691 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
693 /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength
694 * No test added for this as it's highly unlikely that an app depends on this
697 HeapFree( GetProcessHeap(), 0, sii
);
700 static void test_query_kerndebug(void)
704 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi
;
706 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, 0, &ReturnLength
);
707 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
709 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
), &ReturnLength
);
710 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
711 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
713 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
) + 2, &ReturnLength
);
714 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
715 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
718 static void test_query_regquota(void)
722 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi
;
724 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, 0, &ReturnLength
);
725 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
727 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
), &ReturnLength
);
728 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
729 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
731 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
) + 2, &ReturnLength
);
732 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
733 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
736 static void test_query_logicalproc(void)
739 ULONG len
, i
, proc_no
;
740 SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*slpi
;
745 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, NULL
, 0, &len
);
746 if(status
== STATUS_INVALID_INFO_CLASS
)
748 win_skip("SystemLogicalProcessorInformation is not supported\n");
751 if(status
== STATUS_NOT_IMPLEMENTED
)
753 todo_wine
ok(0, "SystemLogicalProcessorInformation is not implemented\n");
756 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
757 ok(len
%sizeof(*slpi
) == 0, "Incorrect length %d\n", len
);
759 slpi
= HeapAlloc(GetProcessHeap(), 0, len
);
760 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, slpi
, len
, &len
);
761 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
764 for(i
=0; i
<len
/sizeof(*slpi
); i
++) {
765 switch(slpi
[i
].Relationship
) {
766 case RelationProcessorCore
:
767 /* Get number of logical processors */
768 for(; slpi
[i
].ProcessorMask
; slpi
[i
].ProcessorMask
/= 2)
769 proc_no
+= slpi
[i
].ProcessorMask
%2;
775 ok(proc_no
> 0, "No processors were found\n");
776 if(si
.dwNumberOfProcessors
<= 32)
777 ok(proc_no
== si
.dwNumberOfProcessors
, "Incorrect number of logical processors: %d, expected %d\n",
778 proc_no
, si
.dwNumberOfProcessors
);
780 HeapFree(GetProcessHeap(), 0, slpi
);
783 static void test_query_logicalprocex(void)
785 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*infoex
, *infoex2
;
786 DWORD relationship
, len2
, len
;
790 if (!pNtQuerySystemInformationEx
)
794 relationship
= RelationProcessorCore
;
795 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len
);
796 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08x\n", status
);
797 ok(len
> 0, "got %u\n", len
);
800 relationship
= RelationAll
;
801 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len
);
802 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08x\n", status
);
803 ok(len
> 0, "got %u\n", len
);
806 ret
= pGetLogicalProcessorInformationEx(RelationAll
, NULL
, &len2
);
807 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %d, error %d\n", ret
, GetLastError());
808 ok(len
== len2
, "got %u, expected %u\n", len2
, len
);
810 if (len
&& len
== len2
) {
813 infoex
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
814 infoex2
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
816 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex
, len
, &len
);
817 ok(status
== STATUS_SUCCESS
, "got 0x%08x\n", status
);
819 ret
= pGetLogicalProcessorInformationEx(RelationAll
, infoex2
, &len2
);
820 ok(ret
, "got %d, error %d\n", ret
, GetLastError());
821 ok(!memcmp(infoex
, infoex2
, len
), "returned info data mismatch\n");
823 for(i
= 0; status
== STATUS_SUCCESS
&& i
< len
; ){
824 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*ex
= (void*)(((char *)infoex
) + i
);
826 ok(ex
->Relationship
>= RelationProcessorCore
&& ex
->Relationship
<= RelationGroup
,
827 "Got invalid relationship value: 0x%x\n", ex
->Relationship
);
830 ok(0, "got infoex[%u].Size=0\n", i
);
834 trace("infoex[%u].Size: %u\n", i
, ex
->Size
);
835 switch(ex
->Relationship
){
836 case RelationProcessorCore
:
837 case RelationProcessorPackage
:
838 trace("infoex[%u].Relationship: 0x%x (Core == 0x0 or Package == 0x3)\n", i
, ex
->Relationship
);
839 trace("infoex[%u].Processor.Flags: 0x%x\n", i
, ex
->Processor
.Flags
);
841 trace("infoex[%u].Processor.EfficiencyClass: 0x%x\n", i
, ex
->Processor
.EfficiencyClass
);
843 trace("infoex[%u].Processor.GroupCount: 0x%x\n", i
, ex
->Processor
.GroupCount
);
844 for(j
= 0; j
< ex
->Processor
.GroupCount
; ++j
){
845 trace("infoex[%u].Processor.GroupMask[%u].Mask: 0x%lx\n", i
, j
, ex
->Processor
.GroupMask
[j
].Mask
);
846 trace("infoex[%u].Processor.GroupMask[%u].Group: 0x%x\n", i
, j
, ex
->Processor
.GroupMask
[j
].Group
);
849 case RelationNumaNode
:
850 trace("infoex[%u].Relationship: 0x%x (NumaNode)\n", i
, ex
->Relationship
);
851 trace("infoex[%u].NumaNode.NodeNumber: 0x%x\n", i
, ex
->NumaNode
.NodeNumber
);
852 trace("infoex[%u].NumaNode.GroupMask.Mask: 0x%lx\n", i
, ex
->NumaNode
.GroupMask
.Mask
);
853 trace("infoex[%u].NumaNode.GroupMask.Group: 0x%x\n", i
, ex
->NumaNode
.GroupMask
.Group
);
856 trace("infoex[%u].Relationship: 0x%x (Cache)\n", i
, ex
->Relationship
);
857 trace("infoex[%u].Cache.Level: 0x%x\n", i
, ex
->Cache
.Level
);
858 trace("infoex[%u].Cache.Associativity: 0x%x\n", i
, ex
->Cache
.Associativity
);
859 trace("infoex[%u].Cache.LineSize: 0x%x\n", i
, ex
->Cache
.LineSize
);
860 trace("infoex[%u].Cache.CacheSize: 0x%x\n", i
, ex
->Cache
.CacheSize
);
861 trace("infoex[%u].Cache.Type: 0x%x\n", i
, ex
->Cache
.Type
);
862 trace("infoex[%u].Cache.GroupMask.Mask: 0x%lx\n", i
, ex
->Cache
.GroupMask
.Mask
);
863 trace("infoex[%u].Cache.GroupMask.Group: 0x%x\n", i
, ex
->Cache
.GroupMask
.Group
);
866 trace("infoex[%u].Relationship: 0x%x (Group)\n", i
, ex
->Relationship
);
867 trace("infoex[%u].Group.MaximumGroupCount: 0x%x\n", i
, ex
->Group
.MaximumGroupCount
);
868 trace("infoex[%u].Group.ActiveGroupCount: 0x%x\n", i
, ex
->Group
.ActiveGroupCount
);
869 for(j
= 0; j
< ex
->Group
.ActiveGroupCount
; ++j
){
870 trace("infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].MaximumProcessorCount
);
871 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorCount
);
872 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%lx\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorMask
);
882 HeapFree(GetProcessHeap(), 0, infoex
);
883 HeapFree(GetProcessHeap(), 0, infoex2
);
887 static void test_query_processor_power_info(void)
890 PROCESSOR_POWER_INFORMATION
* ppi
;
896 size
= si
.dwNumberOfProcessors
* sizeof(PROCESSOR_POWER_INFORMATION
);
897 ppi
= HeapAlloc(GetProcessHeap(), 0, size
);
899 /* If size < (sizeof(PROCESSOR_POWER_INFORMATION) * NumberOfProcessors), Win7 returns
900 * STATUS_BUFFER_TOO_SMALL. WinXP returns STATUS_SUCCESS for any value of size. It copies as
901 * many whole PROCESSOR_POWER_INFORMATION structures that there is room for. Even if there is
902 * not enough room for one structure, WinXP still returns STATUS_SUCCESS having done nothing.
904 * If ppi == NULL, Win7 returns STATUS_INVALID_PARAMETER while WinXP returns STATUS_SUCCESS
907 * The same behavior is seen with CallNtPowerInformation (in powrprof.dll).
910 if (si
.dwNumberOfProcessors
> 1)
912 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
913 ppi
[i
].Number
= 0xDEADBEEF;
915 /* Call with a buffer size that is large enough to hold at least one but not large
916 * enough to hold them all. This will be STATUS_SUCCESS on WinXP but not on Win7 */
917 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
- sizeof(PROCESSOR_POWER_INFORMATION
));
918 if (status
== STATUS_SUCCESS
)
920 /* lax version found on older Windows like WinXP */
921 ok( (ppi
[si
.dwNumberOfProcessors
- 2].Number
!= 0xDEADBEEF) &&
922 (ppi
[si
.dwNumberOfProcessors
- 1].Number
== 0xDEADBEEF),
923 "Expected all but the last record to be overwritten.\n");
925 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
926 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
928 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
929 ppi
[i
].Number
= 0xDEADBEEF;
930 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, sizeof(PROCESSOR_POWER_INFORMATION
) - 1);
931 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
932 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
933 if (ppi
[i
].Number
!= 0xDEADBEEF) break;
934 ok( i
== si
.dwNumberOfProcessors
, "Expected untouched buffer\n");
938 /* picky version found on newer Windows like Win7 */
939 ok( ppi
[1].Number
== 0xDEADBEEF, "Expected untouched buffer.\n");
940 ok( status
== STATUS_BUFFER_TOO_SMALL
, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status
);
942 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
943 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, "Got %08x\n", status
);
945 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, 0);
946 ok( status
== STATUS_BUFFER_TOO_SMALL
|| status
== STATUS_INVALID_PARAMETER
, "Got %08x\n", status
);
951 skip("Test needs more than one processor.\n");
954 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
);
955 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
957 HeapFree(GetProcessHeap(), 0, ppi
);
960 static void test_query_process_wow64(void)
964 ULONG_PTR pbi
[2], dummy
;
966 memset(&dummy
, 0xcc, sizeof(dummy
));
968 /* Do not give a handle and buffer */
969 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, 0, NULL
);
970 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
972 /* Use a correct info class and buffer size, but still no handle and buffer */
973 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
974 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
975 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE, got %08x\n", status
);
977 /* Use a correct info class, buffer size and handle, but no buffer */
978 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
979 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
981 /* Use a correct info class, buffer and buffer size, but no handle */
982 pbi
[0] = pbi
[1] = dummy
;
983 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
984 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
985 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
986 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
988 /* Use a greater buffer size */
989 pbi
[0] = pbi
[1] = dummy
;
990 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, NULL
);
991 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
992 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
993 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
995 /* Use no ReturnLength */
996 pbi
[0] = pbi
[1] = dummy
;
997 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
998 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
999 trace( "Platform is_wow64 %d, ProcessInformation of ProcessWow64Information %lx\n", is_wow64
, pbi
[0]);
1000 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64
, pbi
[0]);
1001 ok( pbi
[0] != dummy
, "pbi[0] %lx\n", pbi
[0]);
1002 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1003 /* Test written size on 64 bit by checking high 32 bit buffer */
1004 if (sizeof(ULONG_PTR
) > sizeof(DWORD
))
1006 DWORD
*ptr
= (DWORD
*)pbi
;
1007 ok( ptr
[1] != (DWORD
)dummy
, "ptr[1] unchanged!\n");
1010 /* Finally some correct calls */
1011 pbi
[0] = pbi
[1] = dummy
;
1012 ReturnLength
= 0xdeadbeef;
1013 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), &ReturnLength
);
1014 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1015 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64
, pbi
[0]);
1016 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1017 ok( ReturnLength
== sizeof(ULONG_PTR
), "Inconsistent length %d\n", ReturnLength
);
1019 /* Everything is correct except a too small buffer size */
1020 pbi
[0] = pbi
[1] = dummy
;
1021 ReturnLength
= 0xdeadbeef;
1022 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) - 1, &ReturnLength
);
1023 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1024 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
1025 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1026 todo_wine
ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength
);
1028 /* Everything is correct except a too large buffer size */
1029 pbi
[0] = pbi
[1] = dummy
;
1030 ReturnLength
= 0xdeadbeef;
1031 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, &ReturnLength
);
1032 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1033 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
1034 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
1035 todo_wine
ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength
);
1038 static void test_query_process_basic(void)
1043 typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE
{
1044 DWORD_PTR ExitStatus
;
1045 PPEB PebBaseAddress
;
1046 DWORD_PTR AffinityMask
;
1047 DWORD_PTR BasePriority
;
1048 ULONG_PTR UniqueProcessId
;
1049 ULONG_PTR InheritedFromUniqueProcessId
;
1050 } PROCESS_BASIC_INFORMATION_PRIVATE
;
1052 PROCESS_BASIC_INFORMATION_PRIVATE pbi
;
1054 /* This test also covers some basic parameter testing that should be the same for
1055 * every information class
1058 /* Use a nonexistent info class */
1059 trace("Check nonexistent info class\n");
1060 status
= pNtQueryInformationProcess(NULL
, -1, NULL
, 0, NULL
);
1061 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
1062 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
1064 /* Do not give a handle and buffer */
1065 trace("Check NULL handle and buffer and zero-length buffersize\n");
1066 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, 0, NULL
);
1067 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1069 /* Use a correct info class and buffer size, but still no handle and buffer */
1070 trace("Check NULL handle and buffer\n");
1071 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, sizeof(pbi
), NULL
);
1072 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1073 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1075 /* Use a correct info class and buffer size, but still no handle */
1076 trace("Check NULL handle\n");
1077 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1078 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1080 /* Use a greater buffer size */
1081 trace("Check NULL handle and too large buffersize\n");
1082 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, NULL
);
1083 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1085 /* Use no ReturnLength */
1086 trace("Check NULL ReturnLength\n");
1087 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1088 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1090 /* Finally some correct calls */
1091 trace("Check with correct parameters\n");
1092 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), &ReturnLength
);
1093 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1094 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1096 /* Everything is correct except a too large buffersize */
1097 trace("Too large buffersize\n");
1098 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, &ReturnLength
);
1099 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1100 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1102 /* Check if we have some return values */
1103 trace("ProcessID : %lx\n", pbi
.UniqueProcessId
);
1104 ok( pbi
.UniqueProcessId
> 0, "Expected a ProcessID > 0, got 0\n");
1107 static void dump_vm_counters(const char *header
, const VM_COUNTERS
*pvi
)
1109 trace("%s:\n", header
);
1110 trace("PeakVirtualSize : %lu\n", pvi
->PeakVirtualSize
);
1111 trace("VirtualSize : %lu\n", pvi
->VirtualSize
);
1112 trace("PageFaultCount : %u\n", pvi
->PageFaultCount
);
1113 trace("PeakWorkingSetSize : %lu\n", pvi
->PeakWorkingSetSize
);
1114 trace("WorkingSetSize : %lu\n", pvi
->WorkingSetSize
);
1115 trace("QuotaPeakPagedPoolUsage : %lu\n", pvi
->QuotaPeakPagedPoolUsage
);
1116 trace("QuotaPagedPoolUsage : %lu\n", pvi
->QuotaPagedPoolUsage
);
1117 trace("QuotaPeakNonPagePoolUsage : %lu\n", pvi
->QuotaPeakNonPagedPoolUsage
);
1118 trace("QuotaNonPagePoolUsage : %lu\n", pvi
->QuotaNonPagedPoolUsage
);
1119 trace("PagefileUsage : %lu\n", pvi
->PagefileUsage
);
1120 trace("PeakPagefileUsage : %lu\n", pvi
->PeakPagefileUsage
);
1123 static void test_query_process_vm(void)
1128 ULONG old_size
= FIELD_OFFSET(VM_COUNTERS
,PrivatePageCount
);
1131 const SIZE_T alloc_size
= 16 * 1024 * 1024;
1134 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, NULL
, sizeof(pvi
), NULL
);
1135 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1136 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1138 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, &pvi
, old_size
, NULL
);
1139 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1141 /* Windows XP and W2K3 will report success for a size of 44 AND 48 !
1142 Windows W2K will only report success for 44.
1143 For now we only care for 44, which is FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
1146 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 24, &ReturnLength
);
1147 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1149 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, old_size
, &ReturnLength
);
1150 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1151 ok( old_size
== ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1153 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 46, &ReturnLength
);
1154 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1155 ok( ReturnLength
== old_size
|| ReturnLength
== sizeof(pvi
), "Inconsistent length %d\n", ReturnLength
);
1157 /* Check if we have some return values */
1158 dump_vm_counters("VM counters for GetCurrentProcess", &pvi
);
1159 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1160 ok( pvi
.PagefileUsage
> 0, "Expected a PagefileUsage > 0\n");
1162 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1163 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1164 ok( status
== STATUS_ACCESS_DENIED
, "Expected STATUS_ACCESS_DENIED, got %08x\n", status
);
1165 CloseHandle(process
);
1167 process
= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION
, FALSE
, GetCurrentProcessId());
1168 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1169 ok( status
== STATUS_SUCCESS
|| broken(!process
) /* XP */, "Expected STATUS_SUCCESS, got %08x\n", status
);
1170 CloseHandle(process
);
1172 memset(&pvi
, 0, sizeof(pvi
));
1173 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, GetCurrentProcessId());
1174 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1175 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1177 /* Check if we have some return values */
1178 dump_vm_counters("VM counters for GetCurrentProcessId", &pvi
);
1179 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1180 ok( pvi
.PagefileUsage
> 0, "Expected a PagefileUsage > 0\n");
1182 CloseHandle(process
);
1184 /* Check if we have real counters */
1185 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1186 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1187 prev_size
= pvi
.VirtualSize
;
1188 if (winetest_debug
> 1)
1189 dump_vm_counters("VM counters before VirtualAlloc", &pvi
);
1190 ptr
= VirtualAlloc(NULL
, alloc_size
, MEM_COMMIT
| MEM_RESERVE
, PAGE_READWRITE
);
1191 ok( ptr
!= NULL
, "VirtualAlloc failed, err %u\n", GetLastError());
1192 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1193 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1194 if (winetest_debug
> 1)
1195 dump_vm_counters("VM counters after VirtualAlloc", &pvi
);
1196 todo_wine
ok( pvi
.VirtualSize
>= prev_size
+ alloc_size
,
1197 "Expected to be greater than %lu, got %lu\n", prev_size
+ alloc_size
, pvi
.VirtualSize
);
1198 VirtualFree( ptr
, 0, MEM_RELEASE
);
1200 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1201 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1202 prev_size
= pvi
.VirtualSize
;
1203 if (winetest_debug
> 1)
1204 dump_vm_counters("VM counters before VirtualAlloc", &pvi
);
1205 ptr
= VirtualAlloc(NULL
, alloc_size
, MEM_RESERVE
, PAGE_READWRITE
);
1206 ok( ptr
!= NULL
, "VirtualAlloc failed, err %u\n", GetLastError());
1207 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1208 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1209 if (winetest_debug
> 1)
1210 dump_vm_counters("VM counters after VirtualAlloc(MEM_RESERVE)", &pvi
);
1211 todo_wine
ok( pvi
.VirtualSize
>= prev_size
+ alloc_size
,
1212 "Expected to be greater than %lu, got %lu\n", prev_size
+ alloc_size
, pvi
.VirtualSize
);
1213 prev_size
= pvi
.VirtualSize
;
1215 ptr
= VirtualAlloc(ptr
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
1216 ok( ptr
!= NULL
, "VirtualAlloc failed, err %u\n", GetLastError());
1217 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1218 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1219 if (winetest_debug
> 1)
1220 dump_vm_counters("VM counters after VirtualAlloc(MEM_COMMIT)", &pvi
);
1221 ok( pvi
.VirtualSize
== prev_size
,
1222 "Expected to equal to %lu, got %lu\n", prev_size
, pvi
.VirtualSize
);
1223 VirtualFree( ptr
, 0, MEM_RELEASE
);
1226 static void test_query_process_io(void)
1232 /* NT4 doesn't support this information class, so check for it */
1233 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
1234 if (status
== STATUS_NOT_SUPPORTED
)
1236 win_skip("ProcessIoCounters information class is not supported\n");
1240 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, NULL
, sizeof(pii
), NULL
);
1241 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1242 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1244 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, &pii
, sizeof(pii
), NULL
);
1245 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1247 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, 24, &ReturnLength
);
1248 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1250 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
1251 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1252 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1254 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
) * 2, &ReturnLength
);
1255 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1256 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1258 /* Check if we have some return values */
1259 trace("OtherOperationCount : 0x%s\n", wine_dbgstr_longlong(pii
.OtherOperationCount
));
1262 ok( pii
.OtherOperationCount
> 0, "Expected an OtherOperationCount > 0\n");
1266 static void test_query_process_times(void)
1271 SYSTEMTIME UTC
, Local
;
1272 KERNEL_USER_TIMES spti
;
1274 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, NULL
, sizeof(spti
), NULL
);
1275 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1276 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1278 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, &spti
, sizeof(spti
), NULL
);
1279 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1281 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, 24, &ReturnLength
);
1282 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1284 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
1287 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
1288 process
= GetCurrentProcess();
1289 trace("ProcessTimes for current process\n");
1292 trace("ProcessTimes for process with ID : %d\n", one_before_last_pid
);
1294 status
= pNtQueryInformationProcess( process
, ProcessTimes
, &spti
, sizeof(spti
), &ReturnLength
);
1295 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1296 ok( sizeof(spti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1297 CloseHandle(process
);
1299 FileTimeToSystemTime((const FILETIME
*)&spti
.CreateTime
, &UTC
);
1300 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
1301 trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
1302 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
1304 FileTimeToSystemTime((const FILETIME
*)&spti
.ExitTime
, &UTC
);
1305 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
1306 trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
1307 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
1309 FileTimeToSystemTime((const FILETIME
*)&spti
.KernelTime
, &Local
);
1310 trace("KernelTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
1312 FileTimeToSystemTime((const FILETIME
*)&spti
.UserTime
, &Local
);
1313 trace("UserTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
1315 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, sizeof(spti
) * 2, &ReturnLength
);
1316 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1317 ok( sizeof(spti
) == ReturnLength
||
1318 ReturnLength
== 0 /* vista */ ||
1319 broken(is_wow64
), /* returns garbage on wow64 */
1320 "Inconsistent length %d\n", ReturnLength
);
1323 static void test_query_process_debug_port(int argc
, char **argv
)
1325 DWORD_PTR debug_port
= 0xdeadbeef;
1326 char cmdline
[MAX_PATH
];
1327 PROCESS_INFORMATION pi
;
1328 STARTUPINFOA si
= { 0 };
1332 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1335 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
, NULL
, &si
, &pi
);
1336 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
1339 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1341 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1343 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1344 NULL
, sizeof(debug_port
), NULL
);
1345 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
,
1346 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1348 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1349 NULL
, sizeof(debug_port
), NULL
);
1350 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1352 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1353 &debug_port
, sizeof(debug_port
), NULL
);
1354 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1356 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1357 &debug_port
, sizeof(debug_port
) - 1, NULL
);
1358 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1360 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1361 &debug_port
, sizeof(debug_port
) + 1, NULL
);
1362 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1364 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1365 &debug_port
, sizeof(debug_port
), NULL
);
1366 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1367 ok(debug_port
== 0, "Expected port 0, got %#lx.\n", debug_port
);
1369 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugPort
,
1370 &debug_port
, sizeof(debug_port
), NULL
);
1371 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1372 ok(debug_port
== ~(DWORD_PTR
)0, "Expected port %#lx, got %#lx.\n", ~(DWORD_PTR
)0, debug_port
);
1378 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1379 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1382 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1384 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1385 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1389 ret
= CloseHandle(pi
.hThread
);
1390 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1391 ret
= CloseHandle(pi
.hProcess
);
1392 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1395 static void test_query_process_priority(void)
1397 PROCESS_PRIORITY_CLASS priority
[2];
1399 DWORD orig_priority
;
1403 status
= pNtQueryInformationProcess(NULL
, ProcessPriorityClass
, NULL
, sizeof(priority
[0]), NULL
);
1404 ok(status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_HANDLE
) /* w2k3 */,
1405 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
1407 status
= pNtQueryInformationProcess(NULL
, ProcessPriorityClass
, &priority
, sizeof(priority
[0]), NULL
);
1408 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1410 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, 1, &ReturnLength
);
1411 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1413 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, sizeof(priority
), &ReturnLength
);
1414 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1416 orig_priority
= GetPriorityClass(GetCurrentProcess());
1417 ret
= SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS
);
1418 ok(ret
, "Failed to set priority class: %u\n", GetLastError());
1420 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, sizeof(priority
[0]), &ReturnLength
);
1421 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1422 ok(priority
[0].PriorityClass
== PROCESS_PRIOCLASS_BELOW_NORMAL
,
1423 "Expected PROCESS_PRIOCLASS_BELOW_NORMAL, got %u\n", priority
[0].PriorityClass
);
1425 ret
= SetPriorityClass(GetCurrentProcess(), orig_priority
);
1426 ok(ret
, "Failed to reset priority class: %u\n", GetLastError());
1429 static void test_query_process_handlecount(void)
1434 BYTE buffer
[2 * sizeof(DWORD
)];
1437 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, NULL
, sizeof(handlecount
), NULL
);
1438 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1439 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1441 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), NULL
);
1442 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1444 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, &handlecount
, 2, &ReturnLength
);
1445 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1447 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
1450 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
1451 process
= GetCurrentProcess();
1452 trace("ProcessHandleCount for current process\n");
1455 trace("ProcessHandleCount for process with ID : %d\n", one_before_last_pid
);
1457 status
= pNtQueryInformationProcess( process
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), &ReturnLength
);
1458 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1459 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1460 CloseHandle(process
);
1462 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, buffer
, sizeof(buffer
), &ReturnLength
);
1463 ok( status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_SUCCESS
,
1464 "Expected STATUS_INFO_LENGTH_MISMATCH or STATUS_SUCCESS, got %08x\n", status
);
1465 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1467 /* Check if we have some return values */
1468 trace("HandleCount : %d\n", handlecount
);
1471 ok( handlecount
> 0, "Expected some handles, got 0\n");
1475 static void test_query_process_image_file_name(void)
1479 UNICODE_STRING image_file_name
;
1484 status
= pNtQueryInformationProcess(NULL
, ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), NULL
);
1485 if (status
== STATUS_INVALID_INFO_CLASS
)
1487 win_skip("ProcessImageFileName is not supported\n");
1490 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1492 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, 2, &ReturnLength
);
1493 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1495 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), &ReturnLength
);
1496 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1498 buffer
= HeapAlloc(GetProcessHeap(), 0, ReturnLength
);
1499 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, buffer
, ReturnLength
, &ReturnLength
);
1500 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1501 memcpy(&image_file_name
, buffer
, sizeof(image_file_name
));
1502 len
= WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), NULL
, 0, NULL
, NULL
);
1503 file_nameA
= HeapAlloc(GetProcessHeap(), 0, len
+ 1);
1504 WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), file_nameA
, len
, NULL
, NULL
);
1505 file_nameA
[len
] = '\0';
1506 HeapFree(GetProcessHeap(), 0, buffer
);
1507 trace("process image file name: %s\n", file_nameA
);
1508 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
);
1509 HeapFree(GetProcessHeap(), 0, file_nameA
);
1512 static void test_query_process_debug_object_handle(int argc
, char **argv
)
1514 char cmdline
[MAX_PATH
];
1515 STARTUPINFOA si
= {0};
1516 PROCESS_INFORMATION pi
;
1518 HANDLE debug_object
;
1521 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1524 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
,
1526 ok(ret
, "CreateProcess failed with last error %u\n", GetLastError());
1529 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
1531 if (status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
)
1533 win_skip("ProcessDebugObjectHandle is not supported\n");
1536 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1537 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n",
1540 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
1541 sizeof(debug_object
), NULL
);
1542 ok(status
== STATUS_INVALID_HANDLE
||
1543 status
== STATUS_ACCESS_VIOLATION
, /* XP */
1544 "Expected NtQueryInformationProcess to return STATUS_INVALID_HANDLE, got 0x%08x\n", status
);
1546 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1547 ProcessDebugObjectHandle
, NULL
, sizeof(debug_object
), NULL
);
1548 ok(status
== STATUS_ACCESS_VIOLATION
,
1549 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
1551 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
,
1552 &debug_object
, sizeof(debug_object
), NULL
);
1553 ok(status
== STATUS_INVALID_HANDLE
,
1554 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
1556 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1557 ProcessDebugObjectHandle
, &debug_object
,
1558 sizeof(debug_object
) - 1, NULL
);
1559 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1560 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
1562 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1563 ProcessDebugObjectHandle
, &debug_object
,
1564 sizeof(debug_object
) + 1, NULL
);
1565 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1566 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
1568 debug_object
= (HANDLE
)0xdeadbeef;
1569 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1570 ProcessDebugObjectHandle
, &debug_object
,
1571 sizeof(debug_object
), NULL
);
1572 ok(status
== STATUS_PORT_NOT_SET
,
1573 "Expected NtQueryInformationProcess to return STATUS_PORT_NOT_SET, got 0x%08x\n", status
);
1574 ok(debug_object
== NULL
||
1575 broken(debug_object
== (HANDLE
)0xdeadbeef), /* Wow64 */
1576 "Expected debug object handle to be NULL, got %p\n", debug_object
);
1578 debug_object
= (HANDLE
)0xdeadbeef;
1579 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugObjectHandle
,
1580 &debug_object
, sizeof(debug_object
), NULL
);
1582 ok(status
== STATUS_SUCCESS
,
1583 "Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08x\n", status
);
1585 ok(debug_object
!= NULL
,
1586 "Expected debug object handle to be non-NULL, got %p\n", debug_object
);
1592 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1593 ok(ret
, "WaitForDebugEvent failed with last error %u\n", GetLastError());
1596 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1598 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1599 ok(ret
, "ContinueDebugEvent failed with last error %u\n", GetLastError());
1603 ret
= CloseHandle(pi
.hThread
);
1604 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1605 ret
= CloseHandle(pi
.hProcess
);
1606 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1609 static void test_query_process_debug_flags(int argc
, char **argv
)
1611 static const DWORD test_flags
[] = { DEBUG_PROCESS
,
1612 DEBUG_ONLY_THIS_PROCESS
,
1613 DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
,
1615 DWORD debug_flags
= 0xdeadbeef;
1616 char cmdline
[MAX_PATH
];
1617 PROCESS_INFORMATION pi
;
1618 STARTUPINFOA si
= { 0 };
1625 /* test invalid arguments */
1626 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, 0, NULL
);
1627 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1628 "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1630 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, sizeof(debug_flags
), NULL
);
1631 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1632 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1634 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1635 NULL
, sizeof(debug_flags
), NULL
);
1636 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1638 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
,
1639 &debug_flags
, sizeof(debug_flags
), NULL
);
1640 ok(status
== STATUS_INVALID_HANDLE
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1641 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1643 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1644 &debug_flags
, sizeof(debug_flags
) - 1, NULL
);
1645 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1647 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1648 &debug_flags
, sizeof(debug_flags
) + 1, NULL
);
1649 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1651 /* test ProcessDebugFlags of current process */
1652 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1653 &debug_flags
, sizeof(debug_flags
), NULL
);
1654 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1655 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %x.\n", debug_flags
);
1657 for (i
= 0; i
< sizeof(test_flags
)/sizeof(test_flags
[0]); i
++)
1659 DWORD expected_flags
= !(test_flags
[i
] & DEBUG_ONLY_THIS_PROCESS
);
1660 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1663 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, test_flags
[i
], NULL
, NULL
, &si
, &pi
);
1664 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
1666 if (!(test_flags
[i
] & (DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
)))
1668 /* test ProcessDebugFlags before attaching with debugger */
1669 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1670 &debug_flags
, sizeof(debug_flags
), NULL
);
1671 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1672 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %x.\n", debug_flags
);
1674 ret
= DebugActiveProcess(pi
.dwProcessId
);
1675 ok(ret
, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1676 expected_flags
= FALSE
;
1679 /* test ProcessDebugFlags after attaching with debugger */
1680 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1681 &debug_flags
, sizeof(debug_flags
), NULL
);
1682 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1683 ok(debug_flags
== expected_flags
, "Expected flag %x, got %x.\n", expected_flags
, debug_flags
);
1685 if (!(test_flags
[i
] & CREATE_SUSPENDED
))
1687 /* Continue a couple of times to make sure the process is fully initialized,
1688 * otherwise Windows XP deadlocks in the following DebugActiveProcess(). */
1691 ret
= WaitForDebugEvent(&ev
, 1000);
1692 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1695 if (ev
.dwDebugEventCode
== LOAD_DLL_DEBUG_EVENT
) break;
1697 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1698 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1702 result
= SuspendThread(pi
.hThread
);
1703 ok(result
== 0, "Expected 0, got %u.\n", result
);
1706 ret
= DebugActiveProcessStop(pi
.dwProcessId
);
1707 ok(ret
, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError());
1709 /* test ProcessDebugFlags after detaching debugger */
1710 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1711 &debug_flags
, sizeof(debug_flags
), NULL
);
1712 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1713 ok(debug_flags
== expected_flags
, "Expected flag %x, got %x.\n", expected_flags
, debug_flags
);
1715 ret
= DebugActiveProcess(pi
.dwProcessId
);
1716 ok(ret
, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1718 /* test ProcessDebugFlags after re-attaching debugger */
1719 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1720 &debug_flags
, sizeof(debug_flags
), NULL
);
1721 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1722 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %x.\n", debug_flags
);
1724 result
= ResumeThread(pi
.hThread
);
1725 todo_wine
ok(result
== 2, "Expected 2, got %u.\n", result
);
1727 /* Wait until the process is terminated. On Windows XP the process randomly
1728 * gets stuck in a non-continuable exception, so stop after 100 iterations.
1729 * On Windows 2003, the debugged process disappears (or stops?) without
1730 * any EXIT_PROCESS_DEBUG_EVENT after a couple of events. */
1731 for (j
= 0; j
< 100; j
++)
1733 ret
= WaitForDebugEvent(&ev
, 1000);
1734 ok(ret
|| broken(GetLastError() == ERROR_SEM_TIMEOUT
),
1735 "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1738 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1740 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1741 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1744 ok(j
< 100 || broken(j
>= 100) /* Win XP */, "Expected less than 100 debug events.\n");
1746 /* test ProcessDebugFlags after process has terminated */
1747 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1748 &debug_flags
, sizeof(debug_flags
), NULL
);
1749 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1750 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %x.\n", debug_flags
);
1752 ret
= CloseHandle(pi
.hThread
);
1753 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1754 ret
= CloseHandle(pi
.hProcess
);
1755 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1759 static void test_readvirtualmemory(void)
1764 static const char teststring
[] = "test string";
1767 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1768 ok(process
!= 0, "Expected to be able to open own process for reading memory\n");
1770 /* normal operation */
1771 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, &readcount
);
1772 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1773 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1774 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1776 /* no number of bytes */
1777 memset(buffer
, 0, 12);
1778 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, NULL
);
1779 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1780 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1782 /* illegal remote address */
1784 status
= pNtReadVirtualMemory(process
, (void *) 0x1234, buffer
, 12, &readcount
);
1785 ok( status
== STATUS_PARTIAL_COPY
|| broken(status
== STATUS_ACCESS_VIOLATION
), "Expected STATUS_PARTIAL_COPY, got %08x\n", status
);
1786 if (status
== STATUS_PARTIAL_COPY
)
1787 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1791 status
= pNtReadVirtualMemory(0, teststring
, buffer
, 12, &readcount
);
1792 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1793 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1795 /* pseudo handle for current process*/
1796 memset(buffer
, 0, 12);
1797 status
= pNtReadVirtualMemory((HANDLE
)-1, teststring
, buffer
, 12, &readcount
);
1798 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1799 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1800 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1802 /* illegal local address */
1803 status
= pNtReadVirtualMemory(process
, teststring
, (void *)0x1234, 12, &readcount
);
1804 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
1805 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1807 CloseHandle(process
);
1810 static void test_mapprotection(void)
1814 MEMORY_BASIC_INFORMATION info
;
1815 ULONG oldflags
, flagsize
, flags
= MEM_EXECUTE_OPTION_ENABLE
;
1816 LARGE_INTEGER size
, offset
;
1818 SIZE_T retlen
, count
;
1822 skip("No NtClose ... Win98\n");
1825 /* Switch to being a noexec unaware process */
1826 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof (oldflags
), &flagsize
);
1827 if (status
== STATUS_INVALID_PARAMETER
) {
1828 skip("Invalid Parameter on ProcessExecuteFlags query?\n");
1831 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1832 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &flags
, sizeof(flags
) );
1833 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1835 size
.u
.LowPart
= 0x2000;
1836 size
.u
.HighPart
= 0;
1837 status
= pNtCreateSection ( &h
,
1838 STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
,
1842 SEC_COMMIT
| SEC_NOCACHE
,
1845 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1847 offset
.u
.LowPart
= 0;
1848 offset
.u
.HighPart
= 0;
1851 status
= pNtMapViewOfSection ( h
, GetCurrentProcess(), &addr
, 0, 0, &offset
, &count
, ViewShare
, 0, PAGE_READWRITE
);
1852 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1854 #if defined(__x86_64__) || defined(__i386__)
1855 *(unsigned char*)addr
= 0xc3; /* lret ... in both i386 and x86_64 */
1856 #elif defined(__arm__)
1857 *(unsigned long*)addr
= 0xe12fff1e; /* bx lr */
1858 #elif defined(__aarch64__)
1859 *(unsigned long*)addr
= 0xd65f03c0; /* ret */
1861 ok(0, "Add a return opcode for your architecture or expect a crash in this test\n");
1863 trace("trying to execute code in the readwrite only mapped anon file...\n");
1865 trace("...done.\n");
1867 status
= pNtQueryVirtualMemory( GetCurrentProcess(), addr
, MemoryBasicInformation
, &info
, sizeof(info
), &retlen
);
1868 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1869 ok( retlen
== sizeof(info
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1870 ok((info
.Protect
& ~PAGE_NOCACHE
) == PAGE_READWRITE
, "addr.Protect is not PAGE_READWRITE, but 0x%x\n", info
.Protect
);
1872 status
= pNtUnmapViewOfSection( GetCurrentProcess(), (char *)addr
+ 0x1050 );
1873 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1877 pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof(oldflags
) );
1880 static void test_queryvirtualmemory(void)
1884 static const WCHAR windowsW
[] = {'w','i','n','d','o','w','s'};
1885 static const char teststring
[] = "test string";
1886 static char datatestbuf
[42] = "abc";
1887 static char rwtestbuf
[42];
1888 MEMORY_BASIC_INFORMATION mbi
;
1891 char buffer_name
[sizeof(MEMORY_SECTION_NAME
) + MAX_PATH
* sizeof(WCHAR
)];
1892 MEMORY_SECTION_NAME
*msn
= (MEMORY_SECTION_NAME
*)buffer_name
;
1896 module
= GetModuleHandleA( "ntdll.dll" );
1897 trace("Check flags of the PE header of NTDLL.DLL at %p\n", module
);
1898 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1899 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1900 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1901 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1902 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1903 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1904 ok (mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READONLY
);
1905 ok (mbi
.Type
== MEM_IMAGE
, "mbi.Type is 0x%x, expected 0x%x\n", mbi
.Type
, MEM_IMAGE
);
1907 trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory
);
1908 module
= GetModuleHandleA( "ntdll.dll" );
1909 status
= pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1910 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1911 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1912 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1913 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1914 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1915 ok (mbi
.Protect
== PAGE_EXECUTE_READ
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_EXECUTE_READ
);
1917 trace("Check flags of heap at %p\n", GetProcessHeap());
1918 status
= pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1919 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1920 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1921 ok (mbi
.AllocationProtect
== PAGE_READWRITE
|| mbi
.AllocationProtect
== PAGE_EXECUTE_READWRITE
,
1922 "mbi.AllocationProtect is 0x%x\n", mbi
.AllocationProtect
);
1923 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1924 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_EXECUTE_READWRITE
,
1925 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1927 trace("Check flags of stack at %p\n", stackbuf
);
1928 status
= pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1929 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1930 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1931 ok (mbi
.AllocationProtect
== PAGE_READWRITE
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_READWRITE
);
1932 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1933 ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READWRITE
);
1935 trace("Check flags of read-only data at %p\n", teststring
);
1936 module
= GetModuleHandleA( NULL
);
1937 status
= pNtQueryVirtualMemory(NtCurrentProcess(), teststring
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1938 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1939 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1940 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1941 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1942 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1943 if (mbi
.Protect
!= PAGE_READONLY
)
1944 todo_wine
ok( mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%X\n", mbi
.Protect
, PAGE_READONLY
);
1946 trace("Check flags of read-write data at %p\n", datatestbuf
);
1947 status
= pNtQueryVirtualMemory(NtCurrentProcess(), datatestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1948 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1949 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1950 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1951 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1952 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1953 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
1954 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1956 trace("Check flags of read-write uninitialized data (.bss) at %p\n", rwtestbuf
);
1957 status
= pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1958 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1959 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1960 if (mbi
.AllocationBase
== module
)
1962 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1963 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1964 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
1965 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1967 else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
1969 trace("Check section name of NTDLL.DLL with invalid size\n");
1970 module
= GetModuleHandleA( "ntdll.dll" );
1971 memset(msn
, 0, sizeof(*msn
));
1973 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemorySectionName
, msn
, sizeof(*msn
), &readcount
);
1974 ok( status
== STATUS_BUFFER_OVERFLOW
, "Expected STATUS_BUFFER_OVERFLOW, got %08x\n", status
);
1975 ok( readcount
> 0, "Expected readcount to be > 0\n");
1977 trace("Check section name of NTDLL.DLL with invalid size\n");
1978 module
= GetModuleHandleA( "ntdll.dll" );
1979 memset(msn
, 0, sizeof(*msn
));
1981 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemorySectionName
, msn
, sizeof(*msn
) - 1, &readcount
);
1982 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1983 ok( readcount
> 0, "Expected readcount to be > 0\n");
1985 trace("Check section name of NTDLL.DLL\n");
1986 module
= GetModuleHandleA( "ntdll.dll" );
1987 memset(msn
, 0x55, sizeof(*msn
));
1988 memset(buffer_name
, 0x77, sizeof(buffer_name
));
1990 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemorySectionName
, msn
, sizeof(buffer_name
), &readcount
);
1991 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1992 ok( readcount
> 0, "Expected readcount to be > 0\n");
1993 trace ("Section Name: %s\n", wine_dbgstr_w(msn
->SectionFileName
.Buffer
));
1994 pRtlDowncaseUnicodeString( &msn
->SectionFileName
, &msn
->SectionFileName
, FALSE
);
1995 for (found
= FALSE
, i
= (msn
->SectionFileName
.Length
- sizeof(windowsW
)) / sizeof(WCHAR
); i
>= 0; i
--)
1996 found
|= !memcmp( &msn
->SectionFileName
.Buffer
[i
], windowsW
, sizeof(windowsW
) );
1997 ok( found
, "Section name does not contain \"Windows\"\n");
1999 trace("Check section name of non mapped memory\n");
2000 memset(msn
, 0, sizeof(*msn
));
2002 status
= pNtQueryVirtualMemory(NtCurrentProcess(), &buffer_name
, MemorySectionName
, msn
, sizeof(buffer_name
), &readcount
);
2003 ok( status
== STATUS_INVALID_ADDRESS
, "Expected STATUS_INVALID_ADDRESS, got %08x\n", status
);
2004 ok( readcount
== 0 || broken(readcount
!= 0) /* wow64 */, "Expected readcount to be 0\n");
2007 static void test_affinity(void)
2010 PROCESS_BASIC_INFORMATION pbi
;
2011 DWORD_PTR proc_affinity
, thread_affinity
;
2012 THREAD_BASIC_INFORMATION tbi
;
2016 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
2017 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2018 proc_affinity
= pbi
.AffinityMask
;
2019 ok( proc_affinity
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected process affinity\n" );
2020 proc_affinity
= 1 << si
.dwNumberOfProcessors
;
2021 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2022 ok( status
== STATUS_INVALID_PARAMETER
,
2023 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2026 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2027 ok( status
== STATUS_INVALID_PARAMETER
,
2028 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2030 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2031 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2032 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected thread affinity\n" );
2033 thread_affinity
= 1 << si
.dwNumberOfProcessors
;
2034 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2035 ok( status
== STATUS_INVALID_PARAMETER
,
2036 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2037 thread_affinity
= 0;
2038 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2039 ok( status
== STATUS_INVALID_PARAMETER
,
2040 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2042 thread_affinity
= 1;
2043 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2044 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2045 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2046 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2047 ok( tbi
.AffinityMask
== 1, "Unexpected thread affinity\n" );
2049 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
2050 thread_affinity
= ~(DWORD_PTR
)0;
2051 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2052 ok( broken(status
== STATUS_INVALID_PARAMETER
) || status
== STATUS_SUCCESS
,
2053 "Expected STATUS_SUCCESS, got %08x\n", status
);
2055 if (si
.dwNumberOfProcessors
<= 1)
2057 skip("only one processor, skipping affinity testing\n");
2061 /* Test thread affinity mask resulting from "all processors" flag */
2062 if (status
== STATUS_SUCCESS
)
2064 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2065 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2066 ok( broken(tbi
.AffinityMask
== 1) || tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
2067 "Unexpected thread affinity\n" );
2070 skip("Cannot test thread affinity mask for 'all processors' flag\n");
2073 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2074 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2075 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
2076 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2077 proc_affinity
= pbi
.AffinityMask
;
2078 ok( proc_affinity
== 2, "Unexpected process affinity\n" );
2079 /* Setting the process affinity changes the thread affinity to match */
2080 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2081 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2082 ok( tbi
.AffinityMask
== 2, "Unexpected thread affinity\n" );
2083 /* The thread affinity is restricted to the process affinity */
2084 thread_affinity
= 1;
2085 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
2086 ok( status
== STATUS_INVALID_PARAMETER
,
2087 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
2089 proc_affinity
= (1 << si
.dwNumberOfProcessors
) - 1;
2090 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
2091 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2092 /* Resetting the process affinity also resets the thread affinity */
2093 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2094 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2095 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
2096 "Unexpected thread affinity\n" );
2099 static void test_NtGetCurrentProcessorNumber(void)
2103 PROCESS_BASIC_INFORMATION pbi
;
2104 THREAD_BASIC_INFORMATION tbi
;
2105 DWORD_PTR old_process_mask
;
2106 DWORD_PTR old_thread_mask
;
2111 if (!pNtGetCurrentProcessorNumber
) {
2112 win_skip("NtGetCurrentProcessorNumber not available\n");
2117 current_cpu
= pNtGetCurrentProcessorNumber();
2118 trace("dwNumberOfProcessors: %d, current processor: %d\n", si
.dwNumberOfProcessors
, current_cpu
);
2120 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
2121 old_process_mask
= pbi
.AffinityMask
;
2122 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2124 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2125 old_thread_mask
= tbi
.AffinityMask
;
2126 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2128 /* allow the test to run on all processors */
2129 new_mask
= (1 << si
.dwNumberOfProcessors
) - 1;
2130 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &new_mask
, sizeof(new_mask
));
2131 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2133 for (i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
2136 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &new_mask
, sizeof(new_mask
));
2137 ok(status
== STATUS_SUCCESS
, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i
, status
);
2139 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
2140 ok(status
== STATUS_SUCCESS
, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i
, status
);
2142 current_cpu
= pNtGetCurrentProcessorNumber();
2143 ok((current_cpu
== i
), "%d (new_mask 0x%lx): running on processor %d (AffinityMask: 0x%lx)\n",
2144 i
, new_mask
, current_cpu
, tbi
.AffinityMask
);
2147 /* restore old values */
2148 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &old_process_mask
, sizeof(old_process_mask
));
2149 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2151 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &old_thread_mask
, sizeof(old_thread_mask
));
2152 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
2155 static DWORD WINAPI
start_address_thread(void *arg
)
2157 PRTL_THREAD_START_ROUTINE entry
;
2163 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2164 &entry
, sizeof(entry
), &ret
);
2165 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2166 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2167 ok(entry
== (void *)start_address_thread
, "expected %p, got %p\n", start_address_thread
, entry
);
2171 static void test_thread_start_address(void)
2173 PRTL_THREAD_START_ROUTINE entry
, expected_entry
;
2174 IMAGE_NT_HEADERS
*nt
;
2180 module
= GetModuleHandleA(0);
2181 ok(module
!= NULL
, "expected non-NULL address for module\n");
2182 nt
= RtlImageNtHeader(module
);
2183 ok(nt
!= NULL
, "expected non-NULL address for NT header\n");
2187 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2188 &entry
, sizeof(entry
), &ret
);
2189 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2190 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2191 expected_entry
= (void *)((char *)module
+ nt
->OptionalHeader
.AddressOfEntryPoint
);
2192 ok(entry
== expected_entry
, "expected %p, got %p\n", expected_entry
, entry
);
2194 entry
= (void *)0xdeadbeef;
2195 status
= pNtSetInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2196 &entry
, sizeof(entry
));
2197 ok(status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, /* >= Vista */
2198 "expected STATUS_SUCCESS or STATUS_INVALID_PARAMETER, got %08x\n", status
);
2200 if (status
== STATUS_SUCCESS
)
2204 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2205 &entry
, sizeof(entry
), &ret
);
2206 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2207 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2208 ok(entry
== (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", entry
);
2211 thread
= CreateThread(NULL
, 0, start_address_thread
, NULL
, 0, NULL
);
2212 ok(thread
!= INVALID_HANDLE_VALUE
, "CreateThread failed with %d\n", GetLastError());
2213 ret
= WaitForSingleObject(thread
, 1000);
2214 ok(ret
== WAIT_OBJECT_0
, "expected WAIT_OBJECT_0, got %u\n", ret
);
2215 CloseHandle(thread
);
2218 static void test_query_data_alignment(void)
2225 status
= pNtQuerySystemInformation(SystemRecommendedSharedDataAlignment
, &value
, sizeof(value
), &ReturnLength
);
2226 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2227 ok(sizeof(value
) == ReturnLength
, "Inconsistent length %u\n", ReturnLength
);
2228 ok(value
== 64, "Expected 64, got %u\n", value
);
2231 static void test_working_set_limit(void)
2233 DWORD_PTR lower
= 0, upper
= ~(DWORD_PTR
)0;
2234 MEMORY_BASIC_INFORMATION mbi
;
2238 while (lower
!= upper
)
2240 DWORD_PTR check
= (lower
>> 1) + (upper
>> 1) + (lower
& upper
& 1);
2241 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (void *)check
, MemoryBasicInformation
,
2242 &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
2243 if (status
== STATUS_INVALID_PARAMETER
) upper
= check
;
2244 else lower
= check
+ 1;
2247 trace("working set limit is %p\n", (void *)upper
);
2248 ok(upper
!= ~(DWORD_PTR
)0, "expected != ~(DWORD_PTR)0\n");
2256 if(!InitFunctionPtrs())
2259 argc
= winetest_get_mainargs(&argv
);
2260 if (argc
>= 3) return; /* Child */
2262 /* NtQuerySystemInformation */
2264 /* 0x0 SystemBasicInformation */
2265 trace("Starting test_query_basic()\n");
2268 /* 0x1 SystemCpuInformation */
2269 trace("Starting test_query_cpu()\n");
2272 /* 0x2 SystemPerformanceInformation */
2273 trace("Starting test_query_performance()\n");
2274 test_query_performance();
2276 /* 0x3 SystemTimeOfDayInformation */
2277 trace("Starting test_query_timeofday()\n");
2278 test_query_timeofday();
2280 /* 0x5 SystemProcessInformation */
2281 trace("Starting test_query_process()\n");
2282 test_query_process();
2284 /* 0x8 SystemProcessorPerformanceInformation */
2285 trace("Starting test_query_procperf()\n");
2286 test_query_procperf();
2288 /* 0xb SystemModuleInformation */
2289 trace("Starting test_query_module()\n");
2290 test_query_module();
2292 /* 0x10 SystemHandleInformation */
2293 trace("Starting test_query_handle()\n");
2294 test_query_handle();
2296 /* 0x40 SystemHandleInformation */
2297 trace("Starting test_query_handle_ex()\n");
2298 test_query_handle_ex();
2300 /* 0x15 SystemCacheInformation */
2301 trace("Starting test_query_cache()\n");
2304 /* 0x17 SystemInterruptInformation */
2305 trace("Starting test_query_interrupt()\n");
2306 test_query_interrupt();
2308 /* 0x23 SystemKernelDebuggerInformation */
2309 trace("Starting test_query_kerndebug()\n");
2310 test_query_kerndebug();
2312 /* 0x25 SystemRegistryQuotaInformation */
2313 trace("Starting test_query_regquota()\n");
2314 test_query_regquota();
2316 /* 0x49 SystemLogicalProcessorInformation */
2317 trace("Starting test_query_logicalproc()\n");
2318 test_query_logicalproc();
2319 test_query_logicalprocex();
2321 /* NtPowerInformation */
2323 /* 0xb ProcessorInformation */
2324 trace("Starting test_query_processor_power_info()\n");
2325 test_query_processor_power_info();
2327 /* NtQueryInformationProcess */
2329 /* 0x0 ProcessBasicInformation */
2330 trace("Starting test_query_process_basic()\n");
2331 test_query_process_basic();
2333 /* 0x2 ProcessIoCounters */
2334 trace("Starting test_query_process_io()\n");
2335 test_query_process_io();
2337 /* 0x3 ProcessVmCounters */
2338 trace("Starting test_query_process_vm()\n");
2339 test_query_process_vm();
2341 /* 0x4 ProcessTimes */
2342 trace("Starting test_query_process_times()\n");
2343 test_query_process_times();
2345 /* 0x7 ProcessDebugPort */
2346 trace("Starting test_process_debug_port()\n");
2347 test_query_process_debug_port(argc
, argv
);
2349 /* 0x12 ProcessPriorityClass */
2350 trace("Starting test_query_process_priority()\n");
2351 test_query_process_priority();
2353 /* 0x14 ProcessHandleCount */
2354 trace("Starting test_query_process_handlecount()\n");
2355 test_query_process_handlecount();
2357 /* 0x1A ProcessWow64Information */
2358 trace("Starting test_query_process_wow64()\n");
2359 test_query_process_wow64();
2361 /* 0x1B ProcessImageFileName */
2362 trace("Starting test_query_process_image_file_name()\n");
2363 test_query_process_image_file_name();
2365 /* 0x1E ProcessDebugObjectHandle */
2366 trace("Starting test_query_process_debug_object_handle()\n");
2367 test_query_process_debug_object_handle(argc
, argv
);
2369 /* 0x1F ProcessDebugFlags */
2370 trace("Starting test_process_debug_flags()\n");
2371 test_query_process_debug_flags(argc
, argv
);
2373 /* belongs to its own file */
2374 trace("Starting test_readvirtualmemory()\n");
2375 test_readvirtualmemory();
2377 trace("Starting test_queryvirtualmemory()\n");
2378 test_queryvirtualmemory();
2380 trace("Starting test_mapprotection()\n");
2381 test_mapprotection();
2383 trace("Starting test_affinity()\n");
2386 trace("Starting test_NtGetCurrentProcessorNumber()\n");
2387 test_NtGetCurrentProcessorNumber();
2389 trace("Starting test_thread_start_address()\n");
2390 test_thread_start_address();
2392 trace("Starting test_query_data_alignment()\n");
2393 test_query_data_alignment();
2395 trace("Starting test_working_set_limit()\n");
2396 test_working_set_limit();