00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "regutil.h"
00021
00022 #define RtlAllocateHeap(x,y,z) malloc(z)
00023 #define RtlFreeHeap(x,y,z) free(z)
00024
00025 UNICODE_STRING
RiOnKeyword;
00026 UNICODE_STRING
RiYesKeyword;
00027 UNICODE_STRING
RiTrueKeyword;
00028 UNICODE_STRING
RiOffKeyword;
00029 UNICODE_STRING
RiNoKeyword;
00030 UNICODE_STRING
RiFalseKeyword;
00031 UNICODE_STRING
RiDeleteKeyword;
00032 UNICODE_STRING
RiRegKeyword;
00033 UNICODE_STRING
RiRegNoneKeyword;
00034 UNICODE_STRING
RiRegSzKeyword;
00035 UNICODE_STRING
RiRegExpandSzKeyword;
00036 UNICODE_STRING
RiRegDwordKeyword;
00037 UNICODE_STRING
RiRegBinaryKeyword;
00038 UNICODE_STRING
RiRegBinaryFileKeyword;
00039 UNICODE_STRING
RiRegLinkKeyword;
00040 UNICODE_STRING
RiRegMultiSzKeyword;
00041 UNICODE_STRING
RiRegMultiSzFileKeyword;
00042 UNICODE_STRING
RiRegDateKeyword;
00043
00044
void
00045 RegInitialize(
void )
00046 {
00047
RtlInitUnicodeString( &
RiOnKeyword,
L"ON" );
00048
RtlInitUnicodeString( &
RiYesKeyword,
L"YES" );
00049
RtlInitUnicodeString( &
RiTrueKeyword,
L"TRUE" );
00050
RtlInitUnicodeString( &
RiOffKeyword,
L"OFF" );
00051
RtlInitUnicodeString( &
RiNoKeyword,
L"NO" );
00052
RtlInitUnicodeString( &
RiFalseKeyword,
L"FALSE" );
00053
RtlInitUnicodeString( &
RiDeleteKeyword,
L"DELETE" );
00054
RtlInitUnicodeString( &
RiRegKeyword,
L"REG_" );
00055
RtlInitUnicodeString( &
RiRegNoneKeyword,
L"REG_NONE" );
00056
RtlInitUnicodeString( &
RiRegSzKeyword,
L"REG_SZ" );
00057
RtlInitUnicodeString( &
RiRegExpandSzKeyword,
L"REG_EXPAND_SZ" );
00058
RtlInitUnicodeString( &
RiRegDwordKeyword,
L"REG_DWORD" );
00059
RtlInitUnicodeString( &
RiRegBinaryKeyword,
L"REG_BINARY" );
00060
RtlInitUnicodeString( &
RiRegBinaryFileKeyword,
L"REG_BINARYFILE" );
00061
RtlInitUnicodeString( &
RiRegLinkKeyword,
L"REG_LINK" );
00062
RtlInitUnicodeString( &
RiRegMultiSzKeyword,
L"REG_MULTI_SZ" );
00063
RtlInitUnicodeString( &
RiRegMultiSzFileKeyword,
L"REG_MULTISZFILE" );
00064
RtlInitUnicodeString( &
RiRegDateKeyword,
L"REG_DATE" );
00065 }
00066
00067
NTSTATUS
00068 RegReadMultiSzFile(
00069 IN PUNICODE_STRING FileName,
00070 OUT PVOID *ValueBuffer,
00071 OUT PULONG ValueLength
00072 )
00073 {
00074
NTSTATUS Status;
00075 UNICODE_STRING NtFileName;
00076 PWSTR s;
00077 UNICODE_STRING MultiSource;
00078 UNICODE_STRING MultiValue;
00079
REG_UNICODE_FILE MultiSzFile;
00080 ULONG MultiSzFileSize;
00081
00082
00083
FileName->Buffer[
FileName->Length/
sizeof(WCHAR) ] = UNICODE_NULL;
00084
00085
RtlDosPathNameToNtPathName_U(
FileName->Buffer,
00086 &NtFileName,
00087
NULL,
00088
NULL );
00089
00090
Status =
RegLoadAsciiFileAsUnicode( &NtFileName, &MultiSzFile );
00091
00092
if (!
NT_SUCCESS(
Status )) {
00093
return(
Status );
00094 }
00095
00096 MultiSzFileSize = (MultiSzFile.
EndOfFile -
00097 MultiSzFile.
NextLine) *
sizeof(WCHAR);
00098
00099 *ValueLength = 0;
00100 *
ValueBuffer =
RtlAllocateHeap( RtlProcessHeap(), 0,
00101 MultiSzFileSize);
00102
00103 MultiSource.Buffer = MultiSzFile.
NextLine;
00104
if (MultiSzFileSize <= MAXUSHORT) {
00105 MultiSource.Length =
00106 MultiSource.MaximumLength = (
USHORT)MultiSzFileSize;
00107 }
else {
00108 MultiSource.Length =
00109 MultiSource.MaximumLength = MAXUSHORT;
00110 }
00111
00112
while (
RegGetMultiString(&MultiSource, &MultiValue)) {
00113 RtlMoveMemory( (PUCHAR)*
ValueBuffer + *ValueLength,
00114 MultiValue.Buffer,
00115 MultiValue.Length );
00116 *ValueLength += MultiValue.Length;
00117
00118 s = MultiSource.Buffer;
00119
while ( *s !=
L'"' &&
00120 *s !=
L',' &&
00121 ((s - MultiSource.Buffer) *
sizeof(WCHAR)) <
00122 MultiSource.Length ) s++;
00123
if ( ((s - MultiSource.Buffer) *
sizeof(WCHAR)) ==
00124 MultiSource.Length ||
00125 *s ==
L',' ||
00126 *s ==
L';' ) {
00127
00128 ((PWSTR)*
ValueBuffer)[ *ValueLength /
sizeof(WCHAR) ] =
00129 UNICODE_NULL;
00130 *ValueLength +=
sizeof(UNICODE_NULL);
00131
if ( *s ==
L';' ) {
00132
break;
00133 }
00134 }
00135
00136
if ( (MultiSzFile.
EndOfFile - MultiSource.Buffer) *
sizeof(WCHAR) >=
00137 MAXUSHORT ) {
00138 MultiSource.Length =
00139 MultiSource.MaximumLength = MAXUSHORT;
00140 }
else {
00141 MultiSource.Length =
00142 MultiSource.MaximumLength =
00143 (
USHORT)((MultiSzFile.
EndOfFile - MultiSource.Buffer) *
00144
sizeof(WCHAR));
00145 }
00146 }
00147
00148 ((PWSTR)*
ValueBuffer)[ *ValueLength /
sizeof(WCHAR) ] = UNICODE_NULL;
00149 *ValueLength +=
sizeof(UNICODE_NULL);
00150
00151
00152
00153
00154
return(
TRUE );
00155 }
00156
00157
NTSTATUS
00158 RegReadBinaryFile(
00159 IN PUNICODE_STRING FileName,
00160 OUT PVOID *ValueBuffer,
00161 OUT PULONG ValueLength
00162 )
00163 {
00164
NTSTATUS Status;
00165 UNICODE_STRING NtFileName;
00166 OBJECT_ATTRIBUTES
ObjectAttributes;
00167 IO_STATUS_BLOCK IoStatus;
00168 HANDLE
File;
00169 FILE_STANDARD_INFORMATION FileInformation;
00170 WCHAR
FileNameBuffer[ 256 ];
00171 PWSTR s;
00172
00173
FileName->Buffer[
FileName->Length/
sizeof(WCHAR) ] = UNICODE_NULL;
00174 wcscpy(
FileNameBuffer,
L"\\DosDevices\\" );
00175 s = wcscat(
FileNameBuffer,
FileName->Buffer );
00176
while (*s != UNICODE_NULL) {
00177
if (*s ==
L'/') {
00178 *s =
L'\\';
00179 }
00180 s++;
00181 }
00182
RtlInitUnicodeString( &NtFileName,
FileNameBuffer );
00183
00184 InitializeObjectAttributes( &
ObjectAttributes,
00185 &NtFileName,
00186 OBJ_CASE_INSENSITIVE,
00187 (HANDLE)
NULL,
00188
NULL
00189 );
00190
00191
Status =
NtOpenFile( &
File,
00192 SYNCHRONIZE | GENERIC_READ,
00193 &
ObjectAttributes,
00194 &IoStatus,
00195 FILE_SHARE_DELETE |
00196 FILE_SHARE_READ |
00197 FILE_SHARE_WRITE,
00198 FILE_SYNCHRONOUS_IO_NONALERT |
00199 FILE_NON_DIRECTORY_FILE
00200 );
00201
if (!
NT_SUCCESS(
Status )) {
00202
return(
Status );
00203 }
00204
00205
Status =
NtQueryInformationFile(
File,
00206 &IoStatus,
00207 (PVOID)&FileInformation,
00208
sizeof( FileInformation ),
00209 FileStandardInformation
00210 );
00211
if (
NT_SUCCESS(
Status )) {
00212
if (FileInformation.EndOfFile.HighPart) {
00213
Status = STATUS_BUFFER_OVERFLOW;
00214 }
00215 }
00216
if (!
NT_SUCCESS(
Status )) {
00217
NtClose(
File );
00218
return(
Status );
00219 }
00220
00221 *ValueLength = FileInformation.EndOfFile.LowPart;
00222 *
ValueBuffer =
RtlAllocateHeap( RtlProcessHeap(), 0, *ValueLength );
00223
if (*
ValueBuffer ==
NULL) {
00224
Status = STATUS_NO_MEMORY;
00225 }
00226
00227
if (
NT_SUCCESS(
Status )) {
00228
Status =
NtReadFile(
File,
00229
NULL,
00230
NULL,
00231
NULL,
00232 &IoStatus,
00233 *
ValueBuffer,
00234 *ValueLength,
00235
NULL,
00236
NULL
00237 );
00238
00239
if (
NT_SUCCESS(
Status )) {
00240
Status = IoStatus.Status;
00241
00242
if (
NT_SUCCESS(
Status )) {
00243
if (IoStatus.Information != *ValueLength) {
00244
Status = STATUS_END_OF_FILE;
00245 }
00246 }
00247 }
00248
00249
if (!
NT_SUCCESS(
Status )) {
00250
RtlFreeHeap( RtlProcessHeap(), 0, *
ValueBuffer );
00251 }
00252 }
00253
00254
NtClose(
File );
00255
return(
Status );
00256 }
00257
00258
NTSTATUS
00259 RegLoadAsciiFileAsUnicode(
00260 IN PUNICODE_STRING FileName,
00261 OUT
PREG_UNICODE_FILE UnicodeFile
00262 )
00263 {
00264
NTSTATUS Status;
00265 OBJECT_ATTRIBUTES
ObjectAttributes;
00266 IO_STATUS_BLOCK IoStatus;
00267 HANDLE
File;
00268 FILE_BASIC_INFORMATION FileDateTimeInfo;
00269 FILE_STANDARD_INFORMATION FileInformation;
00270 ULONG
BufferSize, i, i1, LineCount;
00271 PVOID BufferBase;
00272 PCHAR Src, Src1;
00273 PWSTR Dst;
00274
00275 InitializeObjectAttributes( &
ObjectAttributes,
00276
FileName,
00277 OBJ_CASE_INSENSITIVE,
00278 (HANDLE)
NULL,
00279
NULL
00280 );
00281
00282
Status =
NtOpenFile( &
File,
00283 SYNCHRONIZE | GENERIC_READ,
00284 &
ObjectAttributes,
00285 &IoStatus,
00286 FILE_SHARE_DELETE |
00287 FILE_SHARE_READ |
00288 FILE_SHARE_WRITE,
00289 FILE_SYNCHRONOUS_IO_NONALERT |
00290 FILE_NON_DIRECTORY_FILE
00291 );
00292
if (!
NT_SUCCESS(
Status )) {
00293
return(
Status );
00294 }
00295
00296
Status =
NtQueryInformationFile(
File,
00297 &IoStatus,
00298 (PVOID)&FileInformation,
00299
sizeof( FileInformation ),
00300 FileStandardInformation
00301 );
00302
if (
NT_SUCCESS(
Status )) {
00303
if (FileInformation.EndOfFile.HighPart) {
00304
Status = STATUS_BUFFER_OVERFLOW;
00305 }
00306 }
00307
if (!
NT_SUCCESS(
Status )) {
00308
NtClose(
File );
00309
return(
Status );
00310 }
00311
00312
00313
BufferSize = FileInformation.EndOfFile.LowPart *
sizeof( WCHAR );
00314
BufferSize +=
sizeof( UNICODE_NULL );
00315 BufferBase =
NULL;
00316
Status =
NtAllocateVirtualMemory( NtCurrentProcess(),
00317 (PVOID *)&BufferBase,
00318 0,
00319 &
BufferSize,
00320 MEM_COMMIT,
00321 PAGE_READWRITE
00322 );
00323
if (
NT_SUCCESS(
Status )) {
00324 Src = (PCHAR)BufferBase + ((FileInformation.EndOfFile.LowPart+1) & ~1);
00325 Dst = (PWSTR)BufferBase;
00326
Status =
NtReadFile(
File,
00327
NULL,
00328
NULL,
00329
NULL,
00330 &IoStatus,
00331 Src,
00332 FileInformation.EndOfFile.LowPart,
00333
NULL,
00334
NULL
00335 );
00336
00337
if (
NT_SUCCESS(
Status )) {
00338
Status = IoStatus.Status;
00339
00340
if (
NT_SUCCESS(
Status )) {
00341
if (IoStatus.Information != FileInformation.EndOfFile.LowPart) {
00342
Status = STATUS_END_OF_FILE;
00343 }
00344
else {
00345
Status =
NtQueryInformationFile(
File,
00346 &IoStatus,
00347 (PVOID)&FileDateTimeInfo,
00348
sizeof( FileDateTimeInfo ),
00349 FileBasicInformation
00350 );
00351 }
00352 }
00353 }
00354
00355
if (!
NT_SUCCESS(
Status )) {
00356
NtFreeVirtualMemory( NtCurrentProcess(),
00357 (PVOID *)&BufferBase,
00358 &
BufferSize,
00359 MEM_RELEASE
00360 );
00361 }
00362 }
00363
00364
NtClose(
File );
00365
if (!
NT_SUCCESS(
Status )) {
00366
return(
Status );
00367 }
00368
00369 i = 0;
00370
while (i < FileInformation.EndOfFile.LowPart) {
00371
if (i > 1 && (Src[-2] ==
' ' || Src[-2] ==
'\t') &&
00372 Src[-1] ==
'\\' && (*Src ==
'\r' || *Src ==
'\n')
00373 ) {
00374
if (Dst[-1] ==
L'\\') {
00375 --Dst;
00376 }
00377
while (Dst > (PWSTR)BufferBase) {
00378
if (Dst[-1] >
L' ') {
00379
break;
00380 }
00381 Dst--;
00382 }
00383 LineCount = 0;
00384
while (i < FileInformation.EndOfFile.LowPart) {
00385
if (*Src ==
'\n') {
00386 i++;
00387 Src++;
00388 LineCount++;
00389 }
00390
else
00391
if (*Src ==
'\r' &&
00392 (i+1) < FileInformation.EndOfFile.LowPart &&
00393 Src[ 1 ] ==
'\n'
00394 ) {
00395 i += 2;
00396 Src += 2;
00397 LineCount++;
00398 }
00399
else {
00400
break;
00401 }
00402 }
00403
00404
if (LineCount > 1) {
00405 *Dst++ =
L'\n';
00406 }
00407
else {
00408 *Dst++ =
L' ';
00409
while (i < FileInformation.EndOfFile.LowPart && (*Src ==
' ' || *Src ==
'\t')) {
00410 i++;
00411 Src++;
00412 }
00413 }
00414
00415
if (i >= FileInformation.EndOfFile.LowPart) {
00416
break;
00417 }
00418 }
00419
else
00420
if ((*Src ==
'\r' && Src[1] ==
'\n') || *Src ==
'\n') {
00421
while (
TRUE) {
00422
while (i < FileInformation.EndOfFile.LowPart && (*Src ==
'\r' || *Src ==
'\n')) {
00423 i++;
00424 Src++;
00425 }
00426 Src1 = Src;
00427 i1 = i;
00428
while (i1 < FileInformation.EndOfFile.LowPart && (*Src1 ==
' ' || *Src1 ==
'\t')) {
00429 i1++;
00430 Src1++;
00431 }
00432
if (i1 < FileInformation.EndOfFile.LowPart &&
00433 (*Src1 ==
'\r' && Src1[1] ==
'\n') || *Src1 ==
'\n'
00434 ) {
00435 Src = Src1;
00436 i = i1;
00437 }
00438
else {
00439
break;
00440 }
00441 }
00442
00443 *Dst++ =
L'\n';
00444 }
00445
else {
00446 i++;
00447 *Dst++ =
RtlAnsiCharToUnicodeChar( &Src );
00448 }
00449 }
00450
00451
if (
NT_SUCCESS(
Status )) {
00452 *Dst = UNICODE_NULL;
00453 UnicodeFile->FileContents = BufferBase;
00454 UnicodeFile->EndOfFile = Dst;
00455 UnicodeFile->BeginLine =
NULL;
00456 UnicodeFile->EndOfLine =
NULL;
00457 UnicodeFile->NextLine = BufferBase;
00458 UnicodeFile->LastWriteTime = FileDateTimeInfo.LastWriteTime;
00459 }
00460
else {
00461
NtFreeVirtualMemory( NtCurrentProcess(),
00462 (PVOID *)&BufferBase,
00463 &
BufferSize,
00464 MEM_RELEASE
00465 );
00466 }
00467
00468
return(
Status );
00469 }
00470
00471
00472 BOOLEAN
00473 RegGetNextLine(
00474 IN OUT
PREG_UNICODE_FILE UnicodeFile,
00475 OUT PULONG IndentAmount,
00476 OUT PWSTR *FirstEqual
00477 )
00478 {
00479 PWSTR s, s1;
00480
00481
while (
TRUE) {
00482
if (!(s = UnicodeFile->NextLine)) {
00483
return(
FALSE );
00484 }
00485
00486 *IndentAmount = 0;
00487
while (*s <=
L' ') {
00488
if (*s ==
L' ') {
00489 *IndentAmount += 1;
00490 }
00491
else
00492
if (*s ==
L'\t') {
00493 *IndentAmount = ((*IndentAmount + 8) -
00494 (*IndentAmount % 8)
00495 );
00496 }
00497
00498
if (++s >= UnicodeFile->EndOfFile) {
00499
return(
FALSE );
00500 }
00501 }
00502
00503 UnicodeFile->BeginLine = s;
00504
00505 *FirstEqual =
NULL;
00506 UnicodeFile->NextLine =
NULL;
00507
while (s < UnicodeFile->EndOfFile) {
00508
if (*s ==
L'=') {
00509
if (*FirstEqual ==
NULL) {
00510 *FirstEqual = s;
00511 }
00512 }
00513
else
00514
if (*s ==
L'\n') {
00515 s1 = s;
00516
while (s > UnicodeFile->BeginLine && s[ -1 ] <=
L' ') {
00517 s--;
00518 }
00519 UnicodeFile->EndOfLine = s;
00520
do {
00521
if (++s1 >= UnicodeFile->EndOfFile) {
00522 s1 =
NULL;
00523
break;
00524 }
00525 }
00526
while (*s1 ==
L'\r' || *s1 ==
L'\n');
00527
00528 UnicodeFile->NextLine = s1;
00529
break;
00530 }
00531
00532
if (++s == UnicodeFile->EndOfFile) {
00533
break;
00534 }
00535 }
00536
00537
if (UnicodeFile->EndOfLine > UnicodeFile->BeginLine) {
00538
if (
DebugOutput) {
00539 fprintf( stderr,
"%02u %.*ws\n",
00540 *IndentAmount,
00541 UnicodeFile->EndOfLine - UnicodeFile->BeginLine,
00542 UnicodeFile->BeginLine
00543 );
00544 }
00545
00546
return(
TRUE );
00547 }
00548 }
00549
00550
return(
FALSE );
00551 }
00552
00553
00554
void
00555 RegDumpKeyValue(
00556 FILE *fh,
00557 PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
00558 ULONG IndentLevel
00559 )
00560 {
00561 PULONG p;
00562 PWSTR pw, pw1;
00563 ULONG i, j, k, m, cbPrefix;
00564 UNICODE_STRING
ValueName;
00565 PUCHAR pbyte;
00566
00567 cbPrefix = fprintf( fh,
"%.*s",
00568 IndentLevel,
00569
" "
00570 );
00571
ValueName.Buffer = (PWSTR)&(KeyValueInformation->Name[0]);
00572
ValueName.Length = (
USHORT)KeyValueInformation->NameLength;
00573
ValueName.MaximumLength = (
USHORT)KeyValueInformation->NameLength;
00574
00575
if (
ValueName.Length) {
00576 cbPrefix += fprintf( fh,
"%wZ ", &
ValueName );
00577 }
00578 cbPrefix += fprintf( fh,
"= " );
00579
00580
if (KeyValueInformation->DataLength == 0) {
00581 fprintf( fh,
" [no data] \n");
00582
return;
00583 }
00584
00585
switch( KeyValueInformation->Type ) {
00586
case REG_SZ:
00587
case REG_EXPAND_SZ:
00588
00589
if (KeyValueInformation->Type == REG_EXPAND_SZ) {
00590 cbPrefix += fprintf( fh,
"REG_EXPAND_SZ " );
00591 }
00592 pw = (PWSTR)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
00593 *(PWSTR)((PCHAR)pw + KeyValueInformation->DataLength) = UNICODE_NULL;
00594 i = 0;
00595
while (*pw) {
00596
if ((cbPrefix + wcslen(pw)) > 80) {
00597 pw1 = pw;
00598
while (*pw1 && *pw1 >
L' ') {
00599 pw1++;
00600 }
00601
00602
if (*pw1) {
00603 *pw1++ = UNICODE_NULL;
00604
while (*pw1 && *pw1 <=
L' ') {
00605 pw1++;
00606 }
00607 }
00608 }
else {
00609 pw1 =
NULL;
00610 }
00611
if (i > 0) {
00612 fprintf( fh,
" \\\n%.*s",
00613 cbPrefix,
00614
" "
00615 );
00616 }
00617
00618 fprintf( fh,
"%ws", pw );
00619
if (!pw1) {
00620
break;
00621 }
00622 i++;
00623 pw = pw1;
00624 }
00625
break;
00626
00627
case REG_BINARY:
00628 fprintf( fh,
"REG_BINARY 0x%08lx", KeyValueInformation->DataLength );
00629 p = (PULONG)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
00630 i = (KeyValueInformation->DataLength + 3) /
sizeof( ULONG );
00631
if (!
SummaryOutput || i <= 8) {
00632
for (j=0; j<i; j++) {
00633
if ((j % 8) == 0) {
00634 fprintf( fh,
"\n%.*s",
00635 IndentLevel+4,
00636
" "
00637 );
00638 }
00639
00640 fprintf( fh,
"0x%08lx ", *p++ );
00641 }
00642 }
00643
else {
00644 fprintf( fh,
" *** value display suppressed ***" );
00645 }
00646 fprintf( fh,
"\n" );
00647
break;
00648
00649
00650
case REG_DWORD:
00651 fprintf( fh,
"REG_DWORD 0x%08lx",
00652 *((PULONG)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset))
00653 );
00654
break;
00655
00656
case REG_DWORD_BIG_ENDIAN:
00657 fprintf( fh,
"REG_DWORD_BIG_ENDIAN 0x%08lx",
00658 *((PULONG)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset))
00659 );
00660
break;
00661
00662
case REG_LINK:
00663 fprintf( fh,
"REG_LINK %ws",
00664 ((PWSTR)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset))
00665 );
00666
break;
00667
00668
case REG_MULTI_SZ:
00669 cbPrefix += fprintf( fh,
"REG_MULTI_SZ " );
00670 pw = (PWSTR)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
00671 i = 0;
00672
if (*pw)
00673
while (i < ((KeyValueInformation->DataLength-1) /
sizeof(WCHAR))) {
00674
if (i > 0) {
00675 fprintf( fh,
" \\\n%.*s",
00676 cbPrefix,
00677
" "
00678 );
00679 }
00680 fprintf(fh,
"\"%ws\" ",pw+i);
00681
do {
00682 ++i;
00683 }
while ( pw[i] != UNICODE_NULL );
00684 ++i;
00685 }
00686
break;
00687
00688
case REG_RESOURCE_LIST:
00689
case REG_FULL_RESOURCE_DESCRIPTOR:
00690 {
00691 PCM_RESOURCE_LIST ResourceList = ((PCM_RESOURCE_LIST)((PCHAR)KeyValueInformation +
00692 KeyValueInformation->DataOffset));
00693 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
00694 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
00695 ULONG k, l, count;
00696 PWSTR TypeName;
00697 PWSTR FlagName;
00698 ULONG
Size = KeyValueInformation->DataLength;
00699
00700
if (KeyValueInformation->Type == REG_RESOURCE_LIST) {
00701
00702 fprintf( fh,
" REG_RESOURCE_LIST\n");
00703
00704 fprintf( fh,
"%.*sNumber of Full resource Descriptors = %d",
00705 IndentLevel,
00706
" ",
00707 ResourceList->Count
00708 );
00709
00710 count = ResourceList->Count;
00711 FullDescriptor = &ResourceList->List[0];
00712
00713 }
else {
00714
00715 fprintf( fh,
" REG_FULL_RESOURCE_DESCRIPTOR\n");
00716 count = 1;
00717 FullDescriptor = ((PCM_FULL_RESOURCE_DESCRIPTOR)
00718 ((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset));
00719
00720 }
00721
00722
for (i=0; i< count; i++) {
00723
00724 fprintf( fh,
"\n%.*sPartial List number %d\n",
00725 IndentLevel+4,
00726
" ",
00727 i
00728 );
00729
00730
switch(FullDescriptor->InterfaceType) {
00731
00732
case Internal: TypeName =
L"Internal";
break;
00733
case Isa: TypeName =
L"Isa";
break;
00734
case Eisa: TypeName =
L"Eisa";
break;
00735
case MicroChannel: TypeName =
L"MicroChannel";
break;
00736
case TurboChannel: TypeName =
L"TurboChannel";
break;
00737
case PCIBus: TypeName =
L"PCI";
break;
00738
case VMEBus: TypeName =
L"VME";
break;
00739
case NuBus: TypeName =
L"NuBus";
break;
00740
case PCMCIABus: TypeName =
L"PCMCIA";
break;
00741
case CBus: TypeName =
L"CBUS";
break;
00742
case MPIBus: TypeName =
L"MPI";
break;
00743
00744
default:
00745 TypeName =
L"***invalid bus type***";
00746
break;
00747 }
00748
00749 fprintf( fh,
"%.*sINTERFACE_TYPE %ws\n",
00750 IndentLevel+8,
00751
" ",
00752 TypeName
00753 );
00754
00755 fprintf( fh,
"%.*sBUS_NUMBER %d\n",
00756 IndentLevel+8,
00757
" ",
00758 FullDescriptor->BusNumber
00759 );
00760
00761
00762
00763
00764
00765
00766
if (
Size < FullDescriptor->PartialResourceList.Count *
00767
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) ) {
00768
00769 fprintf( fh,
"\n%.*s *** !!! Invalid ResourceList !!! *** \n",
00770 IndentLevel+8,
00771
" ",
00772 i
00773 );
00774
00775
break;
00776 }
00777
00778
Size -= FullDescriptor->PartialResourceList.Count *
00779
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
00780
00781
00782
00783
for (j=0; j<FullDescriptor->PartialResourceList.Count; j++) {
00784
00785 fprintf( fh,
"%.*sDescriptor number %d\n",
00786 IndentLevel+12,
00787
" ",
00788 j
00789 );
00790
00791 PartialResourceDescriptor =
00792 &(FullDescriptor->PartialResourceList.PartialDescriptors[j]);
00793
00794
switch(PartialResourceDescriptor->ShareDisposition) {
00795
00796
case CmResourceShareUndetermined:
00797 TypeName =
L"CmResourceShareUndetermined";
00798
break;
00799
case CmResourceShareDeviceExclusive:
00800 TypeName =
L"CmResourceDeviceExclusive";
00801
break;
00802
case CmResourceShareDriverExclusive:
00803 TypeName =
L"CmResourceDriverExclusive";
00804
break;
00805
case CmResourceShareShared:
00806 TypeName =
L"CmResourceShared";
00807
break;
00808
default:
00809 TypeName =
L"***invalid share disposition***";
00810
break;
00811 }
00812
00813 fprintf( fh,
"%.*sShare Disposition %ws\n",
00814 IndentLevel+12,
00815
" ",
00816 TypeName
00817 );
00818
00819 FlagName =
L"***invalid Flags";
00820
00821
switch(PartialResourceDescriptor->Type) {
00822
00823
case CmResourceTypeNull:
00824 TypeName =
L"NULL";
00825 FlagName =
L"***Unused";
00826
break;
00827
case CmResourceTypePort:
00828 TypeName =
L"PORT";
00829
if (PartialResourceDescriptor->Flags == CM_RESOURCE_PORT_MEMORY) {
00830 FlagName =
L"CM_RESOURCE_PORT_MEMORY";
00831 }
00832
if (PartialResourceDescriptor->Flags == CM_RESOURCE_PORT_IO) {
00833 FlagName =
L"CM_RESOURCE_PORT_IO";
00834 }
00835
break;
00836
case CmResourceTypeInterrupt:
00837 TypeName =
L"INTERRUPT";
00838
if (PartialResourceDescriptor->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE) {
00839 FlagName =
L"CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE";
00840 }
00841
if (PartialResourceDescriptor->Flags == CM_RESOURCE_INTERRUPT_LATCHED) {
00842 FlagName =
L"CM_RESOURCE_INTERRUPT_LATCHED";
00843 }
00844
break;
00845
case CmResourceTypeMemory:
00846 TypeName =
L"MEMORY";
00847
if (PartialResourceDescriptor->Flags == CM_RESOURCE_MEMORY_READ_WRITE) {
00848 FlagName =
L"CM_RESOURCE_MEMORY_READ_WRITE";
00849 }
00850
if (PartialResourceDescriptor->Flags == CM_RESOURCE_MEMORY_READ_ONLY) {
00851 FlagName =
L"CM_RESOURCE_MEMORY_READ_ONLY";
00852 }
00853
if (PartialResourceDescriptor->Flags == CM_RESOURCE_MEMORY_WRITE_ONLY) {
00854 FlagName =
L"CM_RESOURCE_MEMORY_WRITE_ONLY";
00855 }
00856
break;
00857
case CmResourceTypeDma:
00858 TypeName =
L"DMA";
00859 FlagName =
L"***Unused";
00860
break;
00861
case CmResourceTypeDeviceSpecific:
00862 TypeName =
L"DEVICE SPECIFIC";
00863 FlagName =
L"***Unused";
00864
break;
00865
default:
00866 TypeName =
L"***invalid type***";
00867
break;
00868 }
00869
00870 fprintf( fh,
"%.*sTYPE %ws\n",
00871 IndentLevel+12,
00872
" ",
00873 TypeName
00874 );
00875
00876 fprintf( fh,
"%.*sFlags %ws\n",
00877 IndentLevel+12,
00878
" ",
00879 FlagName
00880 );
00881
00882
switch(PartialResourceDescriptor->Type) {
00883
00884
case CmResourceTypePort:
00885 fprintf( fh,
"%.*sSTART 0x%08lx LENGTH 0x%08lx\n",
00886 IndentLevel+12,
00887
" ",
00888 PartialResourceDescriptor->u.Port.Start.LowPart,
00889 PartialResourceDescriptor->u.Port.Length
00890 );
00891
break;
00892
00893
case CmResourceTypeInterrupt:
00894 fprintf( fh,
"%.*sLEVEL %d VECTOR %d AFFINITY %d\n",
00895 IndentLevel+12,
00896
" ",
00897 PartialResourceDescriptor->u.Interrupt.Level,
00898 PartialResourceDescriptor->u.Interrupt.Vector,
00899 PartialResourceDescriptor->u.Interrupt.Affinity
00900 );
00901
break;
00902
00903
case CmResourceTypeMemory:
00904 fprintf( fh,
"%.*sSTART 0x%08lx%08lx LENGTH 0x%08lx\n",
00905 IndentLevel+12,
00906
" ",
00907 PartialResourceDescriptor->u.Memory.Start.HighPart,
00908 PartialResourceDescriptor->u.Memory.Start.LowPart,
00909 PartialResourceDescriptor->u.Memory.Length
00910 );
00911
break;
00912
00913
case CmResourceTypeDma:
00914 fprintf( fh,
"%.*sCHANNEL %d PORT %d\n",
00915 IndentLevel+12,
00916
" ",
00917 PartialResourceDescriptor->u.Dma.Channel,
00918 PartialResourceDescriptor->u.Dma.Port
00919 );
00920
break;
00921
00922
case CmResourceTypeDeviceSpecific:
00923 fprintf( fh,
"%.*sDataSize 0x%08lx\n",
00924 IndentLevel+12,
00925
" ",
00926 PartialResourceDescriptor->u.DeviceSpecificData.DataSize
00927 );
00928
00929 p = (PULONG)(PartialResourceDescriptor + 1);
00930 k = (PartialResourceDescriptor->u.DeviceSpecificData.DataSize + 3) /
sizeof( ULONG );
00931
for (l=0; l<k; l++) {
00932
if ((l % 8) == 0) {
00933 fprintf( fh,
"\n%.*s",
00934 IndentLevel+12,
00935
" "
00936 );
00937 }
00938
00939 fprintf( fh,
"0x%08lx ", *p++ );
00940 }
00941 fprintf( fh,
"\n" );
00942
break;
00943
00944
default:
00945 fprintf( fh,
"%.*s*** Unknown resource list type: %c ****\n",
00946 IndentLevel+12,
00947
" ",
00948 PartialResourceDescriptor->Type
00949 );
00950
break;
00951 }
00952
00953 fprintf( fh,
"\n" );
00954 }
00955
00956 FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) (PartialResourceDescriptor+1);
00957 }
00958
00959
break;
00960 }
00961
00962
case REG_NONE:
00963
default:
00964
if (KeyValueInformation->Type == REG_NONE) {
00965 fprintf( fh,
"REG_NONE\n");
00966 }
00967
else {
00968 fprintf( fh,
"*** Unknown registry type (%08lx)",
00969 KeyValueInformation->Type
00970 );
00971 }
00972 fprintf( fh,
"%.*s",
00973 IndentLevel,
00974
" "
00975 );
00976 fprintf( fh,
" Length: 0x%lx\n", KeyValueInformation->DataLength );
00977 fprintf( fh,
"\n%.*s",
00978 IndentLevel,
00979
" "
00980 );
00981 fprintf( fh,
" Data: ");
00982 pbyte = ((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
00983
for ( k=0, m=1; k<KeyValueInformation->DataLength; k++,m++) {
00984 fprintf( fh,
"%02x ", (*pbyte) );
00985 pbyte++;
00986
00987
if (m==8) {
00988 fprintf( fh,
"\n%.*s",
00989 IndentLevel+12,
00990
" "
00991 );
00992 m=0;
00993 }
00994 }
00995
break;
00996 }
00997
00998 fprintf( fh,
"\n" );
00999
return;
01000 }
01001
01002
01003
01004
01005
01006 #define upcase(C) (WCHAR )(((C) >= 'a' && (C) <= 'z' ? (C) - ('a' - 'A') : (C)))
01007
01008 BOOLEAN
01009 RegGetMultiString(
01010 IN OUT PUNICODE_STRING ValueString,
01011 OUT PUNICODE_STRING MultiString
01012 )
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 {
01048
01049
01050
01051
while ((*(ValueString->Buffer) !=
L'"') &&
01052 (ValueString->Length > 0)) {
01053 ++ValueString->Buffer;
01054 ValueString->Length -=
sizeof(WCHAR);
01055 ValueString->MaximumLength -=
sizeof(WCHAR);
01056 }
01057
01058
if (ValueString->Length == 0) {
01059
return(
FALSE);
01060 }
01061
01062
01063
01064
01065
01066 ++ValueString->Buffer;
01067 ValueString->Length -=
sizeof(WCHAR);
01068 ValueString->MaximumLength -=
sizeof(WCHAR);
01069 MultiString->Buffer = ValueString->Buffer;
01070 MultiString->Length = 0;
01071 MultiString->MaximumLength = 0;
01072
while ((*(ValueString->Buffer) !=
L'"') &&
01073 (ValueString->Length > 0)) {
01074 ++ValueString->Buffer;
01075 ValueString->Length -=
sizeof(WCHAR);
01076 ValueString->MaximumLength -=
sizeof(WCHAR);
01077
01078 MultiString->Length +=
sizeof(WCHAR);
01079 MultiString->MaximumLength +=
sizeof(WCHAR);
01080 }
01081
01082
if (ValueString->Length == 0) {
01083
return(
FALSE);
01084 }
01085
01086 ++ValueString->Buffer;
01087 ValueString->Length -=
sizeof(WCHAR);
01088 ValueString->MaximumLength -=
sizeof(WCHAR);
01089
01090
return(
TRUE );
01091
01092 }
01093
01094
01095 BOOLEAN
01096 RegGetKeyValue(
01097 IN PUNICODE_STRING InitialKeyValue,
01098 IN OUT
PREG_UNICODE_FILE UnicodeFile,
01099 OUT PULONG ValueType,
01100 OUT PVOID *ValueBuffer,
01101 OUT PULONG ValueLength
01102 )
01103 {
01104 ULONG PrefixLength;
01105 PWSTR s;
01106 PULONG p;
01107 ULONG
n;
01108
NTSTATUS Status;
01109 ULONG IndentAmount;
01110 PWSTR FirstEqual;
01111 UNICODE_STRING KeyValue;
01112 UNICODE_STRING MultiValue;
01113 BOOLEAN GetDataFromBinaryFile =
FALSE;
01114 BOOLEAN GetDataFromMultiSzFile =
FALSE;
01115 BOOLEAN ParseDateTime =
FALSE;
01116
01117 KeyValue = *InitialKeyValue;
01118
if (
RtlPrefixUnicodeString( &
RiDeleteKeyword, &KeyValue,
TRUE )) {
01119 *
ValueBuffer =
NULL;
01120
return(
TRUE );
01121 }
01122
else
01123
if (!
RtlPrefixUnicodeString( &
RiRegKeyword, &KeyValue,
TRUE )) {
01124 *ValueType = REG_SZ;
01125 PrefixLength = 0;
01126 }
01127
else
01128
if (
RtlPrefixUnicodeString( &
RiRegNoneKeyword, &KeyValue,
TRUE )) {
01129 *ValueType = REG_NONE;
01130 PrefixLength =
RiRegNoneKeyword.Length;
01131 }
01132
else
01133
if (
RtlPrefixUnicodeString( &
RiRegSzKeyword, &KeyValue,
TRUE )) {
01134 *ValueType = REG_SZ;
01135 PrefixLength =
RiRegSzKeyword.Length;
01136 }
01137
else
01138
if (
RtlPrefixUnicodeString( &
RiRegExpandSzKeyword, &KeyValue,
TRUE )) {
01139 *ValueType = REG_EXPAND_SZ;
01140 PrefixLength =
RiRegExpandSzKeyword.Length;
01141 }
01142
else
01143
if (
RtlPrefixUnicodeString( &
RiRegDwordKeyword, &KeyValue,
TRUE )) {
01144 *ValueType = REG_DWORD;
01145 PrefixLength =
RiRegDwordKeyword.Length;
01146 }
01147
else
01148
if (
RtlPrefixUnicodeString( &
RiRegBinaryFileKeyword, &KeyValue,
TRUE )) {
01149 *ValueType = REG_BINARY;
01150 PrefixLength =
RiRegBinaryFileKeyword.Length;
01151 GetDataFromBinaryFile =
TRUE;
01152 }
01153
else
01154
if (
RtlPrefixUnicodeString( &
RiRegBinaryKeyword, &KeyValue,
TRUE )) {
01155 *ValueType = REG_BINARY;
01156 PrefixLength =
RiRegBinaryKeyword.Length;
01157 }
01158
else
01159
if (
RtlPrefixUnicodeString( &
RiRegLinkKeyword, &KeyValue,
TRUE )) {
01160 *ValueType = REG_LINK;
01161 PrefixLength =
RiRegLinkKeyword.Length;
01162 }
01163
else
01164
if (
RtlPrefixUnicodeString( &
RiRegMultiSzFileKeyword, &KeyValue,
TRUE)) {
01165 *ValueType = REG_MULTI_SZ;
01166 PrefixLength =
RiRegMultiSzFileKeyword.Length;
01167 GetDataFromMultiSzFile =
TRUE;
01168 }
01169
else
01170
if (
RtlPrefixUnicodeString( &
RiRegMultiSzKeyword, &KeyValue,
TRUE)) {
01171 *ValueType = REG_MULTI_SZ;
01172 PrefixLength =
RiRegMultiSzKeyword.Length;
01173 }
01174
else
01175
if (
RtlPrefixUnicodeString( &
RiRegDateKeyword, &KeyValue,
TRUE )) {
01176 *ValueType = REG_BINARY;
01177 ParseDateTime =
TRUE;
01178 PrefixLength =
RiRegDateKeyword.Length;
01179 }
01180
else {
01181
return(
FALSE );
01182 }
01183
01184
if (*ValueType != REG_NONE) {
01185 s = (PWSTR)
01186 ((PCHAR)KeyValue.Buffer + PrefixLength);
01187 KeyValue.Length -= (
USHORT)PrefixLength;
01188
while (KeyValue.Length != 0 && *s <=
L' ') {
01189 s++;
01190 KeyValue.Length -=
sizeof( WCHAR );
01191 }
01192 KeyValue.Buffer = s;
01193 }
01194
else {
01195 *ValueType = REG_SZ;
01196 }
01197
01198
01199
if (GetDataFromBinaryFile) {
01200
Status =
RegReadBinaryFile( &KeyValue,
ValueBuffer, ValueLength );
01201
if (
NT_SUCCESS(
Status )) {
01202
return(
TRUE );
01203 }
01204
else {
01205 fprintf( stderr,
"REGINI: Unable to read data from %wZ - Status == %lx\n", &KeyValue,
Status );
01206
return(
FALSE );
01207 }
01208 }
01209
01210
if (GetDataFromMultiSzFile) {
01211
Status =
RegReadMultiSzFile( &KeyValue,
ValueBuffer, ValueLength );
01212
if (
NT_SUCCESS(
Status )) {
01213
return(
TRUE );
01214 }
01215
else {
01216 fprintf( stderr,
"REGINI: Unable to read data from %wZ - Status == %lx\n", &KeyValue,
Status );
01217
return(
FALSE );
01218 }
01219 }
01220
01221
switch( *ValueType ) {
01222
case REG_SZ:
01223
case REG_EXPAND_SZ:
01224
case REG_LINK:
01225 *ValueLength = KeyValue.Length +
sizeof( UNICODE_NULL );
01226 *
ValueBuffer =
RtlAllocateHeap( RtlProcessHeap(), 0, *ValueLength );
01227
if (*
ValueBuffer ==
NULL) {
01228
return(
FALSE );
01229 }
01230
01231 RtlMoveMemory( *
ValueBuffer, KeyValue.Buffer, KeyValue.Length );
01232 ((PWSTR)*
ValueBuffer)[ KeyValue.Length /
sizeof( WCHAR ) ] = UNICODE_NULL;
01233
return(
TRUE );
01234
01235
case REG_DWORD:
01236 *
ValueBuffer =
RtlAllocateHeap( RtlProcessHeap(), 0,
sizeof( ULONG ) );
01237
if (*
ValueBuffer ==
NULL) {
01238
return(
FALSE );
01239 }
01240
01241
if (
RtlPrefixUnicodeString( &
RiTrueKeyword, &KeyValue,
TRUE ) ||
01242
RtlPrefixUnicodeString( &
RiYesKeyword, &KeyValue,
TRUE ) ||
01243
RtlPrefixUnicodeString( &
RiOnKeyword, &KeyValue,
TRUE )
01244 ) {
01245 *(PULONG)*
ValueBuffer = (ULONG)
TRUE;
01246 }
01247
else
01248
if (
RtlPrefixUnicodeString( &
RiFalseKeyword, &KeyValue,
TRUE ) ||
01249
RtlPrefixUnicodeString( &
RiNoKeyword, &KeyValue,
TRUE ) ||
01250
RtlPrefixUnicodeString( &
RiOffKeyword, &KeyValue,
TRUE )
01251 ) {
01252 *(PULONG)*
ValueBuffer = (ULONG)
FALSE;
01253 }
01254
else {
01255
Status =
RtlUnicodeStringToInteger( &KeyValue, 0, (PULONG)*
ValueBuffer );
01256
if (!
NT_SUCCESS(
Status )) {
01257 fprintf( stderr,
"REGINI: CharToInteger( %wZ ) failed - Status == %lx\n", &KeyValue,
Status );
01258
RtlFreeHeap( RtlProcessHeap(), 0, *
ValueBuffer );
01259
return(
FALSE );
01260 }
01261 }
01262
01263 *ValueLength =
sizeof( ULONG );
01264
return(
TRUE );
01265
01266
case REG_BINARY:
01267
if (ParseDateTime) {
01268
#define NUMBER_DATE_TIME_FIELDS 6
01269
ULONG FieldIndexes[
NUMBER_DATE_TIME_FIELDS ] = {1, 2, 0, 3, 4, 7};
01270
01271
01272
01273
01274 ULONG CurrentField = 0;
01275 PCSHORT Fields;
01276 TIME_FIELDS DateTimeFields;
01277 UNICODE_STRING Field;
01278 ULONG FieldValue;
01279
01280 RtlZeroMemory( &DateTimeFields,
sizeof( DateTimeFields ) );
01281 Fields = &DateTimeFields.Year;
01282
while (KeyValue.Length) {
01283
if (CurrentField >= 7) {
01284
return(
FALSE );
01285 }
01286
01287 s = KeyValue.Buffer;
01288
while (KeyValue.Length && *s ==
L' ') {
01289 KeyValue.Length--;
01290 s++;
01291 }
01292
01293 Field.Buffer = s;
01294
while (KeyValue.Length) {
01295
if (CurrentField == (
NUMBER_DATE_TIME_FIELDS-1)) {
01296 }
01297
else
01298
if (*s < L'0' || *s >
L'9') {
01299
break;
01300 }
01301
01302 KeyValue.Length--;
01303 s++;
01304 }
01305
01306 Field.Length = (
USHORT)((PCHAR)s - (PCHAR)Field.Buffer);
01307 Field.MaximumLength = Field.Length;
01308
01309
if (KeyValue.Length) {
01310 KeyValue.Length--;
01311 s++;
01312 }
01313 KeyValue.Buffer = s;
01314
01315
if (CurrentField == (
NUMBER_DATE_TIME_FIELDS-1)) {
01316
if (Field.Length < 3) {
01317 printf(
"REGINI: %wZ invalid day of week length\n", &Field );
01318
return FALSE;
01319 }
01320
01321
if (DateTimeFields.Year != 0) {
01322 printf(
"REGINI: Year must be zero to specify day of week\n" );
01323
return FALSE;
01324 }
01325
01326
if (!_wcsnicmp( Field.Buffer,
L"SUN", 3 )) {
01327 FieldValue = 0;
01328 }
01329
else
01330
if (!_wcsnicmp( Field.Buffer,
L"MON", 3 )) {
01331 FieldValue = 1;
01332 }
01333
else
01334
if (!_wcsnicmp( Field.Buffer,
L"TUE", 3 )) {
01335 FieldValue = 2;
01336 }
01337
else
01338
if (!_wcsnicmp( Field.Buffer,
L"WED", 3 )) {
01339 FieldValue = 3;
01340 }
01341
else
01342
if (!_wcsnicmp( Field.Buffer,
L"THU", 3 )) {
01343 FieldValue = 4;
01344 }
01345
else
01346
if (!_wcsnicmp( Field.Buffer,
L"FRI", 3 )) {
01347 FieldValue = 5;
01348 }
01349
else
01350
if (!_wcsnicmp( Field.Buffer,
L"SAT", 3 )) {
01351 FieldValue = 6;
01352 }
01353
else {
01354 printf(
"REGINI: %wZ invalid day of week\n", &Field );
01355
return FALSE;
01356 }
01357 }
01358
else {
01359
Status =
RtlUnicodeStringToInteger( &Field, 10, &FieldValue );
01360
if (!
NT_SUCCESS(
Status )) {
01361
return(
FALSE );
01362 }
01363 }
01364
01365 Fields[ FieldIndexes[ CurrentField++ ] ] = (CSHORT)FieldValue;
01366 }
01367
01368
if (DateTimeFields.Year == 0) {
01369
if (DateTimeFields.Day > 5) {
01370 printf(
"REGINI: Day must be 0 - 5 if year is zero.\n" );
01371
return FALSE;
01372 }
01373 }
01374
else
01375
if (DateTimeFields.Year < 100) {
01376 DateTimeFields.Year += 1900;
01377 }
01378
01379 *
ValueBuffer =
RtlAllocateHeap( RtlProcessHeap(), 0,
sizeof( DateTimeFields ) );
01380 *ValueLength =
sizeof( DateTimeFields );
01381 RtlMoveMemory( *
ValueBuffer, &DateTimeFields,
sizeof( DateTimeFields ) );
01382
return TRUE;
01383 }
01384
else {
01385
Status =
RtlUnicodeStringToInteger( &KeyValue, 0, ValueLength );
01386
if (!
NT_SUCCESS(
Status )) {
01387
return(
FALSE );
01388 }
01389 s = KeyValue.Buffer;
01390
while (KeyValue.Length != 0 && *s >
L' ') {
01391 s++;
01392 KeyValue.Length -=
sizeof( WCHAR );
01393 }
01394 KeyValue.Buffer = s;
01395 }
01396
break;
01397
01398
case REG_MULTI_SZ:
01399 *ValueLength = 0;
01400 *
ValueBuffer =
RtlAllocateHeap( RtlProcessHeap(), 0, KeyValue.Length +
sizeof( UNICODE_NULL ) );
01401
while (
RegGetMultiString(&KeyValue, &MultiValue)) {
01402 RtlMoveMemory( (PUCHAR)*
ValueBuffer + *ValueLength,
01403 MultiValue.Buffer,
01404 MultiValue.Length );
01405 *ValueLength += MultiValue.Length;
01406 ((PWSTR)*
ValueBuffer)[ *ValueLength /
sizeof(WCHAR) ] = UNICODE_NULL;
01407 *ValueLength +=
sizeof(UNICODE_NULL);
01408 }
01409 ((PWSTR)*
ValueBuffer)[ *ValueLength /
sizeof(WCHAR) ] = UNICODE_NULL;
01410 *ValueLength +=
sizeof(UNICODE_NULL);
01411
01412
return(
TRUE );
01413
01414
default:
01415
return(
FALSE );
01416 }
01417
01418 *
ValueBuffer =
RtlAllocateHeap( RtlProcessHeap(), 0, *ValueLength );
01419 p = *
ValueBuffer;
01420
n = (*ValueLength +
sizeof( ULONG ) - 1) /
sizeof( ULONG );
01421
while (
n--) {
01422
if (KeyValue.Length == 0) {
01423
if (!
RegGetNextLine( UnicodeFile, &IndentAmount, &FirstEqual )) {
01424
RtlFreeHeap( RtlProcessHeap(), 0, *
ValueBuffer );
01425
return(
FALSE );
01426 }
01427 KeyValue.Buffer = UnicodeFile->BeginLine;
01428 KeyValue.Length = (
USHORT)
01429 ((PCHAR)UnicodeFile->EndOfLine - (PCHAR)UnicodeFile->BeginLine);
01430 KeyValue.MaximumLength = KeyValue.Length;
01431 }
01432
01433 s = KeyValue.Buffer;
01434
while (KeyValue.Length != 0 && *s <=
L' ') {
01435 s++;
01436 KeyValue.Length -=
sizeof( WCHAR );
01437 }
01438 KeyValue.Buffer = s;
01439
if (KeyValue.Length != 0) {
01440
Status =
RtlUnicodeStringToInteger( &KeyValue, 0, p );
01441
if (!
NT_SUCCESS(
Status )) {
01442
RtlFreeHeap( RtlProcessHeap(), 0, *
ValueBuffer );
01443
return(
FALSE );
01444 }
01445 p++;
01446
01447 s = KeyValue.Buffer;
01448
while (KeyValue.Length != 0 && *s >
L' ') {
01449 s++;
01450 KeyValue.Length -=
sizeof( WCHAR );
01451 }
01452 KeyValue.Buffer = s;
01453 }
01454 }
01455
01456
return(
TRUE );
01457 }
01458
01459 BOOLEAN
01460 RtlPrefixUnicodeString(
01461 IN PUNICODE_STRING String1,
01462 IN PUNICODE_STRING String2,
01463 IN BOOLEAN CaseInSensitive
01464 )
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493 {
01494 PWSTR s1, s2;
01495 ULONG
n;
01496 WCHAR c1, c2;
01497
01498 s1 =
String1->Buffer;
01499 s2 =
String2->Buffer;
01500
if (
String2->Length <
String1->Length) {
01501
return(
FALSE );
01502 }
01503
01504
n =
String1->Length /
sizeof( c1 );
01505
while (
n) {
01506 c1 = *s1++;
01507 c2 = *s2++;
01508
01509
if (CaseInSensitive) {
01510 c1 =
upcase(c1);
01511 c2 =
upcase(c2);
01512 }
01513
if (c1 != c2) {
01514
return(
FALSE );
01515 }
01516
01517
n--;
01518 }
01519
01520
return(
TRUE );
01521 }
01522