作為 DELPHI 版本,需要引用 jwaNative, JwaWinType ,他們是 JEDI API 的一部分。JEDI 官網有下載。
先給出 2 個輔助函數 和 一些結構體。
type PRecord = ^TRecord; TRecord = record end; PSystemInformationList = ^TSystemInformationList; TSystemInformationList = record Count: ULONG; List: array [0 .. 0] of TRecord; end; PSYSTEM_HANDLE_Informations = ^TSYSTEM_HANDLE_Informations; _SYSTEM_HANDLE_Informations = record Count: ULONG; SH: array [0 .. 0] of _SYSTEM_HANDLE_INFORMATION; end; TSYSTEM_HANDLE_Informations = _SYSTEM_HANDLE_Informations; SYSTEM_HANDLE_Informations = _SYSTEM_HANDLE_Informations; PNM_INFO = ^TNM_INFO; _NM_INFO = record hFile: THandle; Info: _FILE_NAME_Information; Name: array [0 .. MAX_PATH - 1] of WideChar; end; TNM_INFO = _NM_INFO; NM_INFO = _NM_INFO; Function GetSystemInformationClassSize(Const ATableType: SYSTEM_INFORMATION_CLASS; Const Count: ULONG): ULONG; begin Result := 0; case ATableType of SystemBasicInformation: Result := $002C; SystemProcessorInformation: Result := $0000C; SystemPerformanceInformation: Result := $0138; // SystemTimeInformation: Result := $0020; // SystemPathInformation: Result := $0; // SystemProcessInformation: Result := $00C8 + Count; // SystemCallInformation: Result := $0018 + (Count * $0004); SystemConfigurationInformation: Result := $0018; // SystemProcessorCounters: Result := $0030 + Count;//per cpu SystemGlobalFlag: Result := $0004; // (fails if size != 4) // SystemCallTimeInformation: Result := $0; SystemModuleInformation: Result := $0004 + (Count * Sizeof(SYSTEM_MODULE_INFORMATION)); //(n * 0x011C) SystemLockInformation: Result := $0004 + (Count * Sizeof(SYSTEM_LOCK_INFORMATION)); //(n * 0x0024) // SystemStackTraceInformation: Result := $0; // SystemPagedPoolInformation: Result := $0; // SystemNonPagedPoolInformation: Result := $0; SystemHandleInformation: Result := $0004 + (Count * Sizeof(SYSTEM_HANDLE_INFORMATION)); //(n * 0x0010) // SystemObjectTypeInformation: Result := $0038+ + (Count * $0030);// +) SystemPageFileInformation: Result := $0018 + (Count * Sizeof(SYSTEM_PAGEFILE_INFORMATION)); // SystemVdmInstemulInformation: Result := $0088; // SystemVdmBopInformation: Result := $0; SystemCacheInformation: Result := $0024; SystemPoolTagInformation: Result := $0004 + (Count * Sizeof(SYSTEM_POOL_TAG_INFORMATION)); // (n * 0x001C) // SystemInterruptInformation: Result := $0000 + Count;//, or 0x0018 per cpu SystemDpcInformation: Result := $0014; // SystemFullMemoryInformation: Result := $0; // SystemLoadDriver: Result := $0018;//, set mode only // SystemUnloadDriver: Result := $0004;//, set mode only // SystemTimeAdjustmentInformation: Result := $000C;//, 0x0008 writeable // SystemSummaryMemoryInformation: Result := $0; // SystemNextEventIdInformation: Result := $0; // SystemEventIdsInformation: Result := $0; SystemCrashDumpInformation: Result := $0004; SystemExceptionInformation: Result := $0010; SystemCrashDumpStateInformation: Result := $0004; // SystemDebuggerInformation: Result := $0002; SystemContextSwitchInformation: Result := $0030; SystemRegistryQuotaInformation: Result := $000C; // SystemAddDriver: Result := $0008;//, set mode only // SystemPrioritySeparationInformatio: Result := $0004;//, set mode only // SystemPlugPlayBusInformation: Result := $0; // SystemDockInformation: Result := $0; // SystemPowerInfo: Result := $0060;// (XP only!) // SystemProcessorSpeedInformation: Result := $000C;// (XP only!) SystemTimeZoneInformation: Result := $00AC; SystemLookasideInformation: Result := Count * $0020; SystemSetTimeSlipEvent: Result := $0; SystemCreateSession: Result := $0; SystemDeleteSession: Result := $0; SystemInvalidInfoClass1: Result := $0; SystemRangeStartInformation: Result := $0004; // (fails if size != 4) SystemVerifierInformation: Result := $0; SystemAddVerifier: Result := $0; SystemSessionProcessesInformation: Result := $0; end; end; Function GetSystemInformationClassHasCount(Const ATableType: SYSTEM_INFORMATION_CLASS): BOOL; begin Result := False; case ATableType of // SystemProcessInformation, // SystemCallInformation, // SystemProcessorCounters, SystemModuleInformation, SystemLockInformation, SystemHandleInformation, // SystemObjectTypeInformation, //SystemPageFileInformation, //好像這個還不確定。 // SystemInterruptInformation, SystemPoolTagInformation: Result := True; end; //可以 和 GetSystemInformationClassSize 配合使用。 end;
上面的 NM_INFO 和本文無關。
大家 可以 方便的使用 GetSystemInformationTable 來 獲取所需的系統信息數據。
Function GetSystemInformationTable(hHeap: THandle; Const ATableType: SYSTEM_INFORMATION_CLASS; = = EnableDebugPrivilege(GetCurrentProcess, True, OldPrivilegeAttributes) = = = == ZwQuerySystemInformation(ATableType, AVOID, (ReturnLength > ) //=== HeapAlloc(hHeap, Assigned(AVOID) = NTSTATUS_SUCCESS(Status) == (Status = STATUS_INFO_LENGTH_MISMATCH) GetSystemInformationClassHasCount(ATableType) ////cbBuffer := GetSystemInformationClassSize(ATableType, PSystemInformationList(AVOID).Count + = Sizeof(PSystemInformationList(AVOID).Count) +- Sizeof(PSystemInformationList(AVOID).Count)) * (PSystemInformationList(AVOID).Count + = HeapAlloc(hHeap, Assigned(AVOID) = NTSTATUS_SUCCESS(Status) == = $= HeapAlloc(hHeap, Assigned(AVOID) = (Status = STATUS_INFO_LENGTH_MISMATCH) = cbBuffer * cbBuffer > $ (Status <> NTSTATUS_SUCCESS(Status) == = = ;
第一次 ZwQuerySystemInformation,主要是為了返回 ReturnLength,這個是 最小數據大小,一般對於單個的數據,就直接用這個值。但是對於多個的數據,這個值就是 每一個數據項的大小加上 4 。
第二次調用 ZwQuerySystemInformation,返回了一個數據區,如果多個的數據,肯定會 Status = STATUS_INFO_LENGTH_MISMATCH,所以需要第三次調用。大小有 2 種辦法獲取(具體看代碼)。
如果不確定是不是 多個數據,但是又出現空間不夠用的情況,就需要用網絡上大家常見的循環增大空間的辦法了。
另外 hHeap := GetProcessHeap; 可以得到 hHeap ,而且空間的申請,不一定非要用這個,也可以用 GetMem 等。
最後補上 權限提升函數。
===== hProcessToken = NULL_Handle = (OpenProcessToken(hProcessToken, TOKEN_ADJUST_PRIVILEGES, hToken)) //= , SE_DEBUG_NAME, tp.Privileges[].Luid); //= tp.Privileges[].Attributes :== AdjustTokenPrivileges(hToken, False, tp, sizeof(tp), , ReturnLength); ////==== hProcessToken = NULL_Handle = (OpenProcessToken(hProcessToken, TOKEN_ADJUST_PRIVILEGES, hToken)) //= , SE_DEBUG_NAME, tp.Privileges[].Luid); //= tp.Privileges[ Enable ].Attributes := tp.Privileges[].Attributes // tp.Privileges[].Attributes :=].Attributes := tp.Privileges[].Attributes (// tp.Privileges[].Attributes :=// tp.Privileges[].Attributes := = AdjustTokenPrivileges(hToken, False, tp, sizeof(tp), , ReturnLength); //;