Windows-Server-2003/inetsrv/iis/setup/osrc/reg.cxx

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;
}