2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/registry.cpp
5 * PURPOSE: Registry access object
6 * PROGRAMMER: Johannes Anderwald
11 class CRegistryKey
: public IRegistryKey
14 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
16 STDMETHODIMP_(ULONG
) AddRef()
18 InterlockedIncrement(&m_Ref
);
21 STDMETHODIMP_(ULONG
) Release()
23 InterlockedDecrement(&m_Ref
);
34 CRegistryKey(IUnknown
* OuterUnknown
, HANDLE hKey
) : m_hKey(hKey
){}
35 virtual ~CRegistryKey();
44 CRegistryKey::~CRegistryKey()
53 CRegistryKey::QueryInterface(
57 UNICODE_STRING GuidString
;
59 DPRINT("CRegistryKey::QueryInterface entered\n");
60 if (IsEqualGUIDAligned(refiid
, IID_IRegistryKey
) ||
61 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
63 *Output
= PVOID(PREGISTRYKEY(this));
64 PUNKNOWN(*Output
)->AddRef();
65 return STATUS_SUCCESS
;
68 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
70 DPRINT1("CRegistryKey::QueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
71 RtlFreeUnicodeString(&GuidString
);
74 return STATUS_UNSUCCESSFUL
;
79 CRegistryKey::DeleteKey()
82 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
86 return STATUS_INVALID_HANDLE
;
89 Status
= ZwDeleteKey(m_hKey
);
90 if (NT_SUCCESS(Status
))
99 CRegistryKey::EnumerateKey(
101 IN KEY_INFORMATION_CLASS KeyInformationClass
,
102 OUT PVOID KeyInformation
,
104 OUT PULONG ResultLength
)
106 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
110 return STATUS_INVALID_HANDLE
;
113 return ZwEnumerateKey(m_hKey
, Index
, KeyInformationClass
, KeyInformation
, Length
, ResultLength
);
118 CRegistryKey::EnumerateValueKey(
120 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
,
121 OUT PVOID KeyValueInformation
,
123 OUT PULONG ResultLength
)
125 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
129 return STATUS_INVALID_HANDLE
;
132 return ZwEnumerateValueKey(m_hKey
, Index
, KeyValueInformationClass
, KeyValueInformation
, Length
, ResultLength
);
137 CRegistryKey::NewSubKey(
138 OUT PREGISTRYKEY
*RegistrySubKey
,
139 IN PUNKNOWN OuterUnknown
,
140 IN ACCESS_MASK DesiredAccess
,
141 IN PUNICODE_STRING SubKeyName
,
142 IN ULONG CreateOptions
,
143 OUT PULONG Disposition OPTIONAL
)
145 OBJECT_ATTRIBUTES Attributes
;
148 CRegistryKey
* RegistryKey
;
150 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
152 DPRINT("CRegistryKey::NewSubKey entered %S\n", SubKeyName
->Buffer
);
156 return STATUS_INVALID_HANDLE
;
159 InitializeObjectAttributes(&Attributes
, SubKeyName
, 0, m_hKey
, NULL
);
160 Status
= ZwCreateKey(&hKey
, KEY_READ
| KEY_WRITE
, &Attributes
, 0, NULL
, 0, Disposition
);
161 if (!NT_SUCCESS(Status
))
163 DPRINT("CRegistryKey::NewSubKey failed with %x\n", Status
);
167 RegistryKey
= new(NonPagedPool
, TAG_PORTCLASS
)CRegistryKey(OuterUnknown
, hKey
);
169 return STATUS_INSUFFICIENT_RESOURCES
;
171 Status
= RegistryKey
->QueryInterface(IID_IRegistryKey
, (PVOID
*)RegistrySubKey
);
173 if (!NT_SUCCESS(Status
))
180 *RegistrySubKey
= (PREGISTRYKEY
)RegistryKey
;
182 DPRINT("CRegistryKey::NewSubKey RESULT %p\n", *RegistrySubKey
);
183 return STATUS_SUCCESS
;
188 CRegistryKey::QueryKey(
189 IN KEY_INFORMATION_CLASS KeyInformationClass
,
190 OUT PVOID KeyInformation
,
192 OUT PULONG ResultLength
)
194 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
198 return STATUS_INVALID_HANDLE
;
201 return ZwQueryKey(m_hKey
, KeyInformationClass
, KeyInformation
, Length
, ResultLength
);
206 CRegistryKey::QueryRegistryValues(
207 IN PRTL_QUERY_REGISTRY_TABLE QueryTable
,
208 IN PVOID Context OPTIONAL
)
210 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
214 return STATUS_INVALID_HANDLE
;
217 return RtlQueryRegistryValues(RTL_REGISTRY_HANDLE
, (PCWSTR
)m_hKey
, QueryTable
, Context
, NULL
);
222 CRegistryKey::QueryValueKey(
223 IN PUNICODE_STRING ValueName
,
224 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
,
225 OUT PVOID KeyValueInformation
,
227 OUT PULONG ResultLength
)
231 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
235 return STATUS_INVALID_HANDLE
;
238 Status
= ZwQueryValueKey(m_hKey
, ValueName
, KeyValueInformationClass
, KeyValueInformation
, Length
, ResultLength
);
239 DPRINT("CRegistryKey::QueryValueKey entered %p value %wZ Status %x\n", this, ValueName
, Status
);
245 CRegistryKey::SetValueKey(
246 IN PUNICODE_STRING ValueName OPTIONAL
,
252 DPRINT("CRegistryKey::SetValueKey entered %S\n", ValueName
->Buffer
);
253 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
257 return STATUS_INVALID_HANDLE
;
260 return ZwSetValueKey(m_hKey
, ValueName
, 0, Type
, Data
, DataSize
);
266 OUT PREGISTRYKEY
* OutRegistryKey
,
267 IN PUNKNOWN OuterUnknown OPTIONAL
,
268 IN ULONG RegistryKeyType
,
269 IN ACCESS_MASK DesiredAccess
,
270 IN PVOID DeviceObject OPTIONAL
,
271 IN PVOID SubDevice OPTIONAL
,
272 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
273 IN ULONG CreateOptions OPTIONAL
,
274 OUT PULONG Disposition OPTIONAL
)
277 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
278 CRegistryKey
* RegistryKey
;
279 PPCLASS_DEVICE_EXTENSION DeviceExt
;
280 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
;
282 PSYMBOLICLINK_ENTRY SymEntry
;
284 DPRINT("PcNewRegistryKey entered\n");
287 return STATUS_INVALID_PARAMETER
;
289 if (RegistryKeyType
!= GeneralRegistryKey
&&
290 RegistryKeyType
!= DeviceRegistryKey
&&
291 RegistryKeyType
!= DriverRegistryKey
&&
292 RegistryKeyType
!= HwProfileRegistryKey
&&
293 RegistryKeyType
!= DeviceInterfaceRegistryKey
)
295 return STATUS_INVALID_PARAMETER
;
298 // check for the key type
299 if (RegistryKeyType
== GeneralRegistryKey
)
301 // do we have the required object attributes
302 if (!ObjectAttributes
)
304 // object attributes is mandatory
305 return STATUS_INVALID_PARAMETER
;
307 // try to create the key
308 Status
= ZwCreateKey(&hHandle
, DesiredAccess
, ObjectAttributes
, 0, NULL
, CreateOptions
, Disposition
);
310 else if (RegistryKeyType
== DeviceRegistryKey
||
311 RegistryKeyType
== DriverRegistryKey
||
312 RegistryKeyType
== HwProfileRegistryKey
)
314 // check for HwProfileRegistryKey case
315 if (RegistryKeyType
== HwProfileRegistryKey
)
317 // IoOpenDeviceRegistryKey used different constant
318 RegistryKeyType
= PLUGPLAY_REGKEY_CURRENT_HWPROFILE
| PLUGPLAY_REGKEY_DEVICE
;
321 // obtain the new device extension
322 DeviceExt
= (PPCLASS_DEVICE_EXTENSION
) ((PDEVICE_OBJECT
)DeviceObject
)->DeviceExtension
;
324 Status
= IoOpenDeviceRegistryKey(DeviceExt
->PhysicalDeviceObject
, RegistryKeyType
, DesiredAccess
, &hHandle
);
326 else if (RegistryKeyType
== DeviceInterfaceRegistryKey
)
328 if (SubDevice
== NULL
)
331 return STATUS_INVALID_PARAMETER
;
334 // look up our undocumented interface
335 Status
= ((PUNKNOWN
)SubDevice
)->QueryInterface(IID_ISubdevice
, (LPVOID
*)&Device
);
337 if (!NT_SUCCESS(Status
))
339 DPRINT("No ISubdevice interface\n");
341 return STATUS_INVALID_PARAMETER
;
344 // get the subdevice descriptor
345 Status
= Device
->GetDescriptor(&SubDeviceDescriptor
);
346 if (!NT_SUCCESS(Status
))
348 DPRINT("Failed to get subdevice descriptor %x\n", Status
);
349 ((PUNKNOWN
)SubDevice
)->Release();
350 return STATUS_UNSUCCESSFUL
;
353 // is there an registered device interface
354 if (IsListEmpty(&SubDeviceDescriptor
->SymbolicLinkList
))
356 DPRINT("No device interface registered\n");
357 ((PUNKNOWN
)SubDevice
)->Release();
358 return STATUS_UNSUCCESSFUL
;
361 // get the first symbolic link
362 SymEntry
= (PSYMBOLICLINK_ENTRY
)CONTAINING_RECORD(SubDeviceDescriptor
->SymbolicLinkList
.Flink
, SYMBOLICLINK_ENTRY
, Entry
);
364 // open device interface
365 Status
= IoOpenDeviceInterfaceRegistryKey(&SymEntry
->SymbolicLink
, DesiredAccess
, &hHandle
);
367 // release subdevice interface
368 ((PUNKNOWN
)SubDevice
)->Release();
372 if (!NT_SUCCESS(Status
))
374 DPRINT1("PcNewRegistryKey failed with %lx\n", Status
);
378 // allocate new registry key object
379 RegistryKey
= new(NonPagedPool
, TAG_PORTCLASS
)CRegistryKey(OuterUnknown
, hHandle
);
384 return STATUS_INSUFFICIENT_RESOURCES
;
387 // query for interface
388 Status
= RegistryKey
->QueryInterface(IID_IRegistryKey
, (PVOID
*)OutRegistryKey
);
390 if (!NT_SUCCESS(Status
))
396 DPRINT("PcNewRegistryKey result %p\n", *OutRegistryKey
);
397 return STATUS_SUCCESS
;