Sync to trunk r38200
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / registry.c
1 #include "private.h"
2
3 typedef struct
4 {
5 IRegistryKeyVtbl * lpVtbl;
6
7 LONG ref;
8 HANDLE hKey;
9
10 }IRegistryKeyImpl;
11
12 const GUID IID_IRegistryKey;
13
14 /*
15 Basic IUnknown methods
16 */
17
18 static IRegistryKeyVtbl vt_IRegistryKeyVtbl;
19
20
21 ULONG
22 STDMETHODCALLTYPE
23 IRegistryKey_fnAddRef(
24 IN IRegistryKey* iface)
25 {
26 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
27
28 DPRINT("IRegistryKey_AddRef: This %p\n", This);
29
30 return _InterlockedIncrement(&This->ref);
31 }
32
33 ULONG
34 STDMETHODCALLTYPE
35 IRegistryKey_fnRelease(
36 IN IRegistryKey* iface)
37 {
38 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
39
40 _InterlockedDecrement(&This->ref);
41
42 if (This->ref == 0)
43 {
44 if (This->hKey)
45 {
46 ZwClose(This->hKey);
47 }
48 ExFreePoolWithTag(This, TAG_PORTCLASS);
49 return 0;
50 }
51 /* Return new reference count */
52 return This->ref;
53 }
54
55 NTSTATUS
56 STDMETHODCALLTYPE
57 IRegistryKey_fnQueryInterface(
58 IN IRegistryKey* iface,
59 IN REFIID refiid,
60 OUT PVOID* Output)
61 {
62 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
63
64 if (IsEqualGUIDAligned(refiid, &IID_IRegistryKey))
65 {
66 *Output = (PVOID)&This->lpVtbl;
67 _InterlockedIncrement(&This->ref);
68 return STATUS_SUCCESS;
69 }
70
71 DPRINT("IRegistryKey_QueryInterface: This %p unknown iid\n", This, This->ref);
72 return STATUS_UNSUCCESSFUL;
73 }
74
75 NTSTATUS
76 STDMETHODCALLTYPE
77 IRegistryKey_fnDeleteKey(
78 IN IRegistryKey* iface)
79 {
80 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
81 return ZwDeleteKey(This->hKey);
82 }
83
84 NTSTATUS
85 STDMETHODCALLTYPE
86 IRegistryKey_fnEnumerateKey(
87 IN IRegistryKey* iface,
88 IN ULONG Index,
89 IN KEY_INFORMATION_CLASS KeyInformationClass,
90 OUT PVOID KeyInformation,
91 IN ULONG Length,
92 OUT PULONG ResultLength)
93 {
94 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
95 return ZwEnumerateKey(This->hKey, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
96 }
97
98 NTSTATUS
99 STDMETHODCALLTYPE
100 IRegistryKey_fnEnumerateKeyValue(
101 IN IRegistryKey* iface,
102 IN ULONG Index,
103 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
104 OUT PVOID KeyValueInformation,
105 IN ULONG Length,
106 OUT PULONG ResultLength)
107 {
108 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
109 return ZwEnumerateValueKey(This->hKey, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
110 }
111
112 NTSTATUS
113 STDMETHODCALLTYPE
114 IRegistryKey_fnNewSubKey(
115 IN IRegistryKey* iface,
116 OUT PREGISTRYKEY *RegistrySubKey,
117 IN PUNKNOWN OuterUnknown,
118 IN ACCESS_MASK DesiredAccess,
119 IN PUNICODE_STRING SubKeyName,
120 IN ULONG CreateOptions,
121 OUT PULONG Disposition OPTIONAL)
122 {
123 OBJECT_ATTRIBUTES Attributes;
124 NTSTATUS Status;
125 HANDLE hKey;
126 IRegistryKeyImpl * NewThis, *This = (IRegistryKeyImpl*)iface;
127
128 InitializeObjectAttributes(&Attributes, SubKeyName, 0, This->hKey, NULL);
129 Status = ZwCreateKey(&hKey, KEY_READ | KEY_WRITE, &Attributes, 0, NULL, 0, Disposition);
130 if (!NT_SUCCESS(Status))
131 return Status;
132
133
134 NewThis = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRegistryKeyImpl), TAG_PORTCLASS);
135 if (!NewThis)
136 {
137 ZwClose(hKey);
138 return STATUS_INSUFFICIENT_RESOURCES;
139 }
140
141 NewThis->hKey = hKey;
142 NewThis->ref = 1;
143 NewThis->lpVtbl = &vt_IRegistryKeyVtbl;
144 *RegistrySubKey = (PREGISTRYKEY)&This->lpVtbl;
145 return STATUS_SUCCESS;
146 }
147
148 NTSTATUS
149 STDMETHODCALLTYPE
150 IRegistryKey_fnQueryKey(
151 IN IRegistryKey* iface,
152 IN KEY_INFORMATION_CLASS KeyInformationClass,
153 OUT PVOID KeyInformation,
154 IN ULONG Length,
155 OUT PULONG ResultLength)
156 {
157 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
158 return ZwQueryKey(This->hKey, KeyInformationClass, KeyInformation, Length, ResultLength);
159 }
160
161 NTSTATUS
162 STDMETHODCALLTYPE
163 IRegistryKey_fnQueryRegistryValues(
164 IN IRegistryKey* iface,
165 IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
166 IN PVOID Context OPTIONAL)
167 {
168 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
169 DPRINT("IRegistryKey_QueryRegistryValues: This %p\n", This);
170 return STATUS_UNSUCCESSFUL;
171 }
172
173 NTSTATUS
174 STDMETHODCALLTYPE
175 IRegistryKey_fnQueryValueKey(
176 IN IRegistryKey* iface,
177 IN PUNICODE_STRING ValueName,
178 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
179 OUT PVOID KeyValueInformation,
180 IN ULONG Length,
181 OUT PULONG ResultLength)
182 {
183 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
184 return ZwQueryValueKey(This->hKey, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
185 }
186
187 NTSTATUS
188 STDMETHODCALLTYPE
189 IRegistryKey_fnSetValueKey(
190 IN IRegistryKey* iface,
191 IN PUNICODE_STRING ValueName OPTIONAL,
192 IN ULONG Type,
193 IN PVOID Data,
194 IN ULONG DataSize
195 )
196 {
197 IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface;
198 return ZwSetValueKey(This->hKey, ValueName, 0, Type, Data, DataSize);
199 }
200
201 static IRegistryKeyVtbl vt_IRegistryKey =
202 {
203 /* IUnknown methods */
204 IRegistryKey_fnQueryInterface,
205 IRegistryKey_fnAddRef,
206 IRegistryKey_fnRelease,
207 /* IRegistryKey methods */
208 IRegistryKey_fnQueryKey,
209 IRegistryKey_fnEnumerateKey,
210 IRegistryKey_fnQueryValueKey,
211 IRegistryKey_fnEnumerateKeyValue,
212 IRegistryKey_fnSetValueKey,
213 IRegistryKey_fnQueryRegistryValues,
214 IRegistryKey_fnNewSubKey,
215 IRegistryKey_fnDeleteKey
216 };
217
218 /*
219 * @unimplemented
220 */
221 NTSTATUS NTAPI
222 PcNewRegistryKey(
223 OUT PREGISTRYKEY* OutRegistryKey,
224 IN PUNKNOWN OuterUnknown OPTIONAL,
225 IN ULONG RegistryKeyType,
226 IN ACCESS_MASK DesiredAccess,
227 IN PVOID DeviceObject OPTIONAL,
228 IN PVOID SubDevice OPTIONAL,
229 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
230 IN ULONG CreateOptions OPTIONAL,
231 OUT PULONG Disposition OPTIONAL)
232 {
233 HANDLE hHandle;
234 NTSTATUS Status = STATUS_UNSUCCESSFUL;
235 IRegistryKeyImpl * This;
236
237 if (!OutRegistryKey)
238 return STATUS_INVALID_PARAMETER;
239
240 if (RegistryKeyType != GeneralRegistryKey &&
241 RegistryKeyType != DeviceRegistryKey &&
242 RegistryKeyType != DriverRegistryKey &&
243 RegistryKeyType != HwProfileRegistryKey &&
244 RegistryKeyType != DeviceInterfaceRegistryKey)
245 {
246 return STATUS_INVALID_PARAMETER;
247 }
248
249 if (RegistryKeyType == GeneralRegistryKey)
250 {
251 if (!ObjectAttributes)
252 return STATUS_INVALID_PARAMETER;
253
254 Status = ZwOpenKey(&hHandle, DesiredAccess, ObjectAttributes);
255 }
256 else if (RegistryKeyType == DeviceRegistryKey ||
257 RegistryKeyType == DriverRegistryKey ||
258 RegistryKeyType == HwProfileRegistryKey)
259 {
260 if (RegistryKeyType == HwProfileRegistryKey)
261 {
262 /* IoOpenDeviceRegistryKey used different constant */
263 RegistryKeyType = PLUGPLAY_REGKEY_CURRENT_HWPROFILE;
264 }
265
266 Status = IoOpenDeviceRegistryKey(DeviceObject, RegistryKeyType, DesiredAccess, &hHandle);
267 }
268 else if (RegistryKeyType == DeviceInterfaceRegistryKey)
269 {
270 /* FIXME */
271 }
272
273 if (!NT_SUCCESS(Status))
274 {
275 return Status;
276 }
277
278 This = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRegistryKeyImpl), TAG_PORTCLASS);
279 if (!This)
280 {
281 ZwClose(hHandle);
282 return STATUS_INSUFFICIENT_RESOURCES;
283 }
284
285 This->hKey = hHandle;
286 This->lpVtbl = &vt_IRegistryKey;
287 This->ref = 1;
288
289 *OutRegistryKey = (PREGISTRYKEY)&This->lpVtbl;
290 return STATUS_SUCCESS;
291 }
292