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: System Audio graph builder
6 * PROGRAMMER: Andrew Greenwood
17 Irp
->IoStatus
.Information
= Length
;
18 Irp
->IoStatus
.Status
= Status
;
19 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
26 IN PWDMAUD_CLIENT ClientInfo
,
29 IN SOUND_DEVICE_TYPE DeviceType
)
33 for(Index
= 0; Index
< ClientInfo
->NumPins
; Index
++)
35 if (ClientInfo
->hPins
[Index
].FilterId
== FilterId
&& ClientInfo
->hPins
[Index
].PinId
== PinId
&& ClientInfo
->hPins
[Index
].Handle
&& ClientInfo
->hPins
[Index
].Type
== DeviceType
)
37 if (ClientInfo
->hPins
[Index
].Type
!= MIXER_DEVICE_TYPE
)
39 ZwClose(ClientInfo
->hPins
[Index
].Handle
);
41 ClientInfo
->hPins
[Index
].Handle
= NULL
;
50 IN PWDMAUD_CLIENT ClientInfo
,
53 IN SOUND_DEVICE_TYPE DeviceType
,
57 PWDMAUD_HANDLE Handles
;
59 if (FreeIndex
!= MAXULONG
)
61 /* re-use a free index */
62 ClientInfo
->hPins
[FreeIndex
].Handle
= PinHandle
;
63 ClientInfo
->hPins
[FreeIndex
].FilterId
= FilterId
;
64 ClientInfo
->hPins
[FreeIndex
].PinId
= PinId
;
65 ClientInfo
->hPins
[FreeIndex
].Type
= DeviceType
;
67 return STATUS_SUCCESS
;
70 Handles
= ExAllocatePool(NonPagedPool
, sizeof(WDMAUD_HANDLE
) * (ClientInfo
->NumPins
+1));
73 return STATUS_INSUFFICIENT_RESOURCES
;
75 if (ClientInfo
->NumPins
)
77 RtlMoveMemory(Handles
, ClientInfo
->hPins
, sizeof(WDMAUD_HANDLE
) * ClientInfo
->NumPins
);
78 ExFreePool(ClientInfo
->hPins
);
81 ClientInfo
->hPins
= Handles
;
82 ClientInfo
->hPins
[ClientInfo
->NumPins
].Handle
= PinHandle
;
83 ClientInfo
->hPins
[ClientInfo
->NumPins
].Type
= DeviceType
;
84 ClientInfo
->hPins
[ClientInfo
->NumPins
].FilterId
= FilterId
;
85 ClientInfo
->hPins
[ClientInfo
->NumPins
].PinId
= PinId
;
86 ClientInfo
->NumPins
++;
88 return STATUS_SUCCESS
;
91 PKEY_VALUE_PARTIAL_INFORMATION
94 IN PUNICODE_STRING KeyName
)
98 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
100 /* now query MatchingDeviceId key */
101 Status
= ZwQueryValueKey(hSubKey
, KeyName
, KeyValuePartialInformation
, NULL
, 0, &Length
);
103 /* check for success */
104 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
107 /* allocate a buffer for key data */
108 PartialInformation
= ExAllocatePool(NonPagedPool
, Length
);
110 if (!PartialInformation
)
114 /* now query MatchingDeviceId key */
115 Status
= ZwQueryValueKey(hSubKey
, KeyName
, KeyValuePartialInformation
, PartialInformation
, Length
, &Length
);
117 /* check for success */
118 if (!NT_SUCCESS(Status
))
120 ExFreePool(PartialInformation
);
124 if (PartialInformation
->Type
!= REG_SZ
)
126 /* invalid key type */
127 ExFreePool(PartialInformation
);
131 return PartialInformation
;
139 IN ULONG ProductNameSize
,
140 OUT LPWSTR ProductName
)
142 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
143 UNICODE_STRING DriverDescName
= RTL_CONSTANT_STRING(L
"DriverDesc");
144 UNICODE_STRING MatchingDeviceIdName
= RTL_CONSTANT_STRING(L
"MatchingDeviceId");
148 /* read MatchingDeviceId value */
149 PartialInformation
= ReadKeyValue(hSubKey
, &MatchingDeviceIdName
);
151 if (!PartialInformation
)
152 return STATUS_UNSUCCESSFUL
;
155 /* extract last '&' */
156 DeviceName
= wcsrchr((LPWSTR
)PartialInformation
->Data
, L
'&');
159 DeviceName
[0] = L
'\0';
161 Length
= wcslen((LPWSTR
)PartialInformation
->Data
);
163 DPRINT("DeviceName %S PnpName %S Length %u\n", (LPWSTR
)PartialInformation
->Data
, PnpName
, Length
);
165 if (_wcsnicmp((LPWSTR
)PartialInformation
->Data
, &PnpName
[4], Length
))
167 ExFreePool(PartialInformation
);
168 return STATUS_NO_MATCH
;
172 ExFreePool(PartialInformation
);
174 /* read DriverDescName value */
175 PartialInformation
= ReadKeyValue(hSubKey
, &DriverDescName
);
177 if (!PartialInformation
)
179 /* failed to read driver desc key */
180 return STATUS_UNSUCCESSFUL
;
184 Length
= min(ProductNameSize
* sizeof(WCHAR
), PartialInformation
->DataLength
);
185 RtlMoveMemory(ProductName
, (PVOID
)PartialInformation
->Data
, Length
);
187 /* zero terminate it */
188 ProductName
[ProductNameSize
-1] = L
'\0';
191 ExFreePool(PartialInformation
);
193 return STATUS_SUCCESS
;
201 IN ULONG ProductNameSize
,
202 OUT LPWSTR ProductName
)
204 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
206 UNICODE_STRING SubKeyName
;
208 OBJECT_ATTRIBUTES ObjectAttributes
;
209 HANDLE hKey
, hSubKey
;
212 PKEY_FULL_INFORMATION KeyInformation
;
214 for(Index
= 0; Index
< wcslen(PnpName
); Index
++)
216 if (PnpName
[Index
] == '#')
217 PnpName
[Index
] = L
'\\';
221 /* initialize key attributes */
222 InitializeObjectAttributes(&ObjectAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, NULL
, NULL
);
225 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
227 /* check for success */
228 if (!NT_SUCCESS(Status
))
231 /* query num of subkeys */
232 Status
= ZwQueryKey(hKey
, KeyFullInformation
, NULL
, 0, &Length
);
234 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
236 DPRINT1("ZwQueryKey failed with %x\n", Status
);
242 /* allocate key information struct */
243 KeyInformation
= ExAllocatePool(NonPagedPool
, Length
);
248 return STATUS_INSUFFICIENT_RESOURCES
;
251 /* query num of subkeys */
252 Status
= ZwQueryKey(hKey
, KeyFullInformation
, (PVOID
)KeyInformation
, Length
, &Length
);
254 if (!NT_SUCCESS(Status
))
256 DPRINT1("ZwQueryKey failed with %x\n", Status
);
257 ExFreePool(KeyInformation
);
262 /* now iterate through all subkeys */
263 for(Index
= 0; Index
< KeyInformation
->SubKeys
; Index
++)
265 /* subkeys are always in the format 0000-XXXX */
266 swprintf(SubKey
, L
"%04u", Index
);
268 /* initialize subkey name */
269 RtlInitUnicodeString(&SubKeyName
, SubKey
);
271 /* initialize key attributes */
272 InitializeObjectAttributes(&ObjectAttributes
, &SubKeyName
, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, hKey
, NULL
);
274 /* open the sub key */
275 Status
= ZwOpenKey(&hSubKey
, GENERIC_READ
, &ObjectAttributes
);
277 /* check for success */
278 if (NT_SUCCESS(Status
))
280 /* compare product name */
281 Status
= CompareProductName(hSubKey
, PnpName
, ProductNameSize
, ProductName
);
286 if (NT_SUCCESS(Status
))
292 ExFreePool(KeyInformation
);
297 /* no matching key found */