|
|
//-----------------------------------------------------------------------//
//
// File: Reg.cpp
// Created: Jan 1997
// By: Martin Holladay (a-martih)
// Purpose: Command-line registry manipulation (query, add, update, etc)
// Modification History:
// Created - Jan 1997 (a-martih)
// Oct 1997 (martinho)
// Fixed up help on Add and Update to display REG_MULTI_SZ examples.
// Oct 1997 (martinho)
// Changed /F to /FORCE under usage for delete
// April 1999 Zeyong Xu: re-design, revision -> version 2.0
//
//-----------------------------------------------------------------------//
#include "stdafx.h"
#include "reg.h"
#include <regstr.h>
//
// structures
//
typedef struct __tagRegDataTypes { DWORD dwType; LPCWSTR pwszType; } TREG_DATA_TYPE;
//
// defines / constants / enumerations
//
const WCHAR cwszRegSz[] = L"REG_SZ"; const WCHAR cwszRegExpandSz[] = L"REG_EXPAND_SZ"; const WCHAR cwszRegMultiSz[] = L"REG_MULTI_SZ"; const WCHAR cwszRegBinary[] = L"REG_BINARY"; const WCHAR cwszRegDWord[] = L"REG_DWORD"; const WCHAR cwszRegDWordLittleEndian[] = L"REG_DWORD_LITTLE_ENDIAN"; const WCHAR cwszRegDWordBigEndian[] = L"REG_DWORD_BIG_ENDIAN"; const WCHAR cwszRegNone[] = L"REG_NONE"; const WCHAR cwszRegLink[] = L"REG_LINK"; const WCHAR cwszRegResourceList[] = L"REG_RESOURCE_LIST"; const WCHAR cwszRegFullResourceDescriptor[] = L"REG_FULL_RESOURCE_DESCRIPTOR"; const WCHAR g_wszOptions[ REG_OPTIONS_COUNT ][ 10 ] = { L"QUERY", L"ADD", L"DELETE", L"COPY", L"SAVE", L"RESTORE", L"LOAD", L"UNLOAD", L"COMPARE", L"EXPORT", L"IMPORT" };
const TREG_DATA_TYPE g_regTypes[] = { { REG_SZ, cwszRegSz }, { REG_EXPAND_SZ, cwszRegExpandSz }, { REG_MULTI_SZ, cwszRegMultiSz }, { REG_BINARY, cwszRegBinary }, { REG_DWORD, cwszRegDWord }, { REG_DWORD_LITTLE_ENDIAN, cwszRegDWordLittleEndian }, { REG_DWORD_BIG_ENDIAN, cwszRegDWordBigEndian }, { REG_NONE, cwszRegNone }, { REG_LINK, cwszRegLink }, { REG_RESOURCE_LIST, cwszRegResourceList }, { REG_FULL_RESOURCE_DESCRIPTOR, cwszRegFullResourceDescriptor } };
//
// private functions
//
BOOL IsRegistryToolDisabled(); BOOL ParseRegCmdLine( DWORD argc, LPCWSTR argv[], LONG* plOperation, BOOL* pbUsage ); BOOL ParseMachineName( LPCWSTR pwszStr, PTREG_PARAMS pParams ); LPWSTR AdjustKeyName( LPWSTR pwszStr ); BOOL ParseKeyName( LPWSTR pwszStr, PTREG_PARAMS pParams ); BOOL IsValidSubKey( LPCWSTR pwszSubKey );
//------------------------------------------------------------------------//
//
// main()
//
//------------------------------------------------------------------------//
DWORD __cdecl wmain( DWORD argc, LPCWSTR argv[] ) { // local variables
BOOL bUsage = FALSE; BOOL bResult = FALSE; DWORD dwExitCode = 0; LONG lOperation = 0;
//
// Determine the opertion - and pass control to the *deserving* function
//
bResult = ParseRegCmdLine( argc, argv, &lOperation, &bUsage ); if ( bResult == FALSE ) { dwExitCode = 1; ShowLastErrorEx( stderr, SLE_INTERNAL ); }
// check whether we need to display the usage
else if ( bUsage == TRUE ) { Usage( -1 ); dwExitCode = 0; }
// need to check the sub-option
else { //
// At this point we have a valid operation
//
switch( lOperation ) { case REG_QUERY: dwExitCode = QueryRegistry( argc, argv ); break;
case REG_DELETE: dwExitCode = DeleteRegistry( argc, argv ); break;
case REG_ADD: dwExitCode = AddRegistry( argc, argv ); break;
case REG_COPY: dwExitCode = CopyRegistry( argc, argv ); break;
case REG_SAVE: dwExitCode = SaveHive( argc, argv ); break;
case REG_RESTORE: dwExitCode = RestoreHive( argc, argv ); break;
case REG_LOAD: dwExitCode = LoadHive( argc, argv ); break;
case REG_UNLOAD: dwExitCode = UnLoadHive( argc, argv ); break;
case REG_COMPARE: dwExitCode = CompareRegistry( argc, argv ); break;
case REG_EXPORT: dwExitCode = ExportRegistry( argc, argv ); break;
case REG_IMPORT: dwExitCode = ImportRegistry( argc, argv ); break;
default: break; } }
ReleaseGlobals(); return dwExitCode; }
//------------------------------------------------------------------------//
//
// ParseRegCmdLine()
// Find out the operation - each operation parses it's own cmd-line
//
//------------------------------------------------------------------------//
BOOL ParseRegCmdLine( DWORD argc, LPCWSTR argv[], LONG* plOperation, BOOL* pbUsage ) { // local variables
LONG lIndex = 0;
// check the input
if ( argc == 0 || argv == NULL || plOperation == NULL || pbUsage == NULL ) { SaveErrorMessage( ERROR_INVALID_PARAMETER ); return FALSE; }
// just REG.EXE is error
if ( argc == 1 ) { SetReason( ERROR_INVALID_SYNTAX ); return FALSE; }
// prepare the parser data
*pbUsage = FALSE; *plOperation = -1; for( lIndex = 0; lIndex < REG_OPTIONS_COUNT; lIndex++ ) { if ( StringCompareEx( argv[ 1 ], g_wszOptions[ lIndex ], TRUE, 0 ) == 0 ) { // ...
*plOperation = lIndex;
// check the GPO -- if GPO is enabled, we should block the
// user from using the REGISTRY tool except to see the help
if ( argc >= 3 && IsRegistryToolDisabled() == TRUE && InString( argv[ 2 ], L"-?|/?|-h|/h", TRUE ) == FALSE ) { SetReason( GetResString2( IDS_REGDISABLED, 0 ) ); return FALSE; }
// ...
return TRUE; } }
// no option did match -- might be asking for help
if ( InString( argv[ 1 ], L"-?|/?|-h|/h", TRUE ) == TRUE ) { *pbUsage = TRUE; return TRUE; }
// rest is invalid syntax
SetReason2( 1, ERROR_INVALID_SYNTAX_EX, argv[ 1 ] ); return FALSE; }
BOOL InitGlobalData( LONG lOperation, PTREG_PARAMS pParams ) { // check the input
if ( pParams == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
if ( lOperation < 0 || lOperation >= REG_OPTIONS_COUNT ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
// init to zero's
SecureZeroMemory( pParams, sizeof( TREG_PARAMS ) );
pParams->lOperation = lOperation; // operation
pParams->hRootKey = HKEY_LOCAL_MACHINE; pParams->lRegDataType = (lOperation == REG_QUERY) ? -1 : REG_SZ; pParams->bAllValues = FALSE; pParams->bUseRemoteMachine = FALSE; pParams->bCleanRemoteRootKey = FALSE; pParams->bForce = FALSE; pParams->bRecurseSubKeys = FALSE; pParams->pwszMachineName = NULL; pParams->pwszFullKey = NULL; pParams->pwszSubKey = NULL; pParams->pwszValueName = NULL; pParams->pwszValue = NULL; StringCopy( pParams->wszSeparator, L"\\0", SIZE_OF_ARRAY( pParams->wszSeparator ) );
return TRUE; }
//------------------------------------------------------------------------//
//
// FreeAppVars()
//
//------------------------------------------------------------------------//
BOOL FreeGlobalData( PTREG_PARAMS pParams ) { if ( pParams->bCleanRemoteRootKey == TRUE ) { SafeCloseKey( &pParams->hRootKey ); }
FreeMemory( &pParams->pwszSubKey ); FreeMemory( &pParams->pwszFullKey ); FreeMemory( &pParams->pwszMachineName ); FreeMemory( &pParams->pwszSearchData ); FreeMemory( &pParams->pwszValueName ); FreeMemory( &pParams->pwszValue ); DestroyDynamicArray( &pParams->arrTypes );
return TRUE; }
//------------------------------------------------------------------------//
//
// Prompt() - Answer Y/N question if bForce == FALSE
//
//------------------------------------------------------------------------//
LONG Prompt( LPCWSTR pwszFormat, LPCWSTR pwszValue, LPCWSTR pwszList, BOOL bForce ) { // local variables
WCHAR wch; LONG lIndex = 0;
// check the input
if ( pwszFormat == NULL || pwszList == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return -1; }
if ( bForce == TRUE ) { return 1; }
do { if ( pwszValue != NULL ) { ShowMessageEx( stdout, 1, TRUE, pwszFormat, pwszValue ); } else { ShowMessage( stdout, pwszFormat ); }
fflush( stdin ); wch = (WCHAR) getwchar(); } while ((lIndex = FindChar2( pwszList, wch, TRUE, 0 )) == -1);
// check the character selected by the user
// NOTE: we assume the resource string will have "Y" as the first character
return (lIndex + 1); }
// break down [\\MachineName\]keyName
BOOL BreakDownKeyString( LPCWSTR pwszStr, PTREG_PARAMS pParams ) { // local variables
LONG lIndex = 0; DWORD dwLength = 0; LPWSTR pwszTemp = NULL; LPWSTR pwszTempStr = NULL; BOOL bResult = FALSE;
// check the input
if ( pwszStr == NULL || pParams == NULL ) { SaveErrorMessage( ERROR_INVALID_PARAMETER ); return FALSE; }
// check whether this function is being called for
// valid operation or not
if ( pParams->lOperation < 0 || pParams->lOperation >= REG_OPTIONS_COUNT ) { SaveErrorMessage( ERROR_INVALID_PARAMETER ); return FALSE; }
dwLength = StringLength( pwszStr, 0 ) + 1; pwszTempStr = (LPWSTR) AllocateMemory( dwLength * sizeof( WCHAR ) ); if ( pwszTempStr == NULL ) { SaveErrorMessage( -1 ); return FALSE; }
// copy the string name into temporary buffer
StringCopy( pwszTempStr, pwszStr, dwLength ); TrimString( pwszTempStr, TRIM_ALL );
//
// figure out machine name
//
bResult = TRUE; pwszTemp = pwszTempStr;
// machine name
if( StringLength( pwszTempStr, 0 ) > 2 && StringCompareEx( pwszTempStr, L"\\\\", TRUE, 2 ) == 0 ) { lIndex = FindChar2( pwszTempStr, L'\\', TRUE, 2 ); if(lIndex != -1) { pwszTemp = pwszTempStr + lIndex + 1; *(pwszTempStr + lIndex) = cwchNullChar; } else { pwszTemp = NULL; }
bResult = ParseMachineName( pwszTempStr, pParams ); }
// parse key name
if( bResult == TRUE ) { if( pwszTemp != NULL && StringLength( pwszTemp, 0 ) > 0) { bResult = ParseKeyName( pwszTemp, pParams ); } else { SetLastError( (DWORD) REGDB_E_KEYMISSING ); SetReason2( 1, ERROR_BADKEYNAME, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; } }
// release memory allocated
FreeMemory( &pwszTempStr );
// return
return bResult; }
//------------------------------------------------------------------------//
//
// FindAndAdjustKeyName()
//
// null out the cmdline based on what we think the end of the argument is
//
// we do this because users might not quote out the cmdline properly.
//
//------------------------------------------------------------------------//
LPWSTR AdjustKeyName( LPWSTR pwszStr ) { // local variables
DWORD dwLength = 0;
// check the input
if ( pwszStr == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return NULL; }
// determine the length of the text passed
dwLength = StringLength( pwszStr, 0 ); if ( dwLength > 1 && pwszStr[ dwLength - 1 ] == L'\\' ) { // nullify the last back slash
pwszStr[ dwLength - 1 ] = cwchNullChar; }
// return
return pwszStr; }
//------------------------------------------------------------------------//
//
// IsMachineName()
//
//------------------------------------------------------------------------//
BOOL ParseMachineName( LPCWSTR pwszStr, PTREG_PARAMS pParams ) { // local variables
DWORD dwLength = 0; BOOL bUseRemoteMachine = FALSE;
// check the input
if ( pwszStr == NULL || pParams == NULL ) { SaveErrorMessage( ERROR_INVALID_PARAMETER ); return FALSE; }
//
// copy string
//
bUseRemoteMachine = TRUE; if( StringCompareEx( pwszStr, L"\\\\", TRUE, 0 ) == 0 ) { SetLastError( (DWORD) REGDB_E_KEYMISSING ); SetReason2( 1, ERROR_BADKEYNAME, g_wszOptions[ pParams->lOperation ] ); return FALSE; } else if(StringCompareEx( pwszStr, L"\\\\.", TRUE, 0) == 0) { // current machine -- local
bUseRemoteMachine = FALSE; }
dwLength = StringLength( pwszStr, 0 ) + 1; pParams->pwszMachineName = (LPWSTR) AllocateMemory( dwLength * sizeof(WCHAR) ); if ( pParams->pwszMachineName == NULL ) { SaveErrorMessage( -1 ); return FALSE; }
StringCopy( pParams->pwszMachineName, pwszStr, dwLength ); pParams->bUseRemoteMachine = TRUE; SaveErrorMessage( ERROR_SUCCESS ); return TRUE; }
//------------------------------------------------------------------------//
//
// ParseKeyName()
//
// Pass the full registry path in szStr
//
// Based on input - Sets AppMember fields:
//
// hRootKey
// szKey
// szValueName
// szValue
//
//------------------------------------------------------------------------//
BOOL ParseKeyName( LPWSTR pwszStr, PTREG_PARAMS pParams ) { // local variables
LONG lIndex = 0; BOOL bResult = TRUE; DWORD dwSubKeySize = 0; DWORD dwRootKeySize = 0; DWORD dwFullKeySize = 0; LPWSTR pwszTemp = NULL; LPWSTR pwszRootKey = NULL;
// check the input
if ( pwszStr == NULL || pParams == NULL ) { SaveErrorMessage( ERROR_INVALID_PARAMETER ); return FALSE; }
// check whether this function is being called for
// valid operation or not
if ( pParams->lOperation < 0 || pParams->lOperation >= REG_OPTIONS_COUNT ) { SaveErrorMessage( ERROR_INVALID_PARAMETER ); return FALSE; }
//
// figure out what root key was specified
//
pwszTemp = NULL; lIndex = FindChar2( pwszStr, L'\\', TRUE, 0 ); if (lIndex != -1) { pwszTemp = pwszStr + lIndex + 1; *(pwszStr + lIndex) = cwchNullChar; }
if (*pwszStr == L'\"') { pwszStr += 1; }
//
// Check the ROOT has been entered
//
bResult = TRUE; dwRootKeySize = StringLength( STR_HKEY_CURRENT_CONFIG, 0 ) + 1; pwszRootKey = (LPWSTR) AllocateMemory( dwRootKeySize * sizeof(WCHAR) ); if ( pwszRootKey == NULL) { SaveErrorMessage( -1 ); return FALSE; }
if (StringCompareEx( pwszStr, STR_HKCU, TRUE, 0) == 0 || StringCompareEx( pwszStr, STR_HKEY_CURRENT_USER, TRUE, 0) == 0) { pParams->hRootKey = HKEY_CURRENT_USER; StringCopy( pwszRootKey, STR_HKEY_CURRENT_USER, dwRootKeySize );
// check remotable and loadable
if( pParams->bUseRemoteMachine == TRUE ) { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_NONREMOTABLEROOT, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; } else if( pParams->lOperation == REG_LOAD || pParams->lOperation == REG_UNLOAD ) { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_NONLOADABLEROOT, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; } } else if ( StringCompareEx( pwszStr, STR_HKCR, TRUE, 0 ) == 0 || StringCompareEx( pwszStr, STR_HKEY_CLASSES_ROOT, TRUE, 0 ) == 0) { pParams->hRootKey = HKEY_CLASSES_ROOT; StringCopy( pwszRootKey, STR_HKEY_CLASSES_ROOT, dwRootKeySize );
// check remotable and loadable
if( pParams->bUseRemoteMachine == TRUE ) { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_NONREMOTABLEROOT, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; } else if( pParams->lOperation == REG_LOAD || pParams->lOperation == REG_UNLOAD ) { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_NONLOADABLEROOT, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; } } else if ( StringCompareEx( pwszStr, STR_HKCC, TRUE, 0 ) == 0 || StringCompareEx( pwszStr, STR_HKEY_CURRENT_CONFIG, TRUE, 0 ) == 0) { pParams->hRootKey = HKEY_CURRENT_CONFIG; StringCopy( pwszRootKey, STR_HKEY_CURRENT_CONFIG, dwRootKeySize );
// check remotable and loadable
if( pParams->bUseRemoteMachine == TRUE ) { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_NONREMOTABLEROOT, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; } else if( pParams->lOperation == REG_LOAD || pParams->lOperation == REG_UNLOAD ) { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_NONLOADABLEROOT, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; } } else if ( StringCompareEx( pwszStr, STR_HKLM, TRUE, 0 ) == 0 || StringCompareEx( pwszStr, STR_HKEY_LOCAL_MACHINE, TRUE, 0 ) == 0) { pParams->hRootKey = HKEY_LOCAL_MACHINE; StringCopy( pwszRootKey, STR_HKEY_LOCAL_MACHINE, dwRootKeySize ); } else if ( StringCompareEx( pwszStr, STR_HKU, TRUE, 0 ) == 0 || StringCompareEx( pwszStr, STR_HKEY_USERS, TRUE, 0 ) == 0 ) { pParams->hRootKey = HKEY_USERS; StringCopy( pwszRootKey, STR_HKEY_USERS, dwRootKeySize ); } else { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_BADKEYNAME, g_wszOptions[ pParams->lOperation ] ); bResult = FALSE; }
if( bResult == TRUE ) { //
// parse the subkey
//
if ( pwszTemp == NULL ) { // only root key, subkey is empty
pParams->pwszSubKey = (LPWSTR) AllocateMemory( 1 * sizeof( WCHAR ) ); if ( pParams->pwszSubKey == NULL) { SaveErrorMessage( -1 ); bResult = FALSE; } else { pParams->pwszFullKey = (LPWSTR) AllocateMemory( dwRootKeySize * sizeof(WCHAR) ); if ( pParams->pwszFullKey == NULL ) { SaveErrorMessage( -1 ); bResult = FALSE; }
StringCopy( pParams->pwszFullKey, pwszRootKey, dwRootKeySize ); } } else { //
// figure out what root key was specified
//
pwszTemp = AdjustKeyName( pwszTemp ); if ( IsValidSubKey( pwszTemp ) == FALSE ) { bResult = FALSE; if ( GetLastError() == ERROR_INVALID_PARAMETER ) { SaveErrorMessage( -1 ); } else { SetLastError( (DWORD) MK_E_SYNTAX ); SetReason2( 1, ERROR_BADKEYNAME, g_wszOptions[ pParams->lOperation ] ); } } else { // get subkey
dwSubKeySize = StringLength( pwszTemp, 0 ) + 1; pParams->pwszSubKey = (LPWSTR) AllocateMemory( dwSubKeySize * sizeof(WCHAR) ); if( pParams->pwszSubKey == NULL ) { SaveErrorMessage( -1 ); bResult = FALSE; } else { StringCopy( pParams->pwszSubKey, pwszTemp, dwSubKeySize );
// get fullkey ( +2 ==> "/" + buffer )
dwFullKeySize = dwRootKeySize + dwSubKeySize + 2; pParams->pwszFullKey = (LPWSTR) AllocateMemory( dwFullKeySize * sizeof(WCHAR) ); if ( pParams->pwszFullKey == NULL ) { SaveErrorMessage( -1 ); bResult = FALSE; } else { StringCopy( pParams->pwszFullKey, pwszRootKey, dwFullKeySize ); StringConcat( pParams->pwszFullKey, L"\\", dwFullKeySize ); StringConcat( pParams->pwszFullKey, pParams->pwszSubKey, dwFullKeySize ); } } } } }
FreeMemory( &pwszRootKey ); return bResult; }
BOOL IsValidSubKey( LPCWSTR pwszSubKey ) { // local variables
LONG lLength = 0; LONG lIndex = -1; LONG lPrevIndex = -1;
if ( pwszSubKey == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } else if ( StringLength( pwszSubKey, 0 ) == 0 ) { SetLastError( (DWORD) NTE_BAD_KEY ); return FALSE; }
do { if ( lIndex != lPrevIndex ) { if ( lIndex - lPrevIndex == 1 || lIndex - lPrevIndex > 255 ) { SetLastError( (DWORD) NTE_BAD_KEY ); return FALSE; }
lPrevIndex = lIndex; } } while ((lIndex = FindChar2( pwszSubKey, L'\\', TRUE, lIndex + 1 )) != -1 );
// get the length of the subkey
lLength = StringLength( pwszSubKey, 0 );
if ( lPrevIndex == lLength - 1 || (lPrevIndex == -1 && lLength > 255) || (lLength - lPrevIndex > 255) ) { SetLastError( (DWORD) NTE_BAD_KEY ); return FALSE; }
SetLastError( NO_ERROR ); return TRUE; }
//------------------------------------------------------------------------//
//
// IsRegDataType()
//
//------------------------------------------------------------------------//
LONG IsRegDataType( LPCWSTR pwszStr ) { // local variables
LONG lResult = -1; LPWSTR pwszDup = NULL;
if ( pwszStr == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return -1; }
// create a duplicate string of the input string
pwszDup = StrDup( pwszStr ); if ( pwszDup == NULL ) { SetLastError( ERROR_OUTOFMEMORY ); return -1; }
// remove the unwanted spaces and tab characters
TrimString2( pwszDup, NULL, TRIM_ALL );
if( StringCompareEx( pwszDup, cwszRegSz, TRUE, 0 ) == 0) { lResult = REG_SZ; } else if( StringCompareEx( pwszDup, cwszRegExpandSz, TRUE, 0 ) == 0) { lResult = REG_EXPAND_SZ; } else if( StringCompareEx( pwszDup, cwszRegMultiSz, TRUE, 0 ) == 0) { lResult = REG_MULTI_SZ; } else if( StringCompareEx( pwszDup, cwszRegBinary, TRUE, 0 ) == 0) { lResult = REG_BINARY; } else if( StringCompareEx( pwszDup, cwszRegDWord, TRUE, 0 ) == 0) { lResult = REG_DWORD; } else if( StringCompareEx( pwszDup, cwszRegDWordLittleEndian, TRUE, 0 ) == 0) { lResult = REG_DWORD_LITTLE_ENDIAN; } else if( StringCompareEx( pwszDup, cwszRegDWordBigEndian, TRUE, 0 ) == 0) { lResult = REG_DWORD_BIG_ENDIAN; } else if( StringCompareEx( pwszDup, cwszRegNone, TRUE, 0) == 0 ) { lResult = REG_NONE; }
// free the memory
LocalFree( pwszDup ); pwszDup = NULL;
// ...
SetLastError( NO_ERROR ); return lResult; }
//------------------------------------------------------------------------//
//
// Usage() - Display Usage Information
//
//------------------------------------------------------------------------//
BOOL Usage( LONG lOperation ) { // display the banner
ShowMessage( stdout, L"\n" );
// display the help based on the operation
switch( lOperation ) { case REG_QUERY: ShowResMessage( stdout, IDS_USAGE_QUERY1 ); ShowResMessage( stdout, IDS_USAGE_QUERY2 ); ShowResMessage( stdout, IDS_USAGE_QUERY3 ); break;
case REG_ADD: ShowResMessage( stdout, IDS_USAGE_ADD1 ); ShowResMessage( stdout, IDS_USAGE_ADD2 ); break;
case REG_DELETE: ShowResMessage( stdout, IDS_USAGE_DELETE ); break;
case REG_COPY: ShowResMessage( stdout, IDS_USAGE_COPY ); break;
case REG_SAVE: ShowResMessage( stdout, IDS_USAGE_SAVE ); break;
case REG_RESTORE: ShowResMessage( stdout, IDS_USAGE_RESTORE ); break;
case REG_LOAD: ShowResMessage( stdout, IDS_USAGE_LOAD ); break;
case REG_UNLOAD: ShowResMessage( stdout, IDS_USAGE_UNLOAD ); break;
case REG_COMPARE: ShowResMessage( stdout, IDS_USAGE_COMPARE1 ); ShowResMessage( stdout, IDS_USAGE_COMPARE2 ); break;
case REG_EXPORT: ShowResMessage( stdout, IDS_USAGE_EXPORT ); break;
case REG_IMPORT: ShowResMessage( stdout, IDS_USAGE_IMPORT ); break;
case -1: default: ShowResMessage( stdout, IDS_USAGE_REG ); break; }
return TRUE; }
BOOL RegConnectMachine( PTREG_PARAMS pParams ) { // local variables
LONG lResult = 0; HKEY hKeyConnect = NULL;
// check the input
if ( pParams == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
lResult = ERROR_SUCCESS; if ( pParams->bUseRemoteMachine == TRUE ) { // close the remote key
if( pParams->hRootKey != NULL && pParams->bCleanRemoteRootKey == TRUE ) { SafeCloseKey( &pParams->hRootKey ); }
// connect to remote key
lResult = RegConnectRegistry( pParams->pwszMachineName, pParams->hRootKey, &hKeyConnect); if( lResult == ERROR_SUCCESS ) { // sanity check
if ( hKeyConnect != NULL ) { pParams->hRootKey = hKeyConnect; pParams->bCleanRemoteRootKey = TRUE; } else { lResult = ERROR_PROCESS_ABORTED; } } }
SetLastError( lResult ); return (lResult == ERROR_SUCCESS); }
BOOL SaveErrorMessage( LONG lLastError ) { // local variables
DWORD dwLastError = 0;
dwLastError = (lLastError < 0) ? GetLastError() : (DWORD) lLastError; switch( dwLastError ) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: { SetReason( ERROR_PATHNOTFOUND ); break; }
default: { SetLastError( dwLastError ); SaveLastError(); break; } }
return TRUE; }
LPCWSTR GetTypeStrFromType( LPWSTR pwszTypeStr, DWORD* pdwLength, DWORD dwType ) { // local variables
DWORD dw = 0; LPCWSTR pwsz = NULL;
for( dw = 0; dw < SIZE_OF_ARRAY( g_regTypes ); dw++ ) { if ( dwType == g_regTypes[ dw ].dwType ) { pwsz = g_regTypes[ dw ].pwszType; break; } }
if ( pwsz == NULL ) { SetLastError( ERROR_NOT_FOUND ); pwsz = cwszRegNone; }
// check the input buffers passed by the caller
if ( pwszTypeStr == NULL ) { if ( pdwLength != NULL ) { *pdwLength = StringLength( pwsz, 0 ); } } else if ( pdwLength == NULL || *pdwLength == 0 ) { SetLastError( ERROR_INVALID_PARAMETER ); pwsz = cwszNullString; } else { StringCopy( pwszTypeStr, pwsz, *pdwLength ); }
// return
return pwsz; }
BOOL ShowRegistryValue( PTREG_SHOW_INFO pShowInfo ) { // local variables
DWORD dw = 0; DWORD dwSize = 0; LPCWSTR pwszEnd = NULL; LPBYTE pByteData = NULL; BOOL bShowSeparator = FALSE; LPCWSTR pwszSeparator = NULL; LPCWSTR pwszValueName = NULL;
// check the input
if ( pShowInfo == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
// validate and the show the contents
// ignore mask
if ( (pShowInfo->dwFlags & RSI_IGNOREMASK) == RSI_IGNOREMASK ) { return TRUE; }
// check if the padding is required or not
if ( pShowInfo->dwPadLength != 0 ) { ShowMessageEx( stdout, 1, TRUE, L"%*s", pShowInfo->dwPadLength, L" " ); }
// value name
if ( (pShowInfo->dwFlags & RSI_IGNOREVALUENAME) == 0 ) { if ( pShowInfo->pwszValueName == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
// alignment flag and separator cannot go along
if ( pShowInfo->pwszSeparator != NULL && (pShowInfo->dwFlags & RSI_ALIGNVALUENAME) ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
// valuename = no name
pwszValueName = pShowInfo->pwszValueName; if( StringLength( pwszValueName, 0 ) == 0 ) { pwszValueName = GetResString2( IDS_NONAME, 0 ); }
// alignment
if ( pShowInfo->dwFlags & RSI_ALIGNVALUENAME ) { if ( pShowInfo->dwMaxValueNameLength == 0 ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
// show the value name
ShowMessageEx( stdout, 2, TRUE, L"%-*s", pShowInfo->dwMaxValueNameLength, pwszValueName ); } else { ShowMessage( stdout, pwszValueName ); }
// display the separator
if ( pShowInfo->pwszSeparator != NULL ) { ShowMessage( stdout, pShowInfo->pwszSeparator ); } else { ShowMessage( stdout, L" " ); } }
// type
if ( (pShowInfo->dwFlags & RSI_IGNORETYPE) == 0 ) { if ( pShowInfo->dwFlags & RSI_SHOWTYPENUMBER ) { ShowMessageEx( stdout, 2, TRUE, L"%s (%d)", GetTypeStrFromType( NULL, NULL, pShowInfo->dwType ), pShowInfo->dwType ); } else { ShowMessage( stdout, GetTypeStrFromType( NULL, NULL, pShowInfo->dwType ) ); }
// display the separator
if ( pShowInfo->pwszSeparator != NULL ) { ShowMessage( stdout, pShowInfo->pwszSeparator ); } else { ShowMessage( stdout, L" " ); } }
// value
if ( (pShowInfo->dwFlags & RSI_IGNOREVALUE) == 0 ) { dwSize = pShowInfo->dwSize; pByteData = pShowInfo->pByteData; if ( pByteData == NULL ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } else if ( dwSize != 0 ) {
switch( pShowInfo->dwType ) { default: case REG_LINK: case REG_BINARY: case REG_RESOURCE_LIST: case REG_FULL_RESOURCE_DESCRIPTOR: { for( dw = 0; dw < dwSize; dw++ ) { ShowMessageEx( stdout, 1, TRUE, L"%02X", pByteData[ dw ] ); } break; }
case REG_SZ: case REG_EXPAND_SZ: { ShowMessage( stdout, (LPCWSTR) pByteData ); break; }
case REG_DWORD: case REG_DWORD_BIG_ENDIAN: { ShowMessageEx( stdout, 1, TRUE, L"0x%x", *((DWORD*) pByteData) ); break; }
case REG_MULTI_SZ: { //
// Replace '\0' with "\0" for MULTI_SZ
//
pwszSeparator = L"\\0"; if ( pShowInfo->pwszMultiSzSeparator != NULL ) { pwszSeparator = pShowInfo->pwszMultiSzSeparator; }
// ...
pwszEnd = (LPCWSTR) pByteData; while( ((BYTE*) pwszEnd) < (pByteData + dwSize) ) { if( *pwszEnd == 0 ) { // enable the display of value separator and skip this
pwszEnd++; bShowSeparator = TRUE; } else { // check whether we need to display the separator or not
if ( bShowSeparator == TRUE ) { ShowMessage( stdout, pwszSeparator ); }
ShowMessage( stdout, pwszEnd ); pwszEnd += StringLength( pwszEnd, 0 ); } }
break; } } } }
// ...
ShowMessage( stdout, L"\n" );
// return
return TRUE; }
LPWSTR GetTemporaryFileName( LPCWSTR pwszSavedFilePath ) { // local variables
LONG lIndex = 0; DWORD dwTemp = 0; DWORD dwPathLength = 0; DWORD dwFileNameLength = 0; LPWSTR pwszPath = NULL; LPWSTR pwszFileName = NULL;
// allocate memory for path info
dwPathLength = MAX_PATH; pwszPath = (LPWSTR) AllocateMemory( (dwPathLength + 1) * sizeof( WCHAR ) ); if ( pwszPath == NULL ) { SetLastError( ERROR_OUTOFMEMORY ); return NULL; }
//
// get the temporary path location
dwTemp = GetTempPath( dwPathLength, pwszPath ); if ( dwTemp == 0 ) { FreeMemory( &pwszPath ); return NULL; } else if ( dwTemp >= dwPathLength ) { dwPathLength = dwTemp + 2; if ( ReallocateMemory( &pwszPath, (dwPathLength + 1) * sizeof( WCHAR ) ) == FALSE ) { FreeMemory( &pwszPath ); SetLastError( ERROR_OUTOFMEMORY ); return NULL; }
// this is a simple and silly check being done just to overcome the
// PREfix error -- ReAllocateMemory function will not return TRUE
// when the memory is not successfully allocated
if ( pwszPath == NULL ) { SetLastError( ERROR_OUTOFMEMORY ); return NULL; }
// try to get temporary path again
dwTemp = GetTempPath( dwPathLength, pwszPath ); if ( dwTemp == 0 ) { FreeMemory( &pwszPath ); return NULL; } else if ( dwTemp >= dwPathLength ) { FreeMemory( &pwszPath ); SetLastError( (DWORD) STG_E_UNKNOWN ); return FALSE; } }
//
// get the temporary file name
dwFileNameLength = MAX_PATH; pwszFileName = (LPWSTR) AllocateMemory( (dwFileNameLength + 1) * sizeof( WCHAR ) ); if ( pwszFileName == NULL ) { FreeMemory( &pwszPath ); SetLastError( ERROR_OUTOFMEMORY ); return NULL; }
// ...
dwTemp = GetTempFileName( pwszPath, L"REG", 0, pwszFileName ); if ( dwTemp == 0 ) { if ( pwszSavedFilePath != NULL && GetLastError() == ERROR_ACCESS_DENIED ) { SetLastError( ERROR_ACCESS_DENIED ); lIndex = StringLength( pwszSavedFilePath, 0 ) - 1; for( ; lIndex >= 0; lIndex-- ) { if ( pwszSavedFilePath[ lIndex ] == L'\\' ) { if ( lIndex >= (LONG) dwPathLength ) { dwPathLength = lIndex + 1; if ( ReallocateMemory( &pwszPath, (dwPathLength + 5) ) == FALSE ) { FreeMemory( &pwszPath ); FreeMemory( &pwszFileName ); return NULL; } }
// ...
StringCopy( pwszPath, pwszSavedFilePath, lIndex );
// break from the loop
break; } }
// check whether we got the path information or not
dwTemp = 0; if ( lIndex == -1 ) { StringCopy( pwszPath, L".", MAX_PATH ); }
// now again try to get the temporary file name
dwTemp = GetTempFileName( pwszPath, L"REG", 0, pwszFileName );
// ...
if ( dwTemp == 0 ) { FreeMemory( &pwszPath ); FreeMemory( &pwszFileName ); return NULL; } } else { FreeMemory( &pwszPath ); FreeMemory( &pwszFileName ); return NULL; } }
// release the memory allocated for path variable
FreeMemory( &pwszPath );
// since the API already created the file -- need to delete and pass just
// the file name to the caller
if ( DeleteFile( pwszFileName ) == FALSE ) { FreeMemory( &pwszPath ); return FALSE; }
// return temporary file name generated
return pwszFileName; }
BOOL IsRegistryToolDisabled() { // local variables
HKEY hKey = NULL; DWORD dwType = 0; DWORD dwValue = 0; DWORD dwLength = 0; BOOL bRegistryToolDisabled = FALSE;
bRegistryToolDisabled = FALSE; if ( RegOpenKey( HKEY_CURRENT_USER, REGSTR_PATH_POLICIES TEXT("\\") REGSTR_KEY_SYSTEM, &hKey ) == ERROR_SUCCESS ) { dwLength = sizeof( DWORD ); if ( RegQueryValueEx( hKey, REGSTR_VAL_DISABLEREGTOOLS, NULL, &dwType, (LPBYTE) &dwValue, &dwLength ) == ERROR_SUCCESS ) { if ( (dwType == REG_DWORD) && (dwLength == sizeof(DWORD)) && (dwValue != FALSE) ) { bRegistryToolDisabled = TRUE; } }
SafeCloseKey( &hKey ); }
return bRegistryToolDisabled; }
|