https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4259aab7b0546ef0dc7a1…
commit 4259aab7b0546ef0dc7a1c60cda87dc81978b3ef
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Tue Jul 31 18:48:32 2018 +0300
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Aug 12 14:21:56 2018 +0200
[SDK] Add user-mode DMI/SMBIOS helper library
CORE-5961
---
sdk/lib/CMakeLists.txt | 1 +
sdk/lib/udmihelp/CMakeLists.txt | 12 +++
sdk/lib/udmihelp/precomp.h | 8 ++
sdk/lib/udmihelp/udmihelp.c | 178 ++++++++++++++++++++++++++++++++++++++++
sdk/lib/udmihelp/udmihelp.h | 27 ++++++
5 files changed, 226 insertions(+)
diff --git a/sdk/lib/CMakeLists.txt b/sdk/lib/CMakeLists.txt
index 99c68493aa..e5d2d92453 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 0000000000..270c234a44
--- /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 0000000000..ee1c7a55c6
--- /dev/null
+++ b/sdk/lib/udmihelp/precomp.h
@@ -0,0 +1,8 @@
+#ifndef _UDMIHELP_PCH_
+#define _UDMIHELP_PCH_
+
+#include <windows.h>
+#include <dmilib.h>
+#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 0000000000..a7070eb33d
--- /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 0000000000..8ed59d9f3c
--- /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);