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
25 #define WIN32_NO_STATUS
30 #include "ddk/ntddk.h"
32 #include "wine/test.h"
34 static NTSTATUS (WINAPI
* pNtQuerySystemInformation
)(SYSTEM_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
35 static NTSTATUS (WINAPI
* pNtSetSystemInformation
)(SYSTEM_INFORMATION_CLASS
, PVOID
, ULONG
);
36 static NTSTATUS (WINAPI
* pRtlGetNativeSystemInformation
)(SYSTEM_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
37 static NTSTATUS (WINAPI
* pNtQuerySystemInformationEx
)(SYSTEM_INFORMATION_CLASS
, void*, ULONG
, void*, ULONG
, ULONG
*);
38 static NTSTATUS (WINAPI
* pNtPowerInformation
)(POWER_INFORMATION_LEVEL
, PVOID
, ULONG
, PVOID
, ULONG
);
39 static NTSTATUS (WINAPI
* pNtQueryInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
, PULONG
);
40 static NTSTATUS (WINAPI
* pNtSetInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
);
41 static NTSTATUS (WINAPI
* pNtSetInformationThread
)(HANDLE
, THREADINFOCLASS
, PVOID
, ULONG
);
42 static NTSTATUS (WINAPI
* pNtReadVirtualMemory
)(HANDLE
, const void*, void*, SIZE_T
, SIZE_T
*);
43 static NTSTATUS (WINAPI
* pNtQueryVirtualMemory
)(HANDLE
, LPCVOID
, MEMORY_INFORMATION_CLASS
, PVOID
, SIZE_T
, SIZE_T
*);
44 static NTSTATUS (WINAPI
* pNtCreateSection
)(HANDLE
*,ACCESS_MASK
,const OBJECT_ATTRIBUTES
*,const LARGE_INTEGER
*,ULONG
,ULONG
,HANDLE
);
45 static NTSTATUS (WINAPI
* pNtMapViewOfSection
)(HANDLE
,HANDLE
,PVOID
*,ULONG_PTR
,SIZE_T
,const LARGE_INTEGER
*,SIZE_T
*,SECTION_INHERIT
,ULONG
,ULONG
);
46 static NTSTATUS (WINAPI
* pNtUnmapViewOfSection
)(HANDLE
,PVOID
);
47 static NTSTATUS (WINAPI
* pNtClose
)(HANDLE
);
48 static ULONG (WINAPI
* pNtGetCurrentProcessorNumber
)(void);
49 static BOOL (WINAPI
* pGetLogicalProcessorInformationEx
)(LOGICAL_PROCESSOR_RELATIONSHIP
,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*,DWORD
*);
50 static DEP_SYSTEM_POLICY_TYPE (WINAPI
* pGetSystemDEPPolicy
)(void);
51 static NTSTATUS (WINAPI
* pNtOpenThread
)(HANDLE
*, ACCESS_MASK
, const OBJECT_ATTRIBUTES
*, const CLIENT_ID
*);
52 static NTSTATUS (WINAPI
* pNtQueryObject
)(HANDLE
, OBJECT_INFORMATION_CLASS
, void *, ULONG
, ULONG
*);
53 static NTSTATUS (WINAPI
* pNtCreateDebugObject
)( HANDLE
*, ACCESS_MASK
, OBJECT_ATTRIBUTES
*, ULONG
);
54 static NTSTATUS (WINAPI
* pNtSetInformationDebugObject
)(HANDLE
,DEBUGOBJECTINFOCLASS
,PVOID
,ULONG
,ULONG
*);
55 static NTSTATUS (WINAPI
* pDbgUiConvertStateChangeStructure
)(DBGUI_WAIT_STATE_CHANGE
*,DEBUG_EVENT
*);
56 static HANDLE (WINAPI
* pDbgUiGetThreadDebugObject
)(void);
57 static void (WINAPI
* pDbgUiSetThreadDebugObject
)(HANDLE
);
58 static NTSTATUS (WINAPI
* pNtSystemDebugControl
)(SYSDBG_COMMAND
,PVOID
,ULONG
,PVOID
,ULONG
,PULONG
);
61 static BOOL old_wow64
;
63 /* one_before_last_pid is used to be able to compare values of a still running process
64 with the output of the test_query_process_times and test_query_process_handlecount tests.
66 static DWORD one_before_last_pid
= 0;
68 static inline DWORD_PTR
get_affinity_mask(DWORD num_cpus
)
70 if (num_cpus
>= sizeof(DWORD_PTR
) * 8) return ~(DWORD_PTR
)0;
71 return ((DWORD_PTR
)1 << num_cpus
) - 1;
74 #define NTDLL_GET_PROC(func) do { \
75 p ## func = (void*)GetProcAddress(hntdll, #func); \
77 trace("GetProcAddress(%s) failed\n", #func); \
81 /* Firmware table providers */
82 #define ACPI 0x41435049
83 #define FIRM 0x4649524D
84 #define RSMB 0x52534D42
86 static void InitFunctionPtrs(void)
88 /* All needed functions are NT based, so using GetModuleHandle is a good check */
89 HMODULE hntdll
= GetModuleHandleA("ntdll");
90 HMODULE hkernel32
= GetModuleHandleA("kernel32");
92 NTDLL_GET_PROC(NtQuerySystemInformation
);
93 NTDLL_GET_PROC(NtQuerySystemInformationEx
);
94 NTDLL_GET_PROC(NtSetSystemInformation
);
95 NTDLL_GET_PROC(RtlGetNativeSystemInformation
);
96 NTDLL_GET_PROC(NtPowerInformation
);
97 NTDLL_GET_PROC(NtQueryInformationThread
);
98 NTDLL_GET_PROC(NtSetInformationProcess
);
99 NTDLL_GET_PROC(NtSetInformationThread
);
100 NTDLL_GET_PROC(NtReadVirtualMemory
);
101 NTDLL_GET_PROC(NtQueryVirtualMemory
);
102 NTDLL_GET_PROC(NtClose
);
103 NTDLL_GET_PROC(NtCreateSection
);
104 NTDLL_GET_PROC(NtMapViewOfSection
);
105 NTDLL_GET_PROC(NtUnmapViewOfSection
);
106 NTDLL_GET_PROC(NtOpenThread
);
107 NTDLL_GET_PROC(NtQueryObject
);
108 NTDLL_GET_PROC(NtCreateDebugObject
);
109 NTDLL_GET_PROC(NtSetInformationDebugObject
);
110 NTDLL_GET_PROC(NtGetCurrentProcessorNumber
);
111 NTDLL_GET_PROC(DbgUiConvertStateChangeStructure
);
112 NTDLL_GET_PROC(DbgUiGetThreadDebugObject
);
113 NTDLL_GET_PROC(DbgUiSetThreadDebugObject
);
114 NTDLL_GET_PROC(NtSystemDebugControl
);
116 if (!IsWow64Process( GetCurrentProcess(), &is_wow64
)) is_wow64
= FALSE
;
120 TEB64
*teb64
= ULongToPtr( NtCurrentTeb()->GdiBatchCount
);
124 PEB64
*peb64
= ULongToPtr(teb64
->Peb
);
125 old_wow64
= !peb64
->LdrData
;
129 pGetSystemDEPPolicy
= (void *)GetProcAddress(hkernel32
, "GetSystemDEPPolicy");
130 pGetLogicalProcessorInformationEx
= (void *) GetProcAddress(hkernel32
, "GetLogicalProcessorInformationEx");
133 static void test_query_basic(void)
136 ULONG i
, ReturnLength
;
137 SYSTEM_BASIC_INFORMATION sbi
, sbi2
, sbi3
;
139 /* This test also covers some basic parameter testing that should be the same for
140 * every information class
143 /* Use a nonexistent info class */
144 status
= pNtQuerySystemInformation(-1, NULL
, 0, NULL
);
145 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
146 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08lx\n", status
);
148 /* Use an existing class but with a zero-length buffer */
149 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, 0, NULL
);
150 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
152 /* Use an existing class, correct length but no SystemInformation buffer */
153 status
= pNtQuerySystemInformation(SystemBasicInformation
, NULL
, sizeof(sbi
), NULL
);
154 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
/* vista */,
155 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got %08lx\n", status
);
157 /* Use an existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
158 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), NULL
);
159 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
161 /* Check a too large buffer size */
162 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
) * 2, &ReturnLength
);
163 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
165 /* Finally some correct calls */
166 memset(&sbi
, 0xcc, sizeof(sbi
));
167 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
168 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
169 ok( sizeof(sbi
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
171 /* Check if we have some return values */
172 if (winetest_debug
> 1) trace("Number of Processors : %d\n", sbi
.NumberOfProcessors
);
173 ok( sbi
.NumberOfProcessors
> 0, "Expected more than 0 processors, got %d\n", sbi
.NumberOfProcessors
);
175 memset(&sbi2
, 0xcc, sizeof(sbi2
));
176 status
= pRtlGetNativeSystemInformation(SystemBasicInformation
, &sbi2
, sizeof(sbi2
), &ReturnLength
);
177 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx.\n", status
);
178 ok( sizeof(sbi2
) == ReturnLength
, "Unexpected length %lu.\n", ReturnLength
);
180 ok( sbi
.unknown
== sbi2
.unknown
, "Expected unknown %#lx, got %#lx.\n", sbi
.unknown
, sbi2
.unknown
);
181 ok( sbi
.KeMaximumIncrement
== sbi2
.KeMaximumIncrement
, "Expected KeMaximumIncrement %lu, got %lu.\n",
182 sbi
.KeMaximumIncrement
, sbi2
.KeMaximumIncrement
);
183 ok( sbi
.PageSize
== sbi2
.PageSize
, "Expected PageSize field %lu, %lu.\n", sbi
.PageSize
, sbi2
.PageSize
);
184 ok( sbi
.MmNumberOfPhysicalPages
== sbi2
.MmNumberOfPhysicalPages
,
185 "Expected MmNumberOfPhysicalPages %lu, got %lu.\n",
186 sbi
.MmNumberOfPhysicalPages
, sbi2
.MmNumberOfPhysicalPages
);
187 ok( sbi
.MmLowestPhysicalPage
== sbi2
.MmLowestPhysicalPage
, "Expected MmLowestPhysicalPage %lu, got %lu.\n",
188 sbi
.MmLowestPhysicalPage
, sbi2
.MmLowestPhysicalPage
);
189 ok( sbi
.MmHighestPhysicalPage
== sbi2
.MmHighestPhysicalPage
, "Expected MmHighestPhysicalPage %lu, got %lu.\n",
190 sbi
.MmHighestPhysicalPage
, sbi2
.MmHighestPhysicalPage
);
191 /* Higher 32 bits of AllocationGranularity is sometimes garbage on Windows. */
192 ok( (ULONG
)sbi
.AllocationGranularity
== (ULONG
)sbi2
.AllocationGranularity
,
193 "Expected AllocationGranularity %#Ix, got %#Ix.\n",
194 sbi
.AllocationGranularity
, sbi2
.AllocationGranularity
);
195 ok( sbi
.LowestUserAddress
== sbi2
.LowestUserAddress
, "Expected LowestUserAddress %p, got %p.\n",
196 sbi
.LowestUserAddress
, sbi2
.LowestUserAddress
);
197 ok( sbi
.ActiveProcessorsAffinityMask
== sbi2
.ActiveProcessorsAffinityMask
,
198 "Expected ActiveProcessorsAffinityMask %#Ix, got %#Ix.\n",
199 sbi
.ActiveProcessorsAffinityMask
, sbi2
.ActiveProcessorsAffinityMask
);
200 ok( sbi
.NumberOfProcessors
== sbi2
.NumberOfProcessors
, "Expected NumberOfProcessors %u, got %u.\n",
201 sbi
.NumberOfProcessors
, sbi2
.NumberOfProcessors
);
203 ok( sbi
.HighestUserAddress
== sbi2
.HighestUserAddress
, "Expected HighestUserAddress %p, got %p.\n",
204 (void *)sbi
.HighestUserAddress
, (void *)sbi2
.HighestUserAddress
);
206 ok( sbi
.HighestUserAddress
== (void *)0x7ffeffff, "wrong limit %p\n", sbi
.HighestUserAddress
);
207 todo_wine_if( old_wow64
)
208 ok( sbi2
.HighestUserAddress
== (is_wow64
? (void *)0xfffeffff : (void *)0x7ffeffff),
209 "wrong limit %p\n", sbi
.HighestUserAddress
);
212 memset(&sbi3
, 0xcc, sizeof(sbi3
));
213 status
= pNtQuerySystemInformation(SystemNativeBasicInformation
, &sbi3
, sizeof(sbi3
), &ReturnLength
);
215 ok( status
== STATUS_SUCCESS
|| broken(status
== STATUS_INVALID_INFO_CLASS
), "got %08lx\n", status
);
218 ok( sizeof(sbi3
) == ReturnLength
, "Unexpected length %lu.\n", ReturnLength
);
219 ok( !memcmp( &sbi2
, &sbi3
, offsetof(SYSTEM_BASIC_INFORMATION
,NumberOfProcessors
)+1 ),
220 "info is different\n" );
223 ok( status
== STATUS_INVALID_INFO_CLASS
|| broken(status
== STATUS_SUCCESS
), /* some Win8 */
224 "got %08lx\n", status
);
225 status
= pRtlGetNativeSystemInformation( SystemNativeBasicInformation
, &sbi3
, sizeof(sbi3
), &ReturnLength
);
226 ok( !status
|| status
== STATUS_INFO_LENGTH_MISMATCH
||
227 broken(status
== STATUS_INVALID_INFO_CLASS
) || broken(status
== STATUS_NOT_IMPLEMENTED
),
228 "failed %lx\n", status
);
229 if (!status
|| status
== STATUS_INFO_LENGTH_MISMATCH
)
230 todo_wine_if( old_wow64
)
231 ok( !status
== !is_wow64
, "got wrong status %lx wow64 %u\n", status
, is_wow64
);
234 ok( sizeof(sbi3
) == ReturnLength
, "Unexpected length %lu.\n", ReturnLength
);
235 ok( !memcmp( &sbi2
, &sbi3
, offsetof(SYSTEM_BASIC_INFORMATION
,NumberOfProcessors
)+1 ),
236 "info is different\n" );
238 else if (status
== STATUS_INFO_LENGTH_MISMATCH
)
240 /* SystemNativeBasicInformation uses the 64-bit structure on Wow64 */
244 ULONG KeMaximumIncrement
;
246 ULONG MmNumberOfPhysicalPages
;
247 ULONG MmLowestPhysicalPage
;
248 ULONG MmHighestPhysicalPage
;
249 ULONG64 AllocationGranularity
;
250 ULONG64 LowestUserAddress
;
251 ULONG64 HighestUserAddress
;
252 ULONG64 ActiveProcessorsAffinityMask
;
253 BYTE NumberOfProcessors
;
256 ok( ReturnLength
== sizeof(sbi64
), "len %lx\n", ReturnLength
);
257 memset( &sbi64
, 0xcc, sizeof(sbi64
) );
259 status
= pRtlGetNativeSystemInformation( SystemNativeBasicInformation
, &sbi64
, sizeof(sbi64
), &ReturnLength
);
260 ok( !status
, "failed %lx\n", status
);
261 ok( ReturnLength
== sizeof(sbi64
), "len %lx\n", ReturnLength
);
263 ok( sbi
.unknown
== sbi64
.unknown
, "unknown %#lx / %#lx\n", sbi
.unknown
, sbi64
.unknown
);
264 ok( sbi
.KeMaximumIncrement
== sbi64
.KeMaximumIncrement
, "KeMaximumIncrement %lu / %lu\n",
265 sbi
.KeMaximumIncrement
, sbi64
.KeMaximumIncrement
);
266 ok( sbi
.PageSize
== sbi64
.PageSize
, "PageSize %lu / %lu\n", sbi
.PageSize
, sbi64
.PageSize
);
267 ok( sbi
.MmNumberOfPhysicalPages
== sbi64
.MmNumberOfPhysicalPages
,
268 "MmNumberOfPhysicalPages %lu / %lu\n",
269 sbi
.MmNumberOfPhysicalPages
, sbi64
.MmNumberOfPhysicalPages
);
270 ok( sbi
.MmLowestPhysicalPage
== sbi64
.MmLowestPhysicalPage
, "MmLowestPhysicalPage %lu / %lu\n",
271 sbi
.MmLowestPhysicalPage
, sbi64
.MmLowestPhysicalPage
);
272 ok( sbi
.MmHighestPhysicalPage
== sbi64
.MmHighestPhysicalPage
, "MmHighestPhysicalPage %lu / %lu\n",
273 sbi
.MmHighestPhysicalPage
, sbi64
.MmHighestPhysicalPage
);
274 ok( sbi
.AllocationGranularity
== (ULONG_PTR
)sbi64
.AllocationGranularity
,
275 "AllocationGranularity %#Ix / %#Ix\n", sbi
.AllocationGranularity
,
276 (ULONG_PTR
)sbi64
.AllocationGranularity
);
277 ok( (ULONG_PTR
)sbi
.LowestUserAddress
== sbi64
.LowestUserAddress
, "LowestUserAddress %p / %s\n",
278 sbi
.LowestUserAddress
, wine_dbgstr_longlong(sbi64
.LowestUserAddress
));
279 ok( sbi
.ActiveProcessorsAffinityMask
== sbi64
.ActiveProcessorsAffinityMask
,
280 "ActiveProcessorsAffinityMask %#Ix / %s\n",
281 sbi
.ActiveProcessorsAffinityMask
, wine_dbgstr_longlong(sbi64
.ActiveProcessorsAffinityMask
));
282 ok( sbi
.NumberOfProcessors
== sbi64
.NumberOfProcessors
, "NumberOfProcessors %u / %u\n",
283 sbi
.NumberOfProcessors
, sbi64
.NumberOfProcessors
);
284 ok( sbi64
.HighestUserAddress
== 0x7ffffffeffff, "wrong limit %s\n",
285 wine_dbgstr_longlong(sbi64
.HighestUserAddress
));
289 memset(&sbi3
, 0xcc, sizeof(sbi3
));
290 status
= pNtQuerySystemInformation(SystemEmulationBasicInformation
, &sbi3
, sizeof(sbi3
), &ReturnLength
);
291 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx.\n", status
);
292 ok( sizeof(sbi3
) == ReturnLength
, "Unexpected length %lu.\n", ReturnLength
);
293 ok( !memcmp( &sbi
, &sbi3
, offsetof(SYSTEM_BASIC_INFORMATION
,NumberOfProcessors
)+1 ),
294 "info is different\n" );
296 for (i
= 0; i
< 256; i
++)
298 NTSTATUS expect
= pNtQuerySystemInformation( i
, NULL
, 0, &ReturnLength
);
299 status
= pRtlGetNativeSystemInformation( i
, NULL
, 0, &ReturnLength
);
302 case SystemNativeBasicInformation
:
303 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_INFO_LENGTH_MISMATCH
||
304 broken(status
== STATUS_NOT_IMPLEMENTED
) /* vista */, "%lu: %lx / %lx\n", i
, status
, expect
);
306 case SystemBasicInformation
:
307 case SystemCpuInformation
:
308 case SystemEmulationBasicInformation
:
309 case SystemEmulationProcessorInformation
:
310 ok( status
== expect
, "%lu: %lx / %lx\n", i
, status
, expect
);
313 if (is_wow64
) /* only a few info classes are supported on Wow64 */
314 todo_wine_if (is_wow64
&& status
!= STATUS_INVALID_INFO_CLASS
)
315 ok( status
== STATUS_INVALID_INFO_CLASS
||
316 broken(status
== STATUS_NOT_IMPLEMENTED
), /* vista */
317 "%lu: %lx\n", i
, status
);
319 ok( status
== expect
, "%lu: %lx / %lx\n", i
, status
, expect
);
325 static void test_query_cpu(void)
328 ULONG len
, buffer
[16];
329 SYSTEM_PROCESSOR_FEATURES_INFORMATION features
;
330 SYSTEM_CPU_INFORMATION sci
, sci2
, sci3
;
332 memset(&sci
, 0xcc, sizeof(sci
));
333 status
= pNtQuerySystemInformation(SystemCpuInformation
, &sci
, sizeof(sci
), &len
);
334 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
335 ok( sizeof(sci
) == len
, "Inconsistent length %ld\n", len
);
337 memset(&sci2
, 0xcc, sizeof(sci2
));
338 status
= pRtlGetNativeSystemInformation(SystemCpuInformation
, &sci2
, sizeof(sci2
), &len
);
339 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx.\n", status
);
340 ok( sizeof(sci2
) == len
, "Unexpected length %lu.\n", len
);
344 ok( sci
.ProcessorArchitecture
== PROCESSOR_ARCHITECTURE_INTEL
, "ProcessorArchitecture wrong %x\n",
345 sci
.ProcessorArchitecture
);
346 ok( sci2
.ProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
||
347 sci2
.ProcessorArchitecture
== PROCESSOR_ARCHITECTURE_ARM64
,
348 "ProcessorArchitecture wrong %x\n", sci2
.ProcessorArchitecture
);
351 ok( sci
.ProcessorArchitecture
== sci2
.ProcessorArchitecture
,
352 "ProcessorArchitecture differs %x / %x\n",
353 sci
.ProcessorArchitecture
, sci2
.ProcessorArchitecture
);
355 if (sci2
.ProcessorArchitecture
!= PROCESSOR_ARCHITECTURE_ARM64
)
357 /* Check if we have some return values */
358 if (winetest_debug
> 1) trace("Processor FeatureSet : %08lx\n", sci
.ProcessorFeatureBits
);
359 ok( sci
.ProcessorFeatureBits
!= 0, "Expected some features for this processor, got %08lx\n",
360 sci
.ProcessorFeatureBits
);
362 ok( sci
.ProcessorLevel
== sci2
.ProcessorLevel
, "ProcessorLevel differs %x / %x\n",
363 sci
.ProcessorLevel
, sci2
.ProcessorLevel
);
364 ok( sci
.ProcessorRevision
== sci2
.ProcessorRevision
, "ProcessorRevision differs %x / %x\n",
365 sci
.ProcessorRevision
, sci2
.ProcessorRevision
);
366 ok( sci
.MaximumProcessors
== sci2
.MaximumProcessors
, "MaximumProcessors differs %x / %x\n",
367 sci
.MaximumProcessors
, sci2
.MaximumProcessors
);
368 ok( sci
.ProcessorFeatureBits
== sci2
.ProcessorFeatureBits
, "ProcessorFeatureBits differs %lx / %lx\n",
369 sci
.ProcessorFeatureBits
, sci2
.ProcessorFeatureBits
);
371 memset(&sci3
, 0xcc, sizeof(sci3
));
372 status
= pNtQuerySystemInformation(SystemEmulationProcessorInformation
, &sci3
, sizeof(sci3
), &len
);
373 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx.\n", status
);
374 ok( sizeof(sci3
) == len
, "Unexpected length %lu.\n", len
);
377 if (sci2
.ProcessorArchitecture
== PROCESSOR_ARCHITECTURE_ARM64
)
378 ok( sci3
.ProcessorArchitecture
== PROCESSOR_ARCHITECTURE_ARM
, "ProcessorArchitecture wrong %x\n",
379 sci3
.ProcessorArchitecture
);
381 ok( sci3
.ProcessorArchitecture
== PROCESSOR_ARCHITECTURE_INTEL
, "ProcessorArchitecture wrong %x\n",
382 sci3
.ProcessorArchitecture
);
384 ok( sci
.ProcessorArchitecture
== sci3
.ProcessorArchitecture
,
385 "ProcessorArchitecture differs %x / %x\n",
386 sci
.ProcessorArchitecture
, sci3
.ProcessorArchitecture
);
388 ok( sci
.ProcessorLevel
== sci3
.ProcessorLevel
, "ProcessorLevel differs %x / %x\n",
389 sci
.ProcessorLevel
, sci3
.ProcessorLevel
);
390 ok( sci
.ProcessorRevision
== sci3
.ProcessorRevision
, "ProcessorRevision differs %x / %x\n",
391 sci
.ProcessorRevision
, sci3
.ProcessorRevision
);
392 ok( sci
.MaximumProcessors
== sci3
.MaximumProcessors
, "MaximumProcessors differs %x / %x\n",
393 sci
.MaximumProcessors
, sci3
.MaximumProcessors
);
394 ok( sci
.ProcessorFeatureBits
== sci3
.ProcessorFeatureBits
, "ProcessorFeatureBits differs %lx / %lx\n",
395 sci
.ProcessorFeatureBits
, sci3
.ProcessorFeatureBits
);
398 status
= pNtQuerySystemInformation( SystemProcessorFeaturesInformation
, &features
, sizeof(features
), &len
);
399 if (status
!= STATUS_NOT_SUPPORTED
&& status
!= STATUS_INVALID_INFO_CLASS
)
401 ok( !status
, "SystemProcessorFeaturesInformation failed %lx\n", status
);
402 ok( len
== sizeof(features
), "wrong len %lu\n", len
);
403 ok( (ULONG
)features
.ProcessorFeatureBits
== sci
.ProcessorFeatureBits
, "wrong bits %I64x / %lx\n",
404 features
.ProcessorFeatureBits
, sci
.ProcessorFeatureBits
);
406 else skip( "SystemProcessorFeaturesInformation is not supported\n" );
409 status
= pNtQuerySystemInformation( SystemProcessorBrandString
, buffer
, sizeof(buffer
), &len
);
410 if (status
!= STATUS_NOT_SUPPORTED
)
412 ok( !status
, "SystemProcessorBrandString failed %lx\n", status
);
413 ok( len
== 49, "wrong len %lu\n", len
);
414 trace( "got %s len %u\n", debugstr_a( (char *)buffer
), lstrlenA( (char *)buffer
));
417 status
= pNtQuerySystemInformation( SystemProcessorBrandString
, buffer
, 49, &len
);
418 ok( !status
, "SystemProcessorBrandString failed %lx\n", status
);
419 ok( len
== 49, "wrong len %lu\n", len
);
422 status
= pNtQuerySystemInformation( SystemProcessorBrandString
, buffer
, 48, &len
);
423 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "SystemProcessorBrandString failed %lx\n", status
);
424 ok( len
== 49, "wrong len %lu\n", len
);
427 status
= pNtQuerySystemInformation( SystemProcessorBrandString
, (char *)buffer
+ 1, 49, &len
);
428 ok( status
== STATUS_DATATYPE_MISALIGNMENT
, "SystemProcessorBrandString failed %lx\n", status
);
429 ok( len
== 0xdeadbeef, "wrong len %lu\n", len
);
431 else skip( "SystemProcessorBrandString is not supported\n" );
434 static void test_query_performance(void)
438 ULONGLONG buffer
[sizeof(SYSTEM_PERFORMANCE_INFORMATION
)/sizeof(ULONGLONG
) + 5];
439 DWORD size
= sizeof(SYSTEM_PERFORMANCE_INFORMATION
);
441 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, 0, &ReturnLength
);
442 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
444 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
445 if (status
== STATUS_INFO_LENGTH_MISMATCH
&& is_wow64
)
447 /* size is larger on wow64 under w2k8/win7 */
449 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
, &ReturnLength
);
451 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
452 ok( ReturnLength
== size
, "Inconsistent length %ld\n", ReturnLength
);
454 status
= pNtQuerySystemInformation(SystemPerformanceInformation
, buffer
, size
+ 2, &ReturnLength
);
455 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
456 ok( ReturnLength
== size
|| ReturnLength
== size
+ 2 /* win8+ */,
457 "Inconsistent length %ld\n", ReturnLength
);
459 /* Not return values yet, as struct members are unknown */
462 static void test_query_timeofday(void)
467 /* Copy of our winternl.h structure turned into a private one */
468 typedef struct _SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
{
469 LARGE_INTEGER liKeBootTime
;
470 LARGE_INTEGER liKeSystemTime
;
471 LARGE_INTEGER liExpTimeZoneBias
;
472 ULONG uCurrentTimeZoneId
;
474 } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE
;
476 SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti
;
478 status
= pNtQuerySystemInformation( SystemTimeOfDayInformation
, &sti
, 0, &ReturnLength
);
479 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
480 ok( 0 == ReturnLength
, "ReturnLength should be 0, it is (%ld)\n", ReturnLength
);
482 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
483 status
= pNtQuerySystemInformation( SystemTimeOfDayInformation
, &sti
, 24, &ReturnLength
);
484 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
485 ok( 24 == ReturnLength
, "ReturnLength should be 24, it is (%ld)\n", ReturnLength
);
486 ok( 0xdeadbeef == sti
.uCurrentTimeZoneId
, "This part of the buffer should not have been filled\n");
488 sti
.uCurrentTimeZoneId
= 0xdeadbeef;
489 status
= pNtQuerySystemInformation( SystemTimeOfDayInformation
, &sti
, 32, &ReturnLength
);
490 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
491 ok( 32 == ReturnLength
, "ReturnLength should be 32, it is (%ld)\n", ReturnLength
);
492 ok( 0xdeadbeef != sti
.uCurrentTimeZoneId
, "Buffer should have been partially filled\n");
494 status
= pNtQuerySystemInformation( SystemTimeOfDayInformation
, &sti
, 49, &ReturnLength
);
495 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
496 ok( ReturnLength
== 0 || ReturnLength
== sizeof(sti
) /* vista */,
497 "ReturnLength should be 0, it is (%ld)\n", ReturnLength
);
499 status
= pNtQuerySystemInformation( SystemTimeOfDayInformation
, &sti
, sizeof(sti
), &ReturnLength
);
500 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
501 ok( sizeof(sti
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
503 /* Check if we have some return values */
504 if (winetest_debug
> 1) trace("uCurrentTimeZoneId : (%ld)\n", sti
.uCurrentTimeZoneId
);
507 static void test_query_process( BOOL extended
)
513 PROCESS_BASIC_INFORMATION pbi
;
514 THREAD_BASIC_INFORMATION tbi
;
515 OBJECT_ATTRIBUTES attr
;
519 /* Copy of our winternl.h structure turned into a private one */
520 typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE
{
521 ULONG NextEntryOffset
;
523 LARGE_INTEGER WorkingSetPrivateSize
;
524 ULONG HardFaultCount
;
525 ULONG NumberOfThreadsHighWatermark
;
527 FILETIME ftCreationTime
;
529 FILETIME ftKernelTime
;
530 UNICODE_STRING ProcessName
;
531 DWORD dwBasePriority
;
532 HANDLE UniqueProcessId
;
533 HANDLE ParentProcessId
;
536 ULONG_PTR UniqueProcessKey
;
537 VM_COUNTERS_EX vmCounters
;
538 IO_COUNTERS ioCounters
;
539 SYSTEM_THREAD_INFORMATION ti
[1];
540 } SYSTEM_PROCESS_INFORMATION_PRIVATE
;
542 BOOL is_process_wow64
= FALSE
, current_process_found
= FALSE
;
543 SYSTEM_PROCESS_INFORMATION_PRIVATE
*spi
, *spi_buf
;
544 SYSTEM_EXTENDED_THREAD_INFORMATION
*ti
;
545 SYSTEM_INFORMATION_CLASS info_class
;
546 void *expected_address
;
547 ULONG thread_info_size
;
551 info_class
= SystemExtendedProcessInformation
;
552 thread_info_size
= sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION
);
556 info_class
= SystemProcessInformation
;
557 thread_info_size
= sizeof(SYSTEM_THREAD_INFORMATION
);
560 /* test ReturnLength */
562 status
= pNtQuerySystemInformation( info_class
, NULL
, 0, &ReturnLength
);
563 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH got %08lx\n", status
);
564 ok( ReturnLength
> 0, "got 0 length\n" );
566 /* W2K3 and later returns the needed length, the rest returns 0. */
569 win_skip( "Zero return length, skipping tests." );
573 winetest_push_context( "extended %d", extended
);
575 spi_buf
= HeapAlloc(GetProcessHeap(), 0, ReturnLength
);
576 status
= pNtQuerySystemInformation(info_class
, spi_buf
, ReturnLength
, &ReturnLength
);
578 /* Sometimes new process or threads appear between the call and increase the size,
579 * otherwise the previously returned buffer size should be sufficient. */
580 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INFO_LENGTH_MISMATCH
,
581 "Expected STATUS_SUCCESS, got %08lx\n", status
);
590 winetest_push_context( "i %u (%s)", i
, debugstr_w(spi
->ProcessName
.Buffer
) );
594 last_pid
= (DWORD_PTR
)spi
->UniqueProcessId
;
595 ok( !(last_pid
& 3), "Unexpected PID low bits: %p\n", spi
->UniqueProcessId
);
597 if (last_pid
== GetCurrentProcessId())
598 current_process_found
= TRUE
;
600 if (extended
&& is_wow64
&& spi
->UniqueProcessId
)
602 InitializeObjectAttributes( &attr
, NULL
, 0, NULL
, NULL
);
603 cid
.UniqueProcess
= spi
->UniqueProcessId
;
604 cid
.UniqueThread
= 0;
605 status
= NtOpenProcess( &handle
, PROCESS_QUERY_LIMITED_INFORMATION
, &attr
, &cid
);
606 ok( status
== STATUS_SUCCESS
|| status
== STATUS_ACCESS_DENIED
,
607 "Got unexpected status %#lx, pid %p.\n", status
, spi
->UniqueProcessId
);
613 status
= NtQueryInformationProcess( handle
, ProcessWow64Information
, &info
, sizeof(info
), NULL
);
614 ok( status
== STATUS_SUCCESS
, "Got unexpected status %#lx.\n", status
);
615 is_process_wow64
= !!info
;
620 for (j
= 0; j
< spi
->dwThreadCount
; j
++)
622 ti
= (SYSTEM_EXTENDED_THREAD_INFORMATION
*)((BYTE
*)spi
->ti
+ j
* thread_info_size
);
625 ok ( ti
->ThreadInfo
.ClientId
.UniqueProcess
== spi
->UniqueProcessId
,
626 "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n",
627 ti
->ThreadInfo
.ClientId
.UniqueProcess
, spi
->UniqueProcessId
);
629 tid
= (DWORD_PTR
)ti
->ThreadInfo
.ClientId
.UniqueThread
;
630 ok( !(tid
& 3), "Unexpected TID low bits: %p\n", ti
->ThreadInfo
.ClientId
.UniqueThread
);
634 todo_wine
ok( !!ti
->StackBase
, "Got NULL StackBase.\n" );
635 todo_wine
ok( !!ti
->StackLimit
, "Got NULL StackLimit.\n" );
636 ok( !!ti
->Win32StartAddress
, "Got NULL Win32StartAddress.\n" );
638 cid
.UniqueProcess
= 0;
639 cid
.UniqueThread
= ti
->ThreadInfo
.ClientId
.UniqueThread
;
641 InitializeObjectAttributes( &attr
, NULL
, 0, NULL
, NULL
);
642 status
= NtOpenThread( &handle
, THREAD_QUERY_INFORMATION
, &attr
, &cid
);
645 THREAD_BASIC_INFORMATION tbi
;
647 status
= pNtQueryInformationThread( handle
, ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
648 ok( status
== STATUS_SUCCESS
, "Got unexpected status %#lx.\n", status
);
649 expected_address
= tbi
.TebBaseAddress
;
650 if (is_wow64
&& is_process_wow64
)
651 expected_address
= (BYTE
*)expected_address
- 0x2000;
652 if (!is_wow64
&& !is_process_wow64
&& !tbi
.TebBaseAddress
)
653 win_skip( "Could not get TebBaseAddress, thread %lu.\n", j
);
655 ok( ti
->TebBase
== expected_address
|| (is_wow64
&& !expected_address
&& !!ti
->TebBase
),
656 "Got unexpected TebBase %p, expected %p.\n", ti
->TebBase
, expected_address
);
663 if (!spi
->NextEntryOffset
)
665 winetest_pop_context();
668 one_before_last_pid
= last_pid
;
670 spi
= (SYSTEM_PROCESS_INFORMATION_PRIVATE
*)((char*)spi
+ spi
->NextEntryOffset
);
671 winetest_pop_context();
673 ok( current_process_found
, "Test process not found.\n" );
674 if (winetest_debug
> 1) trace("%u processes, %u threads\n", i
, k
);
676 if (one_before_last_pid
== 0) one_before_last_pid
= last_pid
;
678 HeapFree( GetProcessHeap(), 0, spi_buf
);
680 for (i
= 1; i
< 4; ++i
)
682 InitializeObjectAttributes( &attr
, NULL
, 0, NULL
, NULL
);
683 cid
.UniqueProcess
= ULongToHandle(GetCurrentProcessId() + i
);
684 cid
.UniqueThread
= 0;
686 status
= NtOpenProcess( &handle
, PROCESS_QUERY_LIMITED_INFORMATION
, &attr
, &cid
);
687 ok( status
== STATUS_SUCCESS
|| broken( status
== STATUS_ACCESS_DENIED
) /* wxppro */,
688 "NtOpenProcess returned:%lx\n", status
);
689 if (status
!= STATUS_SUCCESS
) continue;
691 status
= NtQueryInformationProcess( handle
, ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
692 ok( status
== STATUS_SUCCESS
, "NtQueryInformationProcess returned:%lx\n", status
);
693 ok( pbi
.UniqueProcessId
== GetCurrentProcessId(),
694 "Expected pid %p, got %p\n", ULongToHandle(GetCurrentProcessId()), ULongToHandle(pbi
.UniqueProcessId
) );
699 for (i
= 1; i
< 4; ++i
)
701 InitializeObjectAttributes( &attr
, NULL
, 0, NULL
, NULL
);
702 cid
.UniqueProcess
= 0;
703 cid
.UniqueThread
= ULongToHandle(GetCurrentThreadId() + i
);
705 status
= NtOpenThread( &handle
, THREAD_QUERY_LIMITED_INFORMATION
, &attr
, &cid
);
706 ok( status
== STATUS_SUCCESS
|| broken( status
== STATUS_ACCESS_DENIED
) /* wxppro */,
707 "NtOpenThread returned:%lx\n", status
);
708 if (status
!= STATUS_SUCCESS
) continue;
710 status
= pNtQueryInformationThread( handle
, ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
711 ok( status
== STATUS_SUCCESS
, "NtQueryInformationThread returned:%lx\n", status
);
712 ok( tbi
.ClientId
.UniqueThread
== ULongToHandle(GetCurrentThreadId()),
713 "Expected tid %p, got %p\n", ULongToHandle(GetCurrentThreadId()), tbi
.ClientId
.UniqueThread
);
717 winetest_pop_context();
720 static void test_query_procperf(void)
725 SYSTEM_BASIC_INFORMATION sbi
;
726 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
* sppi
;
728 /* Find out the number of processors */
729 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
730 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
731 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
733 sppi
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
735 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, 0, &ReturnLength
);
736 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
738 /* Try it for 1 processor */
739 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
740 sppi
->UserTime
.QuadPart
= 0xdeaddead;
741 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
742 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
,
743 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
), &ReturnLength
);
744 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
745 ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) == ReturnLength
,
746 "Inconsistent length %ld\n", ReturnLength
);
747 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
748 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
749 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
751 /* Try it for all processors */
752 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
753 sppi
->UserTime
.QuadPart
= 0xdeaddead;
754 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
755 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
, &ReturnLength
);
756 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
757 ok( NeededLength
== ReturnLength
, "Inconsistent length (%ld) <-> (%ld)\n", NeededLength
, ReturnLength
);
758 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
759 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
760 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
762 /* A too large given buffer size */
763 sppi
= HeapReAlloc(GetProcessHeap(), 0, sppi
, NeededLength
+ 2);
764 sppi
->KernelTime
.QuadPart
= 0xdeaddead;
765 sppi
->UserTime
.QuadPart
= 0xdeaddead;
766 sppi
->IdleTime
.QuadPart
= 0xdeaddead;
767 status
= pNtQuerySystemInformation(SystemProcessorPerformanceInformation
, sppi
, NeededLength
+ 2, &ReturnLength
);
768 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INFO_LENGTH_MISMATCH
/* vista */,
769 "Expected STATUS_SUCCESS or STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
770 ok( NeededLength
== ReturnLength
, "Inconsistent length (%ld) <-> (%ld)\n", NeededLength
, ReturnLength
);
771 if (status
== STATUS_SUCCESS
)
773 ok (sppi
->KernelTime
.QuadPart
!= 0xdeaddead, "KernelTime unchanged\n");
774 ok (sppi
->UserTime
.QuadPart
!= 0xdeaddead, "UserTime unchanged\n");
775 ok (sppi
->IdleTime
.QuadPart
!= 0xdeaddead, "IdleTime unchanged\n");
777 else /* vista and 2008 */
779 ok (sppi
->KernelTime
.QuadPart
== 0xdeaddead, "KernelTime changed\n");
780 ok (sppi
->UserTime
.QuadPart
== 0xdeaddead, "UserTime changed\n");
781 ok (sppi
->IdleTime
.QuadPart
== 0xdeaddead, "IdleTime changed\n");
784 HeapFree( GetProcessHeap(), 0, sppi
);
787 static void test_query_module(void)
789 const RTL_PROCESS_MODULE_INFORMATION_EX
*infoex
;
790 RTL_PROCESS_MODULES
*info
;
795 status
= pNtQuerySystemInformation(SystemModuleInformation
, NULL
, 0, &size
);
796 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", status
);
797 ok(size
> 0, "expected nonzero size\n");
800 status
= pNtQuerySystemInformation(SystemModuleInformation
, info
, size
, &size
);
801 ok(!status
, "got %#lx\n", status
);
803 ok(info
->ModulesCount
> 0, "Expected some modules to be loaded\n");
805 for (i
= 0; i
< info
->ModulesCount
; i
++)
807 RTL_PROCESS_MODULE_INFORMATION
*module
= &info
->Modules
[i
];
809 ok(module
->LoadOrderIndex
== i
, "%lu: got index %u\n", i
, module
->LoadOrderIndex
);
810 ok(module
->ImageBaseAddress
|| is_wow64
, "%lu: got NULL address for %s\n", i
, module
->Name
);
811 ok(module
->ImageSize
, "%lu: got 0 size\n", i
);
812 ok(module
->LoadCount
, "%lu: got 0 load count\n", i
);
817 status
= pNtQuerySystemInformation(SystemModuleInformationEx
, NULL
, 0, &size
);
818 if (status
== STATUS_INVALID_INFO_CLASS
)
820 win_skip("SystemModuleInformationEx is not supported.\n");
823 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", status
);
824 ok(size
> 0, "expected nonzero size\n");
826 buffer
= malloc(size
);
827 status
= pNtQuerySystemInformation(SystemModuleInformationEx
, buffer
, size
, &size
);
828 ok(!status
, "got %#lx\n", status
);
830 infoex
= (const void *)buffer
;
831 for (i
= 0; infoex
->NextOffset
; i
++)
833 const RTL_PROCESS_MODULE_INFORMATION
*module
= &infoex
->BaseInfo
;
835 ok(module
->LoadOrderIndex
== i
, "%lu: got index %u\n", i
, module
->LoadOrderIndex
);
836 ok(module
->ImageBaseAddress
|| is_wow64
, "%lu: got NULL address for %s\n", i
, module
->Name
);
837 ok(module
->ImageSize
, "%lu: got 0 size\n", i
);
838 ok(module
->LoadCount
, "%lu: got 0 load count\n", i
);
840 infoex
= (const void *)((const char *)infoex
+ infoex
->NextOffset
);
842 ok(((char *)infoex
- buffer
) + sizeof(infoex
->NextOffset
) == size
,
843 "got size %lu, null terminator %Iu\n", size
, (char *)infoex
- buffer
);
849 static void test_query_handle(void)
852 ULONG ExpectedLength
, ReturnLength
;
853 ULONG SystemInformationLength
= sizeof(SYSTEM_HANDLE_INFORMATION
);
854 SYSTEM_HANDLE_INFORMATION
* shi
= HeapAlloc(GetProcessHeap(), 0, SystemInformationLength
);
859 EventHandle
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
860 ok( EventHandle
!= NULL
, "CreateEventA failed %lu\n", GetLastError() );
861 ret
= SetHandleInformation(EventHandle
, HANDLE_FLAG_INHERIT
| HANDLE_FLAG_PROTECT_FROM_CLOSE
,
862 HANDLE_FLAG_INHERIT
| HANDLE_FLAG_PROTECT_FROM_CLOSE
);
863 ok(ret
, "got error %lu\n", GetLastError());
865 /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
866 ReturnLength
= 0xdeadbeef;
867 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
868 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
869 ok( ReturnLength
!= 0xdeadbeef, "Expected valid ReturnLength\n" );
871 SystemInformationLength
= ReturnLength
;
872 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
873 memset(shi
, 0x55, SystemInformationLength
);
875 ReturnLength
= 0xdeadbeef;
876 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
877 while (status
== STATUS_INFO_LENGTH_MISMATCH
) /* Vista / 2008 */
879 SystemInformationLength
*= 2;
880 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
881 memset(shi
, 0x55, SystemInformationLength
);
882 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
884 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
885 ExpectedLength
= FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION
, Handle
[shi
->Count
]);
886 ok( ReturnLength
== ExpectedLength
|| broken(ReturnLength
== ExpectedLength
- sizeof(DWORD
)), /* Vista / 2008 */
887 "Expected length %lu, got %lu\n", ExpectedLength
, ReturnLength
);
888 ok( shi
->Count
> 1, "Expected more than 1 handle, got %lu\n", shi
->Count
);
889 ok( shi
->Handle
[1].HandleValue
!= 0x5555 || broken( shi
->Handle
[1].HandleValue
== 0x5555 ), /* Vista / 2008 */
890 "Uninitialized second handle\n" );
891 if (shi
->Handle
[1].HandleValue
== 0x5555)
893 win_skip("Skipping broken SYSTEM_HANDLE_INFORMATION\n");
894 CloseHandle(EventHandle
);
899 for (i
= 0; i
< shi
->Count
; i
++)
901 if (shi
->Handle
[i
].OwnerPid
== GetCurrentProcessId() &&
902 (HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
)
904 ok(shi
->Handle
[i
].HandleFlags
== (OBJ_INHERIT
| OBJ_PROTECT_CLOSE
),
905 "got attributes %#x\n", shi
->Handle
[i
].HandleFlags
);
910 ok( found
, "Expected to find event handle %p (pid %lx) in handle list\n", EventHandle
, GetCurrentProcessId() );
912 ret
= SetHandleInformation(EventHandle
, HANDLE_FLAG_PROTECT_FROM_CLOSE
, 0);
913 ok(ret
, "got error %lu\n", GetLastError());
914 CloseHandle(EventHandle
);
916 ReturnLength
= 0xdeadbeef;
917 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
918 while (status
== STATUS_INFO_LENGTH_MISMATCH
) /* Vista / 2008 */
920 SystemInformationLength
*= 2;
921 shi
= HeapReAlloc(GetProcessHeap(), 0, shi
, SystemInformationLength
);
922 status
= pNtQuerySystemInformation(SystemHandleInformation
, shi
, SystemInformationLength
, &ReturnLength
);
924 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
925 for (i
= 0, found
= FALSE
; i
< shi
->Count
&& !found
; i
++)
926 found
= (shi
->Handle
[i
].OwnerPid
== GetCurrentProcessId()) &&
927 ((HANDLE
)(ULONG_PTR
)shi
->Handle
[i
].HandleValue
== EventHandle
);
928 ok( !found
, "Unexpectedly found event handle in handle list\n" );
930 status
= pNtQuerySystemInformation(SystemHandleInformation
, NULL
, SystemInformationLength
, &ReturnLength
);
931 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status
);
934 HeapFree( GetProcessHeap(), 0, shi
);
937 static void test_query_handle_ex(void)
939 SYSTEM_HANDLE_INFORMATION_EX
*info
= malloc(sizeof(SYSTEM_HANDLE_INFORMATION_EX
));
940 ULONG size
, expect_size
;
946 event
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
947 ok(event
!= NULL
, "failed to create event, error %lu\n", GetLastError());
948 ret
= SetHandleInformation(event
, HANDLE_FLAG_INHERIT
| HANDLE_FLAG_PROTECT_FROM_CLOSE
,
949 HANDLE_FLAG_INHERIT
| HANDLE_FLAG_PROTECT_FROM_CLOSE
);
950 ok(ret
, "got error %lu\n", GetLastError());
953 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, info
, sizeof(SYSTEM_HANDLE_INFORMATION_EX
), &size
);
954 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", status
);
955 ok(size
> sizeof(SYSTEM_HANDLE_INFORMATION_EX
), "got size %lu\n", size
);
957 while (status
== STATUS_INFO_LENGTH_MISMATCH
)
959 info
= realloc(info
, size
);
960 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, info
, size
, &size
);
962 ok(!status
, "got %#lx\n", status
);
963 expect_size
= FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX
, Handles
[info
->NumberOfHandles
]);
964 ok(size
== expect_size
, "expected size %lu, got %lu\n", expect_size
, size
);
965 ok(info
->NumberOfHandles
> 1, "got %Iu handles\n", info
->NumberOfHandles
);
968 for (i
= 0; i
< info
->NumberOfHandles
; ++i
)
970 if (info
->Handles
[i
].UniqueProcessId
== GetCurrentProcessId()
971 && (HANDLE
)info
->Handles
[i
].HandleValue
== event
)
973 ok(info
->Handles
[i
].HandleAttributes
== (OBJ_INHERIT
| OBJ_PROTECT_CLOSE
),
974 "got flags %#lx\n", info
->Handles
[i
].HandleAttributes
);
975 ok(info
->Handles
[i
].GrantedAccess
== EVENT_ALL_ACCESS
, "got access %#lx\n", info
->Handles
[i
].GrantedAccess
);
978 ok(!info
->Handles
[i
].CreatorBackTraceIndex
, "got backtrace index %u\n", info
->Handles
[i
].CreatorBackTraceIndex
);
980 ok(found
, "event handle not found\n");
982 ret
= SetHandleInformation(event
, HANDLE_FLAG_PROTECT_FROM_CLOSE
, 0);
983 ok(ret
, "got error %lu\n", GetLastError());
986 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, info
, size
, &size
);
987 while (status
== STATUS_INFO_LENGTH_MISMATCH
)
989 info
= realloc(info
, size
);
990 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, info
, size
, &size
);
992 ok(!status
, "got %#lx\n", status
);
993 expect_size
= FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX
, Handles
[info
->NumberOfHandles
]);
994 ok(size
== expect_size
, "expected size %lu, got %lu\n", expect_size
, size
);
995 ok(info
->NumberOfHandles
> 1, "got %Iu handles\n", info
->NumberOfHandles
);
998 for (i
= 0; i
< info
->NumberOfHandles
; ++i
)
1000 if (info
->Handles
[i
].UniqueProcessId
== GetCurrentProcessId()
1001 && (HANDLE
)info
->Handles
[i
].HandleValue
== event
)
1007 ok(!found
, "event handle found\n");
1009 status
= pNtQuerySystemInformation(SystemExtendedHandleInformation
, NULL
, sizeof(SYSTEM_HANDLE_INFORMATION_EX
), &size
);
1010 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status
);
1015 static void test_query_cache(void)
1020 SYSTEM_CACHE_INFORMATION
*sci
= (SYSTEM_CACHE_INFORMATION
*) buffer
;
1024 expected
= sizeof(SYSTEM_CACHE_INFORMATION
);
1025 for (i
= sizeof(buffer
); i
>= expected
; i
--)
1027 ReturnLength
= 0xdeadbeef;
1028 status
= pNtQuerySystemInformation(SystemFileCacheInformation
, sci
, i
, &ReturnLength
);
1029 ok(!status
&& (ReturnLength
== expected
),
1030 "%d: got 0x%lx and %lu (expected STATUS_SUCCESS and %lu)\n", i
, status
, ReturnLength
, expected
);
1033 /* buffer too small for the full result.
1034 Up to win7, the function succeeds with a partial result. */
1035 status
= pNtQuerySystemInformation(SystemFileCacheInformation
, sci
, i
, &ReturnLength
);
1038 expected
= 3 * sizeof(ULONG
);
1039 for (; i
>= expected
; i
--)
1041 ReturnLength
= 0xdeadbeef;
1042 status
= pNtQuerySystemInformation(SystemFileCacheInformation
, sci
, i
, &ReturnLength
);
1043 ok(!status
&& (ReturnLength
== expected
),
1044 "%d: got 0x%lx and %lu (expected STATUS_SUCCESS and %lu)\n", i
, status
, ReturnLength
, expected
);
1048 /* buffer too small for the result, this call will always fail */
1049 ReturnLength
= 0xdeadbeef;
1050 status
= pNtQuerySystemInformation(SystemFileCacheInformation
, sci
, i
, &ReturnLength
);
1051 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
1052 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
1053 "%d: got 0x%lx and %lu (expected STATUS_INFO_LENGTH_MISMATCH and %lu)\n", i
, status
, ReturnLength
, expected
);
1056 /* this crashes on some vista / win7 machines */
1057 ReturnLength
= 0xdeadbeef;
1058 status
= pNtQuerySystemInformation(SystemFileCacheInformation
, sci
, 0, &ReturnLength
);
1059 ok( status
== STATUS_INFO_LENGTH_MISMATCH
&&
1060 ((ReturnLength
== expected
) || broken(!ReturnLength
) || broken(ReturnLength
== 0xfffffff0)),
1061 "0: got 0x%lx and %lu (expected STATUS_INFO_LENGTH_MISMATCH and %lu)\n", status
, ReturnLength
, expected
);
1065 static void test_query_interrupt(void)
1070 SYSTEM_BASIC_INFORMATION sbi
;
1071 SYSTEM_INTERRUPT_INFORMATION
* sii
;
1073 /* Find out the number of processors */
1074 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), &ReturnLength
);
1075 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1076 NeededLength
= sbi
.NumberOfProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
);
1078 sii
= HeapAlloc(GetProcessHeap(), 0, NeededLength
);
1080 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, 0, &ReturnLength
);
1081 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1082 ok(ReturnLength
== NeededLength
, "got %lu\n", ReturnLength
);
1084 /* Try it for all processors */
1085 status
= pNtQuerySystemInformation(SystemInterruptInformation
, sii
, NeededLength
, &ReturnLength
);
1086 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1088 /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength
1089 * No test added for this as it's highly unlikely that an app depends on this
1092 HeapFree( GetProcessHeap(), 0, sii
);
1095 static void test_time_adjustment(void)
1097 SYSTEM_TIME_ADJUSTMENT_QUERY query
;
1098 SYSTEM_TIME_ADJUSTMENT adjust
;
1102 memset( &query
, 0xcc, sizeof(query
) );
1103 status
= pNtQuerySystemInformation( SystemTimeAdjustmentInformation
, &query
, sizeof(query
), &len
);
1104 ok( status
== STATUS_SUCCESS
, "got %08lx\n", status
);
1105 ok( len
== sizeof(query
) || broken(!len
) /* winxp */, "wrong len %lu\n", len
);
1106 ok( query
.TimeAdjustmentDisabled
== TRUE
|| query
.TimeAdjustmentDisabled
== FALSE
,
1107 "wrong value %x\n", query
.TimeAdjustmentDisabled
);
1109 status
= pNtQuerySystemInformation( SystemTimeAdjustmentInformation
, &query
, sizeof(query
)-1, &len
);
1110 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %08lx\n", status
);
1111 ok( len
== sizeof(query
) || broken(!len
) /* winxp */, "wrong len %lu\n", len
);
1113 status
= pNtQuerySystemInformation( SystemTimeAdjustmentInformation
, &query
, sizeof(query
)+1, &len
);
1114 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %08lx\n", status
);
1115 ok( len
== sizeof(query
) || broken(!len
) /* winxp */, "wrong len %lu\n", len
);
1117 adjust
.TimeAdjustment
= query
.TimeAdjustment
;
1118 adjust
.TimeAdjustmentDisabled
= query
.TimeAdjustmentDisabled
;
1119 status
= pNtSetSystemInformation( SystemTimeAdjustmentInformation
, &adjust
, sizeof(adjust
) );
1120 ok( status
== STATUS_SUCCESS
|| status
== STATUS_PRIVILEGE_NOT_HELD
, "got %08lx\n", status
);
1121 status
= pNtSetSystemInformation( SystemTimeAdjustmentInformation
, &adjust
, sizeof(adjust
)-1 );
1123 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %08lx\n", status
);
1124 status
= pNtSetSystemInformation( SystemTimeAdjustmentInformation
, &adjust
, sizeof(adjust
)+1 );
1126 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %08lx\n", status
);
1129 static void test_query_kerndebug(void)
1133 /* some Windows version expect alignment */
1134 SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX
DECLSPEC_ALIGN(4) skdi_ex
;
1135 SYSTEM_KERNEL_DEBUGGER_INFORMATION
DECLSPEC_ALIGN(4) skdi
;
1137 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, 0, &ReturnLength
);
1138 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1140 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
), &ReturnLength
);
1141 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1142 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1144 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformation
, &skdi
, sizeof(skdi
) + 2, &ReturnLength
);
1145 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1146 ok( sizeof(skdi
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1148 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformationEx
, &skdi_ex
, 0, &ReturnLength
);
1149 ok( status
== STATUS_INFO_LENGTH_MISMATCH
1150 || status
== STATUS_NOT_IMPLEMENTED
/* before win7 */
1151 || status
== STATUS_INVALID_INFO_CLASS
/* wow64 on Win10 */,
1152 "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1154 if (status
!= STATUS_INFO_LENGTH_MISMATCH
)
1156 win_skip( "NtQuerySystemInformation(SystemKernelDebuggerInformationEx) is not implemented.\n" );
1160 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformationEx
, &skdi_ex
,
1161 sizeof(skdi_ex
), &ReturnLength
);
1162 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1163 ok( sizeof(skdi_ex
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1165 status
= pNtQuerySystemInformation(SystemKernelDebuggerInformationEx
, &skdi_ex
,
1166 sizeof(skdi_ex
) + 2, &ReturnLength
);
1167 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1168 ok( sizeof(skdi_ex
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1172 static void test_query_regquota(void)
1176 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi
;
1178 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, 0, &ReturnLength
);
1179 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1181 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
), &ReturnLength
);
1182 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1183 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1185 status
= pNtQuerySystemInformation(SystemRegistryQuotaInformation
, &srqi
, sizeof(srqi
) + 2, &ReturnLength
);
1186 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1187 ok( sizeof(srqi
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1190 static void test_query_logicalproc(void)
1193 ULONG len
, i
, proc_no
;
1194 SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*slpi
;
1199 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, NULL
, 0, &len
);
1200 if (status
== STATUS_INVALID_INFO_CLASS
) /* wow64 win8+, arm64 */
1202 skip("SystemLogicalProcessorInformation is not supported\n");
1205 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1206 ok(len
%sizeof(*slpi
) == 0, "Incorrect length %ld\n", len
);
1208 slpi
= HeapAlloc(GetProcessHeap(), 0, len
);
1209 status
= pNtQuerySystemInformation(SystemLogicalProcessorInformation
, slpi
, len
, &len
);
1210 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1213 for(i
=0; i
<len
/sizeof(*slpi
); i
++) {
1214 switch(slpi
[i
].Relationship
) {
1215 case RelationProcessorCore
:
1216 /* Get number of logical processors */
1217 for(; slpi
[i
].ProcessorMask
; slpi
[i
].ProcessorMask
/= 2)
1218 proc_no
+= slpi
[i
].ProcessorMask
%2;
1224 ok(proc_no
> 0, "No processors were found\n");
1225 if(si
.dwNumberOfProcessors
<= 32)
1226 ok(proc_no
== si
.dwNumberOfProcessors
, "Incorrect number of logical processors: %ld, expected %ld\n",
1227 proc_no
, si
.dwNumberOfProcessors
);
1229 HeapFree(GetProcessHeap(), 0, slpi
);
1232 static void test_query_logicalprocex(void)
1234 static const char * const names
[] = { "Core", "NumaNode", "Cache", "Package", "Group", "Die", "NumaNodeEx", "Module" };
1235 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*infoex
, *infoex_public
, *infoex_core
, *infoex_numa
, *infoex_cache
,
1236 *infoex_package
, *infoex_group
, *infoex_die
, *infoex_numa_ex
,
1237 *infoex_module
, *ex
;
1238 DWORD relationship
, len
, len_public
, len_core
, len_numa
, len_cache
, len_package
, len_group
, len_die
, len_numa_ex
,
1239 len_module
, len_union
, ret_len
;
1244 if (!pNtQuerySystemInformationEx
)
1248 relationship
= RelationAll
;
1249 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len
);
1250 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08lx\n", status
);
1251 ok(len
> 0, "got %lu\n", len
);
1254 relationship
= RelationProcessorCore
;
1255 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_core
);
1256 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08lx\n", status
);
1257 ok(len_core
> 0, "got %lu\n", len_core
);
1260 relationship
= RelationNumaNode
;
1261 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_numa
);
1262 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08lx\n", status
);
1263 ok(len_numa
> 0, "got %lu\n", len_numa
);
1266 relationship
= RelationCache
;
1267 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_cache
);
1268 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08lx\n", status
);
1269 ok(len_cache
> 0, "got %lu\n", len_cache
);
1272 relationship
= RelationProcessorPackage
;
1273 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_package
);
1274 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08lx\n", status
);
1275 ok(len_package
> 0, "got %lu\n", len_package
);
1278 relationship
= RelationGroup
;
1279 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_group
);
1280 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got 0x%08lx\n", status
);
1281 ok(len_group
> 0, "got %lu\n", len_group
);
1283 relationship
= RelationProcessorDie
;
1284 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_die
);
1285 todo_wine
ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_UNSUCCESSFUL
|| broken(status
== STATUS_SUCCESS
),
1286 "got 0x%08lx\n", status
);
1289 relationship
= RelationNumaNodeEx
;
1290 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_numa_ex
);
1291 todo_wine
ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_UNSUCCESSFUL
|| broken(status
== STATUS_SUCCESS
),
1292 "got 0x%08lx\n", status
);
1295 relationship
= RelationProcessorModule
;
1296 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), NULL
, 0, &len_module
);
1297 todo_wine
ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_UNSUCCESSFUL
|| broken(status
== STATUS_SUCCESS
),
1298 "got 0x%08lx\n", status
);
1301 ret
= pGetLogicalProcessorInformationEx(RelationAll
, NULL
, &len_public
);
1302 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %d, error %ld\n", ret
, GetLastError());
1303 ok(len
== len_public
, "got %lu, expected %lu\n", len_public
, len
);
1305 infoex
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1306 infoex_public
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_public
);
1307 infoex_core
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_core
);
1308 infoex_numa
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_numa
);
1309 infoex_cache
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_cache
);
1310 infoex_package
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_package
);
1311 infoex_group
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_group
);
1312 infoex_die
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_die
);
1313 infoex_numa_ex
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_numa_ex
);
1314 infoex_module
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len_module
);
1316 relationship
= RelationAll
;
1317 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex
, len
, &ret_len
);
1318 ok(status
== STATUS_SUCCESS
, "got 0x%08lx\n", status
);
1319 ok(ret_len
== len
, "got %08lx expected %08lx\n", ret_len
, len
);
1321 ret
= pGetLogicalProcessorInformationEx(RelationAll
, infoex_public
, &len_public
);
1322 ok(ret
, "got %d, error %ld\n", ret
, GetLastError());
1323 ok(!memcmp(infoex
, infoex_public
, len
), "returned info data mismatch\n");
1325 /* Test for RelationAll. */
1326 for (i
= 0; status
== STATUS_SUCCESS
&& i
< len
; )
1328 ex
= (void *)(((char *)infoex
) + i
);
1329 ok(ex
->Size
, "%u: got size 0\n", i
);
1331 if (winetest_debug
<= 1)
1337 trace("infoex[%u].Size: %lu\n", i
, ex
->Size
);
1338 switch (ex
->Relationship
)
1340 case RelationProcessorCore
:
1341 case RelationProcessorPackage
:
1342 case RelationProcessorDie
:
1343 case RelationProcessorModule
:
1344 trace("infoex[%u].Relationship: 0x%x (%s)\n", i
, ex
->Relationship
, names
[ex
->Relationship
]);
1345 trace("infoex[%u].Processor.Flags: 0x%x\n", i
, ex
->Processor
.Flags
);
1346 trace("infoex[%u].Processor.EfficiencyClass: 0x%x\n", i
, ex
->Processor
.EfficiencyClass
);
1347 trace("infoex[%u].Processor.GroupCount: 0x%x\n", i
, ex
->Processor
.GroupCount
);
1348 for (j
= 0; j
< ex
->Processor
.GroupCount
; ++j
)
1350 trace("infoex[%u].Processor.GroupMask[%u].Mask: 0x%Ix\n", i
, j
, ex
->Processor
.GroupMask
[j
].Mask
);
1351 trace("infoex[%u].Processor.GroupMask[%u].Group: 0x%x\n", i
, j
, ex
->Processor
.GroupMask
[j
].Group
);
1354 case RelationNumaNode
:
1355 case RelationNumaNodeEx
:
1356 trace("infoex[%u].Relationship: 0x%x (%s)\n", i
, ex
->Relationship
, names
[ex
->Relationship
]);
1357 trace("infoex[%u].NumaNode.NodeNumber: 0x%lx\n", i
, ex
->NumaNode
.NodeNumber
);
1358 trace("infoex[%u].NumaNode.GroupMask.Mask: 0x%Ix\n", i
, ex
->NumaNode
.GroupMask
.Mask
);
1359 trace("infoex[%u].NumaNode.GroupMask.Group: 0x%x\n", i
, ex
->NumaNode
.GroupMask
.Group
);
1362 trace("infoex[%u].Relationship: 0x%x (Cache)\n", i
, ex
->Relationship
);
1363 trace("infoex[%u].Cache.Level: 0x%x\n", i
, ex
->Cache
.Level
);
1364 trace("infoex[%u].Cache.Associativity: 0x%x\n", i
, ex
->Cache
.Associativity
);
1365 trace("infoex[%u].Cache.LineSize: 0x%x\n", i
, ex
->Cache
.LineSize
);
1366 trace("infoex[%u].Cache.CacheSize: 0x%lx\n", i
, ex
->Cache
.CacheSize
);
1367 trace("infoex[%u].Cache.Type: 0x%x\n", i
, ex
->Cache
.Type
);
1368 trace("infoex[%u].Cache.GroupMask.Mask: 0x%Ix\n", i
, ex
->Cache
.GroupMask
.Mask
);
1369 trace("infoex[%u].Cache.GroupMask.Group: 0x%x\n", i
, ex
->Cache
.GroupMask
.Group
);
1372 trace("infoex[%u].Relationship: 0x%x (Group)\n", i
, ex
->Relationship
);
1373 trace("infoex[%u].Group.MaximumGroupCount: 0x%x\n", i
, ex
->Group
.MaximumGroupCount
);
1374 trace("infoex[%u].Group.ActiveGroupCount: 0x%x\n", i
, ex
->Group
.ActiveGroupCount
);
1375 for (j
= 0; j
< ex
->Group
.ActiveGroupCount
; ++j
)
1377 trace("infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].MaximumProcessorCount
);
1378 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorCount
);
1379 trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%Ix\n", i
, j
, ex
->Group
.GroupInfo
[j
].ActiveProcessorMask
);
1383 ok(0, "Got invalid relationship value: 0x%x\n", ex
->Relationship
);
1390 /* Test Relationship filtering. */
1392 relationship
= RelationProcessorCore
;
1393 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex_core
, len_core
, &len_core
);
1394 ok(status
== STATUS_SUCCESS
, "got 0x%08lx\n", status
);
1396 for (i
= 0; status
== STATUS_SUCCESS
&& i
< len_core
;)
1398 ex
= (void *)(((char*)infoex_core
) + i
);
1399 ok(ex
->Size
, "%u: got size 0\n", i
);
1400 ok(ex
->Relationship
== RelationProcessorCore
, "%u: got relationship %#x\n", i
, ex
->Relationship
);
1404 relationship
= RelationNumaNode
;
1405 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex_numa
, len_numa
, &len_numa
);
1406 ok(status
== STATUS_SUCCESS
, "got 0x%08lx\n", status
);
1408 for (i
= 0; status
== STATUS_SUCCESS
&& i
< len_numa
;)
1410 ex
= (void *)(((char*)infoex_numa
) + i
);
1411 ok(ex
->Size
, "%u: got size 0\n", i
);
1412 ok(ex
->Relationship
== RelationNumaNode
, "%u: got relationship %#x\n", i
, ex
->Relationship
);
1416 relationship
= RelationCache
;
1417 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex_cache
, len_cache
, &len_cache
);
1418 ok(status
== STATUS_SUCCESS
, "got 0x%08lx\n", status
);
1420 for (i
= 0; status
== STATUS_SUCCESS
&& i
< len_cache
;)
1422 ex
= (void *)(((char*)infoex_cache
) + i
);
1423 ok(ex
->Size
, "%u: got size 0\n", i
);
1424 ok(ex
->Relationship
== RelationCache
, "%u: got relationship %#x\n", i
, ex
->Relationship
);
1428 relationship
= RelationProcessorPackage
;
1429 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex_package
, len_package
, &len_package
);
1430 ok(status
== STATUS_SUCCESS
, "got 0x%08lx\n", status
);
1432 for (i
= 0; status
== STATUS_SUCCESS
&& i
< len_package
;)
1434 ex
= (void *)(((char*)infoex_package
) + i
);
1435 ok(ex
->Size
, "%u: got size 0\n", i
);
1436 ok(ex
->Relationship
== RelationProcessorPackage
, "%u: got relationship %#x\n", i
, ex
->Relationship
);
1440 relationship
= RelationGroup
;
1441 status
= pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx
, &relationship
, sizeof(relationship
), infoex_group
, len_group
, &len_group
);
1442 ok(status
== STATUS_SUCCESS
, "got 0x%08lx\n", status
);
1444 for (i
= 0; status
== STATUS_SUCCESS
&& i
< len_group
;)
1446 ex
= (void *)(((char *)infoex_group
) + i
);
1447 ok(ex
->Size
, "%u: got size 0\n", i
);
1448 ok(ex
->Relationship
== RelationGroup
, "%u: got relationship %#x\n", i
, ex
->Relationship
);
1452 len_union
= len_core
+ len_numa
+ len_cache
+ len_package
+ len_group
+ len_module
;
1453 ok(len
== len_union
, "Expected %lu, got %lu\n", len
, len_union
);
1455 HeapFree(GetProcessHeap(), 0, infoex
);
1456 HeapFree(GetProcessHeap(), 0, infoex_public
);
1457 HeapFree(GetProcessHeap(), 0, infoex_core
);
1458 HeapFree(GetProcessHeap(), 0, infoex_numa
);
1459 HeapFree(GetProcessHeap(), 0, infoex_cache
);
1460 HeapFree(GetProcessHeap(), 0, infoex_package
);
1461 HeapFree(GetProcessHeap(), 0, infoex_group
);
1462 HeapFree(GetProcessHeap(), 0, infoex_die
);
1463 HeapFree(GetProcessHeap(), 0, infoex_numa_ex
);
1464 HeapFree(GetProcessHeap(), 0, infoex_module
);
1467 static void test_query_cpusetinfo(void)
1469 SYSTEM_CPU_SET_INFORMATION
*info
;
1470 unsigned int i
, cpu_count
;
1471 ULONG len
, expected_len
;
1476 if (!pNtQuerySystemInformationEx
)
1480 cpu_count
= si
.dwNumberOfProcessors
;
1481 expected_len
= cpu_count
* sizeof(*info
);
1483 process
= GetCurrentProcess();
1485 status
= pNtQuerySystemInformationEx(SystemCpuSetInformation
, &process
, sizeof(process
), NULL
, 0, &len
);
1486 if (status
== STATUS_INVALID_INFO_CLASS
)
1488 win_skip("SystemCpuSetInformation is not supported\n");
1492 ok(status
== STATUS_BUFFER_TOO_SMALL
, "Got unexpected status %#lx.\n", status
);
1493 ok(len
== expected_len
, "Got unexpected length %lu.\n", len
);
1496 status
= pNtQuerySystemInformation(SystemCpuSetInformation
, NULL
, 0, &len
);
1497 ok(status
== STATUS_INVALID_PARAMETER
|| status
== STATUS_INVALID_INFO_CLASS
,
1498 "Got unexpected status %#lx.\n", status
);
1499 ok(len
== 0xdeadbeef, "Got unexpected len %lu.\n", len
);
1502 process
= (HANDLE
)0xdeadbeef;
1503 status
= pNtQuerySystemInformationEx(SystemCpuSetInformation
, &process
, sizeof(process
), NULL
, 0, &len
);
1504 ok(status
== STATUS_INVALID_HANDLE
, "Got unexpected status %#lx.\n", status
);
1505 ok(len
== 0xdeadbeef, "Got unexpected length %lu.\n", len
);
1509 status
= pNtQuerySystemInformationEx(SystemCpuSetInformation
, &process
, 4 * sizeof(process
), NULL
, 0, &len
);
1510 ok((status
== STATUS_INVALID_PARAMETER
&& len
== 0xdeadbeef)
1511 || (status
== STATUS_BUFFER_TOO_SMALL
&& len
== expected_len
),
1512 "Got unexpected status %#lx, length %lu.\n", status
, len
);
1515 status
= pNtQuerySystemInformationEx(SystemCpuSetInformation
, NULL
, sizeof(process
), NULL
, 0, &len
);
1516 ok(status
== STATUS_INVALID_PARAMETER
, "Got unexpected status %#lx.\n", status
);
1517 ok(len
== 0xdeadbeef, "Got unexpected length %lu.\n", len
);
1519 status
= pNtQuerySystemInformationEx(SystemCpuSetInformation
, &process
, sizeof(process
), NULL
, 0, &len
);
1520 ok(status
== STATUS_BUFFER_TOO_SMALL
, "Got unexpected status %#lx.\n", status
);
1521 ok(len
== expected_len
, "Got unexpected length %lu.\n", len
);
1524 status
= pNtQuerySystemInformationEx(SystemCpuSetInformation
, &process
, sizeof(process
), NULL
,
1525 expected_len
, &len
);
1526 ok(status
== STATUS_ACCESS_VIOLATION
, "Got unexpected status %#lx.\n", status
);
1527 ok(len
== 0xdeadbeef, "Got unexpected length %lu.\n", len
);
1529 info
= malloc(expected_len
);
1531 status
= pNtQuerySystemInformationEx(SystemCpuSetInformation
, &process
, sizeof(process
), info
, expected_len
, &len
);
1532 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#lx.\n", status
);
1533 ok(len
== expected_len
, "Got unexpected length %lu.\n", len
);
1535 for (i
= 0; i
< cpu_count
; ++i
)
1537 SYSTEM_CPU_SET_INFORMATION
*d
= &info
[i
];
1539 ok(d
->Size
== sizeof(*d
), "Got unexpected size %lu, i %u.\n", d
->Size
, i
);
1540 ok(d
->Type
== CpuSetInformation
, "Got unexpected type %u, i %u.\n", d
->Type
, i
);
1541 ok(d
->CpuSet
.Id
== 0x100 + i
, "Got unexpected Id %#lx, i %u.\n", d
->CpuSet
.Id
, i
);
1542 ok(!d
->CpuSet
.Group
, "Got unexpected Group %u, i %u.\n", d
->CpuSet
.Group
, i
);
1543 ok(d
->CpuSet
.LogicalProcessorIndex
== i
, "Got unexpected LogicalProcessorIndex %u, i %u.\n",
1544 d
->CpuSet
.LogicalProcessorIndex
, i
);
1545 ok(!d
->CpuSet
.AllFlags
, "Got unexpected AllFlags %#x, i %u.\n", d
->CpuSet
.AllFlags
, i
);
1550 static void test_query_firmware(void)
1552 static const ULONG min_sfti_len
= FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION
, TableBuffer
);
1555 SYSTEM_FIRMWARE_TABLE_INFORMATION
*sfti
;
1557 sfti
= HeapAlloc(GetProcessHeap(), 0, sizeof(*sfti
));
1558 ok(!!sfti
, "Failed to allocate memory\n");
1560 sfti
->ProviderSignature
= 0;
1564 status
= pNtQuerySystemInformation(SystemFirmwareTableInformation
, sfti
, min_sfti_len
- 1, &len1
);
1565 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* xp */,
1566 "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1567 if (len1
== 0) /* xp, 2003 */
1569 win_skip("SystemFirmwareTableInformation is not available\n");
1570 HeapFree(GetProcessHeap(), 0, sfti
);
1573 ok(len1
== min_sfti_len
, "Expected length %lu, got %lu\n", min_sfti_len
, len1
);
1575 status
= pNtQuerySystemInformation(SystemFirmwareTableInformation
, sfti
, min_sfti_len
, &len1
);
1576 ok(status
== STATUS_NOT_IMPLEMENTED
, "Expected STATUS_NOT_IMPLEMENTED, got %08lx\n", status
);
1577 ok(len1
== 0, "Expected length 0, got %lu\n", len1
);
1579 sfti
->ProviderSignature
= RSMB
;
1580 sfti
->Action
= SystemFirmwareTable_Get
;
1582 status
= pNtQuerySystemInformation(SystemFirmwareTableInformation
, sfti
, min_sfti_len
, &len1
);
1583 ok(status
== STATUS_BUFFER_TOO_SMALL
, "Expected STATUS_BUFFER_TOO_SMALL, got %08lx\n", status
);
1584 ok(len1
>= min_sfti_len
, "Expected length >= %lu, got %lu\n", min_sfti_len
, len1
);
1585 ok(sfti
->TableBufferLength
== len1
- min_sfti_len
,
1586 "Expected length %lu, got %lu\n", len1
- min_sfti_len
, sfti
->TableBufferLength
);
1588 sfti
= HeapReAlloc(GetProcessHeap(), 0, sfti
, len1
);
1589 ok(!!sfti
, "Failed to allocate memory\n");
1591 status
= pNtQuerySystemInformation(SystemFirmwareTableInformation
, sfti
, len1
, &len2
);
1592 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1593 ok(len2
== len1
, "Expected length %lu, got %lu\n", len1
, len2
);
1594 ok(sfti
->TableBufferLength
== len1
- min_sfti_len
,
1595 "Expected length %lu, got %lu\n", len1
- min_sfti_len
, sfti
->TableBufferLength
);
1597 HeapFree(GetProcessHeap(), 0, sfti
);
1600 static void test_query_battery(void)
1602 SYSTEM_BATTERY_STATE bs
;
1606 memset(&bs
, 0x23, sizeof(bs
));
1607 status
= NtPowerInformation(SystemBatteryState
, NULL
, 0, &bs
, sizeof(bs
));
1608 if (status
== STATUS_NOT_IMPLEMENTED
)
1610 skip("SystemBatteryState not implemented\n");
1613 ok(status
== STATUS_SUCCESS
, "expected success\n");
1615 if (winetest_debug
> 1)
1617 trace("Battery state:\n");
1618 trace("AcOnLine : %u\n", bs
.AcOnLine
);
1619 trace("BatteryPresent : %u\n", bs
.BatteryPresent
);
1620 trace("Charging : %u\n", bs
.Charging
);
1621 trace("Discharging : %u\n", bs
.Discharging
);
1622 trace("Tag : %u\n", bs
.Tag
);
1623 trace("MaxCapacity : %lu\n", bs
.MaxCapacity
);
1624 trace("RemainingCapacity : %lu\n", bs
.RemainingCapacity
);
1625 trace("Rate : %ld\n", (LONG
)bs
.Rate
);
1626 trace("EstimatedTime : %lu\n", bs
.EstimatedTime
);
1627 trace("DefaultAlert1 : %lu\n", bs
.DefaultAlert1
);
1628 trace("DefaultAlert2 : %lu\n", bs
.DefaultAlert2
);
1631 ok(bs
.MaxCapacity
>= bs
.RemainingCapacity
,
1632 "expected MaxCapacity %lu to be greater than or equal to RemainingCapacity %lu\n",
1633 bs
.MaxCapacity
, bs
.RemainingCapacity
);
1635 if (!bs
.BatteryPresent
)
1637 else if (!bs
.Charging
&& (LONG
)bs
.Rate
< 0)
1638 time_left
= 3600 * bs
.RemainingCapacity
/ -(LONG
)bs
.Rate
;
1641 ok(bs
.EstimatedTime
== time_left
,
1642 "expected %lu minutes remaining got %lu minutes\n", time_left
, bs
.EstimatedTime
);
1645 static void test_query_processor_power_info(void)
1648 PROCESSOR_POWER_INFORMATION
* ppi
;
1654 size
= si
.dwNumberOfProcessors
* sizeof(PROCESSOR_POWER_INFORMATION
);
1655 ppi
= HeapAlloc(GetProcessHeap(), 0, size
);
1657 /* If size < (sizeof(PROCESSOR_POWER_INFORMATION) * NumberOfProcessors), Win7 returns
1658 * STATUS_BUFFER_TOO_SMALL. WinXP returns STATUS_SUCCESS for any value of size. It copies as
1659 * many whole PROCESSOR_POWER_INFORMATION structures that there is room for. Even if there is
1660 * not enough room for one structure, WinXP still returns STATUS_SUCCESS having done nothing.
1662 * If ppi == NULL, Win7 returns STATUS_INVALID_PARAMETER while WinXP returns STATUS_SUCCESS
1665 * The same behavior is seen with CallNtPowerInformation (in powrprof.dll).
1668 if (si
.dwNumberOfProcessors
> 1)
1670 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
1671 ppi
[i
].Number
= 0xDEADBEEF;
1673 /* Call with a buffer size that is large enough to hold at least one but not large
1674 * enough to hold them all. This will be STATUS_SUCCESS on WinXP but not on Win7 */
1675 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
- sizeof(PROCESSOR_POWER_INFORMATION
));
1676 if (status
== STATUS_SUCCESS
)
1678 /* lax version found on older Windows like WinXP */
1679 ok( (ppi
[si
.dwNumberOfProcessors
- 2].Number
!= 0xDEADBEEF) &&
1680 (ppi
[si
.dwNumberOfProcessors
- 1].Number
== 0xDEADBEEF),
1681 "Expected all but the last record to be overwritten.\n");
1683 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
1684 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1686 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
1687 ppi
[i
].Number
= 0xDEADBEEF;
1688 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, sizeof(PROCESSOR_POWER_INFORMATION
) - 1);
1689 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1690 for(i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
1691 if (ppi
[i
].Number
!= 0xDEADBEEF) break;
1692 ok( i
== si
.dwNumberOfProcessors
, "Expected untouched buffer\n");
1696 /* picky version found on newer Windows like Win7 */
1697 ok( ppi
[1].Number
== 0xDEADBEEF, "Expected untouched buffer.\n");
1698 ok( status
== STATUS_BUFFER_TOO_SMALL
, "Expected STATUS_BUFFER_TOO_SMALL, got %08lx\n", status
);
1700 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, 0, size
);
1701 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, "Got %08lx\n", status
);
1703 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, 0);
1704 ok( status
== STATUS_BUFFER_TOO_SMALL
|| status
== STATUS_INVALID_PARAMETER
, "Got %08lx\n", status
);
1709 skip("Test needs more than one processor.\n");
1712 status
= pNtPowerInformation(ProcessorInformation
, 0, 0, ppi
, size
);
1713 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1715 HeapFree(GetProcessHeap(), 0, ppi
);
1718 static void test_query_process_wow64(void)
1722 ULONG_PTR pbi
[2], dummy
;
1724 memset(&dummy
, 0xcc, sizeof(dummy
));
1726 /* Do not give a handle and buffer */
1727 status
= NtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, 0, NULL
);
1728 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1730 /* Use a correct info class and buffer size, but still no handle and buffer */
1731 status
= NtQueryInformationProcess(NULL
, ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
1732 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1733 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE, got %08lx\n", status
);
1735 /* Use a correct info class, buffer size and handle, but no buffer */
1736 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, NULL
, sizeof(ULONG_PTR
), NULL
);
1737 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status
);
1739 /* Use a correct info class, buffer and buffer size, but no handle */
1740 pbi
[0] = pbi
[1] = dummy
;
1741 status
= NtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
1742 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
1743 ok( pbi
[0] == dummy
, "pbi[0] changed to %Ix\n", pbi
[0]);
1744 ok( pbi
[1] == dummy
, "pbi[1] changed to %Ix\n", pbi
[1]);
1746 /* Use a greater buffer size */
1747 pbi
[0] = pbi
[1] = dummy
;
1748 status
= NtQueryInformationProcess(NULL
, ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, NULL
);
1749 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1750 ok( pbi
[0] == dummy
, "pbi[0] changed to %Ix\n", pbi
[0]);
1751 ok( pbi
[1] == dummy
, "pbi[1] changed to %Ix\n", pbi
[1]);
1753 /* Use no ReturnLength */
1754 pbi
[0] = pbi
[1] = dummy
;
1755 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), NULL
);
1756 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1757 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %Ix\n", is_wow64
, pbi
[0]);
1759 ok( (void *)pbi
[0] == NtCurrentTeb()->Peb
, "pbi[0] %Ix / %p\n", pbi
[0], NtCurrentTeb()->Peb
);
1760 ok( pbi
[1] == dummy
, "pbi[1] changed to %Ix\n", pbi
[1]);
1761 /* Test written size on 64 bit by checking high 32 bit buffer */
1762 if (sizeof(ULONG_PTR
) > sizeof(DWORD
))
1764 DWORD
*ptr
= (DWORD
*)pbi
;
1765 ok( ptr
[1] != (DWORD
)dummy
, "ptr[1] unchanged!\n");
1768 /* Finally some correct calls */
1769 pbi
[0] = pbi
[1] = dummy
;
1770 ReturnLength
= 0xdeadbeef;
1771 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
), &ReturnLength
);
1772 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1773 ok( is_wow64
== (pbi
[0] != 0), "is_wow64 %x, pbi[0] %Ix\n", is_wow64
, pbi
[0]);
1775 ok( (void *)pbi
[0] == NtCurrentTeb()->Peb
, "pbi[0] %Ix / %p\n", pbi
[0], NtCurrentTeb()->Peb
);
1776 ok( pbi
[1] == dummy
, "pbi[1] changed to %Ix\n", pbi
[1]);
1777 ok( ReturnLength
== sizeof(ULONG_PTR
), "Inconsistent length %ld\n", ReturnLength
);
1779 /* Everything is correct except a too small buffer size */
1780 pbi
[0] = pbi
[1] = dummy
;
1781 ReturnLength
= 0xdeadbeef;
1782 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) - 1, &ReturnLength
);
1783 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1784 ok( pbi
[0] == dummy
, "pbi[0] changed to %Ix\n", pbi
[0]);
1785 ok( pbi
[1] == dummy
, "pbi[1] changed to %Ix\n", pbi
[1]);
1786 ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", ReturnLength
);
1788 /* Everything is correct except a too large buffer size */
1789 pbi
[0] = pbi
[1] = dummy
;
1790 ReturnLength
= 0xdeadbeef;
1791 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information
, pbi
, sizeof(ULONG_PTR
) + 1, &ReturnLength
);
1792 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1793 ok( pbi
[0] == dummy
, "pbi[0] changed to %Ix\n", pbi
[0]);
1794 ok( pbi
[1] == dummy
, "pbi[1] changed to %Ix\n", pbi
[1]);
1795 ok( ReturnLength
== 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", ReturnLength
);
1798 static void test_query_process_basic(void)
1803 typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE
{
1804 DWORD_PTR ExitStatus
;
1805 PPEB PebBaseAddress
;
1806 DWORD_PTR AffinityMask
;
1807 DWORD_PTR BasePriority
;
1808 ULONG_PTR UniqueProcessId
;
1809 ULONG_PTR InheritedFromUniqueProcessId
;
1810 } PROCESS_BASIC_INFORMATION_PRIVATE
;
1812 PROCESS_BASIC_INFORMATION_PRIVATE pbi
;
1814 /* This test also covers some basic parameter testing that should be the same for
1815 * every information class
1818 status
= NtQueryInformationProcess(NULL
, -1, NULL
, 0, NULL
);
1819 ok( status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
/* vista */,
1820 "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08lx\n", status
);
1822 status
= NtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, 0, NULL
);
1823 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1825 status
= NtQueryInformationProcess(NULL
, ProcessBasicInformation
, NULL
, sizeof(pbi
), NULL
);
1826 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1827 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status
);
1829 status
= NtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1830 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
1832 status
= NtQueryInformationProcess(NULL
, ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, NULL
);
1833 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1835 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
1836 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1838 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), &ReturnLength
);
1839 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1840 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1842 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
) * 2, &ReturnLength
);
1843 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1844 ok( sizeof(pbi
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1846 if (winetest_debug
> 1) trace("ProcessID : %Ix\n", pbi
.UniqueProcessId
);
1847 ok( pbi
.UniqueProcessId
> 0, "Expected a ProcessID > 0, got 0\n");
1850 static void dump_vm_counters(const char *header
, const VM_COUNTERS_EX
*pvi
)
1852 trace("%s:\n", header
);
1853 trace("PeakVirtualSize : %Iu\n", pvi
->PeakVirtualSize
);
1854 trace("VirtualSize : %Iu\n", pvi
->VirtualSize
);
1855 trace("PageFaultCount : %lu\n", pvi
->PageFaultCount
);
1856 trace("PeakWorkingSetSize : %Iu\n", pvi
->PeakWorkingSetSize
);
1857 trace("WorkingSetSize : %Iu\n", pvi
->WorkingSetSize
);
1858 trace("QuotaPeakPagedPoolUsage : %Iu\n", pvi
->QuotaPeakPagedPoolUsage
);
1859 trace("QuotaPagedPoolUsage : %Iu\n", pvi
->QuotaPagedPoolUsage
);
1860 trace("QuotaPeakNonPagePoolUsage : %Iu\n", pvi
->QuotaPeakNonPagedPoolUsage
);
1861 trace("QuotaNonPagePoolUsage : %Iu\n", pvi
->QuotaNonPagedPoolUsage
);
1862 trace("PagefileUsage : %Iu\n", pvi
->PagefileUsage
);
1863 trace("PeakPagefileUsage : %Iu\n", pvi
->PeakPagefileUsage
);
1866 static void test_query_process_vm(void)
1873 const SIZE_T alloc_size
= 16 * 1024 * 1024;
1876 status
= NtQueryInformationProcess(NULL
, ProcessVmCounters
, NULL
, sizeof(pvi
), NULL
);
1877 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1878 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status
);
1880 status
= NtQueryInformationProcess(NULL
, ProcessVmCounters
, &pvi
, sizeof(VM_COUNTERS
), NULL
);
1881 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
1883 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 24, &ReturnLength
);
1884 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1886 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(VM_COUNTERS
), &ReturnLength
);
1887 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1888 ok( ReturnLength
== sizeof(VM_COUNTERS
), "Inconsistent length %ld\n", ReturnLength
);
1890 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters
, &pvi
, 46, &ReturnLength
);
1891 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1892 todo_wine
ok( ReturnLength
== sizeof(VM_COUNTERS
), "wrong size %ld\n", ReturnLength
);
1894 /* Check if we have some return values */
1895 if (winetest_debug
> 1)
1896 dump_vm_counters("VM counters for GetCurrentProcess", &pvi
);
1897 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1898 ok( pvi
.PagefileUsage
> 0, "Expected a PagefileUsage > 0\n");
1900 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
1901 status
= NtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1902 ok( status
== STATUS_ACCESS_DENIED
, "Expected STATUS_ACCESS_DENIED, got %08lx\n", status
);
1903 CloseHandle(process
);
1905 process
= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION
, FALSE
, GetCurrentProcessId());
1906 status
= NtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1907 ok( status
== STATUS_SUCCESS
|| broken(!process
) /* XP */, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1908 CloseHandle(process
);
1910 memset(&pvi
, 0, sizeof(pvi
));
1911 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, GetCurrentProcessId());
1912 status
= NtQueryInformationProcess(process
, ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1913 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1914 ok( pvi
.PrivateUsage
== pvi
.PagefileUsage
, "wrong value %Iu/%Iu\n", pvi
.PrivateUsage
, pvi
.PagefileUsage
);
1916 /* Check if we have some return values */
1917 if (winetest_debug
> 1)
1918 dump_vm_counters("VM counters for GetCurrentProcessId", &pvi
);
1919 ok( pvi
.WorkingSetSize
> 0, "Expected a WorkingSetSize > 0\n");
1920 ok( pvi
.PagefileUsage
> 0, "Expected a PagefileUsage > 0\n");
1922 CloseHandle(process
);
1924 /* Check if we have real counters */
1925 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1926 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1927 ok( pvi
.PrivateUsage
== pvi
.PagefileUsage
, "wrong value %Iu/%Iu\n", pvi
.PrivateUsage
, pvi
.PagefileUsage
);
1928 prev_size
= pvi
.VirtualSize
;
1929 if (winetest_debug
> 1)
1930 dump_vm_counters("VM counters before VirtualAlloc", &pvi
);
1931 ptr
= VirtualAlloc(NULL
, alloc_size
, MEM_COMMIT
| MEM_RESERVE
, PAGE_READWRITE
);
1932 ok( ptr
!= NULL
, "VirtualAlloc failed, err %lu\n", GetLastError());
1933 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1934 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1935 ok( pvi
.PrivateUsage
== pvi
.PagefileUsage
, "wrong value %Iu/%Iu\n", pvi
.PrivateUsage
, pvi
.PagefileUsage
);
1936 if (winetest_debug
> 1)
1937 dump_vm_counters("VM counters after VirtualAlloc", &pvi
);
1938 todo_wine
ok( pvi
.VirtualSize
>= prev_size
+ alloc_size
,
1939 "Expected to be greater than %Iu, got %Iu\n", prev_size
+ alloc_size
, pvi
.VirtualSize
);
1940 VirtualFree( ptr
, 0, MEM_RELEASE
);
1942 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1943 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1944 ok( pvi
.PrivateUsage
== pvi
.PagefileUsage
, "wrong value %Iu/%Iu\n", pvi
.PrivateUsage
, pvi
.PagefileUsage
);
1945 prev_size
= pvi
.VirtualSize
;
1946 if (winetest_debug
> 1)
1947 dump_vm_counters("VM counters before VirtualAlloc", &pvi
);
1948 ptr
= VirtualAlloc(NULL
, alloc_size
, MEM_RESERVE
, PAGE_READWRITE
);
1949 ok( ptr
!= NULL
, "VirtualAlloc failed, err %lu\n", GetLastError());
1950 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1951 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1952 ok( pvi
.PrivateUsage
== pvi
.PagefileUsage
, "wrong value %Iu/%Iu\n", pvi
.PrivateUsage
, pvi
.PagefileUsage
);
1953 if (winetest_debug
> 1)
1954 dump_vm_counters("VM counters after VirtualAlloc(MEM_RESERVE)", &pvi
);
1955 todo_wine
ok( pvi
.VirtualSize
>= prev_size
+ alloc_size
,
1956 "Expected to be greater than %Iu, got %Iu\n", prev_size
+ alloc_size
, pvi
.VirtualSize
);
1957 prev_size
= pvi
.VirtualSize
;
1959 ptr
= VirtualAlloc(ptr
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
1960 ok( ptr
!= NULL
, "VirtualAlloc failed, err %lu\n", GetLastError());
1961 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessVmCounters
, &pvi
, sizeof(pvi
), NULL
);
1962 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1963 ok( pvi
.PrivateUsage
== pvi
.PagefileUsage
, "wrong value %Iu/%Iu\n", pvi
.PrivateUsage
, pvi
.PagefileUsage
);
1964 if (winetest_debug
> 1)
1965 dump_vm_counters("VM counters after VirtualAlloc(MEM_COMMIT)", &pvi
);
1966 ok( pvi
.VirtualSize
== prev_size
,
1967 "Expected to equal to %Iu, got %Iu\n", prev_size
, pvi
.VirtualSize
);
1968 VirtualFree( ptr
, 0, MEM_RELEASE
);
1971 static void test_query_process_io(void)
1977 status
= NtQueryInformationProcess(NULL
, ProcessIoCounters
, NULL
, sizeof(pii
), NULL
);
1978 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
1979 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status
);
1981 status
= NtQueryInformationProcess(NULL
, ProcessIoCounters
, &pii
, sizeof(pii
), NULL
);
1982 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
1984 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, 24, &ReturnLength
);
1985 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1987 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
), &ReturnLength
);
1988 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
1989 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1991 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters
, &pii
, sizeof(pii
) * 2, &ReturnLength
);
1992 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
1993 ok( sizeof(pii
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
1995 /* Check if we have some return values */
1996 if (winetest_debug
> 1) trace("OtherOperationCount : 0x%s\n", wine_dbgstr_longlong(pii
.OtherOperationCount
));
1999 ok( pii
.OtherOperationCount
> 0, "Expected an OtherOperationCount > 0\n");
2003 static void test_query_process_times(void)
2008 SYSTEMTIME UTC
, Local
;
2009 KERNEL_USER_TIMES spti
;
2011 status
= NtQueryInformationProcess(NULL
, ProcessTimes
, NULL
, sizeof(spti
), NULL
);
2012 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
2013 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status
);
2015 status
= NtQueryInformationProcess(NULL
, ProcessTimes
, &spti
, sizeof(spti
), NULL
);
2016 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
2018 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, 24, &ReturnLength
);
2019 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2021 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
2024 if (winetest_debug
> 1) trace("Could not open process with ID : %ld, error : %lu. Going to use current one.\n", one_before_last_pid
, GetLastError());
2025 process
= GetCurrentProcess();
2028 trace("ProcessTimes for process with ID : %ld\n", one_before_last_pid
);
2030 status
= NtQueryInformationProcess( process
, ProcessTimes
, &spti
, sizeof(spti
), &ReturnLength
);
2031 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2032 ok( sizeof(spti
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
2033 CloseHandle(process
);
2035 FileTimeToSystemTime((const FILETIME
*)&spti
.CreateTime
, &UTC
);
2036 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
2037 if (winetest_debug
> 1) trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
2038 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
2040 FileTimeToSystemTime((const FILETIME
*)&spti
.ExitTime
, &UTC
);
2041 SystemTimeToTzSpecificLocalTime(NULL
, &UTC
, &Local
);
2042 if (winetest_debug
> 1) trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local
.wMonth
, Local
.wDay
, Local
.wYear
,
2043 Local
.wHour
, Local
.wMinute
, Local
.wSecond
);
2045 FileTimeToSystemTime((const FILETIME
*)&spti
.KernelTime
, &Local
);
2046 if (winetest_debug
> 1) trace("KernelTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
2048 FileTimeToSystemTime((const FILETIME
*)&spti
.UserTime
, &Local
);
2049 if (winetest_debug
> 1) trace("UserTime : %02d:%02d:%02d.%03d\n", Local
.wHour
, Local
.wMinute
, Local
.wSecond
, Local
.wMilliseconds
);
2051 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessTimes
, &spti
, sizeof(spti
) * 2, &ReturnLength
);
2052 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2053 ok( sizeof(spti
) == ReturnLength
||
2054 ReturnLength
== 0 /* vista */ ||
2055 broken(is_wow64
), /* returns garbage on wow64 */
2056 "Inconsistent length %ld\n", ReturnLength
);
2059 static void test_query_process_debug_port(int argc
, char **argv
)
2061 DWORD_PTR debug_port
= 0xdeadbeef;
2062 char cmdline
[MAX_PATH
];
2063 PROCESS_INFORMATION pi
;
2064 STARTUPINFOA si
= { 0 };
2069 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
2072 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
, NULL
, &si
, &pi
);
2073 ok(ret
, "CreateProcess failed, last error %#lx.\n", GetLastError());
2076 status
= NtQueryInformationProcess(NULL
, ProcessDebugPort
,
2078 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#lx.\n", status
);
2080 status
= NtQueryInformationProcess(NULL
, ProcessDebugPort
,
2081 NULL
, sizeof(debug_port
), NULL
);
2082 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
/* XP */, "got %#lx\n", status
);
2084 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
2085 NULL
, sizeof(debug_port
), NULL
);
2086 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#lx.\n", status
);
2089 status
= NtQueryInformationProcess(NULL
, ProcessDebugPort
,
2090 &debug_port
, sizeof(debug_port
), &len
);
2091 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %#lx.\n", status
);
2092 ok(len
== 0xdeadbeef || broken(len
!= sizeof(debug_port
)), /* wow64 */
2093 "len set to %lx\n", len
);
2096 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
2097 &debug_port
, sizeof(debug_port
) - 1, &len
);
2098 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#lx.\n", status
);
2099 ok(len
== 0xdeadbeef || broken(len
!= sizeof(debug_port
)), /* wow64 */
2100 "len set to %lx\n", len
);
2103 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
2104 &debug_port
, sizeof(debug_port
) + 1, &len
);
2105 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#lx.\n", status
);
2106 ok(len
== 0xdeadbeef || broken(len
!= sizeof(debug_port
)), /* wow64 */
2107 "len set to %lx\n", len
);
2110 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort
,
2111 &debug_port
, sizeof(debug_port
), &len
);
2112 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2113 ok(debug_port
== 0, "Expected port 0, got %#Ix.\n", debug_port
);
2114 ok(len
== sizeof(debug_port
), "len set to %lx\n", len
);
2117 status
= NtQueryInformationProcess(pi
.hProcess
, ProcessDebugPort
,
2118 &debug_port
, sizeof(debug_port
), &len
);
2119 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2120 ok(debug_port
== ~(DWORD_PTR
)0, "Expected port %#Ix, got %#Ix.\n", ~(DWORD_PTR
)0, debug_port
);
2121 ok(len
== sizeof(debug_port
), "len set to %lx\n", len
);
2127 ret
= WaitForDebugEvent(&ev
, INFINITE
);
2128 ok(ret
, "WaitForDebugEvent failed, last error %#lx.\n", GetLastError());
2131 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
2133 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
2134 ok(ret
, "ContinueDebugEvent failed, last error %#lx.\n", GetLastError());
2138 ret
= CloseHandle(pi
.hThread
);
2139 ok(ret
, "CloseHandle failed, last error %#lx.\n", GetLastError());
2140 ret
= CloseHandle(pi
.hProcess
);
2141 ok(ret
, "CloseHandle failed, last error %#lx.\n", GetLastError());
2144 static void subtest_query_process_debug_port_custom_dacl(int argc
, char **argv
, ACCESS_MASK access
, PSID sid
)
2146 HANDLE old_debug_obj
, debug_obj
;
2147 OBJECT_ATTRIBUTES attr
;
2148 SECURITY_DESCRIPTOR sd
;
2151 DWORD buffer
[(sizeof(ACL
) +
2152 (offsetof(ACCESS_ALLOWED_ACE
, SidStart
) + SECURITY_MAX_SID_SIZE
) +
2153 sizeof(DWORD
) - 1) / sizeof(DWORD
)];
2155 char cmdline
[MAX_PATH
];
2156 PROCESS_INFORMATION pi
;
2162 InitializeAcl(&acl
.acl
, sizeof(acl
), ACL_REVISION
);
2163 AddAccessAllowedAce(&acl
.acl
, ACL_REVISION
, access
, sid
);
2164 InitializeSecurityDescriptor(&sd
, SECURITY_DESCRIPTOR_REVISION
);
2165 SetSecurityDescriptorDacl(&sd
, TRUE
, &acl
.acl
, FALSE
);
2167 InitializeObjectAttributes(&attr
, NULL
, 0, NULL
, &sd
);
2168 status
= NtCreateDebugObject(&debug_obj
, MAXIMUM_ALLOWED
, &attr
, DEBUG_KILL_ON_CLOSE
);
2169 ok(SUCCEEDED(status
), "Failed to create debug object: %#010lx\n", status
);
2170 if (FAILED(status
)) return;
2172 old_debug_obj
= pDbgUiGetThreadDebugObject();
2173 pDbgUiSetThreadDebugObject(debug_obj
);
2175 sprintf(cmdline
, "%s %s %s %lu", argv
[0], argv
[1], "debuggee:dbgport", access
);
2177 memset(&si
, 0, sizeof(si
));
2179 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
,
2180 DEBUG_PROCESS
, NULL
, NULL
, &si
, &pi
);
2181 ok(ret
, "CreateProcess failed, last error %#lx.\n", GetLastError());
2182 if (!ret
) goto close_debug_obj
;
2186 ret
= WaitForDebugEvent(&ev
, INFINITE
);
2187 ok(ret
, "WaitForDebugEvent failed, last error %#lx.\n", GetLastError());
2190 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
2191 ok(ret
, "ContinueDebugEvent failed, last error %#lx.\n", GetLastError());
2193 } while (ev
.dwDebugEventCode
!= EXIT_PROCESS_DEBUG_EVENT
);
2195 wait_child_process(pi
.hProcess
);
2196 ret
= CloseHandle(pi
.hThread
);
2197 ok(ret
, "CloseHandle failed, last error %#lx.\n", GetLastError());
2198 ret
= CloseHandle(pi
.hProcess
);
2199 ok(ret
, "CloseHandle failed, last error %#lx.\n", GetLastError());
2202 pDbgUiSetThreadDebugObject(old_debug_obj
);
2206 static TOKEN_OWNER
*get_current_owner(void)
2213 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS
, &token
);
2214 ok(ret
, "Failed to get process token: %lu\n", GetLastError());
2216 ret
= GetTokenInformation(token
, TokenOwner
, NULL
, 0, &length
);
2217 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
2218 "GetTokenInformation failed: %lu\n", GetLastError());
2219 ok(length
!= 0, "Failed to get token owner information length: %lu\n", GetLastError());
2221 owner
= HeapAlloc(GetProcessHeap(), 0, length
);
2222 ret
= GetTokenInformation(token
, TokenOwner
, owner
, length
, &length
);
2223 ok(ret
, "Failed to get token owner information: %lu)\n", GetLastError());
2229 static void test_query_process_debug_port_custom_dacl(int argc
, char **argv
)
2231 static const ACCESS_MASK all_access_masks
[] = {
2234 STANDARD_RIGHTS_REQUIRED
| SYNCHRONIZE
,
2239 if (!pDbgUiSetThreadDebugObject
)
2241 win_skip("DbgUiGetThreadDebugObject not found\n");
2245 if (!pDbgUiGetThreadDebugObject
)
2247 win_skip("DbgUiSetThreadDebugObject not found\n");
2251 owner
= get_current_owner();
2253 for (i
= 0; i
< ARRAY_SIZE(all_access_masks
); i
++)
2255 ACCESS_MASK access
= all_access_masks
[i
];
2257 winetest_push_context("debug object access %08lx", access
);
2258 subtest_query_process_debug_port_custom_dacl(argc
, argv
, access
, owner
->Owner
);
2259 winetest_pop_context();
2262 HeapFree(GetProcessHeap(), 0, owner
);
2265 static void test_query_process_priority(void)
2267 PROCESS_PRIORITY_CLASS priority
[2];
2269 DWORD orig_priority
;
2273 status
= NtQueryInformationProcess(NULL
, ProcessPriorityClass
, NULL
, sizeof(priority
[0]), NULL
);
2274 ok(status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_HANDLE
) /* w2k3 */,
2275 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status
);
2277 status
= NtQueryInformationProcess(NULL
, ProcessPriorityClass
, &priority
, sizeof(priority
[0]), NULL
);
2278 ok(status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
2280 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, 1, &ReturnLength
);
2281 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2283 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, sizeof(priority
), &ReturnLength
);
2284 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2286 orig_priority
= GetPriorityClass(GetCurrentProcess());
2287 ret
= SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS
);
2288 ok(ret
, "Failed to set priority class: %lu\n", GetLastError());
2290 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessPriorityClass
, &priority
, sizeof(priority
[0]), &ReturnLength
);
2291 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2292 ok(priority
[0].PriorityClass
== PROCESS_PRIOCLASS_BELOW_NORMAL
,
2293 "Expected PROCESS_PRIOCLASS_BELOW_NORMAL, got %u\n", priority
[0].PriorityClass
);
2295 ret
= SetPriorityClass(GetCurrentProcess(), orig_priority
);
2296 ok(ret
, "Failed to reset priority class: %lu\n", GetLastError());
2299 static void test_query_process_handlecount(void)
2304 BYTE buffer
[2 * sizeof(DWORD
)];
2307 status
= NtQueryInformationProcess(NULL
, ProcessHandleCount
, NULL
, sizeof(handlecount
), NULL
);
2308 ok( status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_HANDLE
,
2309 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status
);
2311 status
= NtQueryInformationProcess(NULL
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), NULL
);
2312 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
2314 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, &handlecount
, 2, &ReturnLength
);
2315 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2317 process
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, one_before_last_pid
);
2320 trace("Could not open process with ID : %ld, error : %lu. Going to use current one.\n", one_before_last_pid
, GetLastError());
2321 process
= GetCurrentProcess();
2324 if (winetest_debug
> 1) trace("ProcessHandleCount for process with ID : %ld\n", one_before_last_pid
);
2326 status
= NtQueryInformationProcess( process
, ProcessHandleCount
, &handlecount
, sizeof(handlecount
), &ReturnLength
);
2327 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2328 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
2329 CloseHandle(process
);
2331 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount
, buffer
, sizeof(buffer
), &ReturnLength
);
2332 ok( status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_SUCCESS
,
2333 "Expected STATUS_INFO_LENGTH_MISMATCH or STATUS_SUCCESS, got %08lx\n", status
);
2334 ok( sizeof(handlecount
) == ReturnLength
, "Inconsistent length %ld\n", ReturnLength
);
2336 /* Check if we have some return values */
2337 if (winetest_debug
> 1) trace("HandleCount : %ld\n", handlecount
);
2340 ok( handlecount
> 0, "Expected some handles, got 0\n");
2344 static void test_query_process_image_file_name(void)
2346 static const WCHAR deviceW
[] = {'\\','D','e','v','i','c','e','\\'};
2349 UNICODE_STRING image_file_name
;
2350 UNICODE_STRING
*buffer
= NULL
;
2352 status
= NtQueryInformationProcess(NULL
, ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), NULL
);
2353 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
2355 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, 2, &ReturnLength
);
2356 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2358 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, &image_file_name
, sizeof(image_file_name
), &ReturnLength
);
2359 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2361 buffer
= malloc(ReturnLength
);
2362 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, buffer
, ReturnLength
, &ReturnLength
);
2363 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2365 ok(!memcmp(buffer
->Buffer
, deviceW
, sizeof(deviceW
)),
2366 "Expected image name to begin with \\Device\\, got %s\n",
2367 wine_dbgstr_wn(buffer
->Buffer
, buffer
->Length
/ sizeof(WCHAR
)));
2370 status
= NtQueryInformationProcess(NULL
, ProcessImageFileNameWin32
, &image_file_name
, sizeof(image_file_name
), NULL
);
2371 if (status
== STATUS_INVALID_INFO_CLASS
)
2373 win_skip("ProcessImageFileNameWin32 is not supported\n");
2376 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
2378 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileNameWin32
, &image_file_name
, 2, &ReturnLength
);
2379 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2381 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileNameWin32
, &image_file_name
, sizeof(image_file_name
), &ReturnLength
);
2382 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
2384 buffer
= malloc(ReturnLength
);
2385 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileNameWin32
, buffer
, ReturnLength
, &ReturnLength
);
2386 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2387 ok(memcmp(buffer
->Buffer
, deviceW
, sizeof(deviceW
)),
2388 "Expected image name not to begin with \\Device\\, got %s\n",
2389 wine_dbgstr_wn(buffer
->Buffer
, buffer
->Length
/ sizeof(WCHAR
)));
2393 static void test_query_process_image_info(void)
2395 IMAGE_NT_HEADERS
*nt
= RtlImageNtHeader( NtCurrentTeb()->Peb
->ImageBaseAddress
);
2397 SECTION_IMAGE_INFORMATION info
;
2400 status
= NtQueryInformationProcess( NULL
, ProcessImageInformation
, &info
, sizeof(info
), &len
);
2401 ok( status
== STATUS_INVALID_HANDLE
|| broken(status
== STATUS_INVALID_PARAMETER
), /* winxp */
2402 "got %08lx\n", status
);
2404 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageInformation
, &info
, sizeof(info
)-1, &len
);
2405 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %08lx\n", status
);
2407 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageInformation
, &info
, sizeof(info
)+1, &len
);
2408 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %08lx\n", status
);
2410 memset( &info
, 0xcc, sizeof(info
) );
2411 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageInformation
, &info
, sizeof(info
), &len
);
2412 ok( status
== STATUS_SUCCESS
, "got %08lx\n", status
);
2413 ok( len
== sizeof(info
), "wrong len %lu\n", len
);
2415 ok( info
.MajorSubsystemVersion
== nt
->OptionalHeader
.MajorSubsystemVersion
,
2416 "wrong major version %x/%x\n",
2417 info
.MajorSubsystemVersion
, nt
->OptionalHeader
.MajorSubsystemVersion
);
2418 ok( info
.MinorSubsystemVersion
== nt
->OptionalHeader
.MinorSubsystemVersion
,
2419 "wrong minor version %x/%x\n",
2420 info
.MinorSubsystemVersion
, nt
->OptionalHeader
.MinorSubsystemVersion
);
2421 ok( info
.MajorOperatingSystemVersion
== nt
->OptionalHeader
.MajorOperatingSystemVersion
||
2422 broken( !info
.MajorOperatingSystemVersion
), /* <= win8 */
2423 "wrong major OS version %x/%x\n",
2424 info
.MajorOperatingSystemVersion
, nt
->OptionalHeader
.MajorOperatingSystemVersion
);
2425 ok( info
.MinorOperatingSystemVersion
== nt
->OptionalHeader
.MinorOperatingSystemVersion
,
2426 "wrong minor OS version %x/%x\n",
2427 info
.MinorOperatingSystemVersion
, nt
->OptionalHeader
.MinorOperatingSystemVersion
);
2430 static void test_query_process_debug_object_handle(int argc
, char **argv
)
2432 char cmdline
[MAX_PATH
];
2433 STARTUPINFOA si
= {0};
2434 PROCESS_INFORMATION pi
;
2436 HANDLE debug_object
;
2440 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
2443 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, DEBUG_PROCESS
, NULL
,
2445 ok(ret
, "CreateProcess failed with last error %lu\n", GetLastError());
2449 status
= NtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
, 0, &len
);
2450 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
2451 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08lx\n",
2453 ok(len
== 0xdeadbeef || broken(len
== 0xfffffffc || len
== 0xffc), /* wow64 */
2454 "len set to %lx\n", len
);
2457 status
= NtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
, NULL
, sizeof(debug_object
), &len
);
2458 ok(status
== STATUS_INVALID_HANDLE
||
2459 status
== STATUS_ACCESS_VIOLATION
, /* XP */
2460 "Expected NtQueryInformationProcess to return STATUS_INVALID_HANDLE, got 0x%08lx\n", status
);
2461 ok(len
== 0xdeadbeef || broken(len
== 0xfffffffc || len
== 0xffc), /* wow64 */
2462 "len set to %lx\n", len
);
2464 status
= NtQueryInformationProcess(GetCurrentProcess(),
2465 ProcessDebugObjectHandle
, NULL
, sizeof(debug_object
), &len
);
2466 ok(status
== STATUS_ACCESS_VIOLATION
,
2467 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08lx\n", status
);
2468 ok(len
== 0xdeadbeef || broken(len
== 0xfffffffc || len
== 0xffc), /* wow64 */
2469 "len set to %lx\n", len
);
2471 status
= NtQueryInformationProcess(NULL
, ProcessDebugObjectHandle
,
2472 &debug_object
, sizeof(debug_object
), NULL
);
2473 ok(status
== STATUS_INVALID_HANDLE
,
2474 "Expected NtQueryInformationProcess to return STATUS_ACCESS_VIOLATION, got 0x%08lx\n", status
);
2477 status
= NtQueryInformationProcess(GetCurrentProcess(),
2478 ProcessDebugObjectHandle
, &debug_object
, sizeof(debug_object
) - 1, &len
);
2479 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
2480 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08lx\n", status
);
2481 ok(len
== 0xdeadbeef || broken(len
== 0xfffffffc || len
== 0xffc), /* wow64 */
2482 "len set to %lx\n", len
);
2485 status
= NtQueryInformationProcess(GetCurrentProcess(),
2486 ProcessDebugObjectHandle
, &debug_object
, sizeof(debug_object
) + 1, &len
);
2487 ok(status
== STATUS_INFO_LENGTH_MISMATCH
,
2488 "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08lx\n", status
);
2489 ok(len
== 0xdeadbeef || broken(len
== 0xfffffffc || len
== 0xffc), /* wow64 */
2490 "len set to %lx\n", len
);
2493 debug_object
= (HANDLE
)0xdeadbeef;
2494 status
= NtQueryInformationProcess(GetCurrentProcess(),
2495 ProcessDebugObjectHandle
, &debug_object
,
2496 sizeof(debug_object
), &len
);
2497 ok(status
== STATUS_PORT_NOT_SET
,
2498 "Expected NtQueryInformationProcess to return STATUS_PORT_NOT_SET, got 0x%08lx\n", status
);
2499 ok(debug_object
== NULL
||
2500 broken(debug_object
== (HANDLE
)0xdeadbeef), /* Wow64 */
2501 "Expected debug object handle to be NULL, got %p\n", debug_object
);
2502 ok(len
== sizeof(debug_object
), "len set to %lx\n", len
);
2505 debug_object
= (HANDLE
)0xdeadbeef;
2506 status
= NtQueryInformationProcess(pi
.hProcess
, ProcessDebugObjectHandle
,
2507 &debug_object
, sizeof(debug_object
), &len
);
2508 ok(status
== STATUS_SUCCESS
,
2509 "Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08lx\n", status
);
2510 ok(debug_object
!= NULL
,
2511 "Expected debug object handle to be non-NULL, got %p\n", debug_object
);
2512 ok(len
== sizeof(debug_object
), "len set to %lx\n", len
);
2513 status
= NtClose( debug_object
);
2514 ok( !status
, "NtClose failed %lx\n", status
);
2520 ret
= WaitForDebugEvent(&ev
, INFINITE
);
2521 ok(ret
, "WaitForDebugEvent failed with last error %lu\n", GetLastError());
2524 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
2526 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
2527 ok(ret
, "ContinueDebugEvent failed with last error %lu\n", GetLastError());
2531 ret
= CloseHandle(pi
.hThread
);
2532 ok(ret
, "CloseHandle failed with last error %lu\n", GetLastError());
2533 ret
= CloseHandle(pi
.hProcess
);
2534 ok(ret
, "CloseHandle failed with last error %lu\n", GetLastError());
2537 static void test_query_process_debug_flags(int argc
, char **argv
)
2539 static const DWORD test_flags
[] = { DEBUG_PROCESS
,
2540 DEBUG_ONLY_THIS_PROCESS
,
2541 DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
,
2543 DWORD debug_flags
= 0xdeadbeef;
2544 char cmdline
[MAX_PATH
];
2545 PROCESS_INFORMATION pi
;
2546 STARTUPINFOA si
= { 0 };
2553 /* test invalid arguments */
2554 status
= NtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, 0, NULL
);
2555 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
2556 "Expected STATUS_INFO_LENGTH_MISMATCH, got %#lx.\n", status
);
2558 status
= NtQueryInformationProcess(NULL
, ProcessDebugFlags
, NULL
, sizeof(debug_flags
), NULL
);
2559 ok(status
== STATUS_INVALID_HANDLE
|| status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
2560 "Expected STATUS_INVALID_HANDLE, got %#lx.\n", status
);
2562 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
2563 NULL
, sizeof(debug_flags
), NULL
);
2564 ok(status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %#lx.\n", status
);
2566 status
= NtQueryInformationProcess(NULL
, ProcessDebugFlags
,
2567 &debug_flags
, sizeof(debug_flags
), NULL
);
2568 ok(status
== STATUS_INVALID_HANDLE
|| broken(status
== STATUS_INVALID_INFO_CLASS
) /* WOW64 */,
2569 "Expected STATUS_INVALID_HANDLE, got %#lx.\n", status
);
2571 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
2572 &debug_flags
, sizeof(debug_flags
) - 1, NULL
);
2573 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#lx.\n", status
);
2575 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
2576 &debug_flags
, sizeof(debug_flags
) + 1, NULL
);
2577 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#lx.\n", status
);
2579 /* test ProcessDebugFlags of current process */
2580 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags
,
2581 &debug_flags
, sizeof(debug_flags
), NULL
);
2582 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2583 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %lx.\n", debug_flags
);
2585 for (i
= 0; i
< ARRAY_SIZE(test_flags
); i
++)
2587 DWORD expected_flags
= !(test_flags
[i
] & DEBUG_ONLY_THIS_PROCESS
);
2588 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], "debuggee");
2591 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, test_flags
[i
], NULL
, NULL
, &si
, &pi
);
2592 ok(ret
, "CreateProcess failed, last error %#lx.\n", GetLastError());
2594 if (!(test_flags
[i
] & (DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
)))
2596 /* test ProcessDebugFlags before attaching with debugger */
2597 status
= NtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
2598 &debug_flags
, sizeof(debug_flags
), NULL
);
2599 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2600 ok(debug_flags
== TRUE
, "Expected flag TRUE, got %lx.\n", debug_flags
);
2602 ret
= DebugActiveProcess(pi
.dwProcessId
);
2603 ok(ret
, "DebugActiveProcess failed, last error %#lx.\n", GetLastError());
2604 expected_flags
= FALSE
;
2607 /* test ProcessDebugFlags after attaching with debugger */
2608 status
= NtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
2609 &debug_flags
, sizeof(debug_flags
), NULL
);
2610 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2611 ok(debug_flags
== expected_flags
, "Expected flag %lx, got %lx.\n", expected_flags
, debug_flags
);
2613 if (!(test_flags
[i
] & CREATE_SUSPENDED
))
2615 /* Continue a couple of times to make sure the process is fully initialized,
2616 * otherwise Windows XP deadlocks in the following DebugActiveProcess(). */
2619 ret
= WaitForDebugEvent(&ev
, 1000);
2620 ok(ret
, "WaitForDebugEvent failed, last error %#lx.\n", GetLastError());
2623 if (ev
.dwDebugEventCode
== LOAD_DLL_DEBUG_EVENT
) break;
2625 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
2626 ok(ret
, "ContinueDebugEvent failed, last error %#lx.\n", GetLastError());
2630 result
= SuspendThread(pi
.hThread
);
2631 ok(result
== 0, "Expected 0, got %lu.\n", result
);
2634 ret
= DebugActiveProcessStop(pi
.dwProcessId
);
2635 ok(ret
, "DebugActiveProcessStop failed, last error %#lx.\n", GetLastError());
2637 /* test ProcessDebugFlags after detaching debugger */
2638 status
= NtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
2639 &debug_flags
, sizeof(debug_flags
), NULL
);
2640 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2641 ok(debug_flags
== expected_flags
, "Expected flag %lx, got %lx.\n", expected_flags
, debug_flags
);
2643 ret
= DebugActiveProcess(pi
.dwProcessId
);
2644 ok(ret
, "DebugActiveProcess failed, last error %#lx.\n", GetLastError());
2646 /* test ProcessDebugFlags after re-attaching debugger */
2647 status
= NtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
2648 &debug_flags
, sizeof(debug_flags
), NULL
);
2649 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2650 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %lx.\n", debug_flags
);
2652 result
= ResumeThread(pi
.hThread
);
2653 todo_wine
ok(result
== 2, "Expected 2, got %lu.\n", result
);
2655 /* Wait until the process is terminated. On Windows XP the process randomly
2656 * gets stuck in a non-continuable exception, so stop after 100 iterations.
2657 * On Windows 2003, the debugged process disappears (or stops?) without
2658 * any EXIT_PROCESS_DEBUG_EVENT after a couple of events. */
2659 for (j
= 0; j
< 100; j
++)
2661 ret
= WaitForDebugEvent(&ev
, 1000);
2662 ok(ret
|| broken(GetLastError() == ERROR_SEM_TIMEOUT
),
2663 "WaitForDebugEvent failed, last error %#lx.\n", GetLastError());
2666 if (ev
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
) break;
2668 ret
= ContinueDebugEvent(ev
.dwProcessId
, ev
.dwThreadId
, DBG_CONTINUE
);
2669 ok(ret
, "ContinueDebugEvent failed, last error %#lx.\n", GetLastError());
2672 ok(j
< 100 || broken(j
>= 100) /* Win XP */, "Expected less than 100 debug events.\n");
2674 /* test ProcessDebugFlags after process has terminated */
2675 status
= NtQueryInformationProcess(pi
.hProcess
, ProcessDebugFlags
,
2676 &debug_flags
, sizeof(debug_flags
), NULL
);
2677 ok(!status
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2678 ok(debug_flags
== FALSE
, "Expected flag FALSE, got %lx.\n", debug_flags
);
2680 ret
= CloseHandle(pi
.hThread
);
2681 ok(ret
, "CloseHandle failed, last error %#lx.\n", GetLastError());
2682 ret
= CloseHandle(pi
.hProcess
);
2683 ok(ret
, "CloseHandle failed, last error %#lx.\n", GetLastError());
2687 static void test_query_process_quota_limits(void)
2689 QUOTA_LIMITS qlimits
;
2694 status
= NtQueryInformationProcess(NULL
, ProcessQuotaLimits
, NULL
, sizeof(qlimits
), NULL
);
2695 ok(status
== STATUS_INVALID_HANDLE
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2697 status
= NtQueryInformationProcess(NULL
, ProcessQuotaLimits
, &qlimits
, sizeof(qlimits
), NULL
);
2698 ok(status
== STATUS_INVALID_HANDLE
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2700 process
= GetCurrentProcess();
2701 status
= NtQueryInformationProcess( process
, ProcessQuotaLimits
, &qlimits
, 2, &ret_len
);
2702 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2704 memset(&qlimits
, 0, sizeof(qlimits
));
2705 status
= NtQueryInformationProcess( process
, ProcessQuotaLimits
, &qlimits
, sizeof(qlimits
), &ret_len
);
2706 ok(status
== STATUS_SUCCESS
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2707 ok(sizeof(qlimits
) == ret_len
, "len set to %lx\n", ret_len
);
2708 ok(qlimits
.MinimumWorkingSetSize
== 204800,"Expected MinimumWorkingSetSize = 204800, got %s\n",
2709 wine_dbgstr_longlong(qlimits
.MinimumWorkingSetSize
));
2710 ok(qlimits
.MaximumWorkingSetSize
== 1413120,"Expected MaximumWorkingSetSize = 1413120, got %s\n",
2711 wine_dbgstr_longlong(qlimits
.MaximumWorkingSetSize
));
2712 ok(qlimits
.PagefileLimit
== ~0,"Expected PagefileLimit = ~0, got %s\n",
2713 wine_dbgstr_longlong(qlimits
.PagefileLimit
));
2714 ok(qlimits
.TimeLimit
.QuadPart
== ~0,"Expected TimeLimit = ~0, got %s\n",
2715 wine_dbgstr_longlong(qlimits
.TimeLimit
.QuadPart
));
2717 if (winetest_debug
> 1)
2719 trace("Quota Limits:\n");
2720 trace("PagedPoolLimit: %s\n", wine_dbgstr_longlong(qlimits
.PagedPoolLimit
));
2721 trace("NonPagedPoolLimit: %s\n", wine_dbgstr_longlong(qlimits
.NonPagedPoolLimit
));
2724 memset(&qlimits
, 0, sizeof(qlimits
));
2725 status
= NtQueryInformationProcess( process
, ProcessQuotaLimits
, &qlimits
, sizeof(qlimits
) * 2, &ret_len
);
2726 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2727 ok(sizeof(qlimits
) == ret_len
, "len set to %lx\n", ret_len
);
2729 memset(&qlimits
, 0, sizeof(qlimits
));
2730 status
= NtQueryInformationProcess( process
, ProcessQuotaLimits
, &qlimits
, sizeof(qlimits
) - 1, &ret_len
);
2731 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2732 ok(sizeof(qlimits
) == ret_len
, "len set to %lx\n", ret_len
);
2734 memset(&qlimits
, 0, sizeof(qlimits
));
2735 status
= NtQueryInformationProcess( process
, ProcessQuotaLimits
, &qlimits
, sizeof(qlimits
) + 1, &ret_len
);
2736 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationProcess failed, status %#lx.\n", status
);
2737 ok(sizeof(qlimits
) == ret_len
, "len set to %lx\n", ret_len
);
2740 static void test_readvirtualmemory(void)
2745 static const char teststring
[] = "test string";
2748 process
= OpenProcess(PROCESS_VM_READ
, FALSE
, GetCurrentProcessId());
2749 ok(process
!= 0, "Expected to be able to open own process for reading memory\n");
2751 /* normal operation */
2752 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, &readcount
);
2753 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2754 ok( readcount
== 12, "Expected to read 12 bytes, got %Id\n",readcount
);
2755 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
2757 /* no number of bytes */
2758 memset(buffer
, 0, 12);
2759 status
= pNtReadVirtualMemory(process
, teststring
, buffer
, 12, NULL
);
2760 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2761 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
2763 /* illegal remote address */
2765 status
= pNtReadVirtualMemory(process
, (void *) 0x1234, buffer
, 12, &readcount
);
2766 ok( status
== STATUS_PARTIAL_COPY
, "Expected STATUS_PARTIAL_COPY, got %08lx\n", status
);
2767 if (status
== STATUS_PARTIAL_COPY
)
2768 ok( readcount
== 0, "Expected to read 0 bytes, got %Id\n",readcount
);
2772 status
= pNtReadVirtualMemory(0, teststring
, buffer
, 12, &readcount
);
2773 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
2774 ok( readcount
== 0, "Expected to read 0 bytes, got %Id\n",readcount
);
2776 /* pseudo handle for current process*/
2777 memset(buffer
, 0, 12);
2778 status
= pNtReadVirtualMemory((HANDLE
)-1, teststring
, buffer
, 12, &readcount
);
2779 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2780 ok( readcount
== 12, "Expected to read 12 bytes, got %Id\n",readcount
);
2781 ok( strcmp(teststring
, buffer
) == 0, "Expected read memory to be the same as original memory\n");
2783 /* illegal local address */
2784 status
= pNtReadVirtualMemory(process
, teststring
, (void *)0x1234, 12, &readcount
);
2785 ok( status
== STATUS_ACCESS_VIOLATION
|| broken(status
== STATUS_PARTIAL_COPY
) /* Win10 */,
2786 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status
);
2787 if (status
== STATUS_ACCESS_VIOLATION
)
2788 ok( readcount
== 0, "Expected to read 0 bytes, got %Id\n",readcount
);
2790 CloseHandle(process
);
2793 static void test_mapprotection(void)
2797 MEMORY_BASIC_INFORMATION info
;
2798 ULONG oldflags
, flagsize
, flags
= MEM_EXECUTE_OPTION_ENABLE
;
2799 LARGE_INTEGER size
, offset
;
2801 SIZE_T retlen
, count
;
2803 BOOL reset_flags
= FALSE
;
2805 /* Switch to being a noexec unaware process */
2806 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof (oldflags
), &flagsize
);
2807 if (status
== STATUS_INVALID_PARAMETER
)
2809 skip("Unable to query process execute flags on this platform\n");
2812 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2813 if (winetest_debug
> 1) trace("Process execute flags %08lx\n", oldflags
);
2815 if (!(oldflags
& MEM_EXECUTE_OPTION_ENABLE
))
2817 if (oldflags
& MEM_EXECUTE_OPTION_PERMANENT
)
2819 skip("Unable to turn off noexec\n");
2823 if (pGetSystemDEPPolicy
&& pGetSystemDEPPolicy() == AlwaysOn
)
2825 skip("System policy requires noexec\n");
2829 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &flags
, sizeof(flags
) );
2830 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2834 size
.u
.LowPart
= 0x2000;
2835 size
.u
.HighPart
= 0;
2836 status
= pNtCreateSection ( &h
,
2837 STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
,
2841 SEC_COMMIT
| SEC_NOCACHE
,
2844 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2846 offset
.u
.LowPart
= 0;
2847 offset
.u
.HighPart
= 0;
2850 status
= pNtMapViewOfSection ( h
, GetCurrentProcess(), &addr
, 0, 0, &offset
, &count
, ViewShare
, 0, PAGE_READWRITE
);
2851 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2853 #if defined(__x86_64__) || defined(__i386__)
2854 *(unsigned char*)addr
= 0xc3; /* lret ... in both i386 and x86_64 */
2855 #elif defined(__arm__)
2856 *(unsigned long*)addr
= 0xe12fff1e; /* bx lr */
2857 #elif defined(__aarch64__)
2858 *(unsigned long*)addr
= 0xd65f03c0; /* ret */
2860 ok(0, "Add a return opcode for your architecture or expect a crash in this test\n");
2862 if (winetest_debug
> 1) trace("trying to execute code in the readwrite only mapped anon file...\n");
2864 if (winetest_debug
> 1) trace("...done.\n");
2866 status
= pNtQueryVirtualMemory( GetCurrentProcess(), addr
, MemoryBasicInformation
, &info
, sizeof(info
), &retlen
);
2867 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2868 ok( retlen
== sizeof(info
), "Expected STATUS_SUCCESS, got %08lx\n", status
);
2869 ok((info
.Protect
& ~PAGE_NOCACHE
) == PAGE_READWRITE
, "addr.Protect is not PAGE_READWRITE, but 0x%lx\n", info
.Protect
);
2871 status
= pNtUnmapViewOfSection( GetCurrentProcess(), (char *)addr
+ 0x1050 );
2872 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2876 pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &oldflags
, sizeof(oldflags
) );
2879 static void test_threadstack(void)
2881 PROCESS_STACK_ALLOCATION_INFORMATION info
= { 0x100000, 0, (void *)0xdeadbeef };
2882 PROCESS_STACK_ALLOCATION_INFORMATION_EX info_ex
= { 0 };
2883 MEMORY_BASIC_INFORMATION meminfo
;
2887 info
.ReserveSize
= 0x100000;
2888 info
.StackBase
= (void *)0xdeadbeef;
2889 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
, &info
, sizeof(info
) );
2890 ok( !status
, "NtSetInformationProcess failed %08lx\n", status
);
2891 ok( info
.StackBase
!= (void *)0xdeadbeef, "stackbase not set\n" );
2893 status
= pNtQueryVirtualMemory( GetCurrentProcess(), info
.StackBase
, MemoryBasicInformation
,
2894 &meminfo
, sizeof(meminfo
), &retlen
);
2895 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2896 ok( retlen
== sizeof(meminfo
), "Expected STATUS_SUCCESS, got %08lx\n", status
);
2897 ok( meminfo
.AllocationBase
== info
.StackBase
, "wrong base %p/%p\n",
2898 meminfo
.AllocationBase
, info
.StackBase
);
2899 ok( meminfo
.RegionSize
== info
.ReserveSize
, "wrong size %Ix/%Ix\n",
2900 meminfo
.RegionSize
, info
.ReserveSize
);
2901 ok( meminfo
.State
== MEM_RESERVE
, "wrong state %lx\n", meminfo
.State
);
2902 ok( meminfo
.Protect
== 0, "wrong protect %lx\n", meminfo
.Protect
);
2903 ok( meminfo
.Type
== MEM_PRIVATE
, "wrong type %lx\n", meminfo
.Type
);
2905 info_ex
.AllocInfo
= info
;
2906 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
,
2907 &info_ex
, sizeof(info_ex
) );
2908 if (status
!= STATUS_INVALID_PARAMETER
)
2910 ok( !status
, "NtSetInformationProcess failed %08lx\n", status
);
2911 ok( info_ex
.AllocInfo
.StackBase
!= info
.StackBase
, "stackbase not set\n" );
2912 status
= pNtQueryVirtualMemory( GetCurrentProcess(), info_ex
.AllocInfo
.StackBase
,
2913 MemoryBasicInformation
, &meminfo
, sizeof(meminfo
), &retlen
);
2914 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2915 ok( retlen
== sizeof(meminfo
), "Expected STATUS_SUCCESS, got %08lx\n", status
);
2916 ok( meminfo
.AllocationBase
== info_ex
.AllocInfo
.StackBase
, "wrong base %p/%p\n",
2917 meminfo
.AllocationBase
, info_ex
.AllocInfo
.StackBase
);
2918 ok( meminfo
.RegionSize
== info_ex
.AllocInfo
.ReserveSize
, "wrong size %Ix/%Ix\n",
2919 meminfo
.RegionSize
, info_ex
.AllocInfo
.ReserveSize
);
2920 ok( meminfo
.State
== MEM_RESERVE
, "wrong state %lx\n", meminfo
.State
);
2921 ok( meminfo
.Protect
== 0, "wrong protect %lx\n", meminfo
.Protect
);
2922 ok( meminfo
.Type
== MEM_PRIVATE
, "wrong type %lx\n", meminfo
.Type
);
2923 VirtualFree( info_ex
.AllocInfo
.StackBase
, 0, MEM_FREE
);
2924 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
,
2925 &info
, sizeof(info
) - 1 );
2926 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtSetInformationProcess failed %08lx\n", status
);
2927 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
,
2928 &info
, sizeof(info
) + 1 );
2929 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtSetInformationProcess failed %08lx\n", status
);
2930 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
,
2931 &info_ex
, sizeof(info_ex
) - 1 );
2932 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtSetInformationProcess failed %08lx\n", status
);
2933 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
,
2934 &info_ex
, sizeof(info_ex
) + 1 );
2935 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtSetInformationProcess failed %08lx\n", status
);
2937 else win_skip( "ProcessThreadStackAllocation ex not supported\n" );
2939 VirtualFree( info
.StackBase
, 0, MEM_FREE
);
2942 static void test_queryvirtualmemory(void)
2945 SIZE_T readcount
, prev
;
2946 static const char teststring
[] = "test string";
2947 static char datatestbuf
[42] = "abc";
2948 static char rwtestbuf
[42];
2949 MEMORY_BASIC_INFORMATION mbi
;
2952 void *user_shared_data
= (void *)0x7ffe0000;
2954 MEMORY_SECTION_NAME
*name
= (MEMORY_SECTION_NAME
*)buffer
;
2955 SYSTEM_BASIC_INFORMATION sbi
;
2957 module
= GetModuleHandleA( "ntdll.dll" );
2958 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
2959 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2960 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
2961 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
2962 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%lx, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
2963 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
2964 ok (mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%lx, expected 0x%x\n", mbi
.Protect
, PAGE_READONLY
);
2965 ok (mbi
.Type
== MEM_IMAGE
, "mbi.Type is 0x%lx, expected 0x%x\n", mbi
.Type
, MEM_IMAGE
);
2967 module
= GetModuleHandleA( "ntdll.dll" );
2968 status
= pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
2969 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2970 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
2971 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
2972 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%lx, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
2973 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
2974 ok (mbi
.Protect
== PAGE_EXECUTE_READ
, "mbi.Protect is 0x%lx, expected 0x%x\n", mbi
.Protect
, PAGE_EXECUTE_READ
);
2976 status
= pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
2977 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2978 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
2979 ok (mbi
.AllocationProtect
== PAGE_READWRITE
|| mbi
.AllocationProtect
== PAGE_EXECUTE_READWRITE
,
2980 "mbi.AllocationProtect is 0x%lx\n", mbi
.AllocationProtect
);
2981 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
2982 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_EXECUTE_READWRITE
,
2983 "mbi.Protect is 0x%lx\n", mbi
.Protect
);
2985 status
= pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
2986 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2987 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
2988 ok (mbi
.AllocationProtect
== PAGE_READWRITE
, "mbi.AllocationProtect is 0x%lx, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_READWRITE
);
2989 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%x\n", mbi
.State
, MEM_COMMIT
);
2990 ok (mbi
.Protect
== PAGE_READWRITE
, "mbi.Protect is 0x%lx, expected 0x%x\n", mbi
.Protect
, PAGE_READWRITE
);
2992 module
= GetModuleHandleA( NULL
);
2993 status
= pNtQueryVirtualMemory(NtCurrentProcess(), teststring
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
2994 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
2995 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
2996 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
2997 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%lx, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
2998 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
2999 ok (mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%lx, expected 0x%X\n", mbi
.Protect
, PAGE_READONLY
);
3001 status
= pNtQueryVirtualMemory(NtCurrentProcess(), datatestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
3002 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3003 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
3004 ok (mbi
.AllocationBase
== module
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, module
);
3005 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%lx, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
3006 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
3007 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
3008 "mbi.Protect is 0x%lx\n", mbi
.Protect
);
3010 status
= pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
3011 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3012 ok( readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
3013 if (mbi
.AllocationBase
== module
)
3015 ok (mbi
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "mbi.AllocationProtect is 0x%lx, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_EXECUTE_WRITECOPY
);
3016 ok (mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
3017 ok (mbi
.Protect
== PAGE_READWRITE
|| mbi
.Protect
== PAGE_WRITECOPY
,
3018 "mbi.Protect is 0x%lx\n", mbi
.Protect
);
3020 else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
3022 status
= pNtQueryVirtualMemory(NtCurrentProcess(), user_shared_data
, MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
), &readcount
);
3023 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3024 ok(readcount
== sizeof(MEMORY_BASIC_INFORMATION
), "Expected to read %d bytes, got %Id\n",(int)sizeof(MEMORY_BASIC_INFORMATION
),readcount
);
3025 ok(mbi
.AllocationBase
== user_shared_data
, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi
.AllocationBase
, user_shared_data
);
3026 ok(mbi
.AllocationProtect
== PAGE_READONLY
, "mbi.AllocationProtect is 0x%lx, expected 0x%x\n", mbi
.AllocationProtect
, PAGE_READONLY
);
3027 ok(mbi
.State
== MEM_COMMIT
, "mbi.State is 0x%lx, expected 0x%X\n", mbi
.State
, MEM_COMMIT
);
3028 ok(mbi
.Protect
== PAGE_READONLY
, "mbi.Protect is 0x%lx\n", mbi
.Protect
);
3029 ok(mbi
.Type
== MEM_PRIVATE
, "mbi.Type is 0x%lx, expected 0x%x\n", mbi
.Type
, MEM_PRIVATE
);
3030 ok(mbi
.RegionSize
== 0x1000, "mbi.RegionSize is 0x%Ix, expected 0x%x\n", mbi
.RegionSize
, 0x1000);
3032 /* check error code when addr is higher than user space limit */
3033 status
= pNtQuerySystemInformation(SystemBasicInformation
, &sbi
, sizeof(sbi
), NULL
);
3034 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3035 status
= pNtQueryVirtualMemory(NtCurrentProcess(), sbi
.LowestUserAddress
, MemoryBasicInformation
, &mbi
, sizeof(mbi
), &readcount
);
3036 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3037 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (char *)sbi
.LowestUserAddress
-1, MemoryBasicInformation
, &mbi
, sizeof(mbi
), &readcount
);
3038 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3039 status
= pNtQueryVirtualMemory(NtCurrentProcess(), sbi
.HighestUserAddress
, MemoryBasicInformation
, &mbi
, sizeof(mbi
), &readcount
);
3040 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3041 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (char *)sbi
.HighestUserAddress
+1, MemoryBasicInformation
, &mbi
, sizeof(mbi
), &readcount
);
3042 ok(status
== STATUS_INVALID_PARAMETER
, "Expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3043 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (void *)~0, MemoryBasicInformation
, &mbi
, sizeof(mbi
), &readcount
);
3044 ok(status
== STATUS_INVALID_PARAMETER
, "Expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3046 /* check error code when len is less than MEMORY_BASIC_INFORMATION size */
3047 status
= pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation
, &mbi
, sizeof(MEMORY_BASIC_INFORMATION
) - 1, &readcount
);
3048 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3050 module
= GetModuleHandleA( "ntdll.dll" );
3051 memset(buffer
, 0xcc, sizeof(buffer
));
3052 readcount
= 0xdeadbeef;
3053 status
= pNtQueryVirtualMemory(NtCurrentProcess(), module
, MemoryMappedFilenameInformation
,
3054 name
, sizeof(*name
) + 16, &readcount
);
3055 ok(status
== STATUS_BUFFER_OVERFLOW
, "got %08lx\n", status
);
3056 ok(name
->SectionFileName
.Length
== 0xcccc || broken(!name
->SectionFileName
.Length
), /* vista64 */
3057 "Wrong len %u\n", name
->SectionFileName
.Length
);
3058 ok(readcount
> sizeof(*name
), "Wrong count %Iu\n", readcount
);
3060 memset(buffer
, 0xcc, sizeof(buffer
));
3061 readcount
= 0xdeadbeef;
3062 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (char *)module
+ 1234, MemoryMappedFilenameInformation
,
3063 name
, sizeof(buffer
), &readcount
);
3064 ok(status
== STATUS_SUCCESS
, "got %08lx\n", status
);
3065 ok(name
->SectionFileName
.Buffer
== (WCHAR
*)(name
+ 1), "Wrong ptr %p/%p\n",
3066 name
->SectionFileName
.Buffer
, name
+ 1 );
3067 ok(name
->SectionFileName
.Length
!= 0xcccc, "Wrong len %u\n", name
->SectionFileName
.Length
);
3068 ok(name
->SectionFileName
.MaximumLength
== name
->SectionFileName
.Length
+ sizeof(WCHAR
),
3069 "Wrong maxlen %u/%u\n", name
->SectionFileName
.MaximumLength
, name
->SectionFileName
.Length
);
3070 ok(readcount
== sizeof(name
->SectionFileName
) + name
->SectionFileName
.MaximumLength
,
3071 "Wrong count %Iu/%u\n", readcount
, name
->SectionFileName
.MaximumLength
);
3072 ok( !name
->SectionFileName
.Buffer
[name
->SectionFileName
.Length
/ sizeof(WCHAR
)],
3073 "buffer not null-terminated\n" );
3075 memset(buffer
, 0xcc, sizeof(buffer
));
3076 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (char *)module
+ 1234, MemoryMappedFilenameInformation
,
3077 name
, sizeof(buffer
), NULL
);
3078 ok(status
== STATUS_SUCCESS
, "got %08lx\n", status
);
3080 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (char *)module
+ 1234, MemoryMappedFilenameInformation
,
3081 NULL
, sizeof(buffer
), NULL
);
3082 ok(status
== STATUS_ACCESS_VIOLATION
, "got %08lx\n", status
);
3084 memset(buffer
, 0xcc, sizeof(buffer
));
3086 readcount
= 0xdeadbeef;
3087 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (char *)module
+ 321, MemoryMappedFilenameInformation
,
3088 name
, sizeof(*name
) - 1, &readcount
);
3089 ok(status
== STATUS_INFO_LENGTH_MISMATCH
, "got %08lx\n", status
);
3090 ok(name
->SectionFileName
.Length
== 0xcccc, "Wrong len %u\n", name
->SectionFileName
.Length
);
3091 ok(readcount
== prev
, "Wrong count %Iu\n", readcount
);
3093 memset(buffer
, 0xcc, sizeof(buffer
));
3094 readcount
= 0xdeadbeef;
3095 status
= pNtQueryVirtualMemory((HANDLE
)0xdead, (char *)module
+ 1234, MemoryMappedFilenameInformation
,
3096 name
, sizeof(buffer
), &readcount
);
3097 ok(status
== STATUS_INVALID_HANDLE
, "got %08lx\n", status
);
3098 ok(readcount
== 0xdeadbeef || broken(readcount
== 1024 + sizeof(*name
)), /* wow64 */
3099 "Wrong count %Iu\n", readcount
);
3101 memset(buffer
, 0xcc, sizeof(buffer
));
3102 readcount
= 0xdeadbeef;
3103 status
= pNtQueryVirtualMemory(NtCurrentProcess(), buffer
, MemoryMappedFilenameInformation
,
3104 name
, sizeof(buffer
), &readcount
);
3105 ok(status
== STATUS_INVALID_ADDRESS
, "got %08lx\n", status
);
3106 ok(name
->SectionFileName
.Length
== 0xcccc, "Wrong len %u\n", name
->SectionFileName
.Length
);
3107 ok(readcount
== 0xdeadbeef || broken(readcount
== 1024 + sizeof(*name
)), /* wow64 */
3108 "Wrong count %Iu\n", readcount
);
3110 readcount
= 0xdeadbeef;
3111 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (void *)0x1234, MemoryMappedFilenameInformation
,
3112 name
, sizeof(buffer
), &readcount
);
3113 ok(status
== STATUS_INVALID_ADDRESS
, "got %08lx\n", status
);
3114 ok(name
->SectionFileName
.Length
== 0xcccc, "Wrong len %u\n", name
->SectionFileName
.Length
);
3115 ok(readcount
== 0xdeadbeef || broken(readcount
== 1024 + sizeof(*name
)), /* wow64 */
3116 "Wrong count %Iu\n", readcount
);
3118 readcount
= 0xdeadbeef;
3119 status
= pNtQueryVirtualMemory(NtCurrentProcess(), (void *)0x1234, MemoryMappedFilenameInformation
,
3120 name
, sizeof(*name
) - 1, &readcount
);
3121 ok(status
== STATUS_INVALID_ADDRESS
, "got %08lx\n", status
);
3122 ok(name
->SectionFileName
.Length
== 0xcccc, "Wrong len %u\n", name
->SectionFileName
.Length
);
3123 ok(readcount
== 0xdeadbeef || broken(readcount
== 15), /* wow64 */
3124 "Wrong count %Iu\n", readcount
);
3127 static void test_affinity(void)
3130 PROCESS_BASIC_INFORMATION pbi
;
3131 DWORD_PTR proc_affinity
, thread_affinity
;
3132 THREAD_BASIC_INFORMATION tbi
;
3136 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
3137 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3138 proc_affinity
= pbi
.AffinityMask
;
3139 ok( proc_affinity
== get_affinity_mask( si
.dwNumberOfProcessors
), "Unexpected process affinity\n" );
3140 if (si
.dwNumberOfProcessors
< 8 * sizeof(DWORD_PTR
))
3142 proc_affinity
= (DWORD_PTR
)1 << si
.dwNumberOfProcessors
;
3143 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
3144 ok( status
== STATUS_INVALID_PARAMETER
,
3145 "Expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3148 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
3149 ok( status
== STATUS_INVALID_PARAMETER
,
3150 "Expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3152 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3153 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3154 ok( tbi
.AffinityMask
== get_affinity_mask( si
.dwNumberOfProcessors
), "Unexpected thread affinity\n" );
3155 if (si
.dwNumberOfProcessors
< 8 * sizeof(DWORD_PTR
))
3157 thread_affinity
= (DWORD_PTR
)1 << si
.dwNumberOfProcessors
;
3158 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
3159 ok( status
== STATUS_INVALID_PARAMETER
,
3160 "Expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3162 thread_affinity
= 0;
3163 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
3164 ok( status
== STATUS_INVALID_PARAMETER
,
3165 "Expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3167 thread_affinity
= 1;
3168 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
3169 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3170 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3171 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3172 ok( tbi
.AffinityMask
== 1, "Unexpected thread affinity\n" );
3174 /* NOTE: Pre-Vista does not allow bits to be set that are higher than the highest set bit in process affinity mask */
3175 thread_affinity
= (pbi
.AffinityMask
<< 1) | pbi
.AffinityMask
;
3176 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
3177 ok( broken(status
== STATUS_INVALID_PARAMETER
) || (status
== STATUS_SUCCESS
), "Expected STATUS_SUCCESS, got %08lx\n", status
);
3178 if (status
== STATUS_SUCCESS
)
3180 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3181 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3182 ok( tbi
.AffinityMask
== pbi
.AffinityMask
, "Unexpected thread affinity. Expected %Ix, got %Ix\n", pbi
.AffinityMask
, tbi
.AffinityMask
);
3185 thread_affinity
= ~(DWORD_PTR
)0 - 1;
3186 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
3187 ok( broken(status
== STATUS_INVALID_PARAMETER
) || (status
== STATUS_SUCCESS
), "Expected STATUS_SUCCESS, got %08lx\n", status
);
3188 if (status
== STATUS_SUCCESS
)
3190 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3191 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3192 ok( tbi
.AffinityMask
== (pbi
.AffinityMask
& (~(DWORD_PTR
)0 - 1)), "Unexpected thread affinity. Expected %Ix, got %Ix\n", pbi
.AffinityMask
& (~(DWORD_PTR
)0 - 1), tbi
.AffinityMask
);
3195 /* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
3196 thread_affinity
= ~(DWORD_PTR
)0;
3197 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
3198 ok( broken(status
== STATUS_INVALID_PARAMETER
) || status
== STATUS_SUCCESS
,
3199 "Expected STATUS_SUCCESS, got %08lx\n", status
);
3201 if (si
.dwNumberOfProcessors
<= 1)
3203 skip("only one processor, skipping affinity testing\n");
3207 /* Test thread affinity mask resulting from "all processors" flag */
3208 if (status
== STATUS_SUCCESS
)
3210 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3211 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3212 ok( tbi
.AffinityMask
== get_affinity_mask( si
.dwNumberOfProcessors
), "unexpected affinity %#Ix\n", tbi
.AffinityMask
);
3215 skip("Cannot test thread affinity mask for 'all processors' flag\n");
3218 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
3219 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3220 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
3221 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3222 proc_affinity
= pbi
.AffinityMask
;
3223 ok( proc_affinity
== 2, "Unexpected process affinity\n" );
3224 /* Setting the process affinity changes the thread affinity to match */
3225 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3226 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3227 ok( tbi
.AffinityMask
== 2, "Unexpected thread affinity\n" );
3228 /* The thread affinity is restricted to the process affinity */
3229 thread_affinity
= 1;
3230 status
= pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask
, &thread_affinity
, sizeof(thread_affinity
) );
3231 ok( status
== STATUS_INVALID_PARAMETER
,
3232 "Expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3234 proc_affinity
= get_affinity_mask( si
.dwNumberOfProcessors
);
3235 status
= pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask
, &proc_affinity
, sizeof(proc_affinity
) );
3236 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3237 /* Resetting the process affinity also resets the thread affinity */
3238 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3239 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3240 ok( tbi
.AffinityMask
== get_affinity_mask( si
.dwNumberOfProcessors
),
3241 "Unexpected thread affinity\n" );
3244 static DWORD WINAPI
hide_from_debugger_thread(void *arg
)
3246 HANDLE stop_event
= arg
;
3247 WaitForSingleObject( stop_event
, INFINITE
);
3251 static void test_HideFromDebugger(void)
3254 HANDLE thread
, stop_event
;
3258 status
= pNtSetInformationThread( GetCurrentThread(), ThreadHideFromDebugger
, &dummy
, sizeof(ULONG
) );
3259 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3261 status
= pNtSetInformationThread( GetCurrentThread(), ThreadHideFromDebugger
, &dummy
, 1 );
3262 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3263 status
= pNtSetInformationThread( (HANDLE
)0xdeadbeef, ThreadHideFromDebugger
, NULL
, 0 );
3264 ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
3265 status
= pNtSetInformationThread( GetCurrentThread(), ThreadHideFromDebugger
, NULL
, 0 );
3266 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3268 status
= NtQueryInformationThread( GetCurrentThread(), ThreadHideFromDebugger
, &dummy
, sizeof(ULONG
), NULL
);
3269 if (status
== STATUS_INVALID_INFO_CLASS
)
3271 win_skip("ThreadHideFromDebugger not available\n");
3275 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3277 status
= NtQueryInformationThread( (HANDLE
)0xdeadbeef, ThreadHideFromDebugger
, &dummy
, sizeof(ULONG
), NULL
);
3278 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3280 status
= NtQueryInformationThread( GetCurrentThread(), ThreadHideFromDebugger
, &dummy
, 1, NULL
);
3281 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3282 ok( dummy
== 1, "Expected dummy == 1, got %08lx\n", dummy
);
3284 stop_event
= CreateEventA( NULL
, FALSE
, FALSE
, NULL
);
3285 ok( stop_event
!= NULL
, "CreateEvent failed\n" );
3286 thread
= CreateThread( NULL
, 0, hide_from_debugger_thread
, stop_event
, 0, NULL
);
3287 ok( thread
!= INVALID_HANDLE_VALUE
, "CreateThread failed with %ld\n", GetLastError() );
3290 status
= NtQueryInformationThread( thread
, ThreadHideFromDebugger
, &dummy
, 1, NULL
);
3291 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3292 ok( dummy
== 0, "Expected dummy == 0, got %08lx\n", dummy
);
3294 status
= pNtSetInformationThread( thread
, ThreadHideFromDebugger
, NULL
, 0 );
3295 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3298 status
= NtQueryInformationThread( thread
, ThreadHideFromDebugger
, &dummy
, 1, NULL
);
3299 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3300 ok( dummy
== 1, "Expected dummy == 1, got %08lx\n", dummy
);
3302 SetEvent( stop_event
);
3303 WaitForSingleObject( thread
, INFINITE
);
3304 CloseHandle( thread
);
3305 CloseHandle( stop_event
);
3308 static void test_NtGetCurrentProcessorNumber(void)
3312 PROCESS_BASIC_INFORMATION pbi
;
3313 THREAD_BASIC_INFORMATION tbi
;
3314 DWORD_PTR old_process_mask
;
3315 DWORD_PTR old_thread_mask
;
3320 if (!pNtGetCurrentProcessorNumber
) {
3321 win_skip("NtGetCurrentProcessorNumber not available\n");
3326 current_cpu
= pNtGetCurrentProcessorNumber();
3327 if (winetest_debug
> 1) trace("dwNumberOfProcessors: %ld, current processor: %ld\n", si
.dwNumberOfProcessors
, current_cpu
);
3329 status
= NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation
, &pbi
, sizeof(pbi
), NULL
);
3330 old_process_mask
= pbi
.AffinityMask
;
3331 ok(status
== STATUS_SUCCESS
, "got 0x%lx (expected STATUS_SUCCESS)\n", status
);
3333 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3334 old_thread_mask
= tbi
.AffinityMask
;
3335 ok(status
== STATUS_SUCCESS
, "got 0x%lx (expected STATUS_SUCCESS)\n", status
);
3337 /* allow the test to run on all processors */
3338 new_mask
= get_affinity_mask( si
.dwNumberOfProcessors
);
3339 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &new_mask
, sizeof(new_mask
));
3340 ok(status
== STATUS_SUCCESS
, "got 0x%lx (expected STATUS_SUCCESS)\n", status
);
3342 for (i
= 0; i
< si
.dwNumberOfProcessors
; i
++)
3344 new_mask
= (DWORD_PTR
)1 << i
;
3345 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &new_mask
, sizeof(new_mask
));
3346 ok(status
== STATUS_SUCCESS
, "%ld: got 0x%lx (expected STATUS_SUCCESS)\n", i
, status
);
3348 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation
, &tbi
, sizeof(tbi
), NULL
);
3349 ok(status
== STATUS_SUCCESS
, "%ld: got 0x%lx (expected STATUS_SUCCESS)\n", i
, status
);
3351 current_cpu
= pNtGetCurrentProcessorNumber();
3352 ok((current_cpu
== i
), "%ld (new_mask 0x%Ix): running on processor %ld (AffinityMask: 0x%Ix)\n",
3353 i
, new_mask
, current_cpu
, tbi
.AffinityMask
);
3356 /* restore old values */
3357 status
= pNtSetInformationProcess(GetCurrentProcess(), ProcessAffinityMask
, &old_process_mask
, sizeof(old_process_mask
));
3358 ok(status
== STATUS_SUCCESS
, "got 0x%lx (expected STATUS_SUCCESS)\n", status
);
3360 status
= pNtSetInformationThread(GetCurrentThread(), ThreadAffinityMask
, &old_thread_mask
, sizeof(old_thread_mask
));
3361 ok(status
== STATUS_SUCCESS
, "got 0x%lx (expected STATUS_SUCCESS)\n", status
);
3364 static void test_ThreadEnableAlignmentFaultFixup(void)
3370 status
= NtQueryInformationThread( GetCurrentThread(), ThreadEnableAlignmentFaultFixup
, &dummy
, sizeof(ULONG
), NULL
);
3371 ok( status
== STATUS_INVALID_INFO_CLASS
, "Expected STATUS_INVALID_INFO_CLASS, got %08lx\n", status
);
3372 status
= NtQueryInformationThread( GetCurrentThread(), ThreadEnableAlignmentFaultFixup
, &dummy
, 1, NULL
);
3373 ok( status
== STATUS_INVALID_INFO_CLASS
, "Expected STATUS_INVALID_INFO_CLASS, got %08lx\n", status
);
3376 status
= pNtSetInformationThread( GetCurrentThread(), ThreadEnableAlignmentFaultFixup
, &dummy
, sizeof(ULONG
) );
3377 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3378 status
= pNtSetInformationThread( (HANDLE
)0xdeadbeef, ThreadEnableAlignmentFaultFixup
, NULL
, 0 );
3379 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3380 status
= pNtSetInformationThread( (HANDLE
)0xdeadbeef, ThreadEnableAlignmentFaultFixup
, NULL
, 1 );
3381 ok( status
== STATUS_ACCESS_VIOLATION
, "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status
);
3382 status
= pNtSetInformationThread( (HANDLE
)0xdeadbeef, ThreadEnableAlignmentFaultFixup
, &dummy
, 1 );
3383 todo_wine
ok( status
== STATUS_INVALID_HANDLE
, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
3384 status
= pNtSetInformationThread( GetCurrentProcess(), ThreadEnableAlignmentFaultFixup
, &dummy
, 1 );
3385 todo_wine
ok( status
== STATUS_OBJECT_TYPE_MISMATCH
, "Expected STATUS_OBJECT_TYPE_MISMATCH, got %08lx\n", status
);
3387 status
= pNtSetInformationThread( GetCurrentThread(), ThreadEnableAlignmentFaultFixup
, &dummy
, 1 );
3388 ok( status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3391 status
= pNtSetInformationThread( GetCurrentProcess(), ThreadEnableAlignmentFaultFixup
, &dummy
, 8 );
3392 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3395 static DWORD WINAPI
start_address_thread(void *arg
)
3397 PRTL_THREAD_START_ROUTINE entry
;
3403 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
3404 &entry
, sizeof(entry
), &ret
);
3405 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3406 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %lu bytes\n", ret
);
3407 ok(entry
== (void *)start_address_thread
, "expected %p, got %p\n", start_address_thread
, entry
);
3411 static void test_thread_start_address(void)
3413 PRTL_THREAD_START_ROUTINE entry
, expected_entry
;
3414 IMAGE_NT_HEADERS
*nt
;
3420 module
= GetModuleHandleA(0);
3421 ok(module
!= NULL
, "expected non-NULL address for module\n");
3422 nt
= RtlImageNtHeader(module
);
3423 ok(nt
!= NULL
, "expected non-NULL address for NT header\n");
3427 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
3428 &entry
, sizeof(entry
), &ret
);
3429 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3430 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %lu bytes\n", ret
);
3431 expected_entry
= (void *)((char *)module
+ nt
->OptionalHeader
.AddressOfEntryPoint
);
3432 ok(entry
== expected_entry
, "expected %p, got %p\n", expected_entry
, entry
);
3434 entry
= (void *)0xdeadbeef;
3435 status
= pNtSetInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
3436 &entry
, sizeof(entry
));
3437 ok(status
== STATUS_SUCCESS
|| status
== STATUS_INVALID_PARAMETER
, /* >= Vista */
3438 "expected STATUS_SUCCESS or STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3440 if (status
== STATUS_SUCCESS
)
3444 status
= pNtQueryInformationThread(GetCurrentThread(), ThreadQuerySetWin32StartAddress
,
3445 &entry
, sizeof(entry
), &ret
);
3446 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3447 ok(ret
== sizeof(entry
), "NtQueryInformationThread returned %lu bytes\n", ret
);
3448 ok(entry
== (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", entry
);
3451 thread
= CreateThread(NULL
, 0, start_address_thread
, NULL
, 0, NULL
);
3452 ok(thread
!= INVALID_HANDLE_VALUE
, "CreateThread failed with %ld\n", GetLastError());
3453 ret
= WaitForSingleObject(thread
, 1000);
3454 ok(ret
== WAIT_OBJECT_0
, "expected WAIT_OBJECT_0, got %lu\n", ret
);
3455 CloseHandle(thread
);
3458 static void test_query_data_alignment(void)
3460 SYSTEM_CPU_INFORMATION sci
;
3466 status
= pNtQuerySystemInformation(SystemRecommendedSharedDataAlignment
, &value
, sizeof(value
), &len
);
3467 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %08lx\n", status
);
3468 ok(sizeof(value
) == len
, "Inconsistent length %lu\n", len
);
3470 pRtlGetNativeSystemInformation(SystemCpuInformation
, &sci
, sizeof(sci
), &len
);
3471 switch (sci
.ProcessorArchitecture
)
3473 case PROCESSOR_ARCHITECTURE_ARM
:
3474 ok(value
== 32, "Expected 32, got %lu\n", value
);
3476 case PROCESSOR_ARCHITECTURE_ARM64
:
3477 ok(value
== 128, "Expected 128, got %lu\n", value
);
3480 ok(value
== 64, "Expected 64, got %lu\n", value
);
3485 static void test_thread_lookup(void)
3487 OBJECT_BASIC_INFORMATION obj_info
;
3488 THREAD_BASIC_INFORMATION info
;
3489 OBJECT_ATTRIBUTES attr
;
3494 InitializeObjectAttributes( &attr
, NULL
, 0, NULL
, NULL
);
3495 cid
.UniqueProcess
= ULongToHandle(GetCurrentProcessId());
3496 cid
.UniqueThread
= ULongToHandle(GetCurrentThreadId());
3497 status
= pNtOpenThread(&handle
, THREAD_QUERY_INFORMATION
, &attr
, &cid
);
3498 ok(!status
, "NtOpenThread returned %#lx\n", status
);
3499 status
= pNtOpenThread((HANDLE
*)0xdeadbee0, THREAD_QUERY_INFORMATION
, &attr
, &cid
);
3500 ok( status
== STATUS_ACCESS_VIOLATION
, "NtOpenThread returned %#lx\n", status
);
3502 status
= pNtQueryObject(handle
, ObjectBasicInformation
, &obj_info
, sizeof(obj_info
), NULL
);
3503 ok(!status
, "NtQueryObject returned: %#lx\n", status
);
3504 ok(obj_info
.GrantedAccess
== (THREAD_QUERY_LIMITED_INFORMATION
| THREAD_QUERY_INFORMATION
)
3505 || broken(obj_info
.GrantedAccess
== THREAD_QUERY_INFORMATION
), /* winxp */
3506 "GrantedAccess = %lx\n", obj_info
.GrantedAccess
);
3508 status
= pNtQueryInformationThread(handle
, ThreadBasicInformation
, &info
, sizeof(info
), NULL
);
3509 ok(!status
, "NtQueryInformationThread returned %#lx\n", status
);
3510 ok(info
.ClientId
.UniqueProcess
== ULongToHandle(GetCurrentProcessId()),
3511 "UniqueProcess = %p expected %lx\n", info
.ClientId
.UniqueProcess
, GetCurrentProcessId());
3512 ok(info
.ClientId
.UniqueThread
== ULongToHandle(GetCurrentThreadId()),
3513 "UniqueThread = %p expected %lx\n", info
.ClientId
.UniqueThread
, GetCurrentThreadId());
3516 cid
.UniqueProcess
= 0;
3517 cid
.UniqueThread
= ULongToHandle(GetCurrentThreadId());
3518 status
= pNtOpenThread(&handle
, THREAD_QUERY_INFORMATION
, &attr
, &cid
);
3519 ok(!status
, "NtOpenThread returned %#lx\n", status
);
3520 status
= pNtQueryInformationThread(handle
, ThreadBasicInformation
, &info
, sizeof(info
), NULL
);
3521 ok(!status
, "NtQueryInformationThread returned %#lx\n", status
);
3522 ok(info
.ClientId
.UniqueProcess
== ULongToHandle(GetCurrentProcessId()),
3523 "UniqueProcess = %p expected %lx\n", info
.ClientId
.UniqueProcess
, GetCurrentProcessId());
3524 ok(info
.ClientId
.UniqueThread
== ULongToHandle(GetCurrentThreadId()),
3525 "UniqueThread = %p expected %lx\n", info
.ClientId
.UniqueThread
, GetCurrentThreadId());
3528 cid
.UniqueProcess
= ULongToHandle(0xdeadbeef);
3529 cid
.UniqueThread
= ULongToHandle(GetCurrentThreadId());
3530 handle
= (HANDLE
)0xdeadbeef;
3531 status
= NtOpenThread(&handle
, THREAD_QUERY_INFORMATION
, &attr
, &cid
);
3533 ok(status
== STATUS_INVALID_CID
, "NtOpenThread returned %#lx\n", status
);
3535 ok( !handle
|| broken(handle
== (HANDLE
)0xdeadbeef) /* vista */, "handle set %p\n", handle
);
3536 if (!status
) pNtClose(handle
);
3538 cid
.UniqueProcess
= 0;
3539 cid
.UniqueThread
= ULongToHandle(0xdeadbeef);
3540 handle
= (HANDLE
)0xdeadbeef;
3541 status
= pNtOpenThread(&handle
, THREAD_QUERY_INFORMATION
, &attr
, &cid
);
3542 ok(status
== STATUS_INVALID_CID
|| broken(status
== STATUS_INVALID_PARAMETER
) /* winxp */,
3543 "NtOpenThread returned %#lx\n", status
);
3544 ok( !handle
|| broken(handle
== (HANDLE
)0xdeadbeef) /* vista */, "handle set %p\n", handle
);
3547 static void test_thread_ideal_processor(void)
3553 status
= pNtSetInformationThread( GetCurrentThread(), ThreadIdealProcessor
, &number
, sizeof(number
) );
3554 ok(NT_SUCCESS(status
), "Unexpected status %#lx.\n", status
);
3557 status
= pNtSetInformationThread( GetCurrentThread(), ThreadIdealProcessor
, &number
, sizeof(number
) );
3558 ok(status
== STATUS_INVALID_PARAMETER
, "Unexpected status %#lx.\n", status
);
3561 status
= pNtSetInformationThread( GetCurrentThread(), ThreadIdealProcessor
, &number
, sizeof(number
) );
3562 ok(!status
, "Unexpected status %#lx.\n", status
);
3564 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadIdealProcessor
, &number
, sizeof(number
), &len
);
3565 ok(status
== STATUS_INVALID_INFO_CLASS
, "Unexpected status %#lx.\n", status
);
3568 static void test_thread_info(void)
3575 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread
,
3576 &data
, sizeof(data
), &len
);
3577 ok( !status
, "failed %lx\n", status
);
3578 ok( data
== 0 || data
== 1, "wrong data %lx\n", data
);
3579 ok( len
== sizeof(data
), "wrong len %lu\n", len
);
3583 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread
,
3584 &data
, sizeof(data
) - 1, &len
);
3585 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "failed %lx\n", status
);
3586 ok( data
== 0xcccccccc, "wrong data %lx\n", data
);
3587 ok( len
== 0xdeadbeef, "wrong len %lu\n", len
);
3591 status
= pNtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread
,
3592 &data
, sizeof(data
) + 1, &len
);
3593 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "failed %lx\n", status
);
3594 ok( data
== 0xcccccccc, "wrong data %lx\n", data
);
3595 ok( len
== 0xdeadbeef, "wrong len %lu\n", len
);
3598 static void test_debug_object(void)
3602 OBJECT_ATTRIBUTES attr
= { sizeof(attr
) };
3603 ULONG len
, flag
= 0;
3604 DBGUI_WAIT_STATE_CHANGE state
;
3607 status
= pNtCreateDebugObject( &handle
, DEBUG_ALL_ACCESS
, &attr
, 0 );
3608 ok( !status
, "NtCreateDebugObject failed %lx\n", status
);
3609 status
= pNtSetInformationDebugObject( handle
, 0, &flag
, sizeof(ULONG
), &len
);
3610 ok( status
== STATUS_INVALID_PARAMETER
, "NtSetInformationDebugObject failed %lx\n", status
);
3611 status
= pNtSetInformationDebugObject( handle
, 2, &flag
, sizeof(ULONG
), &len
);
3612 ok( status
== STATUS_INVALID_PARAMETER
, "NtSetInformationDebugObject failed %lx\n", status
);
3613 status
= pNtSetInformationDebugObject( (HANDLE
)0xdead, DebugObjectKillProcessOnExitInformation
,
3614 &flag
, sizeof(ULONG
), &len
);
3615 ok( status
== STATUS_INVALID_HANDLE
, "NtSetInformationDebugObject failed %lx\n", status
);
3618 status
= pNtSetInformationDebugObject( handle
, DebugObjectKillProcessOnExitInformation
,
3619 &flag
, sizeof(ULONG
) + 1, &len
);
3620 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtSetInformationDebugObject failed %lx\n", status
);
3621 ok( len
== sizeof(ULONG
), "wrong len %lu\n", len
);
3624 status
= pNtSetInformationDebugObject( handle
, DebugObjectKillProcessOnExitInformation
,
3625 &flag
, sizeof(ULONG
) - 1, &len
);
3626 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtSetInformationDebugObject failed %lx\n", status
);
3627 ok( len
== sizeof(ULONG
), "wrong len %lu\n", len
);
3630 status
= pNtSetInformationDebugObject( handle
, DebugObjectKillProcessOnExitInformation
,
3631 &flag
, sizeof(ULONG
), &len
);
3632 ok( !status
, "NtSetInformationDebugObject failed %lx\n", status
);
3633 ok( !len
, "wrong len %lu\n", len
);
3635 flag
= DEBUG_KILL_ON_CLOSE
;
3636 status
= pNtSetInformationDebugObject( handle
, DebugObjectKillProcessOnExitInformation
,
3637 &flag
, sizeof(ULONG
), &len
);
3638 ok( !status
, "NtSetInformationDebugObject failed %lx\n", status
);
3639 ok( !len
, "wrong len %lu\n", len
);
3641 for (flag
= 2; flag
; flag
<<= 1)
3643 status
= pNtSetInformationDebugObject( handle
, DebugObjectKillProcessOnExitInformation
,
3644 &flag
, sizeof(ULONG
), &len
);
3645 ok( status
== STATUS_INVALID_PARAMETER
, "NtSetInformationDebugObject failed %lx\n", status
);
3650 memset( &state
, 0xdd, sizeof(state
) );
3651 state
.NewState
= DbgIdle
;
3652 memset( &event
, 0xcc, sizeof(event
) );
3653 status
= pDbgUiConvertStateChangeStructure( &state
, &event
);
3654 ok( status
== STATUS_UNSUCCESSFUL
, "DbgUiConvertStateChangeStructure failed %lx\n", status
);
3655 ok( event
.dwProcessId
== 0xdddddddd, "event not updated %lx\n", event
.dwProcessId
);
3656 ok( event
.dwThreadId
== 0xdddddddd, "event not updated %lx\n", event
.dwThreadId
);
3658 state
.NewState
= DbgReplyPending
;
3659 memset( &event
, 0xcc, sizeof(event
) );
3660 status
= pDbgUiConvertStateChangeStructure( &state
, &event
);
3661 ok( status
== STATUS_UNSUCCESSFUL
, "DbgUiConvertStateChangeStructure failed %lx\n", status
);
3662 ok( event
.dwProcessId
== 0xdddddddd, "event not updated %lx\n", event
.dwProcessId
);
3663 ok( event
.dwThreadId
== 0xdddddddd, "event not updated %lx\n", event
.dwThreadId
);
3665 state
.NewState
= 11;
3666 memset( &event
, 0xcc, sizeof(event
) );
3667 status
= pDbgUiConvertStateChangeStructure( &state
, &event
);
3668 ok( status
== STATUS_UNSUCCESSFUL
, "DbgUiConvertStateChangeStructure failed %lx\n", status
);
3669 ok( event
.dwProcessId
== 0xdddddddd, "event not updated %lx\n", event
.dwProcessId
);
3670 ok( event
.dwThreadId
== 0xdddddddd, "event not updated %lx\n", event
.dwThreadId
);
3672 state
.NewState
= DbgExitProcessStateChange
;
3673 state
.StateInfo
.ExitProcess
.ExitStatus
= 0x123456;
3674 status
= pDbgUiConvertStateChangeStructure( &state
, &event
);
3675 ok( !status
, "DbgUiConvertStateChangeStructure failed %lx\n", status
);
3676 ok( event
.dwProcessId
== 0xdddddddd, "event not updated %lx\n", event
.dwProcessId
);
3677 ok( event
.dwThreadId
== 0xdddddddd, "event not updated %lx\n", event
.dwThreadId
);
3678 ok( event
.u
.ExitProcess
.dwExitCode
== 0x123456, "event not updated %lx\n", event
.u
.ExitProcess
.dwExitCode
);
3680 memset( &state
, 0xdd, sizeof(state
) );
3681 state
.NewState
= DbgCreateProcessStateChange
;
3682 status
= pDbgUiConvertStateChangeStructure( &state
, &event
);
3683 ok( !status
, "DbgUiConvertStateChangeStructure failed %lx\n", status
);
3684 ok( event
.dwProcessId
== 0xdddddddd, "event not updated %lx\n", event
.dwProcessId
);
3685 ok( event
.dwThreadId
== 0xdddddddd, "event not updated %lx\n", event
.dwThreadId
);
3686 ok( event
.u
.CreateProcessInfo
.nDebugInfoSize
== 0xdddddddd, "event not updated %lx\n", event
.u
.CreateProcessInfo
.nDebugInfoSize
);
3687 ok( event
.u
.CreateProcessInfo
.lpThreadLocalBase
== NULL
, "event not updated %p\n", event
.u
.CreateProcessInfo
.lpThreadLocalBase
);
3688 ok( event
.u
.CreateProcessInfo
.lpImageName
== NULL
, "event not updated %p\n", event
.u
.CreateProcessInfo
.lpImageName
);
3689 ok( event
.u
.CreateProcessInfo
.fUnicode
== TRUE
, "event not updated %x\n", event
.u
.CreateProcessInfo
.fUnicode
);
3691 memset( &state
, 0xdd, sizeof(state
) );
3692 state
.NewState
= DbgLoadDllStateChange
;
3693 status
= pDbgUiConvertStateChangeStructure( &state
, &event
);
3694 ok( !status
, "DbgUiConvertStateChangeStructure failed %lx\n", status
);
3695 ok( event
.dwProcessId
== 0xdddddddd, "event not updated %lx\n", event
.dwProcessId
);
3696 ok( event
.dwThreadId
== 0xdddddddd, "event not updated %lx\n", event
.dwThreadId
);
3697 ok( event
.u
.LoadDll
.nDebugInfoSize
== 0xdddddddd, "event not updated %lx\n", event
.u
.LoadDll
.nDebugInfoSize
);
3698 ok( PtrToUlong(event
.u
.LoadDll
.lpImageName
) == 0xdddddddd, "event not updated %p\n", event
.u
.LoadDll
.lpImageName
);
3699 ok( event
.u
.LoadDll
.fUnicode
== TRUE
, "event not updated %x\n", event
.u
.LoadDll
.fUnicode
);
3702 static void test_process_instrumentation_callback(void)
3704 PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION info
;
3707 status
= NtSetInformationProcess( GetCurrentProcess(), ProcessInstrumentationCallback
, NULL
, 0 );
3708 ok( status
== STATUS_INFO_LENGTH_MISMATCH
/* Win10 */ || status
== STATUS_INVALID_INFO_CLASS
3709 || status
== STATUS_NOT_SUPPORTED
, "Got unexpected status %#lx.\n", status
);
3710 if (status
!= STATUS_INFO_LENGTH_MISMATCH
)
3712 win_skip( "ProcessInstrumentationCallback is not supported.\n" );
3716 memset(&info
, 0, sizeof(info
));
3717 status
= NtSetInformationProcess( GetCurrentProcess(), ProcessInstrumentationCallback
, &info
, sizeof(info
) );
3718 ok( status
== STATUS_SUCCESS
/* Win 10 */ || broken( status
== STATUS_PRIVILEGE_NOT_HELD
)
3719 || broken( status
== STATUS_INFO_LENGTH_MISMATCH
), "Got unexpected status %#lx.\n", status
);
3721 memset(&info
, 0, sizeof(info
));
3722 status
= NtSetInformationProcess( GetCurrentProcess(), ProcessInstrumentationCallback
, &info
, 2 * sizeof(info
) );
3723 ok( status
== STATUS_SUCCESS
|| status
== STATUS_INFO_LENGTH_MISMATCH
3724 || broken( status
== STATUS_PRIVILEGE_NOT_HELD
) /* some versions and machines before Win10 */,
3725 "Got unexpected status %#lx.\n", status
);
3728 static void test_debuggee_dbgport(int argc
, char **argv
)
3730 NTSTATUS status
, expect_status
;
3731 DWORD_PTR debug_port
= 0xdeadbeef;
3732 DWORD debug_flags
= 0xdeadbeef;
3738 ok(0, "insufficient arguments for child process\n");
3742 access
= strtoul(argv
[1], NULL
, 0);
3743 winetest_push_context("debug object access %08lx", access
);
3745 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessDebugPort
,
3746 &debug_port
, sizeof(debug_port
), NULL
);
3747 ok( !status
, "NtQueryInformationProcess ProcessDebugPort failed, status %#lx.\n", status
);
3748 ok( debug_port
== ~(DWORD_PTR
)0, "Expected port %#Ix, got %#Ix.\n", ~(DWORD_PTR
)0, debug_port
);
3750 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessDebugFlags
,
3751 &debug_flags
, sizeof(debug_flags
), NULL
);
3752 ok( !status
, "NtQueryInformationProcess ProcessDebugFlags failed, status %#lx.\n", status
);
3754 expect_status
= access
? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
3755 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessDebugObjectHandle
,
3756 &handle
, sizeof(handle
), NULL
);
3757 ok( status
== expect_status
, "NtQueryInformationProcess ProcessDebugObjectHandle expected status %#lx, actual %#lx.\n", expect_status
, status
);
3758 if (SUCCEEDED( status
)) NtClose( handle
);
3760 winetest_pop_context();
3763 static DWORD WINAPI
test_ThreadIsTerminated_thread( void *stop_event
)
3765 WaitForSingleObject( stop_event
, INFINITE
);
3766 return STATUS_PENDING
;
3769 static void test_ThreadIsTerminated(void)
3771 HANDLE thread
, stop_event
;
3775 stop_event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
3776 thread
= CreateThread( NULL
, 0, test_ThreadIsTerminated_thread
, stop_event
, 0, NULL
);
3777 ok( thread
!= INVALID_HANDLE_VALUE
, "failed, error %ld\n", GetLastError() );
3779 status
= pNtQueryInformationThread( thread
, ThreadIsTerminated
, &terminated
, sizeof(terminated
) * 2, NULL
);
3780 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx.\n", status
);
3782 terminated
= 0xdeadbeef;
3783 status
= pNtQueryInformationThread( thread
, ThreadIsTerminated
, &terminated
, sizeof(terminated
), NULL
);
3784 ok( !status
, "got %#lx.\n", status
);
3785 ok( !terminated
, "got %lu.\n", terminated
);
3787 SetEvent( stop_event
);
3788 WaitForSingleObject( thread
, INFINITE
);
3790 status
= pNtQueryInformationThread( thread
, ThreadIsTerminated
, &terminated
, sizeof(terminated
), NULL
);
3791 ok( !status
, "got %#lx.\n", status
);
3792 ok( terminated
== 1, "got %lu.\n", terminated
);
3794 CloseHandle(stop_event
);
3795 CloseHandle(thread
);
3797 status
= pNtQueryInformationThread( thread
, ThreadIsTerminated
, &terminated
, sizeof(terminated
), NULL
);
3798 ok( status
== STATUS_INVALID_HANDLE
, "got %#lx.\n", status
);
3801 static void test_system_debug_control(void)
3806 for (class = 0; class < SysDbgMaxInfoClass
; ++class)
3808 status
= pNtSystemDebugControl( class, NULL
, 0, NULL
, 0, NULL
);
3811 /* Most of the calls return STATUS_NOT_IMPLEMENTED on wow64. */
3812 ok( status
== STATUS_DEBUGGER_INACTIVE
|| status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_INFO_LENGTH_MISMATCH
,
3813 "class %d, got %#lx.\n", class, status
);
3817 ok( status
== STATUS_DEBUGGER_INACTIVE
|| status
== STATUS_ACCESS_DENIED
|| status
== STATUS_INFO_LENGTH_MISMATCH
,
3818 "class %d, got %#lx.\n", class, status
);
3823 static void test_process_token(int argc
, char **argv
)
3825 STARTUPINFOA si
= {.cb
= sizeof(si
)};
3826 PROCESS_ACCESS_TOKEN token_info
= {0};
3827 TOKEN_STATISTICS stats1
, stats2
;
3828 HANDLE token
, their_token
;
3829 PROCESS_INFORMATION pi
;
3830 char cmdline
[MAX_PATH
];
3835 token_info
.Thread
= (HANDLE
)0xdeadbeef;
3837 sprintf( cmdline
, "%s %s dummy", argv
[0], argv
[1] );
3839 ret
= CreateProcessA( NULL
, cmdline
, NULL
, NULL
, FALSE
, CREATE_SUSPENDED
, NULL
, NULL
, &si
, &pi
);
3840 ok( ret
, "got error %lu\n", GetLastError() );
3842 status
= pNtSetInformationProcess( pi
.hProcess
, ProcessAccessToken
, &token_info
, sizeof(token_info
) - 1 );
3843 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", status
);
3845 status
= pNtSetInformationProcess( pi
.hProcess
, ProcessAccessToken
, &token_info
, sizeof(token_info
) );
3846 ok( status
== STATUS_INVALID_HANDLE
, "got %#lx\n", status
);
3848 ret
= OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY
| READ_CONTROL
| TOKEN_DUPLICATE
3849 | TOKEN_ASSIGN_PRIMARY
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_ADJUST_DEFAULT
, &token
);
3850 ok( ret
, "got error %lu\n", GetLastError() );
3852 token_info
.Token
= token
;
3853 status
= pNtSetInformationProcess( pi
.hProcess
, ProcessAccessToken
, &token_info
, sizeof(token_info
) );
3854 todo_wine
ok( status
== STATUS_TOKEN_ALREADY_IN_USE
, "got %#lx\n", status
);
3856 ret
= DuplicateTokenEx( token
, TOKEN_ALL_ACCESS
, NULL
, SecurityAnonymous
, TokenImpersonation
, &token_info
.Token
);
3857 ok( ret
, "got error %lu\n", GetLastError() );
3858 status
= pNtSetInformationProcess( pi
.hProcess
, ProcessAccessToken
, &token_info
, sizeof(token_info
) );
3859 todo_wine
ok( status
== STATUS_BAD_IMPERSONATION_LEVEL
, "got %#lx\n", status
);
3860 CloseHandle( token_info
.Token
);
3862 ret
= DuplicateTokenEx( token
, TOKEN_QUERY
, NULL
, SecurityAnonymous
, TokenPrimary
, &token_info
.Token
);
3863 ok( ret
, "got error %lu\n", GetLastError() );
3864 status
= pNtSetInformationProcess( pi
.hProcess
, ProcessAccessToken
, &token_info
, sizeof(token_info
) );
3865 ok( status
== STATUS_ACCESS_DENIED
, "got %#lx\n", status
);
3866 CloseHandle( token_info
.Token
);
3868 ret
= DuplicateTokenEx( token
, TOKEN_QUERY
| TOKEN_ASSIGN_PRIMARY
, NULL
, SecurityAnonymous
, TokenPrimary
, &token_info
.Token
);
3869 ok(ret
, "got error %lu\n", GetLastError());
3870 status
= pNtSetInformationProcess( pi
.hProcess
, ProcessAccessToken
, &token_info
, sizeof(token_info
) );
3871 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3873 ret
= OpenProcessToken( pi
.hProcess
, TOKEN_QUERY
, &their_token
);
3874 ok( ret
, "got error %lu\n", GetLastError() );
3876 /* The tokens should be the same. */
3877 ret
= GetTokenInformation( token_info
.Token
, TokenStatistics
, &stats1
, sizeof(stats1
), &size
);
3878 ok( ret
, "got error %lu\n", GetLastError() );
3879 ret
= GetTokenInformation( their_token
, TokenStatistics
, &stats2
, sizeof(stats2
), &size
);
3880 ok( ret
, "got error %lu\n", GetLastError() );
3881 ok( !memcmp( &stats1
.TokenId
, &stats2
.TokenId
, sizeof(LUID
) ), "expected same IDs\n" );
3883 CloseHandle( token_info
.Token
);
3884 CloseHandle( their_token
);
3886 ResumeThread( pi
.hThread
);
3887 ret
= WaitForSingleObject( pi
.hProcess
, 1000 );
3888 ok( !ret
, "got %d\n", ret
);
3890 CloseHandle( pi
.hProcess
);
3891 CloseHandle( pi
.hThread
);
3892 CloseHandle( token
);
3895 static void test_process_id(void)
3897 char image_name_buffer
[1024 * sizeof(WCHAR
)];
3898 UNICODE_STRING
*image_name
= (UNICODE_STRING
*)image_name_buffer
;
3899 SYSTEM_PROCESS_ID_INFORMATION info
;
3900 unsigned int i
, length
;
3908 status
= NtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName
, image_name
,
3909 sizeof(image_name_buffer
), NULL
);
3910 ok( !status
, "got %#lx.\n", status
);
3911 length
= image_name
->Length
;
3912 image_name
->Buffer
[length
] = 0;
3915 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, NULL
, 0, &len
);
3916 ok( status
== STATUS_INFO_LENGTH_MISMATCH
|| (is_wow64
&& status
== STATUS_ACCESS_VIOLATION
), "got %#lx.\n", status
);
3917 ok( len
== sizeof(info
) || (is_wow64
&& len
== 0xdeadbeef), "got %#lx.\n", len
);
3919 info
.ProcessId
= 0xdeadbeef;
3920 info
.ImageName
.Length
= info
.ImageName
.MaximumLength
= 0;
3921 info
.ImageName
.Buffer
= NULL
;
3922 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
3923 ok( status
== STATUS_INVALID_CID
, "got %#lx.\n", status
);
3924 ok( !info
.ImageName
.Length
, "got %#x.\n", info
.ImageName
.Length
);
3925 ok( !info
.ImageName
.MaximumLength
, "got %#x.\n", info
.ImageName
.MaximumLength
);
3927 info
.ProcessId
= GetCurrentProcessId();
3928 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
3929 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx.\n", status
);
3930 ok( len
== sizeof(info
), "got %#lx.\n", len
);
3931 ok( !info
.ImageName
.Length
, "got %#x.\n", info
.ImageName
.Length
);
3932 ok( info
.ImageName
.MaximumLength
== length
+ 2 || (is_wow64
&& !info
.ImageName
.MaximumLength
),
3933 "got %#x.\n", info
.ImageName
.MaximumLength
);
3935 info
.ImageName
.MaximumLength
= sizeof(name
);
3937 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
3938 ok( status
== STATUS_ACCESS_VIOLATION
, "got %#lx.\n", status
);
3939 ok( len
== sizeof(info
), "got %#lx.\n", len
);
3940 ok( info
.ImageName
.Length
== length
|| (is_wow64
&& !info
.ImageName
.Length
),
3941 "got %u.\n", info
.ImageName
.Length
);
3942 ok( info
.ImageName
.MaximumLength
== length
+ 2 || (is_wow64
&& !info
.ImageName
.Length
),
3943 "got %#x.\n", info
.ImageName
.MaximumLength
);
3945 info
.ProcessId
= 0xdeadbeef;
3946 info
.ImageName
.MaximumLength
= sizeof(name
);
3947 info
.ImageName
.Buffer
= name
;
3948 info
.ImageName
.Length
= 0;
3949 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
3950 ok( status
== STATUS_INVALID_CID
, "got %#lx.\n", status
);
3951 ok( !info
.ImageName
.Length
, "got %#x.\n", info
.ImageName
.Length
);
3952 ok( info
.ImageName
.MaximumLength
== sizeof(name
), "got %#x.\n", info
.ImageName
.MaximumLength
);
3953 ok( info
.ImageName
.Buffer
== name
, "got %p, %p.\n", info
.ImageName
.Buffer
, name
);
3956 info
.ImageName
.MaximumLength
= sizeof(name
);
3957 info
.ImageName
.Buffer
= name
;
3958 info
.ImageName
.Length
= 0;
3959 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
3960 ok( status
== STATUS_INVALID_CID
, "got %#lx.\n", status
);
3961 ok( !info
.ImageName
.Length
, "got %#x.\n", info
.ImageName
.Length
);
3962 ok( info
.ImageName
.MaximumLength
== sizeof(name
), "got %#x.\n", info
.ImageName
.MaximumLength
);
3963 ok( info
.ImageName
.Buffer
== name
, "got non NULL.\n" );
3966 info
.ImageName
.MaximumLength
= sizeof(name
);
3967 info
.ImageName
.Buffer
= name
;
3968 info
.ImageName
.Length
= 4;
3969 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
3970 ok( status
== STATUS_INVALID_PARAMETER
, "got %#lx.\n", status
);
3971 ok( info
.ImageName
.Length
== 4, "got %#x.\n", info
.ImageName
.Length
);
3972 ok( info
.ImageName
.MaximumLength
== sizeof(name
), "got %#x.\n", info
.ImageName
.MaximumLength
);
3973 ok( info
.ImageName
.Buffer
== name
, "got non NULL.\n" );
3975 info
.ProcessId
= GetCurrentProcessId();
3976 info
.ImageName
.MaximumLength
= sizeof(name
);
3977 info
.ImageName
.Buffer
= name
;
3978 info
.ImageName
.Length
= 4;
3979 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), NULL
);
3980 ok( status
== STATUS_INVALID_PARAMETER
, "got %#lx.\n", status
);
3981 ok( info
.ImageName
.Length
== 4, "got %#x.\n", info
.ImageName
.Length
);
3982 ok( info
.ImageName
.MaximumLength
== sizeof(name
), "got %#x.\n", info
.ImageName
.MaximumLength
);
3984 info
.ImageName
.Length
= 0;
3985 memset( name
, 0xcc, sizeof(name
) );
3986 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
3987 ok( !status
, "got %#lx.\n", status
);
3988 ok( info
.ImageName
.Length
== length
, "got %#x.\n", info
.ImageName
.Length
);
3989 ok( len
== sizeof(info
), "got %#lx.\n", len
);
3990 ok( info
.ImageName
.MaximumLength
== info
.ImageName
.Length
+ 2, "got %#x.\n", info
.ImageName
.MaximumLength
);
3991 ok( !name
[info
.ImageName
.Length
/ 2], "got %#x.\n", name
[info
.ImageName
.Length
/ 2] );
3993 ok( info
.ImageName
.Length
== image_name
->Length
, "got %#x, %#x.\n", info
.ImageName
.Length
, image_name
->Length
);
3994 ok( !wcscmp( name
, image_name
->Buffer
), "got %s, %s.\n", debugstr_w(name
), debugstr_w(image_name
->Buffer
) );
3996 bret
= EnumProcesses( pids
, sizeof(pids
), &len
);
3997 ok( bret
, "got error %lu.\n", GetLastError() );
3998 for (i
= 0; i
< len
/ sizeof(*pids
); ++i
)
4000 process
= OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION
, FALSE
, pids
[i
] );
4001 if (pids
[i
] && !process
&& GetLastError() != ERROR_ACCESS_DENIED
)
4003 /* process is gone already. */
4006 info
.ProcessId
= pids
[i
];
4007 info
.ImageName
.Length
= 0;
4008 info
.ImageName
.MaximumLength
= sizeof(name
);
4009 info
.ImageName
.Buffer
= name
;
4010 status
= pNtQuerySystemInformation( SystemProcessIdInformation
, &info
, sizeof(info
), &len
);
4011 ok( info
.ImageName
.Buffer
== name
|| (!info
.ImageName
.MaximumLength
&& !info
.ImageName
.Length
),
4012 "got %p, %p, pid %lu, lengh %u / %u.\n", info
.ImageName
.Buffer
, name
, pids
[i
],
4013 info
.ImageName
.Length
, info
.ImageName
.MaximumLength
);
4015 ok( !status
, "got %#lx, pid %lu.\n", status
, pids
[i
] );
4017 ok( status
== STATUS_INVALID_CID
, "got %#lx, pid %lu.\n", status
, pids
[i
] );
4018 if (process
) CloseHandle( process
);
4029 argc
= winetest_get_mainargs(&argv
);
4032 if (strcmp(argv
[2], "debuggee:dbgport") == 0) test_debuggee_dbgport(argc
- 2, argv
+ 2);
4036 /* NtQuerySystemInformation */
4039 test_query_performance();
4040 test_query_timeofday();
4041 test_query_process( TRUE
);
4042 test_query_process( FALSE
);
4043 test_query_procperf();
4044 test_query_module();
4045 test_query_handle();
4046 test_query_handle_ex();
4048 test_query_interrupt();
4049 test_time_adjustment();
4050 test_query_kerndebug();
4051 test_query_regquota();
4052 test_query_logicalproc();
4053 test_query_logicalprocex();
4054 test_query_cpusetinfo();
4055 test_query_firmware();
4056 test_query_data_alignment();
4058 /* NtPowerInformation */
4059 test_query_battery();
4060 test_query_processor_power_info();
4062 /* NtQueryInformationProcess */
4063 test_query_process_basic();
4064 test_query_process_io();
4065 test_query_process_vm();
4066 test_query_process_times();
4067 test_query_process_debug_port(argc
, argv
);
4068 test_query_process_debug_port_custom_dacl(argc
, argv
);
4069 test_query_process_priority();
4070 test_query_process_handlecount();
4071 test_query_process_wow64();
4072 test_query_process_image_file_name();
4073 test_query_process_debug_object_handle(argc
, argv
);
4074 test_query_process_debug_flags(argc
, argv
);
4075 test_query_process_image_info();
4076 test_query_process_quota_limits();
4077 test_mapprotection();
4080 /* NtQueryInformationThread */
4082 test_HideFromDebugger();
4083 test_thread_start_address();
4084 test_thread_lookup();
4085 test_thread_ideal_processor();
4086 test_ThreadIsTerminated();
4089 test_debug_object();
4091 /* belongs to its own file */
4092 test_readvirtualmemory();
4093 test_queryvirtualmemory();
4094 test_NtGetCurrentProcessorNumber();
4096 test_ThreadEnableAlignmentFaultFixup();
4097 test_process_instrumentation_callback();
4098 test_system_debug_control();
4099 test_process_token(argc
, argv
);