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:
parent
97a596e282
commit
a12b0ac1db
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user