#include "regutil.h" #include "edithive.h" NTSTATUS RiInitializeRegistryFromAsciiFile( IN PUNICODE_STRING HiveName, IN PUNICODE_STRING FileName ); void Usage( void ) { fprintf( stderr, "usage: HIVEINI -f hivefile [files...]\n" ); exit( 1 ); } PVOID OldValueBuffer; ULONG OldValueBufferSize; typedef struct _KEY_INFO { ULONG IndentAmount; UNICODE_STRING Name; HANDLE HiveHandle; HANDLE Handle; LARGE_INTEGER LastWriteTime; } KEY_INFO, *PKEY_INFO; #define MAX_KEY_DEPTH 64 NTSTATUS RiInitializeRegistryFromAsciiFile( IN PUNICODE_STRING HiveName, IN PUNICODE_STRING FileName ) { NTSTATUS Status; REG_UNICODE_FILE UnicodeFile; PWSTR EndKey, FirstEqual, BeginValue; ULONG IndentAmount; UNICODE_STRING InputLine; UNICODE_STRING KeyName; UNICODE_STRING KeyValue; PKEY_VALUE_FULL_INFORMATION OldValueInformation; PKEY_BASIC_INFORMATION KeyInformation; UCHAR KeyInformationBuffer[ 512 ]; ULONG ResultLength; ULONG OldValueLength; PVOID ValueBuffer; ULONG ValueLength; ULONG ValueType; KEY_INFO KeyPath[ MAX_KEY_DEPTH ]; PKEY_INFO CurrentKey; ULONG KeyPathLength; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Class; ULONG Disposition; BOOLEAN UpdateKeyValue; ULONG i; HANDLE HiveHandle; HANDLE RootKey; UNICODE_STRING RootName; HiveHandle = EhOpenHive(HiveName, &KeyPath[0].Handle, &KeyPath[0].Name, TYPE_SIMPLE); if (HiveHandle == NULL) { return(STATUS_OBJECT_PATH_NOT_FOUND); } KeyPath[0].Handle = (HANDLE)HCELL_NIL; OldValueInformation = (PKEY_VALUE_FULL_INFORMATION)OldValueBuffer; Class.Buffer = NULL; Class.Length = 0; Status = RegLoadAsciiFileAsUnicode( FileName, &UnicodeFile ); if (!NT_SUCCESS( Status )) { return( Status ); } KeyPathLength = 0; while (RegGetNextLine( &UnicodeFile, &IndentAmount, &FirstEqual )) { #if 0 InputLine.Buffer = UnicodeFile.BeginLine; InputLine.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)UnicodeFile.BeginLine); InputLine.MaximumLength = InputLine.Length; printf( "GetNextLine: (%02u) '%wZ'\n", IndentAmount, &InputLine ); #endif if (FirstEqual == NULL) { KeyName.Buffer = UnicodeFile.BeginLine; KeyName.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)KeyName.Buffer); KeyName.MaximumLength = (USHORT)(KeyName.Length + 1); #if 0 printf( "%02u %04u KeyName: %wZ\n", KeyPathLength, IndentAmount, &KeyName ); #endif CurrentKey = &KeyPath[ KeyPathLength ]; if (KeyPathLength == 0 || IndentAmount > CurrentKey->IndentAmount ) { if (KeyPathLength == MAX_KEY_DEPTH) { fprintf( stderr, "HIVEINI: %wZ key exceeded maximum depth (%u) of tree.\n", &KeyName, MAX_KEY_DEPTH ); return( STATUS_UNSUCCESSFUL ); } KeyPathLength++; CurrentKey++; } else { do { CurrentKey->Handle = NULL; if (IndentAmount == CurrentKey->IndentAmount) { break; } CurrentKey--; if (--KeyPathLength == 1) { break; } } while (IndentAmount <= CurrentKey->IndentAmount); } #if 0 printf( " (%02u)\n", KeyPathLength ); #endif CurrentKey->Name = KeyName; CurrentKey->IndentAmount = IndentAmount; Status = EhCreateChild(HiveHandle, KeyPath[ KeyPathLength-1 ].Handle, &KeyName, &CurrentKey->Handle, &Disposition); if (NT_SUCCESS( Status )) { if (DebugOutput) { fprintf( stderr, " Created key %02x %wZ (%08x)\n", CurrentKey->IndentAmount, &CurrentKey->Name, CurrentKey->Handle ); } KeyInformation = (PKEY_BASIC_INFORMATION)KeyInformationBuffer; Status = EhQueryKey( HiveHandle, CurrentKey->Handle, KeyBasicInformation, KeyInformation, sizeof( KeyInformationBuffer ), &ResultLength ); if (NT_SUCCESS( Status )) { CurrentKey->LastWriteTime = KeyInformation->LastWriteTime; } else { RtlZeroMemory( &CurrentKey->LastWriteTime, sizeof( CurrentKey->LastWriteTime ) ); } if (Disposition == REG_CREATED_NEW_KEY) { printf( "Created Key: " ); for (i=0; i UnicodeFile.BeginLine && EndKey[ -1 ] <= L' ') { EndKey--; } KeyName.Buffer = UnicodeFile.BeginLine; KeyName.Length = (USHORT)((PCHAR)EndKey - (PCHAR)KeyName.Buffer); KeyName.MaximumLength = (USHORT)(KeyName.Length + 1); } BeginValue = FirstEqual + 1; while (BeginValue < UnicodeFile.EndOfLine && *BeginValue <= L' ') { BeginValue++; } KeyValue.Buffer = BeginValue; KeyValue.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)BeginValue); KeyValue.MaximumLength = (USHORT)(KeyValue.Length + 1); while (IndentAmount <= CurrentKey->IndentAmount) { if (DebugOutput) { fprintf( stderr, " Popping from key %02x %wZ (%08x)\n", CurrentKey->IndentAmount, &CurrentKey->Name, CurrentKey->Handle ); } CurrentKey->Handle = NULL; CurrentKey--; if (--KeyPathLength == 1) { break; } } if (DebugOutput) { fprintf( stderr, " Adding value '%wZ = %wZ' to key %02x %wZ (%08x)\n", &KeyName, &KeyValue, CurrentKey->IndentAmount, &CurrentKey->Name, CurrentKey->Handle ); } if (RegGetKeyValue( &KeyValue, &UnicodeFile, &ValueType, &ValueBuffer, &ValueLength ) ) { if (ValueBuffer == NULL) { Status = EhDeleteValueKey( HiveHandle, KeyPath[ KeyPathLength+1 ].Handle, &KeyValue ); if (NT_SUCCESS( Status )) { printf( "Delete value for Key: " ); for (i=0; i CurrentKey->LastWriteTime.QuadPart ) { Status = STATUS_UNSUCCESSFUL; UpdateKeyValue = TRUE; } else { Status = EhQueryValueKey( HiveHandle, CurrentKey->Handle, &KeyName, KeyValueFullInformation, OldValueInformation, OldValueBufferSize, &OldValueLength ); if (NT_SUCCESS( Status )) { UpdateKeyValue = TRUE; } else { UpdateKeyValue = FALSE; } } if (!NT_SUCCESS( Status ) || OldValueInformation->Type != ValueType || OldValueInformation->DataLength != ValueLength || !RtlEqualMemory( (PCHAR)OldValueInformation + OldValueInformation->DataOffset, ValueBuffer, ValueLength ) ) { Status = EhSetValueKey( HiveHandle, CurrentKey->Handle, &KeyName, 0, ValueType, ValueBuffer, ValueLength ); if (NT_SUCCESS( Status )) { printf( "%s value for Key: ", UpdateKeyValue ? "Updated" : "Created" ); for (i=1; i<=KeyPathLength; i++) { printf( "%wZ\\", &KeyPath[ i ].Name ); } if (KeyName.Length) { printf( "%wZ ", &KeyName ); } printf( "= '%wZ'\n", &KeyValue ); } else { fprintf( stderr, "HIVEINI: SetValueKey (%wZ) failed - %lx\n", &KeyName, Status ); } } RtlFreeHeap( RtlProcessHeap(), 0, ValueBuffer ); } } else { fprintf( stderr, "HIVEINI: Invalid key (%wZ) value (%wZ)\n", &KeyName, &KeyValue ); } } } EhCloseHive(HiveHandle); return( Status ); } int __cdecl main( argc, argv ) int argc; char *argv[]; { int i; char *s; NTSTATUS Status; BOOL FileArgumentSeen; BOOL HiveArgumentSeen=FALSE; ANSI_STRING AnsiString; UNICODE_STRING DosFileName; UNICODE_STRING FileName; UNICODE_STRING DosHiveName; UNICODE_STRING HiveName; OldValueBufferSize = VALUE_BUFFER_SIZE; OldValueBuffer = VirtualAlloc( NULL, OldValueBufferSize, MEM_COMMIT, PAGE_READWRITE ); if (OldValueBuffer == NULL) { fprintf( stderr, "HIVEINI: Unable to allocate value buffer.\n" ); exit( 1 ); } RegInitialize(); FileArgumentSeen = FALSE; HiveName.Length = HiveName.MaximumLength = 0; HiveName.Buffer = NULL; for (i=1; i