ReactOS 0.4.15-dev-6694-g4ba8af9
sup.c
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/legacy/wdmaud/sup.c
5 * PURPOSE: Misc support routines
6 * PROGRAMMER: Andrew Greenwood
7 * Johannes Anderwald
8 */
9
10#include "wdmaud.h"
11
12#include <stdio.h>
13
14#define NDEBUG
15#include <debug.h>
16
17#define TAG_WDMAUD 'DMDW'
18
23{
25 if (!Item)
26 return Item;
27
29 return Item;
30}
31
32VOID
35{
37}
38
39
40
44{
45 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
49
50 /* setup the query request */
54
55 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
56
57 /* query sysaudio for the device count */
59 if (!NT_SUCCESS(Status))
60 return 0;
61
62 return Count;
63}
64
65
68 IN PIRP Irp,
71{
72 Irp->IoStatus.Information = Length;
73 Irp->IoStatus.Status = Status;
75 return Status;
76
77}
78
82 IN ULONG FilterId,
83 IN ULONG PinId,
85{
87
88 for(Index = 0; Index < ClientInfo->NumPins; Index++)
89 {
90 if (ClientInfo->hPins[Index].FilterId == FilterId && ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle && ClientInfo->hPins[Index].Type == DeviceType)
91 {
92 if (ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
93 {
94 ZwClose(ClientInfo->hPins[Index].Handle);
95 }
96 ClientInfo->hPins[Index].Handle = NULL;
97 return Index;
98 }
99 }
100 return MAXULONG;
101}
102
106 IN ULONG FilterId,
107 IN ULONG PinId,
109 IN HANDLE PinHandle,
110 IN ULONG FreeIndex)
111{
112 PWDMAUD_HANDLE Handles;
113
114 if (FreeIndex != MAXULONG)
115 {
116 /* re-use a free index */
117 ClientInfo->hPins[FreeIndex].Handle = PinHandle;
118 ClientInfo->hPins[FreeIndex].FilterId = FilterId;
119 ClientInfo->hPins[FreeIndex].PinId = PinId;
120 ClientInfo->hPins[FreeIndex].Type = DeviceType;
121
122 return STATUS_SUCCESS;
123 }
124
125 Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1));
126
127 if (!Handles)
129
130 if (ClientInfo->NumPins)
131 {
132 RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins);
133 FreeItem(ClientInfo->hPins);
134 }
135
136 ClientInfo->hPins = Handles;
137 ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
138 ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceType;
139 ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
140 ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
141 ClientInfo->NumPins++;
142
143 return STATUS_SUCCESS;
144}
145
148 IN HANDLE hSubKey,
150{
153 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
154
155 /* now query MatchingDeviceId key */
156 Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0, &Length);
157
158 /* check for success */
160 return NULL;
161
162 /* allocate a buffer for key data */
163 PartialInformation = AllocateItem(NonPagedPool, Length);
164
165 if (!PartialInformation)
166 return NULL;
167
168
169 /* now query MatchingDeviceId key */
170 Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length);
171
172 /* check for success */
173 if (!NT_SUCCESS(Status))
174 {
175 FreeItem(PartialInformation);
176 return NULL;
177 }
178
179 if (PartialInformation->Type != REG_SZ)
180 {
181 /* invalid key type */
182 FreeItem(PartialInformation);
183 return NULL;
184 }
185
186 return PartialInformation;
187}
188
189
192 IN HANDLE hSubKey,
194 IN ULONG ProductNameSize,
195 OUT LPWSTR ProductName)
196{
197 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
198 UNICODE_STRING DriverDescName = RTL_CONSTANT_STRING(L"DriverDesc");
199 UNICODE_STRING MatchingDeviceIdName = RTL_CONSTANT_STRING(L"MatchingDeviceId");
202
203 /* read MatchingDeviceId value */
204 PartialInformation = ReadKeyValue(hSubKey, &MatchingDeviceIdName);
205
206 if (!PartialInformation)
207 return STATUS_UNSUCCESSFUL;
208
209
210 /* extract last '&' */
211 DeviceName = wcsrchr((LPWSTR)PartialInformation->Data, L'&');
213 /* terminate it */
214 DeviceName[0] = L'\0';
215
216 Length = wcslen((LPWSTR)PartialInformation->Data);
217
218 DPRINT("DeviceName %S PnpName %S Length %u\n", (LPWSTR)PartialInformation->Data, PnpName, Length);
219
220 if (_wcsnicmp((LPWSTR)PartialInformation->Data, &PnpName[4], Length))
221 {
222 FreeItem(PartialInformation);
223 return STATUS_NO_MATCH;
224 }
225
226 /* free buffer */
227 FreeItem(PartialInformation);
228
229 /* read DriverDescName value */
230 PartialInformation = ReadKeyValue(hSubKey, &DriverDescName);
231
232 if (!PartialInformation)
233 {
234 /* failed to read driver desc key */
235 return STATUS_UNSUCCESSFUL;
236 }
237
238 /* copy key name */
239 Length = min(ProductNameSize * sizeof(WCHAR), PartialInformation->DataLength);
240 RtlMoveMemory(ProductName, (PVOID)PartialInformation->Data, Length);
241
242 /* zero terminate it */
243 ProductName[ProductNameSize-1] = L'\0';
244
245 /* free buffer */
246 FreeItem(PartialInformation);
247
248 return STATUS_SUCCESS;
249}
250
251
252
256 IN ULONG ProductNameSize,
257 OUT LPWSTR ProductName)
258{
259 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
260
262 WCHAR SubKey[20];
264 HANDLE hKey, hSubKey;
267 PKEY_FULL_INFORMATION KeyInformation;
268
269 for(Index = 0; Index < wcslen(PnpName); Index++)
270 {
271 if (PnpName[Index] == '#')
272 PnpName[Index] = L'\\';
273 }
274
275
276 /* initialize key attributes */
278
279 /* open the key */
280 Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
281
282 /* check for success */
283 if (!NT_SUCCESS(Status))
284 return Status;
285
286 /* query num of subkeys */
287 Status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &Length);
288
290 {
291 DPRINT1("ZwQueryKey failed with %x\n", Status);
292 /* failed */
293 ZwClose(hKey);
294 return Status;
295 }
296
297 /* allocate key information struct */
298 KeyInformation = AllocateItem(NonPagedPool, Length);
299 if (!KeyInformation)
300 {
301 /* no memory */
302 ZwClose(hKey);
304 }
305
306 /* query num of subkeys */
307 Status = ZwQueryKey(hKey, KeyFullInformation, (PVOID)KeyInformation, Length, &Length);
308
309 if (!NT_SUCCESS(Status))
310 {
311 DPRINT1("ZwQueryKey failed with %x\n", Status);
312 FreeItem(KeyInformation);
313 ZwClose(hKey);
314 return Status;
315 }
316
317 /* now iterate through all subkeys */
318 for(Index = 0; Index < KeyInformation->SubKeys; Index++)
319 {
320 /* subkeys are always in the format 0000-XXXX */
321 swprintf(SubKey, L"%04u", Index);
322
323 /* initialize subkey name */
325
326 /* initialize key attributes */
328
329 /* open the sub key */
330 Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
331
332 /* check for success */
333 if (NT_SUCCESS(Status))
334 {
335 /* compare product name */
336 Status = CompareProductName(hSubKey, PnpName, ProductNameSize, ProductName);
337
338 /* close subkey */
339 ZwClose(hSubKey);
340
341 if (NT_SUCCESS(Status))
342 break;
343 }
344 }
345
346 /* free buffer */
347 FreeItem(KeyInformation);
348
349 /* close key */
350 ZwClose(hKey);
351
352 /* no matching key found */
353 return Status;
354}
355
359 IN ULONG DeviceIndex,
360 OUT LPWSTR * Device)
361{
363 KSP_PIN Pin;
365 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
366
367 /* first check if the device index is within bounds */
368 if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject))
370
371 /* setup the query request */
372 Pin.Property.Set = KSPROPSETID_Sysaudio;
374 Pin.Property.Flags = KSPROPERTY_TYPE_GET;
375 Pin.PinId = DeviceIndex;
376
377 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
378
379 /* query sysaudio for the device path */
381
382 /* check if the request failed */
384 return STATUS_UNSUCCESSFUL;
385
386 /* allocate buffer for the device */
388 if (!Device)
390
391 /* query sysaudio again for the device path */
393
394 if (!NT_SUCCESS(Status))
395 {
396 /* failed */
398 return Status;
399 }
400
401 return Status;
402}
403
409{
411 HANDLE hDevice;
412
413 /* now open the device */
415
416 if (!NT_SUCCESS(Status))
417 {
418 return Status;
419 }
420
421 *DeviceHandle = hDevice;
422
423 if (FileObject)
424 {
426
427 if (!NT_SUCCESS(Status))
428 {
429 ZwClose(hDevice);
430 }
431 }
432
433 return Status;
434
435}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define wcsrchr
Definition: compat.h:16
#define GENERIC_READ
Definition: compat.h:135
#define swprintf
Definition: precomp.h:40
KSDDKAPI NTSTATUS NTAPI KsSynchronousIoControlDevice(IN PFILE_OBJECT FileObject, IN KPROCESSOR_MODE RequestorMode, IN ULONG IoControl, IN PVOID InBuffer, IN ULONG InSize, OUT PVOID OutBuffer, IN ULONG OutSize, OUT PULONG BytesReturned)
Definition: api.c:1099
NTSTATUS WdmAudOpenSysAudioDevice(IN LPWSTR DeviceName, OUT PHANDLE Handle)
Definition: deviface.c:16
NTSTATUS GetSysAudioDevicePnpName(IN PDEVICE_OBJECT DeviceObject, IN ULONG DeviceIndex, OUT LPWSTR *Device)
Definition: sup.c:357
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: sup.c:20
NTSTATUS OpenDevice(IN LPWSTR Device, OUT PHANDLE DeviceHandle, OUT PFILE_OBJECT *FileObject)
Definition: sup.c:405
NTSTATUS InsertPinHandle(IN PWDMAUD_CLIENT ClientInfo, IN ULONG FilterId, IN ULONG PinId, IN SOUND_DEVICE_TYPE DeviceType, IN HANDLE PinHandle, IN ULONG FreeIndex)
Definition: sup.c:104
NTSTATUS FindProductName(IN LPWSTR PnpName, IN ULONG ProductNameSize, OUT LPWSTR ProductName)
Definition: sup.c:254
ULONG ClosePin(IN PWDMAUD_CLIENT ClientInfo, IN ULONG FilterId, IN ULONG PinId, IN SOUND_DEVICE_TYPE DeviceType)
Definition: sup.c:80
NTSTATUS CompareProductName(IN HANDLE hSubKey, IN LPWSTR PnpName, IN ULONG ProductNameSize, OUT LPWSTR ProductName)
Definition: sup.c:191
#define TAG_WDMAUD
Definition: sup.c:17
PKEY_VALUE_PARTIAL_INFORMATION ReadKeyValue(IN HANDLE hSubKey, IN PUNICODE_STRING KeyName)
Definition: sup.c:147
VOID FreeItem(IN PVOID Item)
Definition: sup.c:33
NTSTATUS SetIrpIoStatus(IN PIRP Irp, IN NTSTATUS Status, IN ULONG Length)
Definition: sup.c:67
ULONG GetSysAudioDeviceCount(IN PDEVICE_OBJECT DeviceObject)
Definition: sup.c:42
struct WDMAUD_DEVICE_EXTENSION * PWDMAUD_DEVICE_EXTENSION
struct KSIDENTIFIER KSPROPERTY
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:427
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
CLIENT_DATA ClientInfo
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define IOCTL_KS_PROPERTY
Definition: ks.h:127
@ KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME
Definition: ksmedia.h:1171
@ KSPROPERTY_SYSAUDIO_DEVICE_COUNT
Definition: ksmedia.h:1168
#define KSPROPSETID_Sysaudio
Definition: ksmedia.h:1165
#define REG_SZ
Definition: layer.c:22
DeviceType
Definition: mmdrv.h:42
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define min(a, b)
Definition: monoChain.cc:55
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4725
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
int Count
Definition: noreturn.cpp:7
@ KeyFullInformation
Definition: nt_native.h:1133
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IoCompleteRequest
Definition: irp.c:1240
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NO_MATCH
Definition: ntstatus.h:751
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
static PNP_ID_NAME PnpName[]
Definition: pnpdump.c:52
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
SOUND_DEVICE_TYPE
Definition: sndtypes.h:26
@ MIXER_DEVICE_TYPE
Definition: sndtypes.h:33
#define DPRINT
Definition: sndvol32.h:71
Definition: ks.h:642
PFILE_OBJECT FileObject
Definition: wdmaud.h:62
ULONG Flags
Definition: ntfs.h:536
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define MAXULONG
Definition: typedefs.h:251
INT POOL_TYPE
Definition: typedefs.h:78
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184