310 lines
6.4 KiB
C++
310 lines
6.4 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (c) 1998 Microsoft Corporation
|
||
|
//
|
||
|
// Module Name:
|
||
|
// RegUtils.cpp
|
||
|
//
|
||
|
// Abstract:
|
||
|
// Registry utilities
|
||
|
//
|
||
|
// Author:
|
||
|
// Galen Barbee (galenb) November 16, 1998
|
||
|
//
|
||
|
// Revision History:
|
||
|
// 16-Nov-1998 GalenB Stolen from nt\private\gina\samples\gptdemo
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "ClusRtlP.h"
|
||
|
|
||
|
#include <tchar.h>
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// CheckSlash()
|
||
|
//
|
||
|
// Purpose: Checks for an ending slash and adds one if
|
||
|
// it is missing.
|
||
|
//
|
||
|
// Parameters: lpDir - directory
|
||
|
//
|
||
|
// Return: Pointer to the end of the string
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 6/19/95 ericflo Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
LPTSTR CheckSlash( LPTSTR lpDir )
|
||
|
{
|
||
|
DWORD dwStrLen;
|
||
|
LPTSTR lpEnd;
|
||
|
|
||
|
lpEnd = lpDir + lstrlen( lpDir );
|
||
|
if ( *( lpEnd - 1 ) != TEXT( '\\' ) )
|
||
|
{
|
||
|
*lpEnd = TEXT( '\\' );
|
||
|
lpEnd++;
|
||
|
*lpEnd = TEXT( '\0' );
|
||
|
}
|
||
|
|
||
|
return lpEnd;
|
||
|
|
||
|
}
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// RegDelnodeRecurse()
|
||
|
//
|
||
|
// Purpose: Deletes a registry key and all it's subkeys / values.
|
||
|
// Called by RegDelnode
|
||
|
//
|
||
|
// Parameters: hKeyRoot - Root key
|
||
|
// lpSubKey - SubKey to delete
|
||
|
//
|
||
|
// Return: TRUE if successful
|
||
|
// FALSE if an error occurs
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 10/3/95 ericflo Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
BOOL RegDelnodeRecurse( HKEY hKeyRoot, LPTSTR lpSubKey )
|
||
|
{
|
||
|
LPTSTR lpEnd;
|
||
|
LONG lResult;
|
||
|
DWORD dwSize;
|
||
|
TCHAR szName[MAX_PATH];
|
||
|
HKEY hKey;
|
||
|
FILETIME ftWrite;
|
||
|
|
||
|
//
|
||
|
// First, see if we can delete the key without having
|
||
|
// to recurse.
|
||
|
//
|
||
|
lResult = RegDeleteKey( hKeyRoot, lpSubKey );
|
||
|
if (lResult == ERROR_SUCCESS)
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
lResult = RegOpenKeyEx( hKeyRoot, lpSubKey, 0, KEY_READ, &hKey );
|
||
|
if ( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
lpEnd = CheckSlash( lpSubKey );
|
||
|
|
||
|
//
|
||
|
// Enumerate the keys
|
||
|
//
|
||
|
dwSize = MAX_PATH;
|
||
|
lResult = RegEnumKeyEx( hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite );
|
||
|
if ( lResult == ERROR_SUCCESS )
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
|
||
|
lstrcpy( lpEnd, szName );
|
||
|
|
||
|
if ( !RegDelnodeRecurse( hKeyRoot, lpSubKey ) )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Enumerate again
|
||
|
//
|
||
|
dwSize = MAX_PATH;
|
||
|
|
||
|
lResult = RegEnumKeyEx( hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite );
|
||
|
|
||
|
} while ( lResult == ERROR_SUCCESS );
|
||
|
}
|
||
|
|
||
|
lpEnd--;
|
||
|
*lpEnd = TEXT( '\0' );
|
||
|
|
||
|
RegCloseKey( hKey );
|
||
|
|
||
|
//
|
||
|
// Try again to delete the key
|
||
|
//
|
||
|
lResult = RegDeleteKey( hKeyRoot, lpSubKey );
|
||
|
if ( lResult == ERROR_SUCCESS )
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// RegDelnode()
|
||
|
//
|
||
|
// Purpose: Deletes a registry key and all it's subkeys / values
|
||
|
//
|
||
|
// Parameters: hKeyRoot - Root key
|
||
|
// lpSubKey - SubKey to delete
|
||
|
//
|
||
|
// Return: TRUE if successful
|
||
|
// FALSE if an error occurs
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 10/3/95 ericflo Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
BOOL RegDelnode( HKEY hKeyRoot, const LPTSTR lpSubKey )
|
||
|
{
|
||
|
TCHAR szDelKey[2 * MAX_PATH];
|
||
|
|
||
|
lstrcpy ( szDelKey, lpSubKey );
|
||
|
|
||
|
return RegDelnodeRecurse( hKeyRoot, szDelKey );
|
||
|
|
||
|
}
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// RegCleanUpValue()
|
||
|
//
|
||
|
// Purpose: Removes the target value and if no more values / keys
|
||
|
// are present, removes the key. This function then
|
||
|
// works up the parent tree removing keys if they are
|
||
|
// also empty. If any parent key has a value / subkey,
|
||
|
// it won't be removed.
|
||
|
//
|
||
|
// Parameters: hKeyRoot - Root key
|
||
|
// lpSubKey - SubKey
|
||
|
// lpValueName - Value to remove
|
||
|
//
|
||
|
//
|
||
|
// Return: TRUE if successful
|
||
|
// FALSE if an error occurs
|
||
|
//
|
||
|
//*************************************************************
|
||
|
BOOL RegCleanUpValue( HKEY hKeyRoot, LPTSTR lpSubKey, LPTSTR lpValueName )
|
||
|
{
|
||
|
LPTSTR lpEnd;
|
||
|
DWORD dwKeys;
|
||
|
DWORD dwValues;
|
||
|
LONG lResult;
|
||
|
HKEY hKey;
|
||
|
TCHAR szDelKey[2 * MAX_PATH];
|
||
|
|
||
|
//
|
||
|
// Make a copy of the subkey so we can write to it.
|
||
|
//
|
||
|
lstrcpy( szDelKey, lpSubKey );
|
||
|
|
||
|
//
|
||
|
// First delete the value
|
||
|
//
|
||
|
|
||
|
lResult = RegOpenKeyEx( hKeyRoot, szDelKey, 0, KEY_WRITE, &hKey );
|
||
|
if ( lResult == ERROR_SUCCESS )
|
||
|
{
|
||
|
lResult = RegDeleteValue( hKey, lpValueName );
|
||
|
|
||
|
RegCloseKey( hKey );
|
||
|
|
||
|
if ( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if ( lResult != ERROR_FILE_NOT_FOUND )
|
||
|
{
|
||
|
//DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to delete value <%s> with %d."), lpValueName, lResult));
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Now loop through each of the parents. If the parent is empty
|
||
|
// eg: no values and no other subkeys, then remove the parent and
|
||
|
// keep working up.
|
||
|
//
|
||
|
lpEnd = szDelKey + lstrlen( szDelKey ) - 1;
|
||
|
|
||
|
while ( lpEnd >= szDelKey )
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// Find the parent key
|
||
|
//
|
||
|
while ( ( lpEnd > szDelKey ) && ( *lpEnd != TEXT( '\\' ) ) )
|
||
|
{
|
||
|
lpEnd--;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Open the key
|
||
|
//
|
||
|
lResult = RegOpenKeyEx( hKeyRoot, szDelKey, 0, KEY_READ, &hKey );
|
||
|
if ( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if ( lResult == ERROR_FILE_NOT_FOUND )
|
||
|
{
|
||
|
goto LoopAgain;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to open key <%s> with %d."), szDelKey, lResult));
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// See if there any any values / keys
|
||
|
//
|
||
|
lResult = RegQueryInfoKey( hKey, NULL, NULL, NULL, &dwKeys, NULL, NULL, &dwValues, NULL, NULL, NULL, NULL );
|
||
|
|
||
|
RegCloseKey( hKey );
|
||
|
|
||
|
if ( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
//DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to query key <%s> with %d."), szDelKey, lResult));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Exit now if this key has values or keys
|
||
|
//
|
||
|
if ( ( dwKeys != 0 ) || ( dwValues != 0 ) )
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
RegDeleteKey( hKeyRoot, szDelKey );
|
||
|
|
||
|
LoopAgain:
|
||
|
//
|
||
|
// If we are at the beginning of the subkey, we can leave now.
|
||
|
//
|
||
|
if ( lpEnd == szDelKey )
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// There is a parent key. Remove the slash and loop again.
|
||
|
//
|
||
|
if ( *lpEnd == TEXT( '\\' ) )
|
||
|
{
|
||
|
*lpEnd = TEXT( '\0' );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
}
|