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 }