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

regutil.c File Reference

#include "ntrtlp.h"
#include <ctype.h>

Go to the source code of this file.

Defines

#define MAX_USTRING   ( sizeof(WCHAR) * (MAXUSHORT/sizeof(WCHAR)) )
#define MAX_NONNULL_USTRING   ( MAX_USTRING - sizeof(UNICODE_NULL) )
#define QuadAlignPtr(P)
#define SIZE_OF_TOKEN_INFORMATION

Functions

NTSTATUS RtlpGetRegistryHandle (IN ULONG RelativeTo, IN PCWSTR KeyName, IN BOOLEAN WriteAccess, OUT PHANDLE Key)
NTSTATUS RtlpQueryRegistryDirect (IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN OUT PVOID Destination)
NTSTATUS RtlpCallQueryRegistryRoutine (IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation, IN OUT PULONG PKeyValueInfoLength, IN PVOID Context, IN PVOID Environment OPTIONAL)
PVOID RtlpAllocDeallocQueryBuffer (IN OUT SIZE_T *PAllocLength OPTIONAL, IN PVOID OldKeyValueInformation OPTIONAL, IN SIZE_T OldAllocLength OPTIONAL, OUT NTSTATUS *pStatus OPTIONAL)
NTSTATUS RtlpInitCurrentUserString (OUT PUNICODE_STRING UserString)
NTSTATUS RtlpGetTimeZoneInfoHandle (IN BOOLEAN WriteAccess, OUT PHANDLE Key)
NTSTATUS RtlQueryRegistryValues (IN ULONG RelativeTo, IN PCWSTR Path, IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PVOID Context, IN PVOID Environment OPTIONAL)
NTSTATUS RtlWriteRegistryValue (IN ULONG RelativeTo, IN PCWSTR Path, IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength)
NTSTATUS RtlCheckRegistryKey (IN ULONG RelativeTo, IN PWSTR Path)
NTSTATUS RtlCreateRegistryKey (IN ULONG RelativeTo, IN PWSTR Path)
NTSTATUS RtlDeleteRegistryValue (IN ULONG RelativeTo, IN PCWSTR Path, IN PCWSTR ValueName)
NTSTATUS RtlExpandEnvironmentStrings_U (IN PVOID Environment OPTIONAL, IN PUNICODE_STRING Source, OUT PUNICODE_STRING Destination, OUT PULONG ReturnedLength OPTIONAL)
ULONG RtlGetNtGlobalFlags (VOID)
NTSTATUS RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING CurrentUserKeyPath)
NTSTATUS RtlOpenCurrentUser (IN ULONG DesiredAccess, OUT PHANDLE CurrentUserKey)
NTSTATUS RtlQueryTimeZoneInformation (OUT PRTL_TIME_ZONE_INFORMATION TimeZoneInformation)
NTSTATUS RtlSetTimeZoneInformation (IN PRTL_TIME_ZONE_INFORMATION TimeZoneInformation)
NTSTATUS RtlSetActiveTimeBias (IN LONG ActiveBias)

Variables

const PWSTR RtlpRegistryPaths [RTL_REGISTRY_MAXIMUM]
SIZE_T RtlpRegistryQueryInitialBuffersize = PAGE_SIZE
const WCHAR szBias []
const WCHAR szStandardName []
const WCHAR szStandardBias []
const WCHAR szStandardStart []
const WCHAR szDaylightName []
const WCHAR szDaylightBias []
const WCHAR szDaylightStart []


Define Documentation

#define MAX_NONNULL_USTRING   ( MAX_USTRING - sizeof(UNICODE_NULL) )
 

Definition at line 192 of file rtl/regutil.c.

Referenced by RtlpCallQueryRegistryRoutine().

#define MAX_USTRING   ( sizeof(WCHAR) * (MAXUSHORT/sizeof(WCHAR)) )
 

Definition at line 186 of file rtl/regutil.c.

Referenced by RtlpCallQueryRegistryRoutine(), and RtlpQueryRegistryDirect().

#define QuadAlignPtr  ) 
 

Value:

( \ (PVOID)((((ULONG_PTR)(P)) + 7) & (-8)) \ )

Definition at line 276 of file rtl/regutil.c.

Referenced by RtlpCallQueryRegistryRoutine().

#define SIZE_OF_TOKEN_INFORMATION
 

Value:

sizeof( TOKEN_USER ) \ + sizeof( SID ) \ + sizeof( ULONG ) * SID_MAX_SUB_AUTHORITIES

Definition at line 1446 of file rtl/regutil.c.

Referenced by RtlFormatCurrentUserKeyPath().


Function Documentation

NTSTATUS RtlCheckRegistryKey IN ULONG  RelativeTo,
IN PWSTR  Path
 

Definition at line 1257 of file rtl/regutil.c.

References FALSE, Key, NT_SUCCESS, NTSTATUS(), RTL_PAGED_CODE, RtlpGetRegistryHandle(), and Status.

Referenced by Win32UserInitialize().

01261 { 01262 NTSTATUS Status; 01263 HANDLE Key; 01264 01265 RTL_PAGED_CODE(); 01266 01267 Status = RtlpGetRegistryHandle( RelativeTo, Path, FALSE, &Key ); 01268 if (!NT_SUCCESS( Status )) { 01269 return Status; 01270 } 01271 01272 ZwClose( Key ); 01273 return STATUS_SUCCESS; 01274 }

NTSTATUS RtlCreateRegistryKey IN ULONG  RelativeTo,
IN PWSTR  Path
 

Definition at line 1278 of file rtl/regutil.c.

References Key, NT_SUCCESS, NTSTATUS(), RTL_PAGED_CODE, RtlpGetRegistryHandle(), Status, and TRUE.

01282 { 01283 NTSTATUS Status; 01284 HANDLE Key; 01285 01286 RTL_PAGED_CODE(); 01287 01288 Status = RtlpGetRegistryHandle( RelativeTo, Path, TRUE, &Key ); 01289 if (!NT_SUCCESS( Status )) { 01290 return Status; 01291 } 01292 01293 ZwClose( Key ); 01294 return STATUS_SUCCESS; 01295 }

NTSTATUS RtlDeleteRegistryValue IN ULONG  RelativeTo,
IN PCWSTR  Path,
IN PCWSTR  ValueName
 

Definition at line 1299 of file rtl/regutil.c.

References Key, NT_SUCCESS, NTSTATUS(), RTL_PAGED_CODE, RtlInitUnicodeString(), RtlpGetRegistryHandle(), Status, TRUE, and ValueName.

01304 { 01305 NTSTATUS Status; 01306 UNICODE_STRING KeyValueName; 01307 HANDLE Key; 01308 01309 RTL_PAGED_CODE(); 01310 01311 Status = RtlpGetRegistryHandle( RelativeTo, Path, TRUE, &Key ); 01312 if (!NT_SUCCESS( Status )) { 01313 return Status; 01314 } 01315 01316 RtlInitUnicodeString( &KeyValueName, ValueName ); 01317 Status = ZwDeleteValueKey( Key, &KeyValueName ); 01318 01319 ZwClose( Key ); 01320 return Status; 01321 }

NTSTATUS RtlExpandEnvironmentStrings_U IN PVOID Environment  OPTIONAL,
IN PUNICODE_STRING  Source,
OUT PUNICODE_STRING  Destination,
OUT PULONG ReturnedLength  OPTIONAL
 

Definition at line 1325 of file rtl/regutil.c.

References L, NT_SUCCESS, NTSTATUS(), RTL_PAGED_CODE, RtlQueryEnvironmentVariable_U(), Status, and USHORT.

Referenced by InitializeRestrictedStuff(), and RtlpCallQueryRegistryRoutine().

01331 { 01332 NTSTATUS Status, Status1; 01333 PWCHAR Src, Src1, Dst; 01334 UNICODE_STRING VariableName, VariableValue; 01335 ULONG SrcLength, DstLength, VarLength, RequiredLength; 01336 01337 RTL_PAGED_CODE(); 01338 01339 Src = Source->Buffer; 01340 SrcLength = Source->Length; 01341 Dst = Destination->Buffer; 01342 DstLength = Destination->MaximumLength; 01343 Status = STATUS_SUCCESS; 01344 RequiredLength = 0; 01345 while (SrcLength >= sizeof(WCHAR)) { 01346 if (*Src == L'%') { 01347 Src1 = Src + 1; 01348 VarLength = 0; 01349 VariableName.Length = 0; 01350 VariableName.Buffer = Src1; 01351 01352 while (VarLength < (SrcLength - sizeof(WCHAR))) { 01353 if (*Src1 == L'%') { 01354 if (VarLength) { 01355 VariableName.Length = (USHORT)VarLength; 01356 VariableName.MaximumLength = (USHORT)VarLength; 01357 } 01358 break; 01359 01360 } 01361 01362 Src1++; 01363 VarLength += sizeof(WCHAR); 01364 } 01365 01366 if (VariableName.Length) { 01367 VariableValue.Buffer = Dst; 01368 VariableValue.Length = 0; 01369 VariableValue.MaximumLength = (USHORT)DstLength; 01370 Status1 = RtlQueryEnvironmentVariable_U( Environment, 01371 &VariableName, 01372 &VariableValue 01373 ); 01374 if (NT_SUCCESS( Status1 ) || Status1 == STATUS_BUFFER_TOO_SMALL) { 01375 RequiredLength += VariableValue.Length; 01376 Src = Src1 + 1; 01377 SrcLength -= (VarLength + 2*sizeof(WCHAR)); 01378 01379 if (NT_SUCCESS( Status1 )) { 01380 DstLength -= VariableValue.Length; 01381 Dst += VariableValue.Length / sizeof(WCHAR); 01382 01383 } else { 01384 Status = Status1; 01385 } 01386 01387 continue; 01388 } 01389 } 01390 } 01391 01392 if (NT_SUCCESS( Status )) { 01393 if (DstLength > sizeof(WCHAR)) { 01394 DstLength -= sizeof(WCHAR); 01395 *Dst++ = *Src; 01396 01397 } else { 01398 Status = STATUS_BUFFER_TOO_SMALL; 01399 } 01400 } 01401 01402 RequiredLength += sizeof(WCHAR); 01403 SrcLength -= sizeof(WCHAR); 01404 Src++; 01405 } 01406 01407 if (NT_SUCCESS( Status )) { 01408 if (DstLength) { 01409 DstLength -= sizeof(WCHAR); 01410 *Dst = UNICODE_NULL; 01411 01412 } else { 01413 Status = STATUS_BUFFER_TOO_SMALL; 01414 } 01415 } 01416 01417 RequiredLength += sizeof(WCHAR); 01418 01419 if (ARGUMENT_PRESENT( ReturnedLength )) { 01420 *ReturnedLength = RequiredLength; 01421 } 01422 01423 if (NT_SUCCESS( Status )) { 01424 Destination->Length = (USHORT)(RequiredLength - sizeof(WCHAR)); 01425 } 01426 01427 return Status; 01428 }

