windows-nt/Source/XPSP1/NT/base/fs/utils/reg/delete.c
2020-09-26 16:20:57 +08:00

356 lines
9.5 KiB
C

//-----------------------------------------------------------------------//
//
// File: delete.cpp
// Created: April 1997
// By: Martin Holladay (a-martih)
// Purpose: Registry Delete Support for REG.CPP
// Modification History:
// Copied from Update.cpp and modificd - April 1997 (a-martih)
// April 1999 Zeyong Xu: re-design, revision -> version 2.0
//
//------------------------------------------------------------------------//
#include "stdafx.h"
#include "reg.h"
//-----------------------------------------------------------------------//
//
// DeleteRegistry()
//
//-----------------------------------------------------------------------//
LONG DeleteRegistry(PAPPVARS pAppVars, UINT argc, TCHAR *argv[])
{
LONG nResult;
//
// Parse the cmd-line
//
nResult = ParseDeleteCmdLine(pAppVars, argc, argv);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
//
// Connect to the Remote Machine(s) - if applicable
//
nResult = RegConnectMachine(pAppVars);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
// if delete a value or delete all values under this key
if( pAppVars->szValueName ||
pAppVars->bAllValues )
{
nResult = DeleteValues(pAppVars);
}
// if delete the key
else if (Prompt(_T("\nPermanently delete the registry key %s (Y/N)? "),
pAppVars->szSubKey,
pAppVars->bForce))
{
nResult = RecursiveDeleteKey(pAppVars->hRootKey,
pAppVars->szSubKey);
}
return nResult;
}
//------------------------------------------------------------------------//
//
// ParseDeleteCmdLine()
//
//------------------------------------------------------------------------//
REG_STATUS ParseDeleteCmdLine(PAPPVARS pAppVars,
UINT argc,
TCHAR *argv[])
{
BOOL bHasValue = FALSE;
REG_STATUS nResult;
UINT i;
if(argc < 3)
{
return REG_STATUS_TOFEWPARAMS;
}
else if(argc > 6)
{
return REG_STATUS_TOMANYPARAMS;
}
// Machine Name and Registry key
//
nResult = BreakDownKeyString(argv[2], pAppVars);
if(nResult != ERROR_SUCCESS)
return nResult;
// parsing
for(i=3; i<argc; i++)
{
if(!_tcsicmp(argv[i], _T("/v")))
{
if(bHasValue)
return REG_STATUS_INVALIDPARAMS;
bHasValue = TRUE;
i++;
if(i<argc)
{
pAppVars->szValueName = (TCHAR*) calloc(_tcslen(argv[i]) + 1,
sizeof(TCHAR));
_tcscpy(pAppVars->szValueName, argv[i]);
}
else
return REG_STATUS_TOFEWPARAMS;
}
else if(!_tcsicmp(argv[i], _T("/ve")))
{
if(bHasValue)
return REG_STATUS_INVALIDPARAMS;
bHasValue = TRUE;
pAppVars->szValueName = (TCHAR*) calloc(1, sizeof(TCHAR));
}
else if(!_tcsicmp(argv[i], _T("/va")))
{
if(bHasValue)
return REG_STATUS_INVALIDPARAMS;
bHasValue = TRUE;
pAppVars->bAllValues = TRUE;
}
else if(!_tcsicmp(argv[i], _T("/f")))
{
pAppVars->bForce = TRUE;
}
else
return REG_STATUS_INVALIDPARAMS;
}
return ERROR_SUCCESS;
}
//-----------------------------------------------------------------------//
//
// RecursiveDeleteKey() - Recursive registry key delete
//
//-----------------------------------------------------------------------//
LONG RecursiveDeleteKey(HKEY hKey, LPCTSTR szName)
{
LONG nResult;
HKEY hSubKey;
DWORD dwNumOfSubkey;
DWORD dwLenOfKeyName;
TCHAR* pszNameBuf;
DWORD dwIndex = 0;
//
// Open the SubKey
//
nResult = RegOpenKeyEx( hKey,
szName,
0,
KEY_ALL_ACCESS,
&hSubKey);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
// query key info
nResult = RegQueryInfoKey(hSubKey,
NULL,
NULL,
NULL,
&dwNumOfSubkey,
&dwLenOfKeyName,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if (nResult != ERROR_SUCCESS)
{
RegCloseKey(hSubKey);
return nResult;
}
#ifndef REG_FOR_WIN2000 // ansi version for win98
// fix API bugs: RegQueryInfoKey() returns non-correct length values
// on remote Win98
if(dwLenOfKeyName < MAX_PATH)
dwLenOfKeyName = MAX_PATH;
#endif
// create buffer
dwLenOfKeyName++;
pszNameBuf = (TCHAR*) calloc(dwNumOfSubkey * dwLenOfKeyName,
sizeof(TCHAR));
// Now Enumerate all of the keys
dwIndex = 0;
while(dwIndex < dwNumOfSubkey && nResult == ERROR_SUCCESS)
{
DWORD dwSize = dwLenOfKeyName;
nResult = RegEnumKeyEx(hSubKey,
dwIndex,
pszNameBuf + (dwIndex * dwLenOfKeyName),
&dwSize,
NULL,
NULL,
NULL,
NULL);
dwIndex++;
}
dwIndex = 0;
while(nResult == ERROR_SUCCESS && dwIndex < dwNumOfSubkey)
{
nResult = RecursiveDeleteKey(hSubKey,
pszNameBuf + (dwIndex * dwLenOfKeyName));
if(nResult != ERROR_SUCCESS)
break;
dwIndex++;
}
// freee memory
if(pszNameBuf)
free(pszNameBuf);
// close this subkey and delete it
RegCloseKey(hSubKey);
if (nResult == ERROR_SUCCESS)
nResult = RegDeleteKey(hKey, szName);
return nResult;
}
LONG DeleteValues(PAPPVARS pAppVars)
{
LONG nResult;
HKEY hSubKey;
TCHAR* pszNameBuf = NULL;
DWORD dwIndex = 0;
DWORD dwSize = 0;
if( pAppVars->bAllValues &&
!Prompt(_T("\nDelete all values under the registry key %s (Y/N)? "),
pAppVars->szSubKey,
pAppVars->bForce))
{
return ERROR_SUCCESS;
}
else if( pAppVars->szValueName &&
!Prompt(_T("\nDelete the registry value %s (Y/N)? "),
pAppVars->szValueName,
pAppVars->bForce))
{
return ERROR_SUCCESS;
}
// Open the registry key
nResult = RegOpenKeyEx(pAppVars->hRootKey,
pAppVars->szSubKey,
0,
KEY_ALL_ACCESS,
&hSubKey);
if( nResult != ERROR_SUCCESS)
{
return nResult;
}
if(pAppVars->szValueName) // delete a single value
{
nResult = RegDeleteValue(hSubKey, pAppVars->szValueName);
}
else if(pAppVars->bAllValues) // delete all values
{
// query source key info
DWORD dwLenOfValueName;
DWORD dwNumOfValues;
nResult = RegQueryInfoKey(hSubKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&dwNumOfValues,
&dwLenOfValueName,
NULL,
NULL,
NULL);
if (nResult != ERROR_SUCCESS)
{
RegCloseKey(hSubKey);
return nResult;
}
#ifndef REG_FOR_WIN2000 // ansi version for win98
// fix API bugs: RegQueryInfoKey() returns non-correct length values
// on remote Win98
if(dwLenOfValueName < MAX_PATH)
dwLenOfValueName = MAX_PATH;
#endif
// create buffer
dwLenOfValueName++;
pszNameBuf = (TCHAR*) calloc(dwNumOfValues * dwLenOfValueName,
sizeof(TCHAR));
// Now Enumerate all values
dwIndex = 0;
dwSize = 0;
while(dwIndex < dwNumOfValues && nResult == ERROR_SUCCESS)
{
dwSize = dwLenOfValueName;
nResult = RegEnumValue(hSubKey,
dwIndex,
pszNameBuf + (dwIndex * dwLenOfValueName),
&dwSize,
NULL,
NULL,
NULL,
NULL);
dwIndex++;
}
dwIndex = 0;
while(nResult == ERROR_SUCCESS && dwIndex < dwNumOfValues)
{
nResult = RegDeleteValue(hSubKey,
pszNameBuf + (dwIndex * dwLenOfValueName));
if(nResult != ERROR_SUCCESS)
break;
dwIndex++;
}
// free memory
if(pszNameBuf)
free(pszNameBuf);
}
RegCloseKey(hSubKey);
return nResult;
}