2 * WoW64 system functions
4 * Copyright 2021 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WIN32_NO_STATUS
29 #include "wow64_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wow
);
34 static void put_system_basic_information( SYSTEM_BASIC_INFORMATION32
*info32
,
35 const SYSTEM_BASIC_INFORMATION
*info
)
37 info32
->unknown
= info
->unknown
;
38 info32
->KeMaximumIncrement
= info
->KeMaximumIncrement
;
39 info32
->PageSize
= info
->PageSize
;
40 info32
->MmNumberOfPhysicalPages
= info
->MmNumberOfPhysicalPages
;
41 info32
->MmLowestPhysicalPage
= info
->MmLowestPhysicalPage
;
42 info32
->MmHighestPhysicalPage
= info
->MmHighestPhysicalPage
;
43 info32
->AllocationGranularity
= info
->AllocationGranularity
;
44 info32
->LowestUserAddress
= PtrToUlong( info
->LowestUserAddress
);
45 info32
->HighestUserAddress
= PtrToUlong( info
->HighestUserAddress
);
46 info32
->ActiveProcessorsAffinityMask
= info
->ActiveProcessorsAffinityMask
;
47 info32
->NumberOfProcessors
= info
->NumberOfProcessors
;
51 static void put_group_affinity( GROUP_AFFINITY32
*info32
, const GROUP_AFFINITY
*info
)
53 info32
->Mask
= info
->Mask
;
54 info32
->Group
= info
->Group
;
58 static void put_logical_proc_info_ex( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
*info32
,
59 const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*info
)
63 info32
->Relationship
= info
->Relationship
;
64 info32
->Size
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
, Processor
);
65 switch (info
->Relationship
)
67 case RelationProcessorCore
:
68 case RelationProcessorPackage
:
69 info32
->Processor
.Flags
= info
->Processor
.Flags
;
70 info32
->Processor
.EfficiencyClass
= info
->Processor
.EfficiencyClass
;
71 info32
->Processor
.GroupCount
= info
->Processor
.GroupCount
;
72 for (i
= 0; i
< info
->Processor
.GroupCount
; i
++)
73 put_group_affinity( &info32
->Processor
.GroupMask
[i
], &info
->Processor
.GroupMask
[i
] );
74 info32
->Size
+= offsetof( PROCESSOR_RELATIONSHIP32
, GroupMask
[i
] );
76 case RelationNumaNode
:
77 info32
->NumaNode
.NodeNumber
= info
->NumaNode
.NodeNumber
;
78 put_group_affinity( &info32
->NumaNode
.GroupMask
, &info
->NumaNode
.GroupMask
);
79 info32
->Size
+= sizeof(info32
->NumaNode
);
82 info32
->Cache
.Level
= info
->Cache
.Level
;
83 info32
->Cache
.Associativity
= info
->Cache
.Associativity
;
84 info32
->Cache
.LineSize
= info
->Cache
.LineSize
;
85 info32
->Cache
.CacheSize
= info
->Cache
.CacheSize
;
86 info32
->Cache
.Type
= info
->Cache
.Type
;
87 put_group_affinity( &info32
->Cache
.GroupMask
, &info
->Cache
.GroupMask
);
88 info32
->Size
+= sizeof(info32
->Cache
);
91 info32
->Group
.MaximumGroupCount
= info
->Group
.MaximumGroupCount
;
92 info32
->Group
.ActiveGroupCount
= info
->Group
.ActiveGroupCount
;
93 for (i
= 0; i
< info
->Group
.MaximumGroupCount
; i
++)
95 info32
->Group
.GroupInfo
[i
].MaximumProcessorCount
= info
->Group
.GroupInfo
[i
].MaximumProcessorCount
;
96 info32
->Group
.GroupInfo
[i
].ActiveProcessorCount
= info
->Group
.GroupInfo
[i
].ActiveProcessorCount
;
97 info32
->Group
.GroupInfo
[i
].ActiveProcessorMask
= info
->Group
.GroupInfo
[i
].ActiveProcessorMask
;
99 info32
->Size
+= offsetof( GROUP_RELATIONSHIP32
, GroupInfo
[i
] );
107 static NTSTATUS
put_system_proc_info( SYSTEM_PROCESS_INFORMATION32
*info32
,
108 const SYSTEM_PROCESS_INFORMATION
*info
,
109 BOOL ext_info
, ULONG len
, ULONG
*retlen
)
111 ULONG inpos
= 0, outpos
= 0, i
;
112 SYSTEM_PROCESS_INFORMATION32
*prev
= NULL
;
113 ULONG ti_size
= (ext_info
? sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION
) : sizeof(SYSTEM_THREAD_INFORMATION
));
114 ULONG ti_size32
= (ext_info
? sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION32
) : sizeof(SYSTEM_THREAD_INFORMATION32
));
118 SYSTEM_EXTENDED_THREAD_INFORMATION
*ti
;
119 SYSTEM_EXTENDED_THREAD_INFORMATION32
*ti32
;
120 SYSTEM_PROCESS_INFORMATION
*proc
= (SYSTEM_PROCESS_INFORMATION
*)((char *)info
+ inpos
);
121 SYSTEM_PROCESS_INFORMATION32
*proc32
= (SYSTEM_PROCESS_INFORMATION32
*)((char *)info32
+ outpos
);
122 ULONG proc_len
= offsetof( SYSTEM_PROCESS_INFORMATION32
, ti
) + proc
->dwThreadCount
* ti_size32
;
124 if (outpos
+ proc_len
+ proc
->ProcessName
.MaximumLength
<= len
)
126 memset( proc32
, 0, proc_len
);
128 proc32
->dwThreadCount
= proc
->dwThreadCount
;
129 proc32
->WorkingSetPrivateSize
= proc
->WorkingSetPrivateSize
;
130 proc32
->HardFaultCount
= proc
->HardFaultCount
;
131 proc32
->NumberOfThreadsHighWatermark
= proc
->NumberOfThreadsHighWatermark
;
132 proc32
->CycleTime
= proc
->CycleTime
;
133 proc32
->CreationTime
= proc
->CreationTime
;
134 proc32
->UserTime
= proc
->UserTime
;
135 proc32
->KernelTime
= proc
->KernelTime
;
136 proc32
->ProcessName
.Length
= proc
->ProcessName
.Length
;
137 proc32
->ProcessName
.MaximumLength
= proc
->ProcessName
.MaximumLength
;
138 proc32
->ProcessName
.Buffer
= PtrToUlong( (char *)proc32
+ proc_len
);
139 proc32
->dwBasePriority
= proc
->dwBasePriority
;
140 proc32
->UniqueProcessId
= HandleToULong( proc
->UniqueProcessId
);
141 proc32
->ParentProcessId
= HandleToULong( proc
->ParentProcessId
);
142 proc32
->HandleCount
= proc
->HandleCount
;
143 proc32
->SessionId
= proc
->SessionId
;
144 proc32
->UniqueProcessKey
= proc
->UniqueProcessKey
;
145 proc32
->ioCounters
= proc
->ioCounters
;
146 put_vm_counters( &proc32
->vmCounters
, &proc
->vmCounters
, sizeof(proc32
->vmCounters
) );
147 for (i
= 0; i
< proc
->dwThreadCount
; i
++)
149 ti
= (SYSTEM_EXTENDED_THREAD_INFORMATION
*)((char *)proc
->ti
+ i
* ti_size
);
150 ti32
= (SYSTEM_EXTENDED_THREAD_INFORMATION32
*)((char *)proc32
->ti
+ i
* ti_size32
);
151 ti32
->ThreadInfo
.KernelTime
= ti
->ThreadInfo
.KernelTime
;
152 ti32
->ThreadInfo
.UserTime
= ti
->ThreadInfo
.UserTime
;
153 ti32
->ThreadInfo
.CreateTime
= ti
->ThreadInfo
.CreateTime
;
154 ti32
->ThreadInfo
.dwTickCount
= ti
->ThreadInfo
.dwTickCount
;
155 ti32
->ThreadInfo
.StartAddress
= PtrToUlong( ti
->ThreadInfo
.StartAddress
);
156 ti32
->ThreadInfo
.dwCurrentPriority
= ti
->ThreadInfo
.dwCurrentPriority
;
157 ti32
->ThreadInfo
.dwBasePriority
= ti
->ThreadInfo
.dwBasePriority
;
158 ti32
->ThreadInfo
.dwContextSwitches
= ti
->ThreadInfo
.dwContextSwitches
;
159 ti32
->ThreadInfo
.dwThreadState
= ti
->ThreadInfo
.dwThreadState
;
160 ti32
->ThreadInfo
.dwWaitReason
= ti
->ThreadInfo
.dwWaitReason
;
161 put_client_id( &ti32
->ThreadInfo
.ClientId
, &ti
->ThreadInfo
.ClientId
);
164 ti32
->StackBase
= PtrToUlong( ti
->StackBase
);
165 ti32
->StackLimit
= PtrToUlong( ti
->StackLimit
);
166 ti32
->Win32StartAddress
= PtrToUlong( ti
->Win32StartAddress
);
167 ti32
->TebBase
= PtrToUlong( ti
->TebBase
);
168 ti32
->Reserved2
= ti
->Reserved2
;
169 ti32
->Reserved3
= ti
->Reserved3
;
170 ti32
->Reserved4
= ti
->Reserved4
;
173 memcpy( (char *)proc32
+ proc_len
, proc
->ProcessName
.Buffer
,
174 proc
->ProcessName
.MaximumLength
);
176 if (prev
) prev
->NextEntryOffset
= (char *)proc32
- (char *)prev
;
179 outpos
+= proc_len
+ proc
->ProcessName
.MaximumLength
;
180 inpos
+= proc
->NextEntryOffset
;
181 if (!proc
->NextEntryOffset
) break;
183 if (retlen
) *retlen
= outpos
;
184 if (outpos
<= len
) return STATUS_SUCCESS
;
185 else return STATUS_INFO_LENGTH_MISMATCH
;
189 /**********************************************************************
190 * wow64_NtDisplayString
192 NTSTATUS WINAPI
wow64_NtDisplayString( UINT
*args
)
194 const UNICODE_STRING32
*str32
= get_ptr( &args
);
198 return NtDisplayString( unicode_str_32to64( &str
, str32
));
202 /**********************************************************************
203 * wow64_NtInitiatePowerAction
205 NTSTATUS WINAPI
wow64_NtInitiatePowerAction( UINT
*args
)
207 POWER_ACTION action
= get_ulong( &args
);
208 SYSTEM_POWER_STATE state
= get_ulong( &args
);
209 ULONG flags
= get_ulong( &args
);
210 BOOLEAN async
= get_ulong( &args
);
212 return NtInitiatePowerAction( action
, state
, flags
, async
);
216 /**********************************************************************
219 NTSTATUS WINAPI
wow64_NtLoadDriver( UINT
*args
)
221 UNICODE_STRING32
*str32
= get_ptr( &args
);
225 return NtLoadDriver( unicode_str_32to64( &str
, str32
));
229 /**********************************************************************
230 * wow64_NtPowerInformation
232 NTSTATUS WINAPI
wow64_NtPowerInformation( UINT
*args
)
234 POWER_INFORMATION_LEVEL level
= get_ulong( &args
);
235 void *in_buf
= get_ptr( &args
);
236 ULONG in_len
= get_ulong( &args
);
237 void *out_buf
= get_ptr( &args
);
238 ULONG out_len
= get_ulong( &args
);
242 case SystemPowerCapabilities
: /* SYSTEM_POWER_CAPABILITIES */
243 case SystemBatteryState
: /* SYSTEM_BATTERY_STATE */
244 case SystemExecutionState
: /* ULONG */
245 case ProcessorInformation
: /* PROCESSOR_POWER_INFORMATION */
246 return NtPowerInformation( level
, in_buf
, in_len
, out_buf
, out_len
);
249 FIXME( "unsupported level %u\n", level
);
250 return STATUS_NOT_IMPLEMENTED
;
255 /**********************************************************************
256 * wow64_NtQueryLicenseValue
258 NTSTATUS WINAPI
wow64_NtQueryLicenseValue( UINT
*args
)
260 UNICODE_STRING32
*str32
= get_ptr( &args
);
261 ULONG
*type
= get_ptr( &args
);
262 void *buffer
= get_ptr( &args
);
263 ULONG len
= get_ulong( &args
);
264 ULONG
*retlen
= get_ptr( &args
);
268 return NtQueryLicenseValue( unicode_str_32to64( &str
, str32
), type
, buffer
, len
, retlen
);
272 /**********************************************************************
273 * wow64_NtQuerySystemEnvironmentValue
275 NTSTATUS WINAPI
wow64_NtQuerySystemEnvironmentValue( UINT
*args
)
277 UNICODE_STRING32
*str32
= get_ptr( &args
);
278 WCHAR
*buffer
= get_ptr( &args
);
279 ULONG len
= get_ulong( &args
);
280 ULONG
*retlen
= get_ptr( &args
);
284 return NtQuerySystemEnvironmentValue( unicode_str_32to64( &str
, str32
), buffer
, len
, retlen
);
288 /**********************************************************************
289 * wow64_NtQuerySystemEnvironmentValueEx
291 NTSTATUS WINAPI
wow64_NtQuerySystemEnvironmentValueEx( UINT
*args
)
293 UNICODE_STRING32
*str32
= get_ptr( &args
);
294 GUID
*vendor
= get_ptr( &args
);
295 void *buffer
= get_ptr( &args
);
296 ULONG
*retlen
= get_ptr( &args
);
297 ULONG
*attrib
= get_ptr( &args
);
301 return NtQuerySystemEnvironmentValueEx( unicode_str_32to64( &str
, str32
),
302 vendor
, buffer
, retlen
, attrib
);
306 /**********************************************************************
307 * wow64_NtQuerySystemInformation
309 NTSTATUS WINAPI
wow64_NtQuerySystemInformation( UINT
*args
)
311 SYSTEM_INFORMATION_CLASS
class = get_ulong( &args
);
312 void *ptr
= get_ptr( &args
);
313 ULONG len
= get_ulong( &args
);
314 ULONG
*retlen
= get_ptr( &args
);
320 case SystemPerformanceInformation
: /* SYSTEM_PERFORMANCE_INFORMATION */
321 case SystemTimeOfDayInformation
: /* SYSTEM_TIMEOFDAY_INFORMATION */
322 case SystemProcessorPerformanceInformation
: /* SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION */
323 case SystemInterruptInformation
: /* SYSTEM_INTERRUPT_INFORMATION */
324 case SystemTimeAdjustmentInformation
: /* SYSTEM_TIME_ADJUSTMENT_QUERY */
325 case SystemKernelDebuggerInformation
: /* SYSTEM_KERNEL_DEBUGGER_INFORMATION */
326 case SystemCurrentTimeZoneInformation
: /* RTL_TIME_ZONE_INFORMATION */
327 case SystemRecommendedSharedDataAlignment
: /* ULONG */
328 case SystemFirmwareTableInformation
: /* SYSTEM_FIRMWARE_TABLE_INFORMATION */
329 case SystemDynamicTimeZoneInformation
: /* RTL_DYNAMIC_TIME_ZONE_INFORMATION */
330 case SystemCodeIntegrityInformation
: /* SYSTEM_CODEINTEGRITY_INFORMATION */
331 case SystemKernelDebuggerInformationEx
: /* SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX */
332 case SystemCpuSetInformation
: /* SYSTEM_CPU_SET_INFORMATION */
333 case SystemWineVersionInformation
: /* char[] */
334 return NtQuerySystemInformation( class, ptr
, len
, retlen
);
336 case SystemCpuInformation
: /* SYSTEM_CPU_INFORMATION */
337 case SystemEmulationProcessorInformation
: /* SYSTEM_CPU_INFORMATION */
338 return NtQuerySystemInformation( SystemEmulationProcessorInformation
, ptr
, len
, retlen
);
340 case SystemBasicInformation
: /* SYSTEM_BASIC_INFORMATION */
341 case SystemEmulationBasicInformation
: /* SYSTEM_BASIC_INFORMATION */
342 if (len
== sizeof(SYSTEM_BASIC_INFORMATION32
))
344 SYSTEM_BASIC_INFORMATION info
;
345 SYSTEM_BASIC_INFORMATION32
*info32
= ptr
;
347 if (!(status
= NtQuerySystemInformation( SystemEmulationBasicInformation
, &info
, sizeof(info
), NULL
)))
348 put_system_basic_information( info32
, &info
);
350 else status
= STATUS_INFO_LENGTH_MISMATCH
;
351 if (retlen
) *retlen
= sizeof(SYSTEM_BASIC_INFORMATION32
);
354 case SystemProcessInformation
: /* SYSTEM_PROCESS_INFORMATION */
355 case SystemExtendedProcessInformation
: /* SYSTEM_PROCESS_INFORMATION */
357 ULONG size
= len
* 2, retsize
;
358 SYSTEM_PROCESS_INFORMATION
*info
= Wow64AllocateTemp( size
);
360 status
= NtQuerySystemInformation( class, info
, size
, &retsize
);
363 if (status
== STATUS_INFO_LENGTH_MISMATCH
&& retlen
) *retlen
= retsize
;
366 return put_system_proc_info( ptr
, info
, class == SystemExtendedProcessInformation
, len
, retlen
);
369 case SystemModuleInformation
: /* RTL_PROCESS_MODULES */
370 if (len
>= sizeof(RTL_PROCESS_MODULES32
))
372 RTL_PROCESS_MODULES
*info
;
373 RTL_PROCESS_MODULES32
*info32
= ptr
;
374 ULONG count
= (len
- offsetof( RTL_PROCESS_MODULES32
, Modules
)) / sizeof(info32
->Modules
[0]);
375 ULONG i
, size
= offsetof( RTL_PROCESS_MODULES
, Modules
[count
] );
377 info
= Wow64AllocateTemp( size
);
378 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
380 info32
->ModulesCount
= info
->ModulesCount
;
381 for (i
= 0; i
< info
->ModulesCount
; i
++)
383 info32
->Modules
[i
].Section
= HandleToULong( info
->Modules
[i
].Section
);
384 info32
->Modules
[i
].MappedBaseAddress
= 0;
385 info32
->Modules
[i
].ImageBaseAddress
= 0;
386 info32
->Modules
[i
].ImageSize
= info
->Modules
[i
].ImageSize
;
387 info32
->Modules
[i
].Flags
= info
->Modules
[i
].Flags
;
388 info32
->Modules
[i
].LoadOrderIndex
= info
->Modules
[i
].LoadOrderIndex
;
389 info32
->Modules
[i
].InitOrderIndex
= info
->Modules
[i
].InitOrderIndex
;
390 info32
->Modules
[i
].LoadCount
= info
->Modules
[i
].LoadCount
;
391 info32
->Modules
[i
].NameOffset
= info
->Modules
[i
].NameOffset
;
392 strcpy( (char *)info
->Modules
[i
].Name
, (char *)info32
->Modules
[i
].Name
);
396 else status
= NtQuerySystemInformation( class, NULL
, 0, retlen
);
400 ULONG count
= (*retlen
- offsetof(RTL_PROCESS_MODULES
, Modules
)) / sizeof(RTL_PROCESS_MODULE_INFORMATION32
);
401 *retlen
= offsetof( RTL_PROCESS_MODULES32
, Modules
[count
] );
405 case SystemHandleInformation
: /* SYSTEM_HANDLE_INFORMATION */
406 if (len
>= sizeof(SYSTEM_HANDLE_INFORMATION32
))
408 SYSTEM_HANDLE_INFORMATION
*info
;
409 SYSTEM_HANDLE_INFORMATION32
*info32
= ptr
;
410 ULONG count
= (len
- offsetof(SYSTEM_HANDLE_INFORMATION32
, Handle
)) / sizeof(SYSTEM_HANDLE_ENTRY32
);
411 ULONG i
, size
= offsetof( SYSTEM_HANDLE_INFORMATION
, Handle
[count
] );
413 info
= Wow64AllocateTemp( size
);
414 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
416 info32
->Count
= info
->Count
;
417 for (i
= 0; i
< info
->Count
; i
++)
419 info32
->Handle
[i
].OwnerPid
= info
->Handle
[i
].OwnerPid
;
420 info32
->Handle
[i
].ObjectType
= info
->Handle
[i
].ObjectType
;
421 info32
->Handle
[i
].HandleFlags
= info
->Handle
[i
].HandleFlags
;
422 info32
->Handle
[i
].HandleValue
= info
->Handle
[i
].HandleValue
;
423 info32
->Handle
[i
].ObjectPointer
= PtrToUlong( info
->Handle
[i
].ObjectPointer
);
424 info32
->Handle
[i
].AccessMask
= info
->Handle
[i
].AccessMask
;
429 ULONG count
= (*retlen
- offsetof(SYSTEM_HANDLE_INFORMATION
, Handle
)) / sizeof(SYSTEM_HANDLE_ENTRY
);
430 *retlen
= offsetof( SYSTEM_HANDLE_INFORMATION32
, Handle
[count
] );
434 else return STATUS_INFO_LENGTH_MISMATCH
;
436 case SystemFileCacheInformation
: /* SYSTEM_CACHE_INFORMATION */
437 if (len
>= sizeof(SYSTEM_CACHE_INFORMATION32
))
439 SYSTEM_CACHE_INFORMATION info
;
440 SYSTEM_CACHE_INFORMATION32
*info32
= ptr
;
442 if (!(status
= NtQuerySystemInformation( class, &info
, sizeof(info
), NULL
)))
444 info32
->CurrentSize
= info
.CurrentSize
;
445 info32
->PeakSize
= info
.PeakSize
;
446 info32
->PageFaultCount
= info
.PageFaultCount
;
447 info32
->MinimumWorkingSet
= info
.MinimumWorkingSet
;
448 info32
->MaximumWorkingSet
= info
.MaximumWorkingSet
;
449 info32
->CurrentSizeIncludingTransitionInPages
= info
.CurrentSizeIncludingTransitionInPages
;
450 info32
->PeakSizeIncludingTransitionInPages
= info
.PeakSizeIncludingTransitionInPages
;
451 info32
->TransitionRePurposeCount
= info
.TransitionRePurposeCount
;
452 info32
->Flags
= info
.Flags
;
455 else status
= STATUS_INFO_LENGTH_MISMATCH
;
456 if (retlen
) *retlen
= sizeof(SYSTEM_CACHE_INFORMATION32
);
459 case SystemRegistryQuotaInformation
: /* SYSTEM_REGISTRY_QUOTA_INFORMATION */
460 if (len
>= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION32
))
462 SYSTEM_REGISTRY_QUOTA_INFORMATION info
;
463 SYSTEM_REGISTRY_QUOTA_INFORMATION32
*info32
= ptr
;
465 if (!(status
= NtQuerySystemInformation( class, &info
, sizeof(info
), NULL
)))
467 info32
->RegistryQuotaAllowed
= info
.RegistryQuotaAllowed
;
468 info32
->RegistryQuotaUsed
= info
.RegistryQuotaUsed
;
469 info32
->Reserved1
= PtrToUlong( info
.Reserved1
);
472 else status
= STATUS_INFO_LENGTH_MISMATCH
;
473 if (retlen
) *retlen
= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION32
);
476 case SystemExtendedHandleInformation
: /* SYSTEM_HANDLE_INFORMATION_EX */
477 if (len
>= sizeof(SYSTEM_HANDLE_INFORMATION_EX32
))
479 SYSTEM_HANDLE_INFORMATION_EX
*info
;
480 SYSTEM_HANDLE_INFORMATION_EX32
*info32
= ptr
;
481 ULONG count
= (len
- offsetof(SYSTEM_HANDLE_INFORMATION_EX32
, Handles
)) / sizeof(info32
->Handles
[0]);
482 ULONG i
, size
= offsetof( SYSTEM_HANDLE_INFORMATION_EX
, Handles
[count
] );
484 if (!ptr
) return STATUS_ACCESS_VIOLATION
;
485 info
= Wow64AllocateTemp( size
);
486 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
488 info32
->NumberOfHandles
= info
->NumberOfHandles
;
489 info32
->Reserved
= info
->Reserved
;
490 for (i
= 0; i
< info
->NumberOfHandles
; i
++)
492 info32
->Handles
[i
].Object
= PtrToUlong( info
->Handles
[i
].Object
);
493 info32
->Handles
[i
].UniqueProcessId
= info
->Handles
[i
].UniqueProcessId
;
494 info32
->Handles
[i
].HandleValue
= info
->Handles
[i
].HandleValue
;
495 info32
->Handles
[i
].GrantedAccess
= info
->Handles
[i
].GrantedAccess
;
496 info32
->Handles
[i
].CreatorBackTraceIndex
= info
->Handles
[i
].CreatorBackTraceIndex
;
497 info32
->Handles
[i
].ObjectTypeIndex
= info
->Handles
[i
].ObjectTypeIndex
;
498 info32
->Handles
[i
].HandleAttributes
= info
->Handles
[i
].HandleAttributes
;
499 info32
->Handles
[i
].Reserved
= info
->Handles
[i
].Reserved
;
504 ULONG count
= (*retlen
- offsetof(SYSTEM_HANDLE_INFORMATION_EX
, Handles
)) / sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
);
505 *retlen
= offsetof( SYSTEM_HANDLE_INFORMATION_EX32
, Handles
[count
] );
509 else return STATUS_INFO_LENGTH_MISMATCH
;
511 case SystemLogicalProcessorInformation
: /* SYSTEM_LOGICAL_PROCESSOR_INFORMATION */
513 SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*info
;
514 SYSTEM_LOGICAL_PROCESSOR_INFORMATION32
*info32
= ptr
;
515 ULONG i
, size
, count
;
517 info
= Wow64AllocateTemp( len
* 2 );
518 status
= NtQuerySystemInformation( class, info
, len
* 2, &size
);
519 if (status
&& status
!= STATUS_INFO_LENGTH_MISMATCH
) return status
;
520 count
= size
/ sizeof(*info
);
521 if (!status
&& len
>= count
* sizeof(*info32
))
523 for (i
= 0; i
< count
; i
++)
525 info32
[i
].ProcessorMask
= info
[i
].ProcessorMask
;
526 info32
[i
].Relationship
= info
[i
].Relationship
;
527 info32
[i
].Reserved
[0] = info
[i
].Reserved
[0];
528 info32
[i
].Reserved
[1] = info
[i
].Reserved
[1];
531 else status
= STATUS_INFO_LENGTH_MISMATCH
;
532 if (retlen
) *retlen
= count
* sizeof(*info32
);
536 case SystemModuleInformationEx
: /* RTL_PROCESS_MODULE_INFORMATION_EX */
537 if (len
>= sizeof(RTL_PROCESS_MODULE_INFORMATION_EX
) + sizeof(USHORT
))
539 RTL_PROCESS_MODULE_INFORMATION_EX
*info
;
540 RTL_PROCESS_MODULE_INFORMATION_EX32
*info32
= ptr
;
541 ULONG count
= (len
- sizeof(info32
->NextOffset
)) / sizeof(*info32
);
542 ULONG i
, size
= count
* sizeof(*info
) + sizeof(info
->NextOffset
);
544 info
= Wow64AllocateTemp( size
);
545 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
547 RTL_PROCESS_MODULE_INFORMATION_EX
*mod
= info
;
548 for (i
= 0; mod
->NextOffset
; i
++)
550 info32
[i
].NextOffset
= sizeof(*info32
);
551 info32
[i
].BaseInfo
.Section
= HandleToULong( mod
->BaseInfo
.Section
);
552 info32
[i
].BaseInfo
.MappedBaseAddress
= 0;
553 info32
[i
].BaseInfo
.ImageBaseAddress
= 0;
554 info32
[i
].BaseInfo
.ImageSize
= mod
->BaseInfo
.ImageSize
;
555 info32
[i
].BaseInfo
.Flags
= mod
->BaseInfo
.Flags
;
556 info32
[i
].BaseInfo
.LoadOrderIndex
= mod
->BaseInfo
.LoadOrderIndex
;
557 info32
[i
].BaseInfo
.InitOrderIndex
= mod
->BaseInfo
.InitOrderIndex
;
558 info32
[i
].BaseInfo
.LoadCount
= mod
->BaseInfo
.LoadCount
;
559 info32
[i
].BaseInfo
.NameOffset
= mod
->BaseInfo
.NameOffset
;
560 info32
[i
].ImageCheckSum
= mod
->ImageCheckSum
;
561 info32
[i
].TimeDateStamp
= mod
->TimeDateStamp
;
562 info32
[i
].DefaultBase
= 0;
563 strcpy( (char *)info32
[i
].BaseInfo
.Name
, (char *)mod
->BaseInfo
.Name
);
564 mod
= (RTL_PROCESS_MODULE_INFORMATION_EX
*)((char *)mod
+ mod
->NextOffset
);
566 info32
[i
].NextOffset
= 0;
569 else status
= NtQuerySystemInformation( class, NULL
, 0, retlen
);
573 ULONG count
= (*retlen
- sizeof(USHORT
)) / sizeof(RTL_PROCESS_MODULE_INFORMATION_EX
);
574 *retlen
= count
* sizeof(RTL_PROCESS_MODULE_INFORMATION_EX32
) + sizeof(USHORT
);
578 case SystemNativeBasicInformation
:
579 return STATUS_INVALID_INFO_CLASS
;
582 FIXME( "unsupported class %u\n", class );
583 return STATUS_INVALID_INFO_CLASS
;
588 /**********************************************************************
589 * wow64_NtQuerySystemInformationEx
591 NTSTATUS WINAPI
wow64_NtQuerySystemInformationEx( UINT
*args
)
593 SYSTEM_INFORMATION_CLASS
class = get_ulong( &args
);
594 void *query
= get_ptr( &args
);
595 ULONG query_len
= get_ulong( &args
);
596 void *ptr
= get_ptr( &args
);
597 ULONG len
= get_ulong( &args
);
598 ULONG
*retlen
= get_ptr( &args
);
603 if (!query
|| query_len
< sizeof(LONG
)) return STATUS_INVALID_PARAMETER
;
604 handle
= LongToHandle( *(LONG
*)query
);
608 case SystemLogicalProcessorInformationEx
: /* SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX */
610 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
*ex32
, *info32
= ptr
;
611 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*ex
, *info
;
612 ULONG size
, size32
, pos
= 0, pos32
= 0;
614 status
= NtQuerySystemInformationEx( class, &handle
, sizeof(handle
), NULL
, 0, &size
);
615 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) return status
;
616 info
= Wow64AllocateTemp( size
);
617 status
= NtQuerySystemInformationEx( class, &handle
, sizeof(handle
), info
, size
, &size
);
620 for (pos
= pos32
= 0; pos
< size
; pos
+= ex
->Size
, pos32
+= size32
)
622 ex
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*)((char *)info
+ pos
);
623 ex32
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
*)((char *)info32
+ pos32
);
625 switch (ex
->Relationship
)
627 case RelationProcessorCore
:
628 case RelationProcessorPackage
:
629 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
,
630 Processor
.GroupMask
[ex
->Processor
.GroupCount
] );
632 case RelationNumaNode
:
633 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
, NumaNode
) + sizeof( ex32
->NumaNode
);
636 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
, Cache
) + sizeof( ex32
->Cache
);
639 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
,
640 Group
.GroupInfo
[ex
->Group
.MaximumGroupCount
] );
646 if (pos32
+ size32
<= len
) put_logical_proc_info_ex( ex32
, ex
);
648 if (pos32
> len
) status
= STATUS_INFO_LENGTH_MISMATCH
;
651 if (retlen
) *retlen
= size
;
655 case SystemCpuSetInformation
: /* SYSTEM_CPU_SET_INFORMATION */
656 case SystemSupportedProcessorArchitectures
: /* ULONG */
657 return NtQuerySystemInformationEx( class, &handle
, sizeof(handle
), ptr
, len
, retlen
);
660 FIXME( "unsupported class %u\n", class );
661 return STATUS_INVALID_INFO_CLASS
;
666 /**********************************************************************
667 * wow64_NtQuerySystemTime
669 NTSTATUS WINAPI
wow64_NtQuerySystemTime( UINT
*args
)
671 LARGE_INTEGER
*time
= get_ptr( &args
);
673 return NtQuerySystemTime( time
);
677 /**********************************************************************
678 * wow64_NtRaiseHardError
680 NTSTATUS WINAPI
wow64_NtRaiseHardError( UINT
*args
)
682 NTSTATUS status
= get_ulong( &args
);
683 ULONG count
= get_ulong( &args
);
684 ULONG params_mask
= get_ulong( &args
);
685 ULONG
*params
= get_ptr( &args
);
686 HARDERROR_RESPONSE_OPTION option
= get_ulong( &args
);
687 HARDERROR_RESPONSE
*response
= get_ptr( &args
);
689 FIXME( "%08lx %lu %lx %p %u %p: stub\n", status
, count
, params_mask
, params
, option
, response
);
690 return STATUS_NOT_IMPLEMENTED
;
694 /**********************************************************************
695 * wow64_NtSetIntervalProfile
697 NTSTATUS WINAPI
wow64_NtSetIntervalProfile( UINT
*args
)
699 ULONG interval
= get_ulong( &args
);
700 KPROFILE_SOURCE source
= get_ulong( &args
);
702 return NtSetIntervalProfile( interval
, source
);
706 /**********************************************************************
707 * wow64_NtSetSystemInformation
709 NTSTATUS WINAPI
wow64_NtSetSystemInformation( UINT
*args
)
711 SYSTEM_INFORMATION_CLASS
class = get_ulong( &args
);
712 void *info
= get_ptr( &args
);
713 ULONG len
= get_ulong( &args
);
715 return NtSetSystemInformation( class, info
, len
);
719 /**********************************************************************
720 * wow64_NtSetSystemTime
722 NTSTATUS WINAPI
wow64_NtSetSystemTime( UINT
*args
)
724 const LARGE_INTEGER
*new = get_ptr( &args
);
725 LARGE_INTEGER
*old
= get_ptr( &args
);
727 return NtSetSystemTime( new, old
);
731 /**********************************************************************
732 * wow64_NtShutdownSystem
734 NTSTATUS WINAPI
wow64_NtShutdownSystem( UINT
*args
)
736 SHUTDOWN_ACTION action
= get_ulong( &args
);
738 return NtShutdownSystem( action
);
742 /**********************************************************************
743 * wow64_NtSystemDebugControl
745 NTSTATUS WINAPI
wow64_NtSystemDebugControl( UINT
*args
)
747 SYSDBG_COMMAND command
= get_ulong( &args
);
748 void *in_buf
= get_ptr( &args
);
749 ULONG in_len
= get_ulong( &args
);
750 void *out_buf
= get_ptr( &args
);
751 ULONG out_len
= get_ulong( &args
);
752 ULONG
*retlen
= get_ptr( &args
);
754 return NtSystemDebugControl( command
, in_buf
, in_len
, out_buf
, out_len
, retlen
);
758 /**********************************************************************
759 * wow64_NtUnloadDriver
761 NTSTATUS WINAPI
wow64_NtUnloadDriver( UINT
*args
)
763 UNICODE_STRING32
*str32
= get_ptr( &args
);
767 return NtUnloadDriver( unicode_str_32to64( &str
, str32
));
771 /**********************************************************************
772 * wow64_NtWow64GetNativeSystemInformation
774 NTSTATUS WINAPI
wow64_NtWow64GetNativeSystemInformation( UINT
*args
)
776 ULONG
class = get_ulong( &args
);
777 void *ptr
= get_ptr( &args
);
778 ULONG len
= get_ulong( &args
);
779 ULONG
*retlen
= get_ptr( &args
);
785 case SystemBasicInformation
:
786 case SystemEmulationBasicInformation
:
787 if (len
== sizeof(SYSTEM_BASIC_INFORMATION32
))
789 SYSTEM_BASIC_INFORMATION info
;
790 SYSTEM_BASIC_INFORMATION32
*info32
= ptr
;
792 if (!(status
= NtQuerySystemInformation( class, &info
, sizeof(info
), NULL
)))
793 put_system_basic_information( info32
, &info
);
795 else status
= STATUS_INFO_LENGTH_MISMATCH
;
796 if (retlen
) *retlen
= sizeof(SYSTEM_BASIC_INFORMATION32
);
799 case SystemCpuInformation
:
800 case SystemEmulationProcessorInformation
:
801 case SystemNativeBasicInformation
:
802 return NtQuerySystemInformation( class, ptr
, len
, retlen
);
805 return STATUS_INVALID_INFO_CLASS
;