|
|
/*****************************************************************************
* registry.cpp - registry key object implementation ***************************************************************************** * Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved. */
#include "private.h"
/*****************************************************************************
* Factory. */
#pragma code_seg("PAGE")
/*****************************************************************************
* CreateRegistryKey() ***************************************************************************** * Creates a registry key object. */ NTSTATUS CreateRegistryKey ( OUT PUNKNOWN * Unknown, IN REFCLSID, IN PUNKNOWN UnknownOuter OPTIONAL, IN POOL_TYPE PoolType ) { PAGED_CODE();
ASSERT(Unknown);
_DbgPrintF(DEBUGLVL_LIFETIME,("Creating REGISTRYKEY"));
STD_CREATE_BODY ( CRegistryKey, Unknown, UnknownOuter, PoolType ); }
/*****************************************************************************
* PcNewRegistryKey() ***************************************************************************** * Creates and initializes a registry key object. */ PORTCLASSAPI NTSTATUS NTAPI PcNewRegistryKey ( OUT PREGISTRYKEY * OutRegistryKey, IN PUNKNOWN OuterUnknown OPTIONAL, IN ULONG RegistryKeyType, IN ACCESS_MASK DesiredAccess, IN PVOID DeviceObject OPTIONAL, IN PVOID SubDevice OPTIONAL, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN ULONG CreateOptions OPTIONAL, OUT PULONG Disposition OPTIONAL ) { PAGED_CODE();
ASSERT(OutRegistryKey);
//
// Validate Parameters.
//
if (NULL == OutRegistryKey) { _DbgPrintF(DEBUGLVL_TERSE, ("PcNewRegistryKey : Invalid Parameter.")); return STATUS_INVALID_PARAMETER; }
PUNKNOWN unknown; NTSTATUS ntStatus = CreateRegistryKey ( &unknown, GUID_NULL, OuterUnknown, PagedPool );
if (NT_SUCCESS(ntStatus)) { PREGISTRYKEYINIT RegistryKey; ntStatus = unknown->QueryInterface ( IID_IRegistryKey, (PVOID *) &RegistryKey );
if (NT_SUCCESS(ntStatus)) { ntStatus = RegistryKey->Init( RegistryKeyType, DesiredAccess, PDEVICE_OBJECT(DeviceObject), PSUBDEVICE(SubDevice), ObjectAttributes, CreateOptions, Disposition ); if (NT_SUCCESS(ntStatus)) { *OutRegistryKey = RegistryKey; } else { RegistryKey->Release(); } }
unknown->Release(); }
return ntStatus; }
/*****************************************************************************
* Member functions. */
/*****************************************************************************
* CRegistryKey::~CRegistryKey() ***************************************************************************** * Destructor. */ CRegistryKey:: ~CRegistryKey ( void ) { PAGED_CODE();
_DbgPrintF(DEBUGLVL_LIFETIME,("Destroying REGISTRYKEY (0x%08x)",this));
if ( FALSE == m_KeyDeleted ) { ASSERT(m_KeyHandle); ZwClose(m_KeyHandle); } else { ASSERT(!m_KeyHandle); } }
/*****************************************************************************
* CRegistryKey::NonDelegatingQueryInterface() ***************************************************************************** * Obtains an interface. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: NonDelegatingQueryInterface ( REFIID Interface, PVOID * Object ) { PAGED_CODE();
ASSERT(Object);
if (IsEqualGUIDAligned(Interface,IID_IUnknown)) { *Object = PVOID(PUNKNOWN(this)); } else if (IsEqualGUIDAligned(Interface,IID_IRegistryKey)) { *Object = PVOID(PREGISTRYKEYINIT(this)); } else { *Object = NULL; }
if (*Object) { PUNKNOWN(*Object)->AddRef(); return STATUS_SUCCESS; }
return STATUS_INVALID_PARAMETER; }
/*****************************************************************************
* CRegistryKey::Init() ***************************************************************************** * Initializes a registry key object. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: Init ( IN ULONG RegistryKeyType, IN ACCESS_MASK DesiredAccess, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PSUBDEVICE SubDevice OPTIONAL, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN ULONG CreateOptions OPTIONAL, OUT PULONG Disposition OPTIONAL ) { PAGED_CODE();
_DbgPrintF(DEBUGLVL_LIFETIME,("Initializing REGISTRYKEY (0x%08x)",this));
NTSTATUS ntStatus;
m_KeyDeleted = TRUE; m_GeneralKey = FALSE; m_KeyHandle = NULL;
switch(RegistryKeyType) { case GeneralRegistryKey: ASSERT(ObjectAttributes);
ntStatus = ZwCreateKey( &m_KeyHandle, DesiredAccess, ObjectAttributes, 0, NULL, CreateOptions, Disposition ); if (NT_SUCCESS(ntStatus)) { ASSERT(m_KeyHandle); m_GeneralKey = TRUE; m_KeyDeleted = FALSE; } else { ASSERT(!m_KeyHandle); } break;
case DeviceRegistryKey: case DriverRegistryKey: case HwProfileRegistryKey: { ASSERT(DeviceObject); ULONG DevInstKeyType; if (RegistryKeyType == DeviceRegistryKey) { DevInstKeyType = PLUGPLAY_REGKEY_DEVICE; } else if(RegistryKeyType == DriverRegistryKey) { DevInstKeyType = PLUGPLAY_REGKEY_DRIVER; } else { DevInstKeyType = PLUGPLAY_REGKEY_CURRENT_HWPROFILE; } PDEVICE_CONTEXT deviceContext = PDEVICE_CONTEXT(DeviceObject->DeviceExtension); PDEVICE_OBJECT PhysicalDeviceObject = deviceContext->PhysicalDeviceObject; ntStatus = IoOpenDeviceRegistryKey( PhysicalDeviceObject, DevInstKeyType, DesiredAccess, &m_KeyHandle ); if (NT_SUCCESS(ntStatus)) { ASSERT(m_KeyHandle); m_GeneralKey = FALSE; m_KeyDeleted = FALSE; } else { ASSERT(!m_KeyHandle); } } break;
case DeviceInterfaceRegistryKey: { ASSERT(DeviceObject); ASSERT(SubDevice);
ULONG Index = SubdeviceIndex( DeviceObject, SubDevice );
if(Index != ULONG(-1)) { PDEVICE_CONTEXT deviceContext = PDEVICE_CONTEXT(DeviceObject->DeviceExtension);
PUNICODE_STRING SymbolicLinkName = &deviceContext->SymbolicLinkNames[Index]; ntStatus = IoOpenDeviceInterfaceRegistryKey( SymbolicLinkName, DesiredAccess, &m_KeyHandle );
if (NT_SUCCESS(ntStatus)) { ASSERT(m_KeyHandle); m_GeneralKey = FALSE; m_KeyDeleted = FALSE; } else { ASSERT(!m_KeyHandle); } } else { ntStatus = STATUS_INVALID_PARAMETER; } }
default: ntStatus = STATUS_INVALID_PARAMETER; break; }
return ntStatus; }
/*****************************************************************************
* CRegistryKey::QueryKey() ***************************************************************************** * Queries a registry key. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: QueryKey ( IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength ) { PAGED_CODE();
NTSTATUS ntStatus;
if ( m_KeyDeleted ) { ntStatus = STATUS_INVALID_HANDLE; ASSERT(!m_KeyHandle); } else { ASSERT(m_KeyHandle); ntStatus = ZwQueryKey( m_KeyHandle, KeyInformationClass, KeyInformation, Length, ResultLength ); }
return ntStatus; }
/*****************************************************************************
* CRegistryKey::EnumerateKey() ***************************************************************************** * Enumerates a registry key. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: EnumerateKey ( IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength ) { PAGED_CODE();
NTSTATUS ntStatus;
if ( m_KeyDeleted ) { ntStatus = STATUS_INVALID_HANDLE; ASSERT(!m_KeyHandle); } else { ASSERT(m_KeyHandle); ntStatus = ZwEnumerateKey( m_KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength ); }
return ntStatus; }
/*****************************************************************************
* CRegistryKey::QueryValueKey() ***************************************************************************** * Queries a registry value key. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: QueryValueKey ( IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength ) { PAGED_CODE();
NTSTATUS ntStatus;
if ( m_KeyDeleted ) { ntStatus = STATUS_INVALID_HANDLE; ASSERT(!m_KeyHandle); } else { ASSERT(m_KeyHandle); ntStatus = ZwQueryValueKey( m_KeyHandle, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength ); }
return ntStatus; }
/*****************************************************************************
* CRegistryKey::EnumerateValueKey() ***************************************************************************** * Enumerates a registry value key. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: EnumerateValueKey ( IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength ) { PAGED_CODE();
NTSTATUS ntStatus;
if ( m_KeyDeleted ) { ntStatus = STATUS_INVALID_HANDLE; ASSERT(!m_KeyHandle); } else { ASSERT(m_KeyHandle); ntStatus = ZwEnumerateValueKey( m_KeyHandle, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength ); }
return ntStatus; }
/*****************************************************************************
* CRegistryKey::SetValueKey() ***************************************************************************** * Sets a registry value key. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: SetValueKey ( IN PUNICODE_STRING ValueName OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize ) { PAGED_CODE();
NTSTATUS ntStatus;
if ( m_KeyDeleted ) { ntStatus = STATUS_INVALID_HANDLE; ASSERT(!m_KeyHandle); } else { ASSERT(m_KeyHandle); ntStatus = ZwSetValueKey( m_KeyHandle, ValueName, 0, Type, Data, DataSize ); }
return ntStatus; }
/*****************************************************************************
* CRegistryKey::QueryRegistryValues() ***************************************************************************** * Queries several registry values with a single call. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: QueryRegistryValues ( IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PVOID Context OPTIONAL ) { PAGED_CODE();
ASSERT(QueryTable);
NTSTATUS ntStatus;
if ( m_KeyDeleted ) { ntStatus = STATUS_INVALID_HANDLE; ASSERT(!m_KeyHandle); } else { ASSERT(m_KeyHandle); ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_HANDLE, PWSTR(m_KeyHandle), QueryTable, Context, NULL ); }
return ntStatus; }
/*****************************************************************************
* CRegistryKey::NewSubKey() ***************************************************************************** * Opens/creates a subkey for an open registry key. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: NewSubKey ( OUT PREGISTRYKEY * RegistrySubKey, IN PUNKNOWN OuterUnknown, IN ACCESS_MASK DesiredAccess, IN PUNICODE_STRING SubKeyName, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL ) { PAGED_CODE();
ASSERT(RegistrySubKey); ASSERT(SubKeyName);
OBJECT_ATTRIBUTES ObjectAttributes;
ASSERT(m_KeyHandle); InitializeObjectAttributes( &ObjectAttributes, SubKeyName, OBJ_INHERIT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, m_KeyHandle, NULL );
return PcNewRegistryKey( RegistrySubKey, OuterUnknown, GeneralRegistryKey, DesiredAccess, NULL, NULL, &ObjectAttributes, CreateOptions, Disposition ); }
/*****************************************************************************
* CRegistryKey::DeleteKey() ***************************************************************************** * Deletes a registry key. */ STDMETHODIMP_(NTSTATUS) CRegistryKey:: DeleteKey ( ) { PAGED_CODE();
NTSTATUS ntStatus;
if ( m_KeyDeleted ) { ntStatus = STATUS_INVALID_HANDLE; ASSERT(!m_KeyHandle); } else if ( FALSE == m_GeneralKey ) { ntStatus = STATUS_ACCESS_DENIED; } else { ASSERT(m_KeyHandle); ntStatus = ZwDeleteKey( m_KeyHandle ); if(NT_SUCCESS( ntStatus )) { m_KeyDeleted = TRUE; m_KeyHandle = NULL; } else { _DbgPrintF(DEBUGLVL_TERSE,("ZwDeleteKey failed for %x!!!",m_KeyHandle)); } } return ntStatus; }
/*****************************************************************************
* PcGetDeviceProperty() ***************************************************************************** * This wraps a call to IoGetDeviceProperty. */ PORTCLASSAPI NTSTATUS NTAPI PcGetDeviceProperty ( IN PVOID DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength ) { PDEVICE_CONTEXT deviceContext = PDEVICE_CONTEXT(PDEVICE_OBJECT(DeviceObject)->DeviceExtension); PDEVICE_OBJECT PhysicalDeviceObject = deviceContext->PhysicalDeviceObject;
return IoGetDeviceProperty( PhysicalDeviceObject, DeviceProperty, BufferLength, PropertyBuffer, ResultLength ); }
#pragma code_seg()
|