Correct reading debug variables on Windows

Read value from env when cannot read value from registry

Change-Id: I6691c1b662265313d8cd57f57be7777acd878bd1
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2020-03-19 20:51:30 +01:00
committed by sys_ocldev
parent 80b5cacac5
commit 67d5c28bb1
4 changed files with 145 additions and 30 deletions

View File

@ -7,12 +7,23 @@
#include "shared/source/os_interface/windows/windows_wrapper.h"
uint32_t regOpenKeySuccessCount = 0u;
uint32_t regQueryValueSuccessCount = 0u;
const HKEY validHkey = reinterpret_cast<HKEY>(0);
LSTATUS APIENTRY RegOpenKeyExA(
HKEY hKey,
LPCSTR lpSubKey,
DWORD ulOptions,
REGSAM samDesired,
PHKEY phkResult) {
if (regOpenKeySuccessCount > 0) {
regOpenKeySuccessCount--;
if (phkResult) {
*phkResult = validHkey;
}
return ERROR_SUCCESS;
}
return ERROR_FILE_NOT_FOUND;
};
@ -23,5 +34,30 @@ LSTATUS APIENTRY RegQueryValueExA(
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData) {
if (hKey == validHkey && regQueryValueSuccessCount > 0) {
regQueryValueSuccessCount--;
if (lpcbData) {
if (strcmp(lpValueName, "settingSourceString") == 0) {
const auto settingSource = "registry";
if (lpData) {
strcpy(reinterpret_cast<char *>(lpData), settingSource);
} else {
*lpcbData = static_cast<DWORD>(strlen(settingSource) + 1u);
if (lpType) {
*lpType = REG_SZ;
}
}
} else if (strcmp(lpValueName, "settingSourceInt") == 0) {
if (lpData) {
*reinterpret_cast<DWORD *>(lpData) = 1;
} else {
*lpcbData = sizeof(DWORD);
}
}
}
return ERROR_SUCCESS;
}
return ERROR_FILE_NOT_FOUND;
};

View File

