widl: Properly align name table entries.
[wine.git] / dlls / wow64 / system.c
blobb2c8eec87691f1c9c703639da7fb70b4729f0af0
1 /*
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
21 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnt.h"
28 #include "winternl.h"
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 )
61 ULONG i;
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] );
75 break;
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);
80 break;
81 case RelationCache:
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);
89 break;
90 case RelationGroup:
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] );
100 break;
101 default:
102 break;
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));
116 for (;;)
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 );
162 if (ext_info)
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;
177 prev = proc32;
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 );
196 UNICODE_STRING str;
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 /**********************************************************************
217 * wow64_NtLoadDriver
219 NTSTATUS WINAPI wow64_NtLoadDriver( UINT *args )
221 UNICODE_STRING32 *str32 = get_ptr( &args );
223 UNICODE_STRING str;
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 );
240 switch (level)
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 );
248 default:
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 );
266 UNICODE_STRING str;
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 );
282 UNICODE_STRING str;
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 );
299 UNICODE_STRING str;
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 );
316 NTSTATUS status;
318 switch (class)
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 );
342 return status;
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);
356 return status;
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 );
365 if (status)
367 if (status == STATUS_INFO_LENGTH_MISMATCH && retlen) *retlen = retsize;
368 return status;
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 *)info32->Modules[i].Name, (char *)info->Modules[i].Name );
400 else status = NtQuerySystemInformation( class, NULL, 0, retlen );
402 if (retlen)
404 ULONG count = (*retlen - offsetof(RTL_PROCESS_MODULES, Modules)) / sizeof(RTL_PROCESS_MODULE_INFORMATION32);
405 *retlen = offsetof( RTL_PROCESS_MODULES32, Modules[count] );
407 return status;
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;
431 if (retlen)
433 ULONG count = (*retlen - offsetof(SYSTEM_HANDLE_INFORMATION, Handle)) / sizeof(SYSTEM_HANDLE_ENTRY);
434 *retlen = offsetof( SYSTEM_HANDLE_INFORMATION32, Handle[count] );
436 return status;
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);
461 return status;
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);
478 return status;
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;
506 if (retlen)
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] );
511 return status;
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);
537 return status;
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 );
575 if (retlen)
577 ULONG count = (*retlen - sizeof(USHORT)) / sizeof(RTL_PROCESS_MODULE_INFORMATION_EX);
578 *retlen = count * sizeof(RTL_PROCESS_MODULE_INFORMATION_EX32) + sizeof(USHORT);
580 return status;
582 case SystemNativeBasicInformation:
583 return STATUS_INVALID_INFO_CLASS;
585 default:
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 );
604 HANDLE handle;
605 NTSTATUS status;
607 if (!query || query_len < sizeof(LONG)) return STATUS_INVALID_PARAMETER;
608 handle = LongToHandle( *(LONG *)query );
610 switch (class)
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 );
622 if (!status)
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] );
635 break;
636 case RelationNumaNode:
637 size32 = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32, NumaNode ) + sizeof( ex32->NumaNode );
638 break;
639 case RelationCache:
640 size32 = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32, Cache ) + sizeof( ex32->Cache );
641 break;
642 case RelationGroup:
643 size32 = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32,
644 Group.GroupInfo[ex->Group.MaximumGroupCount] );
645 break;
646 default:
647 size32 = 0;
648 continue;
650 if (pos32 + size32 <= len) put_logical_proc_info_ex( ex32, ex );
652 if (pos32 > len) status = STATUS_INFO_LENGTH_MISMATCH;
653 size = pos32;
655 if (retlen) *retlen = size;
656 return status;
659 case SystemCpuSetInformation: /* SYSTEM_CPU_SET_INFORMATION */
660 case SystemSupportedProcessorArchitectures: /* SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION */
661 return NtQuerySystemInformationEx( class, &handle, sizeof(handle), ptr, len, retlen );
663 default:
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 switch (command)
760 case SysDbgBreakPoint:
761 case SysDbgEnableKernelDebugger:
762 case SysDbgDisableKernelDebugger:
763 case SysDbgGetAutoKdEnable:
764 case SysDbgSetAutoKdEnable:
765 case SysDbgGetPrintBufferSize:
766 case SysDbgSetPrintBufferSize:
767 case SysDbgGetKdUmExceptionEnable:
768 case SysDbgSetKdUmExceptionEnable:
769 case SysDbgGetTriageDump:
770 case SysDbgGetKdBlockEnable:
771 case SysDbgSetKdBlockEnable:
772 case SysDbgRegisterForUmBreakInfo:
773 case SysDbgGetUmBreakPid:
774 case SysDbgClearUmBreakPid:
775 case SysDbgGetUmAttachPid:
776 case SysDbgClearUmAttachPid:
777 return NtSystemDebugControl( command, in_buf, in_len, out_buf, out_len, retlen );
779 default:
780 return STATUS_NOT_IMPLEMENTED; /* not implemented on Windows either */
785 /**********************************************************************
786 * wow64_NtUnloadDriver
788 NTSTATUS WINAPI wow64_NtUnloadDriver( UINT *args )
790 UNICODE_STRING32 *str32 = get_ptr( &args );
792 UNICODE_STRING str;
794 return NtUnloadDriver( unicode_str_32to64( &str, str32 ));
798 /**********************************************************************
799 * wow64_NtWow64GetNativeSystemInformation
801 NTSTATUS WINAPI wow64_NtWow64GetNativeSystemInformation( UINT *args )
803 ULONG class = get_ulong( &args );
804 void *ptr = get_ptr( &args );
805 ULONG len = get_ulong( &args );
806 ULONG *retlen = get_ptr( &args );
808 NTSTATUS status;
810 switch (class)
812 case SystemBasicInformation:
813 case SystemEmulationBasicInformation:
814 if (len == sizeof(SYSTEM_BASIC_INFORMATION32))
816 SYSTEM_BASIC_INFORMATION info;
817 SYSTEM_BASIC_INFORMATION32 *info32 = ptr;
819 if (!(status = NtQuerySystemInformation( class, &info, sizeof(info), NULL )))
820 put_system_basic_information( info32, &info );
822 else status = STATUS_INFO_LENGTH_MISMATCH;
823 if (retlen) *retlen = sizeof(SYSTEM_BASIC_INFORMATION32);
824 return status;
826 case SystemCpuInformation:
827 case SystemEmulationProcessorInformation:
828 case SystemNativeBasicInformation:
829 return NtQuerySystemInformation( class, ptr, len, retlen );
831 default:
832 return STATUS_INVALID_INFO_CLASS;