8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 23:23:04 +01:00

Make a simpler resource management for Windows registry handles and local memory allocation.

This commit is contained in:
robocop 2007-02-22 09:52:02 +00:00
parent 97a596e282
commit a12b0ac1db

View File

@ -297,8 +297,7 @@ bool isTerminalServicesEnabled()
if (pfnVerSetCondition != NULL) if (pfnVerSetCondition != NULL)
{ {
DWORDLONG dwlCondition = DWORDLONG dwlCondition = (*pfnVerSetCondition) (0, VER_SUITENAME, VER_AND);
(*pfnVerSetCondition) (dwlCondition, VER_SUITENAME, VER_AND);
// Get a VerifyVersionInfo pointer. // Get a VerifyVersionInfo pointer.
HMODULE hmodK32 = GetModuleHandleA( "KERNEL32.DLL" ); HMODULE hmodK32 = GetModuleHandleA( "KERNEL32.DLL" );
@ -333,6 +332,115 @@ bool isTerminalServicesEnabled()
return false; return false;
} }
// This is a very basic registry querying class. Not much validation, but avoids
// leaving the registry open by mistake.
class NTRegQuery
{
public:
NTRegQuery();
~NTRegQuery();
bool OpenForRead(const char* key);
bool ReadValueSize(const char* value);
// Assumes previous call to ReadValueSize.
bool ReadValueData(LPSTR data);
void Close();
DWORD getDataType() const;
DWORD getDataSize() const;
private:
HKEY m_hKey;
DWORD m_dwType;
DWORD m_dwSize;
const char* m_value;
};
inline NTRegQuery::NTRegQuery()
: m_hKey(NULL), m_dwType(0), m_dwSize(0)
{
}
inline NTRegQuery::~NTRegQuery()
{
Close();
}
bool NTRegQuery::OpenForRead(const char* key)
{
return RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &m_hKey) == ERROR_SUCCESS;
}
bool NTRegQuery::ReadValueSize(const char* value)
{
m_value = value;
return RegQueryValueExA(m_hKey, value, NULL, &m_dwType, NULL, &m_dwSize) == ERROR_SUCCESS;
}
bool NTRegQuery::ReadValueData(LPSTR data)
{
return RegQueryValueExA(m_hKey, m_value, NULL, &m_dwType, (LPBYTE) data, &m_dwSize) == ERROR_SUCCESS;
}
void NTRegQuery::Close()
{
if (m_hKey)
RegCloseKey(m_hKey);
m_hKey = NULL;
}
inline DWORD NTRegQuery::getDataType() const
{
return m_dwType;
}
inline DWORD NTRegQuery::getDataSize() const
{
return m_dwSize;
}
// This class represents the local allocation of dynamic memory in Windows.
class NTLocalString
{
public:
explicit NTLocalString(DWORD dwSize);
LPCSTR c_str() const;
LPSTR getString();
bool allocated() const;
~NTLocalString();
private:
LPSTR m_string;
};
NTLocalString::NTLocalString(DWORD dwSize)
{
m_string = (LPSTR) LocalAlloc(LPTR, dwSize);
}
NTLocalString::~NTLocalString()
{
if (m_string)
LocalFree(m_string);
}
inline LPCSTR NTLocalString::c_str() const
{
return m_string;
}
inline LPSTR NTLocalString::getString()
{
return m_string;
}
inline bool NTLocalString::allocated() const
{
return m_string != 0;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// validateProductSuite function // validateProductSuite function
// //
@ -343,38 +451,33 @@ bool isTerminalServicesEnabled()
bool validateProductSuite (LPCSTR lpszSuiteToValidate) bool validateProductSuite (LPCSTR lpszSuiteToValidate)
{ {
bool fValidated = false; NTRegQuery query;
HKEY hKey = NULL;
DWORD dwType = 0;
DWORD dwSize = 0;
LPSTR lpszProductSuites = 0;
LPCSTR lpszSuite = 0;
// Open the ProductOptions key. // Open the ProductOptions key.
LONG lResult = RegOpenKeyExA(HKEY_LOCAL_MACHINE, if (!query.OpenForRead("System\\CurrentControlSet\\Control\\ProductOptions"))
"System\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey); return false;
if (lResult != ERROR_SUCCESS)
goto exit;
// Determine required size of ProductSuite buffer. // Determine required size of ProductSuite buffer.
lResult = RegQueryValueExA(hKey, "ProductSuite", NULL, &dwType, NULL, &dwSize); // If we get size == 1 it means multi string data with only a terminator.
if (lResult != ERROR_SUCCESS || !dwSize) if (!query.ReadValueSize("ProductSuite") || query.getDataSize() < 2)
goto exit; return false;
// Allocate buffer. // Allocate buffer.
lpszProductSuites = (LPSTR) LocalAlloc(LPTR, dwSize); NTLocalString lpszProductSuites(query.getDataSize());
if (!lpszProductSuites) if (!lpszProductSuites.allocated())
goto exit; return false;
// Retrieve array of product suite strings. // Retrieve array of product suite strings.
lResult = RegQueryValueExA(hKey, "ProductSuite", NULL, &dwType, if (!query.ReadValueData(lpszProductSuites.getString()) || query.getDataType() != REG_MULTI_SZ)
(LPBYTE) lpszProductSuites, &dwSize); return false;
if (lResult != ERROR_SUCCESS || dwType != REG_MULTI_SZ)
goto exit;
query.Close(); // explicit but redundant.
// Search for suite name in array of strings. // Search for suite name in array of strings.
lpszSuite = lpszProductSuites; bool fValidated = false;
while (*lpszSuite) LPCSTR lpszSuite = lpszProductSuites.c_str();
LPCSTR end = lpszSuite + query.getDataSize(); // paranoid check
while (*lpszSuite && lpszSuite < end)
{ {
if (lstrcmpA(lpszSuite, lpszSuiteToValidate) == 0) if (lstrcmpA(lpszSuite, lpszSuiteToValidate) == 0)
{ {
@ -384,15 +487,6 @@ bool validateProductSuite (LPCSTR lpszSuiteToValidate)
lpszSuite += (lstrlenA(lpszSuite) + 1); lpszSuite += (lstrlenA(lpszSuite) + 1);
} }
exit:
if (lpszProductSuites) {
LocalFree(lpszProductSuites);
}
if (hKey) {
RegCloseKey(hKey);
}
return fValidated; return fValidated;
} }