Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297/*++
Copyright (c) Microsoft Corporation
Module Name:
FxRegKey.cpp
Abstract:
Author:
Environment:
kernel mode only
Revision History:
--*/
#include "fxsupportpch.hpp"
extern "C" {// #include "FxRegKeyKM.tmh"}
#define AT_PASSIVE() ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL)
FxRegKey::FxRegKey( PFX_DRIVER_GLOBALS FxDriverGlobals ) : FxPagedObject(FX_TYPE_REG_KEY, sizeof(FxRegKey), FxDriverGlobals), m_Key(NULL), m_Globals(FxDriverGlobals){}
__drv_maxIRQL(PASSIVE_LEVEL)FxRegKey::~FxRegKey(){ if (m_Key != NULL) { ZwClose(m_Key); m_Key = NULL; }}
__drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSFxRegKey::_Close( __in HANDLE Key ){ return ZwClose(Key);}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSFxRegKey::_Create( __in_opt HANDLE ParentKey, __in PCUNICODE_STRING KeyName, __out HANDLE* NewKey, __in ACCESS_MASK DesiredAccess, __in ULONG CreateOptions, __out_opt PULONG CreateDisposition ){ OBJECT_ATTRIBUTES oa;
AT_PASSIVE();
// // Force OBJ_KERNEL_HANDLE because we are never passing the handle back // up to a process and we don't want to create a handle in an arbitrary // process from which that process can close the handle out from underneath // us. // InitializeObjectAttributes( &oa, (PUNICODE_STRING) KeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, ParentKey, NULL);
return ZwCreateKey(NewKey, DesiredAccess, &oa, 0, 0, CreateOptions, CreateDisposition);}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSFxRegKey::_OpenKey( __in_opt HANDLE ParentKey, __in PCUNICODE_STRING KeyName, __out HANDLE* Key, __in ACCESS_MASK DesiredAccess ){ OBJECT_ATTRIBUTES oa;
AT_PASSIVE();
// // Force OBJ_KERNEL_HANDLE because we are never passing the handle back // up to a process and we don't want to create a handle in an arbitrary // process from which that process can close the handle out from underneath // us. // InitializeObjectAttributes( &oa, (PUNICODE_STRING)KeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, ParentKey, NULL);
return ZwOpenKey(Key, DesiredAccess, &oa);}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSFxRegKey::_SetValue( _In_ HANDLE Key, __in PCUNICODE_STRING ValueName, __in ULONG ValueType, __in_bcount(ValueLength) PVOID Value, __in ULONG ValueLength ){ AT_PASSIVE();
return ZwSetValueKey(Key, (PUNICODE_STRING)ValueName, 0, ValueType, Value, ValueLength);}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSFxRegKey::_QueryValue( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in HANDLE Key, __in PCUNICODE_STRING ValueName, __in ULONG ValueLength, __out_bcount_opt(ValueLength) PVOID Value, __out_opt PULONG ValueLengthQueried, __out_opt PULONG ValueType ){ KEY_VALUE_PARTIAL_INFORMATION *pPartial, partial; NTSTATUS status; ULONG length;
if (Value == NULL) { // // Caller wants just the length // pPartial = &partial; length = _ComputePartialSize(0); RtlZeroMemory(&partial, length); } else { length = _ComputePartialSize(ValueLength); pPartial = (PKEY_VALUE_PARTIAL_INFORMATION) MxMemory::MxAllocatePoolWithTag(PagedPool, length, FxDriverGlobals->Tag);
if (pPartial == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } }
// // We always pass a buffer of at least sizeof(KEY_VALUE_PARTIAL_INFORMATION) // to ZwQueryValueKey. This means that ZwQueryValueKey will write at least // some information to the buffer it receives, even if the user-supplied data // buffer is NULL or too small. // // According to ZwQueryValueKey's contract, this means that it will never return // STATUS_BUFFER_TOO_SMALL (returned when no data is written). Therefore, if the // user passes a NULL or insufficient buffer and the value exists in the registry, // ZwQueryValueKey will return STATUS_BUFFER_OVERFLOW. // status = ZwQueryValueKey(Key, (PUNICODE_STRING)ValueName, KeyValuePartialInformation, pPartial, length, &length);
if (NT_SUCCESS(status) && Value != NULL && (ValueLength >= pPartial->DataLength)) { RtlCopyMemory(Value, &pPartial->Data[0], pPartial->DataLength); }
if (NT_SUCCESS(status) || status == STATUS_BUFFER_OVERFLOW) { if (ValueLengthQueried != NULL) { *ValueLengthQueried = pPartial->DataLength; } if (ValueType != NULL) { *ValueType = pPartial->Type; } }
if (pPartial != &partial) { MxMemory::MxFreePool(pPartial); }
return status;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSFxRegKey::_QueryULong( __in HANDLE Key, __in PCUNICODE_STRING ValueName, __out PULONG Value ){ NTSTATUS status; ULONG length;
PKEY_VALUE_PARTIAL_INFORMATION pPartial; UCHAR buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)+(sizeof(ULONG))];
length = sizeof(buffer); pPartial = (PKEY_VALUE_PARTIAL_INFORMATION) &buffer[0];
status = ZwQueryValueKey(Key, (PUNICODE_STRING)ValueName, KeyValuePartialInformation, pPartial, length, &length);
if ((NT_SUCCESS(status) || status == STATUS_BUFFER_OVERFLOW) && pPartial->Type != REG_DWORD) { status = STATUS_OBJECT_TYPE_MISMATCH; }
if (NT_SUCCESS(status)) { ASSERT(sizeof(ULONG) == pPartial->DataLength);
RtlCopyMemory(Value, &pPartial->Data[0], sizeof(ULONG)); }
return status;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSFxRegKey::_QueryQuadWord( __in HANDLE Key, __in PCUNICODE_STRING ValueName, __out PLARGE_INTEGER Value ){ NTSTATUS status; ULONG length;
PKEY_VALUE_PARTIAL_INFORMATION pPartial; UCHAR buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)+(sizeof(LARGE_INTEGER))];
length = sizeof(buffer); pPartial = (PKEY_VALUE_PARTIAL_INFORMATION) &buffer[0];
status = ZwQueryValueKey(Key, (PUNICODE_STRING)ValueName, KeyValuePartialInformation, pPartial, length, &length);
if ((NT_SUCCESS(status) || status == STATUS_BUFFER_OVERFLOW) && pPartial->Type != REG_QWORD) { status = STATUS_OBJECT_TYPE_MISMATCH; }
if (NT_SUCCESS(status)) { ASSERT(sizeof(LARGE_INTEGER) == pPartial->DataLength);
RtlCopyMemory(Value, &pPartial->Data[0], sizeof(LARGE_INTEGER)); }
return status;}