NTSTATUS RtlFormatCurrentUserKeyPath OUT PUNICODE_STRING  CurrentUserKeyPath  ) 
 

Definition at line 1453 of file rtl/regutil.c.

References FALSE, L, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateStringRoutine, RtlAppendUnicodeToString(), RtlConvertSidToUnicodeString(), RtlFreeUnicodeString(), RtlLengthSidAsUnicodeString(), SIZE_OF_TOKEN_INFORMATION, Status, TRUE, and USHORT.

Referenced by InitializeRestrictedStuff(), InitPreviousUserString(), RtlOpenCurrentUser(), and RtlpGetRegistryHandle().

01459 : 01460 01461 Initialize the supplied buffer with a string representation 01462 of the current user's SID. 01463 01464 Arguments: 01465 01466 CurrentUserKeyPath - Returns a string that represents the current 01467 user's root key in the Registry. Caller must call 01468 RtlFreeUnicodeString to free the buffer when done with it. 01469 01470 Return Value: 01471 01472 NTSTATUS - Returns STATUS_SUCCESS if the user string was 01473 succesfully initialized. 01474 01475 --*/ 01476 01477 { 01478 HANDLE TokenHandle; 01479 UCHAR TokenInformation[ SIZE_OF_TOKEN_INFORMATION ]; 01480 ULONG ReturnLength; 01481 ULONG SidStringLength ; 01482 UNICODE_STRING SidString ; 01483 NTSTATUS Status; 01484 01485 Status = ZwOpenThreadToken( NtCurrentThread(), 01486 TOKEN_READ, 01487 TRUE, 01488 &TokenHandle 01489 ); 01490 01491 if ( !NT_SUCCESS( Status ) && ( Status != STATUS_NO_TOKEN ) ) { 01492 return Status; 01493 } 01494 01495 if ( !NT_SUCCESS( Status ) ) { 01496 01497 Status = ZwOpenProcessToken( NtCurrentProcess(), 01498 TOKEN_READ, 01499 &TokenHandle 01500 ); 01501 if ( !NT_SUCCESS( Status )) { 01502 return Status; 01503 } 01504 } 01505 01506 Status = ZwQueryInformationToken( TokenHandle, 01507 TokenUser, 01508 TokenInformation, 01509 sizeof( TokenInformation ), 01510 &ReturnLength 01511 ); 01512 01513 ZwClose( TokenHandle ); 01514 01515 if ( !NT_SUCCESS( Status )) { 01516 return Status; 01517 } 01518 01519 Status = RtlLengthSidAsUnicodeString( 01520 ((PTOKEN_USER)TokenInformation)->User.Sid, 01521 &SidStringLength 01522 ); 01523 01524 if ( !NT_SUCCESS( Status ) ) { 01525 return Status ; 01526 } 01527 01528 CurrentUserKeyPath->Length = 0; 01529 CurrentUserKeyPath->MaximumLength = (USHORT)(SidStringLength + 01530 sizeof( L"\\REGISTRY\\USER\\" ) + 01531 sizeof( UNICODE_NULL )); 01532 CurrentUserKeyPath->Buffer = (RtlAllocateStringRoutine)( CurrentUserKeyPath->MaximumLength ); 01533 if (CurrentUserKeyPath->Buffer == NULL) { 01534 return STATUS_NO_MEMORY; 01535 } 01536 01537 // 01538 // Copy "\REGISTRY\USER" to the current user string. 01539 // 01540 01541 RtlAppendUnicodeToString( CurrentUserKeyPath, L"\\REGISTRY\\USER\\" ); 01542 01543 SidString.MaximumLength = (USHORT)SidStringLength ; 01544 SidString.Length = 0 ; 01545 SidString.Buffer = CurrentUserKeyPath->Buffer + 01546 (CurrentUserKeyPath->Length / sizeof(WCHAR) ); 01547 01548 Status = RtlConvertSidToUnicodeString( &SidString, 01549 ((PTOKEN_USER)TokenInformation)->User.Sid, 01550 FALSE 01551 ); 01552 if ( !NT_SUCCESS( Status )) { 01553 RtlFreeUnicodeString( CurrentUserKeyPath ); 01554 01555 } else { 01556 CurrentUserKeyPath->Length += SidString.Length ; 01557 } 01558 01559 return Status; 01560 }

ULONG RtlGetNtGlobalFlags VOID   ) 
 

Definition at line 1432 of file rtl/regutil.c.

References NtGlobalFlag.

Referenced by RtlCreateHeap(), RtlCreateUserProcess(), RtlpInitializeHeapSegment(), UserClientDllInitialize(), and UserServerDllInitialization().

