1893 lines
45 KiB
C
1893 lines
45 KiB
C
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
//
|
||
|
// Uncomment the next #define line to get debug trace info about
|
||
|
// Registry keys opened, created or closed.
|
||
|
//
|
||
|
// #define DBG_REG_HANDLES
|
||
|
//
|
||
|
|
||
|
|
||
|
extern HWND hwndFrame;
|
||
|
|
||
|
//
|
||
|
// Updated by DavidHov on 6/1/92:
|
||
|
//
|
||
|
// Centralized error handling;
|
||
|
// Eliminated "title" parameter from APIs; it's
|
||
|
// reserved now, so using it gives "invalid parameter"
|
||
|
//
|
||
|
//
|
||
|
// Updated by DavidHov on 1/6/93
|
||
|
//
|
||
|
// Chnaged FCreateRegKey and FOpenRegKey to always update
|
||
|
// the desired value; a null (empty) string is used if the
|
||
|
// operation has failed.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Local Prototypes
|
||
|
//
|
||
|
|
||
|
BOOL FDeleteTree( HKEY KeyHandle );
|
||
|
BOOL FSetRegValueSz( HKEY hKey, SZ szValueName, UINT TitleIndex, SZ szValueData );
|
||
|
BOOL FSetRegValueExpandSz( HKEY hKey, SZ szValueName, UINT TitleIndex, SZ szValueData );
|
||
|
BOOL FSetRegValueMultiSz( HKEY hKey, SZ szValueName, UINT TitleIndex, UINT ValueType, SZ szValueData );
|
||
|
BOOL FSetRegValueDword( HKEY hKey, SZ szValueName, UINT TitleIndex, SZ szValueData );
|
||
|
BOOL FSetRegValueBin( HKEY hKey, SZ szValueName, UINT TitleIndex, UINT ValueType, SZ szValueData );
|
||
|
|
||
|
PVOID SzToMultiSz( SZ sz, PDWORD cbData );
|
||
|
SZ MultiSzToSz( PVOID Data, DWORD cbData );
|
||
|
PVOID SzToBin( SZ sz, PDWORD cbData );
|
||
|
SZ BinToSz( PVOID Data, DWORD cbData );
|
||
|
SZ ValueDataToSz( DWORD ValueType, PVOID ValueData, DWORD cbData );
|
||
|
|
||
|
|
||
|
//
|
||
|
// Central error handling for all Registry processing errors.
|
||
|
//
|
||
|
void FUpdateRegLastError ( LONG Status, SZ szOp, SZ szName )
|
||
|
{
|
||
|
char RegLastError[25];
|
||
|
|
||
|
_ltoa( Status, RegLastError, 10 );
|
||
|
|
||
|
FAddSymbolValueToSymTab( REGLASTERROR, RegLastError );
|
||
|
|
||
|
/* Uncomment to display all registry errors and their origin */
|
||
|
|
||
|
#if defined(DBG_REG_HANDLES)
|
||
|
|
||
|
OutputDebugString( "SETUP: Reg Error in " );
|
||
|
OutputDebugString( szOp );
|
||
|
OutputDebugString( " = " );
|
||
|
OutputDebugString( RegLastError ) ;
|
||
|
if ( szName )
|
||
|
{
|
||
|
OutputDebugString( "; " );
|
||
|
OutputDebugString( szName ) ;
|
||
|
}
|
||
|
OutputDebugString( "\n" );
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
// Debugging helper routing for finding lost Registry handles.
|
||
|
|
||
|
void FDebugRegKey ( SZ szHandle, SZ szAction, SZ szName )
|
||
|
{
|
||
|
|
||
|
OutputDebugString( "SETUP: REGKEYTRACE: " );
|
||
|
OutputDebugString( szHandle );
|
||
|
OutputDebugString( " : " );
|
||
|
OutputDebugString( szAction );
|
||
|
OutputDebugString( " : " );
|
||
|
if ( szName )
|
||
|
{
|
||
|
OutputDebugString( szName ) ;
|
||
|
}
|
||
|
OutputDebugString( "\n" );
|
||
|
}
|
||
|
|
||
|
#if defined(DBG_REG_HANDLES)
|
||
|
#define DEBUGREGKEY(a,b,c) FDebugRegKey(a,b,c)
|
||
|
#else
|
||
|
#define DEBUGREGKEY(a,b,c)
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* FCreateRegKey
|
||
|
*
|
||
|
* Crates a key in the registry
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FCreateRegKey( SZ szHandle, SZ szKeyName, UINT TitleIndex, SZ szClass,
|
||
|
SZ Security, UINT Access, UINT Options, SZ szNewHandle,
|
||
|
CMO cmo )
|
||
|
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
HKEY hSubKey;
|
||
|
DWORD Disposition;
|
||
|
LONG Status;
|
||
|
char LibraryHandleSTR[25];
|
||
|
LPSECURITY_ATTRIBUTES SecurityAttributes;
|
||
|
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
//
|
||
|
// If the Security parameter is specified, it must contain the
|
||
|
// string "&<Address>" where <Address> is the decimal numeric
|
||
|
// representation of the memory address of a SECURITY_ATTRIBUTES
|
||
|
// structure.
|
||
|
//
|
||
|
if ( !Security || Security[0] != '\0' ) {
|
||
|
|
||
|
if ( Security[0] != '&' ) {
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
SecurityAttributes = (LPSECURITY_ATTRIBUTES)LongToHandle(atol( Security + 1 ));
|
||
|
|
||
|
if ( !SecurityAttributes ||
|
||
|
!IsValidSecurityDescriptor( SecurityAttributes->lpSecurityDescriptor )
|
||
|
) {
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
SecurityAttributes = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create the key
|
||
|
//
|
||
|
fOkay = !( Status = RegCreateKeyEx( hKey,
|
||
|
szKeyName,
|
||
|
0,
|
||
|
szClass,
|
||
|
Options,
|
||
|
Access,
|
||
|
SecurityAttributes,
|
||
|
&hSubKey,
|
||
|
&Disposition ));
|
||
|
|
||
|
// Prepare an initial null result
|
||
|
LibraryHandleSTR[0] = '\0' ;
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "CreateRegKey", szKeyName );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// If the key already existed, we error out.
|
||
|
//
|
||
|
if ( Disposition == REG_OPENED_EXISTING_KEY ) {
|
||
|
|
||
|
RegCloseKey( hSubKey );
|
||
|
FUpdateRegLastError( ERROR_CANTOPEN, "CreateRegKey", szKeyName );
|
||
|
fOkay = fFalse;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// Put the handle in the specified variable
|
||
|
//
|
||
|
LibraryHandleSTR[0] = '|';
|
||
|
|
||
|
#if defined(_WIN64)
|
||
|
_ui64toa( (DWORD_PTR)hSubKey, LibraryHandleSTR+1, 20 );
|
||
|
#else
|
||
|
_ultoa( (DWORD)hSubKey, LibraryHandleSTR+1, 10 );
|
||
|
#endif
|
||
|
|
||
|
DEBUGREGKEY( LibraryHandleSTR+1, "created", szKeyName ) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Always add the value to the symbol table, even if null (empty).
|
||
|
|
||
|
while ( !FAddSymbolValueToSymTab( szNewHandle, LibraryHandleSTR ) )
|
||
|
{
|
||
|
if ( !FHandleOOM( hwndFrame ) )
|
||
|
{
|
||
|
if ( fOkay )
|
||
|
{
|
||
|
RegCloseKey( hSubKey );
|
||
|
RegDeleteKey( hKey, szKeyName );
|
||
|
fOkay = fFalse;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FOpenRegKey
|
||
|
*
|
||
|
* Opens a key in the registry
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FOpenRegKey( SZ szHandle, SZ szMachineName, SZ szKeyName, UINT Access, SZ szNewHandle, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay = fTrue;
|
||
|
HKEY hKey;
|
||
|
HKEY hSubKey;
|
||
|
LONG Status;
|
||
|
char LibraryHandleSTR[25];
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
//
|
||
|
// If a remote machine is specified, we connect to the remote
|
||
|
// machine and use the new handle.
|
||
|
//
|
||
|
if ( szMachineName[0] != '\0' ) {
|
||
|
|
||
|
// BUGBUG ramonsa - Until RegConnectRegistry is operational
|
||
|
//
|
||
|
Status = ERROR_INVALID_PARAMETER;
|
||
|
fOkay = fFalse;
|
||
|
|
||
|
//
|
||
|
//fOkay = !(Status = RegConnectRegistry( szMachineName,
|
||
|
// hKey,
|
||
|
// &hKey
|
||
|
// );
|
||
|
|
||
|
} else if ( szKeyName[0] == '\0' ) {
|
||
|
|
||
|
//
|
||
|
// If no machine name was given then a subkey name must
|
||
|
// be given!
|
||
|
//
|
||
|
Status = ERROR_INVALID_PARAMETER;
|
||
|
fOkay = fFalse;
|
||
|
}
|
||
|
|
||
|
// Prepare an initial null result
|
||
|
LibraryHandleSTR[0] = '\0' ;
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
//
|
||
|
// If no subkey is given, we just want a root handle of the
|
||
|
// remote machine. Otherwise we must open the subkey (and
|
||
|
// close the handle if remote).
|
||
|
//
|
||
|
if ( szKeyName[0] == '\0' ) {
|
||
|
|
||
|
//
|
||
|
// The remote handle is what we want.
|
||
|
//
|
||
|
hSubKey = hKey;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// We want a subkey.
|
||
|
//
|
||
|
fOkay = !( Status = RegOpenKeyEx( hKey,
|
||
|
szKeyName,
|
||
|
0,
|
||
|
Access,
|
||
|
&hSubKey ));
|
||
|
|
||
|
//
|
||
|
// If a remote machine is specified, then hkey has
|
||
|
// a remote handle and we must close it.
|
||
|
//
|
||
|
if ( szMachineName[0] != '\0' ) {
|
||
|
RegCloseKey( hKey );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
//
|
||
|
// Put the handle in the specified variable
|
||
|
//
|
||
|
LibraryHandleSTR[0] = '|';
|
||
|
|
||
|
#if defined(_WIN64)
|
||
|
_ui64toa( (DWORD_PTR)hSubKey, LibraryHandleSTR+1, 20 );
|
||
|
#else
|
||
|
_ultoa( (DWORD)hSubKey, LibraryHandleSTR+1, 10 );
|
||
|
#endif
|
||
|
|
||
|
DEBUGREGKEY( LibraryHandleSTR+1, "opened ", szKeyName ) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
FUpdateRegLastError( Status, "OpenRegKey", szKeyName );
|
||
|
}
|
||
|
|
||
|
while ( !FAddSymbolValueToSymTab( szNewHandle, LibraryHandleSTR ) )
|
||
|
{
|
||
|
if ( !FHandleOOM( hwndFrame ) )
|
||
|
{
|
||
|
if ( fOkay )
|
||
|
{
|
||
|
RegCloseKey( hSubKey );
|
||
|
Status = 0;
|
||
|
fOkay = fFalse;
|
||
|
}
|
||
|
break ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FFlushRegKey
|
||
|
*
|
||
|
* Flushes a key in the registry
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FFlushRegKey( SZ szHandle, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
fOkay = !RegFlushKey( hKey );
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FCloseRegKey
|
||
|
*
|
||
|
* Close a key in the registry
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FCloseRegKey( SZ szHandle, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
LONG Status;
|
||
|
|
||
|
if ( szHandle[0] != '|' )
|
||
|
return fTrue;
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
if ( hKey == NULL )
|
||
|
return fTrue ;
|
||
|
|
||
|
DEBUGREGKEY( szHandle+1, "closed ", NULL ) ;
|
||
|
|
||
|
fOkay = !( Status = RegCloseKey( hKey ) );
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
FUpdateRegLastError( Status, "CloseRegKey", NULL );
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FDeleteRegKey
|
||
|
*
|
||
|
* Deletes a key from the registry
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FDeleteRegKey( SZ szHandle, SZ szKeyName, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
LONG Status;
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
fOkay = !( Status = RegDeleteKey( hKey, szKeyName ) );
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteRegKey", NULL );
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FDeleteRegTree
|
||
|
*
|
||
|
* Deletes a key and all its descentants from the registry
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FDeleteRegTree( SZ szHandle, SZ szKeyName, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
HKEY hSubKey;
|
||
|
LONG Status;
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
//
|
||
|
// Open the key
|
||
|
//
|
||
|
fOkay = !( Status = RegOpenKeyEx( hKey,
|
||
|
szKeyName,
|
||
|
0,
|
||
|
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
|
||
|
&hSubKey ) );
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteRegTree", szKeyName );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
fOkay = FDeleteTree( hSubKey );
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Now delete the key
|
||
|
//
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
fOkay = !( Status = RegCloseKey( hSubKey ) );
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteRegTree", szKeyName );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
fOkay = !RegDeleteKey( hKey, szKeyName );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FDeleteTree
|
||
|
*
|
||
|
* Recursively deletes all the descendants of a key
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FDeleteTree( HKEY KeyHandle )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
DWORD Index;
|
||
|
HKEY ChildHandle;
|
||
|
CHAR KeyName[ cchlFullPathMax ];
|
||
|
DWORD KeyNameLength;
|
||
|
CHAR ClassName[ cchlFullPathMax ];
|
||
|
DWORD ClassNameLength;
|
||
|
DWORD TitleIndex = 0 ;
|
||
|
DWORD NumberOfSubKeys;
|
||
|
DWORD MaxSubKeyLength;
|
||
|
DWORD MaxClassLength;
|
||
|
DWORD NumberOfValues;
|
||
|
DWORD MaxValueNameLength;
|
||
|
DWORD MaxValueDataLength;
|
||
|
DWORD SizeSecurityDescriptor;
|
||
|
FILETIME LastWriteTime;
|
||
|
LONG Status;
|
||
|
|
||
|
ClassNameLength = cchlFullPathMax;
|
||
|
|
||
|
if ( Status = RegQueryInfoKey( KeyHandle,
|
||
|
ClassName,
|
||
|
&ClassNameLength,
|
||
|
NULL,
|
||
|
&NumberOfSubKeys,
|
||
|
&MaxSubKeyLength,
|
||
|
&MaxClassLength,
|
||
|
&NumberOfValues,
|
||
|
&MaxValueNameLength,
|
||
|
&MaxValueDataLength,
|
||
|
&SizeSecurityDescriptor,
|
||
|
&LastWriteTime
|
||
|
) ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteTree", NULL );
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
|
||
|
for ( Index = 0; Index < NumberOfSubKeys; Index++ ) {
|
||
|
|
||
|
KeyNameLength = cchlFullPathMax;
|
||
|
|
||
|
if ( Status = RegEnumKey( KeyHandle,
|
||
|
0,
|
||
|
KeyName,
|
||
|
KeyNameLength
|
||
|
) ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteTree", NULL );
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef BUGBUG
|
||
|
|
||
|
// BUGBUG This should work when MAXIMUM_ALLOWED access works.
|
||
|
|
||
|
if ( Status = RegOpenKey( KeyHandle,
|
||
|
KeyName,
|
||
|
&ChildHandle
|
||
|
) ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteTree", NULL );
|
||
|
return fFalse;
|
||
|
}
|
||
|
#else
|
||
|
|
||
|
if ( Status = RegOpenKeyEx( KeyHandle,
|
||
|
KeyName,
|
||
|
0,
|
||
|
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
|
||
|
&ChildHandle
|
||
|
) ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteTree", NULL );
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
#endif // ROBERTRE
|
||
|
|
||
|
fOkay = FDeleteTree( ChildHandle );
|
||
|
|
||
|
//
|
||
|
// Whether DeleteTree of the ChildHandle succeeded or not, we'll
|
||
|
// try to close it.
|
||
|
//
|
||
|
RegCloseKey( ChildHandle );
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
if ( fOkay = !(Status = RegDeleteKey( KeyHandle, KeyName ) )) {
|
||
|
FUpdateRegLastError( Status, "DeleteTree", NULL );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
return fFalse;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FEnumRegKey
|
||
|
*
|
||
|
* Obtains subkey enumeration
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FEnumRegKey( SZ szHandle, SZ szInfVar, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay = fTrue;
|
||
|
HKEY hKey;
|
||
|
CHAR KeyName[ cbFullPathMax ];
|
||
|
CHAR Class[ cbFullPathMax ];
|
||
|
DWORD cbKeyName;
|
||
|
DWORD cbClass;
|
||
|
DWORD TitleIndex = 0 ;
|
||
|
FILETIME FileTime;
|
||
|
RGSZ rgszEnum;
|
||
|
UINT EnumSize;
|
||
|
RGSZ rgszKey;
|
||
|
SZ szInfo;
|
||
|
char szTitle[25];
|
||
|
UINT Index;
|
||
|
LONG Status;
|
||
|
DWORD NumberOfSubKeys;
|
||
|
DWORD MaxSubKeyLength;
|
||
|
DWORD MaxClassLength;
|
||
|
DWORD NumberOfValues;
|
||
|
DWORD MaxValueNameLength;
|
||
|
DWORD MaxValueDataLength;
|
||
|
DWORD SizeSecurityDescriptor;
|
||
|
FILETIME LastWriteTime;
|
||
|
|
||
|
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
while ( (rgszEnum = (RGSZ)SAlloc( (CB)( 1 * sizeof(SZ)))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
rgszEnum[0] = NULL;
|
||
|
EnumSize = 0;
|
||
|
cbClass = cbFullPathMax;
|
||
|
|
||
|
if ( Status = RegQueryInfoKey( hKey,
|
||
|
Class,
|
||
|
&cbClass,
|
||
|
NULL,
|
||
|
&NumberOfSubKeys,
|
||
|
&MaxSubKeyLength,
|
||
|
&MaxClassLength,
|
||
|
&NumberOfValues,
|
||
|
&MaxValueNameLength,
|
||
|
&MaxValueDataLength,
|
||
|
&SizeSecurityDescriptor,
|
||
|
&LastWriteTime
|
||
|
) ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "EnumRegKey", NULL );
|
||
|
return fFalse;
|
||
|
}
|
||
|
|
||
|
for ( Index = 0 ; Index < NumberOfSubKeys; Index++ ) {
|
||
|
|
||
|
cbKeyName = cbFullPathMax;
|
||
|
cbClass = cbFullPathMax;
|
||
|
|
||
|
if ( Status = RegEnumKeyEx( hKey,
|
||
|
Index,
|
||
|
KeyName,
|
||
|
&cbKeyName,
|
||
|
NULL,
|
||
|
(LPSTR)&Class,
|
||
|
&cbClass,
|
||
|
&FileTime ) ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "EnumRegKey", NULL );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Get a list in which to put the key information.
|
||
|
//
|
||
|
while ( (rgszKey = (RGSZ)SAlloc( (CB)( 4 * sizeof(SZ)))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
//
|
||
|
// Put the information in the list
|
||
|
//
|
||
|
_ultoa( TitleIndex, szTitle, 10 );
|
||
|
|
||
|
rgszKey[0] = KeyName;
|
||
|
rgszKey[1] = szTitle;
|
||
|
rgszKey[2] = Class;
|
||
|
rgszKey[3] = NULL;
|
||
|
|
||
|
//
|
||
|
// Transform the list into a string so that it can be added to the
|
||
|
// symbol table.
|
||
|
//
|
||
|
while ( (szInfo = SzListValueFromRgsz( rgszKey )) == (SZ)NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
while ( (rgszEnum = (RGSZ)SRealloc( rgszEnum,
|
||
|
(CB)( (EnumSize+2) * sizeof(SZ)))
|
||
|
) == NULL ) {
|
||
|
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
rgszEnum[EnumSize] = szInfo;
|
||
|
EnumSize++;
|
||
|
rgszEnum[EnumSize] = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SFree(rgszKey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Convert to SZ
|
||
|
//
|
||
|
while ( (szInfo = SzListValueFromRgsz( rgszEnum )) == (SZ)NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
//
|
||
|
// Add it to the symbol table.
|
||
|
//
|
||
|
while ( !FAddSymbolValueToSymTab( szInfVar, szInfo ) ) {
|
||
|
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SFree(szInfo);
|
||
|
}
|
||
|
|
||
|
FFreeRgsz( rgszEnum );
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FSetRegValue
|
||
|
*
|
||
|
* Sets a value under the given key
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FSetRegValue( SZ szHandle, SZ szValueName, UINT TitleIndex,
|
||
|
UINT ValueType, SZ szValueData, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
switch ( ValueType ) {
|
||
|
|
||
|
case REG_MULTI_SZ:
|
||
|
fOkay = FSetRegValueMultiSz( hKey, szValueName, TitleIndex, REG_MULTI_SZ, szValueData );
|
||
|
break;
|
||
|
|
||
|
case REG_SZ:
|
||
|
fOkay = FSetRegValueSz( hKey, szValueName, TitleIndex, szValueData );
|
||
|
break;
|
||
|
|
||
|
case REG_EXPAND_SZ:
|
||
|
fOkay = FSetRegValueExpandSz( hKey, szValueName, TitleIndex, szValueData );
|
||
|
break;
|
||
|
|
||
|
case REG_DWORD:
|
||
|
fOkay = FSetRegValueDword( hKey, szValueName, TitleIndex, szValueData );
|
||
|
break;
|
||
|
|
||
|
case REG_BINARY:
|
||
|
fOkay = FSetRegValueBin( hKey, szValueName, TitleIndex, REG_BINARY, szValueData );
|
||
|
break;
|
||
|
|
||
|
case REG_RESOURCE_LIST:
|
||
|
fOkay = FSetRegValueBin( hKey, szValueName, TitleIndex, REG_RESOURCE_LIST, szValueData );
|
||
|
break;
|
||
|
|
||
|
case REG_FULL_RESOURCE_DESCRIPTOR:
|
||
|
fOkay = FSetRegValueBin( hKey, szValueName, TitleIndex, REG_FULL_RESOURCE_DESCRIPTOR, szValueData );
|
||
|
break;
|
||
|
|
||
|
case REG_RESOURCE_REQUIREMENTS_LIST:
|
||
|
fOkay = FSetRegValueBin( hKey, szValueName, TitleIndex, REG_RESOURCE_REQUIREMENTS_LIST, szValueData );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fOkay = FSetRegValueBin( hKey, szValueName, TitleIndex, ValueType, szValueData );
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FGetRegValue
|
||
|
*
|
||
|
* Gets the specified value under the given key
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FGetRegValue( SZ szHandle, SZ szValueName, SZ szInfVar, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
DWORD cbData;
|
||
|
DWORD TitleIndex = 0 ;
|
||
|
DWORD ValueType;
|
||
|
PVOID ValueData;
|
||
|
SZ szValueData;
|
||
|
RGSZ rgszValue;
|
||
|
SZ szInfo;
|
||
|
LONG Status;
|
||
|
char szTitle[25];
|
||
|
char szValueType[25];
|
||
|
|
||
|
|
||
|
char szKClass[ MAX_PATH ];
|
||
|
DWORD cbKClass;
|
||
|
DWORD KTitleIndex = 0 ;
|
||
|
DWORD KSubKeys;
|
||
|
DWORD cbKMaxSubKeyLen;
|
||
|
DWORD cbKMaxClassLen;
|
||
|
DWORD KValues;
|
||
|
DWORD cbKMaxValueNameLen;
|
||
|
DWORD SizeSecurityDescriptor;
|
||
|
FILETIME KLastWriteTime;
|
||
|
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
//
|
||
|
// Get the size of the buffer needed
|
||
|
//
|
||
|
cbKClass = MAX_PATH;
|
||
|
fOkay = !( Status = RegQueryInfoKey ( hKey,
|
||
|
szKClass,
|
||
|
&cbKClass,
|
||
|
NULL,
|
||
|
&KSubKeys,
|
||
|
&cbKMaxSubKeyLen,
|
||
|
&cbKMaxClassLen,
|
||
|
&KValues,
|
||
|
&cbKMaxValueNameLen,
|
||
|
&cbData,
|
||
|
&SizeSecurityDescriptor,
|
||
|
&KLastWriteTime ) );
|
||
|
|
||
|
//cbData = 0;
|
||
|
//fOkay = !RegQueryValueEx( hKey,
|
||
|
// szValueName,
|
||
|
// NULL,
|
||
|
// NULL,
|
||
|
// NULL,
|
||
|
// &cbData );
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "GetRegValue", szValueName );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// Allocate the buffer and get the data
|
||
|
//
|
||
|
while ( (ValueData = (PVOID)SAlloc( (CB)( cbData ))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
fOkay = !( Status = RegQueryValueEx( hKey,
|
||
|
szValueName,
|
||
|
NULL,
|
||
|
&ValueType,
|
||
|
ValueData,
|
||
|
&cbData ) );
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "GetRegValue", szValueName );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
|
||
|
//
|
||
|
// Get a list in which to put the key information.
|
||
|
//
|
||
|
while ( (rgszValue = (RGSZ)SAlloc( (CB)( 5 * sizeof(SZ)))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
//
|
||
|
// Put the information in the list
|
||
|
//
|
||
|
if ( (fOkay = (szValueData = ValueDataToSz( ValueType, ValueData, cbData)) != NULL) ) {
|
||
|
|
||
|
_ultoa( TitleIndex, szTitle, 10 );
|
||
|
_ultoa( ValueType, szValueType, 10 );
|
||
|
|
||
|
rgszValue[0] = szValueName;
|
||
|
rgszValue[1] = szTitle;
|
||
|
rgszValue[2] = szValueType;
|
||
|
rgszValue[3] = szValueData;
|
||
|
rgszValue[4] = NULL;
|
||
|
|
||
|
//
|
||
|
// Transform the list into a string so that it can be added to the
|
||
|
// symbol table.
|
||
|
//
|
||
|
while ( (szInfo = SzListValueFromRgsz( rgszValue )) == (SZ)NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
//
|
||
|
// Add it to the symbol table.
|
||
|
//
|
||
|
while ( !FAddSymbolValueToSymTab( szInfVar, szInfo ) ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SFree(szInfo);
|
||
|
}
|
||
|
|
||
|
SFree( szValueData );
|
||
|
}
|
||
|
|
||
|
SFree( rgszValue );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SFree( ValueData );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FDeleteRegValue
|
||
|
*
|
||
|
* Deletes a value under the given key
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FDeleteRegValue( SZ szHandle, SZ szValueName, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
LONG Status;
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
fOkay = !( Status = RegDeleteValue( hKey, szValueName ) );
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "DeleteRegValue", szValueName );
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FEnumRegValue
|
||
|
*
|
||
|
* Obtains information for a value with a certain index.
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FEnumRegValue( SZ szHandle, SZ szInfVar, CMO cmo )
|
||
|
{
|
||
|
BOOL fOkay;
|
||
|
HKEY hKey;
|
||
|
DWORD cbData;
|
||
|
DWORD cbName;
|
||
|
DWORD TitleIndex = 0 ;
|
||
|
DWORD ValueType;
|
||
|
PVOID ValueData;
|
||
|
SZ szValueData;
|
||
|
DWORD cbValueData;
|
||
|
RGSZ rgszValue;
|
||
|
RGSZ rgszEnum;
|
||
|
UINT EnumSize;
|
||
|
SZ szInfo;
|
||
|
SZ szValueName;
|
||
|
DWORD cbValueName;
|
||
|
UINT Index;
|
||
|
LONG Status;
|
||
|
char szTitle[25];
|
||
|
char szValueType[25];
|
||
|
|
||
|
char szKClass[ cchlFullPathMax ];
|
||
|
DWORD cbKClass;
|
||
|
DWORD KTitleIndex = 0 ;
|
||
|
DWORD KSubKeys;
|
||
|
DWORD cbKMaxSubKeyLen;
|
||
|
DWORD cbKMaxClassLen;
|
||
|
DWORD SizeSecurityDescriptor;
|
||
|
DWORD KValues;
|
||
|
FILETIME KLastWriteTime;
|
||
|
|
||
|
hKey = (HKEY)LongToHandle(atol( szHandle + 1 ));
|
||
|
|
||
|
//
|
||
|
// Get the size of the buffer needed
|
||
|
//
|
||
|
cbKClass = MAX_PATH;
|
||
|
fOkay = !( Status = RegQueryInfoKey ( hKey,
|
||
|
szKClass,
|
||
|
&cbKClass,
|
||
|
NULL,
|
||
|
&KSubKeys,
|
||
|
&cbKMaxSubKeyLen,
|
||
|
&cbKMaxClassLen,
|
||
|
&KValues,
|
||
|
&cbName,
|
||
|
&cbData,
|
||
|
&SizeSecurityDescriptor,
|
||
|
&KLastWriteTime ) );
|
||
|
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "EnumRegValue", NULL );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// Allocate the buffer to get the data.
|
||
|
//
|
||
|
while ( (ValueData = (PVOID)SAlloc( (CB)( cbData ))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
//
|
||
|
// Allocate a buffer to get the name. Allow for the string terminator.
|
||
|
//
|
||
|
while ( (szValueName = (SZ)SAlloc( (CB)( ( ++cbName ) * sizeof( TCHAR ) ))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
|
||
|
//
|
||
|
// Allocate empty enum list.
|
||
|
//
|
||
|
while ( (rgszEnum = (RGSZ)SAlloc( (CB)( 1 * sizeof(SZ)))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
rgszEnum[0] = NULL;
|
||
|
EnumSize = 0;
|
||
|
|
||
|
|
||
|
for ( Index = 0 ; ; Index++ ) {
|
||
|
|
||
|
cbValueName = cbName;
|
||
|
cbValueData = cbData;
|
||
|
|
||
|
if ( Status = RegEnumValue( hKey,
|
||
|
Index,
|
||
|
szValueName,
|
||
|
&cbValueName,
|
||
|
NULL,
|
||
|
&ValueType,
|
||
|
ValueData,
|
||
|
&cbValueData ) ) {
|
||
|
|
||
|
FUpdateRegLastError( Status, "EnumRegValue", NULL );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Get a list in which to put the key information.
|
||
|
//
|
||
|
while ( (rgszValue = (RGSZ)SAlloc( (CB)( 5 * sizeof(SZ)))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
//
|
||
|
// Put the information in the list
|
||
|
//
|
||
|
if ( (fOkay = (szValueData = ValueDataToSz( ValueType, ValueData, cbValueData)) != NULL) ) {
|
||
|
|
||
|
_ultoa( TitleIndex, szTitle, 10 );
|
||
|
_ultoa( ValueType, szValueType, 10 );
|
||
|
|
||
|
rgszValue[0] = szValueName;
|
||
|
rgszValue[1] = szTitle;
|
||
|
rgszValue[2] = szValueType;
|
||
|
rgszValue[3] = szValueData;
|
||
|
rgszValue[4] = NULL;
|
||
|
|
||
|
//
|
||
|
// Transform the list into a string so that it can be added to the
|
||
|
// symbol table.
|
||
|
//
|
||
|
while ( (szInfo = SzListValueFromRgsz( rgszValue )) == (SZ)NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
|
||
|
while ( (rgszEnum = (RGSZ)SRealloc( rgszEnum,
|
||
|
(CB)( (EnumSize+2) * sizeof(SZ)))
|
||
|
) == NULL ) {
|
||
|
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
rgszEnum[EnumSize] = szInfo;
|
||
|
EnumSize++;
|
||
|
rgszEnum[EnumSize] = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SFree( szValueData );
|
||
|
}
|
||
|
|
||
|
SFree( rgszValue );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Convert to SZ
|
||
|
//
|
||
|
while ( (szInfo = SzListValueFromRgsz( rgszEnum )) == (SZ)NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fOkay ) {
|
||
|
//
|
||
|
// Add it to the symbol table.
|
||
|
//
|
||
|
while ( !FAddSymbolValueToSymTab( szInfVar, szInfo ) ) {
|
||
|
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
|
||
|
fOkay = fFalse;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SFree( szInfo );
|
||
|
}
|
||
|
|
||
|
FFreeRgsz( rgszEnum );
|
||
|
}
|
||
|
|
||
|
SFree( szValueName );
|
||
|
}
|
||
|
|
||
|
SFree( ValueData );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (cmo & cmoVital) ? fOkay : fTrue;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FSetRegValueSz
|
||
|
*
|
||
|
* Sets a value under the given key for SZ type
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FSetRegValueSz( HKEY hKey, SZ szValueName, UINT TitleIndex, SZ szValueData )
|
||
|
{
|
||
|
|
||
|
LONG Status;
|
||
|
|
||
|
Status = RegSetValueEx( hKey,
|
||
|
szValueName,
|
||
|
0,
|
||
|
REG_SZ,
|
||
|
szValueData,
|
||
|
lstrlen( szValueData ) + 1 );
|
||
|
|
||
|
if ( Status ) {
|
||
|
|
||
|
FUpdateRegLastError( Status,"SetRegValueSz", szValueName );
|
||
|
}
|
||
|
|
||
|
return !Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FSetRegValueExpandSz
|
||
|
*
|
||
|
* Sets a value under the given key for expand SZ type
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL
|
||
|
FSetRegValueExpandSz(
|
||
|
HKEY hKey,
|
||
|
SZ szValueName,
|
||
|
UINT TitleIndex,
|
||
|
SZ szValueData
|
||
|
)
|
||
|
{
|
||
|
|
||
|
LONG Status;
|
||
|
|
||
|
Status = RegSetValueEx( hKey,
|
||
|
szValueName,
|
||
|
0,
|
||
|
REG_EXPAND_SZ,
|
||
|
szValueData,
|
||
|
lstrlen( szValueData ) + 1 );
|
||
|
|
||
|
if ( Status ) {
|
||
|
|
||
|
FUpdateRegLastError( Status,"SetRegValueExpandSz", szValueName );
|
||
|
}
|
||
|
|
||
|
return !Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FSetRegValueMultiSz
|
||
|
*
|
||
|
* Sets a value under the given key for REG_MULTI_SZ type
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL
|
||
|
FSetRegValueMultiSz(
|
||
|
HKEY hKey,
|
||
|
SZ szValueName,
|
||
|
UINT TitleIndex,
|
||
|
UINT ValueType,
|
||
|
SZ szValueData
|
||
|
)
|
||
|
{
|
||
|
BOOL fOkay = fFalse;
|
||
|
PVOID Data;
|
||
|
DWORD cbData;
|
||
|
LONG Status;
|
||
|
|
||
|
Data = SzToMultiSz( szValueData, &cbData );
|
||
|
|
||
|
fOkay = !( Status = RegSetValueEx( hKey,
|
||
|
szValueName,
|
||
|
0,
|
||
|
ValueType,
|
||
|
Data,
|
||
|
cbData ) );
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
|
||
|
FUpdateRegLastError( Status,"SetRegValueMultiSz", szValueName );
|
||
|
}
|
||
|
|
||
|
if ( Data ) {
|
||
|
SFree( Data );
|
||
|
}
|
||
|
|
||
|
return fOkay;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FSetRegValueDword
|
||
|
*
|
||
|
* Sets a value under the given key for DWORD type
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FSetRegValueDword( HKEY hKey, SZ szValueName, UINT TitleIndex, SZ szValueData )
|
||
|
{
|
||
|
|
||
|
DWORD Data;
|
||
|
LONG Status;
|
||
|
|
||
|
Data = (DWORD)atol(szValueData );
|
||
|
|
||
|
Status = RegSetValueEx( hKey,
|
||
|
szValueName,
|
||
|
0,
|
||
|
REG_DWORD,
|
||
|
(LPBYTE)&Data,
|
||
|
sizeof( DWORD ) );
|
||
|
if ( Status ) {
|
||
|
|
||
|
FUpdateRegLastError( Status,"SetRegValueDword", szValueName );
|
||
|
}
|
||
|
|
||
|
return !Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FSetRegValueBin
|
||
|
*
|
||
|
* Sets a value under the given key for BINARY and unknown types
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
BOOL FSetRegValueBin( HKEY hKey, SZ szValueName, UINT TitleIndex,
|
||
|
UINT ValueType, SZ szValueData )
|
||
|
{
|
||
|
BOOL fOkay = fFalse;
|
||
|
PVOID Data;
|
||
|
DWORD cbData;
|
||
|
LONG Status;
|
||
|
|
||
|
Data = SzToBin( szValueData, &cbData );
|
||
|
|
||
|
fOkay = !( Status = RegSetValueEx( hKey,
|
||
|
szValueName,
|
||
|
0,
|
||
|
ValueType,
|
||
|
Data,
|
||
|
cbData ) );
|
||
|
|
||
|
if ( !fOkay ) {
|
||
|
switch( ValueType ) {
|
||
|
case REG_BINARY:
|
||
|
FUpdateRegLastError( Status,"SetRegValueBin", szValueName );
|
||
|
break;
|
||
|
|
||
|
case REG_RESOURCE_LIST:
|
||
|
FUpdateRegLastError( Status,"SetRegValueResourceList", szValueName );
|
||
|
break;
|
||
|
|
||
|
case REG_FULL_RESOURCE_DESCRIPTOR:
|
||
|
FUpdateRegLastError( Status,"SetRegValueFullResourceDescriptor", szValueName );
|
||
|
break;
|
||
|
|
||
|
case REG_RESOURCE_REQUIREMENTS_LIST:
|
||
|
FUpdateRegLastError( Status,"SetRegValueResourceRequirementsList", szValueName );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
FUpdateRegLastError( Status,"SetRegValueUnknownType", szValueName );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( Data ) {
|
||
|
SFree( Data );
|
||
|
}
|
||
|
|
||
|
return fOkay;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* SzToMultiSz
|
||
|
*
|
||
|
* Converts a list of sz strings to a single multi sz string
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
PVOID SzToMultiSz( SZ sz, PDWORD cbData )
|
||
|
{
|
||
|
RGSZ rgsz;
|
||
|
SZ p = NULL, q;
|
||
|
int i, j;
|
||
|
|
||
|
*cbData = 0;
|
||
|
|
||
|
if ( FListValue( sz )) {
|
||
|
|
||
|
if ( rgsz = RgszFromSzListValue( sz )) {
|
||
|
|
||
|
//
|
||
|
// Get size of required buffer
|
||
|
//
|
||
|
|
||
|
for (i = 0, j = 0; rgsz[i] != NULL; i++ ) {
|
||
|
j = j + strlen( rgsz[i] ) + 1;
|
||
|
}
|
||
|
j = j + 1; // for the last null
|
||
|
|
||
|
//
|
||
|
// Allocate buffer
|
||
|
//
|
||
|
|
||
|
while ( (p = q = (SZ)SAlloc( (CB)( j * sizeof( CHAR )))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( p ) {
|
||
|
|
||
|
for ( i=0; rgsz[i] != NULL; i++ ) {
|
||
|
lstrcpy( q, rgsz[ i ] );
|
||
|
q = q + lstrlen( rgsz[ i ] ) + 1;
|
||
|
}
|
||
|
*q = '\0';
|
||
|
*cbData = j * sizeof( CHAR );
|
||
|
}
|
||
|
|
||
|
FFreeRgsz( rgsz );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (PVOID)p;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* MultiSzToSz
|
||
|
*
|
||
|
* Converts a block of memory to a list containing hex digits
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
SZ MultiSzToSz( PVOID Data, DWORD cbData )
|
||
|
{
|
||
|
RGSZ rgsz;
|
||
|
SZ sz = NULL, szData, szEnd;
|
||
|
DWORD i, cbList = 0;
|
||
|
|
||
|
//
|
||
|
// Count the number of list elements in the multi sz list. We do this
|
||
|
// by counting the number of '0's in the string and subtracting 1 from
|
||
|
// this
|
||
|
//
|
||
|
|
||
|
szData = (SZ)( Data );
|
||
|
szEnd = (SZ)( (PBYTE)Data + cbData );
|
||
|
while( szData < szEnd ) {
|
||
|
if (*szData++ == '\0') {
|
||
|
cbList++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if( cbList > 0 ) {
|
||
|
|
||
|
cbList--; // remove the terminating null
|
||
|
|
||
|
//
|
||
|
// Allocate a rgsz list with cbList elements;
|
||
|
//
|
||
|
|
||
|
while ( (rgsz = (RGSZ)SAlloc( (CB)( (cbList + 1) * sizeof(SZ)))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( rgsz ) {
|
||
|
//
|
||
|
// Go through the szList and fill the rgsz structure
|
||
|
//
|
||
|
|
||
|
szData = (SZ)( Data );
|
||
|
|
||
|
for ( i = 0; i < cbList; i++ ) {
|
||
|
rgsz[i] = SzDupl( szData );
|
||
|
szData = szData + lstrlen( szData ) + 1;
|
||
|
}
|
||
|
rgsz[cbList] = NULL;
|
||
|
|
||
|
//
|
||
|
// Transform the list into a string.
|
||
|
//
|
||
|
|
||
|
while ( (sz = SzListValueFromRgsz( rgsz )) == (SZ)NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EvalAssert( FFreeRgsz( rgsz ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( sz );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* SzToBin
|
||
|
*
|
||
|
* Converts a list of hex digits to binary
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
PVOID SzToBin( SZ sz, PDWORD cbData )
|
||
|
{
|
||
|
RGSZ rgsz;
|
||
|
PBYTE p, q = NULL;
|
||
|
int i;
|
||
|
|
||
|
*cbData = 0;
|
||
|
|
||
|
if ( FListValue( sz )) {
|
||
|
|
||
|
if ( rgsz = RgszFromSzListValue( sz )) {
|
||
|
|
||
|
//
|
||
|
// Get size of required buffer
|
||
|
//
|
||
|
for (i=0; rgsz[i] != NULL; i++ );
|
||
|
|
||
|
//
|
||
|
// Allocate buffer
|
||
|
//
|
||
|
while ( (p = q = (PBYTE)SAlloc( (CB)( i ))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( p ) {
|
||
|
|
||
|
for ( i=0; rgsz[i] != NULL; i++ ) {
|
||
|
*p++ = (BYTE)atoi( rgsz[i] );
|
||
|
}
|
||
|
|
||
|
*cbData = i;
|
||
|
}
|
||
|
|
||
|
FFreeRgsz( rgsz );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return q;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* BinToSz
|
||
|
*
|
||
|
* Converts a block of memory to a list containing hex digits
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
SZ BinToSz( PVOID Data, DWORD cbData )
|
||
|
{
|
||
|
RGSZ rgsz;
|
||
|
SZ sz = NULL;
|
||
|
SZ szElement;
|
||
|
DWORD i;
|
||
|
PBYTE pbData;
|
||
|
|
||
|
|
||
|
//
|
||
|
// The list will contain cbData elements
|
||
|
//
|
||
|
while ( (rgsz = (RGSZ)SAlloc( (CB)( (cbData+1) * sizeof(SZ)))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( rgsz ) {
|
||
|
|
||
|
//
|
||
|
// For each element of the list, allocate a buffer and convert it
|
||
|
// to a string
|
||
|
//
|
||
|
pbData = (PBYTE)Data;
|
||
|
|
||
|
for (i=0; i<cbData; i++ ) {
|
||
|
|
||
|
while ( (szElement = (SZ)SAlloc( (CB)( 25 ))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( szElement ) {
|
||
|
_ultoa( *(pbData + i), szElement, 10 );
|
||
|
rgsz[i] = szElement;
|
||
|
|
||
|
} else {
|
||
|
rgsz[i] = NULL;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( i == cbData ) {
|
||
|
|
||
|
rgsz[i] = NULL;
|
||
|
|
||
|
//
|
||
|
// Transform the list into a string.
|
||
|
//
|
||
|
while ( (sz = SzListValueFromRgsz( rgsz )) == (SZ)NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FFreeRgsz( rgsz );
|
||
|
}
|
||
|
|
||
|
return sz;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* ValueDataToSz
|
||
|
*
|
||
|
* Converts a value data to its string form
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
*/
|
||
|
SZ ValueDataToSz( DWORD ValueType, PVOID ValueData, DWORD cbData )
|
||
|
{
|
||
|
SZ sz = NULL;
|
||
|
|
||
|
switch ( ValueType ) {
|
||
|
|
||
|
case REG_SZ:
|
||
|
sz = SzDupl((SZ)ValueData);
|
||
|
break;
|
||
|
|
||
|
case REG_EXPAND_SZ:
|
||
|
sz = SzDupl((SZ)ValueData);
|
||
|
break;
|
||
|
|
||
|
case REG_DWORD:
|
||
|
while ( (sz = (SZ)SAlloc( (CB)( 25 ))) == NULL ) {
|
||
|
if ( !FHandleOOM( hwndFrame ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( sz ) {
|
||
|
_ultoa( *(PDWORD)ValueData, sz, 10 );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
|
||
|
case REG_MULTI_SZ:
|
||
|
sz = MultiSzToSz( ValueData, cbData );
|
||
|
break;
|
||
|
|
||
|
|
||
|
case REG_BINARY:
|
||
|
default:
|
||
|
sz = BinToSz( ValueData, cbData );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return sz;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
RGSZ
|
||
|
MultiSzToRgsz(
|
||
|
IN PVOID MultiSz
|
||
|
)
|
||
|
{
|
||
|
PCHAR p;
|
||
|
ULONG Count;
|
||
|
RGSZ rgsz;
|
||
|
|
||
|
//
|
||
|
// First count the number of strings in the the multisz.
|
||
|
//
|
||
|
|
||
|
Count = 0;
|
||
|
p = MultiSz;
|
||
|
|
||
|
while(*p) {
|
||
|
Count++;
|
||
|
p = strchr(p,'\0') + 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Allocate the rgsz.
|
||
|
//
|
||
|
|
||
|
rgsz = (RGSZ)SAlloc((Count + 1) * sizeof(PCHAR));
|
||
|
|
||
|
if(rgsz == NULL) {
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
memset(rgsz,0,(Count + 1) * sizeof(PCHAR));
|
||
|
|
||
|
//
|
||
|
// Now place the strings in the rgsz.
|
||
|
//
|
||
|
|
||
|
p = MultiSz;
|
||
|
Count = 0;
|
||
|
|
||
|
while(*p) {
|
||
|
|
||
|
if(rgsz[Count++] = SzDupl((SZ)p)) {
|
||
|
|
||
|
p = strchr(p,'\0') + 1;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
FFreeRgsz(rgsz);
|
||
|
return(NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(rgsz);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
PCHAR
|
||
|
RgszToMultiSz(
|
||
|
IN RGSZ rgsz
|
||
|
)
|
||
|
{
|
||
|
ULONG Size;
|
||
|
ULONG Str;
|
||
|
PCHAR MultiSz;
|
||
|
|
||
|
//
|
||
|
// First determine the size of the block to hold the multisz.
|
||
|
//
|
||
|
|
||
|
Size = 0;
|
||
|
Str = 0;
|
||
|
|
||
|
while(rgsz[Str]) {
|
||
|
|
||
|
Size += strlen(rgsz[Str++]) + 1;
|
||
|
}
|
||
|
|
||
|
Size++; // for extra NUL to terminate the multisz.
|
||
|
|
||
|
MultiSz = SAlloc(Size);
|
||
|
|
||
|
if(MultiSz == NULL) {
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
Str = 0;
|
||
|
Size = 0;
|
||
|
|
||
|
while(rgsz[Str]) {
|
||
|
|
||
|
lstrcpy(MultiSz + Size, rgsz[Str]);
|
||
|
|
||
|
Size += lstrlen(rgsz[Str++]) + 1;
|
||
|
}
|
||
|
|
||
|
MultiSz[Size] = 0;
|
||
|
|
||
|
return(MultiSz);
|
||
|
}
|