-/* $Id: RegistryKey.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $
+/* $Id: RegistryKey.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $
*
* regexpl - Console Registry Explorer
*
#include "ph.h"
#include "RegistryKey.h"
+static TCHAR *g_ppszHiveNames[] =
+{
+ _T("HKEY_CLASSES_ROOT"),
+ _T("HKEY_CURRENT_USER"),
+ _T("HKEY_LOCAL_MACHINE"),
+ _T("HKEY_USERS"),
+ _T("HKEY_PERFORMANCE_DATA"),
+ _T("HKEY_CURRENT_CONFIG"),
+ _T("HKEY_DYN_DATA")
+};
+
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CRegistryKey::CRegistryKey(const TCHAR *pchKeyName, class CRegistryKey *pParent)
-{
-// RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
-// &m_dwValueNameBufferSize,&m_dwMaxValueSize,&m_dwSecurityDescriptorSize,&m_ftLastWriteTime);
-// m_pchValueName = NULL;
- ASSERT(pParent != NULL);
- m_pParent = pParent;
- m_pChild = NULL;
- m_hKey = NULL; // Open key with Open() member function
- ASSERT(pchKeyName != NULL);
- m_pchKeyName[MAX_PATH] = 0;
- *m_pszMachineName = 0;
- if (*pchKeyName == _T('\"'))
- {
- _tcsncpy(m_pchKeyName,pchKeyName+1,MAX_PATH);
- TCHAR *pch = _tcschr(m_pchKeyName,_T('\"'));
- if (pch)
- {
- *pch = 0;
- }
- else
- {
- ASSERT(FALSE);
- }
- }
- else
- {
- _tcsncpy(m_pchKeyName,pchKeyName,MAX_PATH);
- }
-}
-
-CRegistryKey::~CRegistryKey()
-{
-// if (m_pchValueName) delete [] m_pchValueName;
- if((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&&
- (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS)
- &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG)
- &&(m_hKey != HKEY_DYN_DATA)&&(m_hKey != NULL))
- {
- RegCloseKey(m_hKey);
- }
-}
+CRegistryKey::CRegistryKey()
+{
+ m_pszKeyName = NULL;
+ m_pszMachineName = NULL;
+ m_CurrentAccess = 0;
+ m_hKey = NULL;
+}
+
+HRESULT CRegistryKey::InitRoot(const TCHAR *pszMachineName = NULL)
+{
+ if ((pszMachineName)&&
+ ((_tcslen(pszMachineName) < 3)||
+ (pszMachineName[0] != _T('\\'))||
+ (pszMachineName[1] != _T('\\'))
+ )
+ )
+ {
+ return E_INVALIDARG;
+ }
+
+ HRESULT hr = Uninit();
+ if (FAILED(hr))
+ return hr;
+
+ if (pszMachineName)
+ { // copy machine name
+ size_t size = _tcslen(pszMachineName);
+
+ m_pszMachineName = new TCHAR [size+2];
+ if (!m_pszMachineName)
+ return E_OUTOFMEMORY;
+ _tcscpy(m_pszMachineName,pszMachineName);
+ m_pszMachineName[size] = _T('\\');
+ m_pszMachineName[size+1] = 0;
+ }
+ else
+ {
+ m_pszMachineName = NULL; // local registry
+ }
+
+ ASSERT(m_pszKeyName == NULL);
+ m_CurrentAccess = 0;
+ ASSERT(m_hKey == NULL);
+
+ return S_OK;
+}
+
+HRESULT CRegistryKey::Init(HKEY hKey, const TCHAR *pszPath, const TCHAR *pszKeyName, REGSAM CurrentAccess)
+{
+ HRESULT hr = Uninit();
+ if (FAILED(hr))
+ return hr;
+
+ if (!pszKeyName || !hKey)
+ return E_INVALIDARG;
+
+ // copy key name name
+ size_t size = _tcslen(pszKeyName);
+ if (pszPath)
+ size += _tcslen(pszPath);
+
+ m_pszKeyName = new TCHAR [size+2];
+ if (!m_pszKeyName)
+ return E_OUTOFMEMORY;
+ _stprintf(m_pszKeyName,_T("%s%s\\"),pszPath?pszPath:_T(""),pszKeyName);
+
+ m_CurrentAccess = CurrentAccess;
+ m_hKey = hKey;
+ ASSERT(m_hKey);
-TCHAR * CRegistryKey::GetKeyName()
-{
- return m_pchKeyName;
+ return S_OK;
}
-class CRegistryKey * CRegistryKey::GetChild()
+HRESULT CRegistryKey::Uninit()
{
- return m_pChild;
-}
+ if (m_pszKeyName)
+ {
+ delete [] m_pszKeyName;
+ m_pszKeyName = NULL;
+ }
-CRegistryKey * CRegistryKey::GetParent()
-{
- return m_pParent;
-}
+ if (m_pszMachineName)
+ {
+ delete [] m_pszMachineName;
+ m_pszMachineName = NULL;
+ }
-CRegistryKey * CRegistryKey::UpOneLevel()
-{
- CRegistryKey *pParent = m_pParent;
- ASSERT(m_pChild == NULL);
- if (pParent)
- {
- ASSERT(pParent->m_pChild == this);
- pParent->m_pChild = NULL;
- }
- delete this;
- return pParent;
+ LONG nError = ERROR_SUCCESS;
+ if((m_hKey != NULL)&&(!IsHive(m_hKey)))
+ nError = RegCloseKey(m_hKey);
+
+ m_hKey = NULL;
+
+ return (nError == ERROR_SUCCESS)?S_OK:E_FAIL;
}
-void CRegistryKey::InitSubKeyEnumeration()
+BOOL CRegistryKey::IsHive(HKEY hKey)
{
- m_dwCurrentSubKeyIndex = 0;
+ return ((hKey == HKEY_CLASSES_ROOT)||
+ (hKey == HKEY_CURRENT_USER)||
+ (hKey == HKEY_LOCAL_MACHINE)||
+ (hKey == HKEY_USERS)||
+ (hKey == HKEY_PERFORMANCE_DATA)||
+ (hKey == HKEY_CURRENT_CONFIG)||
+ (hKey == HKEY_DYN_DATA));
}
-TCHAR * CRegistryKey::GetSubKeyName(DWORD& dwError)
+CRegistryKey::~CRegistryKey()
{
- static TCHAR m_pchSubName[MAX_PATH+1];
- dwError = RegEnumKey(m_hKey,m_dwCurrentSubKeyIndex,m_pchSubName,MAX_PATH + 1);
+ Uninit();
+}
+
+const TCHAR * CRegistryKey::GetKeyName()
+{
+ return m_pszKeyName?m_pszKeyName:(m_pszMachineName?m_pszMachineName:_T("\\"));
+}
+
+BOOL CRegistryKey::IsRoot()
+{
+ return m_hKey == NULL;
+}
+
+LONG CRegistryKey::OpenSubkey(REGSAM samDesired, const TCHAR *pszSubkeyName, HKEY &rhKey)
+{
+ if (m_hKey == NULL)
+ { // subkey of root key is hive root key.
+ if ((_tcsicmp(pszSubkeyName,_T("HKCR")) == 0)||
+ (_tcsicmp(pszSubkeyName,_T("HKEY_CLASSES_ROOT")) == 0))
+ {
+ rhKey = HKEY_CLASSES_ROOT;
+
+ if (m_pszMachineName)
+ return ERROR_FILE_NOT_FOUND;
+
+ return ERROR_SUCCESS;
+ }
+ else if ((_tcsicmp(pszSubkeyName,_T("HKCU")) == 0)||
+ (_tcsicmp(pszSubkeyName,_T("HKEY_CURRENT_USER")) == 0))
+ {
+ rhKey = HKEY_CURRENT_USER;
+
+ if (m_pszMachineName)
+ return ERROR_FILE_NOT_FOUND;
+
+ return ERROR_SUCCESS;
+ }
+ else if ((_tcsicmp(pszSubkeyName,_T("HKLM")) == 0)||
+ (_tcsicmp(pszSubkeyName,_T("HKEY_LOCAL_MACHINE")) == 0))
+ {
+ rhKey = HKEY_LOCAL_MACHINE;
+
+ if (m_pszMachineName)
+ return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey);
+
+ return ERROR_SUCCESS;
+ }
+ else if ((_tcsicmp(pszSubkeyName,_T("HKU")) == 0)||
+ (_tcsicmp(pszSubkeyName,_T("HKEY_USERS")) == 0))
+ {
+ rhKey = HKEY_USERS;
+
+ if (m_pszMachineName)
+ return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey);
+
+ return ERROR_SUCCESS;
+ }
+ else if ((_tcsicmp(pszSubkeyName,_T("HKPD")) == 0)||
+ (_tcsicmp(pszSubkeyName,_T("HKEY_PERFORMANCE_DATA")) == 0))
+ {
+ rhKey = HKEY_PERFORMANCE_DATA;
+
+ if (m_pszMachineName)
+ return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey);
+
+ return ERROR_SUCCESS;
+ }
+ else if ((_tcsicmp(pszSubkeyName,_T("HKDD")) == 0)||
+ (_tcsicmp(pszSubkeyName,_T("HKEY_DYN_DATA")) == 0))
+ {
+ rhKey = HKEY_DYN_DATA;
+
+ if (m_pszMachineName)
+ return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey);
+
+ return ERROR_SUCCESS;
+ }
+ else if ((_tcsicmp(pszSubkeyName,_T("HKCC")) == 0)||
+ (_tcsicmp(pszSubkeyName,_T("HKEY_CURRENT_CONFIG")) == 0))
+ {
+ rhKey = HKEY_CURRENT_CONFIG;
+
+ if (m_pszMachineName)
+ {
+ TCHAR *pch = m_pszMachineName;
+ while (*pch)
+ pch++;
+ pch--;
+
+ ASSERT(*pch == _T('\\'));
+ if (*pch != _T('\\'))
+ return ERROR_INTERNAL_ERROR;
+
+ *pch = 0;
+
+ LONG nError = RegConnectRegistry(m_pszMachineName,rhKey,&rhKey);
+
+ *pch = _T('\\');
+
+ return nError;
+ }
+
+ return ERROR_SUCCESS;
+ }
+ else
+ {
+ return ERROR_FILE_NOT_FOUND;
+ }
+ }
+
+ return RegOpenKeyEx(m_hKey,pszSubkeyName,0,samDesired,&rhKey);
+}
+
+LONG CRegistryKey::OpenSubkey(REGSAM samDesired, const TCHAR *pszSubkeyName, CRegistryKey &rKey)
+{
+ HKEY hKey;
+ LONG nError = OpenSubkey(samDesired, pszSubkeyName, hKey);
+
+ if (nError == ERROR_SUCCESS)
+ {
+ const TCHAR *pszKeyName = GetKeyName();
+ size_t size = _tcslen(pszKeyName) + _tcslen(pszSubkeyName) + 1;
+ TCHAR *pszSubkeyFullName = new TCHAR [size];
+ if (!pszSubkeyFullName)
+ {
+ nError = RegCloseKey(hKey);
+ ASSERT(nError == ERROR_SUCCESS);
+ return ERROR_OUTOFMEMORY;
+ }
+ _tcscpy(pszSubkeyFullName,pszKeyName);
+ _tcscat(pszSubkeyFullName,pszSubkeyName);
+ HRESULT hr = rKey.Init(hKey,GetKeyName(),pszSubkeyName,samDesired);
+ delete pszSubkeyName;
+ if (FAILED(hr))
+ {
+ nError = RegCloseKey(hKey);
+ ASSERT(nError == ERROR_SUCCESS);
+ if (hr == (HRESULT)E_OUTOFMEMORY)
+ return ERROR_OUTOFMEMORY;
+ else
+ return ERROR_INTERNAL_ERROR;
+ }
+ }
+
+ return nError;
+}
+
+LONG CRegistryKey::GetSubkeyNameMaxLength(DWORD &rdwMaxSubkeyNameLength)
+{
+ if (m_hKey == NULL)
+ { // root key
+ rdwMaxSubkeyNameLength = 0;
+ for(int i = 0; i < 7 ; i++)
+ {
+ size_t l = _tcslen(g_ppszHiveNames[i]);
+ if (rdwMaxSubkeyNameLength < l)
+ rdwMaxSubkeyNameLength = l;
+ }
+
+ rdwMaxSubkeyNameLength++; // terminating null
+
+ return ERROR_SUCCESS;
+ }
+
+ LONG nRet;
+
+ nRet = RegQueryInfoKey(m_hKey,NULL,NULL,NULL,NULL,&rdwMaxSubkeyNameLength,NULL,NULL,NULL,NULL,NULL,NULL);
+
+ rdwMaxSubkeyNameLength = (nRet == ERROR_SUCCESS)?(rdwMaxSubkeyNameLength+1):0;
+
+ return nRet;
+}
+
+void CRegistryKey::InitSubkeyEnumeration(TCHAR *pszSubkeyNameBuffer, DWORD dwBufferSize)
+{
+ m_pchSubkeyNameBuffer = pszSubkeyNameBuffer;
+ m_dwSubkeyNameBufferSize = dwBufferSize;
+ m_dwCurrentSubKeyIndex = 0;
+}
+
+LONG CRegistryKey::GetNextSubkeyName(DWORD *pdwActualSize)
+{
+ LONG nError;
+
+ if (m_hKey == NULL)
+ {
+ if (m_dwCurrentSubKeyIndex < (DWORD)(m_pszMachineName?5:7))
+ {
+ DWORD dwIndex = m_pszMachineName?m_dwCurrentSubKeyIndex+2:m_dwCurrentSubKeyIndex;
+ _tcsncpy(m_pchSubkeyNameBuffer,g_ppszHiveNames[dwIndex],m_dwSubkeyNameBufferSize);
+ nError = ERROR_SUCCESS;
+ if (pdwActualSize)
+ *pdwActualSize = strlen(m_pchSubkeyNameBuffer);
+ }
+ else
+ {
+ nError = ERROR_NO_MORE_ITEMS;
+ }
+ }
+ else
+ {
+ DWORD dwActualSize = m_dwSubkeyNameBufferSize;
+ FILETIME ft;
+ nError = RegEnumKeyEx(m_hKey,
+ m_dwCurrentSubKeyIndex,
+ m_pchSubkeyNameBuffer,
+ &dwActualSize,
+ NULL,
+ NULL,
+ NULL,
+ &ft);
+ if (pdwActualSize)
+ *pdwActualSize = dwActualSize;
+ }
+
m_dwCurrentSubKeyIndex++;
- switch (dwError)
- {
- case ERROR_SUCCESS:
- return m_pchSubName;
- case ERROR_NO_MORE_ITEMS:
- return NULL;
- default:
- return NULL;
- }
-}
-void CRegistryKey::UpdateKeyNameCase()
-{
- m_pParent->InitSubKeyEnumeration();
- TCHAR *pchSubKeyName;
- DWORD dwError;
- while ((pchSubKeyName = m_pParent->GetSubKeyName(dwError)) != NULL)
- {
- if (dwError != ERROR_SUCCESS)
- {
- return;
- }
- if (_tcsicmp(pchSubKeyName,m_pchKeyName) == 0)
- {
- _tcscpy(m_pchKeyName,pchSubKeyName);
- return;
- }
- }
+ if (pdwActualSize)
+ *pdwActualSize = strlen(m_pchSubkeyNameBuffer);
+ return nError;
}
-void CRegistryKey::InitValueEnumeration()
+LONG CRegistryKey::GetSubkeyCount(DWORD &rdwSubkeyCount)
{
- m_dwCurrentValueIndex = 0;
+ return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,&rdwSubkeyCount,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
}
-
-// On input dwValueNameSize is size in characters of buffer pointed by pchValueNameBuffer
-// On output dwValueNameSize contains number of characters stored in buffer
-DWORD CRegistryKey::GetNextValue(TCHAR *pchValueNameBuffer,DWORD& dwValueNameSize,
- DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize)
+LONG CRegistryKey::GetMaxValueDataSize(DWORD& rdwMaxValueDataBuferSize)
{
- DWORD dwRet = RegEnumValue(m_hKey,m_dwCurrentValueIndex,pchValueNameBuffer,&dwValueNameSize,NULL,
- pdwType,lpValueDataBuffer,pdwValueDataSize);
- m_dwCurrentValueIndex++;
- return dwRet;
+ return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&rdwMaxValueDataBuferSize,NULL,NULL);
}
-void CRegistryKey::GetLastWriteTime(SYSTEMTIME &st)
+LONG CRegistryKey::GetMaxValueNameLength(DWORD& rdwMaxValueNameBuferSize)
{
- FILETIME ftLocal,ft;
- RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- &ft);
- FileTimeToLocalFileTime(&ft,&ftLocal);
- FileTimeToSystemTime(&ftLocal,&st);
-}
+ if (!m_hKey)
+ return 0; // the root key abstraction has only subkeys (hives)
+
+ LONG nError = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&rdwMaxValueNameBuferSize,NULL,NULL,NULL);
-TCHAR * CRegistryKey::GetLastWriteTime()
-{
- SYSTEMTIME st;
- GetLastWriteTime(st);
- static TCHAR Buffer[256];
- _stprintf(Buffer,_T("%d.%d.%d %02d:%02d:%02d"),st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
- return Buffer;
+ rdwMaxValueNameBuferSize++;
+ return nError;
}
-// Returns ErrorCode (ERROR_SUCCESS on success)
-// dwMaxValueDataBuferSize receives the length, in bytes,
-// of the longest data component among the key's values.
-DWORD CRegistryKey::GetMaxValueDataSize(DWORD& dwMaxValueDataBuferSize)
+void CRegistryKey::InitValueEnumeration(TCHAR *pszValueNameBuffer,
+ DWORD dwValueNameBufferSize,
+ BYTE *pbValueDataBuffer,
+ DWORD dwValueDataBufferSize,
+ DWORD *pdwType)
{
- return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,&dwMaxValueDataBuferSize,NULL,NULL);
-}
-
-// Returns ErrorCode (ERROR_SUCCESS on success)
-// dwMaxValueNameBuferSize receives the length, in characters,
-// of the key's longest value name.
-// The count returned does not include the terminating null character.
-DWORD CRegistryKey::GetMaxValueNameLength(DWORD& dwMaxValueNameBuferSize)
-{
- return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- &dwMaxValueNameBuferSize,NULL,NULL,NULL);
+ m_pszValueNameBuffer = pszValueNameBuffer;
+ m_dwValueNameBufferSize = dwValueNameBufferSize;
+ m_pbValueDataBuffer = pbValueDataBuffer;
+ m_dwValueDataBufferSize = dwValueDataBufferSize;
+ m_pdwType = pdwType;
+
+ m_dwCurrentValueIndex = 0;
}
-DWORD CRegistryKey::Open(REGSAM samDesired)
-{
- if (IsPredefined())
- return ERROR_SUCCESS;
- DWORD dwRet;
- HKEY hKey = NULL;
- if (*m_pszMachineName)
- {
- ASSERT(ERROR_SUCCESS == 0);
- dwRet = RegConnectRegistry(m_pszMachineName,m_hKey,&m_hKey);
- }
- else
- {
- ASSERT((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&&
- (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS)
- &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG)
- &&(m_hKey != HKEY_DYN_DATA));
- if (m_hKey)
- {
- RegCloseKey(m_hKey);
- }
- dwRet = RegOpenKeyEx(*m_pParent,m_pchKeyName,0,samDesired,&hKey);
- }
- if (dwRet == ERROR_SUCCESS)
- {
- m_hKey = hKey;
- UpdateKeyNameCase();
- }
- return dwRet;
+// On input dwValueNameSize is size in characters of buffer pointed by pchValueNameBuffer
+// On output dwValueNameSize contains number of characters stored in buffer
+LONG CRegistryKey::GetNextValue(DWORD *pdwNameActualSize, DWORD *pdwDataActualSize)
+{
+ if (!m_hKey)
+ return ERROR_NO_MORE_ITEMS; // the root key abstraction has only subkeys (hives)
+
+ DWORD dwValueNameBufferSize = m_dwValueNameBufferSize;
+ DWORD dwValueDataBufferSize = m_dwValueDataBufferSize;
+ LONG nError = RegEnumValue(m_hKey,
+ m_dwCurrentValueIndex,
+ m_pszValueNameBuffer,
+ &dwValueNameBufferSize,
+ NULL,
+ m_pdwType,
+ m_pbValueDataBuffer,
+ &dwValueDataBufferSize);
+
+ if (pdwNameActualSize)
+ *pdwNameActualSize = dwValueNameBufferSize;
+
+ if (pdwDataActualSize)
+ *pdwDataActualSize = dwValueDataBufferSize;
+
+ m_dwCurrentValueIndex++;
+ return nError;
}
-CRegistryKey::CRegistryKey(HKEY hKey, LPCTSTR pszMachineName)
+LONG CRegistryKey::GetValueCount(DWORD& rdwValueCount)
{
- TCHAR *pchKeyName = NULL;
- ASSERT((hKey == HKEY_CLASSES_ROOT)||(hKey == HKEY_CURRENT_USER)||
- (hKey == HKEY_LOCAL_MACHINE)||(hKey == HKEY_USERS)
- ||(hKey == HKEY_PERFORMANCE_DATA)||(hKey == HKEY_CURRENT_CONFIG)
- ||(hKey == HKEY_DYN_DATA));
- if(hKey == HKEY_CLASSES_ROOT)
- {
- pchKeyName = _T("HKEY_CLASSES_ROOT");
- }
- else if(hKey == HKEY_CURRENT_USER)
- {
- pchKeyName = _T("HKEY_CURRENT_USER");
- }
- else if (hKey == HKEY_LOCAL_MACHINE)
- {
- pchKeyName = _T("HKEY_LOCAL_MACHINE");
- }
- else if (hKey == HKEY_USERS)
- {
- pchKeyName = _T("HKEY_USERS");
- }
- else if (hKey == HKEY_PERFORMANCE_DATA)
- {
- pchKeyName = _T("HKEY_PERFORMANCE_DATA");
- }
- else if (hKey == HKEY_CURRENT_CONFIG)
- {
- pchKeyName = _T("HKEY_CURRENT_CONFIG");
- }
- else if (hKey == HKEY_DYN_DATA)
- {
- pchKeyName = _T("HKEY_DYN_DATA");
- }
- else
- {
- ASSERT(FALSE);
- return;
- }
-
- m_hKey = hKey;
-
- m_pParent = NULL;
- m_pChild = NULL;
- ASSERT(pchKeyName != NULL);
- m_pchKeyName[MAX_PATH] = 0;
- _tcsncpy(m_pchKeyName,pchKeyName,MAX_PATH);
- _tcsncpy(m_pszMachineName,pszMachineName?pszMachineName:_T(""),MAX_PATH);
+ if (!m_hKey)
+ return 0; // the root key abstraction has only subkeys (hives)
+
+ return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,&rdwValueCount,NULL,NULL,NULL,NULL);
}
-BOOL CRegistryKey::IsPredefined()
+LONG CRegistryKey::GetDefaultValue(DWORD *pdwType,
+ BYTE *pbValueDataBuffer,
+ DWORD dwValueDataBufferSize,
+ DWORD *pdwValueDataActualSize)
{
- return ((m_hKey == HKEY_CLASSES_ROOT)||(m_hKey == HKEY_CURRENT_USER)||
- (m_hKey == HKEY_LOCAL_MACHINE)||(m_hKey == HKEY_USERS)
- ||(m_hKey == HKEY_PERFORMANCE_DATA)||(m_hKey == HKEY_CURRENT_CONFIG)
- ||(m_hKey == HKEY_DYN_DATA));
-}
+ DWORD dwBufferSize = dwValueDataBufferSize;
+
+ LONG nError = RegQueryValueEx(m_hKey,NULL,NULL,pdwType,pbValueDataBuffer,&dwBufferSize);
-DWORD CRegistryKey::GetDefaultValue(DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize)
-{
- return RegQueryValueEx(m_hKey,NULL,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize);
-}
+ if (pdwValueDataActualSize && (nError == ERROR_SUCCESS))
+ *pdwValueDataActualSize = dwBufferSize;
-void CRegistryKey::LinkParent()
-{
- m_pParent->m_pChild = this; // self link
+ return nError;
}
const TCHAR * CRegistryKey::GetValueTypeName(DWORD dwType)
switch(dwType)
{
case REG_NONE:
- return _T("REG_NONE\t\t");
+ return _T("REG_NONE");
case REG_SZ:
- return _T("REG_SZ\t\t\t");
+ return _T("REG_SZ");
case REG_EXPAND_SZ:
- return _T("REG_EXPAND_SZ\t\t");
+ return _T("REG_EXPAND_SZ");
case REG_BINARY:
- return _T("REG_BINARY\t\t");
+ return _T("REG_BINARY");
case REG_DWORD_LITTLE_ENDIAN:
- return _T("REG_DWORD_LITTLE_ENDIAN\t");
+ return _T("REG_DWORD_LITTLE_ENDIAN");
case REG_DWORD_BIG_ENDIAN:
- return _T("REG_DWORD_BIG_ENDIAN\t");
+ return _T("REG_DWORD_BIG_ENDIAN");
case REG_LINK:
- return _T("REG_LINK\t\t");
+ return _T("REG_LINK");
case REG_MULTI_SZ:
- return _T("REG_MULTI_SZ\t\t");
+ return _T("REG_MULTI_SZ");
case REG_RESOURCE_LIST:
- return _T("REG_RESOURCE_LIST\t");
+ return _T("REG_RESOURCE_LIST");
case REG_FULL_RESOURCE_DESCRIPTOR:
return _T("REG_FULL_RESOURCE_DESCRIPTOR");
case REG_RESOURCE_REQUIREMENTS_LIST:
return _T("REG_RESOURCE_REQUIREMENTS_LIST");
default:
- return _T("Unkown Type\t");
+ return _T("Unkown Type");
}
}
return RegQueryValueEx(m_hKey,pchValueName,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize);
}
-DWORD CRegistryKey::GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor)
+LONG CRegistryKey::CreateSubkey(REGSAM samDesired,
+ const TCHAR *pszSubkeyName,
+ HKEY &rhKey,
+ BOOL *pblnOpened,
+ BOOL blnVolatile)
{
- return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,pdwSecurityDescriptor,NULL);
-}
+ DWORD dwDisposition;
+
+ LONG nError = RegCreateKeyEx(
+ m_hKey,
+ pszSubkeyName,
+ 0,
+ NULL,
+ blnVolatile?REG_OPTION_VOLATILE:REG_OPTION_NON_VOLATILE,
+ samDesired,
+ NULL,
+ &rhKey,
+ &dwDisposition);
-LONG CRegistryKey::GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor)
-{
- return RegGetKeySecurity(m_hKey,SecurityInformation,pSecurityDescriptor,lpcbSecurityDescriptor);
+ if ((nError == ERROR_SUCCESS)&&(pblnOpened))
+ *pblnOpened = dwDisposition == REG_OPENED_EXISTING_KEY;
+
+ return nError;
}
-DWORD CRegistryKey::GetSubKeyCount()
+LONG CRegistryKey::GetLastWriteTime(SYSTEMTIME &st)
{
- DWORD nCount;
- DWORD nRet = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,&nCount,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL);
- if (nRet)
- return 0;
- return nCount;
-}
+ FILETIME ftLocal,ft;
+ LONG nError = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&ft);
-DWORD CRegistryKey::GetValuesCount()
-{
- DWORD nCount;
- if (RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,
- &nCount,NULL,NULL,NULL,NULL)) return 0;
- return nCount;
+ if (nError == ERROR_SUCCESS)
+ {
+ FileTimeToLocalFileTime(&ft,&ftLocal);
+ FileTimeToSystemTime(&ftLocal,&st);
+ }
+
+ return nError;
}
-TCHAR * CRegistryKey::GetSubKeyNameByIndex(DWORD dwIndex)
+const TCHAR * CRegistryKey::GetLastWriteTime()
{
- DWORD dwError;
- static TCHAR m_pchSubName[MAX_PATH+1];
- dwError = RegEnumKey(m_hKey,dwIndex,m_pchSubName,MAX_PATH + 1);
- switch (dwError)
- {
- case ERROR_SUCCESS:
- return m_pchSubName;
- case ERROR_NO_MORE_ITEMS:
- return NULL;
- default:
- return NULL;
- }
+ SYSTEMTIME st;
+ if (GetLastWriteTime(st) != ERROR_SUCCESS)
+ return _T("(Cannot get time last write time)");
+
+ static TCHAR Buffer[256];
+ _stprintf(Buffer,_T("%d.%d.%d %02d:%02d:%02d"),st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
+ return Buffer;
}
-DWORD CRegistryKey::Create(REGSAM samDesired, DWORD *pdwDisposition, BOOL blnVolatile)
+LONG CRegistryKey::GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor)
{
- ASSERT((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&&
- (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS)
- &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG)
- &&(m_hKey != HKEY_DYN_DATA));
- if (m_hKey)
- {
- RegCloseKey(m_hKey);
- }
-
- HKEY hKey;
-
- DWORD dwRet = RegCreateKeyEx(*m_pParent,m_pchKeyName,0,NULL,
- blnVolatile?REG_OPTION_VOLATILE:REG_OPTION_NON_VOLATILE,
- samDesired,
- NULL,
- &hKey,
- pdwDisposition);
- if (dwRet == ERROR_SUCCESS)
- {
- m_hKey = hKey;
- UpdateKeyNameCase();
- }
- return dwRet;
+ return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+ NULL,NULL,pdwSecurityDescriptor,NULL);
}
-DWORD CRegistryKey::DeleteSubkey(LPCTSTR pszSubKey, BOOL blnRecursive)
+LONG CRegistryKey::GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor)
{
- CRegistryKey *pKey = new CRegistryKey(pszSubKey,this);
- if (!pKey)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- DWORD dwRet = pKey->Open(KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE);
-
- if (!dwRet)
- dwRet = pKey->Delete(blnRecursive);
-
- delete pKey;
-
- return dwRet;
+ return RegGetKeySecurity(m_hKey,SecurityInformation,pSecurityDescriptor,lpcbSecurityDescriptor);
}
-DWORD CRegistryKey::Delete(BOOL blnRecursive)
+LONG CRegistryKey::DeleteSubkey(const TCHAR *pszSubkeyName)
{
- DWORD dwRet;
- if (blnRecursive)
- {
- // Delete childs
- while(GetSubKeyCount())
- {
- TCHAR *pchKeyName = GetSubKeyNameByIndex(0);
- CRegistryKey *pKey = new CRegistryKey(pchKeyName,this);
- if (!pKey)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- dwRet = pKey->Open(KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE);
-
- if (!dwRet)
- dwRet = pKey->Delete(blnRecursive);
-
- delete pKey;
- }
- }
-
- // Delete yourself
- return RegDeleteKey(m_pParent->m_hKey,m_pchKeyName);
+ return RegDeleteKey(m_hKey,pszSubkeyName);
}
-DWORD CRegistryKey::SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize)
+LONG CRegistryKey::SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize)
{
return RegSetValueEx(m_hKey,pszValueName,0,dwType,lpData,dwDataSize);
}
-DWORD CRegistryKey::DeleteValue(LPCTSTR pszValueName)
+LONG CRegistryKey::DeleteValue(const TCHAR *pszValueName)
{
return RegDeleteValue(m_hKey,pszValueName);
}