01433 { 01434 #ifdef NTOS_KERNEL_RUNTIME 01435 return NtGlobalFlag; 01436 #else 01437 return NtCurrentPeb()->NtGlobalFlag; 01438 #endif 01439 }

NTSTATUS RtlOpenCurrentUser IN ULONG  DesiredAccess,
OUT PHANDLE  CurrentUserKey
 

Definition at line 1564 of file rtl/regutil.c.

References NT_SUCCESS, NTSTATUS(), NULL, RTL_PAGED_CODE, RtlFormatCurrentUserKeyPath(), RtlFreeUnicodeString(), RtlInitUnicodeString(), RtlpRegistryPaths, and Status.

Referenced by CliGetImeHotKeysFromRegistry(), ExpGetCurrentUserUILanguage(), ExpSetCurrentUserUILanguage(), GetActiveKeyboardName(), GetRegistryValues(), GetTimeouts(), and NtSetDefaultLocale().

01571 : 01572 01573 Attempts to open the the HKEY_CURRENT_USER predefined handle. 01574 01575 Arguments: 01576 01577 DesiredAccess - Specifies the access to open the key for. 01578 01579 CurrentUserKey - Returns a handle to the key \REGISTRY\USER\*. 01580 01581 Return Value: 01582 01583 Returns ERROR_SUCCESS (0) for success; error-code for failure. 01584 01585 --*/ 01586 01587 { 01588 UNICODE_STRING CurrentUserKeyPath; 01589 OBJECT_ATTRIBUTES Obja; 01590 NTSTATUS Status; 01591 01592 RTL_PAGED_CODE(); 01593 01594 // 01595 // Format the registry path for the current user. 01596 // 01597 01598 Status = RtlFormatCurrentUserKeyPath( &CurrentUserKeyPath ); 01599 if ( NT_SUCCESS(Status) ) { 01600 01601 InitializeObjectAttributes( &Obja, 01602 &CurrentUserKeyPath, 01603 OBJ_CASE_INSENSITIVE, 01604 NULL, 01605 NULL 01606 ); 01607 Status = ZwOpenKey( CurrentUserKey, 01608 DesiredAccess, 01609 &Obja 01610 ); 01611 RtlFreeUnicodeString( &CurrentUserKeyPath ); 01612 } 01613 01614 if ( !NT_SUCCESS(Status) ) { 01615 // 01616 // Opening \REGISTRY\USER<SID> failed, try \REGISTRY\USER\.DEFAULT 01617 // 01618 RtlInitUnicodeString( &CurrentUserKeyPath, RtlpRegistryPaths[ RTL_REGISTRY_USER ] ); 01619 InitializeObjectAttributes( &Obja, 01620 &CurrentUserKeyPath, 01621 OBJ_CASE_INSENSITIVE, 01622 NULL, 01623 NULL 01624 ); 01625 01626 Status = ZwOpenKey( CurrentUserKey, 01627 DesiredAccess, 01628 &Obja 01629 ); 01630 } 01631 01632 return Status; 01633 }

PVOID RtlpAllocDeallocQueryBuffer IN OUT SIZE_T *PAllocLength  OPTIONAL,
IN PVOID OldKeyValueInformation  OPTIONAL,
IN SIZE_T OldAllocLength  OPTIONAL,
OUT NTSTATUS *pStatus  OPTIONAL
 

Definition at line 679 of file rtl/regutil.c.

References ExAllocatePoolWithTag, ExFreePool(), NT_SUCCESS, NTSTATUS(), NULL, PagedPool, Ptr, and Status.

Referenced by RtlQueryRegistryValues().

00685 { 00686 PVOID Ptr = NULL; 00687 NTSTATUS Status = STATUS_SUCCESS; 00688 00689 #ifdef NTOS_KERNEL_RUNTIME 00690 00691 // 00692 // Kernel version 00693 // 00694 00695 UNREFERENCED_PARAMETER( OldAllocLength ); 00696 00697 if ( ARGUMENT_PRESENT(OldKeyValueInformation) ) { 00698 ExFreePool( OldKeyValueInformation ); 00699 } 00700 00701 if ( ARGUMENT_PRESENT(PAllocLength) ) { 00702 Ptr = ExAllocatePoolWithTag( PagedPool, *PAllocLength, 'vrqR' ); 00703 if (Ptr == NULL) { 00704 Status = STATUS_NO_MEMORY; 00705 } 00706 } 00707 00708 #else 00709 00710 // 00711 // User version 00712 // 00713 00714 if ( ARGUMENT_PRESENT(OldKeyValueInformation) ) { 00715 Status = ZwFreeVirtualMemory( NtCurrentProcess(), 00716 &OldKeyValueInformation, 00717 &OldAllocLength, 00718 MEM_RELEASE ); 00719 } 00720 00721 if ( ARGUMENT_PRESENT(PAllocLength) ) { 00722 00723 Status = ZwAllocateVirtualMemory( NtCurrentProcess(), 00724 &Ptr, 00725 0, 00726 PAllocLength, 00727 MEM_COMMIT, 00728 PAGE_READWRITE ); 00729 if (!NT_SUCCESS(Status)) { 00730 Ptr = NULL; 00731 } 00732 } 00733 00734 #endif 00735 00736 if ( ARGUMENT_PRESENT(pStatus) ) { 00737 *pStatus = Status; 00738 } 00739 00740 return Ptr; 00741 }

NTSTATUS RtlpCallQueryRegistryRoutine IN PRTL_QUERY_REGISTRY_TABLE  QueryTable,
IN PKEY_VALUE_FULL_INFORMATION  KeyValueInformation,
IN OUT PULONG  PKeyValueInfoLength,
IN PVOID  Context,
IN PVOID Environment  OPTIONAL
 

Definition at line 281 of file rtl/regutil.c.

References DbgPrint, FALSE, L, MAX_NONNULL_USTRING, MAX_USTRING, Name, NT_SUCCESS, NTSTATUS(), QuadAlignPtr, RtlExpandEnvironmentStrings_U(), RtlpQueryRegistryDirect(), Status, TRUE, USHORT, and ValueName.

Referenced by RtlQueryRegistryValues().

00291 : 00292 00293 This function implements the caller out the a caller specified 00294 routine. It is reponsible for capturing the arguments for the 00295 routine and then calling it. If not specifically disabled, this 00296 routine will converted REG_EXPAND_SZ Registry values to REG_SZ by 00297 calling RtlExpandEnvironmentStrings_U prior to calling the routine. 00298 It will also converted REG_MULTI_SZ registry values into multiple 00299 REG_SZ calls to the specified routine. 00300 00301 N.B. UNICODE_STRINGs cannot handle strings exceeding MAX_USTRING bytes. This creates 00302 issues both for expansion and for returning queries. Whenever this limitation 00303 is a encountered, we punt as best we can -- often returning an unexpanded, or perhaps 00304 truncated stream -- since this seems to create fewer problems for our callers than 00305 if we unexpectedly fail. 00306 00307 Arguments: 00308 00309 QueryTable - specifies the current query table entry. 00310 00311 KeyValueInformation - points to a buffer that contains the information 00312 about the current registry value. 00313 00314 PKeyValueInfoLength - pointer to the maximum length of the KeyValueInformation 00315 buffer. This function will use the 00316 unused portion at the end of this buffer for storing null terminated 00317 value name strings and the expanded version of REG_EXPAND_SZ values. 00318 PKeyValueInfoLength returns an estimate of the space required if 00319 STATUS_BUFFER_TOO_SMALL is returned. This estimate can be used to retry 00320 with a larger buffer. Two retries may be required if REG_EXPAND_SZ is specified. 00321 00322 Context - specifies a 32-bit quantity that is passed uninterpreted to 00323 each QueryRoutine called. 00324 00325 Environment - optional parameter, that if specified is the environment 00326 used when expanding variable values in REG_EXPAND_SZ registry 00327 values. 00328 00329 Return Value: 00330 00331 Status of the operation. 00332 00333 --*/ 00334 { 00335 NTSTATUS Status; 00336 ULONG ValueType; 00337 PWSTR ValueName; 00338 PVOID ValueData; 00339 ULONG ValueLength; 00340 PWSTR s; 00341 PCHAR FreeMem; 00342 PCHAR EndFreeMem; 00343 LONG FreeMemSize; 00344 ULONG KeyValueInfoLength; 00345 int retries; 00346 00347 00348 // 00349 // Return 0 length unless we return STATUS_BUFFER_TOO_SMALL. 00350 // 00351 KeyValueInfoLength = *PKeyValueInfoLength; 00352 *PKeyValueInfoLength = 0; 00353 00354 // 00355 // Initially assume the entire KeyValueInformation buffer is unused. 00356 // 00357 00358 FreeMem = (PCHAR)KeyValueInformation; 00359 FreeMemSize = KeyValueInfoLength; 00360 EndFreeMem = FreeMem + FreeMemSize; 00361 00362 if (KeyValueInformation->Type == REG_NONE || 00363 (KeyValueInformation->DataLength == 0 && 00364 KeyValueInformation->Type == QueryTable->DefaultType) 00365 ) { 00366 00367 // 00368 // If there is no registry value then see if they want to default 00369 // this value. 00370 // 00371 if (QueryTable->DefaultType == REG_NONE) { 00372 // 00373 // No default value specified. Return success unless this is 00374 // a required value. 00375 // 00376 if ( QueryTable->Flags & RTL_QUERY_REGISTRY_REQUIRED ) { 00377 return STATUS_OBJECT_NAME_NOT_FOUND; 00378 } else { 00379 return STATUS_SUCCESS; 00380 } 00381 } 00382 00383 // 00384 // Default requested. Setup the value data pointers from the 00385 // information in the table entry. 00386 // 00387 00388 ValueName = QueryTable->Name, 00389 ValueType = QueryTable->DefaultType; 00390 ValueData = QueryTable->DefaultData; 00391 ValueLength = QueryTable->DefaultLength; 00392 if (ValueLength == 0) { 00393 // 00394 // If the length of the value is zero, then calculate the 00395 // actual length for REG_SZ, REG_EXPAND_SZ and REG_MULTI_SZ 00396 // value types. 00397 // 00398 00399 s = (PWSTR)ValueData; 00400 if (ValueType == REG_SZ || ValueType == REG_EXPAND_SZ) { 00401 while (*s++ != UNICODE_NULL) { 00402 } 00403 ValueLength = (ULONG)((PCHAR)s - (PCHAR)ValueData); 00404 00405 } else if (ValueType == REG_MULTI_SZ) { 00406 while (*s != UNICODE_NULL) { 00407 while (*s++ != UNICODE_NULL) { 00408 } 00409 } 00410 ValueLength = (ULONG)((PCHAR)s - (PCHAR)ValueData) + sizeof( UNICODE_NULL ); 00411 } 00412 } 00413 00414 } else { 00415 if (!(QueryTable->Flags & RTL_QUERY_REGISTRY_DIRECT)) { 00416 LONG ValueSpaceNeeded; 00417 00418 // 00419 // There is a registry value. Calculate a pointer to the 00420 // free memory at the end of the value information buffer, 00421 // and its size. 00422 // 00423 if (KeyValueInformation->DataLength) { 00424 FreeMem += KeyValueInformation->DataOffset + 00425 KeyValueInformation->DataLength; 00426 } else { 00427 FreeMem += FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) + 00428 KeyValueInformation->NameLength; 00429 } 00430 FreeMem = (PCHAR)QuadAlignPtr(FreeMem); 00431 FreeMemSize = (ULONG) (EndFreeMem - FreeMem); 00432 00433 // 00434 // See if there is room in the free memory area for a null 00435 // terminated copy of the value name string. If not return 00436 // the length we require (so far) and an error. 00437 // 00438 ValueSpaceNeeded = KeyValueInformation->NameLength + sizeof(UNICODE_NULL); 00439 if ( FreeMemSize < ValueSpaceNeeded ) { 00440 00441 *PKeyValueInfoLength = (ULONG)(((PCHAR)FreeMem - (PCHAR)KeyValueInformation) + ValueSpaceNeeded); 00442 return STATUS_BUFFER_TOO_SMALL; 00443 } 00444 00445 // 00446 // There is room, so copy the string, and null terminate it. 00447 // 00448 00449 ValueName = (PWSTR)FreeMem; 00450 RtlCopyMemory( ValueName, 00451 KeyValueInformation->Name, 00452 KeyValueInformation->NameLength 00453 ); 00454 *(PWSTR)((PCHAR)ValueName + KeyValueInformation->NameLength) = UNICODE_NULL; 00455 00456 // 00457 // Update the free memory pointer and size to reflect the space we 00458 // just used for the null terminated value name. 00459 // 00460 FreeMem += ValueSpaceNeeded; 00461 FreeMem = (PCHAR)QuadAlignPtr(FreeMem); 00462 FreeMemSize = (LONG) (EndFreeMem - FreeMem); 00463 00464 } else { 00465 ValueName = QueryTable->Name; 00466 } 00467 00468 // 00469 // Get the remaining data for the registry value. 00470 // 00471 00472 ValueType = KeyValueInformation->Type; 00473 ValueData = (PCHAR)KeyValueInformation + KeyValueInformation->DataOffset; 00474 ValueLength = KeyValueInformation->DataLength; 00475 } 00476 00477 // 00478 // Unless specifically disabled for this table entry, preprocess 00479 // registry values of type REG_EXPAND_SZ and REG_MULTI_SZ 00480 // 00481 00482 if (!(QueryTable->Flags & RTL_QUERY_REGISTRY_NOEXPAND)) { 00483 if (ValueType == REG_MULTI_SZ) { 00484 PWSTR ValueEnd; 00485 00486 // 00487 // For REG_MULTI_SZ value type, call the query routine once 00488 // for each null terminated string in the registry value. Fake 00489 // like this is multiple REG_SZ values with the same value name. 00490 // 00491 00492 Status = STATUS_SUCCESS; 00493 ValueEnd = (PWSTR)((PCHAR)ValueData + ValueLength) - sizeof(UNICODE_NULL); 00494 s = (PWSTR)ValueData; 00495 while (s < ValueEnd) { 00496 while (*s++ != UNICODE_NULL) { 00497 } 00498 00499 ValueLength = (ULONG)((PCHAR)s - (PCHAR)ValueData); 00500 if (QueryTable->Flags & RTL_QUERY_REGISTRY_DIRECT) { 00501 Status = RtlpQueryRegistryDirect( REG_SZ, 00502 ValueData, 00503 ValueLength, 00504 QueryTable->EntryContext 00505 ); 00506 (PUNICODE_STRING)(QueryTable->EntryContext) += 1; 00507 00508 } else { 00509 Status = (QueryTable->QueryRoutine)( ValueName, 00510 REG_SZ, 00511 ValueData, 00512 ValueLength, 00513 Context, 00514 QueryTable->EntryContext 00515 ); 00516 } 00517 00518 // 00519 // We ignore failures where the buffer is too small. 00520 // 00521 if (Status == STATUS_BUFFER_TOO_SMALL) { 00522 Status = STATUS_SUCCESS; 00523 } 00524 00525 if (!NT_SUCCESS( Status )) { 00526 break; 00527 } 00528 00529 ValueData = (PVOID)s; 00530 } 00531 00532 return Status; 00533 } 00534 00535 // 00536 // If requested, expand the Value -- but only if the unexpanded value 00537 // can be represented with a UNICODE_STRING. 00538 // 00539 if ((ValueType == REG_EXPAND_SZ) && 00540 (ValueLength >= sizeof(WCHAR)) && 00541 (ValueLength <= MAX_NONNULL_USTRING)) { 00542 // 00543 // For REG_EXPAND_SZ value type, expand any environment variable 00544 // references in the registry value string using the Rtl function. 00545 // 00546 00547 UNICODE_STRING Source; 00548 UNICODE_STRING Destination; 00549 PWCHAR Src; 00550 ULONG SrcLength; 00551 ULONG RequiredLength; 00552 BOOLEAN PercentFound; 00553 00554 // 00555 // Don't expand unless we have to since expansion doubles buffer usage. 00556 // 00557 00558 PercentFound = FALSE; 00559 SrcLength = ValueLength - sizeof(WCHAR); 00560 Src = (PWSTR)ValueData; 00561 while (SrcLength) { 00562 if (*Src == L'%') { 00563 PercentFound = TRUE; 00564 break; 00565 } 00566 Src++; 00567 SrcLength -= sizeof(WCHAR); 00568 } 00569 00570 if ( PercentFound ) { 00571 Source.Buffer = (PWSTR)ValueData; 00572 Source.MaximumLength = (USHORT)ValueLength; 00573 Source.Length = (USHORT)(Source.MaximumLength - sizeof(UNICODE_NULL)); 00574 Destination.Buffer = (PWSTR)FreeMem; 00575 Destination.Length = 0; 00576 00577 if (FreeMemSize <= 0) { 00578 Destination.MaximumLength = 0; 00579 } else if (FreeMemSize <= MAX_USTRING) { 00580 Destination.MaximumLength = (USHORT)FreeMemSize; 00581 Destination.Buffer[FreeMemSize/sizeof(WCHAR) - 1] = UNICODE_NULL; 00582 } else { 00583 Destination.MaximumLength = MAX_USTRING; 00584 Destination.Buffer[MAX_USTRING/sizeof(WCHAR) - 1] = UNICODE_NULL; 00585 } 00586 00587 Status = RtlExpandEnvironmentStrings_U( Environment, 00588 &Source, 00589 &Destination, 00590 &RequiredLength 00591 ); 00592 ValueType = REG_SZ; 00593 00594 if ( NT_SUCCESS(Status) ) { 00595 ValueData = Destination.Buffer; 00596 ValueLength = Destination.Length + sizeof( UNICODE_NULL ); 00597 } else { 00598 if (Status == STATUS_BUFFER_TOO_SMALL) { 00599 *PKeyValueInfoLength = (ULONG)((PCHAR)FreeMem - (PCHAR)KeyValueInformation) + RequiredLength; 00600 } 00601 //#if DBG 00602 if (Status == STATUS_BUFFER_TOO_SMALL) { 00603 DbgPrint( "RTL: Expand variables for %wZ failed - Status == %lx Size %x > %x <%x>\n", 00604 &Source, Status, *PKeyValueInfoLength, KeyValueInfoLength, 00605 Destination.MaximumLength ); 00606 } else { 00607 DbgPrint( "RTL: Expand variables for %wZ failed - Status == %lx\n", &Source, Status ); 00608 } 00609 //#endif // DBG 00610 if ( Status == STATUS_BUFFER_OVERFLOW || 00611 Status == STATUS_BUFFER_TOO_SMALL && 00612 ( Destination.MaximumLength == MAX_USTRING 00613 || RequiredLength > MAX_NONNULL_USTRING ) ) { 00614 00615 // We can't do variable expansion because the required buffer can't be described 00616 // by a UNICODE_STRING, so we silently ignore expansion. 00617 //#if DBG 00618 DbgPrint("RtlpCallQueryRegistryRoutine: skipping expansion. Status=%x RequiredLength=%x\n", 00619 Status, RequiredLength); 00620 //#endif //DBG 00621 } else { 00622 return Status; 00623 } 00624 } 00625 } 00626 } 00627 //#if DBG 00628 else if (ValueType == REG_EXPAND_SZ && ValueLength > MAX_NONNULL_USTRING) { 00629 DbgPrint("RtlpCallQueryRegistryRoutine: skipping environment expansion. ValueLength=%x\n", 00630 ValueLength); 00631 } 00632 //#endif //DBG 00633 } 00634 00635 // 00636 // No special process of the registry value required so just call 00637 // the query routine. 00638 // 00639 if (QueryTable->Flags & RTL_QUERY_REGISTRY_DIRECT) { 00640 Status = RtlpQueryRegistryDirect( ValueType, 00641 ValueData, 00642 ValueLength, 00643 QueryTable->EntryContext 00644 ); 00645 } else { 00646 Status = (QueryTable->QueryRoutine)( ValueName, 00647 ValueType, 00648 ValueData, 00649 ValueLength, 00650 Context, 00651 QueryTable->EntryContext 00652 ); 00653 00654 } 00655 00656 // 00657 // At this point we fail silently if the buffer is too small. 00658 // 00659 if (Status == STATUS_BUFFER_TOO_SMALL) { 00660 Status = STATUS_SUCCESS; 00661 } 00662 return Status; 00663 }

NTSTATUS RtlpGetRegistryHandle IN ULONG  RelativeTo,
IN PCWSTR  KeyName,
IN BOOLEAN  WriteAccess,
OUT PHANDLE  Key
 

Definition at line 92 of file rtl/regutil.c.

References FALSE, Key, KeyName, KeyPath, KeyPathBuffer, L, NT_SUCCESS, NTSTATUS(), NULL, ObjectAttributes, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlFormatCurrentUserKeyPath(), RtlFreeUnicodeString(), RtlpRegistryPaths, Status, and TRUE.

Referenced by RtlCheckRegistryKey(), RtlCreateRegistryKey(), RtlDeleteRegistryValue(), RtlpGetTimeZoneInfoHandle(), RtlQueryRegistryValues(), and RtlWriteRegistryValue().

00098 { 00099 NTSTATUS Status; 00100 OBJECT_ATTRIBUTES ObjectAttributes; 00101 WCHAR KeyPathBuffer[ MAXIMUM_FILENAME_LENGTH+6 ]; 00102 UNICODE_STRING KeyPath; 00103 UNICODE_STRING CurrentUserKeyPath; 00104 BOOLEAN OptionalPath; 00105 00106 if (RelativeTo & RTL_REGISTRY_HANDLE) { 00107 *Key = (HANDLE)KeyName; 00108 return STATUS_SUCCESS; 00109 } 00110 00111 if (RelativeTo & RTL_REGISTRY_OPTIONAL) { 00112 RelativeTo &= ~RTL_REGISTRY_OPTIONAL; 00113 OptionalPath = TRUE; 00114 } else { 00115 OptionalPath = FALSE; 00116 } 00117 00118 if (RelativeTo >= RTL_REGISTRY_MAXIMUM) { 00119 return STATUS_INVALID_PARAMETER; 00120 } 00121 00122 KeyPath.Buffer = KeyPathBuffer; 00123 KeyPath.Length = 0; 00124 KeyPath.MaximumLength = sizeof( KeyPathBuffer ); 00125 if (RelativeTo != RTL_REGISTRY_ABSOLUTE) { 00126 if (RelativeTo == RTL_REGISTRY_USER && 00127 NT_SUCCESS( RtlFormatCurrentUserKeyPath( &CurrentUserKeyPath ) ) 00128 ) { 00129 Status = RtlAppendUnicodeStringToString( &KeyPath, &CurrentUserKeyPath ); 00130 RtlFreeUnicodeString( &CurrentUserKeyPath ); 00131 } else { 00132 Status = RtlAppendUnicodeToString( &KeyPath, RtlpRegistryPaths[ RelativeTo ] ); 00133 } 00134 00135 if (!NT_SUCCESS( Status )) { 00136 return Status; 00137 } 00138 00139 Status = RtlAppendUnicodeToString( &KeyPath, L"\\" ); 00140 if (!NT_SUCCESS( Status )) { 00141 return Status; 00142 } 00143 } 00144 00145 Status = RtlAppendUnicodeToString( &KeyPath, KeyName ); 00146 if (!NT_SUCCESS( Status )) { 00147 return Status; 00148 } 00149 00150 00151 InitializeObjectAttributes( &ObjectAttributes, 00152 &KeyPath, 00153 OBJ_CASE_INSENSITIVE, 00154 NULL, 00155 NULL 00156 ); 00157 #ifdef NTOS_KERNEL_RUNTIME 00158 // 00159 // Use a kernel-mode handle for the registry key to prevent 00160 // malicious apps from hijacking it. 00161 // 00162 ObjectAttributes.Attributes |= OBJ_KERNEL_HANDLE; 00163 #endif 00164 if (WriteAccess) { 00165 Status = ZwCreateKey( Key, 00166 GENERIC_WRITE, 00167 &ObjectAttributes, 00168 0, 00169 (PUNICODE_STRING) NULL, 00170 0, 00171 NULL 00172 ); 00173 } else { 00174 Status = ZwOpenKey( Key, 00175 MAXIMUM_ALLOWED | GENERIC_READ, 00176 &ObjectAttributes 00177 ); 00178 } 00179 00180 return Status; 00181 }

NTSTATUS RtlpGetTimeZoneInfoHandle IN BOOLEAN  WriteAccess,
OUT PHANDLE  Key
 

Definition at line 1637 of file rtl/regutil.c.

References Key, L, and RtlpGetRegistryHandle().

Referenced by RtlQueryTimeZoneInformation(), RtlSetActiveTimeBias(), and RtlSetTimeZoneInformation().

01641 { 01642 return RtlpGetRegistryHandle( RTL_REGISTRY_CONTROL, L"TimeZoneInformation", WriteAccess, Key ); 01643 }

NTSTATUS RtlpInitCurrentUserString OUT PUNICODE_STRING  UserString  ) 
 

NTSTATUS RtlpQueryRegistryDirect IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN OUT PVOID  Destination
 

Definition at line 200 of file rtl/regutil.c.

References DbgPrint, MAX_USTRING, n, NULL, RtlAllocateStringRoutine, and USHORT.

Referenced by RtlpCallQueryRegistryRoutine().

00206 { 00207 00208 if (ValueType == REG_SZ || 00209 ValueType == REG_EXPAND_SZ || 00210 ValueType == REG_MULTI_SZ 00211 ) { 00212 PUNICODE_STRING DestinationString; 00213 USHORT TruncValueLength; 00214 00215 // 00216 // Truncate ValueLength to be represented in a UNICODE_STRING 00217 // 00218 if ( ValueLength <= MAX_USTRING ) { 00219 TruncValueLength = (USHORT)ValueLength; 00220 } else { 00221 TruncValueLength = MAX_USTRING; 00222 00223 //davepr: move all this stuff to debug builds at some point. 00224 //davepr: but for now, I'd like to identify whether there are components 00225 //davepr: that are seeing silent failures. 00226 //#if DBG 00227 DbgPrint("RtlpQueryRegistryDirect: truncating SZ Value length: %x -> %x\n", 00228 ValueLength, TruncValueLength); 00229 //#endif //DBG 00230 } 00231 00232 DestinationString = (PUNICODE_STRING)Destination; 00233 if (DestinationString->Buffer == NULL) { 00234 00235 DestinationString->Buffer = RtlAllocateStringRoutine( TruncValueLength ); 00236 if (!DestinationString->Buffer) { 00237 return STATUS_NO_MEMORY; 00238 } 00239 DestinationString->MaximumLength = TruncValueLength; 00240 } else if (TruncValueLength > DestinationString->MaximumLength) { 00241 return STATUS_BUFFER_TOO_SMALL; 00242 } 00243 00244 RtlCopyMemory( DestinationString->Buffer, ValueData, TruncValueLength ); 00245 DestinationString->Length = (TruncValueLength - sizeof(UNICODE_NULL)); 00246 00247 } else if (ValueLength <= sizeof( ULONG )) { 00248 RtlCopyMemory( Destination, ValueData, ValueLength ); 00249 00250 } else { 00251 PULONG DestinationLength; 00252 00253 DestinationLength = (PULONG)Destination; 00254 if ((LONG)*DestinationLength < 0) { 00255 ULONG n = -(LONG)*DestinationLength; 00256 00257 if (n < ValueLength) { 00258 return STATUS_BUFFER_TOO_SMALL; 00259 } 00260 RtlCopyMemory( DestinationLength, ValueData, ValueLength ); 00261 00262 } else { 00263 if (*DestinationLength < (2 * sizeof(*DestinationLength) + ValueLength)) { 00264 return STATUS_BUFFER_TOO_SMALL; 00265 } 00266 00267 *DestinationLength++ = ValueLength; 00268 *DestinationLength++ = ValueType; 00269 RtlCopyMemory( DestinationLength, ValueData, ValueLength ); 00270 } 00271 } 00272 00273 return STATUS_SUCCESS; 00274 }

NTSTATUS RtlQueryRegistryValues IN ULONG  RelativeTo,
IN PCWSTR  Path,
IN PRTL_QUERY_REGISTRY_TABLE  QueryTable,
IN PVOID  Context,
IN PVOID Environment  OPTIONAL
 

Definition at line 744 of file rtl/regutil.c.

References DbgPrint, FALSE, Key, KeyPath, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, ObjectAttributes, RTL_PAGED_CODE, RtlInitUnicodeString(), RtlpAllocDeallocQueryBuffer(), RtlpCallQueryRegistryRoutine(), RtlpGetRegistryHandle(), RtlpRegistryQueryInitialBuffersize, Status, TRUE, and USHORT.

Referenced by CmpIsLastKnownGoodBoot(), FsVgaServiceParameters(), GetVersionInfo(), IopCallDriverAddDevice(), IopProcessCriticalDeviceRoutine(), NlsKbdInitializePerSystem(), RtlQueryTimeZoneInformation(), and RtlSetActiveTimeBias().

00754 : 00755 00756 This function allows the caller to query multiple values from the registry 00757 sub-tree with a single call. The caller specifies an initial key path, 00758 and a table. The table contains one or more entries that describe the 00759 key values and subkey names the caller is interested in. This function 00760 starts at the initial key and enumerates the entries in the table. For 00761 each entry that specifies a value name or subkey name that exists in 00762 the registry, this function calls the caller's query routine associated 00763 with each table entry. The caller's query routine is passed the value 00764 name, type, data and data length, to do with what they wish. 00765 00766 Arguments: 00767 00768 RelativeTo - specifies that the Path parameter is either an absolute 00769 registry path, or a path relative to a predefined key path. The 00770 following values are defined: 00771 00772 RTL_REGISTRY_ABSOLUTE - Path is an absolute registry path 00773 RTL_REGISTRY_SERVICES - Path is relative to \Registry\Machine\System\CurrentControlSet\Services 00774 RTL_REGISTRY_CONTROL - Path is relative to \Registry\Machine\System\CurrentControlSet\Control 00775 RTL_REGISTRY_WINDOWS_NT - Path is relative to \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion 00776 RTL_REGISTRY_DEVICEMAP - Path is relative to \Registry\Machine\Hardware\DeviceMap 00777 RTL_REGISTRY_USER - Path is relative to \Registry\User\CurrentUser 00778 00779 RTL_REGISTRY_OPTIONAL - Bit that specifies the key referenced by 00780 this parameter and the Path parameter is 00781 optional. 00782 00783 RTL_REGISTRY_HANDLE - Bit that specifies that the Path parameter 00784 is actually a registry handle to use. 00785 optional. 00786 00787 Path - specifies either an absolute registry path, or a path relative to the 00788 known location specified by the RelativeTo parameter. If the the 00789 RTL_REGISTRY_HANDLE flag is specified, then this parameter is a 00790 registry handle to use directly. 00791 00792 QueryTable - specifies a table of one or more value names and subkey names 00793 that the caller is interested. Each table entry contains a query routine 00794 that will be called for each value name that exists in the registry. 00795 The table is terminated when a NULL table entry is reached. A NULL 00796 table entry is defined as a table entry with a NULL QueryRoutine 00797 and a NULL Name field. 00798 00799 QueryTable entry fields: 00800 00801 PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine - This routine is 00802 called with the name, type, data and data length of a 00803 registry value. If this field is NULL, then it marks the 00804 end of the table. 00805 00806 ULONG Flags - These flags control how the following fields are 00807 interpreted. The following flags are defined: 00808 00809 RTL_QUERY_REGISTRY_SUBKEY - says the Name field of this 00810 table entry is another path to a registry key and all 00811 following table entries are for that key rather than the 00812 key specified by the Path parameter. This change in 00813 focus lasts until the end of the table or another 00814 RTL_QUERY_REGISTRY_SUBKEY entry is seen or 00815 RTL_QUERY_REGISTRY_TOPKEY entry is seen. Each such 00816 entry must specify a path that is relative to the Path 00817 specified on the call to this function. 00818 00819 RTL_QUERY_REGISTRY_TOPKEY - resets the current registry key 00820 handle to the original one specified by the RelativeTo 00821 and Path parameters. Useful for getting back to the 00822 original node after descending into subkeys with the 00823 RTL_QUERY_REGISTRY_SUBKEY flag. 00824 00825 RTL_QUERY_REGISTRY_REQUIRED - specifies that this value is 00826 required and if not found then STATUS_OBJECT_NAME_NOT_FOUND 00827 is returned. For a table entry that specifies a NULL 00828 name so that this function will enumerate all of the 00829 value names under a key, STATUS_OBJECT_NAME_NOT_FOUND 00830 will be returned only if there are no value keys under 00831 the current key. 00832 00833 RTL_QUERY_REGISTRY_NOVALUE - specifies that even though 00834 there is no Name field for this table entry, all the 00835 caller wants is a call back, it does NOT want to 00836 enumerate all the values under the current key. The 00837 query routine is called with NULL for ValueData, 00838 REG_NONE for ValueType and zero for ValueLength. 00839 00840 RTL_QUERY_REGISTRY_NOEXPAND - specifies that if the value 00841 type of this registry value is REG_EXPAND_SZ or 00842 REG_MULTI_SZ, then this function is NOT to do any 00843 preprocessing of the registry values prior to calling 00844 the query routine. Default behavior is to expand 00845 environment variable references in REG_EXPAND_SZ 00846 values and to enumerate the NULL terminated strings 00847 in a REG_MULTI_SZ value and call the query routine 00848 once for each, making it look like multiple REG_SZ 00849 values with the same ValueName. 00850 00851 RTL_QUERY_REGISTRY_DIRECT QueryRoutine field ignored. 00852 EntryContext field points to location to store value. 00853 For null terminated strings, EntryContext points to 00854 UNICODE_STRING structure that that describes maximum 00855 size of buffer. If .Buffer field is NULL then a buffer 00856 is allocated. 00857 00858 RTL_QUERY_REGISTRY_DELETE Used to delete value keys after 00859 they are queried. 00860 00861 PWSTR Name - This field gives the name of a Value the caller 00862 wants to query the value of. If this field is NULL, then 00863 the QueryRoutine specified for this table entry is called 00864 for all values associated with the current registry key. 00865 00866 PVOID EntryContext - This field is an arbitrary 32-bit field 00867 that is passed uninterpreted to each QueryRoutine called. 00868 00869 ULONG DefaultType 00870 PVOID DefaultData 00871 ULONG DefaultLength If there is no value name that matches the 00872 name given by the Name field, and the DefaultType field is 00873 not REG_NONE, then the QueryRoutine for this table entry is 00874 called with the contents of the following fields as if the 00875 value had been found in the registry. If the DefaultType is 00876 REG_SZ, REG_EXPANDSZ or REG_MULTI_SZ and the DefaultLength 00877 is 0 then the value of DefaultLength will be computed based 00878 on the length of unicode string pointed to by DefaultData 00879 00880 Context - specifies a 32-bit quantity that is passed uninterpreted to 00881 each QueryRoutine called. 00882 00883 Environment - optional parameter, that if specified is the environment 00884 used when expanding variable values in REG_EXPAND_SZ registry 00885 values. 00886 00887 Return Value: 00888 00889 Status of the operation. 00890 00891 --*/ 00892 00893 { 00894 NTSTATUS Status; 00895 OBJECT_ATTRIBUTES ObjectAttributes; 00896 UNICODE_STRING KeyPath, KeyValueName; 00897 HANDLE Key, Key1; 00898 PKEY_VALUE_FULL_INFORMATION KeyValueInformation; 00899 SIZE_T KeyValueInfoLength; 00900 ULONG ValueIndex; 00901 SIZE_T AllocLength; 00902 ULONG KeyResultLength; 00903 int retries; 00904 00905 RTL_PAGED_CODE(); 00906 00907 KeyValueInformation = NULL; 00908 00909 Status = RtlpGetRegistryHandle( RelativeTo, Path, FALSE, &Key ); 00910 if (!NT_SUCCESS( Status )) { 00911 return Status; 00912 } 00913 00914 if ((RelativeTo & RTL_REGISTRY_HANDLE) == 0) { 00915 RtlInitUnicodeString(&KeyPath, Path); 00916 } else { 00917 RtlInitUnicodeString(&KeyPath, NULL); 00918 } 00919 00920 AllocLength = RtlpRegistryQueryInitialBuffersize; 00921 00922 KeyValueInformation = RtlpAllocDeallocQueryBuffer( &AllocLength, NULL, 0, &Status ); 00923 if ( KeyValueInformation == NULL ) { 00924 if (!(RelativeTo & RTL_REGISTRY_HANDLE)) { 00925 ZwClose( Key ); 00926 } 00927 return Status; 00928 } 00929 00930 KeyValueInfoLength = AllocLength - sizeof(UNICODE_NULL); 00931 Key1 = Key; 00932 while (QueryTable->QueryRoutine != NULL || 00933 (QueryTable->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_DIRECT)) 00934 ) { 00935 00936 if ((QueryTable->Flags & RTL_QUERY_REGISTRY_DIRECT) && 00937 (QueryTable->Name == NULL || 00938 (QueryTable->Flags & RTL_QUERY_REGISTRY_SUBKEY) || 00939 QueryTable->QueryRoutine != NULL) 00940 ) { 00941 00942 Status = STATUS_INVALID_PARAMETER; 00943 break; 00944 } 00945 00946 if (QueryTable->Flags & (RTL_QUERY_REGISTRY_TOPKEY | RTL_QUERY_REGISTRY_SUBKEY)) { 00947 if (Key1 != Key) { 00948 NtClose( Key1 ); 00949 Key1 = Key; 00950 } 00951 } 00952 00953 if (QueryTable->Flags & RTL_QUERY_REGISTRY_SUBKEY) { 00954 if (QueryTable->Name == NULL) { 00955 Status = STATUS_INVALID_PARAMETER; 00956 } else { 00957 RtlInitUnicodeString( &KeyPath, QueryTable->Name ); 00958 InitializeObjectAttributes( &ObjectAttributes, 00959 &KeyPath, 00960 OBJ_CASE_INSENSITIVE, 00961 Key, 00962 NULL 00963 ); 00964 #ifdef NTOS_KERNEL_RUNTIME 00965 // 00966 // Use a kernel-mode handle for the registry key to prevent 00967 // malicious apps from hijacking it. 00968 // 00969 ObjectAttributes.Attributes |= OBJ_KERNEL_HANDLE; 00970 #endif 00971 Status = ZwOpenKey( &Key1, 00972 MAXIMUM_ALLOWED, 00973 &ObjectAttributes 00974 ); 00975 if (NT_SUCCESS( Status )) { 00976 if (QueryTable->QueryRoutine != NULL) { 00977 goto enumvalues; 00978 } 00979 } 00980 } 00981 00982 } else if (QueryTable->Name != NULL) { 00983 RtlInitUnicodeString( &KeyValueName, QueryTable->Name ); 00984 retries = 0; 00985 retryqueryvalue: 00986 // 00987 // A maximum of two retries is expected. If we see more we must 00988 // have miscomputed how much is required for the query buffer. 00989 // 00990 if (retries++ > 4) { 00991 //#if DBG 00992 DbgPrint("RtlQueryRegistryValues: Miscomputed buffer size at line %d\n", __LINE__); 00993 //#endif 00994 break; 00995 } 00996 00997 Status = ZwQueryValueKey( Key1, 00998 &KeyValueName, 00999 KeyValueFullInformation, 01000 KeyValueInformation, 01001 (ULONG) KeyValueInfoLength, 01002 &KeyResultLength 01003 ); 01004 // 01005 // ZwQueryValueKey returns overflow even though the problem is that 01006 // the specified buffer was too small, so we fix that up here so we 01007 // can decide correctly whether to retry or not below. 01008 // 01009 if (Status == STATUS_BUFFER_OVERFLOW) { 01010 Status = STATUS_BUFFER_TOO_SMALL; 01011 } 01012 01013 if (!NT_SUCCESS( Status )) { 01014 if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { 01015 01016 KeyValueInformation->Type = REG_NONE; 01017 KeyValueInformation->DataLength = 0; 01018 KeyResultLength = (ULONG)KeyValueInfoLength; 01019 Status = RtlpCallQueryRegistryRoutine( QueryTable, 01020 KeyValueInformation, 01021 &KeyResultLength, 01022 Context, 01023 Environment 01024 ); 01025 } 01026 01027 if (Status == STATUS_BUFFER_TOO_SMALL) { 01028 // 01029 // Try to allocate a larger buffer as this is one humongous 01030 // value. 01031 // 01032 AllocLength = KeyResultLength + sizeof(PVOID) + sizeof(UNICODE_NULL); 01033 KeyValueInformation = RtlpAllocDeallocQueryBuffer( &AllocLength, 01034 KeyValueInformation, 01035 AllocLength, 01036 &Status 01037 ); 01038 if ( KeyValueInformation == NULL) { 01039 break; 01040 } 01041 KeyValueInfoLength = AllocLength - sizeof(UNICODE_NULL); 01042 goto retryqueryvalue; 01043 } 01044 01045 } else { 01046 // 01047 // KeyResultLength holds the length of the data returned by ZwQueryKeyValue. 01048 // If this is a MULTI_SZ value, catenate a NUL. 01049 // 01050 if ( KeyValueInformation->Type == REG_MULTI_SZ ) { 01051 *(PWCHAR) ((PUCHAR)KeyValueInformation + KeyResultLength) = UNICODE_NULL; 01052 KeyValueInformation->DataLength += sizeof(UNICODE_NULL); 01053 } 01054 01055 KeyResultLength = (ULONG)KeyValueInfoLength; 01056 Status = RtlpCallQueryRegistryRoutine( QueryTable, 01057 KeyValueInformation, 01058 &KeyResultLength, 01059 Context, 01060 Environment 01061 ); 01062 01063 if ( Status == STATUS_BUFFER_TOO_SMALL ) { 01064 // 01065 // Try to allocate a larger buffer as this is one humongous 01066 // value. 01067 // 01068 AllocLength = KeyResultLength + sizeof(PVOID) + sizeof(UNICODE_NULL); 01069 KeyValueInformation = RtlpAllocDeallocQueryBuffer( &AllocLength, 01070 KeyValueInformation, 01071 AllocLength, 01072 &Status 01073 ); 01074 if ( KeyValueInformation == NULL) { 01075 break; 01076 } 01077 KeyValueInfoLength = AllocLength - sizeof(UNICODE_NULL); 01078 goto retryqueryvalue; 01079 } 01080 01081 // 01082 // If requested, delete the value key after it has been successfully queried. 01083 // 01084 01085 if (NT_SUCCESS( Status ) && QueryTable->Flags & RTL_QUERY_REGISTRY_DELETE) { 01086 ZwDeleteValueKey (Key1, &KeyValueName); 01087 } 01088 } 01089 01090 } else if (QueryTable->Flags & RTL_QUERY_REGISTRY_NOVALUE) { 01091 Status = (QueryTable->QueryRoutine)( NULL, 01092 REG_NONE, 01093 NULL, 01094 0, 01095 Context, 01096 QueryTable->EntryContext 01097 ); 01098 } else { 01099 01100 enumvalues: 01101 retries = 0; 01102 for (ValueIndex = 0; TRUE; ValueIndex++) { 01103 Status = ZwEnumerateValueKey( Key1, 01104 ValueIndex, 01105 KeyValueFullInformation, 01106 KeyValueInformation, 01107 (ULONG) KeyValueInfoLength, 01108 &KeyResultLength 01109 ); 01110 // 01111 // ZwEnumerateValueKey returns overflow even though the problem is that 01112 // the specified buffer was too small, so we fix that up here so we 01113 // can decide correctly whether to retry or not below. 01114 // 01115 if (Status == STATUS_BUFFER_OVERFLOW) { 01116 Status = STATUS_BUFFER_TOO_SMALL; 01117 } 01118 01119 if (Status == STATUS_NO_MORE_ENTRIES) { 01120 if (ValueIndex == 0 && (QueryTable->Flags & RTL_QUERY_REGISTRY_REQUIRED)) { 01121 Status = STATUS_OBJECT_NAME_NOT_FOUND; 01122 } else { 01123 Status = STATUS_SUCCESS; 01124 } 01125 break; 01126 } 01127 01128 if ( NT_SUCCESS( Status ) ) { 01129 01130 KeyResultLength = (ULONG)KeyValueInfoLength; 01131 Status = RtlpCallQueryRegistryRoutine( QueryTable, 01132 KeyValueInformation, 01133 &KeyResultLength, 01134 Context, 01135 Environment 01136 ); 01137 } 01138 01139 if (Status == STATUS_BUFFER_TOO_SMALL) { 01140 // 01141 // Allocate a larger buffer and try again. 01142 // 01143 AllocLength = KeyResultLength + sizeof(PVOID) + sizeof(UNICODE_NULL); 01144 KeyValueInformation = RtlpAllocDeallocQueryBuffer( &AllocLength, 01145 KeyValueInformation, 01146 AllocLength, 01147 &Status 01148 ); 01149 if (KeyValueInformation == NULL) { 01150 break; 01151 } 01152 KeyValueInfoLength = AllocLength - sizeof(UNICODE_NULL); 01153 ValueIndex -= 1; 01154 01155 // 01156 // A maximum of two retries is expected per loop iteration. 01157 // If we see more we must have miscomputed 01158 // how much is required for the query buffer. 01159 // 01160 if (retries++ <= 4) { 01161 continue; 01162 } 01163 //#if DBG 01164 DbgPrint("RtlQueryRegistryValues: Miscomputed buffer size at line %d\n", __LINE__); 01165 //#endif 01166 break; 01167 } 01168 01169 if (!NT_SUCCESS( Status )) { 01170 break; 01171 } 01172 01173 retries = 0; 01174 01175 // 01176 // If requested, delete the value key after it has been successfully queried. 01177 // After deletion the current ValueIndex is for the next sub-key, so adjust it. 01178 // KeyValueInformation->NameLength should fit in a USHORT, but we don't check since 01179 // it only harms our caller. 01180 // 01181 01182 if (QueryTable->Flags & RTL_QUERY_REGISTRY_DELETE) { 01183 KeyValueName.Buffer = KeyValueInformation->Name; 01184 KeyValueName.Length = (USHORT)KeyValueInformation->NameLength; 01185 KeyValueName.MaximumLength = (USHORT)KeyValueInformation->NameLength; 01186 Status = ZwDeleteValueKey( Key1, 01187 &KeyValueName 01188 ); 01189 if (NT_SUCCESS( Status )) { 01190 ValueIndex -= 1; 01191 } 01192 } 01193 } 01194 } 01195 01196 if (!NT_SUCCESS( Status )) { 01197 break; 01198 } 01199 01200 QueryTable++; 01201 } 01202 01203 if (Key != NULL && !(RelativeTo & RTL_REGISTRY_HANDLE)) { 01204 ZwClose( Key ); 01205 } 01206 01207 if (Key1 != NULL && Key1 != Key) { 01208 ZwClose( Key1 ); 01209 } 01210 01211 // 01212 // Free any query buffer we allocated. 01213 // 01214 (void) RtlpAllocDeallocQueryBuffer( NULL, KeyValueInformation, AllocLength, NULL ); 01215 return Status; 01216 }

NTSTATUS RtlQueryTimeZoneInformation OUT PRTL_TIME_ZONE_INFORMATION  TimeZoneInformation  ) 
 

Definition at line 1656 of file rtl/regutil.c.

References FALSE, Key, NT_SUCCESS, NTSTATUS(), NULL, RTL_PAGED_CODE, RtlpGetTimeZoneInfoHandle(), RtlQueryRegistryValues(), Status, szBias, szDaylightBias, szDaylightName, szDaylightStart, szStandardBias, szStandardName, and szStandardStart.

01659 { 01660 NTSTATUS Status; 01661 HANDLE Key; 01662 UNICODE_STRING StandardName, DaylightName; 01663 RTL_QUERY_REGISTRY_TABLE RegistryConfigurationTable[ 8 ]; 01664 01665 RTL_PAGED_CODE(); 01666 01667 Status = RtlpGetTimeZoneInfoHandle( FALSE, &Key ); 01668 if (!NT_SUCCESS( Status )) { 01669 return Status; 01670 } 01671 01672 RtlZeroMemory( TimeZoneInformation, sizeof( *TimeZoneInformation ) ); 01673 RtlZeroMemory( RegistryConfigurationTable, sizeof( RegistryConfigurationTable ) ); 01674 01675 RegistryConfigurationTable[ 0 ].Flags = RTL_QUERY_REGISTRY_DIRECT; 01676 RegistryConfigurationTable[ 0 ].Name = (PWSTR)szBias; 01677 RegistryConfigurationTable[ 0 ].EntryContext = &TimeZoneInformation->Bias; 01678 01679 01680 StandardName.Buffer = TimeZoneInformation->StandardName; 01681 StandardName.Length = 0; 01682 StandardName.MaximumLength = sizeof( TimeZoneInformation->StandardName ); 01683 RegistryConfigurationTable[ 1 ].Flags = RTL_QUERY_REGISTRY_DIRECT; 01684 RegistryConfigurationTable[ 1 ].Name = (PWSTR)szStandardName; 01685 RegistryConfigurationTable[ 1 ].EntryContext = &StandardName; 01686 01687 RegistryConfigurationTable[ 2 ].Flags = RTL_QUERY_REGISTRY_DIRECT; 01688 RegistryConfigurationTable[ 2 ].Name = (PWSTR)szStandardBias; 01689 RegistryConfigurationTable[ 2 ].EntryContext = &TimeZoneInformation->StandardBias; 01690 01691 RegistryConfigurationTable[ 3 ].Flags = RTL_QUERY_REGISTRY_DIRECT; 01692 RegistryConfigurationTable[ 3 ].Name = (PWSTR)szStandardStart; 01693 RegistryConfigurationTable[ 3 ].EntryContext = &TimeZoneInformation->StandardStart; 01694 *(PLONG)(RegistryConfigurationTable[ 3 ].EntryContext) = -(LONG)sizeof( TIME_FIELDS ); 01695 01696 DaylightName.Buffer = TimeZoneInformation->DaylightName; 01697 DaylightName.Length = 0; 01698 DaylightName.MaximumLength = sizeof( TimeZoneInformation->DaylightName ); 01699 RegistryConfigurationTable[ 4 ].Flags = RTL_QUERY_REGISTRY_DIRECT; 01700 RegistryConfigurationTable[ 4 ].Name = (PWSTR)szDaylightName; 01701 RegistryConfigurationTable[ 4 ].EntryContext = &DaylightName; 01702 01703 RegistryConfigurationTable[ 5 ].Flags = RTL_QUERY_REGISTRY_DIRECT; 01704 RegistryConfigurationTable[ 5 ].Name = (PWSTR)szDaylightBias; 01705 RegistryConfigurationTable[ 5 ].EntryContext = &TimeZoneInformation->DaylightBias; 01706 01707 RegistryConfigurationTable[ 6 ].Flags = RTL_QUERY_REGISTRY_DIRECT; 01708 RegistryConfigurationTable[ 6 ].Name = (PWSTR)szDaylightStart; 01709 RegistryConfigurationTable[ 6 ].EntryContext = &TimeZoneInformation->DaylightStart; 01710 *(PLONG)(RegistryConfigurationTable[ 6 ].EntryContext) = -(LONG)sizeof( TIME_FIELDS ); 01711 01712 Status = RtlQueryRegistryValues( RTL_REGISTRY_HANDLE, 01713 (PWSTR)Key, 01714 RegistryConfigurationTable, 01715 NULL, 01716 NULL 01717 ); 01718 ZwClose( Key ); 01719 return Status; 01720 }

NTSTATUS RtlSetActiveTimeBias IN LONG  ActiveBias  ) 
 

Definition at line 1811 of file rtl/regutil.c.

References Key, L, NT_SUCCESS, NTSTATUS(), NULL, RTL_PAGED_CODE, RtlpGetTimeZoneInfoHandle(), RtlQueryRegistryValues(), RtlWriteRegistryValue(), Status, and TRUE.

01814 { 01815 NTSTATUS Status; 01816 HANDLE Key; 01817 RTL_QUERY_REGISTRY_TABLE RegistryConfigurationTable[ 2 ]; 01818 LONG CurrentActiveBias; 01819 01820 RTL_PAGED_CODE(); 01821 01822 Status = RtlpGetTimeZoneInfoHandle( TRUE, &Key ); 01823 if (!NT_SUCCESS( Status )) { 01824 return Status; 01825 } 01826 01827 RtlZeroMemory( RegistryConfigurationTable, sizeof( RegistryConfigurationTable ) ); 01828 RegistryConfigurationTable[ 0 ].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; 01829 RegistryConfigurationTable[ 0 ].Name = L"ActiveTimeBias"; 01830 RegistryConfigurationTable[ 0 ].EntryContext = &CurrentActiveBias; 01831 01832 Status = RtlQueryRegistryValues( RTL_REGISTRY_HANDLE, 01833 (PWSTR)Key, 01834 RegistryConfigurationTable, 01835 NULL, 01836 NULL 01837 ); 01838 01839 if ( !NT_SUCCESS(Status) || CurrentActiveBias != ActiveBias ) { 01840 01841 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01842 (PWSTR)Key, 01843 L"ActiveTimeBias", 01844 REG_DWORD, 01845 &ActiveBias, 01846 sizeof( ActiveBias ) 01847 ); 01848 } 01849 01850 ZwClose( Key ); 01851 return Status; 01852 }

NTSTATUS RtlSetTimeZoneInformation IN PRTL_TIME_ZONE_INFORMATION  TimeZoneInformation  ) 
 

Definition at line 1724 of file rtl/regutil.c.

References Key, NT_SUCCESS, NTSTATUS(), RTL_PAGED_CODE, RtlpGetTimeZoneInfoHandle(), RtlWriteRegistryValue(), Status, szBias, szDaylightBias, szDaylightName, szDaylightStart, szStandardBias, szStandardName, szStandardStart, and TRUE.

01727 { 01728 NTSTATUS Status; 01729 HANDLE Key; 01730 01731 RTL_PAGED_CODE(); 01732 01733 Status = RtlpGetTimeZoneInfoHandle( TRUE, &Key ); 01734 if (!NT_SUCCESS( Status )) { 01735 return Status; 01736 } 01737 01738 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01739 (PWSTR)Key, 01740 szBias, 01741 REG_DWORD, 01742 &TimeZoneInformation->Bias, 01743 sizeof( TimeZoneInformation->Bias ) 01744 ); 01745 if (NT_SUCCESS( Status )) { 01746 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01747 (PWSTR)Key, 01748 szStandardName, 01749 REG_SZ, 01750 TimeZoneInformation->StandardName, 01751 (wcslen( TimeZoneInformation->StandardName ) + 1) * sizeof( WCHAR ) 01752 ); 01753 } 01754 01755 if (NT_SUCCESS( Status )) { 01756 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01757 (PWSTR)Key, 01758 szStandardBias, 01759 REG_DWORD, 01760 &TimeZoneInformation->StandardBias, 01761 sizeof( TimeZoneInformation->StandardBias ) 01762 ); 01763 } 01764 01765 if (NT_SUCCESS( Status )) { 01766 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01767 (PWSTR)Key, 01768 szStandardStart, 01769 REG_BINARY, 01770 &TimeZoneInformation->StandardStart, 01771 sizeof( TimeZoneInformation->StandardStart ) 01772 ); 01773 } 01774 01775 if (NT_SUCCESS( Status )) { 01776 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01777 (PWSTR)Key, 01778 szDaylightName, 01779 REG_SZ, 01780 TimeZoneInformation->DaylightName, 01781 (wcslen( TimeZoneInformation->DaylightName ) + 1) * sizeof( WCHAR ) 01782 ); 01783 } 01784 01785 if (NT_SUCCESS( Status )) { 01786 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01787 (PWSTR)Key, 01788 szDaylightBias, 01789 REG_DWORD, 01790 &TimeZoneInformation->DaylightBias, 01791 sizeof( TimeZoneInformation->DaylightBias ) 01792 ); 01793 } 01794 01795 if (NT_SUCCESS( Status )) { 01796 Status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, 01797 (PWSTR)Key, 01798 szDaylightStart, 01799 REG_BINARY, 01800 &TimeZoneInformation->DaylightStart, 01801 sizeof( TimeZoneInformation->DaylightStart ) 01802 ); 01803 } 01804 01805 ZwClose( Key ); 01806 return Status; 01807 }

