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

regutil.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 regutil.c 00008 00009 Abstract: 00010 00011 Utility routines for use by REGINI and REGDMP programs. 00012 Author: 00013 00014 Steve Wood (stevewo) 10-Mar-92 00015 00016 Revision History: 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 // Virtual memory for reading of MultiSzFile freed at process 00152 // death? 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 // case REG_DWORD_LITTLE_ENDIAN: 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 // This is a basic test to see if the data format is right. 00763 // We know at least some video resource list are bogus ... 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 // Define an upcase macro for temporary use by the upcase routines 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 Routine Description: 01017 01018 This routine parses multi-strings of the form 01019 01020 "foo" "bar" "bletch" 01021 01022 Each time it is called, it strips the first string in quotes from 01023 the input string, and returns it as the multi-string. 01024 01025 INPUT ValueString: "foo" "bar" "bletch" 01026 01027 OUTPUT ValueString: "bar" "bletch" 01028 MultiString: foo 01029 01030 Arguments: 01031 01032 ValueString - Supplies the string from which the multi-string will be 01033 parsed 01034 - Returns the remaining string after the multi-string is 01035 removed 01036 01037 MultiString - Returns the multi-string removed from ValueString 01038 01039 Return Value: 01040 01041 TRUE - multi-string found and removed. 01042 01043 FALSE - no more multi-strings remaining. 01044 01045 --*/ 01046 01047 { 01048 // 01049 // Find the first quote mark. 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 // We have found the start of the multi-string. Now find the end, 01064 // building up our return MultiString as we go. 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 // Month/Day/Year HH:MM DayOfWeek 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 Routine Description: 01469 01470 The RtlPrefixUnicodeString function determines if the String1 01471 counted string parameter is a prefix of the String2 counted string 01472 parameter. 01473 01474 The CaseInSensitive parameter specifies if case is to be ignored when 01475 doing the comparison. 01476 01477 Arguments: 01478 01479 String1 - Pointer to the first unicode string. 01480 01481 String2 - Pointer to the second unicode string. 01482 01483 CaseInsensitive - TRUE if case should be ignored when doing the 01484 comparison. 01485 01486 Return Value: 01487 01488 Boolean value that is TRUE if String1 equals a prefix of String2 and 01489 FALSE otherwise. 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 

Generated on Sat May 15 19:41:38 2004 for test by doxygen 1.3.7