2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/legacy/wdmaud/mmixer.c
5 * PURPOSE: WDM Legacy Mixer
6 * PROGRAMMER: Johannes Anderwald
12 PVOID
Alloc(ULONG NumBytes
);
13 MIXER_STATUS
Close(HANDLE hDevice
);
14 VOID
Free(PVOID Block
);
15 VOID
Copy(PVOID Src
, PVOID Dst
, ULONG NumBytes
);
16 MIXER_STATUS
Open(IN LPWSTR DevicePath
, OUT PHANDLE hDevice
);
17 MIXER_STATUS
Control(IN HANDLE hMixer
, IN ULONG dwIoControlCode
, IN PVOID lpInBuffer
, IN ULONG nInBufferSize
, OUT PVOID lpOutBuffer
, ULONG nOutBufferSize
, PULONG lpBytesReturned
);
18 MIXER_STATUS
Enum(IN PVOID EnumContext
, IN ULONG DeviceIndex
, OUT LPWSTR
* DeviceName
, OUT PHANDLE OutHandle
, OUT PHANDLE OutKey
);
19 MIXER_STATUS
OpenKey(IN HANDLE hKey
, IN LPWSTR SubKey
, IN ULONG DesiredAccess
, OUT PHANDLE OutKey
);
20 MIXER_STATUS
CloseKey(IN HANDLE hKey
);
21 MIXER_STATUS
QueryKeyValue(IN HANDLE hKey
, IN LPWSTR KeyName
, OUT PVOID
* ResultBuffer
, OUT PULONG ResultLength
, OUT PULONG KeyType
);
22 PVOID
AllocEventData(IN ULONG ExtraSize
);
23 VOID
FreeEventData(IN PVOID EventData
);
25 MIXER_CONTEXT MixerContext
=
27 sizeof(MIXER_CONTEXT
),
42 GUID CategoryGuid
= {STATIC_KSCATEGORY_AUDIO
};
48 OUT PVOID
* ResultBuffer
,
49 OUT PULONG ResultLength
,
53 UNICODE_STRING KeyName
;
55 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
57 /* initialize key name */
58 RtlInitUnicodeString(&KeyName
, lpKeyName
);
60 /* now query MatchingDeviceId key */
61 Status
= ZwQueryValueKey(hKey
, &KeyName
, KeyValuePartialInformation
, NULL
, 0, &Length
);
63 /* check for success */
64 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
65 return MM_STATUS_UNSUCCESSFUL
;
67 /* allocate a buffer for key data */
68 PartialInformation
= AllocateItem(NonPagedPool
, Length
);
70 if (!PartialInformation
)
71 return MM_STATUS_NO_MEMORY
;
74 /* now query MatchingDeviceId key */
75 Status
= ZwQueryValueKey(hKey
, &KeyName
, KeyValuePartialInformation
, PartialInformation
, Length
, &Length
);
77 /* check for success */
78 if (!NT_SUCCESS(Status
))
80 FreeItem(PartialInformation
);
81 return MM_STATUS_UNSUCCESSFUL
;
87 *KeyType
= PartialInformation
->Type
;
92 /* return data length */
93 *ResultLength
= PartialInformation
->DataLength
;
96 *ResultBuffer
= AllocateItem(NonPagedPool
, PartialInformation
->DataLength
);
99 /* not enough memory */
100 FreeItem(PartialInformation
);
101 return MM_STATUS_NO_MEMORY
;
105 RtlMoveMemory(*ResultBuffer
, PartialInformation
->Data
, PartialInformation
->DataLength
);
108 FreeItem(PartialInformation
);
110 return MM_STATUS_SUCCESS
;
116 IN LPWSTR lpSubKeyName
,
117 IN ULONG DesiredAccess
,
120 OBJECT_ATTRIBUTES ObjectAttributes
;
121 UNICODE_STRING SubKeyName
;
124 /* initialize sub key name */
125 RtlInitUnicodeString(&SubKeyName
, lpSubKeyName
);
127 /* initialize key attributes */
128 InitializeObjectAttributes(&ObjectAttributes
, &SubKeyName
, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, hKey
, NULL
);
131 Status
= ZwOpenKey(OutKey
, DesiredAccess
, &ObjectAttributes
);
133 if (NT_SUCCESS(Status
))
134 return MM_STATUS_SUCCESS
;
136 return MM_STATUS_UNSUCCESSFUL
;
143 if (ZwClose(hKey
) == STATUS_SUCCESS
)
144 return MM_STATUS_SUCCESS
;
146 return MM_STATUS_UNSUCCESSFUL
;
150 PVOID
Alloc(ULONG NumBytes
)
152 return AllocateItem(NonPagedPool
, NumBytes
);
156 Close(HANDLE hDevice
)
158 if (ZwClose(hDevice
) == STATUS_SUCCESS
)
159 return MM_STATUS_SUCCESS
;
161 return MM_STATUS_UNSUCCESSFUL
;
171 Copy(PVOID Src
, PVOID Dst
, ULONG NumBytes
)
173 RtlMoveMemory(Src
, Dst
, NumBytes
);
178 IN LPWSTR DevicePath
,
181 if (WdmAudOpenSysAudioDevice(DevicePath
, hDevice
) == STATUS_SUCCESS
)
182 return MM_STATUS_SUCCESS
;
184 return MM_STATUS_UNSUCCESSFUL
;
190 IN ULONG dwIoControlCode
,
192 IN ULONG nInBufferSize
,
193 OUT PVOID lpOutBuffer
,
194 ULONG nOutBufferSize
,
195 PULONG lpBytesReturned
)
198 PFILE_OBJECT FileObject
;
200 /* get file object */
201 Status
= ObReferenceObjectByHandle(hMixer
, GENERIC_READ
| GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
202 if (!NT_SUCCESS(Status
))
204 DPRINT("failed to reference %p with %lx\n", hMixer
, Status
);
205 return MM_STATUS_UNSUCCESSFUL
;
208 /* perform request */
209 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, dwIoControlCode
, lpInBuffer
, nInBufferSize
, lpOutBuffer
, nOutBufferSize
, lpBytesReturned
);
211 /* release object reference */
212 ObDereferenceObject(FileObject
);
214 if (Status
== STATUS_MORE_ENTRIES
|| Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
216 /* more data is available */
217 return MM_STATUS_MORE_ENTRIES
;
219 else if (Status
== STATUS_SUCCESS
)
221 /* operation succeeded */
222 return MM_STATUS_SUCCESS
;
226 DPRINT("Failed with %lx\n", Status
);
227 return MM_STATUS_UNSUCCESSFUL
;
233 IN PVOID EnumContext
,
234 IN ULONG DeviceIndex
,
235 OUT LPWSTR
* DeviceName
,
236 OUT PHANDLE OutHandle
,
239 PDEVICE_OBJECT DeviceObject
;
242 UNICODE_STRING KeyName
;
244 /* get enumeration context */
245 DeviceObject
= (PDEVICE_OBJECT
)EnumContext
;
247 /* get device count */
248 DeviceCount
= GetSysAudioDeviceCount(DeviceObject
);
250 if (DeviceIndex
>= DeviceCount
)
252 /* no more devices */
253 return MM_STATUS_NO_MORE_DEVICES
;
256 /* get device name */
257 Status
= GetSysAudioDevicePnpName(DeviceObject
, DeviceIndex
, DeviceName
);
259 if (!NT_SUCCESS(Status
))
261 /* failed to retrieve device name */
262 return MM_STATUS_UNSUCCESSFUL
;
265 /* intialize key name */
266 RtlInitUnicodeString(&KeyName
, *DeviceName
);
268 /* open device interface key */
269 Status
= IoOpenDeviceInterfaceRegistryKey(&KeyName
, GENERIC_READ
| GENERIC_WRITE
, OutKey
);
271 if (!NT_SUCCESS(Status
))
273 /* failed to open key */
274 DPRINT("IoOpenDeviceInterfaceRegistryKey failed with %lx\n", Status
);
275 FreeItem(*DeviceName
);
276 return MM_STATUS_UNSUCCESSFUL
;
280 /* open device handle */
281 Status
= OpenDevice(*DeviceName
, OutHandle
, NULL
);
282 if (!NT_SUCCESS(Status
))
284 /* failed to open device */
285 return MM_STATUS_UNSUCCESSFUL
;
288 return MM_STATUS_SUCCESS
;
295 PKSEVENTDATA Data
= (PKSEVENTDATA
)AllocateItem(NonPagedPool
, sizeof(KSEVENTDATA
) + ExtraSize
);
299 Data
->EventObject
.Event
= AllocateItem(NonPagedPool
, sizeof(KEVENT
));
300 if (!Data
->EventHandle
.Event
)
306 KeInitializeEvent(Data
->EventObject
.Event
, NotificationEvent
, FALSE
);
308 Data
->NotificationType
= KSEVENTF_EVENT_HANDLE
;
313 FreeEventData(IN PVOID EventData
)
315 PKSEVENTDATA Data
= (PKSEVENTDATA
)EventData
;
317 FreeItem(Data
->EventHandle
.Event
);
324 IN PVOID MixerEventContext
,
326 IN ULONG NotificationType
,
329 PWDMAUD_CLIENT ClientInfo
;
333 /* get client context */
334 ClientInfo
= (PWDMAUD_CLIENT
)MixerEventContext
;
336 /* now search for the mixer which originated the request */
337 for(Index
= 0; Index
< ClientInfo
->NumPins
; Index
++)
339 if (ClientInfo
->hPins
[Index
].Handle
== hMixer
&& ClientInfo
->hPins
[Index
].Type
== MIXER_DEVICE_TYPE
)
341 if (ClientInfo
->hPins
[Index
].NotifyEvent
)
343 /* allocate event entry */
344 Entry
= AllocateItem(NonPagedPool
, sizeof(EVENT_ENTRY
));
351 /* setup event entry */
352 Entry
->NotificationType
= NotificationType
;
353 Entry
->Value
= Value
;
354 Entry
->hMixer
= hMixer
;
357 InsertTailList(&ClientInfo
->MixerEventList
, &Entry
->Entry
);
359 /* now notify the client */
360 KeSetEvent(ClientInfo
->hPins
[Index
].NotifyEvent
, 0, FALSE
);
370 WdmAudMixerInitialize(
371 IN PDEVICE_OBJECT DeviceObject
)
375 /* initialize the mixer library */
376 Status
= MMixerInitialize(&MixerContext
, Enum
, (PVOID
)DeviceObject
);
378 if (Status
!= MM_STATUS_SUCCESS
)
380 /* failed to initialize mmixer library */
381 DPRINT("MMixerInitialize failed with %lx\n", Status
);
388 WdmAudMixerCapabilities(
389 IN PDEVICE_OBJECT DeviceObject
,
390 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
391 IN PWDMAUD_CLIENT ClientInfo
,
392 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
394 if (MMixerGetCapabilities(&MixerContext
, DeviceInfo
->DeviceIndex
, &DeviceInfo
->u
.MixCaps
) == MM_STATUS_SUCCESS
)
395 return STATUS_SUCCESS
;
397 return STATUS_INVALID_PARAMETER
;
401 WdmAudControlOpenMixer(
402 IN PDEVICE_OBJECT DeviceObject
,
404 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
405 IN PWDMAUD_CLIENT ClientInfo
)
408 PWDMAUD_HANDLE Handles
;
409 //PWDMAUD_DEVICE_EXTENSION DeviceExtension;
411 PKEVENT EventObject
= NULL
;
413 DPRINT("WdmAudControlOpenMixer\n");
415 //DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
417 if (DeviceInfo
->u
.hNotifyEvent
)
419 Status
= ObReferenceObjectByHandle(DeviceInfo
->u
.hNotifyEvent
, EVENT_MODIFY_STATE
, ExEventObjectType
, UserMode
, (LPVOID
*)&EventObject
, NULL
);
421 if (!NT_SUCCESS(Status
))
423 DPRINT1("Invalid notify event passed %p from client %p\n", DeviceInfo
->u
.hNotifyEvent
, ClientInfo
);
425 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
429 if (MMixerOpen(&MixerContext
, DeviceInfo
->DeviceIndex
, ClientInfo
, EventCallback
, &hMixer
) != MM_STATUS_SUCCESS
)
431 ObDereferenceObject(EventObject
);
432 DPRINT1("Failed to open mixer\n");
433 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
437 Handles
= AllocateItem(NonPagedPool
, sizeof(WDMAUD_HANDLE
) * (ClientInfo
->NumPins
+1));
441 if (ClientInfo
->NumPins
)
443 RtlMoveMemory(Handles
, ClientInfo
->hPins
, sizeof(WDMAUD_HANDLE
) * ClientInfo
->NumPins
);
444 FreeItem(ClientInfo
->hPins
);
447 ClientInfo
->hPins
= Handles
;
448 ClientInfo
->hPins
[ClientInfo
->NumPins
].Handle
= hMixer
;
449 ClientInfo
->hPins
[ClientInfo
->NumPins
].Type
= MIXER_DEVICE_TYPE
;
450 ClientInfo
->hPins
[ClientInfo
->NumPins
].NotifyEvent
= EventObject
;
451 ClientInfo
->NumPins
++;
455 ObDereferenceObject(EventObject
);
456 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, sizeof(WDMAUD_DEVICE_INFO
));
459 DeviceInfo
->hDevice
= hMixer
;
461 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
466 WdmAudGetControlDetails(
467 IN PDEVICE_OBJECT DeviceObject
,
469 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
470 IN PWDMAUD_CLIENT ClientInfo
)
474 /* clear hmixer type flag */
475 DeviceInfo
->Flags
&= ~MIXER_OBJECTF_HMIXER
;
477 /* query mmixer library */
478 Status
= MMixerGetControlDetails(&MixerContext
, DeviceInfo
->hDevice
, DeviceInfo
->DeviceIndex
, DeviceInfo
->Flags
, &DeviceInfo
->u
.MixDetails
);
480 if (Status
== MM_STATUS_SUCCESS
)
481 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
483 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, sizeof(WDMAUD_DEVICE_INFO
));
489 IN PDEVICE_OBJECT DeviceObject
,
491 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
492 IN PWDMAUD_CLIENT ClientInfo
)
496 /* clear hmixer type flag */
497 DeviceInfo
->Flags
&= ~MIXER_OBJECTF_HMIXER
;
499 /* query mixer library */
500 Status
= MMixerGetLineInfo(&MixerContext
, DeviceInfo
->hDevice
, DeviceInfo
->DeviceIndex
, DeviceInfo
->Flags
, &DeviceInfo
->u
.MixLine
);
502 if (Status
== MM_STATUS_SUCCESS
)
503 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
505 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, sizeof(WDMAUD_DEVICE_INFO
));
510 WdmAudGetLineControls(
511 IN PDEVICE_OBJECT DeviceObject
,
513 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
514 IN PWDMAUD_CLIENT ClientInfo
)
518 /* clear hmixer type flag */
519 DeviceInfo
->Flags
&= ~MIXER_OBJECTF_HMIXER
;
521 /* query mixer library */
522 Status
= MMixerGetLineControls(&MixerContext
, DeviceInfo
->hDevice
, DeviceInfo
->DeviceIndex
, DeviceInfo
->Flags
, &DeviceInfo
->u
.MixControls
);
524 if (Status
== MM_STATUS_SUCCESS
)
525 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
527 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, sizeof(WDMAUD_DEVICE_INFO
));
534 WdmAudSetControlDetails(
535 IN PDEVICE_OBJECT DeviceObject
,
537 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
538 IN PWDMAUD_CLIENT ClientInfo
)
542 /* clear hmixer type flag */
543 DeviceInfo
->Flags
&= ~MIXER_OBJECTF_HMIXER
;
545 /* query mixer library */
546 Status
= MMixerSetControlDetails(&MixerContext
, DeviceInfo
->hDevice
, DeviceInfo
->DeviceIndex
, DeviceInfo
->Flags
, &DeviceInfo
->u
.MixDetails
);
548 if (Status
== MM_STATUS_SUCCESS
)
549 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
551 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, sizeof(WDMAUD_DEVICE_INFO
));
557 IN PDEVICE_OBJECT DeviceObject
,
559 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
560 IN PWDMAUD_CLIENT ClientInfo
)
563 PEVENT_ENTRY EventEntry
;
565 /* enumerate event list and check if there is a new event */
566 Entry
= ClientInfo
->MixerEventList
.Flink
;
568 while(Entry
!= &ClientInfo
->MixerEventList
)
570 /* grab event entry */
571 EventEntry
= (PEVENT_ENTRY
)CONTAINING_RECORD(Entry
, EVENT_ENTRY
, Entry
);
573 if (EventEntry
->hMixer
== DeviceInfo
->hDevice
)
576 DeviceInfo
->u
.MixerEvent
.hMixer
= EventEntry
->hMixer
;
577 DeviceInfo
->u
.MixerEvent
.NotificationType
= EventEntry
->NotificationType
;
578 DeviceInfo
->u
.MixerEvent
.Value
= EventEntry
->Value
;
580 /* remove entry from list */
581 RemoveEntryList(&EventEntry
->Entry
);
583 /* free event entry */
584 FreeItem(EventEntry
);
587 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
591 Entry
= Entry
->Flink
;
594 /* no event entry available */
595 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, sizeof(WDMAUD_DEVICE_INFO
));
599 WdmAudGetMixerDeviceCount()
601 return MMixerGetCount(&MixerContext
);
605 WdmAudGetWaveInDeviceCount()
607 return MMixerGetWaveInCount(&MixerContext
);
611 WdmAudGetWaveOutDeviceCount()
613 return MMixerGetWaveOutCount(&MixerContext
);
617 WdmAudGetMidiInDeviceCount()
619 return MMixerGetMidiInCount(&MixerContext
);
623 WdmAudGetMidiOutDeviceCount()
625 return MMixerGetWaveOutCount(&MixerContext
);
629 WdmAudGetPnpNameByIndexAndType(
630 IN ULONG DeviceIndex
,
631 IN SOUND_DEVICE_TYPE DeviceType
,
632 OUT LPWSTR
*DevicePath
)
634 if (DeviceType
== WAVE_IN_DEVICE_TYPE
|| DeviceType
== WAVE_OUT_DEVICE_TYPE
)
636 if (MMixerGetWaveDevicePath(&MixerContext
, DeviceType
== WAVE_IN_DEVICE_TYPE
, DeviceIndex
, DevicePath
) == MM_STATUS_SUCCESS
)
637 return STATUS_SUCCESS
;
639 return STATUS_UNSUCCESSFUL
;
641 else if (DeviceType
== MIDI_IN_DEVICE_TYPE
|| DeviceType
== MIDI_OUT_DEVICE_TYPE
)
643 if (MMixerGetMidiDevicePath(&MixerContext
, DeviceType
== MIDI_IN_DEVICE_TYPE
, DeviceIndex
, DevicePath
) == MM_STATUS_SUCCESS
)
644 return STATUS_SUCCESS
;
646 return STATUS_UNSUCCESSFUL
;
648 else if (DeviceType
== MIXER_DEVICE_TYPE
)
653 return STATUS_UNSUCCESSFUL
;
657 WdmAudWaveCapabilities(
658 IN PDEVICE_OBJECT DeviceObject
,
659 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
660 IN PWDMAUD_CLIENT ClientInfo
,
661 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
663 MIXER_STATUS Status
= MM_STATUS_UNSUCCESSFUL
;
665 if (DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
)
667 /* get capabilities */
668 Status
= MMixerWaveInCapabilities(&MixerContext
, DeviceInfo
->DeviceIndex
, &DeviceInfo
->u
.WaveInCaps
);
670 else if (DeviceInfo
->DeviceType
== WAVE_OUT_DEVICE_TYPE
)
672 /* get capabilities */
673 Status
= MMixerWaveOutCapabilities(&MixerContext
, DeviceInfo
->DeviceIndex
, &DeviceInfo
->u
.WaveOutCaps
);
676 if (Status
== MM_STATUS_SUCCESS
)
677 return STATUS_SUCCESS
;
683 WdmAudMidiCapabilities(
684 IN PDEVICE_OBJECT DeviceObject
,
685 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
686 IN PWDMAUD_CLIENT ClientInfo
,
687 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
689 MIXER_STATUS Status
= MM_STATUS_UNSUCCESSFUL
;
691 if (DeviceInfo
->DeviceType
== MIDI_IN_DEVICE_TYPE
)
693 /* get capabilities */
694 Status
= MMixerMidiInCapabilities(&MixerContext
, DeviceInfo
->DeviceIndex
, &DeviceInfo
->u
.MidiInCaps
);
696 else if (DeviceInfo
->DeviceType
== WAVE_OUT_DEVICE_TYPE
)
698 /* get capabilities */
699 Status
= MMixerMidiOutCapabilities(&MixerContext
, DeviceInfo
->DeviceIndex
, &DeviceInfo
->u
.MidiOutCaps
);
702 if (Status
== MM_STATUS_SUCCESS
)
703 return STATUS_SUCCESS
;
705 return STATUS_UNSUCCESSFUL
;
712 IN ULONG VirtualDeviceId
,
715 IN PKSPIN_CONNECT PinConnect
,
716 IN ACCESS_MASK DesiredAccess
,
717 OUT PHANDLE PinHandle
)
720 SYSAUDIO_INSTANCE_INFO InstanceInfo
;
723 PPIN_CREATE_CONTEXT Context
= (PPIN_CREATE_CONTEXT
)Ctx
;
725 /* setup property request */
726 InstanceInfo
.Property
.Set
= KSPROPSETID_Sysaudio
;
727 InstanceInfo
.Property
.Id
= KSPROPERTY_SYSAUDIO_INSTANCE_INFO
;
728 InstanceInfo
.Property
.Flags
= KSPROPERTY_TYPE_SET
;
729 InstanceInfo
.Flags
= 0;
730 InstanceInfo
.DeviceNumber
= VirtualDeviceId
;
732 /* attach to virtual device */
733 Status
= KsSynchronousIoControlDevice(Context
->DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&InstanceInfo
, sizeof(SYSAUDIO_INSTANCE_INFO
), NULL
, 0, &BytesReturned
);
735 if (!NT_SUCCESS(Status
))
736 return MM_STATUS_UNSUCCESSFUL
;
738 /* close existing pin */
739 FreeIndex
= ClosePin(Context
->ClientInfo
, VirtualDeviceId
, PinId
, Context
->DeviceType
);
741 /* now create the pin */
742 Status
= KsCreatePin(Context
->DeviceExtension
->hSysAudio
, PinConnect
, DesiredAccess
, PinHandle
);
744 /* check for success */
745 if (!NT_SUCCESS(Status
))
746 return MM_STATUS_UNSUCCESSFUL
;
748 /* store the handle */
749 Status
= InsertPinHandle(Context
->ClientInfo
, VirtualDeviceId
, PinId
, Context
->DeviceType
, *PinHandle
, FreeIndex
);
750 if (!NT_SUCCESS(Status
))
752 /* failed to insert handle */
754 return MM_STATUS_UNSUCCESSFUL
;
757 return MM_STATUS_SUCCESS
;
761 WdmAudControlOpenWave(
762 IN PDEVICE_OBJECT DeviceObject
,
764 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
765 IN PWDMAUD_CLIENT ClientInfo
)
768 PIN_CREATE_CONTEXT Context
;
770 Context
.ClientInfo
= ClientInfo
;
771 Context
.DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
772 Context
.DeviceType
= DeviceInfo
->DeviceType
;
774 Status
= MMixerOpenWave(&MixerContext
, DeviceInfo
->DeviceIndex
, DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
, &DeviceInfo
->u
.WaveFormatEx
, CreatePinCallback
, &Context
, &DeviceInfo
->hDevice
);
776 if (Status
== MM_STATUS_SUCCESS
)
777 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
779 return SetIrpIoStatus(Irp
, STATUS_NOT_SUPPORTED
, sizeof(WDMAUD_DEVICE_INFO
));
783 WdmAudControlOpenMidi(
784 IN PDEVICE_OBJECT DeviceObject
,
786 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
787 IN PWDMAUD_CLIENT ClientInfo
)
790 PIN_CREATE_CONTEXT Context
;
792 Context
.ClientInfo
= ClientInfo
;
793 Context
.DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
794 Context
.DeviceType
= DeviceInfo
->DeviceType
;
796 Status
= MMixerOpenMidi(&MixerContext
, DeviceInfo
->DeviceIndex
, DeviceInfo
->DeviceType
== MIDI_IN_DEVICE_TYPE
, CreatePinCallback
, &Context
, &DeviceInfo
->hDevice
);
798 if (Status
== MM_STATUS_SUCCESS
)
799 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
801 return SetIrpIoStatus(Irp
, STATUS_NOT_SUPPORTED
, sizeof(WDMAUD_DEVICE_INFO
));