414 lines
10 KiB
C++
414 lines
10 KiB
C++
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RegistryKey.cpp
|
|
//
|
|
// Copyright (C) 1998, 1999 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// Abstract :
|
|
//
|
|
// This is the implementation of the CRegistryKey class. This class was created in order to
|
|
// support automatic destruction of C++ object when an exception is thrown.
|
|
//
|
|
// History :
|
|
//
|
|
// 05/06/1999 luish Created
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <windows.h>
|
|
#include <shlwapi.h>
|
|
#include "RegistryKey.h"
|
|
#include "ExceptionHandler.h"
|
|
#include "AppManDebug.h"
|
|
#include "Win32API.h"
|
|
|
|
#ifdef DBG_MODULE
|
|
#undef DBG_MODULE
|
|
#endif
|
|
|
|
#define DBG_MODULE DBG_REGISTRY
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CRegistryKey::CRegistryKey(void)
|
|
{
|
|
FUNCTION("CRegistryKey::CRegistryKey (void)");
|
|
|
|
m_fKeyOpen = FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CRegistryKey::~CRegistryKey(void)
|
|
{
|
|
FUNCTION("CRegistryKey::~CRegistryKey (void)");
|
|
|
|
CloseKey();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::EnumKeys(const DWORD dwIndex, LPSTR lpszSubKeyName, LPDWORD lpdwSubKeyNameLen)
|
|
{
|
|
FUNCTION("CRegistryKey::EnumKeys ()");
|
|
|
|
FILETIME sFileTime;
|
|
|
|
//
|
|
// If there is no currently opened registry key, then GetValue was called unexpectedly
|
|
//
|
|
|
|
if (!m_fKeyOpen)
|
|
{
|
|
THROW(E_UNEXPECTED);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != RegEnumKeyEx(m_hRegistryKey, dwIndex, lpszSubKeyName, lpdwSubKeyNameLen, NULL, NULL, NULL, &sFileTime))
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::CheckForExistingKey(HKEY hKey, LPCSTR lpszSubKeyName)
|
|
{
|
|
FUNCTION("CRegistryKey::CheckForExistingKey ()");
|
|
|
|
HKEY hRegistryKey;
|
|
|
|
if (ERROR_SUCCESS != RegOpenKeyEx(hKey, lpszSubKeyName, 0, KEY_READ, &hRegistryKey))
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
RegCloseKey(hRegistryKey);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::CreateKey(HKEY hKey, LPCSTR lpszSubKeyName, const DWORD dwOptions, const REGSAM samDesired, BOOL bSpecifySecurityAttributes, LPDWORD lpdwDisposition)
|
|
{
|
|
FUNCTION("CRegistryKey::CreateKey ()");
|
|
|
|
LONG lReturn = ERROR_SUCCESS;
|
|
HRESULT hResult = S_OK;
|
|
CWin32API oWin32API;
|
|
|
|
//
|
|
// Make sure that current registry is closed before proceeding
|
|
//
|
|
|
|
CloseKey();
|
|
|
|
//
|
|
// Create the new key
|
|
//
|
|
|
|
if ((!(OS_VERSION_9x & oWin32API.GetOSVersion()))&&(bSpecifySecurityAttributes))
|
|
{
|
|
SECURITY_ATTRIBUTES sSecurityAttributes = {0};
|
|
SECURITY_DESCRIPTOR sSecurityDescriptor = {0};
|
|
|
|
sSecurityAttributes.nLength = sizeof sSecurityAttributes;
|
|
sSecurityAttributes.lpSecurityDescriptor = &sSecurityDescriptor;
|
|
|
|
InitializeSecurityDescriptor(&sSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
|
|
SetSecurityDescriptorDacl(&sSecurityDescriptor, TRUE, NULL, FALSE);
|
|
|
|
lReturn = RegCreateKeyEx(hKey, lpszSubKeyName, 0, NULL, dwOptions, samDesired, &sSecurityAttributes, &m_hRegistryKey, lpdwDisposition);
|
|
}
|
|
else
|
|
{
|
|
lReturn = RegCreateKeyEx(hKey, lpszSubKeyName, 0, NULL, dwOptions, samDesired, NULL, &m_hRegistryKey, lpdwDisposition);
|
|
}
|
|
|
|
if (lReturn != ERROR_SUCCESS)
|
|
{
|
|
if (lReturn == ERROR_ACCESS_DENIED)
|
|
{
|
|
hResult = E_ACCESSDENIED;
|
|
}
|
|
else
|
|
{
|
|
hResult = E_FAIL;
|
|
}
|
|
|
|
THROW(hResult);
|
|
}
|
|
|
|
m_fKeyOpen = TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::OpenKey(HKEY hKey, LPCSTR lpszSubKeyName, const REGSAM samDesired)
|
|
{
|
|
FUNCTION("CRegistryKey::OpenKey ()");
|
|
|
|
//
|
|
// Make sure that current registry is closed before proceeding
|
|
//
|
|
|
|
CloseKey();
|
|
|
|
//
|
|
// Open the existing key
|
|
//
|
|
|
|
if (ERROR_SUCCESS != RegOpenKeyEx(hKey, lpszSubKeyName, 0, samDesired, &m_hRegistryKey))
|
|
{
|
|
THROW(E_FAIL);
|
|
}
|
|
|
|
m_fKeyOpen = TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::CloseKey(void)
|
|
{
|
|
FUNCTION("CRegistryKey::CloseKey ()");
|
|
|
|
if (m_fKeyOpen)
|
|
{
|
|
RegCloseKey(m_hRegistryKey);
|
|
m_fKeyOpen = FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::DeleteKey(HKEY hKey, LPCSTR lpszSubKeyName)
|
|
{
|
|
FUNCTION("CRegistryKey::DeleteKey ()");
|
|
|
|
HRESULT hResult = S_OK;
|
|
DWORD dwSubKeyNameLen;
|
|
HKEY hRegistryKey;
|
|
FILETIME sFileTime;
|
|
CHAR strSubKeyName[MAX_PATH];
|
|
CHAR strFullSubKeyName[MAX_PATH];
|
|
|
|
//
|
|
// Recursively delete all subkeys
|
|
//
|
|
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hKey, lpszSubKeyName, 0, KEY_ALL_ACCESS, &hRegistryKey))
|
|
{
|
|
dwSubKeyNameLen = MAX_PATH;
|
|
while ((S_OK == hResult)&&(ERROR_SUCCESS == RegEnumKeyEx(hRegistryKey, 0, strSubKeyName, &dwSubKeyNameLen, NULL, NULL, NULL, &sFileTime)))
|
|
{
|
|
sprintf(strFullSubKeyName, "%s\\%s", lpszSubKeyName, strSubKeyName);
|
|
hResult = DeleteKey(hKey, strFullSubKeyName);
|
|
dwSubKeyNameLen = MAX_PATH;
|
|
}
|
|
|
|
//
|
|
// Close the key
|
|
//
|
|
|
|
RegCloseKey(hRegistryKey);
|
|
|
|
//
|
|
// If all the subkeys were successfully deleted
|
|
//
|
|
|
|
if (S_OK == hResult)
|
|
{
|
|
//
|
|
// Delete this subkey
|
|
//
|
|
|
|
if (ERROR_SUCCESS != RegDeleteKey(hKey, lpszSubKeyName))
|
|
{
|
|
hResult = E_FAIL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::EnumValues(const DWORD dwIndex, LPSTR lpszValueName, LPDWORD lpdwValueNameLen, LPDWORD lpdwType, LPBYTE lpData, LPDWORD lpdwDataLen)
|
|
{
|
|
FUNCTION("CRegistryKey::EnumValues ()");
|
|
|
|
//
|
|
// If there is no currently opened registry key, then GetValue was called unexpectedly
|
|
//
|
|
|
|
if (!m_fKeyOpen)
|
|
{
|
|
THROW(E_UNEXPECTED);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != RegEnumValue(m_hRegistryKey, dwIndex, lpszValueName, lpdwValueNameLen, NULL, lpdwType, lpData, lpdwDataLen))
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::CheckForExistingValue(LPCSTR lpszValueName)
|
|
{
|
|
FUNCTION("CRegistryKey::CheckForExistingValue ()");
|
|
|
|
//
|
|
// If there is no currently opened registry key, then CheckForExistingValue was
|
|
// called unexpectedly
|
|
//
|
|
|
|
if (!m_fKeyOpen)
|
|
{
|
|
THROW(E_UNEXPECTED);
|
|
}
|
|
|
|
//
|
|
// Check to see whether we can RegQueryValueEx() on the target. If we can then the value
|
|
// exists, othersize it does not
|
|
//
|
|
|
|
if (ERROR_SUCCESS != RegQueryValueEx(m_hRegistryKey, lpszValueName, NULL, NULL, NULL, NULL))
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::GetValue(LPCSTR lpszValueName, LPDWORD lpdwType, LPBYTE lpData, LPDWORD lpdwDataLen)
|
|
{
|
|
FUNCTION("CRegistryKey::GetValue ()");
|
|
|
|
//
|
|
// If there is no currently opened registry key, then GetValue was called unexpectedly
|
|
//
|
|
|
|
if (!m_fKeyOpen)
|
|
{
|
|
THROW(E_UNEXPECTED);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != RegQueryValueEx(m_hRegistryKey, lpszValueName, NULL, lpdwType, lpData, lpdwDataLen))
|
|
{
|
|
THROW(E_FAIL);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::SetValue(LPCSTR lpszValueName, const DWORD dwType, const BYTE * lpData, const DWORD dwDataLen)
|
|
{
|
|
FUNCTION("CRegistryKey::SetValue ()");
|
|
|
|
DWORD dwActualDataLen;
|
|
|
|
//
|
|
// If there is no currently opened registry key, then GetValue was called unexpectedly
|
|
//
|
|
|
|
if (!m_fKeyOpen)
|
|
{
|
|
THROW(E_UNEXPECTED);
|
|
}
|
|
|
|
//
|
|
// If this value is of type REG_SZ, define the lenght of the string
|
|
//
|
|
|
|
if (REG_SZ == dwType)
|
|
{
|
|
dwActualDataLen = strlen((LPSTR)lpData) + 1;
|
|
if (dwActualDataLen > dwDataLen)
|
|
{
|
|
dwActualDataLen = dwDataLen - 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwActualDataLen = dwDataLen;
|
|
}
|
|
|
|
//
|
|
//
|
|
// Set the registry value
|
|
//
|
|
|
|
if (ERROR_SUCCESS != RegSetValueEx(m_hRegistryKey, lpszValueName, 0, dwType, lpData, dwActualDataLen))
|
|
{
|
|
THROW(E_FAIL);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CRegistryKey::DeleteValue(LPCSTR lpszValueName)
|
|
{
|
|
FUNCTION("CRegistryKey::DeleteValue ()");
|
|
|
|
//
|
|
// If there is no currently opened registry key, then GetValue was called unexpectedly
|
|
//
|
|
|
|
if (!m_fKeyOpen)
|
|
{
|
|
THROW(E_UNEXPECTED);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != RegDeleteValue(m_hRegistryKey, lpszValueName))
|
|
{
|
|
THROW(E_FAIL);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|