#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 "&
" where 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