1 /* Unit test suite for *Information* Registry API functions
3 * Copyright 2005 Paul Vriens
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "ntdll_test.h"
25 static NTSTATUS (WINAPI
* pNtQuerySystemInformation
)(SYSTEM_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
26 static NTSTATUS (WINAPI
* pNtQuerySystemInformationEx
)(SYSTEM_INFORMATION_CLASS
, void*, ULONG
, void*, ULONG
, ULONG
*);
27 static NTSTATUS (WINAPI
* pNtPowerInformation
)(POWER_INFORMATION_LEVEL
, PVOID
, ULONG
, PVOID
, ULONG
);
28 static NTSTATUS (WINAPI
* pNtQueryInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
, PULONG
);
29 static NTSTATUS (WINAPI
* pNtQueryInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
, PULONG
);
30 static NTSTATUS (WINAPI
* pNtSetInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
);
31 static NTSTATUS (WINAPI
* pNtSetInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
);
32 static NTSTATUS (WINAPI
* pNtReadVirtualMemory
)(HANDLE
, const void*, void*, SIZE_T
, SIZE_T
*);
33 static NTSTATUS (WINAPI
* pNtQueryVirtualMemory
)(HANDLE
, LPCVOID
, MEMORY_INFORMATION_CLASS
, PVOID
, SIZE_T
, SIZE_T
*);
34 static NTSTATUS (WINAPI
* pNtCreateSection
)(HANDLE
*,ACCESS_MASK
,const OBJECT_ATTRIBUTES
*,const LARGE_INTEGER
*,ULONG
,ULONG
,HANDLE
);
35 static NTSTATUS (WINAPI
* pNtMapViewOfSection
)(HANDLE
,HANDLE
,PVOID
*,ULONG
,SIZE_T
,const LARGE_INTEGER
*,SIZE_T
*,SECTION_INHERIT
,ULONG
,ULONG
);
36 static NTSTATUS (WINAPI
* pNtUnmapViewOfSection
)(HANDLE
,PVOID
);
37 static NTSTATUS (WINAPI
* pNtClose
)(HANDLE
);
38 static ULONG (WINAPI
* pNtGetCurrentProcessorNumber
)(void);
39 static BOOL (WINAPI
* pIsWow64Process
)(HANDLE
, PBOOL
);
40 static BOOL (WINAPI
* pGetLogicalProcessorInformationEx
)(LOGICAL_PROCESSOR_RELATIONSHIP
,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*,DWORD
*);
44 /* one_before_last_pid is used to be able to compare values of a still running process
45 with the output of the test_query_process_times and test_query_process_handlecount tests.
47 static DWORD one_before_last_pid
= 0;
49 #define NTDLL_GET_PROC(func) do { \
50 p ## func = (void*)GetProcAddress(hntdll, #func); \
52 trace("GetProcAddress(%s) failed\n", #func); \
57 static BOOL
InitFunctionPtrs(void)
59 /* All needed functions are NT based, so using GetModuleHandle is a good check */
60 HMODULE hntdll
= GetModuleHandleA("ntdll");
61 HMODULE hkernel32
= GetModuleHandleA("kernel32");
65 win_skip("Not running on NT\n");
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_cache(void)
569 SYSTEM_CACHE_INFORMATION
*sci
= (SYSTEM_CACHE_INFORMATION
*) buffer
;
573 /* the large SYSTEM_CACHE_INFORMATION on WIN64 is not documented */
574 expected
= sizeof(SYSTEM_CACHE_INFORMATION
);
575 for (i
= sizeof(buffer
); i
>= expected
; i
--)
577 ReturnLength
= 0xdeadbeef;
578 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
579 ok(!status
&& (ReturnLength
== expected
),
580 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i
, status
, ReturnLength
, expected
);
583 /* buffer too small for the full result.
584 Up to win7, the function succeeds with a partial result. */
585 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
588 expected
= offsetof(SYSTEM_CACHE_INFORMATION
, MinimumWorkingSet
);
589 for (; i
>= expected
; i
--)
591 ReturnLength
= 0xdeadbeef;
592 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
593 ok(!status
&& (ReturnLength
== expected
),
594 "%d: got 0x%x and %u (expected STATUS_SUCCESS and %u)\n", i
, status
, ReturnLength
, expected
);
598 /* buffer too small for the result, this call will always fail */
599 ReturnLength
= 0xdeadbeef;
600 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, i
, &ReturnLength
);
601 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
602 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
603 "%d: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", i
, status
, ReturnLength
, expected
);
606 /* this crashes on some vista / win7 machines */
607 ReturnLength
= 0xdeadbeef;
608 status
= pNtQuerySystemInformation(SystemCacheInformation
, sci
, 0, &ReturnLength
);
609 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
610 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
611 "0: got 0x%x and %u (expected STATUS_INFO_LENGTH_MISMATCH and %u)\n", status
, ReturnLength
, expected
);
615 static void test_query_interrupt(void)
620 SYSTEM_BASIC_INFORMATION sbi
;
621 SYSTEM_INTERRUPT_INFORMATION
* sii
;
623 /* Find out the number of processors */
624 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
625 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
626 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
);
628 sii
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
630 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, 0, &ReturnLength
);
631 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
633 /* Try it for all processors */
634 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, NeededLength
, &ReturnLength
);
635 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
637 /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength
638 * No test added for this as it's highly unlikely that an app depends on this
641 HeapFree( GetProcessHeap(), 0, sii
);
644 static void test_query_kerndebug(void)
648 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi
;
650 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, 0, &ReturnLength
);
651 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
653 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
), &ReturnLength
);
654 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
655 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
657 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
) + 2, &ReturnLength
);
658 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
659 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
662 static void test_query_regquota(void)
666 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi
;
668 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, 0, &ReturnLength
);
669 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
671 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
), &ReturnLength
);
672 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
673 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
675 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
) + 2, &ReturnLength
);
676 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
677 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
680 static void test_query_logicalproc(void)
683 ULONG len
, i
, proc_no
;
684 SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*slpi
;
689 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, NULL
, 0, &len
);
690 if(status
== STATUS_INVALID_INFO_CLASS
)
692 win_skip("SystemLogicalProcessorInformation is not supported\n");
695 if(status
== STATUS_NOT_IMPLEMENTED
)
697 todo_wine
ok(0, "SystemLogicalProcessorInformation is not implemented\n");
700 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
701 ok(len
%sizeof(*slpi
) == 0, "Incorrect length %d\n", len
);
703 slpi
= HeapAlloc(GetProcessHeap(), 0, len
);
704 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, slpi
, len
, &len
);
705 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
708 for(i
=0; i
<len
/sizeof(*slpi
); i
++) {
709 switch(slpi
[i
].Relationship
) {
710 case RelationProcessorCore
:
711 /* Get number of logical processors */
712 for(; slpi
[i
].ProcessorMask
; slpi
[i
].ProcessorMask
/= 2)
713 proc_no
+= slpi
[i
].ProcessorMask
%2;
719 ok(proc_no
> 0, "No processors were found\n");
720 if(si
.dwNumberOfProcessors
<= 32)
721 ok(proc_no
== si
.dwNumberOfProcessors
, "Incorrect number of logical processors: %d, expected %d\n",
722 proc_no
, si
.dwNumberOfProcessors
);
724 HeapFree(GetProcessHeap(), 0, slpi
);
727 static void test_query_logicalprocex(void)
729 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*infoex
, *infoex2
;
730 DWORD relationship
, len2
, len
;
734 if (!pNtQuerySystemInformationEx
)
738 relationship
= RelationProcessorCore
;
739 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len
);
740 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08x\n", status
);
741 ok(len
> 0, "got %u\n", len
);
744 relationship
= RelationAll
;
745 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len
);
746 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08x\n", status
);
747 ok(len
> 0, "got %u\n", len
);
750 ret
= pGetLogicalProcessorInformationEx(RelationAll
, NULL
, &len2
);
751 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %d, error %d\n", ret
, GetLastError());
752 ok(len
== len2
, "got %u, expected %u\n", len2
, len
);
754 if (len
&& len
== len2
) {
757 infoex
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
758 infoex2
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
760 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex
, len
, &len
);
761 ok(status
== STATUS_SUCCESS
, "got 0x%08x\n", status
);
763 ret
= pGetLogicalProcessorInformationEx(RelationAll
, infoex2
, &len2
);
764 ok(ret
, "got %d, error %d\n", ret
, GetLastError());
765 ok(!memcmp(infoex
, infoex2
, len
), "returned info data mismatch\n");
767 for(i
= 0; status
== STATUS_SUCCESS
&& i
< len
; ){
768 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*ex
= (void*)(((char *)infoex
) + i
);
770 ok(ex
->Relationship
>= RelationProcessorCore
&& ex
->Relationship
<= RelationGroup
,
771 "Got invalid relationship value: 0x%x\n", ex
->Relationship
);
774 ok(0, "got infoex[%u].Size=0\n", i
);
778 trace("infoex[%u].Size: %u\n", i
, ex
->Size
);
779 switch(ex
->Relationship
){
780 case RelationProcessorCore
:
781 case RelationProcessorPackage
:
782 trace("infoex[%u].Relationship: 0x%x (Core == 0x0 or Package == 0x3)\n", i
, ex
->Relationship
);
783 trace("infoex[%u].Processor.Flags: 0x%x\n", i
, ex
->Processor
.Flags
);
784 trace("infoex[%u].Processor.EfficiencyClass: 0x%x\n", i
, ex
->Processor
.EfficiencyClass
);
785 trace("infoex[%u].Processor.GroupCount: 0x%x\n", i
, ex
->Processor
.GroupCount
);
786 for(j
= 0; j
< ex
->Processor
.GroupCount
; ++j
){
787 trace("infoex[%u].Processor.GroupMask[%u].Mask: 0x%lx\n", i
, j
, ex
->Processor
.GroupMask
[j
].Mask
);
788 trace("infoex[%u].Processor.GroupMask[%u].Group: 0x%x\n", i
, j
, ex
->Processor
.GroupMask
[j
].Group
);
791 case RelationNumaNode
:
792 trace("infoex[%u].Relationship: 0x%x (NumaNode)\n", i
, ex
->Relationship
);
793 trace("infoex[%u].NumaNode.NodeNumber: 0x%x\n", i
, ex
->NumaNode
.NodeNumber
);
794 trace("infoex[%u].NumaNode.GroupMask.Mask: 0x%lx\n", i
, ex
->NumaNode
.GroupMask
.Mask
);
795 trace("infoex[%u].NumaNode.GroupMask.Group: 0x%x\n", i
, ex
->NumaNode
.GroupMask
.Group
);
798 trace("infoex[%u].Relationship: 0x%x (Cache)\n", i
, ex
->Relationship
);
799 trace("infoex[%u].Cache.Level: 0x%x\n", i
, ex
->Cache
.Level
);
800 trace("infoex[%u].Cache.Associativity: 0x%x\n", i
, ex
->Cache
.Associativity
);
801 trace("infoex[%u].Cache.LineSize: 0x%x\n", i
, ex
->Cache
.LineSize
);
802 trace("infoex[%u].Cache.CacheSize: 0x%x\n", i
, ex
->Cache
.CacheSize
);
803 trace("infoex[%u].Cache.Type: 0x%x\n", i
, ex
->Cache
.Type
);
804 trace("infoex[%u].Cache.GroupMask.Mask: 0x%lx\n", i
, ex
->Cache
.GroupMask
.Mask
);
805 trace("infoex[%u].Cache.GroupMask.Group: 0x%x\n", i
, ex
->Cache
.GroupMask
.Group
);
808 trace("infoex[%u].Relationship: 0x%x (Group)\n", i
, ex
->Relationship
);
809 trace("infoex[%u].Group.MaximumGroupCount: 0x%x\n", i
, ex
->Group
.MaximumGroupCount
);
810 trace("infoex[%u].Group.ActiveGroupCount: 0x%x\n", i
, ex
->Group
.ActiveGroupCount
);
811 for(j
= 0; j
< ex
->Group
.ActiveGroupCount
; ++j
){
812 trace("infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].MaximumProcessorCount
);
813 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorCount
);
814 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%lx\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorMask
);
824 HeapFree(GetProcessHeap(), 0, infoex
);
825 HeapFree(GetProcessHeap(), 0, infoex2
);
829 static void test_query_processor_power_info(void)
832 PROCESSOR_POWER_INFORMATION
* ppi
;
838 size
= si
.dwNumberOfProcessors
* sizeof(PROCESSOR_POWER_INFORMATION
);
839 ppi
= HeapAlloc(GetProcessHeap(), 0, size
);
841 /* If size < (sizeof(PROCESSOR_POWER_INFORMATION) * NumberOfProcessors), Win7 returns
842 * STATUS_BUFFER_TOO_SMALL. WinXP returns STATUS_SUCCESS for any value of size. It copies as
843 * many whole PROCESSOR_POWER_INFORMATION structures that there is room for. Even if there is
844 * not enough room for one structure, WinXP still returns STATUS_SUCCESS having done nothing.
846 * If ppi == NULL, Win7 returns STATUS_INVALID_PARAMETER while WinXP returns STATUS_SUCCESS
849 * The same behavior is seen with CallNtPowerInformation (in powrprof.dll).
852 if (si
.dwNumberOfProcessors
> 1)
854 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
855 ppi
[i
].Number
= 0xDEADBEEF;
857 /* Call with a buffer size that is large enough to hold at least one but not large
858 * enough to hold them all. This will be STATUS_SUCCESS on WinXP but not on Win7 */
859 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
- sizeof(PROCESSOR_POWER_INFORMATION
));
860 if (status
== STATUS_SUCCESS
)
862 /* lax version found on older Windows like WinXP */
863 ok( (ppi
[si
.dwNumberOfProcessors
- 2].Number
!= 0xDEADBEEF) &&
864 (ppi
[si
.dwNumberOfProcessors
- 1].Number
== 0xDEADBEEF),
865 "Expected all but the last record to be overwritten.\n");
867 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
868 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
870 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
871 ppi
[i
].Number
= 0xDEADBEEF;
872 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, sizeof(PROCESSOR_POWER_INFORMATION
) - 1);
873 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
874 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
875 if (ppi
[i
].Number
!= 0xDEADBEEF) break;
876 ok( i
== si
.dwNumberOfProcessors
, "Expected untouched buffer\n");
880 /* picky version found on newer Windows like Win7 */
881 ok( ppi
[1].Number
== 0xDEADBEEF, "Expected untouched buffer.\n");
882 ok( status
== STATUS_BUFFER_TOO_SMALL
, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status
);
884 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
885 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, "Got %08x\n", status
);
887 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, 0);
888 ok( status
== STATUS_BUFFER_TOO_SMALL
|| status
== STATUS_INVALID_PARAMETER
, "Got %08x\n", status
);
893 skip("Test needs more than one processor.\n");
896 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
);
897 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
899 HeapFree(GetProcessHeap(), 0, ppi
);
902 static void test_query_process_wow64(void)
906 ULONG_PTR pbi
[2], dummy
;
908 memset(&dummy
, 0xcc, sizeof(dummy
));
910 /* Do not give a handle and buffer */
911 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, 0, NULL
);
912 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
914 /* Use a correct info class and buffer size, but still no handle and buffer */
915 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
916 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
917 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE, got %08x\n", status
);
919 /* Use a correct info class, buffer size and handle, but no buffer */
920 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
921 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
923 /* Use a correct info class, buffer and buffer size, but no handle */
924 pbi
[0] = pbi
[1] = dummy
;
925 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
926 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
927 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
928 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
930 /* Use a greater buffer size */
931 pbi
[0] = pbi
[1] = dummy
;
932 status
= pNtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, NULL
);
933 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
934 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
935 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
937 /* Use no ReturnLength */
938 pbi
[0] = pbi
[1] = dummy
;
939 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
940 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
941 trace( "Platform is_wow64 %d, ProcessInformation of ProcessWow64Information %lx\n", is_wow64
, pbi
[0]);
942 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64
, pbi
[0]);
943 ok( pbi
[0] != dummy
, "pbi[0] %lx\n", pbi
[0]);
944 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
945 /* Test written size on 64 bit by checking high 32 bit buffer */
946 if (sizeof(ULONG_PTR
) > sizeof(DWORD
))
948 DWORD
*ptr
= (DWORD
*)pbi
;
949 ok( ptr
[1] != (DWORD
)dummy
, "ptr[1] unchanged!\n");
952 /* Finally some correct calls */
953 pbi
[0] = pbi
[1] = dummy
;
954 ReturnLength
= 0xdeadbeef;
955 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), &ReturnLength
);
956 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
957 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64
, pbi
[0]);
958 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
959 ok( ReturnLength
== sizeof(ULONG_PTR
), "Inconsistent length %d\n", ReturnLength
);
961 /* Everything is correct except a too small buffer size */
962 pbi
[0] = pbi
[1] = dummy
;
963 ReturnLength
= 0xdeadbeef;
964 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) - 1, &ReturnLength
);
965 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
966 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
967 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
968 todo_wine
ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength
);
970 /* Everything is correct except a too large buffer size */
971 pbi
[0] = pbi
[1] = dummy
;
972 ReturnLength
= 0xdeadbeef;
973 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, &ReturnLength
);
974 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
975 ok( pbi
[0] == dummy
, "pbi[0] changed to %lx\n", pbi
[0]);
976 ok( pbi
[1] == dummy
, "pbi[1] changed to %lx\n", pbi
[1]);
977 todo_wine
ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength
);
980 static void test_query_process_basic(void)
985 typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE
{
986 DWORD_PTR ExitStatus
;
988 DWORD_PTR AffinityMask
;
989 DWORD_PTR BasePriority
;
990 ULONG_PTR UniqueProcessId
;
991 ULONG_PTR InheritedFromUniqueProcessId
;
992 } PROCESS_BASIC_INFORMATION_PRIVATE
;
994 PROCESS_BASIC_INFORMATION_PRIVATE pbi
;
996 /* This test also covers some basic parameter testing that should be the same for
997 * every information class
1000 /* Use a nonexistent info class */
1001 trace("Check nonexistent info class\n");
1002 status
= pNtQueryInformationProcess(NULL
, -1, NULL
, 0, NULL
);
1003 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
1004 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
1006 /* Do not give a handle and buffer */
1007 trace("Check NULL handle and buffer and zero-length buffersize\n");
1008 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, 0, NULL
);
1009 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1011 /* Use a correct info class and buffer size, but still no handle and buffer */
1012 trace("Check NULL handle and buffer\n");
1013 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, sizeof(pbi
), NULL
);
1014 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1015 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1017 /* Use a correct info class and buffer size, but still no handle */
1018 trace("Check NULL handle\n");
1019 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1020 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1022 /* Use a greater buffer size */
1023 trace("Check NULL handle and too large buffersize\n");
1024 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, NULL
);
1025 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1027 /* Use no ReturnLength */
1028 trace("Check NULL ReturnLength\n");
1029 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1030 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1032 /* Finally some correct calls */
1033 trace("Check with correct parameters\n");
1034 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), &ReturnLength
);
1035 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1036 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1038 /* Everything is correct except a too large buffersize */
1039 trace("Too large buffersize\n");
1040 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, &ReturnLength
);
1041 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1042 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1044 /* Check if we have some return values */
1045 trace("ProcessID : %lx\n", pbi
.UniqueProcessId
);
1046 ok( pbi
.UniqueProcessId
> 0, "Expected a ProcessID > 0, got 0\n");
1049 static void dump_vm_counters(const char *header
, const VM_COUNTERS
*pvi
)
1051 trace("%s:\n", header
);
1052 trace("PeakVirtualSize : %lu\n", pvi
->PeakVirtualSize
);
1053 trace("VirtualSize : %lu\n", pvi
->VirtualSize
);
1054 trace("PageFaultCount : %u\n", pvi
->PageFaultCount
);
1055 trace("PeakWorkingSetSize : %lu\n", pvi
->PeakWorkingSetSize
);
1056 trace("WorkingSetSize : %lu\n", pvi
->WorkingSetSize
);
1057 trace("QuotaPeakPagedPoolUsage : %lu\n", pvi
->QuotaPeakPagedPoolUsage
);
1058 trace("QuotaPagedPoolUsage : %lu\n", pvi
->QuotaPagedPoolUsage
);
1059 trace("QuotaPeakNonPagePoolUsage : %lu\n", pvi
->QuotaPeakNonPagedPoolUsage
);
1060 trace("QuotaNonPagePoolUsage : %lu\n", pvi
->QuotaNonPagedPoolUsage
);
1061 trace("PagefileUsage : %lu\n", pvi
->PagefileUsage
);
1062 trace("PeakPagefileUsage : %lu\n", pvi
->PeakPagefileUsage
);
1065 static void test_query_process_vm(void)
1070 ULONG old_size
= FIELD_OFFSET(VM_COUNTERS
,PrivatePageCount
);
1073 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, NULL
, sizeof(pvi
), NULL
);
1074 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1075 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1077 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, &pvi
, old_size
, NULL
);
1078 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1080 /* Windows XP and W2K3 will report success for a size of 44 AND 48 !
1081 Windows W2K will only report success for 44.
1082 For now we only care for 44, which is FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
1085 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 24, &ReturnLength
);
1086 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1088 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, old_size
, &ReturnLength
);
1089 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1090 ok( old_size
== ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1092 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 46, &ReturnLength
);
1093 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1094 ok( ReturnLength
== old_size
|| ReturnLength
== sizeof(pvi
), "Inconsistent length %d\n", ReturnLength
);
1096 /* Check if we have some return values */
1097 dump_vm_counters("VM counters for GetCurrentProcess", &pvi
);
1098 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1100 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1101 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1102 ok( status
== STATUS_ACCESS_DENIED
, "Expected STATUS_ACCESS_DENIED, got %08x\n", status
);
1103 CloseHandle(process
);
1105 process
= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION
, FALSE
, GetCurrentProcessId());
1106 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1107 ok( status
== STATUS_SUCCESS
|| broken(!process
) /* XP */, "Expected STATUS_SUCCESS, got %08x\n", status
);
1108 CloseHandle(process
);
1110 memset(&pvi
, 0, sizeof(pvi
));
1111 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, GetCurrentProcessId());
1112 status
= pNtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1113 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1115 /* Check if we have some return values */
1116 dump_vm_counters("VM counters for GetCurrentProcessId", &pvi
);
1117 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1119 CloseHandle(process
);
1122 static void test_query_process_io(void)
1128 /* NT4 doesn't support this information class, so check for it */
1129 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
1130 if (status
== STATUS_NOT_SUPPORTED
)
1132 win_skip("ProcessIoCounters information class is not supported\n");
1136 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, NULL
, sizeof(pii
), NULL
);
1137 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1138 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1140 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, &pii
, sizeof(pii
), NULL
);
1141 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1143 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, 24, &ReturnLength
);
1144 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1146 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
1147 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1148 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1150 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
) * 2, &ReturnLength
);
1151 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1152 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1154 /* Check if we have some return values */
1155 trace("OtherOperationCount : 0x%x%08x\n", (DWORD
)(pii
.OtherOperationCount
>> 32), (DWORD
)pii
.OtherOperationCount
);
1158 ok( pii
.OtherOperationCount
> 0, "Expected an OtherOperationCount > 0\n");
1162 static void test_query_process_times(void)
1167 SYSTEMTIME UTC
, Local
;
1168 KERNEL_USER_TIMES spti
;
1170 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, NULL
, sizeof(spti
), NULL
);
1171 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1172 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1174 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, &spti
, sizeof(spti
), NULL
);
1175 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1177 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, 24, &ReturnLength
);
1178 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1180 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
1183 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
1184 process
= GetCurrentProcess();
1185 trace("ProcessTimes for current process\n");
1188 trace("ProcessTimes for process with ID : %d\n", one_before_last_pid
);
1190 status
= pNtQueryInformationProcess( process
, ProcessTimes
, &spti
, sizeof(spti
), &ReturnLength
);
1191 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1192 ok( sizeof(spti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1193 CloseHandle(process
);
1195 FileTimeToSystemTime((const FILETIME
*)&spti
.CreateTime
, &UTC
);
1196 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
1197 trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
1198 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
1200 FileTimeToSystemTime((const FILETIME
*)&spti
.ExitTime
, &UTC
);
1201 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
1202 trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
1203 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
1205 FileTimeToSystemTime((const FILETIME
*)&spti
.KernelTime
, &Local
);
1206 trace("KernelTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
1208 FileTimeToSystemTime((const FILETIME
*)&spti
.UserTime
, &Local
);
1209 trace("UserTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
1211 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, sizeof(spti
) * 2, &ReturnLength
);
1212 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1213 ok( sizeof(spti
) == ReturnLength
||
1214 ReturnLength
== 0 /* vista */ ||
1215 broken(is_wow64
), /* returns garbage on wow64 */
1216 "Inconsistent length %d\n", ReturnLength
);
1219 static void test_query_process_debug_port(int argc
, char **argv
)
1221 DWORD_PTR debug_port
= 0xdeadbeef;
1222 char cmdline
[MAX_PATH
];
1223 PROCESS_INFORMATION pi
;
1224 STARTUPINFOA si
= { 0 };
1228 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1231 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
, NULL
, &si
, &pi
);
1232 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
1235 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1237 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1239 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1240 NULL
, sizeof(debug_port
), NULL
);
1241 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
,
1242 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1244 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1245 NULL
, sizeof(debug_port
), NULL
);
1246 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1248 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
1249 &debug_port
, sizeof(debug_port
), NULL
);
1250 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1252 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1253 &debug_port
, sizeof(debug_port
) - 1, NULL
);
1254 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1256 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1257 &debug_port
, sizeof(debug_port
) + 1, NULL
);
1258 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1260 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
1261 &debug_port
, sizeof(debug_port
), NULL
);
1262 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1263 ok(debug_port
== 0, "Expected port 0, got %#lx.\n", debug_port
);
1265 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugPort
,
1266 &debug_port
, sizeof(debug_port
), NULL
);
1267 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1268 ok(debug_port
== ~(DWORD_PTR
)0, "Expected port %#lx, got %#lx.\n", ~(DWORD_PTR
)0, debug_port
);
1274 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1275 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1278 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1280 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1281 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1285 ret
= CloseHandle(pi
.hThread
);
1286 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1287 ret
= CloseHandle(pi
.hProcess
);
1288 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1291 static void test_query_process_handlecount(void)
1296 BYTE buffer
[2 * sizeof(DWORD
)];
1299 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, NULL
, sizeof(handlecount
), NULL
);
1300 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1301 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
1303 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), NULL
);
1304 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1306 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, &handlecount
, 2, &ReturnLength
);
1307 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1309 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
1312 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
1313 process
= GetCurrentProcess();
1314 trace("ProcessHandleCount for current process\n");
1317 trace("ProcessHandleCount for process with ID : %d\n", one_before_last_pid
);
1319 status
= pNtQueryInformationProcess( process
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), &ReturnLength
);
1320 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1321 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1322 CloseHandle(process
);
1324 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, buffer
, sizeof(buffer
), &ReturnLength
);
1325 ok( status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_SUCCESS
,
1326 "Expected STATUS_INFO_LENGTH_MISMATCH or STATUS_SUCCESS, got %08x\n", status
);
1327 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
1329 /* Check if we have some return values */
1330 trace("HandleCount : %d\n", handlecount
);
1333 ok( handlecount
> 0, "Expected some handles, got 0\n");
1337 static void test_query_process_image_file_name(void)
1341 UNICODE_STRING image_file_name
;
1346 status
= pNtQueryInformationProcess(NULL
, ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), NULL
);
1347 if (status
== STATUS_INVALID_INFO_CLASS
)
1349 win_skip("ProcessImageFileName is not supported\n");
1352 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1354 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, 2, &ReturnLength
);
1355 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1357 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), &ReturnLength
);
1358 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
1360 buffer
= HeapAlloc(GetProcessHeap(), 0, ReturnLength
);
1361 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, buffer
, ReturnLength
, &ReturnLength
);
1362 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1363 memcpy(&image_file_name
, buffer
, sizeof(image_file_name
));
1364 len
= WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), NULL
, 0, NULL
, NULL
);
1365 file_nameA
= HeapAlloc(GetProcessHeap(), 0, len
+ 1);
1366 WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), file_nameA
, len
, NULL
, NULL
);
1367 file_nameA
[len
] = '\0';
1368 HeapFree(GetProcessHeap(), 0, buffer
);
1369 trace("process image file name: %s\n", file_nameA
);
1370 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
);
1371 HeapFree(GetProcessHeap(), 0, file_nameA
);
1374 static void test_query_process_debug_object_handle(int argc
, char **argv
)
1376 char cmdline
[MAX_PATH
];
1377 STARTUPINFOA si
= {0};
1378 PROCESS_INFORMATION pi
;
1380 HANDLE debug_object
;
1383 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1386 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
,
1388 ok(ret
, "CreateProcess failed with last error %u\n", GetLastError());
1391 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
1393 if (status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
)
1395 win_skip("ProcessDebugObjectHandle is not supported\n");
1398 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1399 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n",
1402 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
1403 sizeof(debug_object
), NULL
);
1404 ok(status
== STATUS_INVALID_HANDLE
||
1405 status
== STATUS_ACCESS_VIOLATION
, /* XP */
1406 "Expected NtQueryInformationProcess to return STATUS_INVALID_HANDLE, got 0x%08x\n", status
);
1408 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1409 ProcessDebugObjectHandle
, NULL
, sizeof(debug_object
), NULL
);
1410 ok(status
== STATUS_ACCESS_VIOLATION
,
1411 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
1413 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
,
1414 &debug_object
, sizeof(debug_object
), NULL
);
1415 ok(status
== STATUS_INVALID_HANDLE
,
1416 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
1418 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1419 ProcessDebugObjectHandle
, &debug_object
,
1420 sizeof(debug_object
) - 1, NULL
);
1421 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1422 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
1424 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1425 ProcessDebugObjectHandle
, &debug_object
,
1426 sizeof(debug_object
) + 1, NULL
);
1427 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
1428 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
1430 debug_object
= (HANDLE
)0xdeadbeef;
1431 status
= pNtQueryInformationProcess(GetCurrentProcess(),
1432 ProcessDebugObjectHandle
, &debug_object
,
1433 sizeof(debug_object
), NULL
);
1434 ok(status
== STATUS_PORT_NOT_SET
,
1435 "Expected NtQueryInformationProcess to return STATUS_PORT_NOT_SET, got 0x%08x\n", status
);
1436 ok(debug_object
== NULL
||
1437 broken(debug_object
== (HANDLE
)0xdeadbeef), /* Wow64 */
1438 "Expected debug object handle to be NULL, got %p\n", debug_object
);
1440 debug_object
= (HANDLE
)0xdeadbeef;
1441 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugObjectHandle
,
1442 &debug_object
, sizeof(debug_object
), NULL
);
1444 ok(status
== STATUS_SUCCESS
,
1445 "Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08x\n", status
);
1447 ok(debug_object
!= NULL
,
1448 "Expected debug object handle to be non-NULL, got %p\n", debug_object
);
1454 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1455 ok(ret
, "WaitForDebugEvent failed with last error %u\n", GetLastError());
1458 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1460 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1461 ok(ret
, "ContinueDebugEvent failed with last error %u\n", GetLastError());
1465 ret
= CloseHandle(pi
.hThread
);
1466 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1467 ret
= CloseHandle(pi
.hProcess
);
1468 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1471 static void test_query_process_debug_flags(int argc
, char **argv
)
1473 static const DWORD test_flags
[] = { DEBUG_PROCESS
,
1474 DEBUG_ONLY_THIS_PROCESS
,
1475 DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
,
1477 DWORD debug_flags
= 0xdeadbeef;
1478 char cmdline
[MAX_PATH
];
1479 PROCESS_INFORMATION pi
;
1480 STARTUPINFOA si
= { 0 };
1487 /* test invalid arguments */
1488 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, 0, NULL
);
1489 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1490 "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1492 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, sizeof(debug_flags
), NULL
);
1493 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1494 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1496 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1497 NULL
, sizeof(debug_flags
), NULL
);
1498 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1500 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
,
1501 &debug_flags
, sizeof(debug_flags
), NULL
);
1502 ok(status
== STATUS_INVALID_HANDLE
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
1503 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1505 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1506 &debug_flags
, sizeof(debug_flags
) - 1, NULL
);
1507 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1509 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1510 &debug_flags
, sizeof(debug_flags
) + 1, NULL
);
1511 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1513 /* test ProcessDebugFlags of current process */
1514 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1515 &debug_flags
, sizeof(debug_flags
), NULL
);
1516 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1517 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %x.\n", debug_flags
);
1519 for (i
= 0; i
< sizeof(test_flags
)/sizeof(test_flags
[0]); i
++)
1521 DWORD expected_flags
= !(test_flags
[i
] & DEBUG_ONLY_THIS_PROCESS
);
1522 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1525 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, test_flags
[i
], NULL
, NULL
, &si
, &pi
);
1526 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
1528 if (!(test_flags
[i
] & (DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
)))
1530 /* test ProcessDebugFlags before attaching with debugger */
1531 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1532 &debug_flags
, sizeof(debug_flags
), NULL
);
1533 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1534 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %x.\n", debug_flags
);
1536 ret
= DebugActiveProcess(pi
.dwProcessId
);
1537 ok(ret
, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1538 expected_flags
= FALSE
;
1541 /* test ProcessDebugFlags after attaching with debugger */
1542 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1543 &debug_flags
, sizeof(debug_flags
), NULL
);
1544 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1545 ok(debug_flags
== expected_flags
, "Expected flag %x, got %x.\n", expected_flags
, debug_flags
);
1547 if (!(test_flags
[i
] & CREATE_SUSPENDED
))
1549 /* Continue a couple of times to make sure the process is fully initialized,
1550 * otherwise Windows XP deadlocks in the following DebugActiveProcess(). */
1553 ret
= WaitForDebugEvent(&ev
, 1000);
1554 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1557 if (ev
.dwDebugEventCode
== LOAD_DLL_DEBUG_EVENT
) break;
1559 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1560 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1564 result
= SuspendThread(pi
.hThread
);
1565 ok(result
== 0, "Expected 0, got %u.\n", result
);
1568 ret
= DebugActiveProcessStop(pi
.dwProcessId
);
1569 ok(ret
, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError());
1571 /* test ProcessDebugFlags after detaching debugger */
1572 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1573 &debug_flags
, sizeof(debug_flags
), NULL
);
1574 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1575 ok(debug_flags
== expected_flags
, "Expected flag %x, got %x.\n", expected_flags
, debug_flags
);
1577 ret
= DebugActiveProcess(pi
.dwProcessId
);
1578 ok(ret
, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
1580 /* test ProcessDebugFlags after re-attaching debugger */
1581 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1582 &debug_flags
, sizeof(debug_flags
), NULL
);
1583 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1584 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %x.\n", debug_flags
);
1586 result
= ResumeThread(pi
.hThread
);
1587 todo_wine
ok(result
== 2, "Expected 2, got %u.\n", result
);
1589 /* Wait until the process is terminated. On Windows XP the process randomly
1590 * gets stuck in a non-continuable exception, so stop after 100 iterations.
1591 * On Windows 2003, the debugged process disappears (or stops?) without
1592 * any EXIT_PROCESS_DEBUG_EVENT after a couple of events. */
1593 for (j
= 0; j
< 100; j
++)
1595 ret
= WaitForDebugEvent(&ev
, 1000);
1596 ok(ret
|| broken(GetLastError() == ERROR_SEM_TIMEOUT
),
1597 "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1600 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1602 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1603 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1606 ok(j
< 100 || broken(j
>= 100) /* Win XP */, "Expected less than 100 debug events.\n");
1608 /* test ProcessDebugFlags after process has terminated */
1609 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1610 &debug_flags
, sizeof(debug_flags
), NULL
);
1611 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
1612 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %x.\n", debug_flags
);
1614 ret
= CloseHandle(pi
.hThread
);
1615 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1616 ret
= CloseHandle(pi
.hProcess
);
1617 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1621 static void test_readvirtualmemory(void)
1626 static const char teststring
[] = "test string";
1629 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1630 ok(process
!= 0, "Expected to be able to open own process for reading memory\n");
1632 /* normal operation */
1633 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, &readcount
);
1634 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1635 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1636 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1638 /* no number of bytes */
1639 memset(buffer
, 0, 12);
1640 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, NULL
);
1641 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1642 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1644 /* illegal remote address */
1646 status
= pNtReadVirtualMemory(process
, (void *) 0x1234, buffer
, 12, &readcount
);
1647 ok( status
== STATUS_PARTIAL_COPY
|| broken(status
== STATUS_ACCESS_VIOLATION
), "Expected STATUS_PARTIAL_COPY, got %08x\n", status
);
1648 if (status
== STATUS_PARTIAL_COPY
)
1649 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1653 status
= pNtReadVirtualMemory(0, teststring
, buffer
, 12, &readcount
);
1654 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1655 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1657 /* pseudo handle for current process*/
1658 memset(buffer
, 0, 12);
1659 status
= pNtReadVirtualMemory((HANDLE
)-1, teststring
, buffer
, 12, &readcount
);
1660 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1661 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1662 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1664 /* illegal local address */
1665 status
= pNtReadVirtualMemory(process
, teststring
, (void *)0x1234, 12, &readcount
);
1666 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
1667 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1669 CloseHandle(process
);
1672 static void test_mapprotection(void)
1676 MEMORY_BASIC_INFORMATION info
;
1677 ULONG oldflags
, flagsize
, flags
= MEM_EXECUTE_OPTION_ENABLE
;
1678 LARGE_INTEGER size
, offset
;
1680 SIZE_T retlen
, count
;
1684 skip("No NtClose ... Win98\n");
1687 /* Switch to being a noexec unaware process */
1688 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof (oldflags
), &flagsize
);
1689 if (status
== STATUS_INVALID_PARAMETER
) {
1690 skip("Invalid Parameter on ProcessExecuteFlags query?\n");
1693 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1694 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &flags
, sizeof(flags
) );
1695 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1697 size
.u
.LowPart
= 0x2000;
1698 size
.u
.HighPart
= 0;
1699 status
= pNtCreateSection ( &h
,
1700 STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
,
1704 SEC_COMMIT
| SEC_NOCACHE
,
1707 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1709 offset
.u
.LowPart
= 0;
1710 offset
.u
.HighPart
= 0;
1713 status
= pNtMapViewOfSection ( h
, GetCurrentProcess(), &addr
, 0, 0, &offset
, &count
, ViewShare
, 0, PAGE_READWRITE
);
1714 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1716 #if defined(__x86_64__) || defined(__i386__)
1717 *(unsigned char*)addr
= 0xc3; /* lret ... in both i386 and x86_64 */
1718 #elif defined(__arm__)
1719 *(unsigned long*)addr
= 0xe12fff1e; /* bx lr */
1720 #elif defined(__aarch64__)
1721 *(unsigned long*)addr
= 0xd65f03c0; /* ret */
1723 ok(0, "Add a return opcode for your architecture or expect a crash in this test\n");
1725 trace("trying to execute code in the readwrite only mapped anon file...\n");
1727 trace("...done.\n");
1729 status
= pNtQueryVirtualMemory( GetCurrentProcess(), addr
, MemoryBasicInformation
, &info
, sizeof(info
), &retlen
);
1730 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1731 ok( retlen
== sizeof(info
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1732 ok((info
.Protect
& ~PAGE_NOCACHE
) == PAGE_READWRITE
, "addr.Protect is not PAGE_READWRITE, but 0x%x\n", info
.Protect
);
1734 status
= pNtUnmapViewOfSection( GetCurrentProcess(), (char *)addr
+ 0x1050 );
1735 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1739 pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof(oldflags
) );
1742 static void test_queryvirtualmemory(void)
1746 static const char teststring
[] = "test string";
1747 static char datatestbuf
[42] = "abc";
1748 static char rwtestbuf
[42];
1749 MEMORY_BASIC_INFORMATION mbi
;
1753 module
= GetModuleHandleA( "ntdll.dll" );
1754 trace("Check flags of the PE header of NTDLL.DLL at %p\n", module
);
1755 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1756 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1757 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1758 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1759 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1760 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1761 ok (mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READONLY
);
1762 ok (mbi
.Type
== MEM_IMAGE
, "mbi.Type is 0x%x, expected 0x%x\n", mbi
.Type
, MEM_IMAGE
);
1764 trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory
);
1765 module
= GetModuleHandleA( "ntdll.dll" );
1766 status
= pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1767 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1768 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1769 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1770 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1771 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1772 ok (mbi
.Protect
== PAGE_EXECUTE_READ
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_EXECUTE_READ
);
1774 trace("Check flags of heap at %p\n", GetProcessHeap());
1775 status
= pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1776 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1777 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1778 ok (mbi
.AllocationProtect
== PAGE_READWRITE
|| mbi
.AllocationProtect
== PAGE_EXECUTE_READWRITE
,
1779 "mbi.AllocationProtect is 0x%x\n", mbi
.AllocationProtect
);
1780 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1781 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_EXECUTE_READWRITE
,
1782 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1784 trace("Check flags of stack at %p\n", stackbuf
);
1785 status
= pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1786 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1787 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1788 ok (mbi
.AllocationProtect
== PAGE_READWRITE
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_READWRITE
);
1789 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1790 ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READWRITE
);
1792 trace("Check flags of read-only data at %p\n", teststring
);
1793 module
= GetModuleHandleA( NULL
);
1794 status
= pNtQueryVirtualMemory(NtCurrentProcess(), teststring
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1795 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1796 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1797 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1798 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1799 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1800 if (mbi
.Protect
!= PAGE_READONLY
)
1801 todo_wine
ok( mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%X\n", mbi
.Protect
, PAGE_READONLY
);
1803 trace("Check flags of read-write data at %p\n", datatestbuf
);
1804 status
= pNtQueryVirtualMemory(NtCurrentProcess(), datatestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1805 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1806 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1807 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1808 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1809 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1810 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
1811 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1813 trace("Check flags of read-write uninitialized data (.bss) at %p\n", rwtestbuf
);
1814 status
= pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1815 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1816 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1817 if (mbi
.AllocationBase
== module
)
1819 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1820 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1821 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
1822 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1824 else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
1827 static void test_affinity(void)
1830 PROCESS_BASIC_INFORMATION pbi
;
1831 DWORD_PTR proc_affinity
, thread_affinity
;
1832 THREAD_BASIC_INFORMATION tbi
;
1836 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1837 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1838 proc_affinity
= pbi
.AffinityMask
;
1839 ok( proc_affinity
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected process affinity\n" );
1840 proc_affinity
= 1 << si
.dwNumberOfProcessors
;
1841 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1842 ok( status
== STATUS_INVALID_PARAMETER
,
1843 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1846 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1847 ok( status
== STATUS_INVALID_PARAMETER
,
1848 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1850 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1851 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1852 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected thread affinity\n" );
1853 thread_affinity
= 1 << si
.dwNumberOfProcessors
;
1854 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1855 ok( status
== STATUS_INVALID_PARAMETER
,
1856 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1857 thread_affinity
= 0;
1858 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1859 ok( status
== STATUS_INVALID_PARAMETER
,
1860 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1862 thread_affinity
= 1;
1863 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1864 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1865 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1866 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1867 ok( tbi
.AffinityMask
== 1, "Unexpected thread affinity\n" );
1869 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
1870 thread_affinity
= ~(DWORD_PTR
)0;
1871 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1872 ok( broken(status
== STATUS_INVALID_PARAMETER
) || status
== STATUS_SUCCESS
,
1873 "Expected STATUS_SUCCESS, got %08x\n", status
);
1875 if (si
.dwNumberOfProcessors
<= 1)
1877 skip("only one processor, skipping affinity testing\n");
1881 /* Test thread affinity mask resulting from "all processors" flag */
1882 if (status
== STATUS_SUCCESS
)
1884 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1885 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1886 ok( broken(tbi
.AffinityMask
== 1) || tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
1887 "Unexpected thread affinity\n" );
1890 skip("Cannot test thread affinity mask for 'all processors' flag\n");
1893 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1894 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1895 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1896 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1897 proc_affinity
= pbi
.AffinityMask
;
1898 ok( proc_affinity
== 2, "Unexpected process affinity\n" );
1899 /* Setting the process affinity changes the thread affinity to match */
1900 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1901 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1902 ok( tbi
.AffinityMask
== 2, "Unexpected thread affinity\n" );
1903 /* The thread affinity is restricted to the process affinity */
1904 thread_affinity
= 1;
1905 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1906 ok( status
== STATUS_INVALID_PARAMETER
,
1907 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1909 proc_affinity
= (1 << si
.dwNumberOfProcessors
) - 1;
1910 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1911 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1912 /* Resetting the process affinity also resets the thread affinity */
1913 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1914 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1915 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
1916 "Unexpected thread affinity\n" );
1919 static void test_NtGetCurrentProcessorNumber(void)
1923 PROCESS_BASIC_INFORMATION pbi
;
1924 THREAD_BASIC_INFORMATION tbi
;
1925 DWORD_PTR old_process_mask
;
1926 DWORD_PTR old_thread_mask
;
1931 if (!pNtGetCurrentProcessorNumber
) {
1932 win_skip("NtGetCurrentProcessorNumber not available\n");
1937 current_cpu
= pNtGetCurrentProcessorNumber();
1938 trace("dwNumberOfProcessors: %d, current processor: %d\n", si
.dwNumberOfProcessors
, current_cpu
);
1940 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1941 old_process_mask
= pbi
.AffinityMask
;
1942 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
1944 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1945 old_thread_mask
= tbi
.AffinityMask
;
1946 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
1948 /* allow the test to run on all processors */
1949 new_mask
= (1 << si
.dwNumberOfProcessors
) - 1;
1950 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &new_mask
, sizeof(new_mask
));
1951 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
1953 for (i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
1956 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &new_mask
, sizeof(new_mask
));
1957 ok(status
== STATUS_SUCCESS
, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i
, status
);
1959 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1960 ok(status
== STATUS_SUCCESS
, "%d: got 0x%x (expected STATUS_SUCCESS)\n", i
, status
);
1962 current_cpu
= pNtGetCurrentProcessorNumber();
1963 ok((current_cpu
== i
), "%d (new_mask 0x%lx): running on processor %d (AffinityMask: 0x%lx)\n",
1964 i
, new_mask
, current_cpu
, tbi
.AffinityMask
);
1967 /* restore old values */
1968 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &old_process_mask
, sizeof(old_process_mask
));
1969 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
1971 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &old_thread_mask
, sizeof(old_thread_mask
));
1972 ok(status
== STATUS_SUCCESS
, "got 0x%x (expected STATUS_SUCCESS)\n", status
);
1975 static DWORD WINAPI
start_address_thread(void *arg
)
1977 PRTL_THREAD_START_ROUTINE entry
;
1983 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
1984 &entry
, sizeof(entry
), &ret
);
1985 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
1986 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
1987 ok(entry
== (void *)start_address_thread
, "expected %p, got %p\n", start_address_thread
, entry
);
1991 static void test_thread_start_address(void)
1993 PRTL_THREAD_START_ROUTINE entry
, expected_entry
;
1994 IMAGE_NT_HEADERS
*nt
;
2000 module
= GetModuleHandleA(0);
2001 ok(module
!= NULL
, "expected non-NULL address for module\n");
2002 nt
= RtlImageNtHeader(module
);
2003 ok(nt
!= NULL
, "expected non-NULL address for NT header\n");
2007 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2008 &entry
, sizeof(entry
), &ret
);
2009 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2010 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2011 expected_entry
= (void *)((char *)module
+ nt
->OptionalHeader
.AddressOfEntryPoint
);
2012 ok(entry
== expected_entry
, "expected %p, got %p\n", expected_entry
, entry
);
2014 entry
= (void *)0xdeadbeef;
2015 status
= pNtSetInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2016 &entry
, sizeof(entry
));
2017 ok(status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, /* >= Vista */
2018 "expected STATUS_SUCCESS or STATUS_INVALID_PARAMETER, got %08x\n", status
);
2020 if (status
== STATUS_SUCCESS
)
2024 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
2025 &entry
, sizeof(entry
), &ret
);
2026 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
2027 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %u bytes\n", ret
);
2028 ok(entry
== (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", entry
);
2031 thread
= CreateThread(NULL
, 0, start_address_thread
, NULL
, 0, NULL
);
2032 ok(thread
!= INVALID_HANDLE_VALUE
, "CreateThread failed with %d\n", GetLastError());
2033 ret
= WaitForSingleObject(thread
, 1000);
2034 ok(ret
== WAIT_OBJECT_0
, "expected WAIT_OBJECT_0, got %u\n", ret
);
2035 CloseHandle(thread
);
2038 static void test_query_data_alignment(void)
2045 status
= pNtQuerySystemInformation(SystemRecommendedSharedDataAlignment
, &value
, sizeof(value
), &ReturnLength
);
2046 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
2047 ok(sizeof(value
) == ReturnLength
, "Inconsistent length %u\n", ReturnLength
);
2048 ok(value
== 64, "Expected 64, got %u\n", value
);
2056 if(!InitFunctionPtrs())
2059 argc
= winetest_get_mainargs(&argv
);
2060 if (argc
>= 3) return; /* Child */
2062 /* NtQuerySystemInformation */
2064 /* 0x0 SystemBasicInformation */
2065 trace("Starting test_query_basic()\n");
2068 /* 0x1 SystemCpuInformation */
2069 trace("Starting test_query_cpu()\n");
2072 /* 0x2 SystemPerformanceInformation */
2073 trace("Starting test_query_performance()\n");
2074 test_query_performance();
2076 /* 0x3 SystemTimeOfDayInformation */
2077 trace("Starting test_query_timeofday()\n");
2078 test_query_timeofday();
2080 /* 0x5 SystemProcessInformation */
2081 trace("Starting test_query_process()\n");
2082 test_query_process();
2084 /* 0x8 SystemProcessorPerformanceInformation */
2085 trace("Starting test_query_procperf()\n");
2086 test_query_procperf();
2088 /* 0xb SystemModuleInformation */
2089 trace("Starting test_query_module()\n");
2090 test_query_module();
2092 /* 0x10 SystemHandleInformation */
2093 trace("Starting test_query_handle()\n");
2094 test_query_handle();
2096 /* 0x15 SystemCacheInformation */
2097 trace("Starting test_query_cache()\n");
2100 /* 0x17 SystemInterruptInformation */
2101 trace("Starting test_query_interrupt()\n");
2102 test_query_interrupt();
2104 /* 0x23 SystemKernelDebuggerInformation */
2105 trace("Starting test_query_kerndebug()\n");
2106 test_query_kerndebug();
2108 /* 0x25 SystemRegistryQuotaInformation */
2109 trace("Starting test_query_regquota()\n");
2110 test_query_regquota();
2112 /* 0x49 SystemLogicalProcessorInformation */
2113 trace("Starting test_query_logicalproc()\n");
2114 test_query_logicalproc();
2115 test_query_logicalprocex();
2117 /* NtPowerInformation */
2119 /* 0xb ProcessorInformation */
2120 trace("Starting test_query_processor_power_info()\n");
2121 test_query_processor_power_info();
2123 /* NtQueryInformationProcess */
2125 /* 0x0 ProcessBasicInformation */
2126 trace("Starting test_query_process_basic()\n");
2127 test_query_process_basic();
2129 /* 0x2 ProcessIoCounters */
2130 trace("Starting test_query_process_io()\n");
2131 test_query_process_io();
2133 /* 0x3 ProcessVmCounters */
2134 trace("Starting test_query_process_vm()\n");
2135 test_query_process_vm();
2137 /* 0x4 ProcessTimes */
2138 trace("Starting test_query_process_times()\n");
2139 test_query_process_times();
2141 /* 0x7 ProcessDebugPort */
2142 trace("Starting test_process_debug_port()\n");
2143 test_query_process_debug_port(argc
, argv
);
2145 /* 0x14 ProcessHandleCount */
2146 trace("Starting test_query_process_handlecount()\n");
2147 test_query_process_handlecount();
2149 /* 0x1A ProcessWow64Information */
2150 trace("Starting test_query_process_wow64()\n");
2151 test_query_process_wow64();
2153 /* 0x1B ProcessImageFileName */
2154 trace("Starting test_query_process_image_file_name()\n");
2155 test_query_process_image_file_name();
2157 /* 0x1E ProcessDebugObjectHandle */
2158 trace("Starting test_query_process_debug_object_handle()\n");
2159 test_query_process_debug_object_handle(argc
, argv
);
2161 /* 0x1F ProcessDebugFlags */
2162 trace("Starting test_process_debug_flags()\n");
2163 test_query_process_debug_flags(argc
, argv
);
2165 /* belongs to its own file */
2166 trace("Starting test_readvirtualmemory()\n");
2167 test_readvirtualmemory();
2169 trace("Starting test_queryvirtualmemory()\n");
2170 test_queryvirtualmemory();
2172 trace("Starting test_mapprotection()\n");
2173 test_mapprotection();
2175 trace("Starting test_affinity()\n");
2178 trace("Starting test_NtGetCurrentProcessorNumber()\n");
2179 test_NtGetCurrentProcessorNumber();
2181 trace("Starting test_thread_start_address()\n");
2182 test_thread_start_address();
2184 trace("Starting test_query_data_alignment()\n");
2185 test_query_data_alignment();