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 SystemProcessorBrandString
: /* char[] */
334 case SystemProcessorFeaturesInformation
: /* SYSTEM_PROCESSOR_FEATURES_INFORMATION */
335 case SystemWineVersionInformation
: /* char[] */
336 return NtQuerySystemInformation( class, ptr
, len
, retlen
);
338 case SystemCpuInformation
: /* SYSTEM_CPU_INFORMATION */
339 case SystemEmulationProcessorInformation
: /* SYSTEM_CPU_INFORMATION */
340 status
= NtQuerySystemInformation( SystemEmulationProcessorInformation
, ptr
, len
, retlen
);
341 if (!status
&& pBTCpuUpdateProcessorInformation
) pBTCpuUpdateProcessorInformation( ptr
);
344 case SystemBasicInformation
: /* SYSTEM_BASIC_INFORMATION */
345 case SystemEmulationBasicInformation
: /* SYSTEM_BASIC_INFORMATION */
346 if (len
== sizeof(SYSTEM_BASIC_INFORMATION32
))
348 SYSTEM_BASIC_INFORMATION info
;
349 SYSTEM_BASIC_INFORMATION32
*info32
= ptr
;
351 if (!(status
= NtQuerySystemInformation( SystemEmulationBasicInformation
, &info
, sizeof(info
), NULL
)))
352 put_system_basic_information( info32
, &info
);
354 else status
= STATUS_INFO_LENGTH_MISMATCH
;
355 if (retlen
) *retlen
= sizeof(SYSTEM_BASIC_INFORMATION32
);
358 case SystemProcessInformation
: /* SYSTEM_PROCESS_INFORMATION */
359 case SystemExtendedProcessInformation
: /* SYSTEM_PROCESS_INFORMATION */
361 ULONG size
= len
* 2, retsize
;
362 SYSTEM_PROCESS_INFORMATION
*info
= Wow64AllocateTemp( size
);
364 status
= NtQuerySystemInformation( class, info
, size
, &retsize
);
367 if (status
== STATUS_INFO_LENGTH_MISMATCH
&& retlen
) *retlen
= retsize
;
370 return put_system_proc_info( ptr
, info
, class == SystemExtendedProcessInformation
, len
, retlen
);
373 case SystemModuleInformation
: /* RTL_PROCESS_MODULES */
374 if (len
>= sizeof(RTL_PROCESS_MODULES32
))
376 RTL_PROCESS_MODULES
*info
;
377 RTL_PROCESS_MODULES32
*info32
= ptr
;
378 ULONG count
= (len
- offsetof( RTL_PROCESS_MODULES32
, Modules
)) / sizeof(info32
->Modules
[0]);
379 ULONG i
, size
= offsetof( RTL_PROCESS_MODULES
, Modules
[count
] );
381 info
= Wow64AllocateTemp( size
);
382 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
384 info32
->ModulesCount
= info
->ModulesCount
;
385 for (i
= 0; i
< info
->ModulesCount
; i
++)
387 info32
->Modules
[i
].Section
= HandleToULong( info
->Modules
[i
].Section
);
388 info32
->Modules
[i
].MappedBaseAddress
= 0;
389 info32
->Modules
[i
].ImageBaseAddress
= 0;
390 info32
->Modules
[i
].ImageSize
= info
->Modules
[i
].ImageSize
;
391 info32
->Modules
[i
].Flags
= info
->Modules
[i
].Flags
;
392 info32
->Modules
[i
].LoadOrderIndex
= info
->Modules
[i
].LoadOrderIndex
;
393 info32
->Modules
[i
].InitOrderIndex
= info
->Modules
[i
].InitOrderIndex
;
394 info32
->Modules
[i
].LoadCount
= info
->Modules
[i
].LoadCount
;
395 info32
->Modules
[i
].NameOffset
= info
->Modules
[i
].NameOffset
;
396 strcpy( (char *)info
->Modules
[i
].Name
, (char *)info32
->Modules
[i
].Name
);
400 else status
= NtQuerySystemInformation( class, NULL
, 0, retlen
);
404 ULONG count
= (*retlen
- offsetof(RTL_PROCESS_MODULES
, Modules
)) / sizeof(RTL_PROCESS_MODULE_INFORMATION32
);
405 *retlen
= offsetof( RTL_PROCESS_MODULES32
, Modules
[count
] );
409 case SystemHandleInformation
: /* SYSTEM_HANDLE_INFORMATION */
410 if (len
>= sizeof(SYSTEM_HANDLE_INFORMATION32
))
412 SYSTEM_HANDLE_INFORMATION
*info
;
413 SYSTEM_HANDLE_INFORMATION32
*info32
= ptr
;
414 ULONG count
= (len
- offsetof(SYSTEM_HANDLE_INFORMATION32
, Handle
)) / sizeof(SYSTEM_HANDLE_ENTRY32
);
415 ULONG i
, size
= offsetof( SYSTEM_HANDLE_INFORMATION
, Handle
[count
] );
417 info
= Wow64AllocateTemp( size
);
418 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
420 info32
->Count
= info
->Count
;
421 for (i
= 0; i
< info
->Count
; i
++)
423 info32
->Handle
[i
].OwnerPid
= info
->Handle
[i
].OwnerPid
;
424 info32
->Handle
[i
].ObjectType
= info
->Handle
[i
].ObjectType
;
425 info32
->Handle
[i
].HandleFlags
= info
->Handle
[i
].HandleFlags
;
426 info32
->Handle
[i
].HandleValue
= info
->Handle
[i
].HandleValue
;
427 info32
->Handle
[i
].ObjectPointer
= PtrToUlong( info
->Handle
[i
].ObjectPointer
);
428 info32
->Handle
[i
].AccessMask
= info
->Handle
[i
].AccessMask
;
433 ULONG count
= (*retlen
- offsetof(SYSTEM_HANDLE_INFORMATION
, Handle
)) / sizeof(SYSTEM_HANDLE_ENTRY
);
434 *retlen
= offsetof( SYSTEM_HANDLE_INFORMATION32
, Handle
[count
] );
438 else return STATUS_INFO_LENGTH_MISMATCH
;
440 case SystemFileCacheInformation
: /* SYSTEM_CACHE_INFORMATION */
441 if (len
>= sizeof(SYSTEM_CACHE_INFORMATION32
))
443 SYSTEM_CACHE_INFORMATION info
;
444 SYSTEM_CACHE_INFORMATION32
*info32
= ptr
;
446 if (!(status
= NtQuerySystemInformation( class, &info
, sizeof(info
), NULL
)))
448 info32
->CurrentSize
= info
.CurrentSize
;
449 info32
->PeakSize
= info
.PeakSize
;
450 info32
->PageFaultCount
= info
.PageFaultCount
;
451 info32
->MinimumWorkingSet
= info
.MinimumWorkingSet
;
452 info32
->MaximumWorkingSet
= info
.MaximumWorkingSet
;
453 info32
->CurrentSizeIncludingTransitionInPages
= info
.CurrentSizeIncludingTransitionInPages
;
454 info32
->PeakSizeIncludingTransitionInPages
= info
.PeakSizeIncludingTransitionInPages
;
455 info32
->TransitionRePurposeCount
= info
.TransitionRePurposeCount
;
456 info32
->Flags
= info
.Flags
;
459 else status
= STATUS_INFO_LENGTH_MISMATCH
;
460 if (retlen
) *retlen
= sizeof(SYSTEM_CACHE_INFORMATION32
);
463 case SystemRegistryQuotaInformation
: /* SYSTEM_REGISTRY_QUOTA_INFORMATION */
464 if (len
>= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION32
))
466 SYSTEM_REGISTRY_QUOTA_INFORMATION info
;
467 SYSTEM_REGISTRY_QUOTA_INFORMATION32
*info32
= ptr
;
469 if (!(status
= NtQuerySystemInformation( class, &info
, sizeof(info
), NULL
)))
471 info32
->RegistryQuotaAllowed
= info
.RegistryQuotaAllowed
;
472 info32
->RegistryQuotaUsed
= info
.RegistryQuotaUsed
;
473 info32
->Reserved1
= PtrToUlong( info
.Reserved1
);
476 else status
= STATUS_INFO_LENGTH_MISMATCH
;
477 if (retlen
) *retlen
= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION32
);
480 case SystemExtendedHandleInformation
: /* SYSTEM_HANDLE_INFORMATION_EX */
481 if (len
>= sizeof(SYSTEM_HANDLE_INFORMATION_EX32
))
483 SYSTEM_HANDLE_INFORMATION_EX
*info
;
484 SYSTEM_HANDLE_INFORMATION_EX32
*info32
= ptr
;
485 ULONG count
= (len
- offsetof(SYSTEM_HANDLE_INFORMATION_EX32
, Handles
)) / sizeof(info32
->Handles
[0]);
486 ULONG i
, size
= offsetof( SYSTEM_HANDLE_INFORMATION_EX
, Handles
[count
] );
488 if (!ptr
) return STATUS_ACCESS_VIOLATION
;
489 info
= Wow64AllocateTemp( size
);
490 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
492 info32
->NumberOfHandles
= info
->NumberOfHandles
;
493 info32
->Reserved
= info
->Reserved
;
494 for (i
= 0; i
< info
->NumberOfHandles
; i
++)
496 info32
->Handles
[i
].Object
= PtrToUlong( info
->Handles
[i
].Object
);
497 info32
->Handles
[i
].UniqueProcessId
= info
->Handles
[i
].UniqueProcessId
;
498 info32
->Handles
[i
].HandleValue
= info
->Handles
[i
].HandleValue
;
499 info32
->Handles
[i
].GrantedAccess
= info
->Handles
[i
].GrantedAccess
;
500 info32
->Handles
[i
].CreatorBackTraceIndex
= info
->Handles
[i
].CreatorBackTraceIndex
;
501 info32
->Handles
[i
].ObjectTypeIndex
= info
->Handles
[i
].ObjectTypeIndex
;
502 info32
->Handles
[i
].HandleAttributes
= info
->Handles
[i
].HandleAttributes
;
503 info32
->Handles
[i
].Reserved
= info
->Handles
[i
].Reserved
;
508 ULONG count
= (*retlen
- offsetof(SYSTEM_HANDLE_INFORMATION_EX
, Handles
)) / sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
);
509 *retlen
= offsetof( SYSTEM_HANDLE_INFORMATION_EX32
, Handles
[count
] );
513 else return STATUS_INFO_LENGTH_MISMATCH
;
515 case SystemLogicalProcessorInformation
: /* SYSTEM_LOGICAL_PROCESSOR_INFORMATION */
517 SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*info
;
518 SYSTEM_LOGICAL_PROCESSOR_INFORMATION32
*info32
= ptr
;
519 ULONG i
, size
, count
;
521 info
= Wow64AllocateTemp( len
* 2 );
522 status
= NtQuerySystemInformation( class, info
, len
* 2, &size
);
523 if (status
&& status
!= STATUS_INFO_LENGTH_MISMATCH
) return status
;
524 count
= size
/ sizeof(*info
);
525 if (!status
&& len
>= count
* sizeof(*info32
))
527 for (i
= 0; i
< count
; i
++)
529 info32
[i
].ProcessorMask
= info
[i
].ProcessorMask
;
530 info32
[i
].Relationship
= info
[i
].Relationship
;
531 info32
[i
].Reserved
[0] = info
[i
].Reserved
[0];
532 info32
[i
].Reserved
[1] = info
[i
].Reserved
[1];
535 else status
= STATUS_INFO_LENGTH_MISMATCH
;
536 if (retlen
) *retlen
= count
* sizeof(*info32
);
540 case SystemModuleInformationEx
: /* RTL_PROCESS_MODULE_INFORMATION_EX */
541 if (len
>= sizeof(RTL_PROCESS_MODULE_INFORMATION_EX
) + sizeof(USHORT
))
543 RTL_PROCESS_MODULE_INFORMATION_EX
*info
;
544 RTL_PROCESS_MODULE_INFORMATION_EX32
*info32
= ptr
;
545 ULONG count
= (len
- sizeof(info32
->NextOffset
)) / sizeof(*info32
);
546 ULONG i
, size
= count
* sizeof(*info
) + sizeof(info
->NextOffset
);
548 info
= Wow64AllocateTemp( size
);
549 if (!(status
= NtQuerySystemInformation( class, info
, size
, retlen
)))
551 RTL_PROCESS_MODULE_INFORMATION_EX
*mod
= info
;
552 for (i
= 0; mod
->NextOffset
; i
++)
554 info32
[i
].NextOffset
= sizeof(*info32
);
555 info32
[i
].BaseInfo
.Section
= HandleToULong( mod
->BaseInfo
.Section
);
556 info32
[i
].BaseInfo
.MappedBaseAddress
= 0;
557 info32
[i
].BaseInfo
.ImageBaseAddress
= 0;
558 info32
[i
].BaseInfo
.ImageSize
= mod
->BaseInfo
.ImageSize
;
559 info32
[i
].BaseInfo
.Flags
= mod
->BaseInfo
.Flags
;
560 info32
[i
].BaseInfo
.LoadOrderIndex
= mod
->BaseInfo
.LoadOrderIndex
;
561 info32
[i
].BaseInfo
.InitOrderIndex
= mod
->BaseInfo
.InitOrderIndex
;
562 info32
[i
].BaseInfo
.LoadCount
= mod
->BaseInfo
.LoadCount
;
563 info32
[i
].BaseInfo
.NameOffset
= mod
->BaseInfo
.NameOffset
;
564 info32
[i
].ImageCheckSum
= mod
->ImageCheckSum
;
565 info32
[i
].TimeDateStamp
= mod
->TimeDateStamp
;
566 info32
[i
].DefaultBase
= 0;
567 strcpy( (char *)info32
[i
].BaseInfo
.Name
, (char *)mod
->BaseInfo
.Name
);
568 mod
= (RTL_PROCESS_MODULE_INFORMATION_EX
*)((char *)mod
+ mod
->NextOffset
);
570 info32
[i
].NextOffset
= 0;
573 else status
= NtQuerySystemInformation( class, NULL
, 0, retlen
);
577 ULONG count
= (*retlen
- sizeof(USHORT
)) / sizeof(RTL_PROCESS_MODULE_INFORMATION_EX
);
578 *retlen
= count
* sizeof(RTL_PROCESS_MODULE_INFORMATION_EX32
) + sizeof(USHORT
);
582 case SystemNativeBasicInformation
:
583 return STATUS_INVALID_INFO_CLASS
;
586 FIXME( "unsupported class %u\n", class );
587 return STATUS_INVALID_INFO_CLASS
;
592 /**********************************************************************
593 * wow64_NtQuerySystemInformationEx
595 NTSTATUS WINAPI
wow64_NtQuerySystemInformationEx( UINT
*args
)
597 SYSTEM_INFORMATION_CLASS
class = get_ulong( &args
);
598 void *query
= get_ptr( &args
);
599 ULONG query_len
= get_ulong( &args
);
600 void *ptr
= get_ptr( &args
);
601 ULONG len
= get_ulong( &args
);
602 ULONG
*retlen
= get_ptr( &args
);
607 if (!query
|| query_len
< sizeof(LONG
)) return STATUS_INVALID_PARAMETER
;
608 handle
= LongToHandle( *(LONG
*)query
);
612 case SystemLogicalProcessorInformationEx
: /* SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX */
614 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
*ex32
, *info32
= ptr
;
615 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*ex
, *info
;
616 ULONG size
, size32
, pos
= 0, pos32
= 0;
618 status
= NtQuerySystemInformationEx( class, &handle
, sizeof(handle
), NULL
, 0, &size
);
619 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) return status
;
620 info
= Wow64AllocateTemp( size
);
621 status
= NtQuerySystemInformationEx( class, &handle
, sizeof(handle
), info
, size
, &size
);
624 for (pos
= pos32
= 0; pos
< size
; pos
+= ex
->Size
, pos32
+= size32
)
626 ex
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*)((char *)info
+ pos
);
627 ex32
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
*)((char *)info32
+ pos32
);
629 switch (ex
->Relationship
)
631 case RelationProcessorCore
:
632 case RelationProcessorPackage
:
633 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
,
634 Processor
.GroupMask
[ex
->Processor
.GroupCount
] );
636 case RelationNumaNode
:
637 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
, NumaNode
) + sizeof( ex32
->NumaNode
);
640 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
, Cache
) + sizeof( ex32
->Cache
);
643 size32
= offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32
,
644 Group
.GroupInfo
[ex
->Group
.MaximumGroupCount
] );
650 if (pos32
+ size32
<= len
) put_logical_proc_info_ex( ex32
, ex
);
652 if (pos32
> len
) status
= STATUS_INFO_LENGTH_MISMATCH
;
655 if (retlen
) *retlen
= size
;
659 case SystemCpuSetInformation
: /* SYSTEM_CPU_SET_INFORMATION */
660 case SystemSupportedProcessorArchitectures
: /* ULONG */
661 return NtQuerySystemInformationEx( class, &handle
, sizeof(handle
), ptr
, len
, retlen
);
664 FIXME( "unsupported class %u\n", class );
665 return STATUS_INVALID_INFO_CLASS
;
670 /**********************************************************************
671 * wow64_NtQuerySystemTime
673 NTSTATUS WINAPI
wow64_NtQuerySystemTime( UINT
*args
)
675 LARGE_INTEGER
*time
= get_ptr( &args
);
677 return NtQuerySystemTime( time
);
681 /**********************************************************************
682 * wow64_NtRaiseHardError
684 NTSTATUS WINAPI
wow64_NtRaiseHardError( UINT
*args
)
686 NTSTATUS status
= get_ulong( &args
);
687 ULONG count
= get_ulong( &args
);
688 ULONG params_mask
= get_ulong( &args
);
689 ULONG
*params
= get_ptr( &args
);
690 HARDERROR_RESPONSE_OPTION option
= get_ulong( &args
);
691 HARDERROR_RESPONSE
*response
= get_ptr( &args
);
693 FIXME( "%08lx %lu %lx %p %u %p: stub\n", status
, count
, params_mask
, params
, option
, response
);
694 return STATUS_NOT_IMPLEMENTED
;
698 /**********************************************************************
699 * wow64_NtSetIntervalProfile
701 NTSTATUS WINAPI
wow64_NtSetIntervalProfile( UINT
*args
)
703 ULONG interval
= get_ulong( &args
);
704 KPROFILE_SOURCE source
= get_ulong( &args
);
706 return NtSetIntervalProfile( interval
, source
);
710 /**********************************************************************
711 * wow64_NtSetSystemInformation
713 NTSTATUS WINAPI
wow64_NtSetSystemInformation( UINT
*args
)
715 SYSTEM_INFORMATION_CLASS
class = get_ulong( &args
);
716 void *info
= get_ptr( &args
);
717 ULONG len
= get_ulong( &args
);
719 return NtSetSystemInformation( class, info
, len
);
723 /**********************************************************************
724 * wow64_NtSetSystemTime
726 NTSTATUS WINAPI
wow64_NtSetSystemTime( UINT
*args
)
728 const LARGE_INTEGER
*new = get_ptr( &args
);
729 LARGE_INTEGER
*old
= get_ptr( &args
);
731 return NtSetSystemTime( new, old
);
735 /**********************************************************************
736 * wow64_NtShutdownSystem
738 NTSTATUS WINAPI
wow64_NtShutdownSystem( UINT
*args
)
740 SHUTDOWN_ACTION action
= get_ulong( &args
);
742 return NtShutdownSystem( action
);
746 /**********************************************************************
747 * wow64_NtSystemDebugControl
749 NTSTATUS WINAPI
wow64_NtSystemDebugControl( UINT
*args
)
751 SYSDBG_COMMAND command
= get_ulong( &args
);
752 void *in_buf
= get_ptr( &args
);
753 ULONG in_len
= get_ulong( &args
);
754 void *out_buf
= get_ptr( &args
);
755 ULONG out_len
= get_ulong( &args
);
756 ULONG
*retlen
= get_ptr( &args
);
758 return NtSystemDebugControl( command
, in_buf
, in_len
, out_buf
, out_len
, retlen
);
762 /**********************************************************************
763 * wow64_NtUnloadDriver
765 NTSTATUS WINAPI
wow64_NtUnloadDriver( UINT
*args
)
767 UNICODE_STRING32
*str32
= get_ptr( &args
);
771 return NtUnloadDriver( unicode_str_32to64( &str
, str32
));
775 /**********************************************************************
776 * wow64_NtWow64GetNativeSystemInformation
778 NTSTATUS WINAPI
wow64_NtWow64GetNativeSystemInformation( UINT
*args
)
780 ULONG
class = get_ulong( &args
);
781 void *ptr
= get_ptr( &args
);
782 ULONG len
= get_ulong( &args
);
783 ULONG
*retlen
= get_ptr( &args
);
789 case SystemBasicInformation
:
790 case SystemEmulationBasicInformation
:
791 if (len
== sizeof(SYSTEM_BASIC_INFORMATION32
))
793 SYSTEM_BASIC_INFORMATION info
;
794 SYSTEM_BASIC_INFORMATION32
*info32
= ptr
;
796 if (!(status
= NtQuerySystemInformation( class, &info
, sizeof(info
), NULL
)))
797 put_system_basic_information( info32
, &info
);
799 else status
= STATUS_INFO_LENGTH_MISMATCH
;
800 if (retlen
) *retlen
= sizeof(SYSTEM_BASIC_INFORMATION32
);
803 case SystemCpuInformation
:
804 case SystemEmulationProcessorInformation
:
805 case SystemNativeBasicInformation
:
806 return NtQuerySystemInformation( class, ptr
, len
, retlen
);
809 return STATUS_INVALID_INFO_CLASS
;