/** @file RegistryUtil.cpp @created 2006-04-06 @edited 2006-04-24 Copyright 2000-2006, Morgan McGuire. All rights reserved. */ #include "G3D/platform.h" // This file is only used on Windows #ifdef G3D_WINDOWS #include "G3D/RegistryUtil.h" #include "G3D/System.h" #ifdef __MINGW32__ # ifndef HKEY_PERFORMANCE_TEXT # define HKEY_PERFORMANCE_TEXT ((HKEY)((LONG)0x80000050)) # endif # ifndef HKEY_PERFORMANCE_NLSTEXT # define HKEY_PERFORMANCE_NLSTEXT ((HKEY)((LONG)0x80000060)) # endif #endif namespace G3D { // static helpers static HKEY getRootKeyFromString(const char* str, size_t length); bool RegistryUtil::keyExists(const std::string& key) { size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if (hkey == NULL) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { RegCloseKey(openKey); return true; } else { return false; } } bool RegistryUtil::valueExists(const std::string& key, const std::string& value) { size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if ( hkey == NULL ) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { uint32 dataSize = 0; result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast(&dataSize)); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); RegCloseKey(openKey); } return (result == ERROR_SUCCESS); } bool RegistryUtil::readInt32(const std::string& key, const std::string& value, int32& data) { size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if ( hkey == NULL ) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { uint32 dataSize = sizeof(int32); result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast(&data), reinterpret_cast(&dataSize)); debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value."); RegCloseKey(openKey); } return (result == ERROR_SUCCESS); } bool RegistryUtil::readBytes(const std::string& key, const std::string& value, uint8* data, uint32& dataSize) { size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if (hkey == NULL) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { if (data == NULL) { result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast(&dataSize)); } else { result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast(&data), reinterpret_cast(&dataSize)); } debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value."); RegCloseKey(openKey); } return (result == ERROR_SUCCESS); } bool RegistryUtil::readString(const std::string& key, const std::string& value, std::string& data) { size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if (hkey == NULL) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { uint32 dataSize = 0; result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast(&dataSize)); debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value."); // increment datasize to allow for non null-terminated strings in registry dataSize += 1; if (result == ERROR_SUCCESS) { char* tmpStr = static_cast(System::malloc(dataSize)); System::memset(tmpStr, 0, dataSize); result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast(tmpStr), reinterpret_cast(&dataSize)); debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value."); if (result == ERROR_SUCCESS) { data = tmpStr; } RegCloseKey(openKey); System::free(tmpStr); } } return (result == ERROR_SUCCESS); } bool RegistryUtil::writeInt32(const std::string& key, const std::string& value, int32 data) { size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if (hkey == NULL) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { result = RegSetValueExA(openKey, value.c_str(), 0, REG_DWORD, reinterpret_cast(&data), sizeof(int32)); debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value."); RegCloseKey(openKey); } return (result == ERROR_SUCCESS); } bool RegistryUtil::writeBytes(const std::string& key, const std::string& value, const uint8* data, uint32 dataSize) { debugAssert(data); size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if (hkey == NULL) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { if (data) { result = RegSetValueExA(openKey, value.c_str(), 0, REG_BINARY, reinterpret_cast(data), dataSize); } debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value."); RegCloseKey(openKey); } return (result == ERROR_SUCCESS); } bool RegistryUtil::writeString(const std::string& key, const std::string& value, const std::string& data) { size_t pos = key.find('\\', 0); if (pos == std::string::npos) { return false; } HKEY hkey = getRootKeyFromString(key.c_str(), pos); if (hkey == NULL) { return false; } HKEY openKey; int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey); debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); if (result == ERROR_SUCCESS) { alwaysAssertM(data.size() < 0xFFFFFFFE, "String too long"); result = RegSetValueExA(openKey, value.c_str(), 0, REG_SZ, reinterpret_cast(data.c_str()), (int)(data.size() + 1)); debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value."); RegCloseKey(openKey); } return (result == ERROR_SUCCESS); } // static helpers static HKEY getRootKeyFromString(const char* str, size_t length) { debugAssert(str); if (str) { if ( strncmp(str, "HKEY_CLASSES_ROOT", length) == 0 ) { return HKEY_CLASSES_ROOT; } else if ( strncmp(str, "HKEY_CURRENT_CONFIG", length) == 0 ) { return HKEY_CURRENT_CONFIG; } else if ( strncmp(str, "HKEY_CURRENT_USER", length) == 0 ) { return HKEY_CURRENT_USER; } else if ( strncmp(str, "HKEY_LOCAL_MACHINE", length) == 0 ) { return HKEY_LOCAL_MACHINE; } else if ( strncmp(str, "HKEY_PERFORMANCE_DATA", length) == 0 ) { return HKEY_PERFORMANCE_DATA; } else if ( strncmp(str, "HKEY_PERFORMANCE_NLSTEXT", length) == 0 ) { return HKEY_PERFORMANCE_NLSTEXT; } else if ( strncmp(str, "HKEY_PERFORMANCE_TEXT", length) == 0 ) { return HKEY_PERFORMANCE_TEXT; } else if ( strncmp(str, "HKEY_CLASSES_ROOT", length) == 0 ) { return HKEY_CLASSES_ROOT; } else { return NULL; } } else { return NULL; } } } // namespace G3D #endif // G3D_WINDOWS