062d0b5473cef9b92b03756e347d19279f1c52c5
[reactos.git] / reactos / drivers / usb / usbaudio / filter.c
1 /*
2 * PROJECT: ReactOS Universal Audio Class Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbaudio/filter.c
5 * PURPOSE: USB Audio device driver.
6 * PROGRAMMERS:
7 * Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9
10 #include "usbaudio.h"
11
12 GUID NodeTypeMicrophone = { STATIC_KSNODETYPE_MICROPHONE };
13 GUID NodeTypeDesktopMicrophone = { STATIC_KSNODETYPE_DESKTOP_MICROPHONE };
14 GUID NodeTypePersonalMicrophone = { STATIC_KSNODETYPE_PERSONAL_MICROPHONE };
15 GUID NodeTypeOmmniMicrophone = { STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE };
16 GUID NodeTypeArrayMicrophone = { STATIC_KSNODETYPE_MICROPHONE_ARRAY };
17 GUID NodeTypeProcessingArrayMicrophone = { STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY };
18 GUID NodeTypeSpeaker = { STATIC_KSNODETYPE_SPEAKER };
19 GUID NodeTypeHeadphonesSpeaker = { STATIC_KSNODETYPE_HEADPHONES };
20 GUID NodeTypeHMDA = { STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO };
21 GUID NodeTypeDesktopSpeaker = { STATIC_KSNODETYPE_DESKTOP_SPEAKER };
22 GUID NodeTypeRoomSpeaker = { STATIC_KSNODETYPE_ROOM_SPEAKER };
23 GUID NodeTypeCommunicationSpeaker = { STATIC_KSNODETYPE_COMMUNICATION_SPEAKER };
24 GUID NodeTypeSubwoofer = { STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER };
25 GUID NodeTypeCapture = { STATIC_PINNAME_CAPTURE };
26 GUID NodeTypePlayback = { STATIC_KSCATEGORY_AUDIO };
27 GUID GUID_KSCATEGORY_AUDIO = { STATIC_KSCATEGORY_AUDIO };
28
29 KSPIN_INTERFACE StandardPinInterface =
30 {
31 {STATIC_KSINTERFACESETID_Standard},
32 KSINTERFACE_STANDARD_STREAMING,
33 0
34 };
35
36 KSPIN_MEDIUM StandardPinMedium =
37 {
38 {STATIC_KSMEDIUMSETID_Standard},
39 KSMEDIUM_TYPE_ANYINSTANCE,
40 0
41 };
42
43 KSDATARANGE BridgePinAudioFormat[] =
44 {
45 {
46 sizeof(KSDATAFORMAT),
47 0,
48 0,
49 0,
50 {STATIC_KSDATAFORMAT_TYPE_AUDIO},
51 {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG},
52 {STATIC_KSDATAFORMAT_SPECIFIER_NONE}
53 }
54 };
55
56 static PKSDATARANGE BridgePinAudioFormats[] =
57 {
58 &BridgePinAudioFormat[0]
59 };
60
61 static LPWSTR ReferenceString = L"global";
62
63 NTSTATUS
64 NTAPI
65 USBAudioFilterCreate(
66 PKSFILTER Filter,
67 PIRP Irp);
68
69 static KSFILTER_DISPATCH USBAudioFilterDispatch =
70 {
71 USBAudioFilterCreate,
72 NULL,
73 NULL,
74 NULL
75 };
76
77 NTSTATUS
78 BuildUSBAudioFilterTopology(
79 PKSDEVICE Device)
80 {
81 UNIMPLEMENTED
82 return STATUS_NOT_IMPLEMENTED;
83 }
84
85 NTSTATUS
86 NTAPI
87 USBAudioFilterCreate(
88 PKSFILTER Filter,
89 PIRP Irp)
90 {
91 UNIMPLEMENTED
92 return STATUS_SUCCESS;
93 }
94
95
96 VOID
97 CountTerminalUnits(
98 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
99 OUT PULONG NonStreamingTerminalDescriptorCount,
100 OUT PULONG TotalTerminalDescriptorCount)
101 {
102 PUSB_INTERFACE_DESCRIPTOR Descriptor;
103 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
104 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
105 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
106 ULONG NonStreamingTerminalCount = 0;
107 ULONG TotalTerminalCount = 0;
108
109 for(Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
110 Descriptor != NULL;
111 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
112 {
113 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
114 {
115 InterfaceHeaderDescriptor = USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
116 if (InterfaceHeaderDescriptor != NULL)
117 {
118 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
119 while (CommonDescriptor)
120 {
121 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
122 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
123 {
124 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
125 {
126 NonStreamingTerminalCount++;
127 }
128 TotalTerminalCount++;
129 }
130 CommonDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
131 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
132 break;
133 }
134 }
135 }
136 else if (Descriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING */
137 {
138 UNIMPLEMENTED
139 }
140 }
141 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount;
142 *TotalTerminalDescriptorCount = TotalTerminalCount;
143 }
144
145 LPGUID
146 UsbAudioGetPinCategoryFromTerminalDescriptor(
147 IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
148 {
149 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
150 return &NodeTypeMicrophone;
151 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
152 return &NodeTypeDesktopMicrophone;
153 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
154 return &NodeTypePersonalMicrophone;
155 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
156 return &NodeTypeOmmniMicrophone;
157 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
158 return &NodeTypeArrayMicrophone;
159 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
160 return &NodeTypeProcessingArrayMicrophone;
161
162 /* playback types */
163 if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
164 return &NodeTypeSpeaker;
165 else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
166 return &NodeTypeHeadphonesSpeaker;
167 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
168 return &NodeTypeHMDA;
169 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
170 return &NodeTypeDesktopSpeaker;
171 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
172 return &NodeTypeRoomSpeaker;
173 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
174 return &NodeTypeCommunicationSpeaker;
175 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE)
176 return &NodeTypeSubwoofer;
177
178 if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
179 {
180 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
181 return &NodeTypeCapture;
182 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
183 return &NodeTypePlayback;
184
185 }
186 return NULL;
187 }
188
189 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
190 UsbAudioGetStreamingTerminalDescriptorByIndex(
191 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
192 IN ULONG Index)
193 {
194 PUSB_INTERFACE_DESCRIPTOR Descriptor;
195 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
196 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
197 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
198 ULONG TerminalCount = 0;
199
200 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
201 Descriptor != NULL;
202 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
203 {
204 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
205 {
206 InterfaceHeaderDescriptor = USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
207 if (InterfaceHeaderDescriptor != NULL)
208 {
209 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
210 while (CommonDescriptor)
211 {
212 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
213 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
214 {
215 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
216 {
217 if (TerminalCount == Index)
218 {
219 return InputTerminalDescriptor;
220 }
221 TerminalCount++;
222 }
223 }
224 CommonDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
225 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
226 break;
227 }
228 }
229 }
230 }
231 return NULL;
232 }
233
234 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
235 UsbAudioGetNonStreamingTerminalDescriptorByIndex(
236 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
237 IN ULONG Index)
238 {
239
240 PUSB_INTERFACE_DESCRIPTOR Descriptor;
241 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
242 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
243 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
244 ULONG TerminalCount = 0;
245
246 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
247 Descriptor != NULL;
248 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
249 {
250 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
251 {
252 InterfaceHeaderDescriptor = USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
253 if (InterfaceHeaderDescriptor != NULL)
254 {
255 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
256 while (CommonDescriptor)
257 {
258 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
259 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
260 {
261 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
262 {
263 if (TerminalCount == Index)
264 {
265 return InputTerminalDescriptor;
266 }
267 TerminalCount++;
268 }
269 }
270 CommonDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
271 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
272 break;
273 }
274 }
275 }
276 }
277 return NULL;
278 }
279
280
281
282 NTSTATUS
283 USBAudioPinBuildDescriptors(
284 PKSDEVICE Device,
285 PKSPIN_DESCRIPTOR_EX *PinDescriptors,
286 PULONG PinDescriptorsCount,
287 PULONG PinDescriptorSize)
288 {
289 PDEVICE_EXTENSION DeviceExtension;
290 PKSPIN_DESCRIPTOR_EX Pins;
291 ULONG TotalTerminalDescriptorCount = 0;
292 ULONG NonStreamingTerminalDescriptorCount = 0;
293 ULONG Index = 0;
294 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor = NULL;
295
296 /* get device extension */
297 DeviceExtension = Device->Context;
298
299 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
300 DPRINT1("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount);
301
302 /* allocate pins */
303 Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount);
304 if (!Pins)
305 {
306 /* no memory*/
307 return STATUS_INSUFFICIENT_RESOURCES;
308 }
309
310 for (Index = 0; Index < TotalTerminalDescriptorCount; Index++)
311 {
312 if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount))
313 {
314 /* irp sink pins*/
315 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index);
316 Pins[Index].PinDescriptor.InterfacesCount = 1;
317 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
318 Pins[Index].PinDescriptor.MediumsCount = 1;
319 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
320 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
321
322 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
323 {
324 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH;
325 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
326 }
327 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
328 {
329 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
330 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
331 }
332
333 /* irp sinks / sources can be instantiated */
334 Pins[Index].InstancesPossible = 1;
335 }
336 else
337 {
338 /* bridge pins */
339 TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount));
340 Pins[Index].PinDescriptor.InterfacesCount = 1;
341 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
342 Pins[Index].PinDescriptor.MediumsCount = 1;
343 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
344 Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats;
345 Pins[Index].PinDescriptor.DataRangesCount = 1;
346 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
347 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
348
349 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
350 {
351 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
352 }
353 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
354 {
355 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
356 }
357 }
358
359 }
360
361 *PinDescriptors = Pins;
362 *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX);
363 *PinDescriptorsCount = TotalTerminalDescriptorCount;
364
365 return STATUS_SUCCESS;
366 }
367
368 NTSTATUS
369 USBAudioInitComponentId(
370 PKSDEVICE Device,
371 IN PKSCOMPONENTID ComponentId)
372 {
373 PDEVICE_EXTENSION DeviceExtension;
374
375 /* get device extension */
376 DeviceExtension = Device->Context;
377
378 INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
379 INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
380
381 //ComponentId->Component = KSCOMPONENTID_USBAUDIO;
382 UNIMPLEMENTED
383 return STATUS_NOT_IMPLEMENTED;
384 }
385
386
387 NTSTATUS
388 NTAPI
389 USBAudioCreateFilterContext(
390 PKSDEVICE Device)
391 {
392 KSFILTER_DESCRIPTOR FilterDescriptor;
393 PDEVICE_EXTENSION DeviceExtension;
394 PKSCOMPONENTID ComponentId;
395 NTSTATUS Status;
396
397 /* clear filter descriptor */
398 RtlZeroMemory(&FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
399
400 /* init filter descriptor*/
401 FilterDescriptor.Version = KSFILTER_DESCRIPTOR_VERSION;
402 FilterDescriptor.Flags = 0;
403 FilterDescriptor.ReferenceGuid = &KSNAME_Filter;
404 FilterDescriptor.Dispatch = &USBAudioFilterDispatch;
405 FilterDescriptor.CategoriesCount = 1;
406 FilterDescriptor.Categories = &GUID_KSCATEGORY_AUDIO;
407
408 /* init component id*/
409 ComponentId = AllocFunction(sizeof(KSCOMPONENTID));
410 if (!ComponentId)
411 {
412 /* no memory */
413 return STATUS_INSUFFICIENT_RESOURCES;
414 }
415 Status = USBAudioInitComponentId(Device, ComponentId);
416 if (!NT_SUCCESS(Status))
417 {
418 /* failed*/
419 //FreeFunction(ComponentId);
420 //return Status;
421 }
422 FilterDescriptor.ComponentId = ComponentId;
423
424 /* build pin descriptors */
425 Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor.PinDescriptors, &FilterDescriptor.PinDescriptorsCount, &FilterDescriptor.PinDescriptorSize);
426 if (!NT_SUCCESS(Status))
427 {
428 /* failed*/
429 FreeFunction(ComponentId);
430 return Status;
431 }
432
433 DbgBreakPoint();
434 /* build topology */
435 Status = BuildUSBAudioFilterTopology(Device);
436 if (!NT_SUCCESS(Status))
437 {
438 /* failed*/
439 //FreeFunction(ComponentId);
440 //return Status;
441 }
442
443 /* lets create the filter */
444 DeviceExtension = Device->Context;
445 Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, &FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL);
446 DPRINT1("KsCreateFilterFactory: %x\n", Status);
447
448 return Status;
449 }
450
451