Reactos

[SDK] Add user-mode DMI/SMBIOS helper library

CORE-5961

authored by

Stanislav Motylkov and committed by
Hermès BÉLUSCA - MAÏTO
4259aab7 22e86add

+226
+1
sdk/lib/CMakeLists.txt
··· 47 47 add_subdirectory(strmiids) 48 48 add_subdirectory(smlib) 49 49 add_subdirectory(tdilib) 50 + add_subdirectory(udmihelp) 50 51 add_subdirectory(uuid) 51 52 add_subdirectory(wdmguid) 52 53
+12
sdk/lib/udmihelp/CMakeLists.txt
··· 1 + 2 + include_directories( 3 + ${REACTOS_SOURCE_DIR}/sdk/lib/dmilib) 4 + 5 + list(APPEND SOURCE 6 + udmihelp.c 7 + precomp.h) 8 + 9 + add_library(udmihelp ${SOURCE}) 10 + target_link_libraries(udmihelp dmilib) 11 + add_pch(udmihelp precomp.h SOURCE) 12 + add_dependencies(udmihelp psdk)
+8
sdk/lib/udmihelp/precomp.h
··· 1 + #ifndef _UDMIHELP_PCH_ 2 + #define _UDMIHELP_PCH_ 3 + 4 + #include <windows.h> 5 + #include <dmilib.h> 6 + #include "udmihelp.h" 7 + 8 + #endif /* _UDMIHELP_PCH_ */
+178
sdk/lib/udmihelp/udmihelp.c
··· 1 + /* 2 + * PROJECT: ReactOS User-mode DMI/SMBIOS Helper Functions 3 + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 + * PURPOSE: SMBIOS table parsing functions 5 + * COPYRIGHT: Copyright 2018 Stanislav Motylkov 6 + */ 7 + 8 + #include "precomp.h" 9 + 10 + static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, PVOID, DWORD); 11 + static BOOL bInitAPI = FALSE; 12 + 13 + static 14 + VOID 15 + InitializeAPI() 16 + { 17 + HANDLE hKernel; 18 + 19 + pGetSystemFirmwareTable = NULL; 20 + 21 + hKernel = GetModuleHandleW(L"kernel32.dll"); 22 + if (!hKernel) 23 + return; 24 + 25 + pGetSystemFirmwareTable = (void *)GetProcAddress(hKernel, "GetSystemFirmwareTable"); 26 + } 27 + 28 + /* Load SMBIOS Data */ 29 + PVOID 30 + LoadSMBiosData( 31 + _Inout_updates_(ID_STRINGS_MAX) PCHAR * Strings) 32 + { 33 + PVOID pBuffer = NULL; 34 + HKEY hKey; 35 + DWORD dwType, dwCheck, dwBytes = 0; 36 + 37 + if (!bInitAPI) 38 + { 39 + InitializeAPI(); 40 + bInitAPI = TRUE; 41 + } 42 + 43 + /* Try using GetSystemFirmwareTable (works on NT 5.2 and higher) */ 44 + if (pGetSystemFirmwareTable) 45 + { 46 + dwBytes = pGetSystemFirmwareTable('RSMB', 0, NULL, 0); 47 + if (dwBytes > 0) 48 + { 49 + pBuffer = HeapAlloc(GetProcessHeap(), 0, dwBytes); 50 + if (!pBuffer) 51 + { 52 + return NULL; 53 + } 54 + dwCheck = pGetSystemFirmwareTable('RSMB', 0, pBuffer, dwBytes); 55 + if (dwCheck != dwBytes) 56 + { 57 + HeapFree(GetProcessHeap(), 0, pBuffer); 58 + return NULL; 59 + } 60 + } 61 + } 62 + if (dwBytes == 0) 63 + { 64 + /* Try using registry (works on NT 5.1) */ 65 + if (RegOpenKeyW(HKEY_LOCAL_MACHINE, 66 + L"SYSTEM\\CurrentControlSet\\Services\\mssmbios\\Data", 67 + &hKey) != ERROR_SUCCESS) 68 + { 69 + return NULL; 70 + } 71 + 72 + if (RegQueryValueExW(hKey, 73 + L"SMBiosData", 74 + NULL, 75 + &dwType, 76 + NULL, 77 + &dwBytes) != ERROR_SUCCESS || dwType != REG_BINARY) 78 + { 79 + RegCloseKey(hKey); 80 + return NULL; 81 + } 82 + 83 + pBuffer = HeapAlloc(GetProcessHeap(), 0, dwBytes); 84 + if (!pBuffer) 85 + { 86 + RegCloseKey(hKey); 87 + return NULL; 88 + } 89 + 90 + if (RegQueryValueExW(hKey, 91 + L"SMBiosData", 92 + NULL, 93 + &dwType, 94 + pBuffer, 95 + &dwBytes) != ERROR_SUCCESS || dwType != REG_BINARY) 96 + { 97 + HeapFree(GetProcessHeap(), 0, pBuffer); 98 + RegCloseKey(hKey); 99 + return NULL; 100 + } 101 + 102 + RegCloseKey(hKey); 103 + } 104 + ParseSMBiosTables(pBuffer, dwBytes, Strings); 105 + return pBuffer; 106 + } 107 + 108 + /* Trim converted DMI string */ 109 + VOID 110 + TrimDmiStringW( 111 + _Inout_ PWSTR pStr) 112 + { 113 + SIZE_T Length; 114 + UINT i = 0; 115 + 116 + if (!pStr) 117 + return; 118 + 119 + Length = wcslen(pStr); 120 + if (Length == 0) 121 + return; 122 + 123 + /* Trim leading spaces */ 124 + while (i < Length && pStr[i] <= L' ') 125 + { 126 + i++; 127 + } 128 + 129 + if (i > 0) 130 + { 131 + Length -= i; 132 + memmove(pStr, pStr + i, (Length + 1) * sizeof(WCHAR)); 133 + } 134 + 135 + /* Trim trailing spaces */ 136 + while (Length && pStr[Length-1] <= L' ') 137 + { 138 + pStr[Length-1] = L'\0'; 139 + --Length; 140 + } 141 + } 142 + 143 + /* Convert string from SMBIOS */ 144 + SIZE_T 145 + GetSMBiosStringW( 146 + _In_ PCSTR DmiString, 147 + _Out_ PWSTR pBuf, 148 + _In_ DWORD cchBuf, 149 + _In_ BOOL bTrim) 150 + { 151 + SIZE_T cChars; 152 + 153 + if (!DmiString) 154 + return 0; 155 + 156 + cChars = MultiByteToWideChar(CP_OEMCP, 0, DmiString, -1, pBuf, cchBuf); 157 + 158 + /* NULL-terminate string */ 159 + pBuf[min(cchBuf-1, cChars)] = L'\0'; 160 + 161 + if (bTrim) 162 + { 163 + TrimDmiStringW(pBuf); 164 + } 165 + 166 + return wcslen(pBuf); 167 + } 168 + 169 + /* Free SMBIOS Data */ 170 + VOID 171 + FreeSMBiosData( 172 + _In_ PVOID Buffer) 173 + { 174 + if (!Buffer) 175 + return; 176 + 177 + HeapFree(GetProcessHeap(), 0, Buffer); 178 + }
+27
sdk/lib/udmihelp/udmihelp.h
··· 1 + /* 2 + * PROJECT: ReactOS User-mode DMI/SMBIOS Helper Functions 3 + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 + * PURPOSE: SMBIOS table parsing functions 5 + * COPYRIGHT: Copyright 2018 Stanislav Motylkov 6 + */ 7 + 8 + #pragma once 9 + 10 + PVOID 11 + LoadSMBiosData( 12 + _Inout_updates_(ID_STRINGS_MAX) PCHAR * Strings); 13 + 14 + VOID 15 + TrimDmiStringW( 16 + _Inout_ PWSTR pStr); 17 + 18 + SIZE_T 19 + GetSMBiosStringW( 20 + _In_ PCSTR DmiString, 21 + _Out_ PWSTR pBuf, 22 + _In_ DWORD cchBuf, 23 + _In_ BOOL bTrim); 24 + 25 + VOID 26 + FreeSMBiosData( 27 + _In_ PVOID Buffer);