ReactOS  0.4.14-dev-593-g1793dcc
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 IRegistryKey
18 {
19 public:
21 
23  {
25  return m_Ref;
26  }
28  {
30 
31  if (!m_Ref)
32  {
33  delete this;
34  return 0;
35  }
36  return m_Ref;
37  }
38 
40  CRegistryKey(IUnknown * OuterUnknown, HANDLE hKey, BOOL CanDelete) : m_hKey(hKey), m_Deleted(FALSE), m_CanDelete(CanDelete), m_Ref(0){}
41  virtual ~CRegistryKey();
42 
43 protected:
44 
49 };
50 
52 {
53  if (!m_Deleted)
54  {
55  // close key only when has not been deleted yet
56  ZwClose(m_hKey);
57  }
58 }
59 
60 
62 NTAPI
64  IN REFIID refiid,
65  OUT PVOID* Output)
66 {
68 
69  DPRINT("CRegistryKey::QueryInterface entered\n");
70  if (IsEqualGUIDAligned(refiid, IID_IRegistryKey) ||
72  {
73  *Output = PVOID(PREGISTRYKEY(this));
74  PUNKNOWN(*Output)->AddRef();
75  return STATUS_SUCCESS;
76  }
77 
79  {
80  DPRINT1("CRegistryKey::QueryInterface no interface!!! iface %S\n", GuidString.Buffer);
82  }
83 
84  return STATUS_UNSUCCESSFUL;
85 }
86 
88 NTAPI
90 {
93 
94  if (m_Deleted)
95  {
96  // key already deleted
97  return STATUS_INVALID_HANDLE;
98  }
99 
100  if (!m_CanDelete)
101  {
102  // only general keys can be deleted
103  return STATUS_ACCESS_DENIED;
104  }
105 
106  // delete key
107  Status = ZwDeleteKey(m_hKey);
108  if (NT_SUCCESS(Status))
109  {
110  m_Deleted = TRUE;
111  m_hKey = NULL;
112  }
113  return Status;
114 }
115 
116 NTSTATUS
117 NTAPI
118 CRegistryKey::EnumerateKey(
119  IN ULONG Index,
121  OUT PVOID KeyInformation,
122  IN ULONG Length,
124 {
126 
127  if (m_Deleted)
128  {
129  return STATUS_INVALID_HANDLE;
130  }
131 
132  return ZwEnumerateKey(m_hKey, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
133 }
134 
135 NTSTATUS
136 NTAPI
137 CRegistryKey::EnumerateValueKey(
138  IN ULONG Index,
140  OUT PVOID KeyValueInformation,
141  IN ULONG Length,
143 {
145 
146  if (m_Deleted)
147  {
148  return STATUS_INVALID_HANDLE;
149  }
150 
151  return ZwEnumerateValueKey(m_hKey, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
152 }
153 
154 NTSTATUS
155 NTAPI
156 CRegistryKey::NewSubKey(
157  OUT PREGISTRYKEY *RegistrySubKey,
158  IN PUNKNOWN OuterUnknown,
163 {
166  HANDLE hKey;
167  CRegistryKey * RegistryKey;
168 
170 
171  DPRINT("CRegistryKey::NewSubKey entered %S\n", SubKeyName->Buffer);
172 
173  if (m_Deleted)
174  {
175  return STATUS_INVALID_HANDLE;
176  }
177 
179  Status = ZwCreateKey(&hKey, DesiredAccess, &Attributes, 0, NULL, CreateOptions, Disposition);
180  if (!NT_SUCCESS(Status))
181  {
182  DPRINT("CRegistryKey::NewSubKey failed with %x\n", Status);
183  return Status;
184  }
185 
186  RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hKey, TRUE);
187  if (!RegistryKey)
189 
190  Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)RegistrySubKey);
191 
192  if (!NT_SUCCESS(Status))
193  {
194  delete RegistryKey;
195  return Status;
196  }
197 
198  DPRINT("CRegistryKey::NewSubKey RESULT %p\n", *RegistrySubKey);
199  return STATUS_SUCCESS;
200 }
201 
202 NTSTATUS
203 NTAPI
204 CRegistryKey::QueryKey(
206  OUT PVOID KeyInformation,
207  IN ULONG Length,
209 {
211 
212  if (m_Deleted)
213  {
214  return STATUS_INVALID_HANDLE;
215  }
216 
217  return ZwQueryKey(m_hKey, KeyInformationClass, KeyInformation, Length, ResultLength);
218 }
219 
220 NTSTATUS
221 NTAPI
222 CRegistryKey::QueryRegistryValues(
225 {
227 
228  if (m_Deleted)
229  {
230  return STATUS_INVALID_HANDLE;
231  }
232 
234 }
235 
236 NTSTATUS
237 NTAPI
238 CRegistryKey::QueryValueKey(
241  OUT PVOID KeyValueInformation,
242  IN ULONG Length,
244 {
246 
248 
249  if (m_Deleted)
250  {
251  return STATUS_INVALID_HANDLE;
252  }
253 
254  Status = ZwQueryValueKey(m_hKey, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
255  DPRINT("CRegistryKey::QueryValueKey entered %p value %wZ Status %x\n", this, ValueName, Status);
256  return Status;
257 }
258 
259 NTSTATUS
260 NTAPI
261 CRegistryKey::SetValueKey(
263  IN ULONG Type,
264  IN PVOID Data,
266  )
267 {
268  DPRINT("CRegistryKey::SetValueKey entered %S\n", ValueName->Buffer);
270 
271  if (m_Deleted)
272  {
273  return STATUS_INVALID_HANDLE;
274  }
275 
276  return ZwSetValueKey(m_hKey, ValueName, 0, Type, Data, DataSize);
277 }
278 
279 NTSTATUS
280 NTAPI
282  OUT PREGISTRYKEY* OutRegistryKey,
283  IN PUNKNOWN OuterUnknown OPTIONAL,
284  IN ULONG RegistryKeyType,
287  IN PVOID SubDevice OPTIONAL,
291 {
292  HANDLE hHandle;
294  CRegistryKey * RegistryKey;
295  PPCLASS_DEVICE_EXTENSION DeviceExt;
296  PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
297  ISubdevice * Device;
298  PSYMBOLICLINK_ENTRY SymEntry;
299  BOOL CanDelete = FALSE;
300 
301  DPRINT("PcNewRegistryKey entered\n");
302 
303  if (!OutRegistryKey)
305 
306  if (RegistryKeyType != GeneralRegistryKey &&
307  RegistryKeyType != DeviceRegistryKey &&
308  RegistryKeyType != DriverRegistryKey &&
309  RegistryKeyType != HwProfileRegistryKey &&
310  RegistryKeyType != DeviceInterfaceRegistryKey)
311  {
313  }
314 
315  // check for the key type
316  if (RegistryKeyType == GeneralRegistryKey)
317  {
318  // do we have the required object attributes
319  if (!ObjectAttributes)
320  {
321  // object attributes is mandatory
323  }
324  // try to create the key
325  Status = ZwCreateKey(&hHandle, DesiredAccess, ObjectAttributes, 0, NULL, CreateOptions, Disposition);
326 
327  // key can be deleted
328  CanDelete = TRUE;
329  }
330  else if (RegistryKeyType == DeviceRegistryKey ||
331  RegistryKeyType == DriverRegistryKey ||
332  RegistryKeyType == HwProfileRegistryKey)
333  {
334  // check for HwProfileRegistryKey case
335  if (RegistryKeyType == HwProfileRegistryKey)
336  {
337  // IoOpenDeviceRegistryKey used different constant
339  }
340 
341  // obtain the new device extension
342  DeviceExt = (PPCLASS_DEVICE_EXTENSION) ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
343 
344  Status = IoOpenDeviceRegistryKey(DeviceExt->PhysicalDeviceObject, RegistryKeyType, DesiredAccess, &hHandle);
345  }
346  else if (RegistryKeyType == DeviceInterfaceRegistryKey)
347  {
348  if (SubDevice == NULL)
349  {
350  // invalid parameter
352  }
353 
354  // look up our undocumented interface
355  Status = ((PUNKNOWN)SubDevice)->QueryInterface(IID_ISubdevice, (LPVOID*)&Device);
356 
357  if (!NT_SUCCESS(Status))
358  {
359  DPRINT("No ISubdevice interface\n");
360  // invalid parameter
362  }
363 
364  // get the subdevice descriptor
365  Status = Device->GetDescriptor(&SubDeviceDescriptor);
366  if (!NT_SUCCESS(Status))
367  {
368  DPRINT("Failed to get subdevice descriptor %x\n", Status);
369  ((PUNKNOWN)SubDevice)->Release();
370  return STATUS_UNSUCCESSFUL;
371  }
372 
373  // is there an registered device interface
374  if (IsListEmpty(&SubDeviceDescriptor->SymbolicLinkList))
375  {
376  DPRINT("No device interface registered\n");
377  ((PUNKNOWN)SubDevice)->Release();
378  return STATUS_UNSUCCESSFUL;
379  }
380 
381  // get the first symbolic link
383 
384  // open device interface
386 
387  // release subdevice interface
388  ((PUNKNOWN)SubDevice)->Release();
389  }
390 
391  // check for success
392  if (!NT_SUCCESS(Status))
393  {
394  DPRINT1("PcNewRegistryKey failed with %lx\n", Status);
395  return Status;
396  }
397 
398  // allocate new registry key object
399  RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hHandle, CanDelete);
400  if (!RegistryKey)
401  {
402  // not enough memory
403  ZwClose(hHandle);
405  }
406 
407  // query for interface
408  Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)OutRegistryKey);
409 
410  if (!NT_SUCCESS(Status))
411  {
412  // out of memory
413  delete RegistryKey;
414  }
415 
416  DPRINT("PcNewRegistryKey result %p\n", *OutRegistryKey);
417  return STATUS_SUCCESS;
418 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static PWSTR GuidString
Definition: apphelp.c:91
const uint16_t * PCWSTR
Definition: typedefs.h:55
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
#define IN
Definition: typedefs.h:38
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DeviceInterfaceKey)
Definition: deviface.c:241
BOOL m_Deleted
Definition: registry.cpp:46
Type
Definition: Type.h:6
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
_In_ BOOLEAN Release
Definition: classpnp.h:929
_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:2738
#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
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 STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
#define OBJ_OPENIF
Definition: winternl.h:229
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define STDMETHODIMP
Definition: basetyps.h:43
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
HANDLE m_hKey
Definition: registry.cpp:45
IRegistryKey * PREGISTRYKEY
Definition: portcls.h:999
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PDEVICE_OBJECT PhysicalDeviceObject
Definition: private.hpp:402
const GUID IID_IUnknown
#define OBJ_INHERIT
Definition: winternl.h:225
BOOL m_CanDelete
Definition: registry.cpp:47
static const UCHAR Index[8]
Definition: usbohci.c:18
CRegistryKey(IUnknown *OuterUnknown, HANDLE hKey, BOOL CanDelete)
Definition: registry.cpp:40
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
ULONG AddRef()
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
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:281
#define InterlockedDecrement
Definition: armddk.h:52
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: registry.cpp:63
Definition: arc.h:85
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
virtual ~CRegistryKey()
Definition: registry.cpp:51
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
STDMETHODIMP_(ULONG) Release()
Definition: registry.cpp:27
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define InterlockedIncrement
Definition: armddk.h:53
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
BOOL DeleteKey(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath)
Definition: edit.c:1456
unsigned int * PULONG
Definition: retypes.h:1
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:4586
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING SymbolicLink
Definition: interfaces.hpp:176
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
STDMETHODIMP_(ULONG) AddRef()
Definition: registry.cpp:22
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:93
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_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:2740
enum _KEY_VALUE_INFORMATION_CLASS KEY_VALUE_INFORMATION_CLASS
Definition: reg.c:135
LIST_ENTRY SymbolicLinkList
Definition: interfaces.hpp:219
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68