mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 06:05:49 -06:00
377 lines
8.3 KiB
C++
377 lines
8.3 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
// RCS-ID:
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// registry.cpp - Windows Registry Reader for both 32 and 64 mode
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#include "pgAdmin3.h"
|
|
|
|
#include "utils/registry.h"
|
|
|
|
#ifdef __WXMSW__
|
|
|
|
#define RESERVED 0
|
|
#define PGREG_SEPERATOR wxT("\\")
|
|
|
|
static struct stdkey
|
|
{
|
|
HKEY key;
|
|
wxString name;
|
|
}
|
|
aStdHKeys[] =
|
|
{
|
|
{HKEY_CLASSES_ROOT, wxT("HKEY_CLASSES_ROOT")},
|
|
{HKEY_CURRENT_USER, wxT("HKEY_CURRENT_USER")},
|
|
{HKEY_LOCAL_MACHINE, wxT("HKEY_LOCAL_MACHINE") },
|
|
{HKEY_USERS, wxT("HKEY_USERS")},
|
|
{HKEY_CURRENT_CONFIG, wxT("HKEY_CURRENT_CONFIG")}
|
|
};
|
|
|
|
#define NOS_STD_KEYS (size_t)(sizeof(aStdHKeys)/sizeof(stdkey))
|
|
|
|
pgRegKey::pgRegKey(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode)
|
|
{
|
|
Init(root, subkey, wowMode, accessMode);
|
|
}
|
|
|
|
pgRegKey::pgRegKey(const pgRegKey &parent, const wxString &key)
|
|
{
|
|
wxString strKey;
|
|
strKey << parent.m_strName << PGREG_SEPERATOR << key;
|
|
|
|
Init(parent.m_hRoot, strKey, PGREG_WOW_DEFAULT, parent.m_accessMode);
|
|
m_wowMode = parent.m_wowMode;
|
|
}
|
|
|
|
void pgRegKey::Init(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode)
|
|
{
|
|
m_hRoot = root;
|
|
m_strName = subkey;
|
|
m_accessMode = accessMode;
|
|
m_hKey = NULL;
|
|
#ifdef __WIN64__
|
|
m_wowMode = KEY_WOW64_64KEY;
|
|
#else
|
|
m_wowMode = KEY_WOW64_32KEY;
|
|
#endif
|
|
|
|
switch (wowMode)
|
|
{
|
|
case PGREG_WOW32:
|
|
#ifdef __WIN64__
|
|
m_wowMode = KEY_WOW64_32KEY;
|
|
#endif // __WIN64__
|
|
break;
|
|
|
|
case PGREG_WOW64:
|
|
#ifndef __WIN64__
|
|
// we can only access 64 bit registry under 64 bit platforms
|
|
if (::wxIsPlatform64Bit())
|
|
m_wowMode = KEY_WOW64_64KEY;
|
|
#endif // !__WIN64__
|
|
break;
|
|
}
|
|
}
|
|
|
|
pgRegKey *pgRegKey::OpenRegKey(HKEY root, const wxString &subkey, PGREGACCESSMODE accessmode, PGREGWOWMODE wowMode)
|
|
{
|
|
wxString strKey = subkey;
|
|
|
|
!subkey.IsEmpty() && subkey.EndsWith(wxT("\\"), &strKey);
|
|
pgRegKey *tmpKey = new pgRegKey(root, strKey, wowMode, accessmode);
|
|
|
|
HKEY tmpRegKey = 0;
|
|
long nError = ::RegOpenKeyEx(root, (LPCTSTR)strKey, RESERVED,
|
|
(accessmode == PGREG_READ ? KEY_READ : KEY_ALL_ACCESS) | tmpKey->m_wowMode,
|
|
&tmpRegKey);
|
|
|
|
if (nError != ERROR_SUCCESS)
|
|
{
|
|
delete(tmpKey);
|
|
tmpKey = NULL;
|
|
}
|
|
else
|
|
tmpKey->m_hKey = tmpRegKey;
|
|
|
|
return tmpKey;
|
|
}
|
|
|
|
void pgRegKey::Close()
|
|
{
|
|
if (m_hKey)
|
|
{
|
|
::RegCloseKey(m_hKey);
|
|
m_hKey = NULL;
|
|
}
|
|
}
|
|
|
|
pgRegKey::~pgRegKey()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
bool pgRegKey::KeyExists(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode)
|
|
{
|
|
if (subkey.IsEmpty())
|
|
return true;
|
|
|
|
#ifdef __WIN64__
|
|
long keyWowMode = KEY_WOW64_64KEY;
|
|
#else
|
|
long keyWowMode = KEY_WOW64_32KEY;
|
|
#endif
|
|
|
|
switch (wowMode)
|
|
{
|
|
case PGREG_WOW32:
|
|
#ifdef __WIN64__
|
|
keyWowMode = KEY_WOW64_32KEY;
|
|
#endif // __WIN64__
|
|
break;
|
|
|
|
case PGREG_WOW64:
|
|
#ifndef __WIN64__
|
|
// we can only access 64 bit registry under 64 bit platforms
|
|
if (::wxIsPlatform64Bit())
|
|
keyWowMode = KEY_WOW64_64KEY;
|
|
#endif // ! __WIN64__
|
|
break;
|
|
}
|
|
|
|
HKEY hkeyDummy;
|
|
if (::RegOpenKeyEx(root, (LPCTSTR)subkey, RESERVED, KEY_READ | keyWowMode, &hkeyDummy) == ERROR_SUCCESS)
|
|
{
|
|
::RegCloseKey(hkeyDummy);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool pgRegKey::GetKeyInfo(size_t *pnSubKeys, size_t *pnMaxKeyLen, size_t *pnValues, size_t *pnMaxValueLen) const
|
|
{
|
|
|
|
long nError = ::RegQueryInfoKey(m_hKey, NULL, NULL, RESERVED, (LPDWORD)pnSubKeys, (LPDWORD)pnMaxKeyLen, NULL,
|
|
(LPDWORD)pnValues, (LPDWORD)pnMaxValueLen, NULL, NULL, NULL);
|
|
|
|
if (nError != ERROR_SUCCESS)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
wxString pgRegKey::ToString() const
|
|
{
|
|
wxString str;
|
|
size_t index = 0;
|
|
for (; index < NOS_STD_KEYS; index++)
|
|
{
|
|
if (m_hRoot == aStdHKeys[index].key)
|
|
{
|
|
str = aStdHKeys[index].name;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!m_strName.IsEmpty())
|
|
str << wxT("\\") << m_strName;
|
|
|
|
return str;
|
|
}
|
|
|
|
wxString pgRegKey::GetKeyName() const
|
|
{
|
|
if (!m_strName.IsEmpty())
|
|
{
|
|
int index = m_strName.Find(wxT('\\'), true);
|
|
return m_strName.SubString(index + 1, m_strName.Len());
|
|
}
|
|
return wxEmptyString;
|
|
}
|
|
|
|
bool pgRegKey::QueryValue(const wxString &strkey, LPDWORD pVal) const
|
|
{
|
|
if (strkey.IsEmpty())
|
|
return false;
|
|
|
|
DWORD dwType, dwSize = sizeof(DWORD);
|
|
unsigned char *pBuf = (unsigned char *)pVal;
|
|
|
|
long nError = ::RegQueryValueEx(m_hKey, (LPCTSTR)strkey, RESERVED, &dwType, pBuf, &dwSize);
|
|
|
|
if (nError != ERROR_SUCCESS)
|
|
return false;
|
|
|
|
if (dwType != REG_DWORD && dwType != REG_DWORD_BIG_ENDIAN)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool pgRegKey::QueryValue(const wxString &strVal, wxString &sVal) const
|
|
{
|
|
DWORD dwType, dwSize;
|
|
|
|
long nError = RegQueryValueEx(m_hKey, (LPCTSTR)strVal, RESERVED, &dwType, NULL, &dwSize);
|
|
|
|
if (nError == ERROR_SUCCESS)
|
|
{
|
|
sVal = wxT("");
|
|
if (dwSize == 0)
|
|
return true;
|
|
|
|
wxChar *pBuf = (wxChar *)calloc(dwSize, sizeof(wxChar));
|
|
nError = ::RegQueryValueEx(m_hKey, (LPCTSTR)strVal, RESERVED, &dwType, (LPBYTE)pBuf, &dwSize);
|
|
|
|
DWORD index = 0;
|
|
if (dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ)
|
|
{
|
|
wxChar *actualValueStr = (wxChar *)calloc(dwSize, sizeof(wxChar));
|
|
memcpy(actualValueStr, pBuf, dwSize * sizeof(wxChar));
|
|
|
|
wxChar *curr_line;
|
|
sVal = wxT("");
|
|
do
|
|
{
|
|
DWORD dwExpSize = ::ExpandEnvironmentStrings((actualValueStr + index), NULL, 0);
|
|
curr_line = (wxChar *)calloc(dwExpSize, sizeof(wxChar));
|
|
|
|
::ExpandEnvironmentStrings(actualValueStr + index, curr_line, dwExpSize);
|
|
|
|
if (index != 0)
|
|
sVal << wxT("\n\r") << curr_line;
|
|
else
|
|
sVal << curr_line;
|
|
index += (DWORD)wxStrlen(actualValueStr + index) + 1;
|
|
free(curr_line);
|
|
}
|
|
while (actualValueStr[index] && dwType == REG_MULTI_SZ);
|
|
|
|
free(actualValueStr);
|
|
}
|
|
else
|
|
sVal = pBuf;
|
|
|
|
free(pBuf);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool pgRegKey::QueryValue(const wxString &strVal, LPBYTE &pVal, DWORD &len) const
|
|
{
|
|
DWORD dwType;
|
|
if(RegQueryValueEx(m_hKey, (LPCTSTR)strVal,
|
|
RESERVED, &dwType, pVal, &len) == ERROR_SUCCESS)
|
|
return true;
|
|
len = 0;
|
|
return false;
|
|
}
|
|
|
|
bool pgRegKey::GetFirstValue(wxString &strkey, long &lIndex) const
|
|
{
|
|
lIndex = 0;
|
|
return GetNextValue(strkey, lIndex);
|
|
}
|
|
|
|
bool pgRegKey::GetNextValue(wxString &strval, long &lIndex) const
|
|
{
|
|
if (lIndex < 0)
|
|
return false;
|
|
|
|
TCHAR szVal[1024];
|
|
DWORD dwValLen = 1024;
|
|
|
|
long nError = RegEnumValue(m_hKey, lIndex, szVal, &dwValLen, RESERVED, NULL, NULL, NULL);
|
|
|
|
if (nError != ERROR_SUCCESS)
|
|
{
|
|
if (nError == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
nError = ERROR_SUCCESS;
|
|
lIndex = -1;
|
|
}
|
|
return false;
|
|
}
|
|
strval = szVal;
|
|
lIndex++;
|
|
return true;
|
|
}
|
|
|
|
bool pgRegKey::HasValue(const wxString &strval)
|
|
{
|
|
long nRetVal = ::RegQueryValueEx(m_hKey, (LPCTSTR)strval, RESERVED, NULL, NULL, NULL);
|
|
|
|
return nRetVal == ERROR_SUCCESS;
|
|
}
|
|
|
|
bool pgRegKey::GetFirstKey(pgRegKey *&pkey, long &lIndex) const
|
|
{
|
|
lIndex = 0;
|
|
return GetNextKey(pkey, lIndex);
|
|
}
|
|
|
|
bool pgRegKey::GetNextKey(pgRegKey *&pKey, long &lIndex) const
|
|
{
|
|
pKey = NULL;
|
|
|
|
if (lIndex < 0)
|
|
return false;
|
|
|
|
TCHAR szKey[1024];
|
|
DWORD dwKeyLen = 1023;
|
|
long nError = ::RegEnumKeyEx(m_hKey, lIndex, szKey, &dwKeyLen, NULL, NULL, NULL, NULL);
|
|
|
|
if (nError != ERROR_SUCCESS)
|
|
{
|
|
lIndex = -1;
|
|
return false;
|
|
}
|
|
lIndex++;
|
|
wxString strSubKey = m_strName;
|
|
strSubKey << wxT("\\") << szKey;
|
|
|
|
pgRegKey *tmpKey = new pgRegKey(m_hRoot, (LPCTSTR)strSubKey, PGREG_WOW_DEFAULT, m_accessMode);
|
|
tmpKey->m_wowMode = m_wowMode;
|
|
|
|
HKEY tmpRegKey = 0;
|
|
nError
|
|
= ::RegOpenKeyEx(m_hRoot, (LPCTSTR)strSubKey, RESERVED, (m_accessMode == PGREG_READ ? KEY_READ : KEY_ALL_ACCESS) | m_wowMode, &tmpRegKey);
|
|
|
|
if (nError != ERROR_SUCCESS)
|
|
{
|
|
delete(tmpKey);
|
|
tmpKey = NULL;
|
|
pKey = NULL;
|
|
|
|
return false;
|
|
}
|
|
else
|
|
tmpKey->m_hKey = tmpRegKey;
|
|
|
|
pKey = tmpKey;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool pgRegKey::HasKey(const wxString &strKey) const
|
|
{
|
|
wxString strSubKey = m_strName;
|
|
strSubKey << wxT("\\") << strKey;
|
|
|
|
return pgRegKey::KeyExists(m_hRoot, strSubKey, m_wowMode == KEY_WOW64_64KEY ? PGREG_WOW64 : PGREG_WOW32) ;
|
|
}
|
|
|
|
DWORD pgRegKey::GetValueType(const wxString &key) const
|
|
{
|
|
DWORD dwType;
|
|
long nError = RegQueryValueEx((HKEY) m_hKey, (LPCTSTR)key, RESERVED,
|
|
&dwType, NULL, NULL);
|
|
|
|
if (nError != ERROR_SUCCESS)
|
|
return REG_NONE;
|
|
return dwType;
|
|
}
|
|
|
|
#endif // __WXMSW__
|