NTSTATUS RtlWriteRegistryValue IN ULONG  RelativeTo,
IN PCWSTR  Path,
IN PCWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength
 

Definition at line 1220 of file rtl/regutil.c.

References Key, NT_SUCCESS, NTSTATUS(), RTL_PAGED_CODE, RtlInitUnicodeString(), RtlpGetRegistryHandle(), Status, TRUE, and ValueName.

Referenced by DriverEntry(), RtlSetActiveTimeBias(), and RtlSetTimeZoneInformation().

01228 { 01229 NTSTATUS Status; 01230 UNICODE_STRING KeyValueName; 01231 HANDLE Key; 01232 01233 RTL_PAGED_CODE(); 01234 01235 Status = RtlpGetRegistryHandle( RelativeTo, Path, TRUE, &Key ); 01236 if (!NT_SUCCESS( Status )) { 01237 return Status; 01238 } 01239 01240 RtlInitUnicodeString( &KeyValueName, ValueName ); 01241 Status = ZwSetValueKey( Key, 01242 &KeyValueName, 01243 0, 01244 ValueType, 01245 ValueData, 01246 ValueLength 01247 ); 01248 if (!(RelativeTo & RTL_REGISTRY_HANDLE)) { 01249 ZwClose( Key ); 01250 } 01251 01252 return Status; 01253 }


