1c2c66affSColin Finck /* 2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory 3c2c66affSColin Finck * PROJECT: ReactOS kernel 4c2c66affSColin Finck * FILE: ntoskrnl/ex/sysinfo.c 5c2c66affSColin Finck * PURPOSE: System information functions 6c2c66affSColin Finck * 7c2c66affSColin Finck * PROGRAMMERS: David Welch (welch@mcmail.com) 8c2c66affSColin Finck * Aleksey Bragin (aleksey@reactos.org) 9c2c66affSColin Finck */ 10c2c66affSColin Finck 11c2c66affSColin Finck /* INCLUDES *****************************************************************/ 12c2c66affSColin Finck 13c2c66affSColin Finck #include <ntoskrnl.h> 14d033fe9bSStanislav Motylkov #include <wmidata.h> 15d033fe9bSStanislav Motylkov #include <wmistr.h> 16c2c66affSColin Finck #define NDEBUG 17c2c66affSColin Finck #include <debug.h> 18c2c66affSColin Finck 19c2c66affSColin Finck /* The maximum size of an environment value (in bytes) */ 20c2c66affSColin Finck #define MAX_ENVVAL_SIZE 1024 21c2c66affSColin Finck 22d033fe9bSStanislav Motylkov #define SIG_ACPI 0x41435049 23d033fe9bSStanislav Motylkov #define SIG_FIRM 0x4649524D 24d033fe9bSStanislav Motylkov #define SIG_RSMB 0x52534D42 25d033fe9bSStanislav Motylkov 26c2c66affSColin Finck extern LIST_ENTRY HandleTableListHead; 27c2c66affSColin Finck extern EX_PUSH_LOCK HandleTableListLock; 28c2c66affSColin Finck 29c2c66affSColin Finck FAST_MUTEX ExpEnvironmentLock; 30c2c66affSColin Finck ERESOURCE ExpFirmwareTableResource; 31c2c66affSColin Finck LIST_ENTRY ExpFirmwareTableProviderListHead; 32c2c66affSColin Finck 33c2c66affSColin Finck FORCEINLINE 34c2c66affSColin Finck NTSTATUS 35c2c66affSColin Finck ExpConvertLdrModuleToRtlModule(IN ULONG ModuleCount, 36c2c66affSColin Finck IN PLDR_DATA_TABLE_ENTRY LdrEntry, 37c2c66affSColin Finck OUT PRTL_PROCESS_MODULE_INFORMATION ModuleInfo) 38c2c66affSColin Finck { 39c2c66affSColin Finck PCHAR p; 40c2c66affSColin Finck NTSTATUS Status; 41c2c66affSColin Finck ANSI_STRING ModuleName; 42c2c66affSColin Finck 43c2c66affSColin Finck /* Fill it out */ 44c2c66affSColin Finck ModuleInfo->MappedBase = NULL; 45c2c66affSColin Finck ModuleInfo->ImageBase = LdrEntry->DllBase; 46c2c66affSColin Finck ModuleInfo->ImageSize = LdrEntry->SizeOfImage; 47c2c66affSColin Finck ModuleInfo->Flags = LdrEntry->Flags; 48c2c66affSColin Finck ModuleInfo->LoadCount = LdrEntry->LoadCount; 49c2c66affSColin Finck ModuleInfo->LoadOrderIndex = (USHORT)ModuleCount; 50c2c66affSColin Finck ModuleInfo->InitOrderIndex = 0; 51c2c66affSColin Finck 52c2c66affSColin Finck /* Setup name */ 53c2c66affSColin Finck RtlInitEmptyAnsiString(&ModuleName, 54c2c66affSColin Finck ModuleInfo->FullPathName, 55c2c66affSColin Finck sizeof(ModuleInfo->FullPathName)); 56c2c66affSColin Finck 57c2c66affSColin Finck /* Convert it */ 58c2c66affSColin Finck Status = RtlUnicodeStringToAnsiString(&ModuleName, 59c2c66affSColin Finck &LdrEntry->FullDllName, 60c2c66affSColin Finck FALSE); 61c2c66affSColin Finck if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) 62c2c66affSColin Finck { 63c2c66affSColin Finck /* Calculate offset to name */ 64c2c66affSColin Finck p = ModuleName.Buffer + ModuleName.Length; 65c2c66affSColin Finck while ((p > ModuleName.Buffer) && (*--p)) 66c2c66affSColin Finck { 67c2c66affSColin Finck /* Check if we found the separator */ 68c2c66affSColin Finck if (*p == OBJ_NAME_PATH_SEPARATOR) 69c2c66affSColin Finck { 70c2c66affSColin Finck /* We did, break out */ 71c2c66affSColin Finck p++; 72c2c66affSColin Finck break; 73c2c66affSColin Finck } 74c2c66affSColin Finck } 75c2c66affSColin Finck 76c2c66affSColin Finck /* Set the offset */ 77c2c66affSColin Finck ModuleInfo->OffsetToFileName = (USHORT)(p - ModuleName.Buffer); 78c2c66affSColin Finck } 79c2c66affSColin Finck else 80c2c66affSColin Finck { 81c2c66affSColin Finck /* Return empty name */ 82c2c66affSColin Finck ModuleInfo->FullPathName[0] = ANSI_NULL; 83c2c66affSColin Finck ModuleInfo->OffsetToFileName = 0; 84c2c66affSColin Finck } 85c2c66affSColin Finck 86c2c66affSColin Finck return Status; 87c2c66affSColin Finck } 88c2c66affSColin Finck 89c2c66affSColin Finck NTSTATUS 90c2c66affSColin Finck NTAPI 91c2c66affSColin Finck ExpQueryModuleInformation(IN PLIST_ENTRY KernelModeList, 92c2c66affSColin Finck IN PLIST_ENTRY UserModeList, 93c2c66affSColin Finck OUT PRTL_PROCESS_MODULES Modules, 94c2c66affSColin Finck IN ULONG Length, 95c2c66affSColin Finck OUT PULONG ReturnLength) 96c2c66affSColin Finck { 97c2c66affSColin Finck NTSTATUS Status = STATUS_SUCCESS; 98c2c66affSColin Finck ULONG RequiredLength; 99c2c66affSColin Finck PRTL_PROCESS_MODULE_INFORMATION ModuleInfo; 100c2c66affSColin Finck PLDR_DATA_TABLE_ENTRY LdrEntry; 101c2c66affSColin Finck ULONG ModuleCount = 0; 102c2c66affSColin Finck PLIST_ENTRY NextEntry; 103c2c66affSColin Finck 104c2c66affSColin Finck /* Setup defaults */ 105c2c66affSColin Finck RequiredLength = FIELD_OFFSET(RTL_PROCESS_MODULES, Modules); 106c2c66affSColin Finck ModuleInfo = &Modules->Modules[0]; 107c2c66affSColin Finck 108c2c66affSColin Finck /* Loop the kernel list */ 109c2c66affSColin Finck NextEntry = KernelModeList->Flink; 110c2c66affSColin Finck while (NextEntry != KernelModeList) 111c2c66affSColin Finck { 112c2c66affSColin Finck /* Get the entry */ 113c2c66affSColin Finck LdrEntry = CONTAINING_RECORD(NextEntry, 114c2c66affSColin Finck LDR_DATA_TABLE_ENTRY, 115c2c66affSColin Finck InLoadOrderLinks); 116c2c66affSColin Finck 117c2c66affSColin Finck /* Update size and check if we can manage one more entry */ 118c2c66affSColin Finck RequiredLength += sizeof(RTL_PROCESS_MODULE_INFORMATION); 119c2c66affSColin Finck if (Length >= RequiredLength) 120c2c66affSColin Finck { 121c2c66affSColin Finck Status = ExpConvertLdrModuleToRtlModule(ModuleCount, 122c2c66affSColin Finck LdrEntry, 123c2c66affSColin Finck ModuleInfo); 124c2c66affSColin Finck 125c2c66affSColin Finck /* Go to the next module */ 126c2c66affSColin Finck ModuleInfo++; 127c2c66affSColin Finck } 128c2c66affSColin Finck else 129c2c66affSColin Finck { 130c2c66affSColin Finck /* Set error code */ 131c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH; 132c2c66affSColin Finck } 133c2c66affSColin Finck 134c2c66affSColin Finck /* Update count and move to next entry */ 135c2c66affSColin Finck ModuleCount++; 136c2c66affSColin Finck NextEntry = NextEntry->Flink; 137c2c66affSColin Finck } 138c2c66affSColin Finck 139c2c66affSColin Finck /* Check if caller also wanted user modules */ 140c2c66affSColin Finck if (UserModeList) 141c2c66affSColin Finck { 142c2c66affSColin Finck NextEntry = UserModeList->Flink; 143c2c66affSColin Finck while (NextEntry != UserModeList) 144c2c66affSColin Finck { 145c2c66affSColin Finck /* Get the entry */ 146c2c66affSColin Finck LdrEntry = CONTAINING_RECORD(NextEntry, 147c2c66affSColin Finck LDR_DATA_TABLE_ENTRY, 148c2c66affSColin Finck InLoadOrderLinks); 149c2c66affSColin Finck 150c2c66affSColin Finck /* Update size and check if we can manage one more entry */ 151c2c66affSColin Finck RequiredLength += sizeof(RTL_PROCESS_MODULE_INFORMATION); 152c2c66affSColin Finck if (Length >= RequiredLength) 153c2c66affSColin Finck { 154c2c66affSColin Finck Status = ExpConvertLdrModuleToRtlModule(ModuleCount, 155c2c66affSColin Finck LdrEntry, 156c2c66affSColin Finck ModuleInfo); 157c2c66affSColin Finck 158c2c66affSColin Finck /* Go to the next module */ 159c2c66affSColin Finck ModuleInfo++; 160c2c66affSColin Finck } 161c2c66affSColin Finck else 162c2c66affSColin Finck { 163c2c66affSColin Finck /* Set error code */ 164c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH; 165c2c66affSColin Finck } 166c2c66affSColin Finck 167c2c66affSColin Finck /* Update count and move to next entry */ 168c2c66affSColin Finck ModuleCount++; 169c2c66affSColin Finck NextEntry = NextEntry->Flink; 170c2c66affSColin Finck } 171c2c66affSColin Finck } 172c2c66affSColin Finck 173c2c66affSColin Finck /* Update return length */ 174c2c66affSColin Finck if (ReturnLength) *ReturnLength = RequiredLength; 175c2c66affSColin Finck 176c2c66affSColin Finck /* Validate the length again */ 177c2c66affSColin Finck if (Length >= FIELD_OFFSET(RTL_PROCESS_MODULES, Modules)) 178c2c66affSColin Finck { 179c2c66affSColin Finck /* Set the final count */ 180c2c66affSColin Finck Modules->NumberOfModules = ModuleCount; 181c2c66affSColin Finck } 182c2c66affSColin Finck else 183c2c66affSColin Finck { 184c2c66affSColin Finck /* Otherwise, we failed */ 185c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH; 186c2c66affSColin Finck } 187c2c66affSColin Finck 188c2c66affSColin Finck /* Done */ 189c2c66affSColin Finck return Status; 190c2c66affSColin Finck } 191c2c66affSColin Finck 192c2c66affSColin Finck VOID 193c2c66affSColin Finck NTAPI 194c2c66affSColin Finck ExUnlockUserBuffer(PMDL Mdl) 195c2c66affSColin Finck { 196c2c66affSColin Finck MmUnlockPages(Mdl); 197c2c66affSColin Finck ExFreePoolWithTag(Mdl, TAG_MDL); 198c2c66affSColin Finck } 199c2c66affSColin Finck 200c2c66affSColin Finck NTSTATUS 201c2c66affSColin Finck NTAPI 202c2c66affSColin Finck ExLockUserBuffer( 203c2c66affSColin Finck PVOID BaseAddress, 204c2c66affSColin Finck ULONG Length, 205c2c66affSColin Finck KPROCESSOR_MODE AccessMode, 206c2c66affSColin Finck LOCK_OPERATION Operation, 207c2c66affSColin Finck PVOID *MappedSystemVa, 208c2c66affSColin Finck PMDL *OutMdl) 209c2c66affSColin Finck { 210c2c66affSColin Finck PMDL Mdl; 211c2c66affSColin Finck PAGED_CODE(); 212c2c66affSColin Finck 213c2c66affSColin Finck *MappedSystemVa = NULL; 214c2c66affSColin Finck *OutMdl = NULL; 215c2c66affSColin Finck 216c2c66affSColin Finck /* Allocate an MDL for the buffer */ 217c2c66affSColin Finck Mdl = IoAllocateMdl(BaseAddress, Length, FALSE, TRUE, NULL); 218c2c66affSColin Finck if (Mdl == NULL) 219c2c66affSColin Finck { 220c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES; 221c2c66affSColin Finck } 222c2c66affSColin Finck 223c2c66affSColin Finck /* Enter SEH for probing */ 224c2c66affSColin Finck _SEH2_TRY 225c2c66affSColin Finck { 226c2c66affSColin Finck MmProbeAndLockPages(Mdl, AccessMode, Operation); 227c2c66affSColin Finck } 228c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 229c2c66affSColin Finck { 230c2c66affSColin Finck ExFreePoolWithTag(Mdl, TAG_MDL); 231c2c66affSColin Finck _SEH2_YIELD(return _SEH2_GetExceptionCode()); 232c2c66affSColin Finck } 233c2c66affSColin Finck _SEH2_END; 234c2c66affSColin Finck 235c2c66affSColin Finck /* Return the safe kernel mode buffer */ 236c2c66affSColin Finck *MappedSystemVa = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); 237c2c66affSColin Finck if (*MappedSystemVa == NULL) 238c2c66affSColin Finck { 239c2c66affSColin Finck ExUnlockUserBuffer(Mdl); 240c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES; 241c2c66affSColin Finck } 242c2c66affSColin Finck 243c2c66affSColin Finck /* Return the MDL */ 244c2c66affSColin Finck *OutMdl = Mdl; 245c2c66affSColin Finck return STATUS_SUCCESS; 246c2c66affSColin Finck } 247c2c66affSColin Finck 248d033fe9bSStanislav Motylkov NTSTATUS 249d033fe9bSStanislav Motylkov NTAPI 250d033fe9bSStanislav Motylkov ExpGetRawSMBiosTable( 251d033fe9bSStanislav Motylkov _Out_opt_ PVOID Buffer, 252d033fe9bSStanislav Motylkov _Out_ ULONG * OutSize, 253d033fe9bSStanislav Motylkov _In_ ULONG BufferSize) 254d033fe9bSStanislav Motylkov { 255d033fe9bSStanislav Motylkov NTSTATUS Status; 256d033fe9bSStanislav Motylkov PVOID DataBlockObject; 257d033fe9bSStanislav Motylkov PWNODE_ALL_DATA AllData; 258d033fe9bSStanislav Motylkov ULONG WMIBufSize; 259d033fe9bSStanislav Motylkov 260d033fe9bSStanislav Motylkov ASSERT(OutSize != NULL); 261d033fe9bSStanislav Motylkov *OutSize = 0; 262d033fe9bSStanislav Motylkov 263d033fe9bSStanislav Motylkov /* Open the data block object for the SMBIOS table */ 264d033fe9bSStanislav Motylkov Status = IoWMIOpenBlock(&MSSmBios_RawSMBiosTables_GUID, 265d033fe9bSStanislav Motylkov WMIGUID_QUERY, 266d033fe9bSStanislav Motylkov &DataBlockObject); 267d033fe9bSStanislav Motylkov if (!NT_SUCCESS(Status)) 268d033fe9bSStanislav Motylkov { 269d033fe9bSStanislav Motylkov DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status); 270d033fe9bSStanislav Motylkov return Status; 271d033fe9bSStanislav Motylkov } 272d033fe9bSStanislav Motylkov 273d033fe9bSStanislav Motylkov /* Query the required buffer size */ 274d033fe9bSStanislav Motylkov WMIBufSize = 0; 275d033fe9bSStanislav Motylkov Status = IoWMIQueryAllData(DataBlockObject, &WMIBufSize, NULL); 276d033fe9bSStanislav Motylkov if (!NT_SUCCESS(Status)) 277d033fe9bSStanislav Motylkov { 278d033fe9bSStanislav Motylkov DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status); 279d033fe9bSStanislav Motylkov return Status; 280d033fe9bSStanislav Motylkov } 281d033fe9bSStanislav Motylkov 282d033fe9bSStanislav Motylkov AllData = ExAllocatePoolWithTag(PagedPool, WMIBufSize, 'itfS'); 283d033fe9bSStanislav Motylkov if (AllData == NULL) 284d033fe9bSStanislav Motylkov { 285d033fe9bSStanislav Motylkov DPRINT1("Failed to allocate %lu bytes for SMBIOS tables\n", WMIBufSize); 286d033fe9bSStanislav Motylkov return STATUS_INSUFFICIENT_RESOURCES; 287d033fe9bSStanislav Motylkov } 288d033fe9bSStanislav Motylkov 289d033fe9bSStanislav Motylkov /* Query the buffer data */ 290d033fe9bSStanislav Motylkov Status = IoWMIQueryAllData(DataBlockObject, &WMIBufSize, AllData); 291d033fe9bSStanislav Motylkov if (!NT_SUCCESS(Status)) 292d033fe9bSStanislav Motylkov { 293d033fe9bSStanislav Motylkov DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status); 294d033fe9bSStanislav Motylkov ExFreePoolWithTag(AllData, 'itfS'); 295d033fe9bSStanislav Motylkov return Status; 296d033fe9bSStanislav Motylkov } 297d033fe9bSStanislav Motylkov 298d033fe9bSStanislav Motylkov Status = STATUS_SUCCESS; 299d033fe9bSStanislav Motylkov *OutSize = AllData->FixedInstanceSize; 300d033fe9bSStanislav Motylkov if (Buffer != NULL) 301d033fe9bSStanislav Motylkov { 302d033fe9bSStanislav Motylkov if (BufferSize >= *OutSize) 303d033fe9bSStanislav Motylkov { 304d033fe9bSStanislav Motylkov RtlMoveMemory(Buffer, AllData + 1, *OutSize); 305d033fe9bSStanislav Motylkov } 306d033fe9bSStanislav Motylkov else 307d033fe9bSStanislav Motylkov { 308d033fe9bSStanislav Motylkov Status = STATUS_BUFFER_TOO_SMALL; 309d033fe9bSStanislav Motylkov } 310d033fe9bSStanislav Motylkov } 311d033fe9bSStanislav Motylkov 312d033fe9bSStanislav Motylkov /* Free the buffer */ 313d033fe9bSStanislav Motylkov ExFreePoolWithTag(AllData, 'itfS'); 314d033fe9bSStanislav Motylkov return Status; 315d033fe9bSStanislav Motylkov } 316d033fe9bSStanislav Motylkov 317c2c66affSColin Finck /* FUNCTIONS *****************************************************************/ 318c2c66affSColin Finck 319c2c66affSColin Finck /* 320c2c66affSColin Finck * @implemented 321c2c66affSColin Finck */ 322c2c66affSColin Finck VOID 323c2c66affSColin Finck NTAPI 324c2c66affSColin Finck ExGetCurrentProcessorCpuUsage(PULONG CpuUsage) 325c2c66affSColin Finck { 326c2c66affSColin Finck PKPRCB Prcb; 327c2c66affSColin Finck ULONG TotalTime; 328c2c66affSColin Finck ULONGLONG ScaledIdle; 329c2c66affSColin Finck 330c2c66affSColin Finck Prcb = KeGetCurrentPrcb(); 331c2c66affSColin Finck 332c2c66affSColin Finck ScaledIdle = (ULONGLONG)Prcb->IdleThread->KernelTime * 100; 333c2c66affSColin Finck TotalTime = Prcb->KernelTime + Prcb->UserTime; 334c2c66affSColin Finck if (TotalTime != 0) 335c2c66affSColin Finck *CpuUsage = (ULONG)(100 - (ScaledIdle / TotalTime)); 336c2c66affSColin Finck else 337c2c66affSColin Finck *CpuUsage = 0; 338c2c66affSColin Finck } 339c2c66affSColin Finck 340c2c66affSColin Finck /* 341c2c66affSColin Finck * @implemented 342c2c66affSColin Finck */ 343c2c66affSColin Finck VOID 344c2c66affSColin Finck NTAPI 345c2c66affSColin Finck ExGetCurrentProcessorCounts(PULONG ThreadKernelTime, 346c2c66affSColin Finck PULONG TotalCpuTime, 347c2c66affSColin Finck PULONG ProcessorNumber) 348c2c66affSColin Finck { 349c2c66affSColin Finck PKPRCB Prcb; 350c2c66affSColin Finck 351c2c66affSColin Finck Prcb = KeGetCurrentPrcb(); 352c2c66affSColin Finck 353c2c66affSColin Finck *ThreadKernelTime = Prcb->KernelTime + Prcb->UserTime; 354c2c66affSColin Finck *TotalCpuTime = Prcb->CurrentThread->KernelTime; 355c2c66affSColin Finck *ProcessorNumber = KeGetCurrentProcessorNumber(); 356c2c66affSColin Finck } 357c2c66affSColin Finck 358c2c66affSColin Finck /* 359c2c66affSColin Finck * @implemented 360c2c66affSColin Finck */ 361c2c66affSColin Finck BOOLEAN 362c2c66affSColin Finck NTAPI 363c2c66affSColin Finck ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature) 364c2c66affSColin Finck { 365c2c66affSColin Finck /* Quick check to see if it exists at all */ 366c2c66affSColin Finck if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return(FALSE); 367c2c66affSColin Finck 368c2c66affSColin Finck /* Return our support for it */ 369c2c66affSColin Finck return(SharedUserData->ProcessorFeatures[ProcessorFeature]); 370c2c66affSColin Finck } 371c2c66affSColin Finck 372c2c66affSColin Finck /* 373c2c66affSColin Finck * @implemented 374c2c66affSColin Finck */ 375c2c66affSColin Finck BOOLEAN 376c2c66affSColin Finck NTAPI 377c2c66affSColin Finck ExVerifySuite(SUITE_TYPE SuiteType) 378c2c66affSColin Finck { 379c2c66affSColin Finck if (SuiteType == Personal) return TRUE; 380c2c66affSColin Finck return FALSE; 381c2c66affSColin Finck } 382c2c66affSColin Finck 383c2c66affSColin Finck NTSTATUS 384c2c66affSColin Finck NTAPI 385c2c66affSColin Finck NtQuerySystemEnvironmentValue(IN PUNICODE_STRING VariableName, 386c2c66affSColin Finck OUT PWSTR ValueBuffer, 387c2c66affSColin Finck IN ULONG ValueBufferLength, 388c2c66affSColin Finck IN OUT PULONG ReturnLength OPTIONAL) 389c2c66affSColin Finck { 390c2c66affSColin Finck ANSI_STRING AName; 391c2c66affSColin Finck UNICODE_STRING WName; 392c2c66affSColin Finck ARC_STATUS Result; 393c2c66affSColin Finck PCH AnsiValueBuffer; 394c2c66affSColin Finck ANSI_STRING AValue; 395c2c66affSColin Finck UNICODE_STRING WValue; 396c2c66affSColin Finck KPROCESSOR_MODE PreviousMode; 397c2c66affSColin Finck NTSTATUS Status; 398c2c66affSColin Finck PAGED_CODE(); 399c2c66affSColin Finck 400c2c66affSColin Finck /* Check if the call came from user mode */ 401c2c66affSColin Finck PreviousMode = ExGetPreviousMode(); 402c2c66affSColin Finck if (PreviousMode != KernelMode) 403c2c66affSColin Finck { 404c2c66affSColin Finck _SEH2_TRY 405c2c66affSColin Finck { 406c2c66affSColin Finck /* Probe the input and output buffers */ 407c2c66affSColin Finck ProbeForRead(VariableName, sizeof(UNICODE_STRING), sizeof(ULONG)); 408c2c66affSColin Finck ProbeForWrite(ValueBuffer, ValueBufferLength, sizeof(WCHAR)); 409c2c66affSColin Finck if (ReturnLength != NULL) ProbeForWriteUlong(ReturnLength); 410c2c66affSColin Finck } 411c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 412c2c66affSColin Finck { 413c2c66affSColin Finck /* Return the exception code */ 414c2c66affSColin Finck _SEH2_YIELD(return _SEH2_GetExceptionCode()); 415c2c66affSColin Finck } 416c2c66affSColin Finck _SEH2_END; 417c2c66affSColin Finck } 418c2c66affSColin Finck 419c2c66affSColin Finck /* According to NTInternals the SeSystemEnvironmentName privilege is required! */ 420c2c66affSColin Finck if (!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege, PreviousMode)) 421c2c66affSColin Finck { 422c2c66affSColin Finck DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n"); 423c2c66affSColin Finck return STATUS_PRIVILEGE_NOT_HELD; 424c2c66affSColin Finck } 425c2c66affSColin Finck 426c2c66affSColin Finck /* Copy the name to kernel space if necessary */ 427c2c66affSColin Finck Status = ProbeAndCaptureUnicodeString(&WName, PreviousMode, VariableName); 428c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status; 429c2c66affSColin Finck 430c2c66affSColin Finck /* Convert the name to ANSI and release the captured UNICODE string */ 431c2c66affSColin Finck Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE); 432c2c66affSColin Finck ReleaseCapturedUnicodeString(&WName, PreviousMode); 433c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status; 434c2c66affSColin Finck 435c2c66affSColin Finck /* Allocate a buffer for the ANSI environment variable */ 436c2c66affSColin Finck AnsiValueBuffer = ExAllocatePoolWithTag(NonPagedPool, MAX_ENVVAL_SIZE, 'rvnE'); 437c2c66affSColin Finck if (AnsiValueBuffer == NULL) 438c2c66affSColin Finck { 439c2c66affSColin Finck RtlFreeAnsiString(&AName); 440c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES; 441c2c66affSColin Finck } 442c2c66affSColin Finck 443c2c66affSColin Finck /* Get the environment variable and free the ANSI name */ 444c2c66affSColin Finck Result = HalGetEnvironmentVariable(AName.Buffer, 445c2c66affSColin Finck MAX_ENVVAL_SIZE, 446c2c66affSColin Finck AnsiValueBuffer); 447c2c66affSColin Finck RtlFreeAnsiString(&AName); 448c2c66affSColin Finck 449c2c66affSColin Finck /* Check if we had success */ 450c2c66affSColin Finck if (Result == ESUCCESS) 451c2c66affSColin Finck { 452c2c66affSColin Finck /* Copy the result back to the caller. */ 453c2c66affSColin Finck _SEH2_TRY 454c2c66affSColin Finck { 455c2c66affSColin Finck /* Initialize ANSI string from the result */ 456c2c66affSColin Finck RtlInitAnsiString(&AValue, AnsiValueBuffer); 457c2c66affSColin Finck 458c2c66affSColin Finck /* Initialize a UNICODE string from the callers buffer */ 459c2c66affSColin Finck RtlInitEmptyUnicodeString(&WValue, ValueBuffer, (USHORT)ValueBufferLength); 460c2c66affSColin Finck 461c2c66affSColin Finck /* Convert the result to UNICODE */ 462c2c66affSColin Finck Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, FALSE); 463c2c66affSColin Finck 464c2c66affSColin Finck if (ReturnLength != NULL) 465c2c66affSColin Finck *ReturnLength = WValue.Length; 466c2c66affSColin Finck } 467c2c66affSColin Finck _SEH2_EXCEPT(ExSystemExceptionFilter()) 468c2c66affSColin Finck { 469c2c66affSColin Finck Status = _SEH2_GetExceptionCode(); 470c2c66affSColin Finck } 471c2c66affSColin Finck _SEH2_END; 472c2c66affSColin Finck } 473c2c66affSColin Finck else 474c2c66affSColin Finck { 475c2c66affSColin Finck Status = STATUS_UNSUCCESSFUL; 476c2c66affSColin Finck } 477c2c66affSColin Finck 478c2c66affSColin Finck /* Free the allocated ANSI value buffer */ 479c2c66affSColin Finck ExFreePoolWithTag(AnsiValueBuffer, 'rvnE'); 480c2c66affSColin Finck 481c2c66affSColin Finck return Status; 482c2c66affSColin Finck } 483c2c66affSColin Finck 484c2c66affSColin Finck 485c2c66affSColin Finck NTSTATUS 486c2c66affSColin Finck NTAPI 487c2c66affSColin Finck NtSetSystemEnvironmentValue(IN PUNICODE_STRING VariableName, 488c2c66affSColin Finck IN PUNICODE_STRING Value) 489c2c66affSColin Finck { 490c2c66affSColin Finck UNICODE_STRING CapturedName, CapturedValue; 491c2c66affSColin Finck ANSI_STRING AName, AValue; 492c2c66affSColin Finck KPROCESSOR_MODE PreviousMode; 493c2c66affSColin Finck NTSTATUS Status; 494c2c66affSColin Finck 495c2c66affSColin Finck PAGED_CODE(); 496c2c66affSColin Finck 497c2c66affSColin Finck PreviousMode = ExGetPreviousMode(); 498c2c66affSColin Finck 499c2c66affSColin Finck /* 500c2c66affSColin Finck * Copy the strings to kernel space if necessary 501c2c66affSColin Finck */ 502c2c66affSColin Finck Status = ProbeAndCaptureUnicodeString(&CapturedName, 503c2c66affSColin Finck PreviousMode, 504c2c66affSColin Finck VariableName); 505c2c66affSColin Finck if (NT_SUCCESS(Status)) 506c2c66affSColin Finck { 507c2c66affSColin Finck Status = ProbeAndCaptureUnicodeString(&CapturedValue, 508c2c66affSColin Finck PreviousMode, 509c2c66affSColin Finck Value); 510c2c66affSColin Finck if (NT_SUCCESS(Status)) 511c2c66affSColin Finck { 512c2c66affSColin Finck /* 513c2c66affSColin Finck * according to ntinternals the SeSystemEnvironmentName privilege is required! 514c2c66affSColin Finck */ 515c2c66affSColin Finck if (SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege, 516c2c66affSColin Finck PreviousMode)) 517c2c66affSColin Finck { 518c2c66affSColin Finck /* 519c2c66affSColin Finck * convert the strings to ANSI 520c2c66affSColin Finck */ 521c2c66affSColin Finck Status = RtlUnicodeStringToAnsiString(&AName, 522c2c66affSColin Finck &CapturedName, 523c2c66affSColin Finck TRUE); 524c2c66affSColin Finck if (NT_SUCCESS(Status)) 525c2c66affSColin Finck { 526c2c66affSColin Finck Status = RtlUnicodeStringToAnsiString(&AValue, 527c2c66affSColin Finck &CapturedValue, 528c2c66affSColin Finck TRUE); 529c2c66affSColin Finck if (NT_SUCCESS(Status)) 530c2c66affSColin Finck { 531c2c66affSColin Finck ARC_STATUS Result = HalSetEnvironmentVariable(AName.Buffer, 532c2c66affSColin Finck AValue.Buffer); 533c2c66affSColin Finck 534c2c66affSColin Finck Status = (Result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); 535c2c66affSColin Finck } 536c2c66affSColin Finck } 537c2c66affSColin Finck } 538c2c66affSColin Finck else 539c2c66affSColin Finck { 540c2c66affSColin Finck DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n"); 541c2c66affSColin Finck Status = STATUS_PRIVILEGE_NOT_HELD; 542c2c66affSColin Finck } 543c2c66affSColin Finck 544c2c66affSColin Finck ReleaseCapturedUnicodeString(&CapturedValue, 545c2c66affSColin Finck PreviousMode); 546c2c66affSColin Finck } 547c2c66affSColin Finck 548c2c66affSColin Finck ReleaseCapturedUnicodeString(&CapturedName, 549c2c66affSColin Finck PreviousMode); 550c2c66affSColin Finck } 551c2c66affSColin Finck 552c2c66affSColin Finck return Status; 553c2c66affSColin Finck } 554c2c66affSColin Finck 555c2c66affSColin Finck NTSTATUS 556c2c66affSColin Finck NTAPI 557c2c66affSColin Finck NtEnumerateSystemEnvironmentValuesEx(IN ULONG InformationClass, 558c2c66affSColin Finck IN PVOID Buffer, 559c2c66affSColin Finck IN ULONG BufferLength) 560c2c66affSColin Finck { 561c2c66affSColin Finck UNIMPLEMENTED; 562c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 563c2c66affSColin Finck } 564c2c66affSColin Finck 565c2c66affSColin Finck NTSTATUS 566c2c66affSColin Finck NTAPI 567c2c66affSColin Finck NtQuerySystemEnvironmentValueEx(IN PUNICODE_STRING VariableName, 568c2c66affSColin Finck IN LPGUID VendorGuid, 569c2c66affSColin Finck IN PVOID Value, 570c2c66affSColin Finck IN OUT PULONG ReturnLength, 571c2c66affSColin Finck IN OUT PULONG Attributes) 572c2c66affSColin Finck { 573c2c66affSColin Finck UNIMPLEMENTED; 574c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 575c2c66affSColin Finck } 576c2c66affSColin Finck 577c2c66affSColin Finck NTSTATUS 578c2c66affSColin Finck NTAPI 579c2c66affSColin Finck NtSetSystemEnvironmentValueEx(IN PUNICODE_STRING VariableName, 580c2c66affSColin Finck IN LPGUID VendorGuid, 581c2c66affSColin Finck IN PVOID Value, 582c2c66affSColin Finck IN OUT PULONG ReturnLength, 583c2c66affSColin Finck IN OUT PULONG Attributes) 584c2c66affSColin Finck { 585c2c66affSColin Finck UNIMPLEMENTED; 586c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 587c2c66affSColin Finck } 588c2c66affSColin Finck 589c2c66affSColin Finck /* --- Query/Set System Information --- */ 590c2c66affSColin Finck 591c2c66affSColin Finck /* 592c2c66affSColin Finck * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols 593c2c66affSColin Finck * so the stack is popped only in one place on x86 platform. 594c2c66affSColin Finck */ 595c2c66affSColin Finck #define QSI_USE(n) QSI##n 596c2c66affSColin Finck #define QSI_DEF(n) \ 597c2c66affSColin Finck static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize) 598c2c66affSColin Finck 599c2c66affSColin Finck #define SSI_USE(n) SSI##n 600c2c66affSColin Finck #define SSI_DEF(n) \ 601c2c66affSColin Finck static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size) 602c2c66affSColin Finck 603c2c66affSColin Finck VOID 604c2c66affSColin Finck NTAPI 605c2c66affSColin Finck ExQueryPoolUsage(OUT PULONG PagedPoolPages, 606c2c66affSColin Finck OUT PULONG NonPagedPoolPages, 607c2c66affSColin Finck OUT PULONG PagedPoolAllocs, 608c2c66affSColin Finck OUT PULONG PagedPoolFrees, 609c2c66affSColin Finck OUT PULONG PagedPoolLookasideHits, 610c2c66affSColin Finck OUT PULONG NonPagedPoolAllocs, 611c2c66affSColin Finck OUT PULONG NonPagedPoolFrees, 612c2c66affSColin Finck OUT PULONG NonPagedPoolLookasideHits); 613c2c66affSColin Finck 614c2c66affSColin Finck /* Class 0 - Basic Information */ 615c2c66affSColin Finck QSI_DEF(SystemBasicInformation) 616c2c66affSColin Finck { 617c2c66affSColin Finck PSYSTEM_BASIC_INFORMATION Sbi 618c2c66affSColin Finck = (PSYSTEM_BASIC_INFORMATION) Buffer; 619c2c66affSColin Finck 620c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_BASIC_INFORMATION); 621c2c66affSColin Finck 622c2c66affSColin Finck /* Check user buffer's size */ 623c2c66affSColin Finck if (Size != sizeof(SYSTEM_BASIC_INFORMATION)) 624c2c66affSColin Finck { 625c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 626c2c66affSColin Finck } 627c2c66affSColin Finck 628c2c66affSColin Finck RtlZeroMemory(Sbi, Size); 629c2c66affSColin Finck Sbi->Reserved = 0; 630c2c66affSColin Finck Sbi->TimerResolution = KeMaximumIncrement; 631c2c66affSColin Finck Sbi->PageSize = PAGE_SIZE; 632c2c66affSColin Finck Sbi->NumberOfPhysicalPages = MmNumberOfPhysicalPages; 633c2c66affSColin Finck Sbi->LowestPhysicalPageNumber = (ULONG)MmLowestPhysicalPage; 634c2c66affSColin Finck Sbi->HighestPhysicalPageNumber = (ULONG)MmHighestPhysicalPage; 635c2c66affSColin Finck Sbi->AllocationGranularity = MM_VIRTMEM_GRANULARITY; /* hard coded on Intel? */ 636c2c66affSColin Finck Sbi->MinimumUserModeAddress = 0x10000; /* Top of 64k */ 637c2c66affSColin Finck Sbi->MaximumUserModeAddress = (ULONG_PTR)MmHighestUserAddress; 638c2c66affSColin Finck Sbi->ActiveProcessorsAffinityMask = KeActiveProcessors; 639c2c66affSColin Finck Sbi->NumberOfProcessors = KeNumberProcessors; 640c2c66affSColin Finck 641c2c66affSColin Finck return STATUS_SUCCESS; 642c2c66affSColin Finck } 643c2c66affSColin Finck 644c2c66affSColin Finck /* Class 1 - Processor Information */ 645c2c66affSColin Finck QSI_DEF(SystemProcessorInformation) 646c2c66affSColin Finck { 647c2c66affSColin Finck PSYSTEM_PROCESSOR_INFORMATION Spi 648c2c66affSColin Finck = (PSYSTEM_PROCESSOR_INFORMATION) Buffer; 649c2c66affSColin Finck 650c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_PROCESSOR_INFORMATION); 651c2c66affSColin Finck 652c2c66affSColin Finck /* Check user buffer's size */ 653c2c66affSColin Finck if (Size < sizeof(SYSTEM_PROCESSOR_INFORMATION)) 654c2c66affSColin Finck { 655c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 656c2c66affSColin Finck } 657c2c66affSColin Finck Spi->ProcessorArchitecture = KeProcessorArchitecture; 658c2c66affSColin Finck Spi->ProcessorLevel = KeProcessorLevel; 659c2c66affSColin Finck Spi->ProcessorRevision = KeProcessorRevision; 660*35f30348SAlex Henrie #if (NTDDI_VERSION < NTDDI_WIN8) 661c2c66affSColin Finck Spi->Reserved = 0; 662*35f30348SAlex Henrie #else 663*35f30348SAlex Henrie Spi->MaximumProcessors = 0; 664*35f30348SAlex Henrie #endif 665c2c66affSColin Finck Spi->ProcessorFeatureBits = KeFeatureBits; 666c2c66affSColin Finck 667c2c66affSColin Finck DPRINT("Arch %u Level %u Rev 0x%x\n", Spi->ProcessorArchitecture, 668c2c66affSColin Finck Spi->ProcessorLevel, Spi->ProcessorRevision); 669c2c66affSColin Finck 670c2c66affSColin Finck return STATUS_SUCCESS; 671c2c66affSColin Finck } 672c2c66affSColin Finck 673c2c66affSColin Finck /* Class 2 - Performance Information */ 674c2c66affSColin Finck QSI_DEF(SystemPerformanceInformation) 675c2c66affSColin Finck { 676e6323758SPierre Schweitzer LONG i; 677c2c66affSColin Finck ULONG IdleUser, IdleKernel; 678e6323758SPierre Schweitzer PKPRCB Prcb; 679c2c66affSColin Finck PSYSTEM_PERFORMANCE_INFORMATION Spi 680c2c66affSColin Finck = (PSYSTEM_PERFORMANCE_INFORMATION) Buffer; 681c2c66affSColin Finck 682c2c66affSColin Finck PEPROCESS TheIdleProcess; 683c2c66affSColin Finck 684c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_PERFORMANCE_INFORMATION); 685c2c66affSColin Finck 686c2c66affSColin Finck /* Check user buffer's size */ 687c2c66affSColin Finck if (Size < sizeof(SYSTEM_PERFORMANCE_INFORMATION)) 688c2c66affSColin Finck { 689c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 690c2c66affSColin Finck } 691c2c66affSColin Finck 692c2c66affSColin Finck TheIdleProcess = PsIdleProcess; 693c2c66affSColin Finck 694c2c66affSColin Finck IdleKernel = KeQueryRuntimeProcess(&TheIdleProcess->Pcb, &IdleUser); 695c2c66affSColin Finck Spi->IdleProcessTime.QuadPart = UInt32x32To64(IdleKernel, KeMaximumIncrement); 696c2c66affSColin Finck Spi->IoReadTransferCount = IoReadTransferCount; 697c2c66affSColin Finck Spi->IoWriteTransferCount = IoWriteTransferCount; 698c2c66affSColin Finck Spi->IoOtherTransferCount = IoOtherTransferCount; 699c2c66affSColin Finck Spi->IoReadOperationCount = IoReadOperationCount; 700c2c66affSColin Finck Spi->IoWriteOperationCount = IoWriteOperationCount; 701c2c66affSColin Finck Spi->IoOtherOperationCount = IoOtherOperationCount; 70213d9d3ebSPierre Schweitzer for (i = 0; i < KeNumberProcessors; i ++) 70313d9d3ebSPierre Schweitzer { 70413d9d3ebSPierre Schweitzer Prcb = KiProcessorBlock[i]; 70513d9d3ebSPierre Schweitzer if (Prcb) 70613d9d3ebSPierre Schweitzer { 70713d9d3ebSPierre Schweitzer Spi->IoReadTransferCount.QuadPart += Prcb->IoReadTransferCount.QuadPart; 70813d9d3ebSPierre Schweitzer Spi->IoWriteTransferCount.QuadPart += Prcb->IoWriteTransferCount.QuadPart; 70913d9d3ebSPierre Schweitzer Spi->IoOtherTransferCount.QuadPart += Prcb->IoOtherTransferCount.QuadPart; 71013d9d3ebSPierre Schweitzer Spi->IoReadOperationCount += Prcb->IoReadOperationCount; 71113d9d3ebSPierre Schweitzer Spi->IoWriteOperationCount += Prcb->IoWriteOperationCount; 71213d9d3ebSPierre Schweitzer Spi->IoOtherOperationCount += Prcb->IoOtherOperationCount; 71313d9d3ebSPierre Schweitzer } 71413d9d3ebSPierre Schweitzer } 715c2c66affSColin Finck 716c2c66affSColin Finck Spi->AvailablePages = (ULONG)MmAvailablePages; 717c2c66affSColin Finck /* 718c2c66affSColin Finck * Add up all the used "Committed" memory + pagefile. 719c2c66affSColin Finck * Not sure this is right. 8^\ 720c2c66affSColin Finck */ 721c2c66affSColin Finck Spi->CommittedPages = MiMemoryConsumers[MC_SYSTEM].PagesUsed + 722c2c66affSColin Finck MiMemoryConsumers[MC_CACHE].PagesUsed + 723c2c66affSColin Finck MiMemoryConsumers[MC_USER].PagesUsed + 724c2c66affSColin Finck MiUsedSwapPages; 725c2c66affSColin Finck /* 726c2c66affSColin Finck * Add up the full system total + pagefile. 727c2c66affSColin Finck * All this make Taskmgr happy but not sure it is the right numbers. 728c2c66affSColin Finck * This too, fixes some of GlobalMemoryStatusEx numbers. 729c2c66affSColin Finck */ 730c2c66affSColin Finck Spi->CommitLimit = MmNumberOfPhysicalPages + MiFreeSwapPages + MiUsedSwapPages; 731c2c66affSColin Finck 732c2c66affSColin Finck Spi->PeakCommitment = 0; /* FIXME */ 733c2c66affSColin Finck Spi->PageFaultCount = 0; /* FIXME */ 734c2c66affSColin Finck Spi->CopyOnWriteCount = 0; /* FIXME */ 735c2c66affSColin Finck Spi->TransitionCount = 0; /* FIXME */ 736c2c66affSColin Finck Spi->CacheTransitionCount = 0; /* FIXME */ 737c2c66affSColin Finck Spi->DemandZeroCount = 0; /* FIXME */ 738c2c66affSColin Finck Spi->PageReadCount = 0; /* FIXME */ 739c2c66affSColin Finck Spi->PageReadIoCount = 0; /* FIXME */ 740c2c66affSColin Finck Spi->CacheReadCount = 0; /* FIXME */ 741c2c66affSColin Finck Spi->CacheIoCount = 0; /* FIXME */ 742c2c66affSColin Finck Spi->DirtyPagesWriteCount = 0; /* FIXME */ 743c2c66affSColin Finck Spi->DirtyWriteIoCount = 0; /* FIXME */ 744c2c66affSColin Finck Spi->MappedPagesWriteCount = 0; /* FIXME */ 745c2c66affSColin Finck Spi->MappedWriteIoCount = 0; /* FIXME */ 746c2c66affSColin Finck 747c2c66affSColin Finck Spi->PagedPoolPages = 0; 748c2c66affSColin Finck Spi->NonPagedPoolPages = 0; 749c2c66affSColin Finck Spi->PagedPoolAllocs = 0; 750c2c66affSColin Finck Spi->PagedPoolFrees = 0; 751c2c66affSColin Finck Spi->PagedPoolLookasideHits = 0; 752c2c66affSColin Finck Spi->NonPagedPoolAllocs = 0; 753c2c66affSColin Finck Spi->NonPagedPoolFrees = 0; 754c2c66affSColin Finck Spi->NonPagedPoolLookasideHits = 0; 755c2c66affSColin Finck ExQueryPoolUsage(&Spi->PagedPoolPages, 756c2c66affSColin Finck &Spi->NonPagedPoolPages, 757c2c66affSColin Finck &Spi->PagedPoolAllocs, 758c2c66affSColin Finck &Spi->PagedPoolFrees, 759c2c66affSColin Finck &Spi->PagedPoolLookasideHits, 760c2c66affSColin Finck &Spi->NonPagedPoolAllocs, 761c2c66affSColin Finck &Spi->NonPagedPoolFrees, 762c2c66affSColin Finck &Spi->NonPagedPoolLookasideHits); 763c2c66affSColin Finck Spi->FreeSystemPtes = 0; /* FIXME */ 764c2c66affSColin Finck 765c2c66affSColin Finck Spi->ResidentSystemCodePage = 0; /* FIXME */ 766c2c66affSColin Finck 767c2c66affSColin Finck Spi->TotalSystemDriverPages = 0; /* FIXME */ 768c2c66affSColin Finck Spi->Spare3Count = 0; /* FIXME */ 769c2c66affSColin Finck 770c2c66affSColin Finck Spi->ResidentSystemCachePage = MiMemoryConsumers[MC_CACHE].PagesUsed; 771c2c66affSColin Finck Spi->ResidentPagedPoolPage = 0; /* FIXME */ 772c2c66affSColin Finck 773c2c66affSColin Finck Spi->ResidentSystemDriverPage = 0; /* FIXME */ 774c2c66affSColin Finck Spi->CcFastReadNoWait = 0; /* FIXME */ 775c2c66affSColin Finck Spi->CcFastReadWait = 0; /* FIXME */ 776c2c66affSColin Finck Spi->CcFastReadResourceMiss = 0; /* FIXME */ 777c2c66affSColin Finck Spi->CcFastReadNotPossible = 0; /* FIXME */ 778c2c66affSColin Finck 779c2c66affSColin Finck Spi->CcFastMdlReadNoWait = 0; /* FIXME */ 780c2c66affSColin Finck Spi->CcFastMdlReadWait = 0; /* FIXME */ 781c2c66affSColin Finck Spi->CcFastMdlReadResourceMiss = 0; /* FIXME */ 782c2c66affSColin Finck Spi->CcFastMdlReadNotPossible = 0; /* FIXME */ 783c2c66affSColin Finck 78445964099SPierre Schweitzer Spi->CcMapDataNoWait = CcMapDataNoWait; 78545964099SPierre Schweitzer Spi->CcMapDataWait = CcMapDataWait; 786c2c66affSColin Finck Spi->CcMapDataNoWaitMiss = 0; /* FIXME */ 787c2c66affSColin Finck Spi->CcMapDataWaitMiss = 0; /* FIXME */ 788c2c66affSColin Finck 7893d13a464SPierre Schweitzer Spi->CcPinMappedDataCount = CcPinMappedDataCount; 7900fbdf317SPierre Schweitzer Spi->CcPinReadNoWait = CcPinReadNoWait; 7910fbdf317SPierre Schweitzer Spi->CcPinReadWait = CcPinReadWait; 792c2c66affSColin Finck Spi->CcPinReadNoWaitMiss = 0; /* FIXME */ 793c2c66affSColin Finck Spi->CcPinReadWaitMiss = 0; /* FIXME */ 794c2c66affSColin Finck Spi->CcCopyReadNoWait = 0; /* FIXME */ 795c2c66affSColin Finck Spi->CcCopyReadWait = 0; /* FIXME */ 796c2c66affSColin Finck Spi->CcCopyReadNoWaitMiss = 0; /* FIXME */ 797c2c66affSColin Finck Spi->CcCopyReadWaitMiss = 0; /* FIXME */ 798c2c66affSColin Finck 799c2c66affSColin Finck Spi->CcMdlReadNoWait = 0; /* FIXME */ 800c2c66affSColin Finck Spi->CcMdlReadWait = 0; /* FIXME */ 801c2c66affSColin Finck Spi->CcMdlReadNoWaitMiss = 0; /* FIXME */ 802c2c66affSColin Finck Spi->CcMdlReadWaitMiss = 0; /* FIXME */ 803c2c66affSColin Finck Spi->CcReadAheadIos = 0; /* FIXME */ 80445964099SPierre Schweitzer Spi->CcLazyWriteIos = CcLazyWriteIos; 80545964099SPierre Schweitzer Spi->CcLazyWritePages = CcLazyWritePages; 8069ac2e985SPierre Schweitzer Spi->CcDataFlushes = CcDataFlushes; 8079ac2e985SPierre Schweitzer Spi->CcDataPages = CcDataPages; 808e6323758SPierre Schweitzer 809e6323758SPierre Schweitzer Spi->ContextSwitches = 0; 810e6323758SPierre Schweitzer Spi->FirstLevelTbFills = 0; 811e6323758SPierre Schweitzer Spi->SecondLevelTbFills = 0; 812e6323758SPierre Schweitzer Spi->SystemCalls = 0; 813e6323758SPierre Schweitzer for (i = 0; i < KeNumberProcessors; i ++) 814e6323758SPierre Schweitzer { 815e6323758SPierre Schweitzer Prcb = KiProcessorBlock[i]; 816e6323758SPierre Schweitzer if (Prcb) 817e6323758SPierre Schweitzer { 818e6323758SPierre Schweitzer Spi->ContextSwitches += KeGetContextSwitches(Prcb); 819e6323758SPierre Schweitzer Spi->FirstLevelTbFills += Prcb->KeFirstLevelTbFills; 820e6323758SPierre Schweitzer Spi->SecondLevelTbFills += Prcb->KeSecondLevelTbFills; 821e6323758SPierre Schweitzer Spi->SystemCalls += Prcb->KeSystemCalls; 822e6323758SPierre Schweitzer } 823e6323758SPierre Schweitzer } 824e6323758SPierre Schweitzer 825c2c66affSColin Finck return STATUS_SUCCESS; 826c2c66affSColin Finck } 827c2c66affSColin Finck 828c2c66affSColin Finck /* Class 3 - Time Of Day Information */ 829c2c66affSColin Finck QSI_DEF(SystemTimeOfDayInformation) 830c2c66affSColin Finck { 831c2c66affSColin Finck SYSTEM_TIMEOFDAY_INFORMATION Sti; 832c2c66affSColin Finck LARGE_INTEGER CurrentTime; 833c2c66affSColin Finck 834c2c66affSColin Finck /* Set amount of written information to 0 */ 835c2c66affSColin Finck *ReqSize = 0; 836c2c66affSColin Finck 837c2c66affSColin Finck /* Check user buffer's size */ 838c2c66affSColin Finck if (Size > sizeof(SYSTEM_TIMEOFDAY_INFORMATION)) 839c2c66affSColin Finck { 840c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 841c2c66affSColin Finck } 842c2c66affSColin Finck 843c2c66affSColin Finck /* Get current time */ 844c2c66affSColin Finck KeQuerySystemTime(&CurrentTime); 845c2c66affSColin Finck 846c2c66affSColin Finck /* Zero local buffer */ 847c2c66affSColin Finck RtlZeroMemory(&Sti, sizeof(SYSTEM_TIMEOFDAY_INFORMATION)); 848c2c66affSColin Finck 849c2c66affSColin Finck /* Fill local time structure */ 850c2c66affSColin Finck Sti.BootTime= KeBootTime; 851c2c66affSColin Finck Sti.CurrentTime = CurrentTime; 852c2c66affSColin Finck Sti.TimeZoneBias.QuadPart = ExpTimeZoneBias.QuadPart; 853c2c66affSColin Finck Sti.TimeZoneId = ExpTimeZoneId; 854c2c66affSColin Finck Sti.Reserved = 0; 855c2c66affSColin Finck 856c2c66affSColin Finck /* Copy as much as requested by caller */ 857c2c66affSColin Finck RtlCopyMemory(Buffer, &Sti, Size); 858c2c66affSColin Finck 859c2c66affSColin Finck /* Set amount of information we copied */ 860c2c66affSColin Finck *ReqSize = Size; 861c2c66affSColin Finck 862c2c66affSColin Finck return STATUS_SUCCESS; 863c2c66affSColin Finck } 864c2c66affSColin Finck 865c2c66affSColin Finck /* Class 4 - Path Information */ 866c2c66affSColin Finck QSI_DEF(SystemPathInformation) 867c2c66affSColin Finck { 868c2c66affSColin Finck /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */ 869c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemPathInformation not implemented\n"); 870c2c66affSColin Finck 871c2c66affSColin Finck return STATUS_BREAKPOINT; 872c2c66affSColin Finck } 873c2c66affSColin Finck 874c2c66affSColin Finck /* Class 5 - Process Information */ 875c2c66affSColin Finck QSI_DEF(SystemProcessInformation) 876c2c66affSColin Finck { 877c2c66affSColin Finck PSYSTEM_PROCESS_INFORMATION SpiCurrent; 878c2c66affSColin Finck PSYSTEM_THREAD_INFORMATION ThreadInfo; 879c2c66affSColin Finck PEPROCESS Process = NULL, SystemProcess; 880c2c66affSColin Finck PETHREAD CurrentThread; 881c2c66affSColin Finck ANSI_STRING ImageName; 882c2c66affSColin Finck ULONG CurrentSize; 883c2c66affSColin Finck USHORT ImageNameMaximumLength; // image name length in bytes 884c2c66affSColin Finck USHORT ImageNameLength; 885c2c66affSColin Finck PLIST_ENTRY CurrentEntry; 886c2c66affSColin Finck ULONG TotalSize = 0, ThreadsCount; 887c2c66affSColin Finck ULONG TotalUser, TotalKernel; 888c2c66affSColin Finck PUCHAR Current; 889c2c66affSColin Finck NTSTATUS Status = STATUS_SUCCESS; 890c2c66affSColin Finck PUNICODE_STRING TempProcessImageName; 891c2c66affSColin Finck _SEH2_VOLATILE PUNICODE_STRING ProcessImageName = NULL; 892c2c66affSColin Finck PWCHAR szSrc; 893c2c66affSColin Finck BOOLEAN Overflow = FALSE; 894c2c66affSColin Finck 895c2c66affSColin Finck _SEH2_TRY 896c2c66affSColin Finck { 897c2c66affSColin Finck /* scan the process list */ 898c2c66affSColin Finck 899c2c66affSColin Finck PSYSTEM_PROCESS_INFORMATION Spi 900c2c66affSColin Finck = (PSYSTEM_PROCESS_INFORMATION) Buffer; 901c2c66affSColin Finck 902c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION); 903c2c66affSColin Finck 904c2c66affSColin Finck /* Check for overflow */ 905c2c66affSColin Finck if (Size < sizeof(SYSTEM_PROCESS_INFORMATION)) 906c2c66affSColin Finck { 907c2c66affSColin Finck Overflow = TRUE; 908c2c66affSColin Finck } 909c2c66affSColin Finck 910c2c66affSColin Finck /* Zero user's buffer */ 911c2c66affSColin Finck if (!Overflow) RtlZeroMemory(Spi, Size); 912c2c66affSColin Finck 913c2c66affSColin Finck SystemProcess = PsIdleProcess; 914c2c66affSColin Finck Process = SystemProcess; 915c2c66affSColin Finck Current = (PUCHAR) Spi; 916c2c66affSColin Finck 917c2c66affSColin Finck do 918c2c66affSColin Finck { 919c2c66affSColin Finck SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current; 920c2c66affSColin Finck 921c2c66affSColin Finck /* Lock the Process */ 922c2c66affSColin Finck KeEnterCriticalRegion(); 923c2c66affSColin Finck ExAcquirePushLockShared(&Process->ProcessLock); 924c2c66affSColin Finck 925c2c66affSColin Finck if ((Process->ProcessExiting) && 926c2c66affSColin Finck (Process->Pcb.Header.SignalState) && 927c2c66affSColin Finck !(Process->ActiveThreads) && 928c2c66affSColin Finck (IsListEmpty(&Process->Pcb.ThreadListHead))) 929c2c66affSColin Finck { 930c2c66affSColin Finck DPRINT1("Process %p (%s:%p) is a zombie\n", 931c2c66affSColin Finck Process, Process->ImageFileName, Process->UniqueProcessId); 932c2c66affSColin Finck CurrentSize = 0; 933c2c66affSColin Finck ImageNameMaximumLength = 0; 934c2c66affSColin Finck 935c2c66affSColin Finck /* Unlock the Process */ 936c2c66affSColin Finck ExReleasePushLockShared(&Process->ProcessLock); 937c2c66affSColin Finck KeLeaveCriticalRegion(); 938c2c66affSColin Finck goto Skip; 939c2c66affSColin Finck } 940c2c66affSColin Finck 941c2c66affSColin Finck ThreadsCount = 0; 942c2c66affSColin Finck CurrentEntry = Process->Pcb.ThreadListHead.Flink; 943c2c66affSColin Finck while (CurrentEntry != &Process->Pcb.ThreadListHead) 944c2c66affSColin Finck { 945c2c66affSColin Finck ThreadsCount++; 946c2c66affSColin Finck CurrentEntry = CurrentEntry->Flink; 947c2c66affSColin Finck } 948c2c66affSColin Finck 949c2c66affSColin Finck // size of the structure for every process 950c2c66affSColin Finck CurrentSize = sizeof(SYSTEM_PROCESS_INFORMATION) + sizeof(SYSTEM_THREAD_INFORMATION) * ThreadsCount; 951c2c66affSColin Finck ImageNameLength = 0; 952c2c66affSColin Finck Status = SeLocateProcessImageName(Process, &TempProcessImageName); 953c2c66affSColin Finck ProcessImageName = TempProcessImageName; 954c2c66affSColin Finck szSrc = NULL; 955c2c66affSColin Finck if (NT_SUCCESS(Status) && (ProcessImageName->Length > 0)) 956c2c66affSColin Finck { 957c2c66affSColin Finck szSrc = (PWCHAR)((PCHAR)ProcessImageName->Buffer + ProcessImageName->Length); 958c2c66affSColin Finck /* Loop the file name*/ 959c2c66affSColin Finck while (szSrc > ProcessImageName->Buffer) 960c2c66affSColin Finck { 961c2c66affSColin Finck /* Make sure this isn't a backslash */ 962c2c66affSColin Finck if (*--szSrc == OBJ_NAME_PATH_SEPARATOR) 963c2c66affSColin Finck { 964c2c66affSColin Finck szSrc++; 965c2c66affSColin Finck break; 966c2c66affSColin Finck } 967c2c66affSColin Finck else 968c2c66affSColin Finck { 969c2c66affSColin Finck ImageNameLength += sizeof(WCHAR); 970c2c66affSColin Finck } 971c2c66affSColin Finck } 972c2c66affSColin Finck } 973c2c66affSColin Finck if (!ImageNameLength && Process != PsIdleProcess) 974c2c66affSColin Finck { 975c2c66affSColin Finck ImageNameLength = (USHORT)strlen(Process->ImageFileName) * sizeof(WCHAR); 976c2c66affSColin Finck } 977c2c66affSColin Finck 978c2c66affSColin Finck /* Round up the image name length as NT does */ 979c2c66affSColin Finck if (ImageNameLength > 0) 980c2c66affSColin Finck ImageNameMaximumLength = ROUND_UP(ImageNameLength + sizeof(WCHAR), 8); 981c2c66affSColin Finck else 982c2c66affSColin Finck ImageNameMaximumLength = 0; 983c2c66affSColin Finck 984c2c66affSColin Finck TotalSize += CurrentSize + ImageNameMaximumLength; 985c2c66affSColin Finck 986c2c66affSColin Finck /* Check for overflow */ 987c2c66affSColin Finck if (TotalSize > Size) 988c2c66affSColin Finck { 989c2c66affSColin Finck Overflow = TRUE; 990c2c66affSColin Finck } 991c2c66affSColin Finck 992c2c66affSColin Finck /* Fill system information */ 993c2c66affSColin Finck if (!Overflow) 994c2c66affSColin Finck { 995c2c66affSColin Finck SpiCurrent->NextEntryOffset = CurrentSize + ImageNameMaximumLength; // relative offset to the beginning of the next structure 996c2c66affSColin Finck SpiCurrent->NumberOfThreads = ThreadsCount; 997c2c66affSColin Finck SpiCurrent->CreateTime = Process->CreateTime; 998c2c66affSColin Finck SpiCurrent->ImageName.Length = ImageNameLength; 999c2c66affSColin Finck SpiCurrent->ImageName.MaximumLength = ImageNameMaximumLength; 1000c2c66affSColin Finck SpiCurrent->ImageName.Buffer = (void*)(Current + CurrentSize); 1001c2c66affSColin Finck 1002c2c66affSColin Finck /* Copy name to the end of the struct */ 1003c2c66affSColin Finck if(Process != PsIdleProcess) 1004c2c66affSColin Finck { 1005c2c66affSColin Finck if (szSrc) 1006c2c66affSColin Finck { 1007c2c66affSColin Finck RtlCopyMemory(SpiCurrent->ImageName.Buffer, szSrc, SpiCurrent->ImageName.Length); 1008c2c66affSColin Finck } 1009c2c66affSColin Finck else 1010c2c66affSColin Finck { 1011c2c66affSColin Finck RtlInitAnsiString(&ImageName, Process->ImageFileName); 1012c2c66affSColin Finck RtlAnsiStringToUnicodeString(&SpiCurrent->ImageName, &ImageName, FALSE); 1013c2c66affSColin Finck } 1014c2c66affSColin Finck } 1015c2c66affSColin Finck else 1016c2c66affSColin Finck { 1017c2c66affSColin Finck RtlInitUnicodeString(&SpiCurrent->ImageName, NULL); 1018c2c66affSColin Finck } 1019c2c66affSColin Finck 1020c2c66affSColin Finck SpiCurrent->BasePriority = Process->Pcb.BasePriority; 1021c2c66affSColin Finck SpiCurrent->UniqueProcessId = Process->UniqueProcessId; 1022c2c66affSColin Finck SpiCurrent->InheritedFromUniqueProcessId = Process->InheritedFromUniqueProcessId; 1023c2c66affSColin Finck SpiCurrent->HandleCount = ObGetProcessHandleCount(Process); 1024c2c66affSColin Finck SpiCurrent->PeakVirtualSize = Process->PeakVirtualSize; 1025c2c66affSColin Finck SpiCurrent->VirtualSize = Process->VirtualSize; 1026c2c66affSColin Finck SpiCurrent->PageFaultCount = Process->Vm.PageFaultCount; 1027c2c66affSColin Finck SpiCurrent->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize; 1028c2c66affSColin Finck SpiCurrent->WorkingSetSize = Process->Vm.WorkingSetSize; 1029c2c66affSColin Finck SpiCurrent->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0]; 1030c2c66affSColin Finck SpiCurrent->QuotaPagedPoolUsage = Process->QuotaUsage[0]; 1031c2c66affSColin Finck SpiCurrent->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1]; 1032c2c66affSColin Finck SpiCurrent->QuotaNonPagedPoolUsage = Process->QuotaUsage[1]; 1033c2c66affSColin Finck SpiCurrent->PagefileUsage = Process->QuotaUsage[2]; 1034c2c66affSColin Finck SpiCurrent->PeakPagefileUsage = Process->QuotaPeak[2]; 1035c2c66affSColin Finck SpiCurrent->PrivatePageCount = Process->CommitCharge; 1036c2c66affSColin Finck ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(SpiCurrent + 1); 1037c2c66affSColin Finck 1038c2c66affSColin Finck CurrentEntry = Process->Pcb.ThreadListHead.Flink; 1039c2c66affSColin Finck while (CurrentEntry != &Process->Pcb.ThreadListHead) 1040c2c66affSColin Finck { 1041c2c66affSColin Finck CurrentThread = CONTAINING_RECORD(CurrentEntry, ETHREAD, Tcb.ThreadListEntry); 1042c2c66affSColin Finck 1043c2c66affSColin Finck ThreadInfo->KernelTime.QuadPart = UInt32x32To64(CurrentThread->Tcb.KernelTime, KeMaximumIncrement); 1044c2c66affSColin Finck ThreadInfo->UserTime.QuadPart = UInt32x32To64(CurrentThread->Tcb.UserTime, KeMaximumIncrement); 1045c2c66affSColin Finck ThreadInfo->CreateTime.QuadPart = CurrentThread->CreateTime.QuadPart; 1046c2c66affSColin Finck ThreadInfo->WaitTime = CurrentThread->Tcb.WaitTime; 1047c2c66affSColin Finck ThreadInfo->StartAddress = (PVOID) CurrentThread->StartAddress; 1048c2c66affSColin Finck ThreadInfo->ClientId = CurrentThread->Cid; 1049c2c66affSColin Finck ThreadInfo->Priority = CurrentThread->Tcb.Priority; 1050c2c66affSColin Finck ThreadInfo->BasePriority = CurrentThread->Tcb.BasePriority; 1051c2c66affSColin Finck ThreadInfo->ContextSwitches = CurrentThread->Tcb.ContextSwitches; 1052c2c66affSColin Finck ThreadInfo->ThreadState = CurrentThread->Tcb.State; 1053c2c66affSColin Finck ThreadInfo->WaitReason = CurrentThread->Tcb.WaitReason; 1054c2c66affSColin Finck 1055c2c66affSColin Finck ThreadInfo++; 1056c2c66affSColin Finck CurrentEntry = CurrentEntry->Flink; 1057c2c66affSColin Finck } 1058c2c66affSColin Finck 1059c2c66affSColin Finck /* Query total user/kernel times of a process */ 1060c2c66affSColin Finck TotalKernel = KeQueryRuntimeProcess(&Process->Pcb, &TotalUser); 1061c2c66affSColin Finck SpiCurrent->UserTime.QuadPart = UInt32x32To64(TotalUser, KeMaximumIncrement); 1062c2c66affSColin Finck SpiCurrent->KernelTime.QuadPart = UInt32x32To64(TotalKernel, KeMaximumIncrement); 1063c2c66affSColin Finck } 1064c2c66affSColin Finck 1065c2c66affSColin Finck if (ProcessImageName) 1066c2c66affSColin Finck { 1067c2c66affSColin Finck /* Release the memory allocated by SeLocateProcessImageName */ 1068c2c66affSColin Finck ExFreePoolWithTag(ProcessImageName, TAG_SEPA); 1069c2c66affSColin Finck ProcessImageName = NULL; 1070c2c66affSColin Finck } 1071c2c66affSColin Finck 1072c2c66affSColin Finck /* Unlock the Process */ 1073c2c66affSColin Finck ExReleasePushLockShared(&Process->ProcessLock); 1074c2c66affSColin Finck KeLeaveCriticalRegion(); 1075c2c66affSColin Finck 1076c2c66affSColin Finck /* Handle idle process entry */ 1077c2c66affSColin Finck Skip: 1078c2c66affSColin Finck if (Process == PsIdleProcess) Process = NULL; 1079c2c66affSColin Finck 1080c2c66affSColin Finck Process = PsGetNextProcess(Process); 1081c2c66affSColin Finck ThreadsCount = 0; 1082c2c66affSColin Finck if ((Process == SystemProcess) || (Process == NULL)) 1083c2c66affSColin Finck { 1084c2c66affSColin Finck if (!Overflow) 1085c2c66affSColin Finck SpiCurrent->NextEntryOffset = 0; 1086c2c66affSColin Finck break; 1087c2c66affSColin Finck } 1088c2c66affSColin Finck else 1089c2c66affSColin Finck Current += CurrentSize + ImageNameMaximumLength; 1090c2c66affSColin Finck } while ((Process != SystemProcess) && (Process != NULL)); 1091c2c66affSColin Finck 1092c2c66affSColin Finck if(Process != NULL) 1093c2c66affSColin Finck ObDereferenceObject(Process); 1094c2c66affSColin Finck Status = STATUS_SUCCESS; 1095c2c66affSColin Finck } 1096c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1097c2c66affSColin Finck { 1098c2c66affSColin Finck if(Process != NULL) 1099c2c66affSColin Finck ObDereferenceObject(Process); 1100c2c66affSColin Finck if (ProcessImageName) 1101c2c66affSColin Finck { 1102c2c66affSColin Finck /* Release the memory allocated by SeLocateProcessImageName */ 1103c2c66affSColin Finck ExFreePoolWithTag(ProcessImageName, TAG_SEPA); 1104c2c66affSColin Finck } 1105c2c66affSColin Finck 1106c2c66affSColin Finck Status = _SEH2_GetExceptionCode(); 1107c2c66affSColin Finck } 1108c2c66affSColin Finck _SEH2_END 1109c2c66affSColin Finck 1110c2c66affSColin Finck if (Overflow) 1111c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH; 1112c2c66affSColin Finck 1113c2c66affSColin Finck *ReqSize = TotalSize; 1114c2c66affSColin Finck return Status; 1115c2c66affSColin Finck } 1116c2c66affSColin Finck 1117c2c66affSColin Finck /* Class 6 - Call Count Information */ 1118c2c66affSColin Finck QSI_DEF(SystemCallCountInformation) 1119c2c66affSColin Finck { 1120c2c66affSColin Finck /* FIXME */ 1121c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemCallCountInformation not implemented\n"); 1122c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1123c2c66affSColin Finck } 1124c2c66affSColin Finck 1125c2c66affSColin Finck /* Class 7 - Device Information */ 1126c2c66affSColin Finck QSI_DEF(SystemDeviceInformation) 1127c2c66affSColin Finck { 1128c2c66affSColin Finck PSYSTEM_DEVICE_INFORMATION Sdi 1129c2c66affSColin Finck = (PSYSTEM_DEVICE_INFORMATION) Buffer; 1130c2c66affSColin Finck PCONFIGURATION_INFORMATION ConfigInfo; 1131c2c66affSColin Finck 1132c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_DEVICE_INFORMATION); 1133c2c66affSColin Finck 1134c2c66affSColin Finck /* Check user buffer's size */ 1135c2c66affSColin Finck if (Size < sizeof(SYSTEM_DEVICE_INFORMATION)) 1136c2c66affSColin Finck { 1137c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1138c2c66affSColin Finck } 1139c2c66affSColin Finck 1140c2c66affSColin Finck ConfigInfo = IoGetConfigurationInformation(); 1141c2c66affSColin Finck 1142c2c66affSColin Finck Sdi->NumberOfDisks = ConfigInfo->DiskCount; 1143c2c66affSColin Finck Sdi->NumberOfFloppies = ConfigInfo->FloppyCount; 1144c2c66affSColin Finck Sdi->NumberOfCdRoms = ConfigInfo->CdRomCount; 1145c2c66affSColin Finck Sdi->NumberOfTapes = ConfigInfo->TapeCount; 1146c2c66affSColin Finck Sdi->NumberOfSerialPorts = ConfigInfo->SerialCount; 1147c2c66affSColin Finck Sdi->NumberOfParallelPorts = ConfigInfo->ParallelCount; 1148c2c66affSColin Finck 1149c2c66affSColin Finck return STATUS_SUCCESS; 1150c2c66affSColin Finck } 1151c2c66affSColin Finck 1152c2c66affSColin Finck /* Class 8 - Processor Performance Information */ 1153c2c66affSColin Finck QSI_DEF(SystemProcessorPerformanceInformation) 1154c2c66affSColin Finck { 1155c2c66affSColin Finck PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi 1156c2c66affSColin Finck = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer; 1157c2c66affSColin Finck 1158c2c66affSColin Finck LONG i; 1159c2c66affSColin Finck ULONG TotalTime; 1160c2c66affSColin Finck PKPRCB Prcb; 1161c2c66affSColin Finck 1162c2c66affSColin Finck *ReqSize = KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); 1163c2c66affSColin Finck 1164c2c66affSColin Finck /* Check user buffer's size */ 1165c2c66affSColin Finck if (Size < *ReqSize) 1166c2c66affSColin Finck { 1167c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1168c2c66affSColin Finck } 1169c2c66affSColin Finck 1170c2c66affSColin Finck for (i = 0; i < KeNumberProcessors; i++) 1171c2c66affSColin Finck { 1172c2c66affSColin Finck /* Get the PRCB on this processor */ 1173c2c66affSColin Finck Prcb = KiProcessorBlock[i]; 1174c2c66affSColin Finck 1175c2c66affSColin Finck /* Calculate total user and kernel times */ 1176c2c66affSColin Finck TotalTime = Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime; 1177c2c66affSColin Finck Spi->IdleTime.QuadPart = UInt32x32To64(TotalTime, KeMaximumIncrement); 1178c2c66affSColin Finck Spi->KernelTime.QuadPart = UInt32x32To64(Prcb->KernelTime, KeMaximumIncrement); 1179c2c66affSColin Finck Spi->UserTime.QuadPart = UInt32x32To64(Prcb->UserTime, KeMaximumIncrement); 1180c2c66affSColin Finck Spi->DpcTime.QuadPart = UInt32x32To64(Prcb->DpcTime, KeMaximumIncrement); 1181c2c66affSColin Finck Spi->InterruptTime.QuadPart = UInt32x32To64(Prcb->InterruptTime, KeMaximumIncrement); 1182c2c66affSColin Finck Spi->InterruptCount = Prcb->InterruptCount; 1183c2c66affSColin Finck Spi++; 1184c2c66affSColin Finck } 1185c2c66affSColin Finck 1186c2c66affSColin Finck return STATUS_SUCCESS; 1187c2c66affSColin Finck } 1188c2c66affSColin Finck 1189c2c66affSColin Finck /* Class 9 - Flags Information */ 1190c2c66affSColin Finck QSI_DEF(SystemFlagsInformation) 1191c2c66affSColin Finck { 1192c2c66affSColin Finck #if (NTDDI_VERSION >= NTDDI_VISTA) 1193c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION); 1194c2c66affSColin Finck #endif 1195c2c66affSColin Finck 1196c2c66affSColin Finck if (sizeof(SYSTEM_FLAGS_INFORMATION) != Size) 1197c2c66affSColin Finck { 1198c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1199c2c66affSColin Finck } 1200c2c66affSColin Finck 1201c2c66affSColin Finck ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag; 1202c2c66affSColin Finck #if (NTDDI_VERSION < NTDDI_VISTA) 1203c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION); 1204c2c66affSColin Finck #endif 1205c2c66affSColin Finck 1206c2c66affSColin Finck return STATUS_SUCCESS; 1207c2c66affSColin Finck } 1208c2c66affSColin Finck 1209c2c66affSColin Finck SSI_DEF(SystemFlagsInformation) 1210c2c66affSColin Finck { 1211c2c66affSColin Finck if (sizeof(SYSTEM_FLAGS_INFORMATION) != Size) 1212c2c66affSColin Finck { 1213c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1214c2c66affSColin Finck } 1215c2c66affSColin Finck 1216c2c66affSColin Finck if (!SeSinglePrivilegeCheck(SeDebugPrivilege, ExGetPreviousMode())) 1217c2c66affSColin Finck { 1218c2c66affSColin Finck return STATUS_ACCESS_DENIED; 1219c2c66affSColin Finck } 1220c2c66affSColin Finck 1221c2c66affSColin Finck NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags; 1222c2c66affSColin Finck return STATUS_SUCCESS; 1223c2c66affSColin Finck } 1224c2c66affSColin Finck 1225c2c66affSColin Finck /* Class 10 - Call Time Information */ 1226c2c66affSColin Finck QSI_DEF(SystemCallTimeInformation) 1227c2c66affSColin Finck { 1228c2c66affSColin Finck /* FIXME */ 1229c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemCallTimeInformation not implemented\n"); 1230c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1231c2c66affSColin Finck } 1232c2c66affSColin Finck 1233c2c66affSColin Finck /* Class 11 - Module Information */ 1234c2c66affSColin Finck QSI_DEF(SystemModuleInformation) 1235c2c66affSColin Finck { 1236c2c66affSColin Finck NTSTATUS Status; 1237c2c66affSColin Finck 1238c2c66affSColin Finck /* Acquire system module list lock */ 1239c2c66affSColin Finck KeEnterCriticalRegion(); 1240c2c66affSColin Finck ExAcquireResourceExclusiveLite(&PsLoadedModuleResource, TRUE); 1241c2c66affSColin Finck 1242c2c66affSColin Finck /* Call the generic handler with the system module list */ 1243c2c66affSColin Finck Status = ExpQueryModuleInformation(&PsLoadedModuleList, 1244c2c66affSColin Finck &MmLoadedUserImageList, 1245c2c66affSColin Finck (PRTL_PROCESS_MODULES)Buffer, 1246c2c66affSColin Finck Size, 1247c2c66affSColin Finck ReqSize); 1248c2c66affSColin Finck 1249c2c66affSColin Finck /* Release list lock and return status */ 1250c2c66affSColin Finck ExReleaseResourceLite(&PsLoadedModuleResource); 1251c2c66affSColin Finck KeLeaveCriticalRegion(); 1252c2c66affSColin Finck return Status; 1253c2c66affSColin Finck } 1254c2c66affSColin Finck 1255c2c66affSColin Finck /* Class 12 - Locks Information */ 1256c2c66affSColin Finck QSI_DEF(SystemLocksInformation) 1257c2c66affSColin Finck { 1258c2c66affSColin Finck /* FIXME */ 1259c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemLocksInformation not implemented\n"); 1260c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1261c2c66affSColin Finck } 1262c2c66affSColin Finck 1263c2c66affSColin Finck /* Class 13 - Stack Trace Information */ 1264c2c66affSColin Finck QSI_DEF(SystemStackTraceInformation) 1265c2c66affSColin Finck { 1266c2c66affSColin Finck /* FIXME */ 1267c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemStackTraceInformation not implemented\n"); 1268c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1269c2c66affSColin Finck } 1270c2c66affSColin Finck 1271c2c66affSColin Finck /* Class 14 - Paged Pool Information */ 1272c2c66affSColin Finck QSI_DEF(SystemPagedPoolInformation) 1273c2c66affSColin Finck { 1274c2c66affSColin Finck /* FIXME */ 1275c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemPagedPoolInformation not implemented\n"); 1276c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1277c2c66affSColin Finck } 1278c2c66affSColin Finck 1279c2c66affSColin Finck /* Class 15 - Non Paged Pool Information */ 1280c2c66affSColin Finck QSI_DEF(SystemNonPagedPoolInformation) 1281c2c66affSColin Finck { 1282c2c66affSColin Finck /* FIXME */ 1283c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemNonPagedPoolInformation not implemented\n"); 1284c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1285c2c66affSColin Finck } 1286c2c66affSColin Finck 1287c2c66affSColin Finck 1288c2c66affSColin Finck /* Class 16 - Handle Information */ 1289c2c66affSColin Finck QSI_DEF(SystemHandleInformation) 1290c2c66affSColin Finck { 1291c2c66affSColin Finck PSYSTEM_HANDLE_INFORMATION HandleInformation; 1292c2c66affSColin Finck PLIST_ENTRY NextTableEntry; 1293c2c66affSColin Finck PHANDLE_TABLE HandleTable; 1294c2c66affSColin Finck PHANDLE_TABLE_ENTRY HandleTableEntry; 1295c2c66affSColin Finck EXHANDLE Handle; 1296c2c66affSColin Finck ULONG Index = 0; 1297c2c66affSColin Finck NTSTATUS Status; 1298c2c66affSColin Finck PMDL Mdl; 1299c2c66affSColin Finck PAGED_CODE(); 1300c2c66affSColin Finck 1301c2c66affSColin Finck DPRINT("NtQuerySystemInformation - SystemHandleInformation\n"); 1302c2c66affSColin Finck 1303c2c66affSColin Finck /* Set initial required buffer size */ 1304c2c66affSColin Finck *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handles); 1305c2c66affSColin Finck 1306c2c66affSColin Finck /* Check user's buffer size */ 1307c2c66affSColin Finck if (Size < *ReqSize) 1308c2c66affSColin Finck { 1309c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1310c2c66affSColin Finck } 1311c2c66affSColin Finck 1312c2c66affSColin Finck /* We need to lock down the memory */ 1313c2c66affSColin Finck Status = ExLockUserBuffer(Buffer, 1314c2c66affSColin Finck Size, 1315c2c66affSColin Finck ExGetPreviousMode(), 1316c2c66affSColin Finck IoWriteAccess, 1317c2c66affSColin Finck (PVOID*)&HandleInformation, 1318c2c66affSColin Finck &Mdl); 1319c2c66affSColin Finck if (!NT_SUCCESS(Status)) 1320c2c66affSColin Finck { 1321c2c66affSColin Finck DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status); 1322c2c66affSColin Finck return Status; 1323c2c66affSColin Finck } 1324c2c66affSColin Finck 1325c2c66affSColin Finck /* Reset of count of handles */ 1326c2c66affSColin Finck HandleInformation->NumberOfHandles = 0; 1327c2c66affSColin Finck 1328c2c66affSColin Finck /* Enter a critical region */ 1329c2c66affSColin Finck KeEnterCriticalRegion(); 1330c2c66affSColin Finck 1331c2c66affSColin Finck /* Acquire the handle table lock */ 1332c2c66affSColin Finck ExAcquirePushLockShared(&HandleTableListLock); 1333c2c66affSColin Finck 1334c2c66affSColin Finck /* Enumerate all system handles */ 1335c2c66affSColin Finck for (NextTableEntry = HandleTableListHead.Flink; 1336c2c66affSColin Finck NextTableEntry != &HandleTableListHead; 1337c2c66affSColin Finck NextTableEntry = NextTableEntry->Flink) 1338c2c66affSColin Finck { 1339c2c66affSColin Finck /* Get current handle table */ 1340c2c66affSColin Finck HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList); 1341c2c66affSColin Finck 1342c2c66affSColin Finck /* Set the initial value and loop the entries */ 1343c2c66affSColin Finck Handle.Value = 0; 1344c2c66affSColin Finck while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle))) 1345c2c66affSColin Finck { 1346c2c66affSColin Finck /* Validate the entry */ 1347c2c66affSColin Finck if ((HandleTableEntry->Object) && 1348c2c66affSColin Finck (HandleTableEntry->NextFreeTableEntry != -2)) 1349c2c66affSColin Finck { 1350c2c66affSColin Finck /* Increase of count of handles */ 1351c2c66affSColin Finck ++HandleInformation->NumberOfHandles; 1352c2c66affSColin Finck 1353c2c66affSColin Finck /* Lock the entry */ 1354c2c66affSColin Finck if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) 1355c2c66affSColin Finck { 1356c2c66affSColin Finck /* Increase required buffer size */ 1357c2c66affSColin Finck *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO); 1358c2c66affSColin Finck 1359c2c66affSColin Finck /* Check user's buffer size */ 1360c2c66affSColin Finck if (*ReqSize > Size) 1361c2c66affSColin Finck { 1362c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH; 1363c2c66affSColin Finck } 1364c2c66affSColin Finck else 1365c2c66affSColin Finck { 1366c2c66affSColin Finck POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry); 1367c2c66affSColin Finck 1368c2c66affSColin Finck /* Filling handle information */ 1369c2c66affSColin Finck HandleInformation->Handles[Index].UniqueProcessId = 1370c2c66affSColin Finck (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId; 1371c2c66affSColin Finck 1372c2c66affSColin Finck HandleInformation->Handles[Index].CreatorBackTraceIndex = 0; 1373c2c66affSColin Finck 1374c2c66affSColin Finck #if 0 /* FIXME!!! Type field currupted */ 1375c2c66affSColin Finck HandleInformation->Handles[Index].ObjectTypeIndex = 1376c2c66affSColin Finck (UCHAR) ObjectHeader->Type->Index; 1377c2c66affSColin Finck #else 1378c2c66affSColin Finck HandleInformation->Handles[Index].ObjectTypeIndex = 0; 1379c2c66affSColin Finck #endif 1380c2c66affSColin Finck 1381c2c66affSColin Finck HandleInformation->Handles[Index].HandleAttributes = 1382c2c66affSColin Finck HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES; 1383c2c66affSColin Finck 1384c2c66affSColin Finck HandleInformation->Handles[Index].HandleValue = 1385c2c66affSColin Finck (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay; 1386c2c66affSColin Finck 1387c2c66affSColin Finck HandleInformation->Handles[Index].Object = &ObjectHeader->Body; 1388c2c66affSColin Finck 1389c2c66affSColin Finck HandleInformation->Handles[Index].GrantedAccess = 1390c2c66affSColin Finck HandleTableEntry->GrantedAccess; 1391c2c66affSColin Finck 1392c2c66affSColin Finck ++Index; 1393c2c66affSColin Finck } 1394c2c66affSColin Finck 1395c2c66affSColin Finck /* Unlock it */ 1396c2c66affSColin Finck ExUnlockHandleTableEntry(HandleTable, HandleTableEntry); 1397c2c66affSColin Finck } 1398c2c66affSColin Finck } 1399c2c66affSColin Finck 1400c2c66affSColin Finck /* Go to the next entry */ 1401c2c66affSColin Finck Handle.Value += sizeof(HANDLE); 1402c2c66affSColin Finck } 1403c2c66affSColin Finck } 1404c2c66affSColin Finck 1405c2c66affSColin Finck /* Release the lock */ 1406c2c66affSColin Finck ExReleasePushLockShared(&HandleTableListLock); 1407c2c66affSColin Finck 1408c2c66affSColin Finck /* Leave the critical region */ 1409c2c66affSColin Finck KeLeaveCriticalRegion(); 1410c2c66affSColin Finck 1411c2c66affSColin Finck /* Release the locked user buffer */ 1412c2c66affSColin Finck ExUnlockUserBuffer(Mdl); 1413c2c66affSColin Finck 1414c2c66affSColin Finck return Status; 1415c2c66affSColin Finck } 1416c2c66affSColin Finck 1417c2c66affSColin Finck /* Class 17 - Information */ 1418c2c66affSColin Finck QSI_DEF(SystemObjectInformation) 1419c2c66affSColin Finck { 1420c2c66affSColin Finck /* FIXME */ 1421c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemObjectInformation not implemented\n"); 1422c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1423c2c66affSColin Finck } 1424c2c66affSColin Finck 1425c2c66affSColin Finck /* Class 18 - Information */ 1426c2c66affSColin Finck QSI_DEF(SystemPageFileInformation) 1427c2c66affSColin Finck { 1428c2c66affSColin Finck UNICODE_STRING FileName; /* FIXME */ 1429c2c66affSColin Finck SYSTEM_PAGEFILE_INFORMATION *Spfi = (SYSTEM_PAGEFILE_INFORMATION *) Buffer; 1430c2c66affSColin Finck 1431c2c66affSColin Finck if (Size < sizeof(SYSTEM_PAGEFILE_INFORMATION)) 1432c2c66affSColin Finck { 1433c2c66affSColin Finck * ReqSize = sizeof(SYSTEM_PAGEFILE_INFORMATION); 1434c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1435c2c66affSColin Finck } 1436c2c66affSColin Finck 1437c2c66affSColin Finck RtlInitUnicodeString(&FileName, NULL); /* FIXME */ 1438c2c66affSColin Finck 1439c2c66affSColin Finck /* FIXME */ 1440c2c66affSColin Finck Spfi->NextEntryOffset = 0; 1441c2c66affSColin Finck 1442c2c66affSColin Finck Spfi->TotalSize = MiFreeSwapPages + MiUsedSwapPages; 1443c2c66affSColin Finck Spfi->TotalInUse = MiUsedSwapPages; 1444c2c66affSColin Finck Spfi->PeakUsage = MiUsedSwapPages; /* FIXME */ 1445c2c66affSColin Finck Spfi->PageFileName = FileName; 1446c2c66affSColin Finck return STATUS_SUCCESS; 1447c2c66affSColin Finck } 1448c2c66affSColin Finck 1449c2c66affSColin Finck /* Class 19 - Vdm Instemul Information */ 1450c2c66affSColin Finck QSI_DEF(SystemVdmInstemulInformation) 1451c2c66affSColin Finck { 1452c2c66affSColin Finck /* FIXME */ 1453c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemVdmInstemulInformation not implemented\n"); 1454c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1455c2c66affSColin Finck } 1456c2c66affSColin Finck 1457c2c66affSColin Finck /* Class 20 - Vdm Bop Information */ 1458c2c66affSColin Finck QSI_DEF(SystemVdmBopInformation) 1459c2c66affSColin Finck { 1460c2c66affSColin Finck /* FIXME */ 1461c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemVdmBopInformation not implemented\n"); 1462c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1463c2c66affSColin Finck } 1464c2c66affSColin Finck 1465c2c66affSColin Finck /* Class 21 - File Cache Information */ 1466c2c66affSColin Finck QSI_DEF(SystemFileCacheInformation) 1467c2c66affSColin Finck { 1468c2c66affSColin Finck SYSTEM_FILECACHE_INFORMATION *Sci = (SYSTEM_FILECACHE_INFORMATION *) Buffer; 1469c2c66affSColin Finck 1470c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_FILECACHE_INFORMATION); 1471c2c66affSColin Finck 1472c2c66affSColin Finck if (Size < *ReqSize) 1473c2c66affSColin Finck { 1474c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1475c2c66affSColin Finck } 1476c2c66affSColin Finck 1477c2c66affSColin Finck RtlZeroMemory(Sci, sizeof(SYSTEM_FILECACHE_INFORMATION)); 1478c2c66affSColin Finck 1479c2c66affSColin Finck /* Return the Byte size not the page size. */ 1480c2c66affSColin Finck Sci->CurrentSize = 1481c2c66affSColin Finck MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE; 1482c2c66affSColin Finck Sci->PeakSize = 1483c2c66affSColin Finck MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE; /* FIXME */ 1484c2c66affSColin Finck /* Taskmgr multiplies this one by page size right away */ 1485c2c66affSColin Finck Sci->CurrentSizeIncludingTransitionInPages = 1486c2c66affSColin Finck MiMemoryConsumers[MC_CACHE].PagesUsed; /* FIXME: Should be */ 1487c2c66affSColin Finck /* system working set and standby pages. */ 1488c2c66affSColin Finck Sci->PageFaultCount = 0; /* FIXME */ 1489c2c66affSColin Finck Sci->MinimumWorkingSet = 0; /* FIXME */ 1490c2c66affSColin Finck Sci->MaximumWorkingSet = 0; /* FIXME */ 1491c2c66affSColin Finck 1492c2c66affSColin Finck return STATUS_SUCCESS; 1493c2c66affSColin Finck } 1494c2c66affSColin Finck 1495c2c66affSColin Finck SSI_DEF(SystemFileCacheInformation) 1496c2c66affSColin Finck { 1497c2c66affSColin Finck if (Size < sizeof(SYSTEM_FILECACHE_INFORMATION)) 1498c2c66affSColin Finck { 1499c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1500c2c66affSColin Finck } 1501c2c66affSColin Finck /* FIXME */ 1502c2c66affSColin Finck DPRINT1("NtSetSystemInformation - SystemFileCacheInformation not implemented\n"); 1503c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1504c2c66affSColin Finck } 1505c2c66affSColin Finck 1506c2c66affSColin Finck /* Class 22 - Pool Tag Information */ 1507c2c66affSColin Finck QSI_DEF(SystemPoolTagInformation) 1508c2c66affSColin Finck { 1509c2c66affSColin Finck if (Size < sizeof(SYSTEM_POOLTAG_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH; 1510c2c66affSColin Finck return ExGetPoolTagInfo(Buffer, Size, ReqSize); 1511c2c66affSColin Finck } 1512c2c66affSColin Finck 1513c2c66affSColin Finck /* Class 23 - Interrupt Information for all processors */ 1514c2c66affSColin Finck QSI_DEF(SystemInterruptInformation) 1515c2c66affSColin Finck { 1516c2c66affSColin Finck PKPRCB Prcb; 1517c2c66affSColin Finck LONG i; 1518c2c66affSColin Finck ULONG ti; 1519c2c66affSColin Finck PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer; 1520c2c66affSColin Finck 1521c2c66affSColin Finck if(Size < KeNumberProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION)) 1522c2c66affSColin Finck { 1523c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1524c2c66affSColin Finck } 1525c2c66affSColin Finck 1526c2c66affSColin Finck ti = KeQueryTimeIncrement(); 1527c2c66affSColin Finck 1528c2c66affSColin Finck for (i = 0; i < KeNumberProcessors; i++) 1529c2c66affSColin Finck { 1530c2c66affSColin Finck Prcb = KiProcessorBlock[i]; 1531c2c66affSColin Finck sii->ContextSwitches = KeGetContextSwitches(Prcb); 1532c2c66affSColin Finck sii->DpcCount = Prcb->DpcData[0].DpcCount; 1533c2c66affSColin Finck sii->DpcRate = Prcb->DpcRequestRate; 1534c2c66affSColin Finck sii->TimeIncrement = ti; 1535c2c66affSColin Finck sii->DpcBypassCount = 0; 1536c2c66affSColin Finck sii->ApcBypassCount = 0; 1537c2c66affSColin Finck sii++; 1538c2c66affSColin Finck } 1539c2c66affSColin Finck 1540c2c66affSColin Finck return STATUS_SUCCESS; 1541c2c66affSColin Finck } 1542c2c66affSColin Finck 1543c2c66affSColin Finck /* Class 24 - DPC Behaviour Information */ 1544c2c66affSColin Finck QSI_DEF(SystemDpcBehaviourInformation) 1545c2c66affSColin Finck { 1546962b2fd6SPierre Schweitzer PSYSTEM_DPC_BEHAVIOR_INFORMATION sdbi = (PSYSTEM_DPC_BEHAVIOR_INFORMATION)Buffer; 1547962b2fd6SPierre Schweitzer 1548962b2fd6SPierre Schweitzer if (Size < sizeof(SYSTEM_DPC_BEHAVIOR_INFORMATION)) 1549962b2fd6SPierre Schweitzer { 1550962b2fd6SPierre Schweitzer return STATUS_INFO_LENGTH_MISMATCH; 1551962b2fd6SPierre Schweitzer } 1552962b2fd6SPierre Schweitzer 1553962b2fd6SPierre Schweitzer sdbi->DpcQueueDepth = KiMaximumDpcQueueDepth; 1554962b2fd6SPierre Schweitzer sdbi->MinimumDpcRate = KiMinimumDpcRate; 1555962b2fd6SPierre Schweitzer sdbi->AdjustDpcThreshold = KiAdjustDpcThreshold; 1556962b2fd6SPierre Schweitzer sdbi->IdealDpcRate = KiIdealDpcRate; 1557962b2fd6SPierre Schweitzer 1558962b2fd6SPierre Schweitzer return STATUS_SUCCESS; 1559c2c66affSColin Finck } 1560c2c66affSColin Finck 1561c2c66affSColin Finck SSI_DEF(SystemDpcBehaviourInformation) 1562c2c66affSColin Finck { 1563c2c66affSColin Finck /* FIXME */ 1564c2c66affSColin Finck DPRINT1("NtSetSystemInformation - SystemDpcBehaviourInformation not implemented\n"); 1565c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1566c2c66affSColin Finck } 1567c2c66affSColin Finck 1568c2c66affSColin Finck /* Class 25 - Full Memory Information */ 1569c2c66affSColin Finck QSI_DEF(SystemFullMemoryInformation) 1570c2c66affSColin Finck { 1571c2c66affSColin Finck PULONG Spi = (PULONG) Buffer; 1572c2c66affSColin Finck 1573c2c66affSColin Finck PEPROCESS TheIdleProcess; 1574c2c66affSColin Finck 1575c2c66affSColin Finck *ReqSize = sizeof(ULONG); 1576c2c66affSColin Finck 1577c2c66affSColin Finck if (sizeof(ULONG) != Size) 1578c2c66affSColin Finck { 1579c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1580c2c66affSColin Finck } 1581c2c66affSColin Finck 1582c2c66affSColin Finck DPRINT("SystemFullMemoryInformation\n"); 1583c2c66affSColin Finck 1584c2c66affSColin Finck TheIdleProcess = PsIdleProcess; 1585c2c66affSColin Finck 1586c2c66affSColin Finck DPRINT("PID: %p, KernelTime: %u PFFree: %lu PFUsed: %lu\n", 1587c2c66affSColin Finck TheIdleProcess->UniqueProcessId, 1588c2c66affSColin Finck TheIdleProcess->Pcb.KernelTime, 1589c2c66affSColin Finck MiFreeSwapPages, 1590c2c66affSColin Finck MiUsedSwapPages); 1591c2c66affSColin Finck 1592c2c66affSColin Finck *Spi = MiMemoryConsumers[MC_USER].PagesUsed; 1593c2c66affSColin Finck 1594c2c66affSColin Finck return STATUS_SUCCESS; 1595c2c66affSColin Finck } 1596c2c66affSColin Finck 1597c2c66affSColin Finck /* Class 26 - Load Image */ 1598c2c66affSColin Finck SSI_DEF(SystemLoadGdiDriverInformation) 1599c2c66affSColin Finck { 1600c2c66affSColin Finck PSYSTEM_GDI_DRIVER_INFORMATION DriverInfo = (PVOID)Buffer; 1601c2c66affSColin Finck UNICODE_STRING ImageName; 1602c2c66affSColin Finck PVOID ImageBase; 1603c2c66affSColin Finck PVOID SectionPointer; 1604c2c66affSColin Finck ULONG_PTR EntryPoint; 1605c2c66affSColin Finck NTSTATUS Status; 1606c2c66affSColin Finck ULONG DirSize; 1607c2c66affSColin Finck PIMAGE_NT_HEADERS NtHeader; 1608c2c66affSColin Finck 1609c2c66affSColin Finck /* Validate size */ 1610c2c66affSColin Finck if (Size != sizeof(SYSTEM_GDI_DRIVER_INFORMATION)) 1611c2c66affSColin Finck { 1612c2c66affSColin Finck /* Incorrect buffer length, fail */ 1613c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1614c2c66affSColin Finck } 1615c2c66affSColin Finck 1616c2c66affSColin Finck /* Only kernel mode can call this function */ 1617c2c66affSColin Finck if (ExGetPreviousMode() != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; 1618c2c66affSColin Finck 1619c2c66affSColin Finck /* Load the driver */ 1620c2c66affSColin Finck ImageName = DriverInfo->DriverName; 1621c2c66affSColin Finck Status = MmLoadSystemImage(&ImageName, 1622c2c66affSColin Finck NULL, 1623c2c66affSColin Finck NULL, 1624c2c66affSColin Finck 0, 1625c2c66affSColin Finck &SectionPointer, 1626c2c66affSColin Finck &ImageBase); 1627c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status; 1628c2c66affSColin Finck 1629c2c66affSColin Finck /* Return the export pointer */ 1630c2c66affSColin Finck DriverInfo->ExportSectionPointer = 1631c2c66affSColin Finck RtlImageDirectoryEntryToData(ImageBase, 1632c2c66affSColin Finck TRUE, 1633c2c66affSColin Finck IMAGE_DIRECTORY_ENTRY_EXPORT, 1634c2c66affSColin Finck &DirSize); 1635c2c66affSColin Finck 1636c2c66affSColin Finck /* Get the entrypoint */ 1637c2c66affSColin Finck NtHeader = RtlImageNtHeader(ImageBase); 1638c2c66affSColin Finck EntryPoint = NtHeader->OptionalHeader.AddressOfEntryPoint; 1639c2c66affSColin Finck EntryPoint += (ULONG_PTR)ImageBase; 1640c2c66affSColin Finck 1641c2c66affSColin Finck /* Save other data */ 1642c2c66affSColin Finck DriverInfo->ImageAddress = ImageBase; 1643c2c66affSColin Finck DriverInfo->SectionPointer = SectionPointer; 1644c2c66affSColin Finck DriverInfo->EntryPoint = (PVOID)EntryPoint; 1645c2c66affSColin Finck DriverInfo->ImageLength = NtHeader->OptionalHeader.SizeOfImage; 1646c2c66affSColin Finck 1647c2c66affSColin Finck /* All is good */ 1648c2c66affSColin Finck return STATUS_SUCCESS; 1649c2c66affSColin Finck } 1650c2c66affSColin Finck 1651c2c66affSColin Finck /* Class 27 - Unload Image */ 1652c2c66affSColin Finck SSI_DEF(SystemUnloadGdiDriverInformation) 1653c2c66affSColin Finck { 1654c2c66affSColin Finck PVOID *SectionPointer = Buffer; 1655c2c66affSColin Finck 1656c2c66affSColin Finck /* Validate size */ 1657c2c66affSColin Finck if (Size != sizeof(PVOID)) 1658c2c66affSColin Finck { 1659c2c66affSColin Finck /* Incorrect length, fail */ 1660c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1661c2c66affSColin Finck } 1662c2c66affSColin Finck 1663c2c66affSColin Finck /* Only kernel mode can call this function */ 1664c2c66affSColin Finck if (ExGetPreviousMode() != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; 1665c2c66affSColin Finck 1666c2c66affSColin Finck /* Unload the image */ 1667c2c66affSColin Finck MmUnloadSystemImage(*SectionPointer); 1668c2c66affSColin Finck return STATUS_SUCCESS; 1669c2c66affSColin Finck } 1670c2c66affSColin Finck 1671c2c66affSColin Finck /* Class 28 - Time Adjustment Information */ 1672c2c66affSColin Finck QSI_DEF(SystemTimeAdjustmentInformation) 1673c2c66affSColin Finck { 1674c2c66affSColin Finck PSYSTEM_QUERY_TIME_ADJUST_INFORMATION TimeInfo = 1675c2c66affSColin Finck (PSYSTEM_QUERY_TIME_ADJUST_INFORMATION)Buffer; 1676c2c66affSColin Finck 1677c2c66affSColin Finck /* Check if enough storage was provided */ 1678c2c66affSColin Finck if (sizeof(SYSTEM_QUERY_TIME_ADJUST_INFORMATION) > Size) 1679c2c66affSColin Finck { 1680c2c66affSColin Finck * ReqSize = sizeof(SYSTEM_QUERY_TIME_ADJUST_INFORMATION); 1681c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1682c2c66affSColin Finck } 1683c2c66affSColin Finck 1684c2c66affSColin Finck /* Give time values to our caller */ 1685c2c66affSColin Finck TimeInfo->TimeIncrement = KeMaximumIncrement; 1686c2c66affSColin Finck TimeInfo->TimeAdjustment = KeTimeAdjustment; 1687c2c66affSColin Finck TimeInfo->Enable = !KiTimeAdjustmentEnabled; 1688c2c66affSColin Finck 1689c2c66affSColin Finck return STATUS_SUCCESS; 1690c2c66affSColin Finck } 1691c2c66affSColin Finck 1692c2c66affSColin Finck SSI_DEF(SystemTimeAdjustmentInformation) 1693c2c66affSColin Finck { 1694c2c66affSColin Finck KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); 1695c2c66affSColin Finck PSYSTEM_SET_TIME_ADJUST_INFORMATION TimeInfo = 1696c2c66affSColin Finck (PSYSTEM_SET_TIME_ADJUST_INFORMATION)Buffer; 1697c2c66affSColin Finck 1698c2c66affSColin Finck /* Check size of a buffer, it must match our expectations */ 1699c2c66affSColin Finck if (sizeof(SYSTEM_SET_TIME_ADJUST_INFORMATION) != Size) 1700c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1701c2c66affSColin Finck 1702c2c66affSColin Finck /* Check who is calling */ 1703c2c66affSColin Finck if (PreviousMode != KernelMode) 1704c2c66affSColin Finck { 1705c2c66affSColin Finck /* Check access rights */ 1706c2c66affSColin Finck if (!SeSinglePrivilegeCheck(SeSystemtimePrivilege, PreviousMode)) 1707c2c66affSColin Finck { 1708c2c66affSColin Finck return STATUS_PRIVILEGE_NOT_HELD; 1709c2c66affSColin Finck } 1710c2c66affSColin Finck } 1711c2c66affSColin Finck 1712c2c66affSColin Finck /* FIXME: behaviour suggests the member be named 'Disable' */ 1713c2c66affSColin Finck if (TimeInfo->Enable) 1714c2c66affSColin Finck { 1715c2c66affSColin Finck /* Disable time adjustment and set default value */ 1716c2c66affSColin Finck KiTimeAdjustmentEnabled = FALSE; 1717c2c66affSColin Finck KeTimeAdjustment = KeMaximumIncrement; 1718c2c66affSColin Finck } 1719c2c66affSColin Finck else 1720c2c66affSColin Finck { 1721c2c66affSColin Finck /* Check if a valid time adjustment value is given */ 1722c2c66affSColin Finck if (TimeInfo->TimeAdjustment == 0) return STATUS_INVALID_PARAMETER_2; 1723c2c66affSColin Finck 1724c2c66affSColin Finck /* Enable time adjustment and set the adjustment value */ 1725c2c66affSColin Finck KiTimeAdjustmentEnabled = TRUE; 1726c2c66affSColin Finck KeTimeAdjustment = TimeInfo->TimeAdjustment; 1727c2c66affSColin Finck } 1728c2c66affSColin Finck 1729c2c66affSColin Finck return STATUS_SUCCESS; 1730c2c66affSColin Finck } 1731c2c66affSColin Finck 1732c2c66affSColin Finck /* Class 29 - Summary Memory Information */ 1733c2c66affSColin Finck QSI_DEF(SystemSummaryMemoryInformation) 1734c2c66affSColin Finck { 1735c2c66affSColin Finck /* FIXME */ 1736c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemSummaryMemoryInformation not implemented\n"); 1737c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1738c2c66affSColin Finck } 1739c2c66affSColin Finck 1740c2c66affSColin Finck /* Class 30 - Next Event Id Information */ 1741c2c66affSColin Finck QSI_DEF(SystemNextEventIdInformation) 1742c2c66affSColin Finck { 1743c2c66affSColin Finck /* FIXME */ 1744c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemNextEventIdInformation not implemented\n"); 1745c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1746c2c66affSColin Finck } 1747c2c66affSColin Finck 1748c2c66affSColin Finck /* Class 31 */ 1749c2c66affSColin Finck QSI_DEF(SystemPerformanceTraceInformation) 1750c2c66affSColin Finck { 1751c2c66affSColin Finck /* FIXME */ 1752c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemPerformanceTraceInformation not implemented\n"); 1753c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1754c2c66affSColin Finck } 1755c2c66affSColin Finck 1756c2c66affSColin Finck /* Class 32 - Crash Dump Information */ 1757c2c66affSColin Finck QSI_DEF(SystemCrashDumpInformation) 1758c2c66affSColin Finck { 1759c2c66affSColin Finck /* FIXME */ 1760c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemCrashDumpInformation not implemented\n"); 1761c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1762c2c66affSColin Finck } 1763c2c66affSColin Finck 1764c2c66affSColin Finck /* Class 33 - Exception Information */ 1765c2c66affSColin Finck QSI_DEF(SystemExceptionInformation) 1766c2c66affSColin Finck { 1767c2c66affSColin Finck PSYSTEM_EXCEPTION_INFORMATION ExceptionInformation = 1768c2c66affSColin Finck (PSYSTEM_EXCEPTION_INFORMATION)Buffer; 1769c2c66affSColin Finck PKPRCB Prcb; 1770c2c66affSColin Finck ULONG AlignmentFixupCount = 0, ExceptionDispatchCount = 0; 1771c2c66affSColin Finck ULONG FloatingEmulationCount = 0, ByteWordEmulationCount = 0; 1772c2c66affSColin Finck CHAR i; 1773c2c66affSColin Finck 1774c2c66affSColin Finck /* Check size of a buffer, it must match our expectations */ 1775c2c66affSColin Finck if (sizeof(SYSTEM_EXCEPTION_INFORMATION) != Size) 1776c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1777c2c66affSColin Finck 1778c2c66affSColin Finck /* Sum up exception count information from all processors */ 1779c2c66affSColin Finck for (i = 0; i < KeNumberProcessors; i++) 1780c2c66affSColin Finck { 1781c2c66affSColin Finck Prcb = KiProcessorBlock[i]; 1782c2c66affSColin Finck if (Prcb) 1783c2c66affSColin Finck { 1784c2c66affSColin Finck AlignmentFixupCount += Prcb->KeAlignmentFixupCount; 1785c2c66affSColin Finck ExceptionDispatchCount += Prcb->KeExceptionDispatchCount; 1786c2c66affSColin Finck #ifndef _M_ARM 1787c2c66affSColin Finck FloatingEmulationCount += Prcb->KeFloatingEmulationCount; 1788c2c66affSColin Finck #endif // _M_ARM 1789c2c66affSColin Finck } 1790c2c66affSColin Finck } 1791c2c66affSColin Finck 1792c2c66affSColin Finck /* Save information in user's buffer */ 1793c2c66affSColin Finck ExceptionInformation->AlignmentFixupCount = AlignmentFixupCount; 1794c2c66affSColin Finck ExceptionInformation->ExceptionDispatchCount = ExceptionDispatchCount; 1795c2c66affSColin Finck ExceptionInformation->FloatingEmulationCount = FloatingEmulationCount; 1796c2c66affSColin Finck ExceptionInformation->ByteWordEmulationCount = ByteWordEmulationCount; 1797c2c66affSColin Finck 1798c2c66affSColin Finck return STATUS_SUCCESS; 1799c2c66affSColin Finck } 1800c2c66affSColin Finck 1801c2c66affSColin Finck /* Class 34 - Crash Dump State Information */ 1802c2c66affSColin Finck QSI_DEF(SystemCrashDumpStateInformation) 1803c2c66affSColin Finck { 1804c2c66affSColin Finck /* FIXME */ 1805c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemCrashDumpStateInformation not implemented\n"); 1806c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1807c2c66affSColin Finck } 1808c2c66affSColin Finck 1809c2c66affSColin Finck /* Class 35 - Kernel Debugger Information */ 1810c2c66affSColin Finck QSI_DEF(SystemKernelDebuggerInformation) 1811c2c66affSColin Finck { 1812c2c66affSColin Finck PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer; 1813c2c66affSColin Finck 1814c2c66affSColin Finck #if (NTDDI_VERSION >= NTDDI_VISTA) 1815c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION); 1816c2c66affSColin Finck #endif 1817c2c66affSColin Finck 1818c2c66affSColin Finck if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION)) 1819c2c66affSColin Finck { 1820c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1821c2c66affSColin Finck } 1822c2c66affSColin Finck 1823c2c66affSColin Finck skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED; 1824c2c66affSColin Finck skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT; 1825c2c66affSColin Finck 1826c2c66affSColin Finck #if (NTDDI_VERSION < NTDDI_VISTA) 1827c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION); 1828c2c66affSColin Finck #endif 1829c2c66affSColin Finck 1830c2c66affSColin Finck return STATUS_SUCCESS; 1831c2c66affSColin Finck } 1832c2c66affSColin Finck 1833c2c66affSColin Finck /* Class 36 - Context Switch Information */ 1834c2c66affSColin Finck QSI_DEF(SystemContextSwitchInformation) 1835c2c66affSColin Finck { 1836c2c66affSColin Finck PSYSTEM_CONTEXT_SWITCH_INFORMATION ContextSwitchInformation = 1837c2c66affSColin Finck (PSYSTEM_CONTEXT_SWITCH_INFORMATION)Buffer; 1838c2c66affSColin Finck ULONG ContextSwitches; 1839c2c66affSColin Finck PKPRCB Prcb; 1840c2c66affSColin Finck CHAR i; 1841c2c66affSColin Finck 1842c2c66affSColin Finck /* Check size of a buffer, it must match our expectations */ 1843c2c66affSColin Finck if (sizeof(SYSTEM_CONTEXT_SWITCH_INFORMATION) != Size) 1844c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1845c2c66affSColin Finck 1846c2c66affSColin Finck /* Calculate total value of context switches across all processors */ 1847c2c66affSColin Finck ContextSwitches = 0; 1848c2c66affSColin Finck for (i = 0; i < KeNumberProcessors; i ++) 1849c2c66affSColin Finck { 1850c2c66affSColin Finck Prcb = KiProcessorBlock[i]; 1851c2c66affSColin Finck if (Prcb) 1852c2c66affSColin Finck { 1853c2c66affSColin Finck ContextSwitches += KeGetContextSwitches(Prcb); 1854c2c66affSColin Finck } 1855c2c66affSColin Finck } 1856c2c66affSColin Finck 1857c2c66affSColin Finck ContextSwitchInformation->ContextSwitches = ContextSwitches; 1858c2c66affSColin Finck 1859c2c66affSColin Finck /* FIXME */ 1860c2c66affSColin Finck ContextSwitchInformation->FindAny = 0; 1861c2c66affSColin Finck ContextSwitchInformation->FindLast = 0; 1862c2c66affSColin Finck ContextSwitchInformation->FindIdeal = 0; 1863c2c66affSColin Finck ContextSwitchInformation->IdleAny = 0; 1864c2c66affSColin Finck ContextSwitchInformation->IdleCurrent = 0; 1865c2c66affSColin Finck ContextSwitchInformation->IdleLast = 0; 1866c2c66affSColin Finck ContextSwitchInformation->IdleIdeal = 0; 1867c2c66affSColin Finck ContextSwitchInformation->PreemptAny = 0; 1868c2c66affSColin Finck ContextSwitchInformation->PreemptCurrent = 0; 1869c2c66affSColin Finck ContextSwitchInformation->PreemptLast = 0; 1870c2c66affSColin Finck ContextSwitchInformation->SwitchToIdle = 0; 1871c2c66affSColin Finck 1872c2c66affSColin Finck return STATUS_SUCCESS; 1873c2c66affSColin Finck } 1874c2c66affSColin Finck 1875c2c66affSColin Finck /* Class 37 - Registry Quota Information */ 1876c2c66affSColin Finck QSI_DEF(SystemRegistryQuotaInformation) 1877c2c66affSColin Finck { 1878c2c66affSColin Finck PSYSTEM_REGISTRY_QUOTA_INFORMATION srqi = (PSYSTEM_REGISTRY_QUOTA_INFORMATION) Buffer; 1879c2c66affSColin Finck 1880c2c66affSColin Finck *ReqSize = sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION); 1881c2c66affSColin Finck if (Size < sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION)) 1882c2c66affSColin Finck { 1883c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 1884c2c66affSColin Finck } 1885c2c66affSColin Finck 1886c2c66affSColin Finck DPRINT1("Faking max registry size of 32 MB\n"); 1887c2c66affSColin Finck srqi->RegistryQuotaAllowed = 0x2000000; 1888c2c66affSColin Finck srqi->RegistryQuotaUsed = 0x200000; 1889c2c66affSColin Finck srqi->PagedPoolSize = 0x200000; 1890c2c66affSColin Finck 1891c2c66affSColin Finck return STATUS_SUCCESS; 1892c2c66affSColin Finck } 1893c2c66affSColin Finck 1894c2c66affSColin Finck SSI_DEF(SystemRegistryQuotaInformation) 1895c2c66affSColin Finck { 1896c2c66affSColin Finck /* FIXME */ 1897c2c66affSColin Finck DPRINT1("NtSetSystemInformation - SystemRegistryQuotaInformation not implemented\n"); 1898c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 1899c2c66affSColin Finck } 1900c2c66affSColin Finck 1901c2c66affSColin Finck /* Class 38 - Load And Call Image */ 1902c2c66affSColin Finck SSI_DEF(SystemExtendServiceTableInformation) 1903c2c66affSColin Finck { 1904c2c66affSColin Finck UNICODE_STRING ImageName; 1905c2c66affSColin Finck KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); 1906c2c66affSColin Finck PLDR_DATA_TABLE_ENTRY ModuleObject; 1907c2c66affSColin Finck NTSTATUS Status; 1908c2c66affSColin Finck PIMAGE_NT_HEADERS NtHeader; 1909c2c66affSColin Finck DRIVER_OBJECT Win32k; 1910c2c66affSColin Finck PDRIVER_INITIALIZE DriverInit; 1911c2c66affSColin Finck PVOID ImageBase; 1912c2c66affSColin Finck ULONG_PTR EntryPoint; 1913c2c66affSColin Finck 1914c2c66affSColin Finck /* Validate the size */ 1915c2c66affSColin Finck if (Size != sizeof(UNICODE_STRING)) return STATUS_INFO_LENGTH_MISMATCH; 1916c2c66affSColin Finck 1917c2c66affSColin Finck /* Check who is calling */ 1918c2c66affSColin Finck if (PreviousMode != KernelMode) 1919c2c66affSColin Finck { 1920c2c66affSColin Finck static const UNICODE_STRING Win32kName = 1921c2c66affSColin Finck RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\win32k.sys"); 1922c2c66affSColin Finck 1923c2c66affSColin Finck /* Make sure we can load drivers */ 1924c2c66affSColin Finck if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, UserMode)) 1925c2c66affSColin Finck { 1926c2c66affSColin Finck /* FIXME: We can't, fail */ 1927c2c66affSColin Finck return STATUS_PRIVILEGE_NOT_HELD; 1928c2c66affSColin Finck } 1929c2c66affSColin Finck 1930c2c66affSColin Finck _SEH2_TRY 1931c2c66affSColin Finck { 1932c2c66affSColin Finck /* Probe and copy the unicode string */ 1933c2c66affSColin Finck ProbeForRead(Buffer, sizeof(ImageName), 1); 1934c2c66affSColin Finck ImageName = *(PUNICODE_STRING)Buffer; 1935c2c66affSColin Finck 1936c2c66affSColin Finck /* Probe the string buffer */ 1937c2c66affSColin Finck ProbeForRead(ImageName.Buffer, ImageName.Length, sizeof(WCHAR)); 1938c2c66affSColin Finck 1939c2c66affSColin Finck /* Check if we have the correct name (nothing else is allowed!) */ 1940c2c66affSColin Finck if (!RtlEqualUnicodeString(&ImageName, &Win32kName, FALSE)) 1941c2c66affSColin Finck { 1942c2c66affSColin Finck _SEH2_YIELD(return STATUS_PRIVILEGE_NOT_HELD); 1943c2c66affSColin Finck } 1944c2c66affSColin Finck } 1945c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1946c2c66affSColin Finck { 1947c2c66affSColin Finck _SEH2_YIELD(return _SEH2_GetExceptionCode()); 1948c2c66affSColin Finck } 1949c2c66affSColin Finck _SEH2_END; 1950c2c66affSColin Finck 1951c2c66affSColin Finck /* Recursively call the function, so that we are from kernel mode */ 1952c2c66affSColin Finck return ZwSetSystemInformation(SystemExtendServiceTableInformation, 1953c2c66affSColin Finck (PVOID)&Win32kName, 1954c2c66affSColin Finck sizeof(Win32kName)); 1955c2c66affSColin Finck } 1956c2c66affSColin Finck 1957c2c66affSColin Finck /* Load the image */ 1958c2c66affSColin Finck Status = MmLoadSystemImage((PUNICODE_STRING)Buffer, 1959c2c66affSColin Finck NULL, 1960c2c66affSColin Finck NULL, 1961c2c66affSColin Finck 0, 1962c2c66affSColin Finck (PVOID)&ModuleObject, 1963c2c66affSColin Finck &ImageBase); 1964c2c66affSColin Finck 1965c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status; 1966c2c66affSColin Finck 1967c2c66affSColin Finck /* Get the headers */ 1968c2c66affSColin Finck NtHeader = RtlImageNtHeader(ImageBase); 1969c2c66affSColin Finck if (!NtHeader) 1970c2c66affSColin Finck { 1971c2c66affSColin Finck /* Fail */ 1972c2c66affSColin Finck MmUnloadSystemImage(ModuleObject); 1973c2c66affSColin Finck return STATUS_INVALID_IMAGE_FORMAT; 1974c2c66affSColin Finck } 1975c2c66affSColin Finck 1976c2c66affSColin Finck /* Get the entrypoint */ 1977c2c66affSColin Finck EntryPoint = NtHeader->OptionalHeader.AddressOfEntryPoint; 1978c2c66affSColin Finck EntryPoint += (ULONG_PTR)ImageBase; 1979c2c66affSColin Finck DriverInit = (PDRIVER_INITIALIZE)EntryPoint; 1980c2c66affSColin Finck 1981c2c66affSColin Finck /* Create a dummy device */ 1982c2c66affSColin Finck RtlZeroMemory(&Win32k, sizeof(Win32k)); 1983c2c66affSColin Finck ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 1984c2c66affSColin Finck Win32k.DriverStart = ImageBase; 1985c2c66affSColin Finck 1986c2c66affSColin Finck /* Call it */ 1987c2c66affSColin Finck Status = (DriverInit)(&Win32k, NULL); 1988c2c66affSColin Finck ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 1989c2c66affSColin Finck 1990c2c66affSColin Finck /* Unload if we failed */ 1991c2c66affSColin Finck if (!NT_SUCCESS(Status)) MmUnloadSystemImage(ModuleObject); 1992c2c66affSColin Finck return Status; 1993c2c66affSColin Finck } 1994c2c66affSColin Finck 1995c2c66affSColin Finck /* Class 39 - Priority Separation */ 1996c2c66affSColin Finck SSI_DEF(SystemPrioritySeperation) 1997c2c66affSColin Finck { 1998c2c66affSColin Finck /* Check if the size is correct */ 1999c2c66affSColin Finck if (Size != sizeof(ULONG)) 2000c2c66affSColin Finck { 2001c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 2002c2c66affSColin Finck } 2003c2c66affSColin Finck 2004c2c66affSColin Finck /* We need the TCB privilege */ 2005c2c66affSColin Finck if (!SeSinglePrivilegeCheck(SeTcbPrivilege, ExGetPreviousMode())) 2006c2c66affSColin Finck { 2007c2c66affSColin Finck return STATUS_PRIVILEGE_NOT_HELD; 2008c2c66affSColin Finck } 2009c2c66affSColin Finck 2010c2c66affSColin Finck /* Modify the quantum table */ 2011c2c66affSColin Finck PsChangeQuantumTable(TRUE, *(PULONG)Buffer); 2012c2c66affSColin Finck 2013c2c66affSColin Finck return STATUS_SUCCESS; 2014c2c66affSColin Finck } 2015c2c66affSColin Finck 2016c2c66affSColin Finck /* Class 40 */ 2017c2c66affSColin Finck QSI_DEF(SystemVerifierAddDriverInformation) 2018c2c66affSColin Finck { 2019c2c66affSColin Finck /* FIXME */ 2020c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemVerifierAddDriverInformation not implemented\n"); 2021c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2022c2c66affSColin Finck } 2023c2c66affSColin Finck 2024c2c66affSColin Finck /* Class 41 */ 2025c2c66affSColin Finck QSI_DEF(SystemVerifierRemoveDriverInformation) 2026c2c66affSColin Finck { 2027c2c66affSColin Finck /* FIXME */ 2028c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemVerifierRemoveDriverInformation not implemented\n"); 2029c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2030c2c66affSColin Finck } 2031c2c66affSColin Finck 2032c2c66affSColin Finck /* Class 42 - Power Information */ 2033c2c66affSColin Finck QSI_DEF(SystemProcessorIdleInformation) 2034c2c66affSColin Finck { 2035c2c66affSColin Finck *ReqSize = sizeof(PROCESSOR_POWER_INFORMATION) * KeNumberProcessors; 2036c2c66affSColin Finck 2037c2c66affSColin Finck if (sizeof(PROCESSOR_POWER_INFORMATION) * KeNumberProcessors > Size) 2038c2c66affSColin Finck { 2039c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 2040c2c66affSColin Finck } 2041c2c66affSColin Finck 2042c2c66affSColin Finck /* FIXME */ 2043c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n"); 2044c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2045c2c66affSColin Finck } 2046c2c66affSColin Finck 2047c2c66affSColin Finck /* Class 43 */ 2048c2c66affSColin Finck QSI_DEF(SystemLegacyDriverInformation) 2049c2c66affSColin Finck { 2050c2c66affSColin Finck /* FIXME */ 2051c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemLegacyDriverInformation not implemented\n"); 2052c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2053c2c66affSColin Finck } 2054c2c66affSColin Finck 2055c2c66affSColin Finck /* Class 44 - Current Time Zone Information */ 2056c2c66affSColin Finck QSI_DEF(SystemCurrentTimeZoneInformation) 2057c2c66affSColin Finck { 205849113829SEric Kohl *ReqSize = sizeof(RTL_TIME_ZONE_INFORMATION); 2059c2c66affSColin Finck 206049113829SEric Kohl if (sizeof(RTL_TIME_ZONE_INFORMATION) != Size) 2061c2c66affSColin Finck { 2062c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 2063c2c66affSColin Finck } 2064c2c66affSColin Finck 2065c2c66affSColin Finck /* Copy the time zone information struct */ 2066c2c66affSColin Finck memcpy(Buffer, 2067c2c66affSColin Finck &ExpTimeZoneInfo, 206849113829SEric Kohl sizeof(RTL_TIME_ZONE_INFORMATION)); 2069c2c66affSColin Finck 2070c2c66affSColin Finck return STATUS_SUCCESS; 2071c2c66affSColin Finck } 2072c2c66affSColin Finck 2073c2c66affSColin Finck 2074c2c66affSColin Finck SSI_DEF(SystemCurrentTimeZoneInformation) 2075c2c66affSColin Finck { 2076c2c66affSColin Finck /* Check user buffer's size */ 207749113829SEric Kohl if (Size < sizeof(RTL_TIME_ZONE_INFORMATION)) 2078c2c66affSColin Finck { 2079c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 2080c2c66affSColin Finck } 2081c2c66affSColin Finck 208249113829SEric Kohl return ExpSetTimeZoneInformation((PRTL_TIME_ZONE_INFORMATION)Buffer); 2083c2c66affSColin Finck } 2084c2c66affSColin Finck 2085c2c66affSColin Finck static 2086c2c66affSColin Finck VOID 2087c2c66affSColin Finck ExpCopyLookasideInformation( 2088c2c66affSColin Finck PSYSTEM_LOOKASIDE_INFORMATION *InfoPointer, 2089c2c66affSColin Finck PULONG RemainingPointer, 2090c2c66affSColin Finck PLIST_ENTRY ListHead, 2091c2c66affSColin Finck BOOLEAN ListUsesMisses) 2092c2c66affSColin Finck 2093c2c66affSColin Finck { 2094c2c66affSColin Finck PSYSTEM_LOOKASIDE_INFORMATION Info; 2095c2c66affSColin Finck PGENERAL_LOOKASIDE LookasideList; 2096c2c66affSColin Finck PLIST_ENTRY ListEntry; 2097c2c66affSColin Finck ULONG Remaining; 2098c2c66affSColin Finck 2099c2c66affSColin Finck /* Get info pointer and remaining count of free array element */ 2100c2c66affSColin Finck Info = *InfoPointer; 2101c2c66affSColin Finck Remaining = *RemainingPointer; 2102c2c66affSColin Finck 2103c2c66affSColin Finck /* Loop as long as we have lookaside lists and free array elements */ 2104c2c66affSColin Finck for (ListEntry = ListHead->Flink; 2105c2c66affSColin Finck (ListEntry != ListHead) && (Remaining > 0); 2106c2c66affSColin Finck ListEntry = ListEntry->Flink, Remaining--) 2107c2c66affSColin Finck { 2108c2c66affSColin Finck LookasideList = CONTAINING_RECORD(ListEntry, GENERAL_LOOKASIDE, ListEntry); 2109c2c66affSColin Finck 2110c2c66affSColin Finck /* Fill the next array element */ 2111c2c66affSColin Finck Info->CurrentDepth = LookasideList->Depth; 2112c2c66affSColin Finck Info->MaximumDepth = LookasideList->MaximumDepth; 2113c2c66affSColin Finck Info->TotalAllocates = LookasideList->TotalAllocates; 2114c2c66affSColin Finck Info->TotalFrees = LookasideList->TotalFrees; 2115c2c66affSColin Finck Info->Type = LookasideList->Type; 2116c2c66affSColin Finck Info->Tag = LookasideList->Tag; 2117c2c66affSColin Finck Info->Size = LookasideList->Size; 2118c2c66affSColin Finck 2119c2c66affSColin Finck /* Check how the lists track misses/hits */ 2120c2c66affSColin Finck if (ListUsesMisses) 2121c2c66affSColin Finck { 2122c2c66affSColin Finck /* Copy misses */ 2123c2c66affSColin Finck Info->AllocateMisses = LookasideList->AllocateMisses; 2124c2c66affSColin Finck Info->FreeMisses = LookasideList->FreeMisses; 2125c2c66affSColin Finck } 2126c2c66affSColin Finck else 2127c2c66affSColin Finck { 2128c2c66affSColin Finck /* Calculate misses */ 2129c2c66affSColin Finck Info->AllocateMisses = LookasideList->TotalAllocates 2130c2c66affSColin Finck - LookasideList->AllocateHits; 2131c2c66affSColin Finck Info->FreeMisses = LookasideList->TotalFrees 2132c2c66affSColin Finck - LookasideList->FreeHits; 2133c2c66affSColin Finck } 2134c2c66affSColin Finck } 2135c2c66affSColin Finck 2136c2c66affSColin Finck /* Return the updated pointer and remaining count */ 2137c2c66affSColin Finck *InfoPointer = Info; 2138c2c66affSColin Finck *RemainingPointer = Remaining; 2139c2c66affSColin Finck } 2140c2c66affSColin Finck 2141c2c66affSColin Finck /* Class 45 - Lookaside Information */ 2142c2c66affSColin Finck QSI_DEF(SystemLookasideInformation) 2143c2c66affSColin Finck { 2144c2c66affSColin Finck KPROCESSOR_MODE PreviousMode; 2145c2c66affSColin Finck PSYSTEM_LOOKASIDE_INFORMATION Info; 2146c2c66affSColin Finck PMDL Mdl; 2147c2c66affSColin Finck ULONG MaxCount, Remaining; 2148c2c66affSColin Finck KIRQL OldIrql; 2149c2c66affSColin Finck NTSTATUS Status; 2150c2c66affSColin Finck 2151c2c66affSColin Finck /* First we need to lock down the memory, since we are going to access it 2152c2c66affSColin Finck at high IRQL */ 2153c2c66affSColin Finck PreviousMode = ExGetPreviousMode(); 2154c2c66affSColin Finck Status = ExLockUserBuffer(Buffer, 2155c2c66affSColin Finck Size, 2156c2c66affSColin Finck PreviousMode, 2157c2c66affSColin Finck IoWriteAccess, 2158c2c66affSColin Finck (PVOID*)&Info, 2159c2c66affSColin Finck &Mdl); 2160c2c66affSColin Finck if (!NT_SUCCESS(Status)) 2161c2c66affSColin Finck { 2162c2c66affSColin Finck DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status); 2163c2c66affSColin Finck return Status; 2164c2c66affSColin Finck } 2165c2c66affSColin Finck 2166c2c66affSColin Finck /* Calculate how many items we can store */ 2167c2c66affSColin Finck Remaining = MaxCount = Size / sizeof(SYSTEM_LOOKASIDE_INFORMATION); 2168c2c66affSColin Finck if (Remaining == 0) 2169c2c66affSColin Finck { 2170c2c66affSColin Finck goto Leave; 2171c2c66affSColin Finck } 2172c2c66affSColin Finck 2173c2c66affSColin Finck /* Copy info from pool lookaside lists */ 2174c2c66affSColin Finck ExpCopyLookasideInformation(&Info, 2175c2c66affSColin Finck &Remaining, 2176c2c66affSColin Finck &ExPoolLookasideListHead, 2177c2c66affSColin Finck FALSE); 2178c2c66affSColin Finck if (Remaining == 0) 2179c2c66affSColin Finck { 2180c2c66affSColin Finck goto Leave; 2181c2c66affSColin Finck } 2182c2c66affSColin Finck 2183c2c66affSColin Finck /* Copy info from system lookaside lists */ 2184c2c66affSColin Finck ExpCopyLookasideInformation(&Info, 2185c2c66affSColin Finck &Remaining, 2186c2c66affSColin Finck &ExSystemLookasideListHead, 2187c2c66affSColin Finck TRUE); 2188c2c66affSColin Finck if (Remaining == 0) 2189c2c66affSColin Finck { 2190c2c66affSColin Finck goto Leave; 2191c2c66affSColin Finck } 2192c2c66affSColin Finck 2193c2c66affSColin Finck /* Acquire spinlock for ExpNonPagedLookasideListHead */ 2194c2c66affSColin Finck KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql); 2195c2c66affSColin Finck 2196c2c66affSColin Finck /* Copy info from non-paged lookaside lists */ 2197c2c66affSColin Finck ExpCopyLookasideInformation(&Info, 2198c2c66affSColin Finck &Remaining, 2199c2c66affSColin Finck &ExpNonPagedLookasideListHead, 2200c2c66affSColin Finck TRUE); 2201c2c66affSColin Finck 2202c2c66affSColin Finck /* Release spinlock for ExpNonPagedLookasideListHead */ 2203c2c66affSColin Finck KeReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql); 2204c2c66affSColin Finck 2205c2c66affSColin Finck if (Remaining == 0) 2206c2c66affSColin Finck { 2207c2c66affSColin Finck goto Leave; 2208c2c66affSColin Finck } 2209c2c66affSColin Finck 2210c2c66affSColin Finck /* Acquire spinlock for ExpPagedLookasideListHead */ 2211c2c66affSColin Finck KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql); 2212c2c66affSColin Finck 2213c2c66affSColin Finck /* Copy info from paged lookaside lists */ 2214c2c66affSColin Finck ExpCopyLookasideInformation(&Info, 2215c2c66affSColin Finck &Remaining, 2216c2c66affSColin Finck &ExpPagedLookasideListHead, 2217c2c66affSColin Finck TRUE); 2218c2c66affSColin Finck 2219c2c66affSColin Finck /* Release spinlock for ExpPagedLookasideListHead */ 2220c2c66affSColin Finck KeReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql); 2221c2c66affSColin Finck 2222c2c66affSColin Finck Leave: 2223c2c66affSColin Finck 2224c2c66affSColin Finck /* Release the locked user buffer */ 2225c2c66affSColin Finck ExUnlockUserBuffer(Mdl); 2226c2c66affSColin Finck 2227c2c66affSColin Finck /* Return the size of the actually written data */ 2228c2c66affSColin Finck *ReqSize = (MaxCount - Remaining) * sizeof(SYSTEM_LOOKASIDE_INFORMATION); 2229c2c66affSColin Finck return STATUS_SUCCESS; 2230c2c66affSColin Finck } 2231c2c66affSColin Finck 2232c2c66affSColin Finck 2233c2c66affSColin Finck /* Class 46 - Set time slip event */ 2234c2c66affSColin Finck SSI_DEF(SystemTimeSlipNotification) 2235c2c66affSColin Finck { 2236c2c66affSColin Finck /* FIXME */ 2237c2c66affSColin Finck DPRINT1("NtSetSystemInformation - SystemTimeSlipNotification not implemented\n"); 2238c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2239c2c66affSColin Finck } 2240c2c66affSColin Finck 2241c2c66affSColin Finck NTSTATUS 2242c2c66affSColin Finck NTAPI 2243c2c66affSColin Finck MmSessionCreate(OUT PULONG SessionId); 2244c2c66affSColin Finck 2245c2c66affSColin Finck NTSTATUS 2246c2c66affSColin Finck NTAPI 2247c2c66affSColin Finck MmSessionDelete(IN ULONG SessionId); 2248c2c66affSColin Finck 2249c2c66affSColin Finck /* Class 47 - Create a new session (TSE) */ 2250c2c66affSColin Finck SSI_DEF(SystemSessionCreate) 2251c2c66affSColin Finck { 2252c2c66affSColin Finck ULONG SessionId; 2253c2c66affSColin Finck KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); 2254c2c66affSColin Finck NTSTATUS Status; 2255c2c66affSColin Finck 2256c2c66affSColin Finck if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH; 2257c2c66affSColin Finck 2258c2c66affSColin Finck if (PreviousMode != KernelMode) 2259c2c66affSColin Finck { 2260c2c66affSColin Finck if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode)) 2261c2c66affSColin Finck { 2262c2c66affSColin Finck return STATUS_PRIVILEGE_NOT_HELD; 2263c2c66affSColin Finck } 2264c2c66affSColin Finck 2265c2c66affSColin Finck ProbeForWriteUlong(Buffer); 2266c2c66affSColin Finck } 2267c2c66affSColin Finck 2268c2c66affSColin Finck Status = MmSessionCreate(&SessionId); 2269c2c66affSColin Finck if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId; 2270c2c66affSColin Finck 2271c2c66affSColin Finck return Status; 2272c2c66affSColin Finck } 2273c2c66affSColin Finck 2274c2c66affSColin Finck 2275c2c66affSColin Finck /* Class 48 - Delete an existing session (TSE) */ 2276c2c66affSColin Finck SSI_DEF(SystemSessionDetach) 2277c2c66affSColin Finck { 2278c2c66affSColin Finck ULONG SessionId; 2279c2c66affSColin Finck KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); 2280c2c66affSColin Finck 2281c2c66affSColin Finck if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH; 2282c2c66affSColin Finck 2283c2c66affSColin Finck if (PreviousMode != KernelMode) 2284c2c66affSColin Finck { 2285c2c66affSColin Finck if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode)) 2286c2c66affSColin Finck { 2287c2c66affSColin Finck return STATUS_PRIVILEGE_NOT_HELD; 2288c2c66affSColin Finck } 2289c2c66affSColin Finck } 2290c2c66affSColin Finck 2291c2c66affSColin Finck SessionId = *(PULONG)Buffer; 2292c2c66affSColin Finck 2293c2c66affSColin Finck return MmSessionDelete(SessionId); 2294c2c66affSColin Finck } 2295c2c66affSColin Finck 2296c2c66affSColin Finck 2297c2c66affSColin Finck /* Class 49 - UNKNOWN */ 2298c2c66affSColin Finck QSI_DEF(SystemSessionInformation) 2299c2c66affSColin Finck { 2300c2c66affSColin Finck /* FIXME */ 2301c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemSessionInformation not implemented\n"); 2302c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2303c2c66affSColin Finck } 2304c2c66affSColin Finck 2305c2c66affSColin Finck 2306c2c66affSColin Finck /* Class 50 - System range start address */ 2307c2c66affSColin Finck QSI_DEF(SystemRangeStartInformation) 2308c2c66affSColin Finck { 2309c2c66affSColin Finck /* Check user buffer's size */ 2310c2c66affSColin Finck if (Size != sizeof(ULONG_PTR)) return STATUS_INFO_LENGTH_MISMATCH; 2311c2c66affSColin Finck 2312c2c66affSColin Finck *(PULONG_PTR)Buffer = (ULONG_PTR)MmSystemRangeStart; 2313c2c66affSColin Finck 2314c2c66affSColin Finck if (ReqSize) *ReqSize = sizeof(ULONG_PTR); 2315c2c66affSColin Finck 2316c2c66affSColin Finck return STATUS_SUCCESS; 2317c2c66affSColin Finck } 2318c2c66affSColin Finck 2319c2c66affSColin Finck /* Class 51 - Driver verifier information */ 2320c2c66affSColin Finck QSI_DEF(SystemVerifierInformation) 2321c2c66affSColin Finck { 2322c2c66affSColin Finck /* FIXME */ 2323c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemVerifierInformation not implemented\n"); 2324c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2325c2c66affSColin Finck } 2326c2c66affSColin Finck 2327c2c66affSColin Finck 2328c2c66affSColin Finck SSI_DEF(SystemVerifierInformation) 2329c2c66affSColin Finck { 2330c2c66affSColin Finck /* FIXME */ 2331c2c66affSColin Finck DPRINT1("NtSetSystemInformation - SystemVerifierInformation not implemented\n"); 2332c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2333c2c66affSColin Finck } 2334c2c66affSColin Finck 2335c2c66affSColin Finck 2336c2c66affSColin Finck /* Class 52 */ 2337c2c66affSColin Finck SSI_DEF(SystemVerifierThunkExtend) 2338c2c66affSColin Finck { 2339c2c66affSColin Finck /* FIXME */ 2340c2c66affSColin Finck DPRINT1("NtSetSystemInformation - SystemVerifierThunkExtend not implemented\n"); 2341c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2342c2c66affSColin Finck } 2343c2c66affSColin Finck 2344c2c66affSColin Finck 2345c2c66affSColin Finck /* Class 53 - A session's processes */ 2346c2c66affSColin Finck QSI_DEF(SystemSessionProcessesInformation) 2347c2c66affSColin Finck { 2348c2c66affSColin Finck /* FIXME */ 2349c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemSessionProcessInformation not implemented\n"); 2350c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2351c2c66affSColin Finck } 2352c2c66affSColin Finck 2353c2c66affSColin Finck 2354c2c66affSColin Finck /* Class 54 - Load & map in system space */ 2355c2c66affSColin Finck SSI_DEF(SystemLoadGdiDriverInSystemSpaceInformation) 2356c2c66affSColin Finck { 2357c2c66affSColin Finck /* FIXME */ 2358c2c66affSColin Finck DPRINT1("NtSetSystemInformation - SystemLoadGdiDriverInSystemSpaceInformation not implemented\n"); 2359c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2360c2c66affSColin Finck } 2361c2c66affSColin Finck 2362c2c66affSColin Finck 2363c2c66affSColin Finck /* Class 55 - NUMA processor information */ 2364c2c66affSColin Finck QSI_DEF(SystemNumaProcessorMap) 2365c2c66affSColin Finck { 2366c2c66affSColin Finck ULONG MaxEntries, Node; 2367c2c66affSColin Finck PSYSTEM_NUMA_INFORMATION NumaInformation = (PSYSTEM_NUMA_INFORMATION)Buffer; 2368c2c66affSColin Finck 2369c2c66affSColin Finck /* Validate input size */ 2370c2c66affSColin Finck if (Size < sizeof(ULONG)) 2371c2c66affSColin Finck { 2372c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 2373c2c66affSColin Finck } 2374c2c66affSColin Finck 2375c2c66affSColin Finck /* Return highest node */ 2376c2c66affSColin Finck NumaInformation->HighestNodeNumber = KeNumberNodes - 1; 2377c2c66affSColin Finck 2378c2c66affSColin Finck /* Compute how much entries we will be able to put in output structure */ 2379c2c66affSColin Finck MaxEntries = (Size - FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, ActiveProcessorsAffinityMask)) / sizeof(ULONGLONG); 2380c2c66affSColin Finck /* Make sure we don't overflow KeNodeBlock */ 2381c2c66affSColin Finck if (MaxEntries > KeNumberNodes) 2382c2c66affSColin Finck { 2383c2c66affSColin Finck MaxEntries = KeNumberNodes; 2384c2c66affSColin Finck } 2385c2c66affSColin Finck 2386c2c66affSColin Finck /* If we have entries to write, and room for it */ 2387c2c66affSColin Finck if (Size >= FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, ActiveProcessorsAffinityMask) && 2388c2c66affSColin Finck MaxEntries != 0) 2389c2c66affSColin Finck { 2390c2c66affSColin Finck /* Already set size we return */ 2391c2c66affSColin Finck *ReqSize = FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, ActiveProcessorsAffinityMask) + 2392c2c66affSColin Finck MaxEntries * sizeof(ULONGLONG); 2393c2c66affSColin Finck 2394c2c66affSColin Finck /* For each node, return processor mask */ 2395c2c66affSColin Finck for (Node = 0; Node < MaxEntries; ++Node) 2396c2c66affSColin Finck { 2397c2c66affSColin Finck NumaInformation->ActiveProcessorsAffinityMask[Node] = KeNodeBlock[Node]->ProcessorMask; 2398c2c66affSColin Finck } 2399c2c66affSColin Finck } 2400c2c66affSColin Finck else 2401c2c66affSColin Finck { 2402c2c66affSColin Finck /* We only returned highest node number */ 2403c2c66affSColin Finck *ReqSize = sizeof(ULONG); 2404c2c66affSColin Finck } 2405c2c66affSColin Finck 2406c2c66affSColin Finck return STATUS_SUCCESS; 2407c2c66affSColin Finck } 2408c2c66affSColin Finck 2409c2c66affSColin Finck 2410c2c66affSColin Finck /* Class 56 - Prefetcher information */ 2411c2c66affSColin Finck QSI_DEF(SystemPrefetcherInformation) 2412c2c66affSColin Finck { 2413c2c66affSColin Finck /* FIXME */ 2414c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemPrefetcherInformation not implemented\n"); 2415c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2416c2c66affSColin Finck } 2417c2c66affSColin Finck 2418c2c66affSColin Finck 2419c2c66affSColin Finck /* Class 57 - Extended process information */ 2420c2c66affSColin Finck QSI_DEF(SystemExtendedProcessInformation) 2421c2c66affSColin Finck { 2422c2c66affSColin Finck /* FIXME */ 2423c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemExtendedProcessInformation not implemented\n"); 2424c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2425c2c66affSColin Finck } 2426c2c66affSColin Finck 2427c2c66affSColin Finck 2428c2c66affSColin Finck /* Class 58 - Recommended shared ata alignment */ 2429c2c66affSColin Finck QSI_DEF(SystemRecommendedSharedDataAlignment) 2430c2c66affSColin Finck { 2431c2c66affSColin Finck /* FIXME */ 2432c2c66affSColin Finck DPRINT1("NtQuerySystemInformation - SystemRecommendedSharedDataAlignment not implemented\n"); 2433c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED; 2434c2c66affSColin Finck } 2435c2c66affSColin Finck 2436c2c66affSColin Finck 2437c2c66affSColin Finck /* Class 60 - NUMA memory information */ 2438c2c66affSColin Finck QSI_DEF(SystemNumaAvailableMemory) 2439c2c66affSColin Finck { 2440c2c66affSColin Finck ULONG MaxEntries, Node; 2441c2c66affSColin Finck PSYSTEM_NUMA_INFORMATION NumaInformation = (PSYSTEM_NUMA_INFORMATION)Buffer; 2442c2c66affSColin Finck 2443c2c66affSColin Finck /* Validate input size */ 2444c2c66affSColin Finck if (Size < sizeof(ULONG)) 2445c2c66affSColin Finck { 2446c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 2447c2c66affSColin Finck } 2448c2c66affSColin Finck 2449c2c66affSColin Finck /* Return highest node */ 2450c2c66affSColin Finck NumaInformation->HighestNodeNumber = KeNumberNodes - 1; 2451c2c66affSColin Finck 2452c2c66affSColin Finck /* Compute how much entries we will be able to put in output structure */ 2453c2c66affSColin Finck MaxEntries = (Size - FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, AvailableMemory)) / sizeof(ULONGLONG); 2454c2c66affSColin Finck /* Make sure we don't overflow KeNodeBlock */ 2455c2c66affSColin Finck if (MaxEntries > KeNumberNodes) 2456c2c66affSColin Finck { 2457c2c66affSColin Finck MaxEntries = KeNumberNodes; 2458c2c66affSColin Finck } 2459c2c66affSColin Finck 2460c2c66affSColin Finck /* If we have entries to write, and room for it */ 2461c2c66affSColin Finck if (Size >= FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, AvailableMemory) && 2462c2c66affSColin Finck MaxEntries != 0) 2463c2c66affSColin Finck { 2464c2c66affSColin Finck /* Already set size we return */ 2465c2c66affSColin Finck *ReqSize = FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, AvailableMemory) + 2466c2c66affSColin Finck MaxEntries * sizeof(ULONGLONG); 2467c2c66affSColin Finck 2468c2c66affSColin Finck /* If we have a single entry (us), directly return MM information */ 2469c2c66affSColin Finck if (MaxEntries == 1) 2470c2c66affSColin Finck { 2471c2c66affSColin Finck NumaInformation->AvailableMemory[0] = MmAvailablePages << PAGE_SHIFT; 2472c2c66affSColin Finck } 2473c2c66affSColin Finck else 2474c2c66affSColin Finck { 2475c2c66affSColin Finck /* Otherwise, for each node, return available bytes */ 2476c2c66affSColin Finck for (Node = 0; Node < MaxEntries; ++Node) 2477c2c66affSColin Finck { 2478c2c66affSColin Finck NumaInformation->AvailableMemory[Node] = (KeNodeBlock[Node]->FreeCount[0] + KeNodeBlock[Node]->FreeCount[1]) << PAGE_SHIFT; 2479c2c66affSColin Finck } 2480c2c66affSColin Finck } 2481c2c66affSColin Finck } 2482c2c66affSColin Finck else 2483c2c66affSColin Finck { 2484c2c66affSColin Finck /* We only returned highest node number */ 2485c2c66affSColin Finck *ReqSize = sizeof(ULONG); 2486c2c66affSColin Finck } 2487c2c66affSColin Finck 2488c2c66affSColin Finck return STATUS_SUCCESS; 2489c2c66affSColin Finck } 2490c2c66affSColin Finck 2491c2c66affSColin Finck /* Class 64 - Extended handle information */ 2492c2c66affSColin Finck QSI_DEF(SystemExtendedHandleInformation) 2493c2c66affSColin Finck { 2494c2c66affSColin Finck PSYSTEM_HANDLE_INFORMATION_EX HandleInformation; 2495c2c66affSColin Finck PLIST_ENTRY NextTableEntry; 2496c2c66affSColin Finck PHANDLE_TABLE HandleTable; 2497c2c66affSColin Finck PHANDLE_TABLE_ENTRY HandleTableEntry; 2498c2c66affSColin Finck EXHANDLE Handle; 2499c2c66affSColin Finck ULONG Index = 0; 2500c2c66affSColin Finck NTSTATUS Status; 2501c2c66affSColin Finck PMDL Mdl; 2502c2c66affSColin Finck PAGED_CODE(); 2503c2c66affSColin Finck 2504c2c66affSColin Finck DPRINT("NtQuerySystemInformation - SystemExtendedHandleInformation\n"); 2505c2c66affSColin Finck 2506c2c66affSColin Finck /* Set initial required buffer size */ 2507c2c66affSColin Finck *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handle); 2508c2c66affSColin Finck 2509c2c66affSColin Finck /* Check user's buffer size */ 2510c2c66affSColin Finck if (Size < *ReqSize) 2511c2c66affSColin Finck { 2512c2c66affSColin Finck return STATUS_INFO_LENGTH_MISMATCH; 2513c2c66affSColin Finck } 2514c2c66affSColin Finck 2515c2c66affSColin Finck /* We need to lock down the memory */ 2516c2c66affSColin Finck Status = ExLockUserBuffer(Buffer, 2517c2c66affSColin Finck Size, 2518c2c66affSColin Finck ExGetPreviousMode(), 2519c2c66affSColin Finck IoWriteAccess, 2520c2c66affSColin Finck (PVOID*)&HandleInformation, 2521c2c66affSColin Finck &Mdl); 2522c2c66affSColin Finck if (!NT_SUCCESS(Status)) 2523c2c66affSColin Finck { 2524c2c66affSColin Finck DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status); 2525c2c66affSColin Finck return Status; 2526c2c66affSColin Finck } 2527c2c66affSColin Finck 2528c2c66affSColin Finck /* Reset of count of handles */ 2529c2c66affSColin Finck HandleInformation->Count = 0; 2530c2c66affSColin Finck 2531c2c66affSColin Finck /* Enter a critical region */ 2532c2c66affSColin Finck KeEnterCriticalRegion(); 2533c2c66affSColin Finck 2534c2c66affSColin Finck /* Acquire the handle table lock */ 2535c2c66affSColin Finck ExAcquirePushLockShared(&HandleTableListLock); 2536c2c66affSColin Finck 2537c2c66affSColin Finck /* Enumerate all system handles */ 2538c2c66affSColin Finck for (NextTableEntry = HandleTableListHead.Flink; 2539c2c66affSColin Finck NextTableEntry != &HandleTableListHead; 2540c2c66affSColin Finck NextTableEntry = NextTableEntry->Flink) 2541c2c66affSColin Finck { 2542c2c66affSColin Finck /* Get current handle table */ 2543c2c66affSColin Finck HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList); 2544c2c66affSColin Finck 2545c2c66affSColin Finck /* Set the initial value and loop the entries */ 2546c2c66affSColin Finck Handle.Value = 0; 2547c2c66affSColin Finck while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle))) 2548c2c66affSColin Finck { 2549c2c66affSColin Finck /* Validate the entry */ 2550c2c66affSColin Finck if ((HandleTableEntry->Object) && 2551c2c66affSColin Finck (HandleTableEntry->NextFreeTableEntry != -2)) 2552c2c66affSColin Finck { 2553c2c66affSColin Finck /* Increase of count of handles */ 2554c2c66affSColin Finck ++HandleInformation->Count; 2555c2c66affSColin Finck 2556c2c66affSColin Finck /* Lock the entry */ 2557c2c66affSColin Finck if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) 2558c2c66affSColin Finck { 2559c2c66affSColin Finck /* Increase required buffer size */ 2560c2c66affSColin Finck *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX); 2561c2c66affSColin Finck 2562c2c66affSColin Finck /* Check user's buffer size */ 2563c2c66affSColin Finck if (*ReqSize > Size) 2564c2c66affSColin Finck { 2565c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH; 2566c2c66affSColin Finck } 2567c2c66affSColin Finck else 2568c2c66affSColin Finck { 2569c2c66affSColin Finck POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry); 2570c2c66affSColin Finck 2571c2c66affSColin Finck /* Filling handle information */ 2572c2c66affSColin Finck HandleInformation->Handle[Index].UniqueProcessId = 2573c2c66affSColin Finck (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId; 2574c2c66affSColin Finck 2575c2c66affSColin Finck HandleInformation->Handle[Index].CreatorBackTraceIndex = 0; 2576c2c66affSColin Finck 2577c2c66affSColin Finck #if 0 /* FIXME!!! Type field currupted */ 2578c2c66affSColin Finck HandleInformation->Handles[Index].ObjectTypeIndex = 2579c2c66affSColin Finck (UCHAR) ObjectHeader->Type->Index; 2580c2c66affSColin Finck #else 2581c2c66affSColin Finck HandleInformation->Handle[Index].ObjectTypeIndex = 0; 2582c2c66affSColin Finck #endif 2583c2c66affSColin Finck 2584c2c66affSColin Finck HandleInformation->Handle[Index].HandleAttributes = 2585c2c66affSColin Finck HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES; 2586c2c66affSColin Finck 2587c2c66affSColin Finck HandleInformation->Handle[Index].HandleValue = 2588c2c66affSColin Finck (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay; 2589c2c66affSColin Finck 2590c2c66affSColin Finck HandleInformation->Handle[Index].Object = &ObjectHeader->Body; 2591c2c66affSColin Finck 2592c2c66affSColin Finck HandleInformation->Handle[Index].GrantedAccess = 2593c2c66affSColin Finck HandleTableEntry->GrantedAccess; 2594c2c66affSColin Finck 2595c2c66affSColin Finck HandleInformation->Handle[Index].Reserved = 0; 2596c2c66affSColin Finck 2597c2c66affSColin Finck ++Index; 2598c2c66affSColin Finck } 2599c2c66affSColin Finck 2600c2c66affSColin Finck /* Unlock it */ 2601c2c66affSColin Finck ExUnlockHandleTableEntry(HandleTable, HandleTableEntry); 2602c2c66affSColin Finck } 2603c2c66affSColin Finck } 2604c2c66affSColin Finck 2605c2c66affSColin Finck /* Go to the next entry */ 2606c2c66affSColin Finck Handle.Value += sizeof(HANDLE); 2607c2c66affSColin Finck } 2608c2c66affSColin Finck } 2609c2c66affSColin Finck 2610c2c66affSColin Finck /* Release the lock */ 2611c2c66affSColin Finck ExReleasePushLockShared(&HandleTableListLock); 2612c2c66affSColin Finck 2613c2c66affSColin Finck /* Leave the critical region */ 2614c2c66affSColin Finck KeLeaveCriticalRegion(); 2615c2c66affSColin Finck 2616c2c66affSColin Finck /* Release the locked user buffer */ 2617c2c66affSColin Finck ExUnlockUserBuffer(Mdl); 2618c2c66affSColin Finck 2619c2c66affSColin Finck return Status; 2620c2c66affSColin Finck } 2621c2c66affSColin Finck 2622f821e174SPierre Schweitzer /* Class 70 - System object security mode information */ 2623f821e174SPierre Schweitzer QSI_DEF(SystemObjectSecurityMode) 2624f821e174SPierre Schweitzer { 2625f821e174SPierre Schweitzer PULONG ObjectSecurityInfo = (PULONG)Buffer; 2626f821e174SPierre Schweitzer 2627f821e174SPierre Schweitzer /* Validate input size */ 2628f821e174SPierre Schweitzer if (Size != sizeof(ULONG)) 2629f821e174SPierre Schweitzer { 2630f821e174SPierre Schweitzer return STATUS_INFO_LENGTH_MISMATCH; 2631f821e174SPierre Schweitzer } 2632f821e174SPierre Schweitzer 2633f821e174SPierre Schweitzer *ObjectSecurityInfo = ObpObjectSecurityMode; 2634f821e174SPierre Schweitzer 2635f821e174SPierre Schweitzer return STATUS_SUCCESS; 2636f821e174SPierre Schweitzer } 2637f821e174SPierre Schweitzer 263896ee4509SPierre Schweitzer /* Class 73 - Logical processor information */ 263996ee4509SPierre Schweitzer QSI_DEF(SystemLogicalProcessorInformation) 264096ee4509SPierre Schweitzer { 264196ee4509SPierre Schweitzer LONG i; 264296ee4509SPierre Schweitzer PKPRCB Prcb; 264396ee4509SPierre Schweitzer KAFFINITY CurrentProc; 264496ee4509SPierre Schweitzer NTSTATUS Status = STATUS_SUCCESS; 264596ee4509SPierre Schweitzer ULONG DataSize = 0, ProcessorFlags; 264696ee4509SPierre Schweitzer PSYSTEM_LOGICAL_PROCESSOR_INFORMATION CurrentInfo; 264796ee4509SPierre Schweitzer 264896ee4509SPierre Schweitzer /* First, browse active processors, thanks to the map */ 264996ee4509SPierre Schweitzer i = 0; 265096ee4509SPierre Schweitzer CurrentInfo = Buffer; 265196ee4509SPierre Schweitzer CurrentProc = KeActiveProcessors; 265296ee4509SPierre Schweitzer do 265396ee4509SPierre Schweitzer { 265496ee4509SPierre Schweitzer /* If current processor is active and is main in case of HT/MC, return it */ 265596ee4509SPierre Schweitzer Prcb = KiProcessorBlock[i]; 265696ee4509SPierre Schweitzer if ((CurrentProc & 1) && 265796ee4509SPierre Schweitzer Prcb == Prcb->MultiThreadSetMaster) 265896ee4509SPierre Schweitzer { 265996ee4509SPierre Schweitzer /* Assume processor can do HT or multicore */ 266096ee4509SPierre Schweitzer ProcessorFlags = 1; 266196ee4509SPierre Schweitzer 266296ee4509SPierre Schweitzer /* If set is the same for PRCB and multithread, then 266396ee4509SPierre Schweitzer * actually, the processor is single core 266496ee4509SPierre Schweitzer */ 266596ee4509SPierre Schweitzer if (Prcb->SetMember == Prcb->MultiThreadProcessorSet) 266696ee4509SPierre Schweitzer { 266796ee4509SPierre Schweitzer ProcessorFlags = 0; 266896ee4509SPierre Schweitzer } 266996ee4509SPierre Schweitzer 267096ee4509SPierre Schweitzer /* Check we have enough room to return */ 267196ee4509SPierre Schweitzer DataSize += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); 267296ee4509SPierre Schweitzer if (DataSize > Size) 267396ee4509SPierre Schweitzer { 267496ee4509SPierre Schweitzer Status = STATUS_INFO_LENGTH_MISMATCH; 267596ee4509SPierre Schweitzer } 267696ee4509SPierre Schweitzer else 267796ee4509SPierre Schweitzer { 267896ee4509SPierre Schweitzer /* Zero output and return */ 267996ee4509SPierre Schweitzer RtlZeroMemory(CurrentInfo, sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); 268096ee4509SPierre Schweitzer CurrentInfo->ProcessorMask = Prcb->MultiThreadProcessorSet; 268196ee4509SPierre Schweitzer 268296ee4509SPierre Schweitzer /* Processor core needs 1 if HT/MC is supported */ 268396ee4509SPierre Schweitzer CurrentInfo->Relationship = RelationProcessorCore; 268496ee4509SPierre Schweitzer CurrentInfo->ProcessorCore.Flags = ProcessorFlags; 268596ee4509SPierre Schweitzer ++CurrentInfo; 268696ee4509SPierre Schweitzer } 268796ee4509SPierre Schweitzer } 268896ee4509SPierre Schweitzer 268996ee4509SPierre Schweitzer /* Move to the next proc */ 269096ee4509SPierre Schweitzer CurrentProc >>= 1; 269196ee4509SPierre Schweitzer ++i; 269296ee4509SPierre Schweitzer /* Loop while there's someone in the bitmask */ 269396ee4509SPierre Schweitzer } while (CurrentProc != 0); 269496ee4509SPierre Schweitzer 269596ee4509SPierre Schweitzer /* Now, return the NUMA nodes */ 269696ee4509SPierre Schweitzer for (i = 0; i < KeNumberNodes; ++i) 269796ee4509SPierre Schweitzer { 269896ee4509SPierre Schweitzer /* Check we have enough room to return */ 269996ee4509SPierre Schweitzer DataSize += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); 270096ee4509SPierre Schweitzer if (DataSize > Size) 270196ee4509SPierre Schweitzer { 270296ee4509SPierre Schweitzer Status = STATUS_INFO_LENGTH_MISMATCH; 270396ee4509SPierre Schweitzer } 270496ee4509SPierre Schweitzer else 270596ee4509SPierre Schweitzer { 270696ee4509SPierre Schweitzer /* Zero output and return */ 270796ee4509SPierre Schweitzer RtlZeroMemory(CurrentInfo, sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); 270896ee4509SPierre Schweitzer CurrentInfo->ProcessorMask = KeActiveProcessors; 270996ee4509SPierre Schweitzer 271096ee4509SPierre Schweitzer /* NUMA node needs its ID */ 271196ee4509SPierre Schweitzer CurrentInfo->Relationship = RelationNumaNode; 271296ee4509SPierre Schweitzer CurrentInfo->NumaNode.NodeNumber = i; 271396ee4509SPierre Schweitzer ++CurrentInfo; 271496ee4509SPierre Schweitzer } 271596ee4509SPierre Schweitzer } 271696ee4509SPierre Schweitzer 271796ee4509SPierre Schweitzer *ReqSize = DataSize; 271896ee4509SPierre Schweitzer 271996ee4509SPierre Schweitzer return Status; 272096ee4509SPierre Schweitzer } 272196ee4509SPierre Schweitzer 2722d033fe9bSStanislav Motylkov /* Class 76 - System firmware table information */ 2723d033fe9bSStanislav Motylkov QSI_DEF(SystemFirmwareTableInformation) 2724d033fe9bSStanislav Motylkov { 2725d033fe9bSStanislav Motylkov PSYSTEM_FIRMWARE_TABLE_INFORMATION SysFirmwareInfo = (PSYSTEM_FIRMWARE_TABLE_INFORMATION)Buffer; 2726d033fe9bSStanislav Motylkov NTSTATUS Status = STATUS_SUCCESS; 2727d033fe9bSStanislav Motylkov ULONG InputBufSize; 2728d033fe9bSStanislav Motylkov ULONG DataSize = 0; 2729d033fe9bSStanislav Motylkov ULONG TableCount = 0; 2730d033fe9bSStanislav Motylkov 2731d033fe9bSStanislav Motylkov DPRINT("NtQuerySystemInformation - SystemFirmwareTableInformation\n"); 2732d033fe9bSStanislav Motylkov 2733d033fe9bSStanislav Motylkov /* Set initial required buffer size */ 2734d033fe9bSStanislav Motylkov *ReqSize = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer); 2735d033fe9bSStanislav Motylkov 2736d033fe9bSStanislav Motylkov /* Check user's buffer size */ 2737d033fe9bSStanislav Motylkov if (Size < *ReqSize) 2738d033fe9bSStanislav Motylkov { 2739d033fe9bSStanislav Motylkov return STATUS_INFO_LENGTH_MISMATCH; 2740d033fe9bSStanislav Motylkov } 2741d033fe9bSStanislav Motylkov 2742d033fe9bSStanislav Motylkov InputBufSize = SysFirmwareInfo->TableBufferLength; 2743d033fe9bSStanislav Motylkov switch (SysFirmwareInfo->ProviderSignature) 2744d033fe9bSStanislav Motylkov { 2745d033fe9bSStanislav Motylkov /* 2746d033fe9bSStanislav Motylkov * ExpFirmwareTableResource and ExpFirmwareTableProviderListHead 2747d033fe9bSStanislav Motylkov * variables should be used there somehow... 2748d033fe9bSStanislav Motylkov */ 2749d033fe9bSStanislav Motylkov case SIG_ACPI: 2750d033fe9bSStanislav Motylkov { 2751d033fe9bSStanislav Motylkov /* FIXME: Not implemented yet */ 2752d033fe9bSStanislav Motylkov DPRINT1("ACPI provider not implemented\n"); 2753d033fe9bSStanislav Motylkov Status = STATUS_NOT_IMPLEMENTED; 2754d033fe9bSStanislav Motylkov break; 2755d033fe9bSStanislav Motylkov } 2756d033fe9bSStanislav Motylkov case SIG_FIRM: 2757d033fe9bSStanislav Motylkov { 2758d033fe9bSStanislav Motylkov /* FIXME: Not implemented yet */ 2759d033fe9bSStanislav Motylkov DPRINT1("FIRM provider not implemented\n"); 2760d033fe9bSStanislav Motylkov Status = STATUS_NOT_IMPLEMENTED; 2761d033fe9bSStanislav Motylkov break; 2762d033fe9bSStanislav Motylkov } 2763d033fe9bSStanislav Motylkov case SIG_RSMB: 2764d033fe9bSStanislav Motylkov { 2765d033fe9bSStanislav Motylkov Status = ExpGetRawSMBiosTable(NULL, &DataSize, 0); 2766d033fe9bSStanislav Motylkov if (DataSize > 0) 2767d033fe9bSStanislav Motylkov { 2768d033fe9bSStanislav Motylkov TableCount = 1; 2769d033fe9bSStanislav Motylkov if (SysFirmwareInfo->Action == SystemFirmwareTable_Enumerate) 2770d033fe9bSStanislav Motylkov { 2771d033fe9bSStanislav Motylkov DataSize = TableCount * sizeof(ULONG); 2772d033fe9bSStanislav Motylkov if (DataSize <= InputBufSize) 2773d033fe9bSStanislav Motylkov { 2774d033fe9bSStanislav Motylkov *(ULONG *)SysFirmwareInfo->TableBuffer = 0; 2775d033fe9bSStanislav Motylkov } 2776d033fe9bSStanislav Motylkov } 2777d033fe9bSStanislav Motylkov else if (SysFirmwareInfo->Action == SystemFirmwareTable_Get 2778d033fe9bSStanislav Motylkov && DataSize <= InputBufSize) 2779d033fe9bSStanislav Motylkov { 2780d033fe9bSStanislav Motylkov Status = ExpGetRawSMBiosTable(SysFirmwareInfo->TableBuffer, &DataSize, InputBufSize); 2781d033fe9bSStanislav Motylkov } 2782d033fe9bSStanislav Motylkov SysFirmwareInfo->TableBufferLength = DataSize; 2783d033fe9bSStanislav Motylkov } 2784d033fe9bSStanislav Motylkov break; 2785d033fe9bSStanislav Motylkov } 2786d033fe9bSStanislav Motylkov default: 2787d033fe9bSStanislav Motylkov { 2788d033fe9bSStanislav Motylkov DPRINT1("SystemFirmwareTableInformation: Unsupported provider (0x%x)\n", 2789d033fe9bSStanislav Motylkov SysFirmwareInfo->ProviderSignature); 2790d033fe9bSStanislav Motylkov Status = STATUS_ILLEGAL_FUNCTION; 2791d033fe9bSStanislav Motylkov } 2792d033fe9bSStanislav Motylkov } 2793d033fe9bSStanislav Motylkov 2794d033fe9bSStanislav Motylkov if (NT_SUCCESS(Status)) 2795d033fe9bSStanislav Motylkov { 2796d033fe9bSStanislav Motylkov switch (SysFirmwareInfo->Action) 2797d033fe9bSStanislav Motylkov { 2798d033fe9bSStanislav Motylkov case SystemFirmwareTable_Enumerate: 2799d033fe9bSStanislav Motylkov case SystemFirmwareTable_Get: 2800d033fe9bSStanislav Motylkov { 2801d033fe9bSStanislav Motylkov if (SysFirmwareInfo->TableBufferLength > InputBufSize) 2802d033fe9bSStanislav Motylkov { 2803d033fe9bSStanislav Motylkov Status = STATUS_BUFFER_TOO_SMALL; 2804d033fe9bSStanislav Motylkov } 2805d033fe9bSStanislav Motylkov break; 2806d033fe9bSStanislav Motylkov } 2807d033fe9bSStanislav Motylkov default: 2808d033fe9bSStanislav Motylkov { 2809d033fe9bSStanislav Motylkov DPRINT1("SystemFirmwareTableInformation: Unsupported action (0x%x)\n", 2810d033fe9bSStanislav Motylkov SysFirmwareInfo->Action); 2811d033fe9bSStanislav Motylkov Status = STATUS_ILLEGAL_FUNCTION; 2812d033fe9bSStanislav Motylkov } 2813d033fe9bSStanislav Motylkov } 2814d033fe9bSStanislav Motylkov } 2815d033fe9bSStanislav Motylkov else 2816d033fe9bSStanislav Motylkov { 2817d033fe9bSStanislav Motylkov SysFirmwareInfo->TableBufferLength = 0; 2818d033fe9bSStanislav Motylkov } 2819d033fe9bSStanislav Motylkov return Status; 2820d033fe9bSStanislav Motylkov } 2821d033fe9bSStanislav Motylkov 2822c2c66affSColin Finck /* Query/Set Calls Table */ 2823c2c66affSColin Finck typedef 2824c2c66affSColin Finck struct _QSSI_CALLS 2825c2c66affSColin Finck { 2826c2c66affSColin Finck NTSTATUS (* Query) (PVOID,ULONG,PULONG); 2827c2c66affSColin Finck NTSTATUS (* Set) (PVOID,ULONG); 2828c2c66affSColin Finck } QSSI_CALLS; 2829c2c66affSColin Finck 2830c2c66affSColin Finck // QS Query & Set 2831c2c66affSColin Finck // QX Query 2832c2c66affSColin Finck // XS Set 2833c2c66affSColin Finck // XX unknown behaviour 2834c2c66affSColin Finck // 2835c2c66affSColin Finck #define SI_QS(n) {QSI_USE(n),SSI_USE(n)} 2836c2c66affSColin Finck #define SI_QX(n) {QSI_USE(n),NULL} 2837c2c66affSColin Finck #define SI_XS(n) {NULL,SSI_USE(n)} 2838c2c66affSColin Finck #define SI_XX(n) {NULL,NULL} 2839c2c66affSColin Finck 2840c2c66affSColin Finck static 2841c2c66affSColin Finck QSSI_CALLS 2842c2c66affSColin Finck CallQS [] = 2843c2c66affSColin Finck { 2844c2c66affSColin Finck SI_QX(SystemBasicInformation), 2845c2c66affSColin Finck SI_QX(SystemProcessorInformation), 2846c2c66affSColin Finck SI_QX(SystemPerformanceInformation), 2847c2c66affSColin Finck SI_QX(SystemTimeOfDayInformation), 2848c2c66affSColin Finck SI_QX(SystemPathInformation), /* should be SI_XX */ 2849c2c66affSColin Finck SI_QX(SystemProcessInformation), 2850c2c66affSColin Finck SI_QX(SystemCallCountInformation), 2851c2c66affSColin Finck SI_QX(SystemDeviceInformation), 2852c2c66affSColin Finck SI_QX(SystemProcessorPerformanceInformation), 2853c2c66affSColin Finck SI_QS(SystemFlagsInformation), 2854c2c66affSColin Finck SI_QX(SystemCallTimeInformation), /* should be SI_XX */ 2855c2c66affSColin Finck SI_QX(SystemModuleInformation), 2856c2c66affSColin Finck SI_QX(SystemLocksInformation), 2857c2c66affSColin Finck SI_QX(SystemStackTraceInformation), /* should be SI_XX */ 2858c2c66affSColin Finck SI_QX(SystemPagedPoolInformation), /* should be SI_XX */ 2859c2c66affSColin Finck SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */ 2860c2c66affSColin Finck SI_QX(SystemHandleInformation), 2861c2c66affSColin Finck SI_QX(SystemObjectInformation), 2862c2c66affSColin Finck SI_QX(SystemPageFileInformation), 2863c2c66affSColin Finck SI_QX(SystemVdmInstemulInformation), 2864c2c66affSColin Finck SI_QX(SystemVdmBopInformation), /* it should be SI_XX */ 2865c2c66affSColin Finck SI_QS(SystemFileCacheInformation), 2866c2c66affSColin Finck SI_QX(SystemPoolTagInformation), 2867c2c66affSColin Finck SI_QX(SystemInterruptInformation), 2868c2c66affSColin Finck SI_QS(SystemDpcBehaviourInformation), 2869c2c66affSColin Finck SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */ 2870c2c66affSColin Finck SI_XS(SystemLoadGdiDriverInformation), 2871c2c66affSColin Finck SI_XS(SystemUnloadGdiDriverInformation), 2872c2c66affSColin Finck SI_QS(SystemTimeAdjustmentInformation), 2873c2c66affSColin Finck SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */ 2874c2c66affSColin Finck SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */ 2875c2c66affSColin Finck SI_QX(SystemPerformanceTraceInformation), /* it should be SI_XX */ 2876c2c66affSColin Finck SI_QX(SystemCrashDumpInformation), 2877c2c66affSColin Finck SI_QX(SystemExceptionInformation), 2878c2c66affSColin Finck SI_QX(SystemCrashDumpStateInformation), 2879c2c66affSColin Finck SI_QX(SystemKernelDebuggerInformation), 2880c2c66affSColin Finck SI_QX(SystemContextSwitchInformation), 2881c2c66affSColin Finck SI_QS(SystemRegistryQuotaInformation), 2882c2c66affSColin Finck SI_XS(SystemExtendServiceTableInformation), 2883c2c66affSColin Finck SI_XS(SystemPrioritySeperation), 2884c2c66affSColin Finck SI_QX(SystemVerifierAddDriverInformation), /* it should be SI_XX */ 2885c2c66affSColin Finck SI_QX(SystemVerifierRemoveDriverInformation), /* it should be SI_XX */ 2886c2c66affSColin Finck SI_QX(SystemProcessorIdleInformation), /* it should be SI_XX */ 2887c2c66affSColin Finck SI_QX(SystemLegacyDriverInformation), /* it should be SI_XX */ 2888c2c66affSColin Finck SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */ 2889c2c66affSColin Finck SI_QX(SystemLookasideInformation), 2890c2c66affSColin Finck SI_XS(SystemTimeSlipNotification), 2891c2c66affSColin Finck SI_XS(SystemSessionCreate), 2892c2c66affSColin Finck SI_XS(SystemSessionDetach), 2893c2c66affSColin Finck SI_QX(SystemSessionInformation), /* it should be SI_XX */ 2894c2c66affSColin Finck SI_QX(SystemRangeStartInformation), 2895c2c66affSColin Finck SI_QS(SystemVerifierInformation), 2896c2c66affSColin Finck SI_XS(SystemVerifierThunkExtend), 2897c2c66affSColin Finck SI_QX(SystemSessionProcessesInformation), 2898c2c66affSColin Finck SI_XS(SystemLoadGdiDriverInSystemSpaceInformation), 2899c2c66affSColin Finck SI_QX(SystemNumaProcessorMap), 2900c2c66affSColin Finck SI_QX(SystemPrefetcherInformation), 2901c2c66affSColin Finck SI_QX(SystemExtendedProcessInformation), 2902c2c66affSColin Finck SI_QX(SystemRecommendedSharedDataAlignment), 2903c2c66affSColin Finck SI_XX(SystemComPlusPackage), 2904c2c66affSColin Finck SI_QX(SystemNumaAvailableMemory), 2905c2c66affSColin Finck SI_XX(SystemProcessorPowerInformation), /* FIXME: not implemented */ 2906c2c66affSColin Finck SI_XX(SystemEmulationBasicInformation), /* FIXME: not implemented */ 2907c2c66affSColin Finck SI_XX(SystemEmulationProcessorInformation), /* FIXME: not implemented */ 2908c2c66affSColin Finck SI_QX(SystemExtendedHandleInformation), 2909d033fe9bSStanislav Motylkov SI_XX(SystemLostDelayedWriteInformation), /* FIXME: not implemented */ 2910d033fe9bSStanislav Motylkov SI_XX(SystemBigPoolInformation), /* FIXME: not implemented */ 2911d033fe9bSStanislav Motylkov SI_XX(SystemSessionPoolTagInformation), /* FIXME: not implemented */ 2912d033fe9bSStanislav Motylkov SI_XX(SystemSessionMappedViewInformation), /* FIXME: not implemented */ 2913d033fe9bSStanislav Motylkov SI_XX(SystemHotpatchInformation), /* FIXME: not implemented */ 2914f821e174SPierre Schweitzer SI_QX(SystemObjectSecurityMode), 2915d033fe9bSStanislav Motylkov SI_XX(SystemWatchdogTimerHandler), /* FIXME: not implemented */ 2916d033fe9bSStanislav Motylkov SI_XX(SystemWatchdogTimerInformation), /* FIXME: not implemented */ 291796ee4509SPierre Schweitzer SI_QX(SystemLogicalProcessorInformation), 2918d033fe9bSStanislav Motylkov SI_XX(SystemWow64SharedInformation), /* FIXME: not implemented */ 2919d033fe9bSStanislav Motylkov SI_XX(SystemRegisterFirmwareTableInformationHandler), /* FIXME: not implemented */ 2920d033fe9bSStanislav Motylkov SI_QX(SystemFirmwareTableInformation), 2921c2c66affSColin Finck }; 2922c2c66affSColin Finck 2923c2c66affSColin Finck C_ASSERT(SystemBasicInformation == 0); 2924c2c66affSColin Finck #define MIN_SYSTEM_INFO_CLASS (SystemBasicInformation) 2925c2c66affSColin Finck #define MAX_SYSTEM_INFO_CLASS (sizeof(CallQS) / sizeof(CallQS[0])) 2926c2c66affSColin Finck 2927c2c66affSColin Finck /* 2928c2c66affSColin Finck * @implemented 2929c2c66affSColin Finck */ 2930c2c66affSColin Finck __kernel_entry 2931c2c66affSColin Finck NTSTATUS 2932c2c66affSColin Finck NTAPI 2933c2c66affSColin Finck NtQuerySystemInformation( 2934c2c66affSColin Finck _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, 2935c2c66affSColin Finck _Out_writes_bytes_to_opt_(SystemInformationLength, *ReturnLength) PVOID SystemInformation, 2936c2c66affSColin Finck _In_ ULONG Length, 2937c2c66affSColin Finck _Out_opt_ PULONG UnsafeResultLength) 2938c2c66affSColin Finck { 2939c2c66affSColin Finck KPROCESSOR_MODE PreviousMode; 2940c2c66affSColin Finck ULONG ResultLength = 0; 2941c2c66affSColin Finck ULONG Alignment = TYPE_ALIGNMENT(ULONG); 2942c2c66affSColin Finck NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED; 2943c2c66affSColin Finck 2944c2c66affSColin Finck PAGED_CODE(); 2945c2c66affSColin Finck 2946c2c66affSColin Finck PreviousMode = ExGetPreviousMode(); 2947c2c66affSColin Finck 2948c2c66affSColin Finck _SEH2_TRY 2949c2c66affSColin Finck { 2950c2c66affSColin Finck #if (NTDDI_VERSION >= NTDDI_VISTA) 2951c2c66affSColin Finck /* 2952c2c66affSColin Finck * Check if the request is valid. 2953c2c66affSColin Finck */ 295463977328SThomas Faber if (SystemInformationClass < MIN_SYSTEM_INFO_CLASS || 295563977328SThomas Faber SystemInformationClass >= MAX_SYSTEM_INFO_CLASS) 2956c2c66affSColin Finck { 2957c2c66affSColin Finck _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS); 2958c2c66affSColin Finck } 2959c2c66affSColin Finck #endif 2960c2c66affSColin Finck 2961c2c66affSColin Finck if (PreviousMode != KernelMode) 2962c2c66affSColin Finck { 2963c2c66affSColin Finck /* SystemKernelDebuggerInformation needs only BOOLEAN alignment */ 2964c2c66affSColin Finck if (SystemInformationClass == SystemKernelDebuggerInformation) 2965c2c66affSColin Finck Alignment = TYPE_ALIGNMENT(BOOLEAN); 2966c2c66affSColin Finck 2967c2c66affSColin Finck ProbeForWrite(SystemInformation, Length, Alignment); 2968c2c66affSColin Finck if (UnsafeResultLength != NULL) 2969c2c66affSColin Finck ProbeForWriteUlong(UnsafeResultLength); 2970c2c66affSColin Finck } 2971c2c66affSColin Finck 2972c2c66affSColin Finck if (UnsafeResultLength) 2973c2c66affSColin Finck *UnsafeResultLength = 0; 2974c2c66affSColin Finck 2975c2c66affSColin Finck #if (NTDDI_VERSION < NTDDI_VISTA) 2976c2c66affSColin Finck /* 2977c2c66affSColin Finck * Check if the request is valid. 2978c2c66affSColin Finck */ 297963977328SThomas Faber if (SystemInformationClass < MIN_SYSTEM_INFO_CLASS || 298063977328SThomas Faber SystemInformationClass >= MAX_SYSTEM_INFO_CLASS) 2981c2c66affSColin Finck { 2982c2c66affSColin Finck _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS); 2983c2c66affSColin Finck } 2984c2c66affSColin Finck #endif 2985c2c66affSColin Finck 2986c2c66affSColin Finck if (NULL != CallQS [SystemInformationClass].Query) 2987c2c66affSColin Finck { 2988c2c66affSColin Finck /* 2989c2c66affSColin Finck * Hand the request to a subhandler. 2990c2c66affSColin Finck */ 2991c2c66affSColin Finck FStatus = CallQS [SystemInformationClass].Query(SystemInformation, 2992c2c66affSColin Finck Length, 2993c2c66affSColin Finck &ResultLength); 2994c2c66affSColin Finck 2995c2c66affSColin Finck /* Save the result length to the caller */ 2996c2c66affSColin Finck if (UnsafeResultLength) 2997c2c66affSColin Finck *UnsafeResultLength = ResultLength; 2998c2c66affSColin Finck } 2999c2c66affSColin Finck } 3000c2c66affSColin Finck _SEH2_EXCEPT(ExSystemExceptionFilter()) 3001c2c66affSColin Finck { 3002c2c66affSColin Finck FStatus = _SEH2_GetExceptionCode(); 3003c2c66affSColin Finck } 3004c2c66affSColin Finck _SEH2_END; 3005c2c66affSColin Finck 3006c2c66affSColin Finck return FStatus; 3007c2c66affSColin Finck } 3008c2c66affSColin Finck 3009c2c66affSColin Finck 3010c2c66affSColin Finck NTSTATUS 3011c2c66affSColin Finck NTAPI 3012c2c66affSColin Finck NtSetSystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, 3013c2c66affSColin Finck IN PVOID SystemInformation, 3014c2c66affSColin Finck IN ULONG SystemInformationLength) 3015c2c66affSColin Finck { 3016c2c66affSColin Finck NTSTATUS Status = STATUS_INVALID_INFO_CLASS; 3017c2c66affSColin Finck KPROCESSOR_MODE PreviousMode; 3018c2c66affSColin Finck 3019c2c66affSColin Finck PAGED_CODE(); 3020c2c66affSColin Finck 3021c2c66affSColin Finck PreviousMode = ExGetPreviousMode(); 3022c2c66affSColin Finck 3023c2c66affSColin Finck _SEH2_TRY 3024c2c66affSColin Finck { 3025c2c66affSColin Finck /* 3026c2c66affSColin Finck * If called from user mode, check 3027c2c66affSColin Finck * possible unsafe arguments. 3028c2c66affSColin Finck */ 3029c2c66affSColin Finck if (PreviousMode != KernelMode) 3030c2c66affSColin Finck { 3031c2c66affSColin Finck ProbeForRead(SystemInformation, SystemInformationLength, sizeof(ULONG)); 3032c2c66affSColin Finck } 3033c2c66affSColin Finck 3034c2c66affSColin Finck /* 3035c2c66affSColin Finck * Check the request is valid. 3036c2c66affSColin Finck */ 3037c2c66affSColin Finck if ((SystemInformationClass >= MIN_SYSTEM_INFO_CLASS) && 3038c2c66affSColin Finck (SystemInformationClass < MAX_SYSTEM_INFO_CLASS)) 3039c2c66affSColin Finck { 3040c2c66affSColin Finck if (NULL != CallQS [SystemInformationClass].Set) 3041c2c66affSColin Finck { 3042c2c66affSColin Finck /* 3043c2c66affSColin Finck * Hand the request to a subhandler. 3044c2c66affSColin Finck */ 3045c2c66affSColin Finck Status = CallQS [SystemInformationClass].Set(SystemInformation, 3046c2c66affSColin Finck SystemInformationLength); 3047c2c66affSColin Finck } 3048c2c66affSColin Finck } 3049c2c66affSColin Finck } 3050c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 3051c2c66affSColin Finck { 3052c2c66affSColin Finck Status = _SEH2_GetExceptionCode(); 3053c2c66affSColin Finck } 3054c2c66affSColin Finck _SEH2_END; 3055c2c66affSColin Finck 3056c2c66affSColin Finck return Status; 3057c2c66affSColin Finck } 3058c2c66affSColin Finck 3059c2c66affSColin Finck ULONG 3060c2c66affSColin Finck NTAPI 3061c2c66affSColin Finck NtGetCurrentProcessorNumber(VOID) 3062c2c66affSColin Finck { 3063c2c66affSColin Finck /* Just use Ke */ 3064c2c66affSColin Finck return KeGetCurrentProcessorNumber(); 3065c2c66affSColin Finck } 3066c2c66affSColin Finck 3067c2c66affSColin Finck #undef ExGetPreviousMode 3068c2c66affSColin Finck KPROCESSOR_MODE 3069c2c66affSColin Finck NTAPI 3070c2c66affSColin Finck ExGetPreviousMode(VOID) 3071c2c66affSColin Finck { 3072c2c66affSColin Finck /* Just use Ke */ 3073c2c66affSColin Finck return KeGetPreviousMode(); 3074c2c66affSColin Finck } 3075