Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

678 lines
19 KiB

/*****************************************************************************
* 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()