@ -7,12 +7,16 @@
#include "opencl/test/unit_test/os_interface/windows/registry_reader_tests.h"
#include "opencl/test/unit_test/helpers/variable_backup.h"
#include "test.h"
using namespace NEO;
using RegistryReaderTest = ::testing::Test;
extern uint32_t regOpenKeySuccessCount;
extern uint32_t regQueryValueSuccessCount;
TEST_F(RegistryReaderTest, givenRegistryReaderWhenItIsCreatedWithUserScopeSetToFalseThenItsHkeyTypeIsInitializedToHkeyLocalMachine) {
bool userScope = false;
TestedRegistryReader registryReader(userScope);
@ -61,3 +65,59 @@ TEST_F(RegistryReaderTest, givenRegistryReaderWhenEnvironmentIntVariableExistsTh
TestedRegistryReader registryReader("");
EXPECT_EQ(1234, registryReader.getSetting(envVar, value));
}
struct DebugReaderWithRegistryAndEnvTest : ::testing::Test {
VariableBackup<uint32_t> openRegCountBackup{&regOpenKeySuccessCount};
VariableBackup<uint32_t> queryRegCountBackup{&regQueryValueSuccessCount};
TestedRegistryReader registryReader{""};
};
TEST_F(DebugReaderWithRegistryAndEnvTest, givenIntDebugKeyWhenReadFromRegistrySucceedsThenReturnObtainedValue) {
regOpenKeySuccessCount = 1u;
regQueryValueSuccessCount = 1u;
EXPECT_EQ(1, registryReader.getSetting("settingSourceInt", 0));
}
TEST_F(DebugReaderWithRegistryAndEnvTest, givenIntDebugKeyWhenQueryValueFailsThenObtainValueFromEnv) {
regOpenKeySuccessCount = 1u;
regQueryValueSuccessCount = 0u;
EXPECT_EQ(2, registryReader.getSetting("settingSourceInt", 0));
}
TEST_F(DebugReaderWithRegistryAndEnvTest, givenIntDebugKeyWhenOpenKeyFailsThenObtainValueFromEnv) {
regOpenKeySuccessCount = 0u;
regQueryValueSuccessCount = 0u;
EXPECT_EQ(2, registryReader.getSetting("settingSourceInt", 0));
}
TEST_F(DebugReaderWithRegistryAndEnvTest, givenStringDebugKeyWhenReadFromRegistrySucceedsThenReturnObtainedValue) {
std::string defaultValue("default");
regOpenKeySuccessCount = 1u;
regQueryValueSuccessCount = 2u;
EXPECT_STREQ("registry", registryReader.getSetting("settingSourceString", defaultValue).c_str());
}
TEST_F(DebugReaderWithRegistryAndEnvTest, givenStringDebugKeyWhenQueryValueFailsThenObtainValueFromEnv) {
std::string defaultValue("default");
regOpenKeySuccessCount = 1u;
regQueryValueSuccessCount = 0u;
EXPECT_STREQ("environment", registryReader.getSetting("settingSourceString", defaultValue).c_str());
regOpenKeySuccessCount = 1u;
regQueryValueSuccessCount = 1u;
EXPECT_STREQ("environment", registryReader.getSetting("settingSourceString", defaultValue).c_str());
}
TEST_F(DebugReaderWithRegistryAndEnvTest, givenStringDebugKeyWhenOpenKeyFailsThenObtainValueFromEnv) {
std::string defaultValue("default");
regOpenKeySuccessCount = 0u;
regQueryValueSuccessCount = 0u;
EXPECT_STREQ("environment", registryReader.getSetting("settingSourceString", defaultValue).c_str());
}

View File

@ -24,6 +24,10 @@ class TestedRegistryReader : public RegistryReader {
return "TestedEnvironmentVariableValue";
} else if (strcmp(envVar, "TestedEnvironmentIntVariable") == 0) {
return "1234";
} else if (strcmp(envVar, "settingSourceString") == 0) {
return "environment";
} else if (strcmp(envVar, "settingSourceInt") == 0) {
return "2";
} else {
return nullptr;
}

View File

@ -43,9 +43,10 @@ bool RegistryReader::getSetting(const char *settingName, bool defaultValue) {
}
int32_t RegistryReader::getSetting(const char *settingName, int32_t defaultValue) {
HKEY Key;
HKEY Key{};
DWORD value = defaultValue;
DWORD success = ERROR_SUCCESS;
bool readSettingFromEnv = true;
success = RegOpenKeyExA(hkeyType,
registryReadRootKey.c_str(),
@ -55,17 +56,22 @@ int32_t RegistryReader::getSetting(const char *settingName, int32_t defaultValue
if (ERROR_SUCCESS == success) {
DWORD regType;
DWORD size = sizeof(ULONG);
DWORD size = sizeof(DWORD);
DWORD regData;
success = RegQueryValueExA(Key,
settingName,
NULL,
&regType,
(LPBYTE)&value,
reinterpret_cast<LPBYTE>(&regData),
&size);
if (ERROR_SUCCESS == success) {
value = regData;
readSettingFromEnv = false;
}
RegCloseKey(Key);
value = ERROR_SUCCESS == success ? value : defaultValue;
} else { // Check environment variables
}
if (readSettingFromEnv) {
const char *envValue = getenv(settingName);
if (envValue) {
value = atoi(envValue);
@ -76,9 +82,10 @@ int32_t RegistryReader::getSetting(const char *settingName, int32_t defaultValue
}
std::string RegistryReader::getSetting(const char *settingName, const std::string &value) {
HKEY Key;
HKEY Key{};
DWORD success = ERROR_SUCCESS;
std::string keyValue = value;
bool readSettingFromEnv = true;
success = RegOpenKeyExA(hkeyType,
registryReadRootKey.c_str(),
@ -95,35 +102,43 @@ std::string RegistryReader::getSetting(const char *settingName, const std::strin
&regType,
NULL,
&regSize);
if (success == ERROR_SUCCESS && regType == REG_SZ) {
char *regData = new char[regSize];
success = RegQueryValueExA(Key,
settingName,
NULL,
&regType,
(LPBYTE)regData,
&regSize);
keyValue.assign(regData);
delete[] regData;
} else if (success == ERROR_SUCCESS && regType == REG_BINARY) {
std::unique_ptr<wchar_t[]> regData(new wchar_t[regSize]);
success = RegQueryValueExA(Key,
settingName,
NULL,
&regType,
(LPBYTE)regData.get(),
&regSize);
if (ERROR_SUCCESS == success) {
if (regType == REG_SZ) {
auto regData = std::make_unique<char[]>(regSize);
success = RegQueryValueExA(Key,
settingName,
NULL,
&regType,
reinterpret_cast<LPBYTE>(regData.get()),
&regSize);
if (success == ERROR_SUCCESS) {
keyValue.assign(regData.get());
readSettingFromEnv = false;
}
} else if (regType == REG_BINARY) {
auto regData = std::make_unique<wchar_t[]>(regSize);
success = RegQueryValueExA(Key,
settingName,
NULL,
&regType,
reinterpret_cast<LPBYTE>(regData.get()),
&regSize);
size_t charsConverted = 0;
std::unique_ptr<char[]> convertedData(new char[regSize]);
if (ERROR_SUCCESS == success) {
size_t charsConverted = 0;
auto convertedData = std::make_unique<char[]>(regSize);
wcstombs_s(&charsConverted, convertedData.get(), regSize, regData.get(), regSize);
wcstombs_s(&charsConverted, convertedData.get(), regSize, regData.get(), regSize);
keyValue.assign(convertedData.get());
keyValue.assign(convertedData.get());
readSettingFromEnv = false;
}
}
}
RegCloseKey(Key);
} else { // Check environment variables
}
if (readSettingFromEnv) {
const char *envValue = getenv(settingName);
if (envValue) {
keyValue.assign(envValue);