320 lines
6.7 KiB
C++
320 lines
6.7 KiB
C++
|
//
|
||
|
// Microsoft Corporation 1998
|
||
|
//
|
||
|
// UTIL.CPP - Utility routines
|
||
|
//
|
||
|
#include "main.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, 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)
|
||
|
{
|
||
|
TCHAR szDelKey[2 * MAX_PATH];
|
||
|
LPTSTR lpEnd;
|
||
|
DWORD dwKeys, dwValues;
|
||
|
LONG lResult;
|
||
|
HKEY hKey;
|
||
|
|
||
|
|
||
|
//
|
||
|
// 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;
|
||
|
}
|