ReactOS  0.4.14-dev-323-g6fe6a88
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 
19 PVOID
23 {
25  if (!Item)
26  return Item;
27 
29  return Item;
30 }
31 
32 VOID
34  IN PVOID Item)
35 {
36  ExFreePool(Item);
37 }
38 
39 
40 
41 ULONG
44 {
45  PWDMAUD_DEVICE_EXTENSION DeviceExtension;
49 
50  /* setup the query request */
54 
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,
70  IN ULONG Length)
71 {
72  Irp->IoStatus.Information = Length;
73  Irp->IoStatus.Status = Status;
75  return Status;
76 
77 }
78 
79 ULONG
82  IN ULONG FilterId,
83  IN ULONG PinId,
85 {
86  ULONG Index;
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 
103 NTSTATUS
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 {
152  ULONG Length;
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 
190 NTSTATUS
192  IN HANDLE hSubKey,
193  IN LPWSTR PnpName,
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");
200  ULONG Length;
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 
253 NTSTATUS
255  IN LPWSTR PnpName,
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;
266  ULONG Length, Index;
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 
356 NTSTATUS
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 
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 */
397  FreeItem(*Device);
398  return Status;
399  }
400 
401  return Status;
402 }
403 
404 NTSTATUS
406  IN LPWSTR Device,
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 }
struct KSIDENTIFIER KSPROPERTY
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define IOCTL_KS_PROPERTY
Definition: ks.h:127
#define IN
Definition: typedefs.h:38
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
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
_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
NTSTATUS CompareProductName(IN HANDLE hSubKey, IN LPWSTR PnpName, IN ULONG ProductNameSize, OUT LPWSTR ProductName)
Definition: sup.c:191
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
DeviceType
Definition: mmdrv.h:41
PKEY_VALUE_PARTIAL_INFORMATION ReadKeyValue(IN HANDLE hSubKey, IN PUNICODE_STRING KeyName)
Definition: sup.c:147
LONG NTSTATUS
Definition: precomp.h:26
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: sup.c:20
_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)
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
WCHAR DeviceName[]
Definition: adapter.cpp:21
NTSTATUS GetSysAudioDevicePnpName(IN PDEVICE_OBJECT DeviceObject, IN ULONG DeviceIndex, OUT LPWSTR *Device)
Definition: sup.c:357
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
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
CLIENT_DATA ClientInfo
#define OBJ_OPENIF
Definition: winternl.h:229
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:496
VOID FreeItem(IN PVOID Item)
Definition: sup.c:33
#define FILE_READ_DATA
Definition: nt_native.h:628
struct WDMAUD_DEVICE_EXTENSION * PWDMAUD_DEVICE_EXTENSION
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
ULONG ClosePin(IN PWDMAUD_CLIENT ClientInfo, IN ULONG FilterId, IN ULONG PinId, IN SOUND_DEVICE_TYPE DeviceType)
Definition: sup.c:80
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define FILE_WRITE_DATA
Definition: nt_native.h:631
NTSTATUS WdmAudOpenSysAudioDevice(IN LPWSTR DeviceName, OUT PHANDLE Handle)
Definition: deviface.c:16
NTSTATUS OpenDevice(IN LPWSTR Device, OUT PHANDLE DeviceHandle, OUT PFILE_OBJECT *FileObject)
Definition: sup.c:405
Definition: ks.h:642
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:415
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
INT POOL_TYPE
Definition: typedefs.h:76
#define swprintf(buf, format,...)
Definition: sprintf.c:56
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1955
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG Flags
Definition: ntfs.h:532
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define GENERIC_READ
Definition: compat.h:124
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
Status
Definition: gdiplustypes.h:24
#define TAG_WDMAUD
Definition: sup.c:17
PFILE_OBJECT FileObject
Definition: wdmaud.h:62
#define MAXULONG
Definition: typedefs.h:250
NTSTATUS SetIrpIoStatus(IN PIRP Irp, IN NTSTATUS Status, IN ULONG Length)
Definition: sup.c:67
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define STATUS_NO_MATCH
Definition: ntstatus.h:737
_In_ FILTER_INFORMATION_CLASS _In_ ULONG _Out_ PULONG BytesReturned
Definition: fltkernel.h:1716
#define min(a, b)
Definition: monoChain.cc:55
SOUND_DEVICE_TYPE
Definition: sndtypes.h:25
#define DPRINT1
Definition: precomp.h:8
#define KSPROPSETID_Sysaudio
Definition: ksmedia.h:1065
#define OUT
Definition: typedefs.h:39
NTSTATUS FindProductName(IN LPWSTR PnpName, IN ULONG ProductNameSize, OUT LPWSTR ProductName)
Definition: sup.c:254
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:998
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static PNP_ID_NAME PnpName[]
Definition: pnpdump.c:52
return STATUS_SUCCESS
Definition: btrfs.c:2938
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
ULONG GetSysAudioDeviceCount(IN PDEVICE_OBJECT DeviceObject)
Definition: sup.c:42
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22