ReactOS  0.4.15-dev-4863-gba0d16f
registry.cpp
Go to the documentation of this file.
1 /*
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
7  */
8 
9 #include "private.hpp"
10 
11 #ifndef YDEBUG
12 #define NDEBUG
13 #endif
14 
15 #include <debug.h>
16 
17 class CRegistryKey : public CUnknownImpl<IRegistryKey>
18 {
19 public:
21 
23  CRegistryKey(IUnknown * OuterUnknown, HANDLE hKey, BOOL CanDelete) :
24  m_hKey(hKey),
26  m_CanDelete(CanDelete)
27  {
28  }
29  virtual ~CRegistryKey();
30 
31 protected:
32 
36 };
37 
39 {
40  if (!m_Deleted)
41  {
42  // close key only when has not been deleted yet
43  ZwClose(m_hKey);
44  }
45 }
46 
47 
49 NTAPI
51  IN REFIID refiid,
52  OUT PVOID* Output)
53 {
55 
56  DPRINT("CRegistryKey::QueryInterface entered\n");
57  if (IsEqualGUIDAligned(refiid, IID_IRegistryKey) ||
59  {
60  *Output = PVOID(PREGISTRYKEY(this));
61  PUNKNOWN(*Output)->AddRef();
62  return STATUS_SUCCESS;
63  }
64 
66  {
67  DPRINT1("CRegistryKey::QueryInterface no interface!!! iface %S\n", GuidString.Buffer);
69  }
70 
71  return STATUS_UNSUCCESSFUL;
72 }
73 
75 NTAPI
77 {
80 
81  if (m_Deleted)
82  {
83  // key already deleted
84  return STATUS_INVALID_HANDLE;
85  }
86 
87  if (!m_CanDelete)
88  {
89  // only general keys can be deleted
90  return STATUS_ACCESS_DENIED;
91  }
92 
93  // delete key
94  Status = ZwDeleteKey(m_hKey);
95  if (NT_SUCCESS(Status))
96  {
97  m_Deleted = TRUE;
98  m_hKey = NULL;
99  }
100  return Status;
101 }
102 
103 NTSTATUS
104 NTAPI
105 CRegistryKey::EnumerateKey(
106  IN ULONG Index,
108  OUT PVOID KeyInformation,
109  IN ULONG Length,
111 {
113 
114  if (m_Deleted)
115  {
116  return STATUS_INVALID_HANDLE;
117  }
118 
119  return ZwEnumerateKey(m_hKey, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
120 }
121 
122 NTSTATUS
123 NTAPI
124 CRegistryKey::EnumerateValueKey(
125  IN ULONG Index,
127  OUT PVOID KeyValueInformation,
128  IN ULONG Length,
130 {
132 
133  if (m_Deleted)
134  {
135  return STATUS_INVALID_HANDLE;
136  }
137 
138  return ZwEnumerateValueKey(m_hKey, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
139 }
140 
141 NTSTATUS
142 NTAPI
143 CRegistryKey::NewSubKey(
144  OUT PREGISTRYKEY *RegistrySubKey,
145  IN PUNKNOWN OuterUnknown,
150 {
153  HANDLE hKey;
154  CRegistryKey * RegistryKey;
155 
157 
158  DPRINT("CRegistryKey::NewSubKey entered %S\n", SubKeyName->Buffer);
159 
160  if (m_Deleted)
161  {
162  return STATUS_INVALID_HANDLE;
163  }
164 
167  if (!NT_SUCCESS(Status))
168  {
169  DPRINT("CRegistryKey::NewSubKey failed with %x\n", Status);
170  return Status;
171  }
172 
173  RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hKey, TRUE);
174  if (!RegistryKey)
176 
177  Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)RegistrySubKey);
178 
179  if (!NT_SUCCESS(Status))
180  {
181  delete RegistryKey;
182  return Status;
183  }
184 
185  DPRINT("CRegistryKey::NewSubKey RESULT %p\n", *RegistrySubKey);
186  return STATUS_SUCCESS;
187 }
188 
189 NTSTATUS
190 NTAPI
191 CRegistryKey::QueryKey(
193  OUT PVOID KeyInformation,
194  IN ULONG Length,
196 {
198 
199  if (m_Deleted)
200  {
201  return STATUS_INVALID_HANDLE;
202  }
203 
204  return ZwQueryKey(m_hKey, KeyInformationClass, KeyInformation, Length, ResultLength);
205 }
206 
207 NTSTATUS
208 NTAPI
209 CRegistryKey::QueryRegistryValues(
212 {
214 
215  if (m_Deleted)
216  {
217  return STATUS_INVALID_HANDLE;
218  }
219 
221 }
222 
223 NTSTATUS
224 NTAPI
225 CRegistryKey::QueryValueKey(
228  OUT PVOID KeyValueInformation,
229  IN ULONG Length,
231 {
233 
235 
236  if (m_Deleted)
237  {
238  return STATUS_INVALID_HANDLE;
239  }
240 
241  Status = ZwQueryValueKey(m_hKey, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
242  DPRINT("CRegistryKey::QueryValueKey entered %p value %wZ Status %x\n", this, ValueName, Status);
243  return Status;
244 }
245 
246 NTSTATUS
247 NTAPI
248 CRegistryKey::SetValueKey(
250  IN ULONG Type,
251  IN PVOID Data,
253  )
254 {
255  DPRINT("CRegistryKey::SetValueKey entered %S\n", ValueName->Buffer);
257 
258  if (m_Deleted)
259  {
260  return STATUS_INVALID_HANDLE;
261  }
262 
263  return ZwSetValueKey(m_hKey, ValueName, 0, Type, Data, DataSize);
264 }
265 
266 NTSTATUS
267 NTAPI
269  OUT PREGISTRYKEY* OutRegistryKey,
270  IN PUNKNOWN OuterUnknown OPTIONAL,
271  IN ULONG RegistryKeyType,
274  IN PVOID SubDevice OPTIONAL,
278 {
279  HANDLE hHandle;
281  CRegistryKey * RegistryKey;
282  PPCLASS_DEVICE_EXTENSION DeviceExt;
283  PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
284  ISubdevice * Device;
285  PSYMBOLICLINK_ENTRY SymEntry;
286  BOOL CanDelete = FALSE;
287 
288  DPRINT("PcNewRegistryKey entered\n");
289 
290  if (!OutRegistryKey)
292 
293  if (RegistryKeyType != GeneralRegistryKey &&
294  RegistryKeyType != DeviceRegistryKey &&
295  RegistryKeyType != DriverRegistryKey &&
296  RegistryKeyType != HwProfileRegistryKey &&
297  RegistryKeyType != DeviceInterfaceRegistryKey)
298  {
300  }
301 
302  // check for the key type
303  if (RegistryKeyType == GeneralRegistryKey)
304  {
305  // do we have the required object attributes
306  if (!ObjectAttributes)
307  {
308  // object attributes is mandatory
310  }
311  // try to create the key
312  Status = ZwCreateKey(&hHandle, DesiredAccess, ObjectAttributes, 0, NULL, CreateOptions, Disposition);
313 
314  // key can be deleted
315  CanDelete = TRUE;
316  }
317  else if (RegistryKeyType == DeviceRegistryKey ||
318  RegistryKeyType == DriverRegistryKey ||
319  RegistryKeyType == HwProfileRegistryKey)
320  {
321  // check for HwProfileRegistryKey case
322  if (RegistryKeyType == HwProfileRegistryKey)
323  {
324  // IoOpenDeviceRegistryKey used different constant
326  }
327 
328  // obtain the new device extension
329  DeviceExt = (PPCLASS_DEVICE_EXTENSION) ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
330 
331  Status = IoOpenDeviceRegistryKey(DeviceExt->PhysicalDeviceObject, RegistryKeyType, DesiredAccess, &hHandle);
332  }
333  else if (RegistryKeyType == DeviceInterfaceRegistryKey)
334  {
335  if (SubDevice == NULL)
336  {
337  // invalid parameter
339  }
340 
341  // look up our undocumented interface
342  Status = ((PUNKNOWN)SubDevice)->QueryInterface(IID_ISubdevice, (LPVOID*)&Device);
343 
344  if (!NT_SUCCESS(Status))
345  {
346  DPRINT("No ISubdevice interface\n");
347  // invalid parameter
349  }
350 
351  // get the subdevice descriptor
352  Status = Device->GetDescriptor(&SubDeviceDescriptor);
353  if (!NT_SUCCESS(Status))
354  {
355  DPRINT("Failed to get subdevice descriptor %x\n", Status);
356  ((PUNKNOWN)SubDevice)->Release();
357  return STATUS_UNSUCCESSFUL;
358  }
359 
360  // is there an registered device interface
361  if (IsListEmpty(&SubDeviceDescriptor->SymbolicLinkList))
362  {
363  DPRINT("No device interface registered\n");
364  ((PUNKNOWN)SubDevice)->Release();
365  return STATUS_UNSUCCESSFUL;
366  }
367 
368  // get the first symbolic link
370 
371  // open device interface
373 
374  // release subdevice interface
375  ((PUNKNOWN)SubDevice)->Release();
376  }
377 
378  // check for success
379  if (!NT_SUCCESS(Status))
380  {
381  DPRINT1("PcNewRegistryKey failed with %lx\n", Status);
382  return Status;
383  }
384 
385  // allocate new registry key object
386  RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hHandle, CanDelete);
387  if (!RegistryKey)
388  {
389  // not enough memory
390  ZwClose(hHandle);
392  }
393 
394  // query for interface
395  Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)OutRegistryKey);
396 
397  if (!NT_SUCCESS(Status))
398  {
399  // out of memory
400  delete RegistryKey;
401  }
402 
403  DPRINT("PcNewRegistryKey result %p\n", *OutRegistryKey);
404  return STATUS_SUCCESS;
405 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static PWSTR GuidString
Definition: apphelp.c:93
const uint16_t * PCWSTR
Definition: typedefs.h:57
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define REFIID
Definition: guiddef.h:118
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DeviceInterfaceKey)
Definition: deviface.c:241
BOOL m_Deleted
Definition: registry.cpp:34
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_In_ ULONG _In_ KEY_INFORMATION_CLASS KeyInformationClass
Definition: zwfuncs.h:166
enum _KEY_INFORMATION_CLASS KEY_INFORMATION_CLASS
struct PCLASS_DEVICE_EXTENSION * PPCLASS_DEVICE_EXTENSION
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2786
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define TAG_PORTCLASS
Definition: private.hpp:24
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
struct SYMBOLICLINK_ENTRY * PSYMBOLICLINK_ENTRY
Definition: interfaces.hpp:173
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define OBJ_OPENIF
Definition: winternl.h:229
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define STDMETHODIMP
Definition: basetyps.h:43
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
HANDLE m_hKey
Definition: registry.cpp:33
IRegistryKey * PREGISTRYKEY
Definition: portcls.h:1009
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_INHERIT
Definition: winternl.h:225
PDEVICE_OBJECT PhysicalDeviceObject
Definition: private.hpp:402
_In_ WDFCOLLECTION _In_ ULONG Index
const GUID IID_IUnknown
BOOL m_CanDelete
Definition: registry.cpp:35
CRegistryKey(IUnknown *OuterUnknown, HANDLE hKey, BOOL CanDelete)
Definition: registry.cpp:23
Type
Definition: Type.h:6
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
ULONG AddRef()
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
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)
Definition: registry.cpp:268
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: registry.cpp:50
Definition: arc.h:85
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
virtual ~CRegistryKey()
Definition: registry.cpp:38
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG CreateOptions
Definition: wdfregistry.h:112
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:361
FxAutoRegKey hKey
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
BOOL DeleteKey(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath)
Definition: edit.c:1456
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:2191
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING SymbolicLink
Definition: interfaces.hpp:176
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:93
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
ULONG ACCESS_MASK
Definition: nt_native.h:40
base of all file and directory entries
Definition: entries.h:82
#define PLUGPLAY_REGKEY_CURRENT_HWPROFILE
Definition: iofuncs.h:2788
enum _KEY_VALUE_INFORMATION_CLASS KEY_VALUE_INFORMATION_CLASS
Definition: reg.c:135
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
LIST_ENTRY SymbolicLinkList
Definition: interfaces.hpp:219
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68