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 BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, PBOOL
);
36 /* one_before_last_pid is used to be able to compare values of a still running process
37 with the output of the test_query_process_times and test_query_process_handlecount tests.
39 static DWORD one_before_last_pid
= 0;
41 #define NTDLL_GET_PROC(func) do { \
42 p ## func = (void*)GetProcAddress(hntdll, #func); \
44 trace("GetProcAddress(%s) failed\n", #func); \
49 static BOOL
InitFunctionPtrs(void)
51 /* All needed functions are NT based, so using GetModuleHandle is a good check */
52 HMODULE hntdll
= GetModuleHandle("ntdll");
55 win_skip("Not running on NT\n");
59 NTDLL_GET_PROC(NtQuerySystemInformation
);
60 NTDLL_GET_PROC(NtQueryInformationProcess
);
61 NTDLL_GET_PROC(NtQueryInformationThread
);
62 NTDLL_GET_PROC(NtSetInformationProcess
);
63 NTDLL_GET_PROC(NtSetInformationThread
);
64 NTDLL_GET_PROC(NtReadVirtualMemory
);
65 NTDLL_GET_PROC(NtQueryVirtualMemory
);
67 pIsWow64Process
= (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
68 if (!pIsWow64Process
|| !pIsWow64Process( GetCurrentProcess(), &is_wow64
)) is_wow64
= FALSE
;
72 static void test_query_basic(void)
76 SYSTEM_BASIC_INFORMATION sbi
;
78 /* This test also covers some basic parameter testing that should be the same for
79 * every information class
82 /* Use a nonexistent info class */
83 trace("Check nonexistent info class\n");
84 status
= pNtQuerySystemInformation(-1, NULL
, 0, NULL
);
85 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
86 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
88 /* Use an existing class but with a zero-length buffer */
89 trace("Check zero-length buffer\n");
90 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, 0, NULL
);
91 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
93 /* Use an existing class, correct length but no SystemInformation buffer */
94 trace("Check no SystemInformation buffer\n");
95 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, sizeof(sbi
), NULL
);
96 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
/* vista */,
97 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got %08x\n", status
);
99 /* Use a existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
100 trace("Check no ReturnLength pointer\n");
101 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), NULL
);
102 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
104 /* Check a too large buffer size */
105 trace("Check a too large buffer size\n");
106 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
) * 2, &ReturnLength
);
107 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
109 /* Finally some correct calls */
110 trace("Check with correct parameters\n");
111 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
112 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
113 ok( sizeof(sbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
115 /* Check if we have some return values */
116 trace("Number of Processors : %d\n", sbi
.NumberOfProcessors
);
117 ok( sbi
.NumberOfProcessors
> 0, "Expected more than 0 processors, got %d\n", sbi
.NumberOfProcessors
);
120 static void test_query_cpu(void)
124 SYSTEM_CPU_INFORMATION sci
;
126 status
= pNtQuerySystemInformation(SystemCpuInformation
, &sci
, sizeof(sci
), &ReturnLength
);
127 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
128 ok( sizeof(sci
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
130 /* Check if we have some return values */
131 trace("Processor FeatureSet : %08x\n", sci
.FeatureSet
);
132 ok( sci
.FeatureSet
!= 0, "Expected some features for this processor, got %08x\n", sci
.FeatureSet
);
135 static void test_query_performance(void)
139 ULONGLONG buffer
[sizeof(SYSTEM_PERFORMANCE_INFORMATION
)/sizeof(ULONGLONG
) + 5];
140 DWORD size
= sizeof(SYSTEM_PERFORMANCE_INFORMATION
);
142 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, 0, &ReturnLength
);
143 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
145 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
146 if (status
== STATUS_INFO_LENGTH_MISMATCH
&& is_wow64
)
148 /* size is larger on wow64 under w2k8/win7 */
150 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
152 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
153 ok( ReturnLength
== size
, "Inconsistent length %d\n", ReturnLength
);
155 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
+ 2, &ReturnLength
);
156 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
157 ok( ReturnLength
== size
|| ReturnLength
== size
+ 2,
158 "Inconsistent length %d\n", ReturnLength
);
160 /* Not return values yet, as struct members are unknown */
163 static void test_query_timeofday(void)
168 /* Copy of our winternl.h structure turned into a private one */
169 typedef struct _SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
{
170 LARGE_INTEGER liKeBootTime
;
171 LARGE_INTEGER liKeSystemTime
;
172 LARGE_INTEGER liExpTimeZoneBias
;
173 ULONG uCurrentTimeZoneId
;
175 } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
, *PSYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
;
177 SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti
;
179 /* The struct size for NT (32 bytes) and Win2K/XP (48 bytes) differ.
181 * Windows 2000 and XP return STATUS_INFO_LENGTH_MISMATCH if the given buffer size is greater
182 * then 48 and 0 otherwise
183 * Windows NT returns STATUS_INFO_LENGTH_MISMATCH when the given buffer size is not correct
186 * Windows 2000 and XP copy the given buffer size into the provided buffer, if the return code is STATUS_SUCCESS
187 * NT only fills the buffer if the return code is STATUS_SUCCESS
191 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
193 if (status
== STATUS_INFO_LENGTH_MISMATCH
)
195 trace("Windows version is NT, we have to cater for differences with W2K/WinXP\n");
197 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 0, &ReturnLength
);
198 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
199 ok( 0 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
201 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
202 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 28, &ReturnLength
);
203 ok( 0xdeadbeef == sti
.uCurrentTimeZoneId
, "This part of the buffer should not have been filled\n");
205 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 32, &ReturnLength
);
206 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
207 ok( 32 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
211 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 0, &ReturnLength
);
212 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
213 ok( 0 == ReturnLength
, "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
215 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
216 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 24, &ReturnLength
);
217 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
218 ok( 24 == ReturnLength
, "ReturnLength should be 24, it is (%d)\n", ReturnLength
);
219 ok( 0xdeadbeef == sti
.uCurrentTimeZoneId
, "This part of the buffer should not have been filled\n");
221 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
222 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 32, &ReturnLength
);
223 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
224 ok( 32 == ReturnLength
, "ReturnLength should be 32, it is (%d)\n", ReturnLength
);
225 ok( 0xdeadbeef != sti
.uCurrentTimeZoneId
, "Buffer should have been partially filled\n");
227 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, 49, &ReturnLength
);
228 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
229 ok( ReturnLength
== 0 || ReturnLength
== sizeof(sti
) /* vista */,
230 "ReturnLength should be 0, it is (%d)\n", ReturnLength
);
232 status
= pNtQuerySystemInformation(SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
233 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
234 ok( sizeof(sti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
237 /* Check if we have some return values */
238 trace("uCurrentTimeZoneId : (%d)\n", sti
.uCurrentTimeZoneId
);
241 static void test_query_process(void)
248 SYSTEM_BASIC_INFORMATION sbi
;
250 /* Copy of our winternl.h structure turned into a private one */
251 typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE
{
252 ULONG NextEntryOffset
;
255 FILETIME ftCreationTime
;
257 FILETIME ftKernelTime
;
258 UNICODE_STRING ProcessName
;
259 DWORD dwBasePriority
;
260 HANDLE UniqueProcessId
;
261 HANDLE ParentProcessId
;
265 VM_COUNTERS vmCounters
;
266 IO_COUNTERS ioCounters
;
267 SYSTEM_THREAD_INFORMATION ti
[1];
268 } SYSTEM_PROCESS_INFORMATION_PRIVATE
, *PSYSTEM_PROCESS_INFORMATION_PRIVATE
;
270 ULONG SystemInformationLength
= sizeof(SYSTEM_PROCESS_INFORMATION_PRIVATE
);
271 SYSTEM_PROCESS_INFORMATION_PRIVATE
*spi
, *spi_buf
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
273 /* Only W2K3 returns the needed length, the rest returns 0, so we have to loop */
277 status
= pNtQuerySystemInformation(SystemProcessInformation
, spi_buf
, SystemInformationLength
, &ReturnLength
);
279 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) break;
281 spi_buf
= HeapReAlloc(GetProcessHeap(), 0, spi_buf
, SystemInformationLength
*= 2);
283 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
286 /* Get the first NextEntryOffset, from this we can deduce the OS version we're running
289 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
291 * NextEntryOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
292 * Wine (with every windows version):
293 * NextEntryOffset for a process is 0 if just this test is running
294 * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) +
295 * ProcessName.MaximumLength
296 * if more wine processes are running
298 * Note : On windows the first process is in fact the Idle 'process' with a thread for every processor
301 pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
303 is_nt
= ( spi
->NextEntryOffset
- (sbi
.NumberOfProcessors
* sizeof(SYSTEM_THREAD_INFORMATION
)) == 136);
305 if (is_nt
) win_skip("Windows version is NT, we will skip thread tests\n");
307 /* Check if we have some return values
309 * On windows there will be several processes running (Including the always present Idle and System)
310 * On wine we only have one (if this test is the only wine process running)
313 /* Loop through the processes */
319 last_pid
= (DWORD_PTR
)spi
->UniqueProcessId
;
321 ok( spi
->dwThreadCount
> 0, "Expected some threads for this process, got 0\n");
323 /* Loop through the threads, skip NT4 for now */
328 for ( j
= 0; j
< spi
->dwThreadCount
; j
++)
331 ok ( spi
->ti
[j
].ClientId
.UniqueProcess
== spi
->UniqueProcessId
,
332 "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n",
333 spi
->ti
[j
].ClientId
.UniqueProcess
, spi
->UniqueProcessId
);
337 if (!spi
->NextEntryOffset
) break;
339 one_before_last_pid
= last_pid
;
341 spi
= (SYSTEM_PROCESS_INFORMATION_PRIVATE
*)((char*)spi
+ spi
->NextEntryOffset
);
343 trace("Total number of running processes : %d\n", i
);
344 if (!is_nt
) trace("Total number of running threads : %d\n", k
);
346 if (one_before_last_pid
== 0) one_before_last_pid
= last_pid
;
348 HeapFree( GetProcessHeap(), 0, spi_buf
);
351 static void test_query_procperf(void)
356 SYSTEM_BASIC_INFORMATION sbi
;
357 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
* sppi
;
359 /* Find out the number of processors */
360 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
361 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
363 sppi
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
365 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, 0, &ReturnLength
);
366 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
368 /* Try it for 1 processor */
369 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
370 sppi
->UserTime
.QuadPart
= 0xdeaddead;
371 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
372 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
,
373 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
), &ReturnLength
);
374 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
375 ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) == ReturnLength
,
376 "Inconsistent length %d\n", ReturnLength
);
377 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
378 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
379 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
381 /* Try it for all processors */
382 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
383 sppi
->UserTime
.QuadPart
= 0xdeaddead;
384 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
385 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
, &ReturnLength
);
386 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
387 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
388 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
389 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
390 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
392 /* A too large given buffer size */
393 sppi
= HeapReAlloc(GetProcessHeap(), 0, sppi
, NeededLength
+ 2);
394 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
395 sppi
->UserTime
.QuadPart
= 0xdeaddead;
396 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
397 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
+ 2, &ReturnLength
);
398 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INFO_LENGTH_MISMATCH
/* vista */,
399 "Expected STATUS_SUCCESS or STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
400 ok( NeededLength
== ReturnLength
, "Inconsistent length (%d) <-> (%d)\n", NeededLength
, ReturnLength
);
401 if (status
== STATUS_SUCCESS
)
403 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
404 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
405 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
407 else /* vista and 2008 */
409 ok (sppi
->KernelTime
.QuadPart
== 0xdeaddead, "KernelTime changed\n");
410 ok (sppi
->UserTime
.QuadPart
== 0xdeaddead, "UserTime changed\n");
411 ok (sppi
->IdleTime
.QuadPart
== 0xdeaddead, "IdleTime changed\n");
414 HeapFree( GetProcessHeap(), 0, sppi
);
417 static void test_query_module(void)
421 ULONG ModuleCount
, i
;
423 ULONG SystemInformationLength
= sizeof(SYSTEM_MODULE_INFORMATION
);
424 SYSTEM_MODULE_INFORMATION
* smi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
427 /* Request the needed length */
428 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, 0, &ReturnLength
);
429 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
430 ok( ReturnLength
> 0, "Expected a ReturnLength to show the needed length\n");
432 SystemInformationLength
= ReturnLength
;
433 smi
= HeapReAlloc(GetProcessHeap(), 0, smi
, SystemInformationLength
);
434 status
= pNtQuerySystemInformation(SystemModuleInformation
, smi
, SystemInformationLength
, &ReturnLength
);
435 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
437 ModuleCount
= smi
->ModulesCount
;
438 sm
= &smi
->Modules
[0];
439 /* our implementation is a stub for now */
440 ok( ModuleCount
> 0, "Expected some modules to be loaded\n");
442 /* Loop through all the modules/drivers, Wine doesn't get here (yet) */
443 for (i
= 0; i
< ModuleCount
; i
++)
445 ok( i
== sm
->Id
, "Id (%d) should have matched %u\n", sm
->Id
, i
);
449 HeapFree( GetProcessHeap(), 0, smi
);
452 static void test_query_handle(void)
456 ULONG SystemInformationLength
= sizeof(SYSTEM_HANDLE_INFORMATION
);
457 SYSTEM_HANDLE_INFORMATION
* shi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
459 /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
460 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
461 todo_wine
ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
463 SystemInformationLength
= ReturnLength
;
464 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
465 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
466 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) /* vista */
468 ok( status
== STATUS_SUCCESS
,
469 "Expected STATUS_SUCCESS, got %08x\n", status
);
471 /* Check if we have some return values */
472 trace("Number of Handles : %d\n", shi
->Count
);
475 /* our implementation is a stub for now */
476 ok( shi
->Count
> 1, "Expected more than 1 handles, got (%d)\n", shi
->Count
);
479 HeapFree( GetProcessHeap(), 0, shi
);
482 static void test_query_cache(void)
486 SYSTEM_CACHE_INFORMATION sci
;
488 status
= pNtQuerySystemInformation(SystemCacheInformation
, &sci
, 0, &ReturnLength
);
489 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
491 status
= pNtQuerySystemInformation(SystemCacheInformation
, &sci
, sizeof(sci
), &ReturnLength
);
492 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
493 ok( sizeof(sci
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
495 status
= pNtQuerySystemInformation(SystemCacheInformation
, &sci
, sizeof(sci
) + 2, &ReturnLength
);
496 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
497 ok( sizeof(sci
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
500 static void test_query_interrupt(void)
505 SYSTEM_BASIC_INFORMATION sbi
;
506 SYSTEM_INTERRUPT_INFORMATION
* sii
;
508 /* Find out the number of processors */
509 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
510 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
);
512 sii
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
514 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, 0, &ReturnLength
);
515 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
517 /* Try it for all processors */
518 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, NeededLength
, &ReturnLength
);
519 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
521 /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength
522 * No test added for this as it's highly unlikely that an app depends on this
525 HeapFree( GetProcessHeap(), 0, sii
);
528 static void test_query_kerndebug(void)
532 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi
;
534 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, 0, &ReturnLength
);
535 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
537 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
), &ReturnLength
);
538 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
539 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
541 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
) + 2, &ReturnLength
);
542 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
543 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
546 static void test_query_regquota(void)
550 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi
;
552 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, 0, &ReturnLength
);
553 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
555 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
), &ReturnLength
);
556 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
557 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
559 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
) + 2, &ReturnLength
);
560 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
561 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
564 static void test_query_process_basic(void)
569 typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE
{
570 DWORD_PTR ExitStatus
;
572 DWORD_PTR AffinityMask
;
573 DWORD_PTR BasePriority
;
574 ULONG_PTR UniqueProcessId
;
575 ULONG_PTR InheritedFromUniqueProcessId
;
576 } PROCESS_BASIC_INFORMATION_PRIVATE
, *PPROCESS_BASIC_INFORMATION_PRIVATE
;
578 PROCESS_BASIC_INFORMATION_PRIVATE pbi
;
580 /* This test also covers some basic parameter testing that should be the same for
581 * every information class
584 /* Use a nonexistent info class */
585 trace("Check nonexistent info class\n");
586 status
= pNtQueryInformationProcess(NULL
, -1, NULL
, 0, NULL
);
587 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
588 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status
);
590 /* Do not give a handle and buffer */
591 trace("Check NULL handle and buffer and zero-length buffersize\n");
592 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, 0, NULL
);
593 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
595 /* Use a correct info class and buffer size, but still no handle and buffer */
596 trace("Check NULL handle and buffer\n");
597 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, sizeof(pbi
), NULL
);
598 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
599 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
601 /* Use a correct info class and buffer size, but still no handle */
602 trace("Check NULL handle\n");
603 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
604 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
606 /* Use a greater buffer size */
607 trace("Check NULL handle and too large buffersize\n");
608 status
= pNtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, NULL
);
609 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
611 /* Use no ReturnLength */
612 trace("Check NULL ReturnLength\n");
613 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
614 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
616 /* Finally some correct calls */
617 trace("Check with correct parameters\n");
618 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), &ReturnLength
);
619 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
620 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
622 /* Everything is correct except a too large buffersize */
623 trace("Too large buffersize\n");
624 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, &ReturnLength
);
625 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
626 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
628 /* Check if we have some return values */
629 trace("ProcessID : %lx\n", pbi
.UniqueProcessId
);
630 ok( pbi
.UniqueProcessId
> 0, "Expected a ProcessID > 0, got 0\n");
633 static void test_query_process_vm(void)
638 ULONG old_size
= FIELD_OFFSET(VM_COUNTERS
,PrivatePageCount
);
640 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, NULL
, sizeof(pvi
), NULL
);
641 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
642 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
644 status
= pNtQueryInformationProcess(NULL
, ProcessVmCounters
, &pvi
, old_size
, NULL
);
645 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
647 /* Windows XP and W2K3 will report success for a size of 44 AND 48 !
648 Windows W2K will only report success for 44.
649 For now we only care for 44, which is FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
652 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 24, &ReturnLength
);
653 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
655 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, old_size
, &ReturnLength
);
656 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
657 ok( old_size
== ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
659 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 46, &ReturnLength
);
660 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
661 ok( ReturnLength
== old_size
|| ReturnLength
== sizeof(pvi
), "Inconsistent length %d\n", ReturnLength
);
663 /* Check if we have some return values */
664 trace("WorkingSetSize : %ld\n", pvi
.WorkingSetSize
);
667 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
671 static void test_query_process_io(void)
677 /* NT4 doesn't support this information class, so check for it */
678 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
679 if (status
== STATUS_NOT_SUPPORTED
)
681 win_skip("ProcessIoCounters information class is not supported\n");
685 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, NULL
, sizeof(pii
), NULL
);
686 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
687 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
689 status
= pNtQueryInformationProcess(NULL
, ProcessIoCounters
, &pii
, sizeof(pii
), NULL
);
690 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
692 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, 24, &ReturnLength
);
693 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
695 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
696 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
697 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
699 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
) * 2, &ReturnLength
);
700 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
701 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
703 /* Check if we have some return values */
704 trace("OtherOperationCount : 0x%x%08x\n", (DWORD
)(pii
.OtherOperationCount
>> 32), (DWORD
)pii
.OtherOperationCount
);
707 ok( pii
.OtherOperationCount
> 0, "Expected an OtherOperationCount > 0\n");
711 static void test_query_process_times(void)
716 SYSTEMTIME UTC
, Local
;
717 KERNEL_USER_TIMES spti
;
719 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, NULL
, sizeof(spti
), NULL
);
720 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
721 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
723 status
= pNtQueryInformationProcess(NULL
, ProcessTimes
, &spti
, sizeof(spti
), NULL
);
724 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
726 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, 24, &ReturnLength
);
727 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
729 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
732 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
733 process
= GetCurrentProcess();
734 trace("ProcessTimes for current process\n");
737 trace("ProcessTimes for process with ID : %d\n", one_before_last_pid
);
739 status
= pNtQueryInformationProcess( process
, ProcessTimes
, &spti
, sizeof(spti
), &ReturnLength
);
740 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
741 ok( sizeof(spti
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
742 CloseHandle(process
);
744 FileTimeToSystemTime((const FILETIME
*)&spti
.CreateTime
, &UTC
);
745 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
746 trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
747 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
749 FileTimeToSystemTime((const FILETIME
*)&spti
.ExitTime
, &UTC
);
750 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
751 trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
752 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
754 FileTimeToSystemTime((const FILETIME
*)&spti
.KernelTime
, &Local
);
755 trace("KernelTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
757 FileTimeToSystemTime((const FILETIME
*)&spti
.UserTime
, &Local
);
758 trace("UserTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
760 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, sizeof(spti
) * 2, &ReturnLength
);
761 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
762 ok( sizeof(spti
) == ReturnLength
||
763 ReturnLength
== 0 /* vista */ ||
764 broken(is_wow64
), /* returns garbage on wow64 */
765 "Inconsistent length %d\n", ReturnLength
);
768 static void test_query_process_debug_port(int argc
, char **argv
)
770 DWORD_PTR debug_port
= 0xdeadbeef;
771 char cmdline
[MAX_PATH
];
772 PROCESS_INFORMATION pi
;
773 STARTUPINFO si
= { 0 };
777 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
780 ret
= CreateProcess(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
, NULL
, &si
, &pi
);
781 ok(ret
, "CreateProcess failed, last error %#x.\n", GetLastError());
784 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
786 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
788 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
789 NULL
, sizeof(debug_port
), NULL
);
790 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
,
791 "Expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
793 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
794 NULL
, sizeof(debug_port
), NULL
);
795 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
797 status
= pNtQueryInformationProcess(NULL
, ProcessDebugPort
,
798 &debug_port
, sizeof(debug_port
), NULL
);
799 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
801 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
802 &debug_port
, sizeof(debug_port
) - 1, NULL
);
803 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
805 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
806 &debug_port
, sizeof(debug_port
) + 1, NULL
);
807 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status
);
809 status
= pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
810 &debug_port
, sizeof(debug_port
), NULL
);
811 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
812 ok(debug_port
== 0, "Expected port 0, got %#lx.\n", debug_port
);
814 status
= pNtQueryInformationProcess(pi
.hProcess
, ProcessDebugPort
,
815 &debug_port
, sizeof(debug_port
), NULL
);
816 ok(!status
, "NtQueryInformationProcess failed, status %#x.\n", status
);
817 ok(debug_port
== ~(DWORD_PTR
)0, "Expected port %#lx, got %#lx.\n", ~(DWORD_PTR
)0, debug_port
);
823 ret
= WaitForDebugEvent(&ev
, INFINITE
);
824 ok(ret
, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
827 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
829 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
830 ok(ret
, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
834 ret
= CloseHandle(pi
.hThread
);
835 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
836 ret
= CloseHandle(pi
.hProcess
);
837 ok(ret
, "CloseHandle failed, last error %#x.\n", GetLastError());
840 static void test_query_process_handlecount(void)
845 BYTE buffer
[2 * sizeof(DWORD
)];
848 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, NULL
, sizeof(handlecount
), NULL
);
849 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
850 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status
);
852 status
= pNtQueryInformationProcess(NULL
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), NULL
);
853 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
855 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, &handlecount
, 2, &ReturnLength
);
856 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
858 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
861 trace("Could not open process with ID : %d, error : %u. Going to use current one.\n", one_before_last_pid
, GetLastError());
862 process
= GetCurrentProcess();
863 trace("ProcessHandleCount for current process\n");
866 trace("ProcessHandleCount for process with ID : %d\n", one_before_last_pid
);
868 status
= pNtQueryInformationProcess( process
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), &ReturnLength
);
869 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
870 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
871 CloseHandle(process
);
873 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, buffer
, sizeof(buffer
), &ReturnLength
);
874 ok( status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_SUCCESS
,
875 "Expected STATUS_INFO_LENGTH_MISMATCH or STATUS_SUCCESS, got %08x\n", status
);
876 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %d\n", ReturnLength
);
878 /* Check if we have some return values */
879 trace("HandleCount : %d\n", handlecount
);
882 ok( handlecount
> 0, "Expected some handles, got 0\n");
886 static void test_query_process_image_file_name(void)
890 UNICODE_STRING image_file_name
;
895 status
= pNtQueryInformationProcess(NULL
, ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), NULL
);
896 if (status
== STATUS_INVALID_INFO_CLASS
)
898 win_skip("ProcessImageFileName is not supported\n");
901 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
903 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, 2, &ReturnLength
);
904 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
906 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), &ReturnLength
);
907 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
909 buffer
= HeapAlloc(GetProcessHeap(), 0, ReturnLength
);
910 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, buffer
, ReturnLength
, &ReturnLength
);
911 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
912 memcpy(&image_file_name
, buffer
, sizeof(image_file_name
));
913 len
= WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), NULL
, 0, NULL
, NULL
);
914 file_nameA
= HeapAlloc(GetProcessHeap(), 0, len
+ 1);
915 WideCharToMultiByte(CP_ACP
, 0, image_file_name
.Buffer
, image_file_name
.Length
/sizeof(WCHAR
), file_nameA
, len
, NULL
, NULL
);
916 file_nameA
[len
] = '\0';
917 HeapFree(GetProcessHeap(), 0, buffer
);
918 trace("process image file name: %s\n", file_nameA
);
919 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
);
920 HeapFree(GetProcessHeap(), 0, file_nameA
);
924 static void test_readvirtualmemory(void)
929 static const char teststring
[] = "test string";
932 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
933 ok(process
!= 0, "Expected to be able to open own process for reading memory\n");
935 /* normal operation */
936 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, &readcount
);
937 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
938 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
939 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
941 /* no number of bytes */
942 memset(buffer
, 0, 12);
943 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, NULL
);
944 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
945 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
947 /* illegal remote address */
949 status
= pNtReadVirtualMemory(process
, (void *) 0x1234, buffer
, 12, &readcount
);
950 ok( status
== STATUS_PARTIAL_COPY
|| broken(status
== STATUS_ACCESS_VIOLATION
), "Expected STATUS_PARTIAL_COPY, got %08x\n", status
);
951 if (status
== STATUS_PARTIAL_COPY
)
952 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
956 status
= pNtReadVirtualMemory(0, teststring
, buffer
, 12, &readcount
);
957 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08x\n", status
);
958 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
960 /* pseudo handle for current process*/
961 memset(buffer
, 0, 12);
962 status
= pNtReadVirtualMemory((HANDLE
)-1, teststring
, buffer
, 12, &readcount
);
963 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
964 ok( readcount
== 12, "Expected to read 12 bytes, got %ld\n",readcount
);
965 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
967 /* illegal local address */
968 status
= pNtReadVirtualMemory(process
, teststring
, (void *)0x1234, 12, &readcount
);
969 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
970 ok( readcount
== 0, "Expected to read 0 bytes, got %ld\n",readcount
);
972 CloseHandle(process
);
975 static void test_queryvirtualmemory(void)
979 static const char teststring
[] = "test string";
980 static char rwtestbuf
[42];
981 MEMORY_BASIC_INFORMATION mbi
;
984 trace("Check flags of a function entry in NTDLL.DLL\n");
985 status
= pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
986 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
987 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
988 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
989 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
990 todo_wine
ok (mbi
.Protect
== PAGE_EXECUTE_READ
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_EXECUTE_READ
);
992 trace("Check flags of heap\n");
993 status
= pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
994 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
995 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
996 ok (mbi
.AllocationProtect
== PAGE_READWRITE
|| mbi
.AllocationProtect
== PAGE_EXECUTE_READWRITE
,
997 "mbi.AllocationProtect is 0x%x\n", mbi
.AllocationProtect
);
998 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
999 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_EXECUTE_READWRITE
,
1000 "mbi.Protect is 0x%x\n", mbi
.Protect
);
1002 trace("Check flags of stack\n");
1003 status
= pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1004 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1005 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1006 ok (mbi
.AllocationProtect
== PAGE_READWRITE
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_READWRITE
);
1007 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
1008 ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%x, expected 0x%x\n", mbi
.Protect
, PAGE_READWRITE
);
1010 trace("Check flags of read-only data\n");
1011 status
= pNtQueryVirtualMemory(NtCurrentProcess(), teststring
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1012 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1013 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1014 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1015 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1016 if (mbi
.Protect
!= PAGE_READONLY
)
1017 todo_wine
ok( mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%x, expected 0x%X\n", mbi
.Protect
, PAGE_READONLY
);
1019 trace("Check flags of read-write global data (.bss)\n");
1020 status
= pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
1021 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1022 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
1023 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
1024 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%x, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
1025 todo_wine
ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%x, expected 0x%X\n", mbi
.Protect
, PAGE_READWRITE
);
1028 static void test_affinity(void)
1031 PROCESS_BASIC_INFORMATION pbi
;
1032 DWORD_PTR proc_affinity
, thread_affinity
;
1033 THREAD_BASIC_INFORMATION tbi
;
1037 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1038 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1039 proc_affinity
= (DWORD_PTR
)pbi
.Reserved2
[0];
1040 ok( proc_affinity
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected process affinity\n" );
1041 proc_affinity
= 1 << si
.dwNumberOfProcessors
;
1042 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1043 ok( status
== STATUS_INVALID_PARAMETER
,
1044 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1047 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1048 ok( status
== STATUS_INVALID_PARAMETER
,
1049 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1051 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1052 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1053 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1, "Unexpected thread affinity\n" );
1054 thread_affinity
= 1 << si
.dwNumberOfProcessors
;
1055 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1056 ok( status
== STATUS_INVALID_PARAMETER
,
1057 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1058 thread_affinity
= 0;
1059 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1060 ok( status
== STATUS_INVALID_PARAMETER
,
1061 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1063 thread_affinity
= 1;
1064 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1065 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1066 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1067 ok( tbi
.AffinityMask
== 1, "Unexpected thread affinity\n" );
1069 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
1070 thread_affinity
= ~(DWORD_PTR
)0;
1071 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1072 ok( broken(status
== STATUS_INVALID_PARAMETER
) || status
== STATUS_SUCCESS
,
1073 "Expected STATUS_SUCCESS, got %08x\n", status
);
1075 if (si
.dwNumberOfProcessors
<= 1)
1077 skip("only one processor, skipping affinity testing\n");
1081 /* Test thread affinity mask resulting from "all processors" flag */
1082 if (status
== STATUS_SUCCESS
)
1084 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1085 ok( broken(tbi
.AffinityMask
== 1) || tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
1086 "Unexpected thread affinity\n" );
1089 skip("Cannot test thread affinity mask for 'all processors' flag\n");
1092 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1093 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1094 status
= pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1095 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1096 proc_affinity
= (DWORD_PTR
)pbi
.Reserved2
[0];
1097 ok( proc_affinity
== 2, "Unexpected process affinity\n" );
1098 /* Setting the process affinity changes the thread affinity to match */
1099 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1100 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1101 ok( tbi
.AffinityMask
== 2, "Unexpected thread affinity\n" );
1102 /* The thread affinity is restricted to the process affinity */
1103 thread_affinity
= 1;
1104 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
1105 ok( status
== STATUS_INVALID_PARAMETER
,
1106 "Expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
1108 proc_affinity
= (1 << si
.dwNumberOfProcessors
) - 1;
1109 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
1110 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1111 /* Resetting the process affinity also resets the thread affinity */
1112 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
1113 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08x\n", status
);
1114 ok( tbi
.AffinityMask
== (1 << si
.dwNumberOfProcessors
) - 1,
1115 "Unexpected thread affinity\n" );
1123 if(!InitFunctionPtrs())
1126 argc
= winetest_get_mainargs(&argv
);
1127 if (argc
>= 3) return; /* Child */
1129 /* NtQuerySystemInformation */
1131 /* 0x0 SystemBasicInformation */
1132 trace("Starting test_query_basic()\n");
1135 /* 0x1 SystemCpuInformation */
1136 trace("Starting test_query_cpu()\n");
1139 /* 0x2 SystemPerformanceInformation */
1140 trace("Starting test_query_performance()\n");
1141 test_query_performance();
1143 /* 0x3 SystemTimeOfDayInformation */
1144 trace("Starting test_query_timeofday()\n");
1145 test_query_timeofday();
1147 /* 0x5 SystemProcessInformation */
1148 trace("Starting test_query_process()\n");
1149 test_query_process();
1151 /* 0x8 SystemProcessorPerformanceInformation */
1152 trace("Starting test_query_procperf()\n");
1153 test_query_procperf();
1155 /* 0xb SystemModuleInformation */
1156 trace("Starting test_query_module()\n");
1157 test_query_module();
1159 /* 0x10 SystemHandleInformation */
1160 trace("Starting test_query_handle()\n");
1161 test_query_handle();
1163 /* 0x15 SystemCacheInformation */
1164 trace("Starting test_query_cache()\n");
1167 /* 0x17 SystemInterruptInformation */
1168 trace("Starting test_query_interrupt()\n");
1169 test_query_interrupt();
1171 /* 0x23 SystemKernelDebuggerInformation */
1172 trace("Starting test_query_kerndebug()\n");
1173 test_query_kerndebug();
1175 /* 0x25 SystemRegistryQuotaInformation */
1176 trace("Starting test_query_regquota()\n");
1177 test_query_regquota();
1179 /* NtQueryInformationProcess */
1181 /* 0x0 ProcessBasicInformation */
1182 trace("Starting test_query_process_basic()\n");
1183 test_query_process_basic();
1185 /* 0x2 ProcessIoCounters */
1186 trace("Starting test_query_process_io()\n");
1187 test_query_process_io();
1189 /* 0x3 ProcessVmCounters */
1190 trace("Starting test_query_process_vm()\n");
1191 test_query_process_vm();
1193 /* 0x4 ProcessTimes */
1194 trace("Starting test_query_process_times()\n");
1195 test_query_process_times();
1197 /* 0x7 ProcessDebugPort */
1198 trace("Starting test_process_debug_port()\n");
1199 test_query_process_debug_port(argc
, argv
);
1201 /* 0x14 ProcessHandleCount */
1202 trace("Starting test_query_process_handlecount()\n");
1203 test_query_process_handlecount();
1205 /* 27 ProcessImageFileName */
1206 trace("Starting test_query_process_image_file_name()\n");
1207 test_query_process_image_file_name();
1209 /* belongs into it's own file */
1210 trace("Starting test_readvirtualmemory()\n");
1211 test_readvirtualmemory();
1212 trace("Starting test_queryvirtualmemory()\n");
1213 test_queryvirtualmemory();
1215 trace("Starting test_affinity()\n");