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
* pNtQueryInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
, PULONG
);
27 static NTSTATUS (WINAPI
* pNtQueryInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
, PULONG
);
28 static NTSTATUS (WINAPI
* pNtSetInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
);
29 static NTSTATUS (WINAPI
* pNtSetInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
);
30 static NTSTATUS (WINAPI
* pNtReadVirtualMemory
)(HANDLE
, const void*, void*, SIZE_T
, SIZE_T
*);
31 static NTSTATUS (WINAPI
* pNtQueryVirtualMemory
)(HANDLE
, LPCVOID
, MEMORY_INFORMATION_CLASS
, PVOID
, SIZE_T
, SIZE_T
*);
32 static NTSTATUS (WINAPI
* pNtCreateSection
)(HANDLE
*,ACCESS_MASK
,const OBJECT_ATTRIBUTES
*,const LARGE_INTEGER
*,ULONG
,ULONG
,HANDLE
);
33 static NTSTATUS (WINAPI
* pNtMapViewOfSection
)(HANDLE
,HANDLE
,PVOID
*,ULONG
,SIZE_T
,const LARGE_INTEGER
*,SIZE_T
*,SECTION_INHERIT
,ULONG
,ULONG
);
34 static NTSTATUS (WINAPI
* pNtUnmapViewOfSection
)(HANDLE
,PVOID
);
35 static NTSTATUS (WINAPI
* pNtClose
)(HANDLE
);
36 static BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, PBOOL
);
40 /* one_before_last_pid is used to be able to compare values of a still running process
41 with the output of the test_query_process_times and test_query_process_handlecount tests.
43 static DWORD one_before_last_pid
= 0;
45 #define NTDLL_GET_PROC(func) do { \
46 p ## func = (void*)GetProcAddress(hntdll, #func); \
48 trace("GetProcAddress(%s) failed\n", #func); \
53 static BOOL
InitFunctionPtrs(void)
55 /* All needed functions are NT based, so using GetModuleHandle is a good check */
56 HMODULE hntdll
= GetModuleHandle("ntdll");
59 win_skip("Not running on NT\n");
63 NTDLL_GET_PROC(NtQuerySystemInformation
);
64 NTDLL_GET_PROC(NtQueryInformationProcess
);
65 NTDLL_GET_PROC(NtQueryInformationThread
);
66 NTDLL_GET_PROC(NtSetInformationProcess
);
67 NTDLL_GET_PROC(NtSetInformationThread
);
68 NTDLL_GET_PROC(NtReadVirtualMemory
);
69 NTDLL_GET_PROC(NtQueryVirtualMemory
);
70 NTDLL_GET_PROC(NtClose
);
71 NTDLL_GET_PROC(NtCreateSection
);
72 NTDLL_GET_PROC(NtMapViewOfSection
);
73 NTDLL_GET_PROC(NtUnmapViewOfSection
);
75 pIsWow64Process
= (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
76 if (!pIsWow64Process
|| !pIsWow64Process( GetCurrentProcess(), &is_wow64
)) is_wow64
= FALSE
;
80 static void test_query_basic(void)
84 SYSTEM_BASIC_INFORMATION sbi
;
86 /* This test also covers some basic parameter testing that should be the same for
87 * every information class
90 /* Use a nonexistent info class */
91 trace("Check nonexistent info class\n");
92 status
= pNtQuerySystemInformation(-1, NULL
, 0, NULL
);
93 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
94 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
96 /* Use an existing class but with a zero-length buffer */
97 trace("Check zero-length buffer\n");
98 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, 0, NULL
);
99 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
101 /* Use an existing class, correct length but no SystemInformation buffer */
102 trace("Check no SystemInformation buffer\n");
103 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, sizeof(sbi
), NULL
);
104 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
/* vista */,
105 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got %08x\n", status
);
107 /* Use a existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
108 trace("Check no ReturnLength pointer\n");
109 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), NULL
);
110 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
112 /* Check a too large buffer size */
113 trace("Check a too large buffer size\n");
114 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
) * 2, &ReturnLength
);
115 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
117 /* Finally some correct calls */
118 trace("Check with correct parameters\n");
119 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
120 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
121 ok( sizeof(sbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
123 /* Check if we have some return values */
124 trace("Number of Processors : %d\n", sbi
.NumberOfProcessors
);
125 ok( sbi
.NumberOfProcessors
> 0, "Expected more than 0 processors, got %d\n", sbi
.NumberOfProcessors
);
128 static void test_query_cpu(void)
132 SYSTEM_CPU_INFORMATION sci
;
134 status
= pNtQuerySystemInformation(SystemCpuInformation
, &sci
, sizeof(sci
), &ReturnLength
);
135 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
136 ok( sizeof(sci
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
138 /* Check if we have some return values */
139 trace("Processor FeatureSet : %08x\n", sci
.FeatureSet
);
140 ok( sci
.FeatureSet
!= 0, "Expected some features for this processor, got %08x\n", sci
.FeatureSet
);
143 static void test_query_performance(void)
147 ULONGLONG buffer
[sizeof(SYSTEM_PERFORMANCE_INFORMATION
)/sizeof(ULONGLONG
) + 5];
148 DWORD size
= sizeof(SYSTEM_PERFORMANCE_INFORMATION
);
150 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, 0, &ReturnLength
);
151 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
153 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
154 if (status
== STATUS_INFO_LENGTH_MISMATCH
&& is_wow64
)
156 /* size is larger on wow64 under w2k8/win7 */
158 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
160 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
161 ok( ReturnLength
== size
, "Inconsistent length %d\n", ReturnLength
);
163 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
+ 2, &ReturnLength
);
164 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
165 ok( ReturnLength
== size
|| ReturnLength
== size
+ 2,
166 "Inconsistent length %d\n", ReturnLength
);
168 /* Not return values yet, as struct members are unknown */
171 static void test_query_timeofday(void)
176 /* Copy of our winternl.h structure turned into a private one */
177 typedef struct _SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
{
178 LARGE_INTEGER liKeBootTime
;
179 LARGE_INTEGER liKeSystemTime
;
180 LARGE_INTEGER liExpTimeZoneBias
;
181 ULONG uCurrentTimeZoneId
;
183 } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
, *PSYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
;
185 SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti
;
187 /* The struct size for NT (32 bytes) and Win2K/XP (48 bytes) differ.
189 * Windows 2000 and XP return STATUS_INFO_LENGTH_MISMATCH if the given buffer size is greater
190 * then 48 and 0 otherwise
191 * Windows NT returns STATUS_INFO_LENGTH_MISMATCH when the given buffer size is not correct
194 * Windows 2000 and XP copy the given buffer size into the provided buffer, if the return code is STATUS_SUCCESS
195 * NT only fills the buffer if the return code is STATUS_SUCCESS
199 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
201 if (status
== STATUS_INFO_LENGTH_MISMATCH
)
203 trace("Windows version is NT, we have to cater for differences with W2K/WinXP\n");
205 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 0, &ReturnLength
);
206 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
207 ok( 0 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
209 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
210 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 28, &ReturnLength
);
211 ok(status
== STATUS_SUCCESS
|| broken(status
== STATUS_INFO_LENGTH_MISMATCH
/* NT4 */), "Expected STATUS_SUCCESS, got %08x\n", status
);
212 ok( 0xdeadbeef == sti
.uCurrentTimeZoneId
, "This part of the buffer should not have been filled\n");
214 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 32, &ReturnLength
);
215 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
216 ok( 32 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
220 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 0, &ReturnLength
);
221 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
222 ok( 0 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
224 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
225 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 24, &ReturnLength
);
226 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
227 ok( 24 == ReturnLength
, "ReturnLength should be 24, it is (%d)\n", ReturnLength
);
228 ok( 0xdeadbeef == sti
.uCurrentTimeZoneId
, "This part of the buffer should not have been filled\n");
230 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
231 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 32, &ReturnLength
);
232 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
233 ok( 32 == ReturnLength
, "ReturnLength should be 32, it is (%d)\n", ReturnLength
);
234 ok( 0xdeadbeef != sti
.uCurrentTimeZoneId
, "Buffer should have been partially filled\n");
236 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 49, &ReturnLength
);
237 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
238 ok( ReturnLength
== 0 || ReturnLength
== sizeof(sti
) /* vista */,
239 "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
241 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
242 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
243 ok( sizeof(sti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
246 /* Check if we have some return values */
247 trace("uCurrentTimeZoneId : (%d)\n", sti
.uCurrentTimeZoneId
);
250 static void test_query_process(void)
257 SYSTEM_BASIC_INFORMATION sbi
;
259 /* Copy of our winternl.h structure turned into a private one */
260 typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE
{
261 ULONG NextEntryOffset
;
264 FILETIME ftCreationTime
;
266 FILETIME ftKernelTime
;
267 UNICODE_STRING ProcessName
;
268 DWORD dwBasePriority
;
269 HANDLE UniqueProcessId
;
270 HANDLE ParentProcessId
;
274 VM_COUNTERS vmCounters
;
275 IO_COUNTERS ioCounters
;
276 SYSTEM_THREAD_INFORMATION ti
[1];
277 } SYSTEM_PROCESS_INFORMATION_PRIVATE
, *PSYSTEM_PROCESS_INFORMATION_PRIVATE
;
279 ULONG SystemInformationLength
= sizeof(SYSTEM_PROCESS_INFORMATION_PRIVATE
);
280 SYSTEM_PROCESS_INFORMATION_PRIVATE
*spi
, *spi_buf
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
282 /* Only W2K3 returns the needed length, the rest returns 0, so we have to loop */
286 status
= pNtQuerySystemInformation(SystemProcessInformation
, spi_buf
, SystemInformationLength
, &ReturnLength
);
288 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) break;
290 spi_buf
= HeapReAlloc(GetProcessHeap(), 0, spi_buf
, SystemInformationLength
*= 2);
292 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
295 /* Get the first NextEntryOffset, from this we can deduce the OS version we're running
298 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
300 * NextEntryOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
301 * Wine (with every windows version):
302 * NextEntryOffset for a process is 0 if just this test is running
303 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) +
304 * ProcessName.MaximumLength
305 * if more wine processes are running
307 * Note : On windows the first process is in fact the Idle 'process' with a thread for every processor
310 pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
312 is_nt
= ( spi
->NextEntryOffset
- (sbi
.NumberOfProcessors
* sizeof(SYSTEM_THREAD_INFORMATION
)) == 136);
314 if (is_nt
) win_skip("Windows version is NT, we will skip thread tests\n");
316 /* Check if we have some return values
318 * On windows there will be several processes running (Including the always present Idle and System)
319 * On wine we only have one (if this test is the only wine process running)
322 /* Loop through the processes */
328 last_pid
= (DWORD_PTR
)spi
->UniqueProcessId
;
330 ok( spi
->dwThreadCount
> 0, "Expected some threads for this process, got 0\n");
332 /* Loop through the threads, skip NT4 for now */
337 for ( j
= 0; j
< spi
->dwThreadCount
; j
++)
340 ok ( spi
->ti
[j
].ClientId
.UniqueProcess
== spi
->UniqueProcessId
,
341 "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n",
342 spi
->ti
[j
].ClientId
.UniqueProcess
, spi
->UniqueProcessId
);
346 if (!spi
->NextEntryOffset
) break;
348 one_before_last_pid
= last_pid
;
350 spi
= (SYSTEM_PROCESS_INFORMATION_PRIVATE
*)((char*)spi
+ spi
->NextEntryOffset
);
352 trace("Total number of running processes : %d\n", i
);
353 if (!is_nt
) trace("Total number of running threads : %d\n", k
);
355 if (one_before_last_pid
== 0) one_before_last_pid
= last_pid
;
357 HeapFree( GetProcessHeap(), 0, spi_buf
);
360 static void test_query_procperf(void)
365 SYSTEM_BASIC_INFORMATION sbi
;
366 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
* sppi
;
368 /* Find out the number of processors */
369 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
370 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
371 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
373 sppi
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
375 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, 0, &ReturnLength
);
376 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
378 /* Try it for 1 processor */
379 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
380 sppi
->UserTime
.QuadPart
= 0xdeaddead;
381 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
382 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
,
383 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
), &ReturnLength
);
384 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
385 ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) == ReturnLength
,
386 "Inconsistent length %d\n", ReturnLength
);
387 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
388 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
389 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
391 /* Try it for all processors */
392 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
393 sppi
->UserTime
.QuadPart
= 0xdeaddead;
394 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
395 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
, &ReturnLength
);
396 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
397 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
398 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
399 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
400 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
402 /* A too large given buffer size */
403 sppi
= HeapReAlloc(GetProcessHeap(), 0, sppi
, NeededLength
+ 2);
404 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
405 sppi
->UserTime
.QuadPart
= 0xdeaddead;
406 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
407 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
+ 2, &ReturnLength
);
408 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INFO_LENGTH_MISMATCH
/* vista */,
409 "Expected STATUS_SUCCESS or STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
410 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
411 if (status
== STATUS_SUCCESS
)
413 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
414 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
415 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
417 else /* vista and 2008 */
419 ok (sppi
->KernelTime
.QuadPart
== 0xdeaddead, "KernelTime changed\n");
420 ok (sppi
->UserTime
.QuadPart
== 0xdeaddead, "UserTime changed\n");
421 ok (sppi
->IdleTime
.QuadPart
== 0xdeaddead, "IdleTime changed\n");
424 HeapFree( GetProcessHeap(), 0, sppi
);
427 static void test_query_module(void)
431 ULONG ModuleCount
, i
;
433 ULONG SystemInformationLength
= sizeof(SYSTEM_MODULE_INFORMATION
);
434 SYSTEM_MODULE_INFORMATION
* smi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
437 /* Request the needed length */
438 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, 0, &ReturnLength
);
439 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
440 ok( ReturnLength
> 0, "Expected a ReturnLength to show the needed length\n");
442 SystemInformationLength
= ReturnLength
;
443 smi
= HeapReAlloc(GetProcessHeap(), 0, smi
, SystemInformationLength
);
444 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, SystemInformationLength
, &ReturnLength
);
445 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
447 ModuleCount
= smi
->ModulesCount
;
448 sm
= &smi
->Modules
[0];
449 /* our implementation is a stub for now */
450 ok( ModuleCount
> 0, "Expected some modules to be loaded\n");
452 /* Loop through all the modules/drivers, Wine doesn't get here (yet) */
453 for (i
= 0; i
< ModuleCount
; i
++)
455 ok( i
== sm
->Id
, "Id (%d) should have matched %u\n", sm
->Id
, i
);
459 HeapFree( GetProcessHeap(), 0, smi
);
462 static void test_query_handle(void)
466 ULONG SystemInformationLength
= sizeof(SYSTEM_HANDLE_INFORMATION
);
467 SYSTEM_HANDLE_INFORMATION
* shi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
469 /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
470 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
471 todo_wine
ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
473 SystemInformationLength
= ReturnLength
;
474 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
475 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
476 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) /* vista */
478 ok( status
== STATUS_SUCCESS
,
479 "Expected STATUS_SUCCESS, got %08x\n", status
);
481 /* Check if we have some return values */
482 trace("Number of Handles : %d\n", shi
->Count
);
485 /* our implementation is a stub for now */
486 ok( shi
->Count
> 1, "Expected more than 1 handles, got (%d)\n", shi
->Count
);
489 HeapFree( GetProcessHeap(), 0, shi
);
492 static void test_query_cache(void)
496 SYSTEM_CACHE_INFORMATION sci
;
498 status
= pNtQuerySystemInformation(SystemCacheInformation
, &sci
, 0, &ReturnLength
);
499 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
501 status
= pNtQuerySystemInformation(SystemCacheInformation
, &sci
, sizeof(sci
), &ReturnLength
);
502 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
503 ok( sizeof(sci
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
505 status
= pNtQuerySystemInformation(SystemCacheInformation
, &sci
, sizeof(sci
) + 2, &ReturnLength
);
506 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
507 ok( sizeof(sci
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
510 static void test_query_interrupt(void)
515 SYSTEM_BASIC_INFORMATION sbi
;
516 SYSTEM_INTERRUPT_INFORMATION
* sii
;
518 /* Find out the number of processors */
519 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
520 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
521 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
);
523 sii
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
525 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, 0, &ReturnLength
);
526 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
528 /* Try it for all processors */
529 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, NeededLength
, &ReturnLength
);
530 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
532 /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength
533 * No test added for this as it's highly unlikely that an app depends on this
536 HeapFree( GetProcessHeap(), 0, sii
);
539 static void test_query_kerndebug(void)
543 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi
;
545 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, 0, &ReturnLength
);
546 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
548 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
), &ReturnLength
);
549 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
550 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
552 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
) + 2, &ReturnLength
);
553 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
554 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
557 static void test_query_regquota(void)
561 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi
;
563 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, 0, &ReturnLength
);
564 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
566 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
), &ReturnLength
);
567 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
568 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
570 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
) + 2, &ReturnLength
);
571 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
572 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
575 static void test_query_process_basic(void)
580 typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE
{
581 DWORD_PTR ExitStatus
;
583 DWORD_PTR AffinityMask
;
584 DWORD_PTR BasePriority
;
585 ULONG_PTR UniqueProcessId
;
586 ULONG_PTR InheritedFromUniqueProcessId
;
587 } PROCESS_BASIC_INFORMATION_PRIVATE
, *PPROCESS_BASIC_INFORMATION_PRIVATE
;
589 PROCESS_BASIC_INFORMATION_PRIVATE pbi
;
591 /* This test also covers some basic parameter testing that should be the same for
592 * every information class
595 /* Use a nonexistent info class */
596 trace("Check nonexistent info class\n");
597 status
= pNtQueryInformationProcess(NULL
, -1, NULL
, 0, NULL
);
598 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
599 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
601 /* Do not give a handle and buffer */
602 trace("Check NULL handle and buffer and zero-length buffersize\n");
603 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, 0, NULL
);
604 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
606 /* Use a correct info class and buffer size, but still no handle and buffer */
607 trace("Check NULL handle and buffer\n");
608 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, sizeof(pbi
), NULL
);
609 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
610 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
612 /* Use a correct info class and buffer size, but still no handle */
613 trace("Check NULL handle\n");
614 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
615 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
617 /* Use a greater buffer size */
618 trace("Check NULL handle and too large buffersize\n");
619 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, NULL
);
620 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
622 /* Use no ReturnLength */
623 trace("Check NULL ReturnLength\n");
624 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
625 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
627 /* Finally some correct calls */
628 trace("Check with correct parameters\n");
629 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), &ReturnLength
);
630 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
631 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
633 /* Everything is correct except a too large buffersize */
634 trace("Too large buffersize\n");
635 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, &ReturnLength
);
636 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
637 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
639 /* Check if we have some return values */
640 trace("ProcessID : %lx\n", pbi
.UniqueProcessId
);
641 ok( pbi
.UniqueProcessId
> 0, "Expected a ProcessID > 0, got 0\n");
644 static void test_query_process_vm(void)
649 ULONG old_size
= FIELD_OFFSET(VM_COUNTERS
,PrivatePageCount
);
651 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, NULL
, sizeof(pvi
), NULL
);
652 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
653 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
655 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, &pvi
, old_size
, NULL
);
656 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
658 /* Windows XP and W2K3 will report success for a size of 44 AND 48 !
659 Windows W2K will only report success for 44.
660 For now we only care for 44, which is FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
663 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 24, &ReturnLength
);
664 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
666 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, old_size
, &ReturnLength
);
667 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
668 ok( old_size
== ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
670 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 46, &ReturnLength
);
671 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
672 ok( ReturnLength
== old_size
|| ReturnLength
== sizeof(pvi
), "Inconsistent length %d\n", ReturnLength
);
674 /* Check if we have some return values */
675 trace("WorkingSetSize : %ld\n", pvi
.WorkingSetSize
);
678 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
682 static void test_query_process_io(void)
688 /* NT4 doesn't support this information class, so check for it */
689 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
690 if (status
== STATUS_NOT_SUPPORTED
)
692 win_skip("ProcessIoCounters information class is not supported\n");
696 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, NULL
, sizeof(pii
), NULL
);
697 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
698 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
700 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, &pii
, sizeof(pii
), NULL
);
701 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
703 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, 24, &ReturnLength
);
704 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
706 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
707 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
708 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
710 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
) * 2, &ReturnLength
);
711 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
712 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
714 /* Check if we have some return values */
715 trace("OtherOperationCount : 0x%x%08x\n", (DWORD
)(pii
.OtherOperationCount
>> 32), (DWORD
)pii
.OtherOperationCount
);
718 ok( pii
.OtherOperationCount
> 0, "Expected an OtherOperationCount > 0\n");
722 static void test_query_process_times(void)
727 SYSTEMTIME UTC
, Local
;
728 KERNEL_USER_TIMES spti
;
730 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, NULL
, sizeof(spti
), NULL
);
731 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
732 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
734 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, &spti
, sizeof(spti
), NULL
);
735 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
737 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, 24, &ReturnLength
);
738 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
740 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
743 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
744 process
= GetCurrentProcess();
745 trace("ProcessTimes for current process\n");
748 trace("ProcessTimes for process with ID : %d\n", one_before_last_pid
);
750 status
= pNtQueryInformationProcess( process
, ProcessTimes
, &spti
, sizeof(spti
), &ReturnLength
);
751 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
752 ok( sizeof(spti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
753 CloseHandle(process
);
755 FileTimeToSystemTime((const FILETIME
*)&spti
.CreateTime
, &UTC
);
756 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
757 trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
758 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
760 FileTimeToSystemTime((const FILETIME
*)&spti
.ExitTime
, &UTC
);
761 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
762 trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
763 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
765 FileTimeToSystemTime((const FILETIME
*)&spti
.KernelTime
, &Local
);
766 trace("KernelTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
768 FileTimeToSystemTime((const FILETIME
*)&spti
.UserTime
, &Local
);
769 trace("UserTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
771 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, sizeof(spti
) * 2, &ReturnLength
);
772 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
773 ok( sizeof(spti
) == ReturnLength
||
774 ReturnLength
== 0 /* vista */ ||
775 broken(is_wow64
), /* returns garbage on wow64 */
776 "Inconsistent length %d\n", ReturnLength
);
779 static void test_query_process_debug_port(int argc
, char **argv
)
781 DWORD_PTR debug_port
= 0xdeadbeef;
782 char cmdline
[MAX_PATH
];
783 PROCESS_INFORMATION pi
;
784 STARTUPINFO si
= { 0 };
788 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
791 ret
= CreateProcess(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
, NULL
, &si
, &pi
);
792 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
795 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
797 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
799 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
800 NULL
, sizeof(debug_port
), NULL
);
801 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
,
802 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
804 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
805 NULL
, sizeof(debug_port
), NULL
);
806 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
808 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
809 &debug_port
, sizeof(debug_port
), NULL
);
810 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
812 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
813 &debug_port
, sizeof(debug_port
) - 1, NULL
);
814 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
816 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
817 &debug_port
, sizeof(debug_port
) + 1, NULL
);
818 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
820 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
821 &debug_port
, sizeof(debug_port
), NULL
);
822 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
823 ok(debug_port
== 0, "Expected port 0, got %#lx.\n", debug_port
);
825 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugPort
,
826 &debug_port
, sizeof(debug_port
), NULL
);
827 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
828 ok(debug_port
== ~(DWORD_PTR
)0, "Expected port %#lx, got %#lx.\n", ~(DWORD_PTR
)0, debug_port
);
834 ret
= WaitForDebugEvent(&ev
, INFINITE
);
835 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
838 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
840 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
841 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
845 ret
= CloseHandle(pi
.hThread
);
846 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
847 ret
= CloseHandle(pi
.hProcess
);
848 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
851 static void test_query_process_handlecount(void)
856 BYTE buffer
[2 * sizeof(DWORD
)];
859 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, NULL
, sizeof(handlecount
), NULL
);
860 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
861 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
863 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), NULL
);
864 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
866 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, &handlecount
, 2, &ReturnLength
);
867 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
869 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
872 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
873 process
= GetCurrentProcess();
874 trace("ProcessHandleCount for current process\n");
877 trace("ProcessHandleCount for process with ID : %d\n", one_before_last_pid
);
879 status
= pNtQueryInformationProcess( process
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), &ReturnLength
);
880 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
881 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
882 CloseHandle(process
);
884 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, buffer
, sizeof(buffer
), &ReturnLength
);
885 ok( status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_SUCCESS
,
886 "Expected STATUS_INFO_LENGTH_MISMATCH or STATUS_SUCCESS, got %08x\n", status
);
887 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
889 /* Check if we have some return values */
890 trace("HandleCount : %d\n", handlecount
);
893 ok( handlecount
> 0, "Expected some handles, got 0\n");
897 static void test_query_process_image_file_name(void)
901 UNICODE_STRING image_file_name
;
906 status
= pNtQueryInformationProcess(NULL
, ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), NULL
);
907 if (status
== STATUS_INVALID_INFO_CLASS
)
909 win_skip("ProcessImageFileName is not supported\n");
912 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
914 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, 2, &ReturnLength
);
915 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
917 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), &ReturnLength
);
918 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
920 buffer
= HeapAlloc(GetProcessHeap(), 0, ReturnLength
);
921 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, buffer
, ReturnLength
, &ReturnLength
);
922 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
923 memcpy(&image_file_name
, buffer
, sizeof(image_file_name
));
924 len
= WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), NULL
, 0, NULL
, NULL
);
925 file_nameA
= HeapAlloc(GetProcessHeap(), 0, len
+ 1);
926 WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), file_nameA
, len
, NULL
, NULL
);
927 file_nameA
[len
] = '\0';
928 HeapFree(GetProcessHeap(), 0, buffer
);
929 trace("process image file name: %s\n", file_nameA
);
930 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
);
931 HeapFree(GetProcessHeap(), 0, file_nameA
);
934 static void test_query_process_debug_object_handle(int argc
, char **argv
)
936 char cmdline
[MAX_PATH
];
937 STARTUPINFO si
= {0};
938 PROCESS_INFORMATION pi
;
943 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
946 ret
= CreateProcess(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
,
948 ok(ret
, "CreateProcess failed with last error %u\n", GetLastError());
951 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
953 if (status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
)
955 win_skip("ProcessDebugObjectHandle is not supported\n");
958 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
959 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n",
962 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
,
963 sizeof(debug_object
), NULL
);
964 ok(status
== STATUS_INVALID_HANDLE
||
965 status
== STATUS_ACCESS_VIOLATION
, /* XP */
966 "Expected NtQueryInformationProcess to return STATUS_INVALID_HANDLE, got 0x%08x\n", status
);
968 status
= pNtQueryInformationProcess(GetCurrentProcess(),
969 ProcessDebugObjectHandle
, NULL
, sizeof(debug_object
), NULL
);
970 ok(status
== STATUS_ACCESS_VIOLATION
,
971 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
973 status
= pNtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
,
974 &debug_object
, sizeof(debug_object
), NULL
);
975 ok(status
== STATUS_INVALID_HANDLE
,
976 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08x\n", status
);
978 status
= pNtQueryInformationProcess(GetCurrentProcess(),
979 ProcessDebugObjectHandle
, &debug_object
,
980 sizeof(debug_object
) - 1, NULL
);
981 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
982 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
984 status
= pNtQueryInformationProcess(GetCurrentProcess(),
985 ProcessDebugObjectHandle
, &debug_object
,
986 sizeof(debug_object
) + 1, NULL
);
987 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
988 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08x\n", status
);
990 debug_object
= (HANDLE
)0xdeadbeef;
991 status
= pNtQueryInformationProcess(GetCurrentProcess(),
992 ProcessDebugObjectHandle
, &debug_object
,
993 sizeof(debug_object
), NULL
);
994 ok(status
== STATUS_PORT_NOT_SET
,
995 "Expected NtQueryInformationProcess to return STATUS_PORT_NOT_SET, got 0x%08x\n", status
);
996 ok(debug_object
== NULL
||
997 broken(debug_object
== (HANDLE
)0xdeadbeef), /* Wow64 */
998 "Expected debug object handle to be NULL, got %p\n", debug_object
);
1000 debug_object
= (HANDLE
)0xdeadbeef;
1001 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugObjectHandle
,
1002 &debug_object
, sizeof(debug_object
), NULL
);
1004 ok(status
== STATUS_SUCCESS
,
1005 "Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08x\n", status
);
1007 ok(debug_object
!= NULL
,
1008 "Expected debug object handle to be non-NULL, got %p\n", debug_object
);
1014 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1015 ok(ret
, "WaitForDebugEvent failed with last error %u\n", GetLastError());
1018 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1020 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1021 ok(ret
, "ContinueDebugEvent failed with last error %u\n", GetLastError());
1025 ret
= CloseHandle(pi
.hThread
);
1026 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1027 ret
= CloseHandle(pi
.hProcess
);
1028 ok(ret
, "CloseHandle failed with last error %u\n", GetLastError());
1031 static void test_query_process_debug_flags(int argc
, char **argv
)
1033 DWORD debug_flags
= 0xdeadbeef;
1034 char cmdline
[MAX_PATH
];
1035 PROCESS_INFORMATION pi
;
1036 STARTUPINFO si
= { 0 };
1040 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
1043 ret
= CreateProcess(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
, NULL
, NULL
, &si
, &pi
);
1044 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
1047 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
,
1049 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1051 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
,
1052 NULL
, sizeof(debug_flags
), NULL
);
1053 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* W7PROX64 (32-bit) */,
1054 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
1056 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1057 NULL
, sizeof(debug_flags
), NULL
);
1058 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1060 status
= pNtQueryInformationProcess(NULL
, ProcessDebugFlags
,
1061 &debug_flags
, sizeof(debug_flags
), NULL
);
1062 ok(status
== STATUS_INVALID_HANDLE
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
1064 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1065 &debug_flags
, sizeof(debug_flags
) - 1, NULL
);
1066 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1068 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1069 &debug_flags
, sizeof(debug_flags
) + 1, NULL
);
1070 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
1072 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
1073 &debug_flags
, sizeof(debug_flags
), NULL
);
1074 ok(!status
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "NtQueryInformationProcess failed, status %#x.\n", status
);
1075 ok(debug_flags
== TRUE
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "Expected flag TRUE, got %x.\n", debug_flags
);
1077 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
1078 &debug_flags
, sizeof(debug_flags
), NULL
);
1079 ok(!status
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "NtQueryInformationProcess failed, status %#x.\n", status
);
1080 ok(debug_flags
== FALSE
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* NT4 */, "Expected flag FALSE, got %x.\n", debug_flags
);
1086 ret
= WaitForDebugEvent(&ev
, INFINITE
);
1087 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
1090 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
1092 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
1093 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
1097 ret
= CloseHandle(pi
.hThread
);
1098 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1099 ret
= CloseHandle(pi
.hProcess
);
1100 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
1103 static void test_readvirtualmemory(void)
1108 static const char teststring
[] = "test string";
1111 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1112 ok(process
!= 0, "Expected to be able to open own process for reading memory\n");
1114 /* normal operation */
1115 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, &readcount
);
1116 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1117 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1118 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1120 /* no number of bytes */
1121 memset(buffer
, 0, 12);
1122 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, NULL
);
1123 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1124 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1126 /* illegal remote address */
1128 status
= pNtReadVirtualMemory(process
, (void *) 0x1234, buffer
, 12, &readcount
);
1129 ok( status
== STATUS_PARTIAL_COPY
|| broken(status
== STATUS_ACCESS_VIOLATION
), "Expected STATUS_PARTIAL_COPY, got %08x\n", status
);
1130 if (status
== STATUS_PARTIAL_COPY
)
1131 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1135 status
= pNtReadVirtualMemory(0, teststring
, buffer
, 12, &readcount
);
1136 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
1137 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1139 /* pseudo handle for current process*/
1140 memset(buffer
, 0, 12);
1141 status
= pNtReadVirtualMemory((HANDLE
)-1, teststring
, buffer
, 12, &readcount
);
1142 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1143 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
1144 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
1146 /* illegal local address */
1147 status
= pNtReadVirtualMemory(process
, teststring
, (void *)0x1234, 12, &readcount
);
1148 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
1149 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
1151 CloseHandle(process
);
1154 static void test_mapprotection(void)
1158 MEMORY_BASIC_INFORMATION info
;
1159 ULONG oldflags
, flagsize
, flags
= MEM_EXECUTE_OPTION_ENABLE
;
1160 LARGE_INTEGER size
, offset
;
1162 SIZE_T retlen
, count
;
1166 skip("No NtClose ... Win98\n");
1169 /* Switch to being a noexec unaware process */
1170 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof (oldflags
), &flagsize
);
1171 if (status
== STATUS_INVALID_PARAMETER
) {
1172 skip("Invalid Parameter on ProcessExecuteFlags query?\n");
1175 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1176 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &flags
, sizeof(flags
) );
1177 ok( (status
== STATUS_SUCCESS
) || (status
== STATUS_INVALID_INFO_CLASS
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1179 size
.u
.LowPart
= 0x1000;
1180 size
.u
.HighPart
= 0;
1181 status
= pNtCreateSection ( &h
,
1182 STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
,
1186 SEC_COMMIT
| SEC_NOCACHE
,
1189 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1191 offset
.u
.LowPart
= 0;
1192 offset
.u
.HighPart
= 0;
1195 status
= pNtMapViewOfSection ( h
, GetCurrentProcess(), &addr
, 0, 0, &offset
, &count
, ViewShare
, 0, PAGE_READWRITE
);
1196 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1197 #if defined(__x86_64__) || defined(__i386__)
1198 memset (addr
, 0xc3, 1); /* lret ... in both i386 and x86_64 */
1199 trace("trying to execute code in the readwrite only mapped anon file...\n");
1201 trace("...done.\n");
1204 status
= pNtQueryVirtualMemory( GetCurrentProcess(), addr
, MemoryBasicInformation
, &info
, sizeof(info
), &retlen
);
1205 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1206 ok( retlen
== sizeof(info
), "Expected STATUS_SUCCESS, got %08x\n", status
);
1207 ok(info
.Protect
== PAGE_READWRITE
, "addr.Protect is not PAGE_READWRITE, but 0x%x\n", info
.Protect
);
1209 status
= pNtUnmapViewOfSection (GetCurrentProcess(), addr
);
1210 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1214 pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof(oldflags
) );
1217 static void test_queryvirtualmemory(void)
1221 static const char teststring
[] = "test string";
1222 static char datatestbuf
[42] = "abc";
1223 static char rwtestbuf
[42];
1224 MEMORY_BASIC_INFORMATION mbi
;
1228 module
= GetModuleHandle( "ntdll.dll" );
1229 trace("Check flags of the PE header of NTDLL.DLL at %p\n", module
);
1230 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1231 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1232 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1233 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1234 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1235 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1236 ok (mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READONLY
);
1237 ok (mbi
.Type
== MEM_IMAGE
, "mbi.Type is 0x%x, expected 0x%x\n", mbi
.Type
, MEM_IMAGE
);
1239 trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory
);
1240 module
= GetModuleHandle( "ntdll.dll" );
1241 status
= pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1242 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1243 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1244 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1245 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1246 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1247 ok (mbi
.Protect
== PAGE_EXECUTE_READ
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_EXECUTE_READ
);
1249 trace("Check flags of heap at %p\n", GetProcessHeap());
1250 status
= pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1251 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1252 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1253 ok (mbi
.AllocationProtect
== PAGE_READWRITE
|| mbi
.AllocationProtect
== PAGE_EXECUTE_READWRITE
,
1254 "mbi.AllocationProtect is 0x%x\n", mbi
.AllocationProtect
);
1255 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1256 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_EXECUTE_READWRITE
,
1257 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1259 trace("Check flags of stack at %p\n", stackbuf
);
1260 status
= pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1261 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1262 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1263 ok (mbi
.AllocationProtect
== PAGE_READWRITE
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_READWRITE
);
1264 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1265 ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READWRITE
);
1267 trace("Check flags of read-only data at %p\n", teststring
);
1268 module
= GetModuleHandle( NULL
);
1269 status
= pNtQueryVirtualMemory(NtCurrentProcess(), teststring
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1270 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1271 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1272 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1273 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1274 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1275 if (mbi
.Protect
!= PAGE_READONLY
)
1276 todo_wine
ok( mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%X\n", mbi
.Protect
, PAGE_READONLY
);
1278 trace("Check flags of read-write data at %p\n", datatestbuf
);
1279 status
= pNtQueryVirtualMemory(NtCurrentProcess(), datatestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1280 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1281 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1282 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
1283 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1284 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1285 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
1286 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1288 trace("Check flags of read-write uninitialized data (.bss) at %p\n", rwtestbuf
);
1289 status
= pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1290 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1291 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1292 if (mbi
.AllocationBase
== module
)
1294 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1295 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1296 ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%x, expected 0x%X\n", mbi
.Protect
, PAGE_READWRITE
);
1298 else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
1301 static void test_affinity(void)
1304 PROCESS_BASIC_INFORMATION pbi
;
1305 DWORD_PTR proc_affinity
, thread_affinity
;
1306 THREAD_BASIC_INFORMATION tbi
;
1310 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1311 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1312 proc_affinity
= (DWORD_PTR
)pbi
.Reserved2
[0];
1313 ok( proc_affinity
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected process affinity\n" );
1314 proc_affinity
= 1 << si
.dwNumberOfProcessors
;
1315 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1316 ok( status
== STATUS_INVALID_PARAMETER
,
1317 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1320 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1321 ok( status
== STATUS_INVALID_PARAMETER
,
1322 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1324 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1325 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1326 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected thread affinity\n" );
1327 thread_affinity
= 1 << si
.dwNumberOfProcessors
;
1328 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1329 ok( status
== STATUS_INVALID_PARAMETER
,
1330 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1331 thread_affinity
= 0;
1332 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1333 ok( status
== STATUS_INVALID_PARAMETER
,
1334 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1336 thread_affinity
= 1;
1337 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1338 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1339 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1340 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1341 ok( tbi
.AffinityMask
== 1, "Unexpected thread affinity\n" );
1343 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
1344 thread_affinity
= ~(DWORD_PTR
)0;
1345 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1346 ok( broken(status
== STATUS_INVALID_PARAMETER
) || status
== STATUS_SUCCESS
,
1347 "Expected STATUS_SUCCESS, got %08x\n", status
);
1349 if (si
.dwNumberOfProcessors
<= 1)
1351 skip("only one processor, skipping affinity testing\n");
1355 /* Test thread affinity mask resulting from "all processors" flag */
1356 if (status
== STATUS_SUCCESS
)
1358 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1359 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1360 ok( broken(tbi
.AffinityMask
== 1) || tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
1361 "Unexpected thread affinity\n" );
1364 skip("Cannot test thread affinity mask for 'all processors' flag\n");
1367 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1368 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1369 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1370 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1371 proc_affinity
= (DWORD_PTR
)pbi
.Reserved2
[0];
1372 ok( proc_affinity
== 2, "Unexpected process affinity\n" );
1373 /* Setting the process affinity changes the thread affinity to match */
1374 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1375 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1376 ok( tbi
.AffinityMask
== 2, "Unexpected thread affinity\n" );
1377 /* The thread affinity is restricted to the process affinity */
1378 thread_affinity
= 1;
1379 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1380 ok( status
== STATUS_INVALID_PARAMETER
,
1381 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1383 proc_affinity
= (1 << si
.dwNumberOfProcessors
) - 1;
1384 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1385 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1386 /* Resetting the process affinity also resets the thread affinity */
1387 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1388 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1389 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
1390 "Unexpected thread affinity\n" );
1398 if(!InitFunctionPtrs())
1401 argc
= winetest_get_mainargs(&argv
);
1402 if (argc
>= 3) return; /* Child */
1404 /* NtQuerySystemInformation */
1406 /* 0x0 SystemBasicInformation */
1407 trace("Starting test_query_basic()\n");
1410 /* 0x1 SystemCpuInformation */
1411 trace("Starting test_query_cpu()\n");
1414 /* 0x2 SystemPerformanceInformation */
1415 trace("Starting test_query_performance()\n");
1416 test_query_performance();
1418 /* 0x3 SystemTimeOfDayInformation */
1419 trace("Starting test_query_timeofday()\n");
1420 test_query_timeofday();
1422 /* 0x5 SystemProcessInformation */
1423 trace("Starting test_query_process()\n");
1424 test_query_process();
1426 /* 0x8 SystemProcessorPerformanceInformation */
1427 trace("Starting test_query_procperf()\n");
1428 test_query_procperf();
1430 /* 0xb SystemModuleInformation */
1431 trace("Starting test_query_module()\n");
1432 test_query_module();
1434 /* 0x10 SystemHandleInformation */
1435 trace("Starting test_query_handle()\n");
1436 test_query_handle();
1438 /* 0x15 SystemCacheInformation */
1439 trace("Starting test_query_cache()\n");
1442 /* 0x17 SystemInterruptInformation */
1443 trace("Starting test_query_interrupt()\n");
1444 test_query_interrupt();
1446 /* 0x23 SystemKernelDebuggerInformation */
1447 trace("Starting test_query_kerndebug()\n");
1448 test_query_kerndebug();
1450 /* 0x25 SystemRegistryQuotaInformation */
1451 trace("Starting test_query_regquota()\n");
1452 test_query_regquota();
1454 /* NtQueryInformationProcess */
1456 /* 0x0 ProcessBasicInformation */
1457 trace("Starting test_query_process_basic()\n");
1458 test_query_process_basic();
1460 /* 0x2 ProcessIoCounters */
1461 trace("Starting test_query_process_io()\n");
1462 test_query_process_io();
1464 /* 0x3 ProcessVmCounters */
1465 trace("Starting test_query_process_vm()\n");
1466 test_query_process_vm();
1468 /* 0x4 ProcessTimes */
1469 trace("Starting test_query_process_times()\n");
1470 test_query_process_times();
1472 /* 0x7 ProcessDebugPort */
1473 trace("Starting test_process_debug_port()\n");
1474 test_query_process_debug_port(argc
, argv
);
1476 /* 0x14 ProcessHandleCount */
1477 trace("Starting test_query_process_handlecount()\n");
1478 test_query_process_handlecount();
1480 /* 0x1B ProcessImageFileName */
1481 trace("Starting test_query_process_image_file_name()\n");
1482 test_query_process_image_file_name();
1484 /* 0x1E ProcessDebugObjectHandle */
1485 trace("Starting test_query_process_debug_object_handle()\n");
1486 test_query_process_debug_object_handle(argc
, argv
);
1488 /* 0x1F ProcessDebugFlags */
1489 trace("Starting test_process_debug_flags()\n");
1490 test_query_process_debug_flags(argc
, argv
);
1492 /* belongs into it's own file */
1493 trace("Starting test_readvirtualmemory()\n");
1494 test_readvirtualmemory();
1496 trace("Starting test_queryvirtualmemory()\n");
1497 test_queryvirtualmemory();
1499 trace("Starting test_mapprotection()\n");
1500 test_mapprotection();
1502 trace("Starting test_affinity()\n");