diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/tdi/tcpip/ip/ntreg.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/tdi/tcpip/ip/ntreg.c')
-rw-r--r-- | private/ntos/tdi/tcpip/ip/ntreg.c | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/private/ntos/tdi/tcpip/ip/ntreg.c b/private/ntos/tdi/tcpip/ip/ntreg.c new file mode 100644 index 000000000..e9c53c208 --- /dev/null +++ b/private/ntos/tdi/tcpip/ip/ntreg.c @@ -0,0 +1,672 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + ntreg.c + +Abstract: + + This source file contains the routines to to access the NT Registry for + configuration info. + + +Author: + + Mike Massa (mikemas) September 3, 1993 + + (taken from routines by jballard) + +Revision History: + +--*/ + + +#include <oscfg.h> +#include <ndis.h> +#include <cxport.h> + + +#define WORK_BUFFER_SIZE 512 + + +// +// Local function prototypes +// +NTSTATUS +OpenRegKey( + PHANDLE HandlePtr, + PWCHAR KeyName + ); + +NTSTATUS +GetRegDWORDValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PULONG ValueData + ); + +NTSTATUS +SetRegDWORDValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PULONG ValueData + ); + +NTSTATUS +GetRegStringValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PKEY_VALUE_PARTIAL_INFORMATION *ValueData, + PUSHORT ValueSize + ); + +NTSTATUS +GetRegSZValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PUNICODE_STRING ValueData, + PULONG ValueType + ); + +NTSTATUS +GetRegMultiSZValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PUNICODE_STRING ValueData + ); + +VOID +InitRegDWORDParameter( + HANDLE RegKey, + PWCHAR ValueName, + ULONG *Value, + ULONG DefaultValue + ); + + +#ifdef ALLOC_PRAGMA +// +// All of the init code can be discarded +// + +#ifndef _PNP_POWER + +#pragma alloc_text(INIT, GetRegDWORDValue) +#pragma alloc_text(INIT, SetRegDWORDValue) +#pragma alloc_text(INIT, InitRegDWORDParameter) + +#else // _PNP_POWER + +#pragma alloc_text(PAGE, GetRegDWORDValue) +#pragma alloc_text(PAGE, SetRegDWORDValue) +#pragma alloc_text(PAGE, InitRegDWORDParameter) + +#endif // _PNP_POWER + +// +// This code is pagable. +// +#pragma alloc_text(PAGE, OpenRegKey) +#pragma alloc_text(PAGE, GetRegStringValue) +#pragma alloc_text(PAGE, GetRegSZValue) +#pragma alloc_text(PAGE, GetRegMultiSZValue) + + +#endif // ALLOC_PRAGMA + + + +// +// Function definitions +// +NTSTATUS +OpenRegKey( + PHANDLE HandlePtr, + PWCHAR KeyName + ) + +/*++ + +Routine Description: + + Opens a Registry key and returns a handle to it. + +Arguments: + + HandlePtr - The varible into which to write the opened handle. + KeyName - The name of the Registry key to open. + +Return Value: + + STATUS_SUCCESS or an appropriate failure code. + +--*/ + +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING UKeyName; + + + PAGED_CODE(); + + RtlInitUnicodeString(&UKeyName, KeyName); + + memset(&ObjectAttributes, 0, sizeof(OBJECT_ATTRIBUTES)); + InitializeObjectAttributes(&ObjectAttributes, + &UKeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = ZwOpenKey(HandlePtr, + KEY_READ, + &ObjectAttributes); + + return Status; +} + + + +NTSTATUS +GetRegDWORDValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PULONG ValueData + ) + +/*++ + +Routine Description: + + Reads a REG_DWORD value from the registry into the supplied variable. + +Arguments: + + KeyHandle - Open handle to the parent key of the value to read. + ValueName - The name of the value to read. + ValueData - The variable into which to read the data. + +Return Value: + + STATUS_SUCCESS or an appropriate failure code. + +--*/ + +{ + NTSTATUS status; + ULONG resultLength; + PKEY_VALUE_FULL_INFORMATION keyValueFullInformation; + UCHAR keybuf[WORK_BUFFER_SIZE]; + UNICODE_STRING UValueName; + + +#ifdef _PNP_POWER + PAGED_CODE(); +#endif // _PNP_POWER + + RtlInitUnicodeString(&UValueName, ValueName); + + keyValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)keybuf; + RtlZeroMemory(keyValueFullInformation, sizeof(keyValueFullInformation)); + + + status = ZwQueryValueKey(KeyHandle, + &UValueName, + KeyValueFullInformation, + keyValueFullInformation, + WORK_BUFFER_SIZE, + &resultLength); + + if (NT_SUCCESS(status)) { + if (keyValueFullInformation->Type != REG_DWORD) { + status = STATUS_INVALID_PARAMETER_MIX; + } else { + *ValueData = *((ULONG UNALIGNED *)((PCHAR)keyValueFullInformation + + keyValueFullInformation->DataOffset)); + } + } + + return status; +} + + + +NTSTATUS +SetRegDWORDValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PULONG ValueData + ) + +/*++ + +Routine Description: + + Writes the contents of a variable to a REG_DWORD value. + +Arguments: + + KeyHandle - Open handle to the parent key of the value to write. + ValueName - The name of the value to write. + ValueData - The variable from which to write the data. + +Return Value: + + STATUS_SUCCESS or an appropriate failure code. + +--*/ + +{ + NTSTATUS status; + UNICODE_STRING UValueName; + + +#ifdef _PNP_POWER + PAGED_CODE(); +#endif // _PNP_POWER + + RtlInitUnicodeString(&UValueName, ValueName); + + status = ZwSetValueKey(KeyHandle, + &UValueName, + 0, + REG_DWORD, + ValueData, + sizeof(ULONG)); + + return status; +} + + + +NTSTATUS +GetRegStringValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PKEY_VALUE_PARTIAL_INFORMATION *ValueData, + PUSHORT ValueSize + ) + +/*++ + +Routine Description: + + Reads a REG_*_SZ string value from the Registry into the supplied + key value buffer. If the buffer string buffer is not large enough, + it is reallocated. + +Arguments: + + KeyHandle - Open handle to the parent key of the value to read. + ValueName - The name of the value to read. + ValueData - Destination for the read data. + ValueSize - Size of the ValueData buffer. Updated on output. + +Return Value: + + STATUS_SUCCESS or an appropriate failure code. + +--*/ + +{ + NTSTATUS status; + ULONG resultLength; + UNICODE_STRING UValueName; + + + PAGED_CODE(); + + RtlInitUnicodeString(&UValueName, ValueName); + + status = ZwQueryValueKey( + KeyHandle, + &UValueName, + KeyValuePartialInformation, + *ValueData, + (ULONG) *ValueSize, + &resultLength + ); + + if ( (status == STATUS_BUFFER_OVERFLOW) || + (status == STATUS_BUFFER_TOO_SMALL) + ) + { + PVOID temp; + + // + // Free the old buffer and allocate a new one of the + // appropriate size. + // + + ASSERT(resultLength > (ULONG) *ValueSize); + + if (resultLength <= 0xFFFF) { + + temp = CTEAllocMem(resultLength); + + if (temp != NULL) { + + if (*ValueData != NULL) { + CTEFreeMem(*ValueData); + } + + *ValueData = temp; + *ValueSize = (USHORT) resultLength; + + status = ZwQueryValueKey(KeyHandle, + &UValueName, + KeyValuePartialInformation, + *ValueData, + *ValueSize, + &resultLength + ); + + ASSERT( (status != STATUS_BUFFER_OVERFLOW) && + (status != STATUS_BUFFER_TOO_SMALL) + ); + } + else { + status = STATUS_INSUFFICIENT_RESOURCES; + } + } + else { + status = STATUS_BUFFER_TOO_SMALL; + } + } + + return(status); +} + + + +NTSTATUS +GetRegMultiSZValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PUNICODE_STRING ValueData + ) + +/*++ + +Routine Description: + + Reads a REG_MULTI_SZ string value from the Registry into the supplied + Unicode string. If the Unicode string buffer is not large enough, + it is reallocated. + +Arguments: + + KeyHandle - Open handle to the parent key of the value to read. + ValueName - The name of the value to read. + ValueData - Destination Unicode string for the value data. + +Return Value: + + STATUS_SUCCESS or an appropriate failure code. + +--*/ + +{ + NTSTATUS status; + ULONG resultLength; + PKEY_VALUE_PARTIAL_INFORMATION keyValuePartialInformation; + UNICODE_STRING UValueName; + + + PAGED_CODE(); + + ValueData->Length = 0; + + status = GetRegStringValue( + KeyHandle, + ValueName, + (PKEY_VALUE_PARTIAL_INFORMATION *) &(ValueData->Buffer), + &(ValueData->MaximumLength) + ); + + if (NT_SUCCESS(status)) { + + keyValuePartialInformation = + (PKEY_VALUE_PARTIAL_INFORMATION) ValueData->Buffer; + + if (keyValuePartialInformation->Type == REG_MULTI_SZ) { + + ValueData->Length = (USHORT) + keyValuePartialInformation->DataLength; + + RtlCopyMemory( + ValueData->Buffer, + &(keyValuePartialInformation->Data), + ValueData->Length + ); + } + else { + status = STATUS_INVALID_PARAMETER_MIX; + } + } + + return status; + +} // GetRegMultiSZValue + + + +NTSTATUS +GetRegSZValue( + HANDLE KeyHandle, + PWCHAR ValueName, + PUNICODE_STRING ValueData, + PULONG ValueType + ) + +/*++ + +Routine Description: + + Reads a REG_SZ string value from the Registry into the supplied + Unicode string. If the Unicode string buffer is not large enough, + it is reallocated. + +Arguments: + + KeyHandle - Open handle to the parent key of the value to read. + ValueName - The name of the value to read. + ValueData - Destination Unicode string for the value data. + ValueType - On return, contains the Registry type of the value read. + +Return Value: + + STATUS_SUCCESS or an appropriate failure code. + +--*/ + +{ + NTSTATUS status; + ULONG resultLength; + PKEY_VALUE_PARTIAL_INFORMATION keyValuePartialInformation; + UNICODE_STRING UValueName; + + + PAGED_CODE(); + + ValueData->Length = 0; + + status = GetRegStringValue( + KeyHandle, + ValueName, + (PKEY_VALUE_PARTIAL_INFORMATION *) &(ValueData->Buffer), + &(ValueData->MaximumLength) + ); + + if (NT_SUCCESS(status)) { + + keyValuePartialInformation = + (PKEY_VALUE_PARTIAL_INFORMATION)ValueData->Buffer; + + if ((keyValuePartialInformation->Type == REG_SZ) || + (keyValuePartialInformation->Type == REG_EXPAND_SZ) + ) + { + WCHAR *src; + WCHAR *dst; + ULONG dataLength; + + + *ValueType = keyValuePartialInformation->Type; + dataLength = keyValuePartialInformation->DataLength; + + ASSERT(dataLength <= ValueData->MaximumLength); + + dst = ValueData->Buffer; + src = (PWCHAR) &(keyValuePartialInformation->Data); + + while (ValueData->Length <= dataLength) { + + if ( (*dst++ = *src++) == UNICODE_NULL ) { + break; + } + + ValueData->Length += sizeof(WCHAR); + } + + if (ValueData->Length < (ValueData->MaximumLength - 1)) { + ValueData->Buffer[ValueData->Length/sizeof(WCHAR)] = + UNICODE_NULL; + } + } + else { + status = STATUS_INVALID_PARAMETER_MIX; + } + } + + return status; +} + + + +VOID +InitRegDWORDParameter( + HANDLE RegKey, + PWCHAR ValueName, + ULONG *Value, + ULONG DefaultValue + ) + +/*++ + +Routine Description: + + Reads a REG_DWORD parameter from the Registry into a variable. If the + read fails, the variable is initialized to a default. + +Arguments: + + RegKey - Open handle to the parent key of the value to read. + ValueName - The name of the value to read. + Value - Destination variable into which to read the data. + DefaultValue - Default to assign if the read fails. + +Return Value: + + STATUS_SUCCESS or an appropriate failure code. + +--*/ + +{ + NTSTATUS status; + + +#ifdef _PNP_POWER + PAGED_CODE(); +#endif // _PNP_POWER + + status = GetRegDWORDValue( + RegKey, + ValueName, + Value + ); + + if (!NT_SUCCESS(status)) { + // + // These registry parameters override the defaults, so their + // absence is not an error. + // + *Value = DefaultValue; + } + + return; +} + + +PWCHAR +EnumRegMultiSz( + IN PWCHAR MszString, + IN ULONG MszStringLength, + IN ULONG StringIndex + ) +/*++ + + Routine Description: + + Parses a REG_MULTI_SZ string and returns the specified substring. + + Arguments: + + MszString - A pointer to the REG_MULTI_SZ string. + + MszStringLength - The length of the REG_MULTI_SZ string, including the + terminating null character. + + StringIndex - Index number of the substring to return. Specifiying + index 0 retrieves the first substring. + + Return Value: + + A pointer to the specified substring. + + Notes: + + This code is called at raised IRQL. It is not pageable. + +--*/ +{ + PWCHAR string = MszString; + + if ( MszStringLength < (2 * sizeof(WCHAR)) ) { + return(NULL); + } + + // + // Find the start of the desired string. + // + while (StringIndex) { + + while (MszStringLength >= sizeof(WCHAR)) { + MszStringLength -= sizeof(WCHAR); + + if (*string++ == UNICODE_NULL) { + break; + } + } + + // + // Check for index out of range. + // + if ( MszStringLength < (2 * sizeof(UNICODE_NULL)) ) { + return(NULL); + } + + StringIndex--; + } + + if ( MszStringLength < (2 * sizeof(UNICODE_NULL)) ) { + return(NULL); + } + + return(string); +} + + |