diff --git a/sdk/lib/CMakeLists.txt b/sdk/lib/CMakeLists.txt index 99c68493aa2..e5d2d924533 100644 --- a/sdk/lib/CMakeLists.txt +++ b/sdk/lib/CMakeLists.txt @@ -47,6 +47,7 @@ add_subdirectory(skiplist) add_subdirectory(strmiids) add_subdirectory(smlib) add_subdirectory(tdilib) +add_subdirectory(udmihelp) add_subdirectory(uuid) add_subdirectory(wdmguid) diff --git a/sdk/lib/udmihelp/CMakeLists.txt b/sdk/lib/udmihelp/CMakeLists.txt new file mode 100644 index 00000000000..270c234a448 --- /dev/null +++ b/sdk/lib/udmihelp/CMakeLists.txt @@ -0,0 +1,12 @@ + +include_directories( + ${REACTOS_SOURCE_DIR}/sdk/lib/dmilib) + +list(APPEND SOURCE + udmihelp.c + precomp.h) + +add_library(udmihelp ${SOURCE}) +target_link_libraries(udmihelp dmilib) +add_pch(udmihelp precomp.h SOURCE) +add_dependencies(udmihelp psdk) diff --git a/sdk/lib/udmihelp/precomp.h b/sdk/lib/udmihelp/precomp.h new file mode 100644 index 00000000000..ee1c7a55c68 --- /dev/null +++ b/sdk/lib/udmihelp/precomp.h @@ -0,0 +1,8 @@ +#ifndef _UDMIHELP_PCH_ +#define _UDMIHELP_PCH_ + +#include +#include +#include "udmihelp.h" + +#endif /* _UDMIHELP_PCH_ */ diff --git a/sdk/lib/udmihelp/udmihelp.c b/sdk/lib/udmihelp/udmihelp.c new file mode 100644 index 00000000000..a7070eb33d1 --- /dev/null +++ b/sdk/lib/udmihelp/udmihelp.c @@ -0,0 +1,178 @@ +/* + * PROJECT: ReactOS User-mode DMI/SMBIOS Helper Functions + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: SMBIOS table parsing functions + * COPYRIGHT: Copyright 2018 Stanislav Motylkov + */ + +#include "precomp.h" + +static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, PVOID, DWORD); +static BOOL bInitAPI = FALSE; + +static +VOID +InitializeAPI() +{ + HANDLE hKernel; + + pGetSystemFirmwareTable = NULL; + + hKernel = GetModuleHandleW(L"kernel32.dll"); + if (!hKernel) + return; + + pGetSystemFirmwareTable = (void *)GetProcAddress(hKernel, "GetSystemFirmwareTable"); +} + +/* Load SMBIOS Data */ +PVOID +LoadSMBiosData( + _Inout_updates_(ID_STRINGS_MAX) PCHAR * Strings) +{ + PVOID pBuffer = NULL; + HKEY hKey; + DWORD dwType, dwCheck, dwBytes = 0; + + if (!bInitAPI) + { + InitializeAPI(); + bInitAPI = TRUE; + } + + /* Try using GetSystemFirmwareTable (works on NT 5.2 and higher) */ + if (pGetSystemFirmwareTable) + { + dwBytes = pGetSystemFirmwareTable('RSMB', 0, NULL, 0); + if (dwBytes > 0) + { + pBuffer = HeapAlloc(GetProcessHeap(), 0, dwBytes); + if (!pBuffer) + { + return NULL; + } + dwCheck = pGetSystemFirmwareTable('RSMB', 0, pBuffer, dwBytes); + if (dwCheck != dwBytes) + { + HeapFree(GetProcessHeap(), 0, pBuffer); + return NULL; + } + } + } + if (dwBytes == 0) + { + /* Try using registry (works on NT 5.1) */ + if (RegOpenKeyW(HKEY_LOCAL_MACHINE, + L"SYSTEM\\CurrentControlSet\\Services\\mssmbios\\Data", + &hKey) != ERROR_SUCCESS) + { + return NULL; + } + + if (RegQueryValueExW(hKey, + L"SMBiosData", + NULL, + &dwType, + NULL, + &dwBytes) != ERROR_SUCCESS || dwType != REG_BINARY) + { + RegCloseKey(hKey); + return NULL; + } + + pBuffer = HeapAlloc(GetProcessHeap(), 0, dwBytes); + if (!pBuffer) + { + RegCloseKey(hKey); + return NULL; + } + + if (RegQueryValueExW(hKey, + L"SMBiosData", + NULL, + &dwType, + pBuffer, + &dwBytes) != ERROR_SUCCESS || dwType != REG_BINARY) + { + HeapFree(GetProcessHeap(), 0, pBuffer); + RegCloseKey(hKey); + return NULL; + } + + RegCloseKey(hKey); + } + ParseSMBiosTables(pBuffer, dwBytes, Strings); + return pBuffer; +} + +/* Trim converted DMI string */ +VOID +TrimDmiStringW( + _Inout_ PWSTR pStr) +{ + SIZE_T Length; + UINT i = 0; + + if (!pStr) + return; + + Length = wcslen(pStr); + if (Length == 0) + return; + + /* Trim leading spaces */ + while (i < Length && pStr[i] <= L' ') + { + i++; + } + + if (i > 0) + { + Length -= i; + memmove(pStr, pStr + i, (Length + 1) * sizeof(WCHAR)); + } + + /* Trim trailing spaces */ + while (Length && pStr[Length-1] <= L' ') + { + pStr[Length-1] = L'\0'; + --Length; + } +} + +/* Convert string from SMBIOS */ +SIZE_T +GetSMBiosStringW( + _In_ PCSTR DmiString, + _Out_ PWSTR pBuf, + _In_ DWORD cchBuf, + _In_ BOOL bTrim) +{ + SIZE_T cChars; + + if (!DmiString) + return 0; + + cChars = MultiByteToWideChar(CP_OEMCP, 0, DmiString, -1, pBuf, cchBuf); + + /* NULL-terminate string */ + pBuf[min(cchBuf-1, cChars)] = L'\0'; + + if (bTrim) + { + TrimDmiStringW(pBuf); + } + + return wcslen(pBuf); +} + +/* Free SMBIOS Data */ +VOID +FreeSMBiosData( + _In_ PVOID Buffer) +{ + if (!Buffer) + return; + + HeapFree(GetProcessHeap(), 0, Buffer); +} diff --git a/sdk/lib/udmihelp/udmihelp.h b/sdk/lib/udmihelp/udmihelp.h new file mode 100644 index 00000000000..8ed59d9f3c9 --- /dev/null +++ b/sdk/lib/udmihelp/udmihelp.h @@ -0,0 +1,27 @@ +/* + * PROJECT: ReactOS User-mode DMI/SMBIOS Helper Functions + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: SMBIOS table parsing functions + * COPYRIGHT: Copyright 2018 Stanislav Motylkov + */ + +#pragma once + +PVOID +LoadSMBiosData( + _Inout_updates_(ID_STRINGS_MAX) PCHAR * Strings); + +VOID +TrimDmiStringW( + _Inout_ PWSTR pStr); + +SIZE_T +GetSMBiosStringW( + _In_ PCSTR DmiString, + _Out_ PWSTR pBuf, + _In_ DWORD cchBuf, + _In_ BOOL bTrim); + +VOID +FreeSMBiosData( + _In_ PVOID Buffer);