593 lines
13 KiB
C++
593 lines
13 KiB
C++
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
reg.cxx
|
|
|
|
Abstract:
|
|
|
|
Class that modifies the registry
|
|
|
|
Author:
|
|
|
|
Christopher Achille (cachille)
|
|
|
|
Project:
|
|
|
|
Internet Services Setup
|
|
|
|
Revision History:
|
|
|
|
June 2001: Created
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "reg.hxx"
|
|
#include "tstr.hxx"
|
|
|
|
// constructor
|
|
//
|
|
CRegistry::CRegistry():
|
|
m_hKey(NULL)
|
|
{
|
|
}
|
|
|
|
// destructor
|
|
//
|
|
CRegistry::~CRegistry()
|
|
{
|
|
CloseRegistry();
|
|
}
|
|
|
|
// function: QueryKey
|
|
//
|
|
// Query our current registry key
|
|
//
|
|
HKEY
|
|
CRegistry::QueryKey()
|
|
{
|
|
return m_hKey;
|
|
}
|
|
|
|
// function: OpenRegistry
|
|
//
|
|
// Open a registry handle
|
|
//
|
|
// Parameters:
|
|
// szNodetoOpen - A string containing the node to open
|
|
// szSubKey - The subkey that you need to open
|
|
// dwAccess - Access that is needed
|
|
// pKey - A pointer to a key that is returned
|
|
//
|
|
// Return
|
|
// TRUE - Success
|
|
// FALSE - Failure
|
|
//
|
|
BOOL
|
|
CRegistry::OpenRegistry(LPTSTR szNodetoOpen, LPTSTR szSubKey, DWORD dwAccess)
|
|
{
|
|
HKEY hHandleValue = HKEY_LOCAL_MACHINE;
|
|
|
|
if ( _tcsicmp( szNodetoOpen, _T("HKCR") ) == 0 )
|
|
{
|
|
hHandleValue = HKEY_CLASSES_ROOT;
|
|
}
|
|
else if ( _tcsicmp( szNodetoOpen, _T("HKCC") ) == 0 )
|
|
{
|
|
hHandleValue = HKEY_CURRENT_CONFIG;
|
|
}
|
|
else if ( _tcsicmp( szNodetoOpen, _T("HKCU") ) == 0 )
|
|
{
|
|
hHandleValue = HKEY_CURRENT_USER;
|
|
}
|
|
else if ( _tcsicmp( szNodetoOpen, _T("HKLM") ) == 0 )
|
|
{
|
|
hHandleValue = HKEY_LOCAL_MACHINE;
|
|
}
|
|
else if ( _tcsicmp( szNodetoOpen, _T("HKU") ) == 0 )
|
|
{
|
|
hHandleValue = HKEY_USERS;
|
|
}
|
|
|
|
return OpenRegistry( hHandleValue, szSubKey, dwAccess );
|
|
}
|
|
|
|
// function: OpenRegistry
|
|
//
|
|
// Open a registry handle
|
|
//
|
|
// Parameters:
|
|
// hKey - Key to open from
|
|
// szSubKey - The subkey that you need to open
|
|
// dwAccess - Access that is needed
|
|
// bCreateIfNotPresent - Should we create key if not existent?
|
|
//
|
|
// Return
|
|
// TRUE - Success
|
|
// FALSE - Failure
|
|
//
|
|
BOOL
|
|
CRegistry::OpenRegistry(HKEY hKey, LPCTSTR szSubKey, DWORD dwAccess, BOOL bCreateIfNotPresent /*= FALSE*/ )
|
|
{
|
|
DWORD dwRet;
|
|
|
|
// Close just incase it was open before
|
|
CloseRegistry();
|
|
|
|
dwRet = RegOpenKeyEx(hKey, szSubKey, 0, dwAccess, &m_hKey);
|
|
|
|
if ( ( dwRet == ERROR_PATH_NOT_FOUND ) &&
|
|
( bCreateIfNotPresent ) )
|
|
{
|
|
// Try to create is
|
|
dwRet = RegCreateKeyEx( hKey,
|
|
szSubKey,
|
|
0, // Reserved
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
dwAccess,
|
|
NULL, // SD
|
|
&m_hKey,
|
|
NULL );
|
|
}
|
|
|
|
return ( dwRet == ERROR_SUCCESS );
|
|
}
|
|
|
|
// function: CloseRegistry
|
|
//
|
|
void
|
|
CRegistry::CloseRegistry()
|
|
{
|
|
if ( m_hKey )
|
|
{
|
|
RegCloseKey( m_hKey );
|
|
m_hKey = NULL;
|
|
}
|
|
}
|
|
|
|
// function: ReadValue
|
|
//
|
|
// Parameters:
|
|
// Value - The container for the Value
|
|
//
|
|
// Return:
|
|
// TRUE - Successfully read
|
|
// FALSE - Could not be read
|
|
BOOL
|
|
CRegistry::ReadValue(LPCTSTR szName, CRegValue &Value)
|
|
{
|
|
DWORD dwSize = 0;
|
|
DWORD dwType;
|
|
|
|
if ( RegQueryValueEx(m_hKey, szName, NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS)
|
|
{
|
|
// We could not request the size
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !Value.m_buffData.Resize( dwSize ) )
|
|
{
|
|
// Could not expland value size
|
|
return FALSE;
|
|
}
|
|
|
|
Value.m_dwSize = dwSize;
|
|
|
|
if ( RegQueryValueEx(m_hKey, szName, NULL, &Value.m_dwType, (LPBYTE) Value.m_buffData.QueryPtr() , &dwSize) != ERROR_SUCCESS)
|
|
{
|
|
// Could not retrieve value
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// funtion : ReadValueString
|
|
//
|
|
// Read a string in from the registry. If it is not string, then fail
|
|
//
|
|
// Parameters:
|
|
// szName - The name of the registry key
|
|
// strValue - The value of the registry value
|
|
//
|
|
// Return:
|
|
// TRUE - Successfully read
|
|
// FALSE - Could not be read, or it is not a string value
|
|
BOOL
|
|
CRegistry::ReadValueString(LPCTSTR szName, TSTR *strValue)
|
|
{
|
|
DWORD dwSize = 0;
|
|
DWORD dwType;
|
|
|
|
if ( RegQueryValueEx(m_hKey, szName, NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS)
|
|
{
|
|
// We could not request the size
|
|
return FALSE;
|
|
}
|
|
|
|
if ( dwType != REG_SZ )
|
|
{
|
|
// It is not a string
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !strValue->Resize( dwSize ) )
|
|
{
|
|
// Could not expland the string
|
|
return FALSE;
|
|
}
|
|
|
|
if ( RegQueryValueEx(m_hKey, szName, NULL, &dwType, (LPBYTE) strValue->QueryStr() , &dwSize) != ERROR_SUCCESS)
|
|
{
|
|
// Could not retrieve value
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// function: SetValue
|
|
//
|
|
// Parameters:
|
|
// szName - Name of Value
|
|
// Value - The container for the Value
|
|
//
|
|
// Return:
|
|
// TRUE - Successfully written
|
|
// FALSE - Could not be written
|
|
BOOL
|
|
CRegistry::SetValue(LPCTSTR szName, CRegValue &Value)
|
|
{
|
|
DWORD dwSize = 0;
|
|
|
|
if ( RegSetValueEx(m_hKey, szName, NULL, Value.m_dwType, (LPBYTE) Value.m_buffData.QueryPtr(), Value.m_dwSize ) != ERROR_SUCCESS)
|
|
{
|
|
// Failed to write value
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// function: DeleteValue
|
|
//
|
|
// Parameters:
|
|
// szName - Name of item to remove
|
|
//
|
|
BOOL
|
|
CRegistry::DeleteValue(LPCTSTR szName)
|
|
{
|
|
return ( RegDeleteValue( m_hKey, szName ) == ERROR_SUCCESS );
|
|
}
|
|
|
|
// function: DeleteAllValues
|
|
//
|
|
// Delete all of the values inside a key
|
|
//
|
|
// Parameters:
|
|
//
|
|
BOOL
|
|
CRegistry::DeleteAllValues()
|
|
{
|
|
TSTR strValueName;
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
DWORD dwValueNameSize;
|
|
|
|
if ( !strValueName.Resize( MAX_PATH ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
while ( dwRet == ERROR_SUCCESS )
|
|
{
|
|
dwValueNameSize = strValueName.QuerySize();
|
|
|
|
dwRet = RegEnumValue( m_hKey,
|
|
0, // Always delete first item
|
|
strValueName.QueryStr(), // Buffer
|
|
&dwValueNameSize, // Buffer Size
|
|
NULL, // Reserverd
|
|
NULL, // Type
|
|
NULL, // Data
|
|
0); // Size of Data Buffer
|
|
|
|
if ( dwRet == ERROR_SUCCESS )
|
|
{
|
|
dwRet = RegDeleteValue( m_hKey, strValueName.QueryStr() );
|
|
}
|
|
}
|
|
|
|
return ( ( dwRet == ERROR_SUCCESS ) ||
|
|
( dwRet == ERROR_NO_MORE_ITEMS )
|
|
);
|
|
}
|
|
|
|
// function: DeleteKey
|
|
//
|
|
// Delete a key, and possible recursively delete the keys within it
|
|
//
|
|
// Parameters:
|
|
// szKeyName - The name of the key to delete
|
|
// bDeleteSubKeys - Should we delete all subkeys?
|
|
// dwDepth - The depth that we are in, in our recursive calls
|
|
//
|
|
BOOL
|
|
CRegistry::DeleteKey(LPTSTR szKeyName, BOOL bDeleteSubKeys, DWORD dwDepth )
|
|
{
|
|
CRegistry CurrentKey;
|
|
TSTR strSubKeyName;
|
|
DWORD dwSubKeySize;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
FILETIME ft;
|
|
|
|
if ( dwDepth >= REGKEY_RECURSION_MAXDEPTH )
|
|
{
|
|
// For security reasons, and stack space, lets put a limit on the depth
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !strSubKeyName.Resize( MAX_PATH ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( bDeleteSubKeys )
|
|
{
|
|
if ( !CurrentKey.OpenRegistry( m_hKey, szKeyName, KEY_ALL_ACCESS ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
while ( dwErr == ERROR_SUCCESS )
|
|
{
|
|
dwSubKeySize = strSubKeyName.QuerySize();
|
|
|
|
// Always look at the first key, since after you delete the first key,
|
|
// the second will automatically become the first, and so on
|
|
// WARNING: Watch the return paths for DeleteKey, because if it returns
|
|
// a true without deleting the key, we will loop forever...
|
|
dwErr = RegEnumKeyEx( CurrentKey.QueryKey(),
|
|
0,
|
|
strSubKeyName.QueryStr(),
|
|
&dwSubKeySize,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&ft );
|
|
|
|
// Not call this function, to recursively delete the key
|
|
// that we have found
|
|
if ( dwErr == ERROR_SUCCESS )
|
|
{
|
|
if ( !CurrentKey.DeleteKey( strSubKeyName.QueryStr(), TRUE, dwDepth + 1 ) )
|
|
{
|
|
dwErr = ERROR_ACCESS_DENIED;
|
|
}
|
|
}
|
|
}
|
|
|
|
// This should be treated as success, we hit the end of the list
|
|
if ( dwErr == ERROR_NO_MORE_ITEMS )
|
|
{
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
|
|
// If we had not problem so far and we are deleting recurisively,
|
|
// delete all the values in this key
|
|
if ( dwErr == ERROR_SUCCESS )
|
|
{
|
|
if (!CurrentKey.DeleteAllValues() )
|
|
{
|
|
dwErr = ERROR_ACCESS_DENIED;
|
|
}
|
|
}
|
|
|
|
CurrentKey.CloseRegistry();
|
|
}
|
|
|
|
// If we had not problem so far, delete the key itself
|
|
if ( dwErr == ERROR_SUCCESS )
|
|
{
|
|
dwErr = RegDeleteKey( m_hKey, strSubKeyName.QueryStr() );
|
|
}
|
|
|
|
return ( dwErr == ERROR_SUCCESS );
|
|
}
|
|
|
|
// function: Verify Parameters
|
|
//
|
|
// Verify that the parameters are correct
|
|
//
|
|
BOOL
|
|
CRegistry_MoveValue::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
if ( ciParams.GetNumberOfItems() == 6 )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// function: DoInternalWork
|
|
//
|
|
// Move a registry value
|
|
//
|
|
// Parameters:
|
|
// ciList - Parameters for function
|
|
// 0 - Source location (HKLM/HKCU/...)
|
|
// 1 - Source Path (/Software/Microsoft/...)
|
|
// 2 - Source Name
|
|
// 3 - Target location
|
|
// 4 - Target Path
|
|
// 5 - Target Name
|
|
//
|
|
BOOL
|
|
CRegistry_MoveValue::DoInternalWork(CItemList &ciList)
|
|
{
|
|
CRegistry RegSource;
|
|
CRegistry RegTarget;
|
|
CRegValue Value;
|
|
BOOL bRet = TRUE;
|
|
BOOL bSameLocation = TRUE;
|
|
|
|
if ( !RegSource.OpenRegistry(ciList.GetItem(0), ciList.GetItem(1), KEY_READ | KEY_WRITE) )
|
|
{
|
|
// We could not open this node in the registry
|
|
return FALSE;
|
|
}
|
|
|
|
if ( ( _tcsicmp( ciList.GetItem(0), ciList.GetItem(3) ) != 0 ) ||
|
|
( _tcsicmp( ciList.GetItem(1), ciList.GetItem(4) ) != 0 )
|
|
)
|
|
{
|
|
// Since the read and write are not both located at the same node, open the
|
|
// write node also.
|
|
if ( !RegTarget.OpenRegistry(ciList.GetItem(3), ciList.GetItem(4), KEY_READ |KEY_WRITE ) )
|
|
{
|
|
// We could not open the node needed for write in the registry
|
|
return FALSE;
|
|
}
|
|
|
|
bSameLocation = FALSE;
|
|
}
|
|
|
|
// See if the target already has a value, if it does, then we do not need to move the old value
|
|
if ( bSameLocation )
|
|
bRet = !RegSource.ReadValue( ciList.GetItem(5), Value );
|
|
else
|
|
bRet = !RegTarget.ReadValue( ciList.GetItem(5), Value );
|
|
|
|
if ( bRet )
|
|
{
|
|
// Try to read old value
|
|
bRet = RegSource.ReadValue( ciList.GetItem(2), Value );
|
|
}
|
|
|
|
if ( bRet )
|
|
{
|
|
// Try to Set the new value
|
|
if ( bSameLocation )
|
|
bRet = RegSource.SetValue( ciList.GetItem(5), Value );
|
|
else
|
|
bRet = RegTarget.SetValue( ciList.GetItem(5), Value );
|
|
}
|
|
|
|
if ( bRet )
|
|
{
|
|
// Remove old value, since we have successfully copied it
|
|
bRet = RegSource.DeleteValue( ciList.GetItem(2) );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
LPTSTR
|
|
CRegistry_MoveValue::GetMethodName()
|
|
{
|
|
return _T("Registry_MoveValue");
|
|
}
|
|
|
|
// function: Verify Parameters
|
|
//
|
|
// Verify that the parameters are correct
|
|
//
|
|
BOOL
|
|
CRegistry_DeleteKey::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
// 3 parameters are for Root,Path,Name of Key
|
|
// 4th parameter can be the if you want it recursively deleted
|
|
if ( ( ciParams.GetNumberOfItems() == 3 ) ||
|
|
( ( ciParams.GetNumberOfItems() == 4 ) &&
|
|
( ciParams.IsNumber(3) )
|
|
)
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// function: DoInternalWork
|
|
//
|
|
// Delete a registry key
|
|
//
|
|
// Parameters:
|
|
// ciList - Parameters for function
|
|
// 0 - Source location (HKLM/HKCU/...)
|
|
// 1 - Source Path (/Software/Microsoft/...)
|
|
// 2 - Source Name
|
|
// 3 - Recursively delete keys? (optional)
|
|
//
|
|
BOOL
|
|
CRegistry_DeleteKey::DoInternalWork(CItemList &ciList)
|
|
{
|
|
CRegistry Reg;
|
|
BOOL bRet = TRUE;
|
|
|
|
if ( !Reg.OpenRegistry(ciList.GetItem(0), ciList.GetItem(1), KEY_ALL_ACCESS ) )
|
|
{
|
|
// We could not open this node in the registry
|
|
return FALSE;
|
|
}
|
|
|
|
bRet = Reg.DeleteKey( ciList.GetItem(2), // Name of specific key to delete
|
|
ciList.GetNumberOfItems() == 4 ? ciList.GetNumber(3) != 0 : TRUE); // Delete recursively
|
|
|
|
Reg.CloseRegistry( );
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
LPTSTR
|
|
CRegistry_DeleteKey::GetMethodName()
|
|
{
|
|
return _T("Registry_DeleteKey");
|
|
}
|
|
|
|
// SetDword
|
|
//
|
|
// Set the value to a DWORD
|
|
//
|
|
BOOL
|
|
CRegValue::SetDword( DWORD dwNewValue )
|
|
{
|
|
if ( !m_buffData.Resize( sizeof( DWORD ) ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_dwSize = sizeof( DWORD );
|
|
m_dwType = REG_DWORD;
|
|
*( (LPDWORD) m_buffData.QueryPtr() ) = dwNewValue;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// GetDword
|
|
//
|
|
// Retrieve the DWORD Value from the class
|
|
//
|
|
BOOL
|
|
CRegValue::GetDword( LPDWORD pdwValue )
|
|
{
|
|
if ( m_dwType != REG_DWORD )
|
|
{
|
|
// This is not a DWORD
|
|
return FALSE;
|
|
}
|
|
|
|
*pdwValue = *( (LPDWORD) m_buffData.QueryPtr() );
|
|
|
|
return TRUE;
|
|
}
|