Variable Documentation

const PWSTR RtlpRegistryPaths[RTL_REGISTRY_MAXIMUM]
 

Definition at line 89 of file rtl/regutil.c.

Referenced by RtlOpenCurrentUser(), and RtlpGetRegistryHandle().

SIZE_T RtlpRegistryQueryInitialBuffersize = PAGE_SIZE
 

Definition at line 672 of file rtl/regutil.c.

Referenced by RtlQueryRegistryValues().

const WCHAR szBias[]
 

Definition at line 1647 of file rtl/regutil.c.

Referenced by RtlQueryTimeZoneInformation(), and RtlSetTimeZoneInformation().

const WCHAR szDaylightBias[]
 

Definition at line 1652 of file rtl/regutil.c.

Referenced by RtlQueryTimeZoneInformation(), and RtlSetTimeZoneInformation().

const WCHAR szDaylightName[]
 

Definition at line 1651 of file rtl/regutil.c.

Referenced by RtlQueryTimeZoneInformation(), and RtlSetTimeZoneInformation().

const WCHAR szDaylightStart[]
 

Definition at line 1653 of file rtl/regutil.c.

Referenced by RtlQueryTimeZoneInformation(), and RtlSetTimeZoneInformation().

const WCHAR szStandardBias[]
 

Definition at line 1649 of file rtl/regutil.c.

Referenced by RtlQueryTimeZoneInformation(), and RtlSetTimeZoneInformation().

const WCHAR szStandardName[]
 

Definition at line 1648 of file rtl/regutil.c.

Referenced by RtlQueryTimeZoneInformation(), and RtlSetTimeZoneInformation().

const WCHAR szStandardStart[]
 

Definition at line 1650 of file rtl/regutil.c.

Referenced by RtlQueryTimeZoneInformation(), and RtlSetTimeZoneInformation().


Generated on Sat May 15 19:45:28 2004 for test by doxygen 1.3.7