You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1445 lines
40 KiB
1445 lines
40 KiB
//-----------------------------------------------------------------------//
|
|
//
|
|
// 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;
|
|
}
|