From 9b64b95bbc4afdedd41164902d7c6d9eeb70dfbb Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Thu, 8 Oct 2020 00:45:31 +0300 Subject: [PATCH] mdbx-windows: fix mdbx_RegGetValue() for Windows 2000/XP. Change-Id: I436a254300fcba8dbf75ea7568c2bf0c963fe060 --- .github/actions/spelling/expect.txt | 1 + src/lck-windows.c | 4 +++ src/osal.c | 53 +++++++++++++++++------------ src/osal.h | 6 ++++ 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 88cd2752..08196736 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -10,6 +10,7 @@ adata addprefix addsuffix addtogroup +advapi Affero ahupowerdns ahutils diff --git a/src/lck-windows.c b/src/lck-windows.c index f750a100..68c93b31 100644 --- a/src/lck-windows.c +++ b/src/lck-windows.c @@ -747,6 +747,7 @@ MDBX_SetFileInformationByHandle mdbx_SetFileInformationByHandle; MDBX_NtFsControlFile mdbx_NtFsControlFile; MDBX_PrefetchVirtualMemory mdbx_PrefetchVirtualMemory; MDBX_GetTickCount64 mdbx_GetTickCount64; +MDBX_RegGetValueA mdbx_RegGetValueA; #if 0 /* LY: unused for now */ MDBX_DiscardVirtualMemory mdbx_DiscardVirtualMemory; MDBX_OfferVirtualMemory mdbx_OfferVirtualMemory; @@ -780,6 +781,9 @@ static void mdbx_winnt_import(void) { GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory); } + const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll"); + GET_PROC_ADDR(hAdvapi32dll, RegGetValueA); + #if 0 /* LY: unused for now */ if (!mdbx_RunningUnderWine()) { GET_PROC_ADDR(hKernel32dll, DiscardVirtualMemory); diff --git a/src/osal.c b/src/osal.c index 9212640f..5c4dd2b6 100644 --- a/src/osal.c +++ b/src/osal.c @@ -1916,22 +1916,33 @@ static uint64_t windows_bootime(void) { return 0; } -static LSTATUS mdbx_RegGetValue(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, - DWORD dwFlags, LPDWORD pdwType, PVOID pvData, - LPDWORD pcbData) { - LSTATUS rc = - RegGetValueA(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); +static LSTATUS mdbx_RegGetValue(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValue, + PVOID pvData, LPDWORD pcbData) { + LSTATUS rc; + if (!mdbx_RegGetValueA) { + /* an old Windows 2000/XP */ + HKEY hSubKey; + rc = RegOpenKeyA(hKey, lpSubKey, &hSubKey); + if (rc == ERROR_SUCCESS) { + rc = RegQueryValueExA(hSubKey, lpValue, NULL, NULL, pvData, pcbData); + RegCloseKey(hSubKey); + } + return rc; + } + + rc = mdbx_RegGetValueA(hKey, lpSubKey, lpValue, RRF_RT_ANY, NULL, pvData, + pcbData); if (rc != ERROR_FILE_NOT_FOUND) return rc; - rc = RegGetValueA(hkey, lpSubKey, lpValue, - dwFlags | 0x00010000 /* RRF_SUBKEY_WOW6464KEY */, pdwType, - pvData, pcbData); + rc = mdbx_RegGetValueA(hKey, lpSubKey, lpValue, + RRF_RT_ANY | 0x00010000 /* RRF_SUBKEY_WOW6464KEY */, + NULL, pvData, pcbData); if (rc != ERROR_FILE_NOT_FOUND) return rc; - return RegGetValueA(hkey, lpSubKey, lpValue, - dwFlags | 0x00020000 /* RRF_SUBKEY_WOW6432KEY */, pdwType, - pvData, pcbData); + return mdbx_RegGetValueA(hKey, lpSubKey, lpValue, + RRF_RT_ANY | 0x00020000 /* RRF_SUBKEY_WOW6432KEY */, + NULL, pvData, pcbData); } #endif @@ -2049,7 +2060,7 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) { DWORD len = sizeof(buf); /* Windows is madness and must die */ if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_MicrosoftCryptography, - "MachineGuid", RRF_RT_ANY, NULL, &buf.MachineGuid, + "MachineGuid", &buf.MachineGuid, &len) == ERROR_SUCCESS && len > 42 && len < sizeof(buf)) got_machineid = bootid_parse_uuid(&bin, &buf.MachineGuid, len); @@ -2067,24 +2078,24 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) { len = sizeof(buf); if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_WindowsNT, - "DigitalProductId", RRF_RT_ANY, NULL, - &buf.DigitalProductId, &len) == ERROR_SUCCESS && + "DigitalProductId", &buf.DigitalProductId, + &len) == ERROR_SUCCESS && len > 42 && len < sizeof(buf)) { bootid_collect(&bin, &buf.DigitalProductId, len); got_machineid = true; } len = sizeof(buf); if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_WindowsNT_DPK, - "DigitalProductId", RRF_RT_ANY, NULL, - &buf.DigitalProductId, &len) == ERROR_SUCCESS && + "DigitalProductId", &buf.DigitalProductId, + &len) == ERROR_SUCCESS && len > 42 && len < sizeof(buf)) { bootid_collect(&bin, &buf.DigitalProductId, len); got_machineid = true; } len = sizeof(buf); if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_WindowsNT_DPK2, - "DigitalProductId", RRF_RT_ANY, NULL, - &buf.DigitalProductId, &len) == ERROR_SUCCESS && + "DigitalProductId", &buf.DigitalProductId, + &len) == ERROR_SUCCESS && len > 42 && len < sizeof(buf)) { bootid_collect(&bin, &buf.DigitalProductId, len); got_machineid = true; @@ -2096,8 +2107,7 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) { "Management\\PrefetchParameters"; len = sizeof(buf); if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BootId", - RRF_RT_DWORD, NULL, &buf.BootId, - &len) == ERROR_SUCCESS && + &buf.BootId, &len) == ERROR_SUCCESS && len > 1 && len < sizeof(buf)) { bootid_collect(&bin, &buf.BootId, len); got_bootseq = true; @@ -2105,8 +2115,7 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) { len = sizeof(buf); if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BaseTime", - RRF_RT_DWORD, NULL, &buf.BaseTime, - &len) == ERROR_SUCCESS && + &buf.BaseTime, &len) == ERROR_SUCCESS && len >= sizeof(buf.BaseTime) && buf.BaseTime) { bootid_collect(&bin, &buf.BaseTime, len); got_boottime = true; diff --git a/src/osal.h b/src/osal.h index 3af23ce0..8fdf9790 100644 --- a/src/osal.h +++ b/src/osal.h @@ -887,6 +887,12 @@ static __inline bool mdbx_RunningUnderWine(void) { return !mdbx_NtExtendSection; } +typedef LSTATUS(WINAPI *MDBX_RegGetValueA)(HKEY hkey, LPCSTR lpSubKey, + LPCSTR lpValue, DWORD dwFlags, + LPDWORD pdwType, PVOID pvData, + LPDWORD pcbData); +MDBX_INTERNAL_VAR MDBX_RegGetValueA mdbx_RegGetValueA; + #endif /* Windows */ /*----------------------------------------------------------------------------*/