test: hiveini.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# hiveini.c

Go to the documentation of this file.

    00001 #include "regutil.h"
    00002 #include "edithive.h"
    00003
    00004 NTSTATUS
    00005 RiInitializeRegistryFromAsciiFile(
    00006     IN PUNICODE_STRING HiveName,
    00007     IN PUNICODE_STRING FileName
    00008     );
    00009
    00010 void
    00011 Usage( void )
    00012 {
    00013     fprintf( stderr, "usage: HIVEINI -f hivefile [files...]\n" );
    00014     exit( 1 );
    00015 }
    00016
    00017 PVOID OldValueBuffer;
    00018 ULONG OldValueBufferSize;
    00019
    00020 typedef struct _KEY_INFO {
    00021     ULONG IndentAmount;
    00022     UNICODE_STRING Name;
    00023     HANDLE HiveHandle;
    00024     HANDLE Handle;
    00025     LARGE_INTEGER LastWriteTime;
    00026 } KEY_INFO, *PKEY_INFO;
    00027
    00028 #define MAX_KEY_DEPTH 64
    00029
    00030 NTSTATUS
    00031 RiInitializeRegistryFromAsciiFile(
    00032     IN PUNICODE_STRING HiveName,
    00033     IN PUNICODE_STRING FileName
    00034     )
    00035 {
    00036     NTSTATUS Status;
    00037     REG_UNICODE_FILE UnicodeFile;
    00038     PWSTR EndKey, FirstEqual, BeginValue;
    00039     ULONG IndentAmount;
    00040     UNICODE_STRING InputLine;
    00041     UNICODE_STRING KeyName;
    00042     UNICODE_STRING KeyValue;
    00043     PKEY_VALUE_FULL_INFORMATION OldValueInformation;
    00044     PKEY_BASIC_INFORMATION KeyInformation;
    00045     UCHAR KeyInformationBuffer[ 512 ];
    00046     ULONG ResultLength;
    00047     ULONG OldValueLength;
    00048     PVOID ValueBuffer;
    00049     ULONG ValueLength;
    00050     ULONG ValueType;
    00051     KEY_INFO KeyPath[ MAX_KEY_DEPTH ];
    00052     PKEY_INFO CurrentKey;
    00053     ULONG KeyPathLength;
    00054     OBJECT_ATTRIBUTES ObjectAttributes;
    00055     UNICODE_STRING Class;
    00056     ULONG Disposition;
    00057     BOOLEAN UpdateKeyValue;
    00058     ULONG i;
    00059     HANDLE HiveHandle;
    00060     HANDLE RootKey;
    00061     UNICODE_STRING RootName;
    00062
    00063     HiveHandle = EhOpenHive(HiveName,
    00064                             &KeyPath[0].Handle,
    00065                             &KeyPath[0].Name,
    00066                             TYPE_SIMPLE);
    00067     if (HiveHandle == NULL) {
    00068         return(STATUS_OBJECT_PATH_NOT_FOUND);
    00069     }
    00070     KeyPath[0].Handle = (HANDLE)HCELL_NIL;
    00071
    00072     OldValueInformation = (PKEY_VALUE_FULL_INFORMATION)OldValueBuffer;
    00073     Class.Buffer = NULL;
    00074     Class.Length = 0;
    00075
    00076     Status = RegLoadAsciiFileAsUnicode( FileName,
    00077                                         &UnicodeFile
    00078                                       );
    00079     if (!NT_SUCCESS( Status )) {
    00080         return( Status );
    00081         }
    00082
    00083     KeyPathLength = 0;
    00084     while (RegGetNextLine( &UnicodeFile, &IndentAmount, &FirstEqual )) {
    00085 #if 0
    00086         InputLine.Buffer = UnicodeFile.BeginLine;
    00087         InputLine.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)UnicodeFile.BeginLine);
    00088         InputLine.MaximumLength = InputLine.Length;
    00089         printf( "GetNextLine: (%02u) '%wZ'\n", IndentAmount, &InputLine );
    00090 #endif
    00091         if (FirstEqual == NULL) {
    00092             KeyName.Buffer = UnicodeFile.BeginLine;
    00093             KeyName.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)KeyName.Buffer);
    00094             KeyName.MaximumLength = (USHORT)(KeyName.Length + 1);
    00095
    00096 #if 0
    00097             printf( "%02u %04u  KeyName: %wZ\n", KeyPathLength, IndentAmount, &KeyName );
    00098 #endif
    00099             CurrentKey = &KeyPath[ KeyPathLength ];
    00100             if (KeyPathLength == 0 ||
    00101                 IndentAmount > CurrentKey->IndentAmount
    00102                ) {
    00103                 if (KeyPathLength == MAX_KEY_DEPTH) {
    00104                     fprintf( stderr,
    00105                              "HIVEINI: %wZ key exceeded maximum depth (%u) of tree.\n",
    00106                              &KeyName,
    00107                              MAX_KEY_DEPTH
    00108                            );
    00109
    00110                     return( STATUS_UNSUCCESSFUL );
    00111                     }
    00112                 KeyPathLength++;
    00113                 CurrentKey++;
    00114                 }
    00115             else {
    00116                 do {
    00117                     CurrentKey->Handle = NULL;
    00118                     if (IndentAmount == CurrentKey->IndentAmount) {
    00119                         break;
    00120                         }
    00121                     CurrentKey--;
    00122                     if (--KeyPathLength == 1) {
    00123                         break;
    00124                         }
    00125                     }
    00126                 while (IndentAmount <= CurrentKey->IndentAmount);
    00127                 }
    00128
    00129 #if 0
    00130             printf( "  (%02u)\n", KeyPathLength );
    00131 #endif
    00132             CurrentKey->Name = KeyName;
    00133             CurrentKey->IndentAmount = IndentAmount;
    00134             Status = EhCreateChild(HiveHandle,
    00135                                    KeyPath[ KeyPathLength-1 ].Handle,
    00136                                    &KeyName,
    00137                                    &CurrentKey->Handle,
    00138                                    &Disposition);
    00139
    00140             if (NT_SUCCESS( Status )) {
    00141                 if (DebugOutput) {
    00142                     fprintf( stderr, "    Created key %02x %wZ (%08x)\n",
    00143                                      CurrentKey->IndentAmount,
    00144                                      &CurrentKey->Name,
    00145                                      CurrentKey->Handle
    00146                            );
    00147                     }
    00148                 KeyInformation = (PKEY_BASIC_INFORMATION)KeyInformationBuffer;
    00149                 Status = EhQueryKey( HiveHandle,
    00150                                      CurrentKey->Handle,
    00151                                      KeyBasicInformation,
    00152                                      KeyInformation,
    00153                                      sizeof( KeyInformationBuffer ),
    00154                                      &ResultLength
    00155                                    );
    00156                 if (NT_SUCCESS( Status )) {
    00157                     CurrentKey->LastWriteTime = KeyInformation->LastWriteTime;
    00158                     }
    00159                 else {
    00160                     RtlZeroMemory( &CurrentKey->LastWriteTime,
    00161                                    sizeof( CurrentKey->LastWriteTime )
    00162                                  );
    00163
    00164                     }
    00165
    00166                 if (Disposition == REG_CREATED_NEW_KEY) {
    00167                     printf( "Created Key: " );
    00168                     for (i=0; i<KeyPathLength; i++) {
    00169                         printf( "%wZ\\", &KeyPath[ i ].Name );
    00170                         }
    00171                     printf( "%wZ\n", &KeyName );
    00172                     }
    00173                 }
    00174             else {
    00175                 fprintf( stderr,
    00176                          "HIVEINI: CreateKey (%wZ) relative to handle (%lx) failed - %lx\n",
    00177                          &KeyName,
    00178                          ObjectAttributes.RootDirectory,
    00179                          Status
    00180                        );
    00181                 }
    00182             }
    00183         else {
    00184             if (FirstEqual == UnicodeFile.BeginLine) {
    00185                 KeyName.Buffer = NULL;
    00186                 KeyName.Length = 0;
    00187                 KeyName.MaximumLength = 0;
    00188                 }
    00189             else {
    00190                 EndKey = FirstEqual;
    00191                 while (EndKey > UnicodeFile.BeginLine && EndKey[ -1 ] <= L' ') {
    00192                     EndKey--;
    00193                     }
    00194                 KeyName.Buffer = UnicodeFile.BeginLine;
    00195                 KeyName.Length = (USHORT)((PCHAR)EndKey - (PCHAR)KeyName.Buffer);
    00196                 KeyName.MaximumLength = (USHORT)(KeyName.Length + 1);
    00197                 }
    00198
    00199             BeginValue = FirstEqual + 1;
    00200             while (BeginValue < UnicodeFile.EndOfLine && *BeginValue <= L' ') {
    00201                 BeginValue++;
    00202                 }
    00203             KeyValue.Buffer = BeginValue;
    00204             KeyValue.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)BeginValue);
    00205             KeyValue.MaximumLength = (USHORT)(KeyValue.Length + 1);
    00206
    00207             while (IndentAmount <= CurrentKey->IndentAmount) {
    00208                 if (DebugOutput) {
    00209                     fprintf( stderr, "    Popping from key %02x %wZ (%08x)\n",
    00210                                      CurrentKey->IndentAmount,
    00211                                      &CurrentKey->Name,
    00212                                      CurrentKey->Handle
    00213                            );
    00214                     }
    00215                 CurrentKey->Handle = NULL;
    00216                 CurrentKey--;
    00217                 if (--KeyPathLength == 1) {
    00218                     break;
    00219                     }
    00220                 }
    00221             if (DebugOutput) {
    00222                 fprintf( stderr, "    Adding value '%wZ = %wZ' to key %02x %wZ (%08x)\n",
    00223                                  &KeyName,
    00224                                  &KeyValue,
    00225                                  CurrentKey->IndentAmount,
    00226                                  &CurrentKey->Name,
    00227                                  CurrentKey->Handle
    00228                        );
    00229                 }
    00230
    00231             if (RegGetKeyValue( &KeyValue,
    00232                                 &UnicodeFile,
    00233                                 &ValueType,
    00234                                 &ValueBuffer,
    00235                                 &ValueLength
    00236                               )
    00237                ) {
    00238                 if (ValueBuffer == NULL) {
    00239                     Status = EhDeleteValueKey( HiveHandle,
    00240                                                KeyPath[ KeyPathLength+1 ].Handle,
    00241                                                &KeyValue
    00242                                              );
    00243                     if (NT_SUCCESS( Status )) {
    00244                         printf( "Delete value for Key: " );
    00245                         for (i=0; i<KeyPathLength; i++) {
    00246                             printf( "%wZ\\", &KeyPath[ i ].Name );
    00247                             }
    00248                         printf( "%wZ\n", &KeyName );
    00249                         }
    00250                     }
    00251                 else {
    00252                     if ( UnicodeFile.LastWriteTime.QuadPart >
    00253                          CurrentKey->LastWriteTime.QuadPart
    00254                        ) {
    00255                         Status = STATUS_UNSUCCESSFUL;
    00256                         UpdateKeyValue = TRUE;
    00257                         }
    00258                     else {
    00259                         Status = EhQueryValueKey( HiveHandle,
    00260                                                   CurrentKey->Handle,
    00261                                                   &KeyName,
    00262                                                   KeyValueFullInformation,
    00263                                                   OldValueInformation,
    00264                                                   OldValueBufferSize,
    00265                                                   &OldValueLength
    00266                                                 );
    00267                         if (NT_SUCCESS( Status )) {
    00268                             UpdateKeyValue = TRUE;
    00269                             }
    00270                         else {
    00271                             UpdateKeyValue = FALSE;
    00272                             }
    00273                         }
    00274
    00275                     if (!NT_SUCCESS( Status ) ||
    00276                         OldValueInformation->Type != ValueType ||
    00277                         OldValueInformation->DataLength != ValueLength ||
    00278                         !RtlEqualMemory( (PCHAR)OldValueInformation +
    00279                                             OldValueInformation->DataOffset,
    00280                                           ValueBuffer,
    00281                                           ValueLength )
    00282                        ) {
    00283
    00284                         Status = EhSetValueKey( HiveHandle,
    00285                                                 CurrentKey->Handle,
    00286                                                 &KeyName,
    00287                                                 0,
    00288                                                 ValueType,
    00289                                                 ValueBuffer,
    00290                                                 ValueLength
    00291                                               );
    00292                         if (NT_SUCCESS( Status )) {
    00293                             printf( "%s value for Key: ",
    00294                                     UpdateKeyValue ? "Updated" : "Created"
    00295                                   );
    00296                             for (i=1; i<=KeyPathLength; i++) {
    00297                                 printf( "%wZ\\", &KeyPath[ i ].Name );
    00298                                 }
    00299
    00300                             if (KeyName.Length) {
    00301                                 printf( "%wZ ", &KeyName );
    00302                                 }
    00303                             printf( "= '%wZ'\n", &KeyValue );
    00304                             }
    00305                         else {
    00306                             fprintf( stderr,
    00307                                      "HIVEINI: SetValueKey (%wZ) failed - %lx\n",
    00308                                      &KeyName,
    00309                                      Status
    00310                                    );
    00311                             }
    00312                         }
    00313
    00314                     RtlFreeHeap( RtlProcessHeap(), 0, ValueBuffer );
    00315                     }
    00316                 }
    00317             else {
    00318                 fprintf( stderr,
    00319                          "HIVEINI: Invalid key (%wZ) value (%wZ)\n", &KeyName,
    00320                          &KeyValue
    00321                        );
    00322                 }
    00323             }
    00324         }
    00325
    00326         EhCloseHive(HiveHandle);
    00327
    00328     return( Status );
    00329 }
    00330
    00331
    00332 int
    00333 __cdecl main( argc, argv )
    00334 int argc;
    00335 char *argv[];
    00336 {
    00337     int i;
    00338     char *s;
    00339     NTSTATUS Status;
    00340     BOOL FileArgumentSeen;
    00341     BOOL HiveArgumentSeen=FALSE;
    00342     ANSI_STRING AnsiString;
    00343     UNICODE_STRING DosFileName;
    00344     UNICODE_STRING FileName;
    00345     UNICODE_STRING DosHiveName;
    00346     UNICODE_STRING HiveName;
    00347
    00348     OldValueBufferSize = VALUE_BUFFER_SIZE;
    00349     OldValueBuffer = VirtualAlloc( NULL, OldValueBufferSize, MEM_COMMIT, PAGE_READWRITE );
    00350     if (OldValueBuffer == NULL) {
    00351         fprintf( stderr, "HIVEINI: Unable to allocate value buffer.\n" );
    00352         exit( 1 );
    00353         }
    00354
    00355     RegInitialize();
    00356
    00357     FileArgumentSeen = FALSE;
    00358     HiveName.Length = HiveName.MaximumLength = 0;
    00359     HiveName.Buffer = NULL;
    00360     for (i=1; i<argc; i++) {
    00361         s = argv[ i ];
    00362         if (*s == '-' || *s == '/') {
    00363             while (*++s) {
    00364                 switch( tolower( *s ) ) {
    00365                     case 'd':
    00366                         DebugOutput = TRUE;
    00367                         break;
    00368
    00369                     case 'f':
    00370                         if (++i < argc) {
    00371                             RtlInitAnsiString(&AnsiString, argv[i]);
    00372                             RtlAnsiStringToUnicodeString( &DosHiveName,
    00373                                                           &AnsiString,
    00374                                                           TRUE );
    00375                             RtlDosPathNameToNtPathName_U( DosHiveName.Buffer,
    00376                                                           &HiveName,
    00377                                                           NULL,
    00378                                                           NULL );
    00379                             break;
    00380                         }
    00381
    00382                     default:    Usage();
    00383                     }
    00384                 }
    00385             }
    00386         else {
    00387             FileArgumentSeen = TRUE;
    00388             RtlInitAnsiString( &AnsiString, s );
    00389             Status = RtlAnsiStringToUnicodeString( &DosFileName, &AnsiString, TRUE );
    00390             if (NT_SUCCESS( Status )) {
    00391                 if (RtlDosPathNameToNtPathName_U( DosFileName.Buffer,
    00392                                                   &FileName,
    00393                                                   NULL,
    00394                                                   NULL
    00395                                                 )
    00396                    ) {
    00397                     Status = RiInitializeRegistryFromAsciiFile( &HiveName,
    00398                                                                 &FileName );
    00399                     if (!NT_SUCCESS( Status )) {
    00400                         fprintf( stderr,
    00401                                  "HIVEINI: Failed to load from %wZ - Status == %lx\n",
    00402                                  &FileName,
    00403                                  Status
    00404                            );
    00405                         }
    00406                     }
    00407                 else {
    00408                     Status = STATUS_UNSUCCESSFUL;
    00409                     fprintf( stderr,
    00410                              "HIVEINI: Unable to map Dos Name (%wZ) to NT name\n",
    00411                              &DosFileName
    00412                        );
    00413                     }
    00414                 }
    00415             else {
    00416                 fprintf( stderr,
    00417                          "HIVEINI: Unable to convert %s to unicode - Status == %lx\n",
    00418                          &AnsiString,
    00419                          Status
    00420                        );
    00421                 }
    00422             }
    00423         }
    00424
    00425     if (!FileArgumentSeen) {
    00426         RtlInitUnicodeString( &FileName, L"\\SystemRoot\\System32\\Config\\registry.sys" );
    00427         Status = RiInitializeRegistryFromAsciiFile( &HiveName,
    00428                                                     &FileName );
    00429         if (!NT_SUCCESS( Status )) {
    00430             fprintf( stderr,
    00431                      "HIVEINI: Failed to load from %wZ - Status == %lx\n",
    00432                      &FileName,
    00433                      Status
    00434                    );
    00435             }
    00436         else {
    00437             RtlInitUnicodeString( &FileName, L"\\SystemRoot\\System32\\Config\\registry.usr" );
    00438             Status = RiInitializeRegistryFromAsciiFile( &HiveName,
    00439                                                         &FileName );
    00440             if (!NT_SUCCESS( Status )) {
    00441                 fprintf( stderr,
    00442                          "HIVEINI: Failed to load from %wZ - Status == %lx\n",
    00443                          &FileName,
    00444                          Status
    00445                        );
    00446                 }
    00447             }
    00448         }
    00449
    00450     return( 0 );
    00451 }