ReactOS 0.4.16-dev-91-g764881a
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}
26
27VOID
30{
32}
33
37{
38 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
42
43 /* setup the query request */
47
48 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
49
50 /* query sysaudio for the device count */
52 if (!NT_SUCCESS(Status))
53 return 0;
54
55 return Count;
56}
57
60 IN PIRP Irp,
63{
64 Irp->IoStatus.Information = Length;
65 Irp->IoStatus.Status = Status;
67
68 return Status;
69}
70
74 IN ULONG FilterId,
75 IN ULONG PinId,
77{
79
80 for(Index = 0; Index < ClientInfo->NumPins; Index++)
81 {
82 if (ClientInfo->hPins[Index].FilterId == FilterId && ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle && ClientInfo->hPins[Index].Type == DeviceType)
83 {
84 if (ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
85 {
86 ZwClose(ClientInfo->hPins[Index].Handle);
87 }
88 ClientInfo->hPins[Index].Handle = NULL;
89 return Index;
90 }
91 }
92 return MAXULONG;
93}
94
98 IN ULONG FilterId,
99 IN ULONG PinId,
101 IN HANDLE PinHandle,
102 IN ULONG FreeIndex)
103{
104 PWDMAUD_HANDLE Handles;
105
106 if (FreeIndex != MAXULONG)
107 {
108 /* re-use a free index */
109 ClientInfo->hPins[FreeIndex].Handle = PinHandle;
110 ClientInfo->hPins[FreeIndex].FilterId = FilterId;
111 ClientInfo->hPins[FreeIndex].PinId = PinId;
112 ClientInfo->hPins[FreeIndex].Type = DeviceType;
113
114 return STATUS_SUCCESS;
115 }
116
117 Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1));
118
119 if (!Handles)
121
122 if (ClientInfo->NumPins)
123 {
124 RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins);
125 FreeItem(ClientInfo->hPins);
126 }
127
128 ClientInfo->hPins = Handles;
129 ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
130 ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceType;
131 ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
132 ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
133 ClientInfo->NumPins++;
134
135 return STATUS_SUCCESS;
136}
137
140 IN HANDLE hSubKey,
142{
145 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
146
147 /* now query MatchingDeviceId key */
148 Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0, &Length);
149
150 /* check for success */
152 return NULL;
153
154 /* allocate a buffer for key data */
155 PartialInformation = AllocateItem(NonPagedPool, Length);
156
157 if (!PartialInformation)
158 return NULL;
159
160
161 /* now query MatchingDeviceId key */
162 Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length);
163
164 /* check for success */
165 if (!NT_SUCCESS(Status))
166 {
167 FreeItem(PartialInformation);
168 return NULL;
169 }
170
171 if (PartialInformation->Type != REG_SZ)
172 {
173 /* invalid key type */
174 FreeItem(PartialInformation);
175 return NULL;
176 }
177
178 return PartialInformation;
179}
180
183 IN HANDLE hSubKey,
185 IN ULONG ProductNameSize,
186 OUT LPWSTR ProductName)
187{
188 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
189 UNICODE_STRING DriverDescName = RTL_CONSTANT_STRING(L"DriverDesc");
190 UNICODE_STRING MatchingDeviceIdName = RTL_CONSTANT_STRING(L"MatchingDeviceId");
193
194 /* read MatchingDeviceId value */
195 PartialInformation = ReadKeyValue(hSubKey, &MatchingDeviceIdName);
196
197 if (!PartialInformation)
198 return STATUS_UNSUCCESSFUL;
199
200
201 /* extract last '&' */
202 DeviceName = wcsrchr((LPWSTR)PartialInformation->Data, L'&');
204 /* terminate it */
205 DeviceName[0] = L'\0';
206
207 Length = wcslen((LPWSTR)PartialInformation->Data);
208
209 DPRINT("DeviceName %S PnpName %S Length %u\n", (LPWSTR)PartialInformation->Data, PnpName, Length);
210
211 if (_wcsnicmp((LPWSTR)PartialInformation->Data, &PnpName[4], Length))
212 {
213 FreeItem(PartialInformation);
214 return STATUS_NO_MATCH;
215 }
216
217 /* free buffer */
218 FreeItem(PartialInformation);
219
220 /* read DriverDescName value */
221 PartialInformation = ReadKeyValue(hSubKey, &DriverDescName);
222
223 if (!PartialInformation)
224 {
225 /* failed to read driver desc key */
226 return STATUS_UNSUCCESSFUL;
227 }
228
229 /* copy key name */
230 Length = min(ProductNameSize * sizeof(WCHAR), PartialInformation->DataLength);
231 RtlMoveMemory(ProductName, (PVOID)PartialInformation->Data, Length);
232
233 /* zero terminate it */
234 ProductName[ProductNameSize-1] = L'\0';
235
236 /* free buffer */
237 FreeItem(PartialInformation);
238
239 return STATUS_SUCCESS;
240}
241
245 IN ULONG ProductNameSize,
246 OUT LPWSTR ProductName)
247{
248 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
249
251 WCHAR SubKey[20];
253 HANDLE hKey, hSubKey;
256 PKEY_FULL_INFORMATION KeyInformation;
257
258 for(Index = 0; Index < wcslen(PnpName); Index++)
259 {
260 if (PnpName[Index] == '#')
261 PnpName[Index] = L'\\';
262 }
263
264
265 /* initialize key attributes */
267
268 /* open the key */
269 Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
270
271 /* check for success */
272 if (!NT_SUCCESS(Status))
273 return Status;
274
275 /* query num of subkeys */
276 Status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &Length);
277
279 {
280 DPRINT1("ZwQueryKey failed with %x\n", Status);
281 /* failed */
282 ZwClose(hKey);
283 return Status;
284 }
285
286 /* allocate key information struct */
287 KeyInformation = AllocateItem(NonPagedPool, Length);
288 if (!KeyInformation)
289 {
290 /* no memory */
291 ZwClose(hKey);
293 }
294
295 /* query num of subkeys */
296 Status = ZwQueryKey(hKey, KeyFullInformation, (PVOID)KeyInformation, Length, &Length);
297
298 if (!NT_SUCCESS(Status))
299 {
300 DPRINT1("ZwQueryKey failed with %x\n", Status);
301 FreeItem(KeyInformation);
302 ZwClose(hKey);
303 return Status;
304 }
305
306 /* now iterate through all subkeys */
307 for(Index = 0; Index < KeyInformation->SubKeys; Index++)
308 {
309 /* subkeys are always in the format 0000-XXXX */
310 swprintf(SubKey, L"%04u", Index);
311
312 /* initialize subkey name */
314
315 /* initialize key attributes */
317
318 /* open the sub key */
319 Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
320
321 /* check for success */
322 if (NT_SUCCESS(Status))
323 {
324 /* compare product name */
325 Status = CompareProductName(hSubKey, PnpName, ProductNameSize, ProductName);
326
327 /* close subkey */
328 ZwClose(hSubKey);
329
330 if (NT_SUCCESS(Status))
331 break;
332 }
333 }
334
335 /* free buffer */
336 FreeItem(KeyInformation);
337
338 /* close key */
339 ZwClose(hKey);
340
341 /* no matching key found */
342 return Status;
343}
344
348 IN ULONG DeviceIndex,
349 OUT LPWSTR * Device)
350{
352 KSP_PIN Pin;
354 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
355
356 /* first check if the device index is within bounds */
357 if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject))
359
360 /* setup the query request */
361 Pin.Property.Set = KSPROPSETID_Sysaudio;
363 Pin.Property.Flags = KSPROPERTY_TYPE_GET;
364 Pin.PinId = DeviceIndex;
365
366 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
367
368 /* query sysaudio for the device path */
370
371 /* check if the request failed */
373 return STATUS_UNSUCCESSFUL;
374
375 /* allocate buffer for the device */
377 if (!Device)
379
380 /* query sysaudio again for the device path */
382
383 if (!NT_SUCCESS(Status))
384 {
385 /* failed */
387 return Status;
388 }
389
390 return Status;
391}
392
398{
400 HANDLE hDevice;
401
402 /* now open the device */
404
405 if (!NT_SUCCESS(Status))
406 {
407 return Status;
408 }
409
410 *DeviceHandle = hDevice;
411
412 if (FileObject)
413 {
415
416 if (!NT_SUCCESS(Status))
417 {
418 ZwClose(hDevice);
419 }
420 }
421
422 return Status;
423}
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:33
#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:346
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:394
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:96
NTSTATUS FindProductName(IN LPWSTR PnpName, IN ULONG ProductNameSize, OUT LPWSTR ProductName)
Definition: sup.c:243
ULONG ClosePin(IN PWDMAUD_CLIENT ClientInfo, IN ULONG FilterId, IN ULONG PinId, IN SOUND_DEVICE_TYPE DeviceType)
Definition: sup.c:72
NTSTATUS CompareProductName(IN HANDLE hSubKey, IN LPWSTR PnpName, IN ULONG ProductNameSize, OUT LPWSTR ProductName)
Definition: sup.c:182
#define TAG_WDMAUD
Definition: sup.c:17
PKEY_VALUE_PARTIAL_INFORMATION ReadKeyValue(IN HANDLE hSubKey, IN PUNICODE_STRING KeyName)
Definition: sup.c:139
VOID FreeItem(IN PVOID Item)
Definition: sup.c:28
NTSTATUS SetIrpIoStatus(IN PIRP Irp, IN NTSTATUS Status, IN ULONG Length)
Definition: sup.c:59
ULONG GetSysAudioDeviceCount(IN PDEVICE_OBJECT DeviceObject)
Definition: sup.c:35
struct WDMAUD_DEVICE_EXTENSION * PWDMAUD_DEVICE_EXTENSION
struct KSIDENTIFIER KSPROPERTY
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define NonPagedPool
Definition: env_spec_w32.h:307
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:428
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 ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#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:73
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 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