mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
a248f1e7c3
svn path=/trunk/; revision=1419
458 lines
11 KiB
C++
458 lines
11 KiB
C++
/* $Id: RegistryKey.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $
|
|
*
|
|
* regexpl - Console Registry Explorer
|
|
*
|
|
* Copyright (C) 2000 Nedko Arnaoudov <nedkohome@atia.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
// RegistryKey.cpp: implementation of the CRegistryKey class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "ph.h"
|
|
#include "RegistryKey.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
TCHAR * CRegistryKey::GetKeyName()
|
|
{
|
|
return m_pchKeyName;
|
|
}
|
|
|
|
class CRegistryKey * CRegistryKey::GetChild()
|
|
{
|
|
return m_pChild;
|
|
}
|
|
|
|
CRegistryKey * CRegistryKey::GetParent()
|
|
{
|
|
return m_pParent;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
void CRegistryKey::InitSubKeyEnumeration()
|
|
{
|
|
m_dwCurrentSubKeyIndex = 0;
|
|
}
|
|
|
|
TCHAR * CRegistryKey::GetSubKeyName(DWORD& dwError)
|
|
{
|
|
static TCHAR m_pchSubName[MAX_PATH+1];
|
|
dwError = RegEnumKey(m_hKey,m_dwCurrentSubKeyIndex,m_pchSubName,MAX_PATH + 1);
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CRegistryKey::InitValueEnumeration()
|
|
{
|
|
m_dwCurrentValueIndex = 0;
|
|
}
|
|
|
|
|
|
// 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)
|
|
{
|
|
DWORD dwRet = RegEnumValue(m_hKey,m_dwCurrentValueIndex,pchValueNameBuffer,&dwValueNameSize,NULL,
|
|
pdwType,lpValueDataBuffer,pdwValueDataSize);
|
|
m_dwCurrentValueIndex++;
|
|
return dwRet;
|
|
}
|
|
|
|
void CRegistryKey::GetLastWriteTime(SYSTEMTIME &st)
|
|
{
|
|
FILETIME ftLocal,ft;
|
|
RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
|
&ft);
|
|
FileTimeToLocalFileTime(&ft,&ftLocal);
|
|
FileTimeToSystemTime(&ftLocal,&st);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
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);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
CRegistryKey::CRegistryKey(HKEY hKey, LPCTSTR pszMachineName)
|
|
{
|
|
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);
|
|
}
|
|
|
|
BOOL CRegistryKey::IsPredefined()
|
|
{
|
|
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 CRegistryKey::GetDefaultValue(DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize)
|
|
{
|
|
return RegQueryValueEx(m_hKey,NULL,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize);
|
|
}
|
|
|
|
void CRegistryKey::LinkParent()
|
|
{
|
|
m_pParent->m_pChild = this; // self link
|
|
}
|
|
|
|
const TCHAR * CRegistryKey::GetValueTypeName(DWORD dwType)
|
|
{
|
|
switch(dwType)
|
|
{
|
|
case REG_NONE:
|
|
return _T("REG_NONE\t\t");
|
|
case REG_SZ:
|
|
return _T("REG_SZ\t\t\t");
|
|
case REG_EXPAND_SZ:
|
|
return _T("REG_EXPAND_SZ\t\t");
|
|
case REG_BINARY:
|
|
return _T("REG_BINARY\t\t");
|
|
case REG_DWORD_LITTLE_ENDIAN:
|
|
return _T("REG_DWORD_LITTLE_ENDIAN\t");
|
|
case REG_DWORD_BIG_ENDIAN:
|
|
return _T("REG_DWORD_BIG_ENDIAN\t");
|
|
case REG_LINK:
|
|
return _T("REG_LINK\t\t");
|
|
case REG_MULTI_SZ:
|
|
return _T("REG_MULTI_SZ\t\t");
|
|
case REG_RESOURCE_LIST:
|
|
return _T("REG_RESOURCE_LIST\t");
|
|
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");
|
|
}
|
|
}
|
|
|
|
DWORD CRegistryKey::GetValue(TCHAR *pchValueName, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize)
|
|
{
|
|
return RegQueryValueEx(m_hKey,pchValueName,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize);
|
|
}
|
|
|
|
DWORD CRegistryKey::GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor)
|
|
{
|
|
return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
|
NULL,NULL,pdwSecurityDescriptor,NULL);
|
|
}
|
|
|
|
LONG CRegistryKey::GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor)
|
|
{
|
|
return RegGetKeySecurity(m_hKey,SecurityInformation,pSecurityDescriptor,lpcbSecurityDescriptor);
|
|
}
|
|
|
|
DWORD CRegistryKey::GetSubKeyCount()
|
|
{
|
|
DWORD nCount;
|
|
DWORD nRet = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,&nCount,NULL,NULL,NULL,
|
|
NULL,NULL,NULL,NULL);
|
|
if (nRet)
|
|
return 0;
|
|
return nCount;
|
|
}
|
|
|
|
DWORD CRegistryKey::GetValuesCount()
|
|
{
|
|
DWORD nCount;
|
|
if (RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,
|
|
&nCount,NULL,NULL,NULL,NULL)) return 0;
|
|
return nCount;
|
|
}
|
|
|
|
TCHAR * CRegistryKey::GetSubKeyNameByIndex(DWORD dwIndex)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
DWORD CRegistryKey::Create(REGSAM samDesired, DWORD *pdwDisposition, BOOL blnVolatile)
|
|
{
|
|
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;
|
|
}
|
|
|
|
DWORD CRegistryKey::DeleteSubkey(LPCTSTR pszSubKey, BOOL blnRecursive)
|
|
{
|
|
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;
|
|
}
|
|
|
|
DWORD CRegistryKey::Delete(BOOL blnRecursive)
|
|
{
|
|
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);
|
|
}
|
|
|
|
DWORD CRegistryKey::SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize)
|
|
{
|
|
return RegSetValueEx(m_hKey,pszValueName,0,dwType,lpData,dwDataSize);
|
|
}
|
|
|
|
DWORD CRegistryKey::DeleteValue(LPCTSTR pszValueName)
|
|
{
|
|
return RegDeleteValue(m_hKey,pszValueName);
|
|
}
|