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 }