2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/legacy/wdmaud/mixer.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Andrew Greenwood
12 IsVirtualDeviceATopologyFilter(
13 IN PDEVICE_OBJECT DeviceObject
,
14 ULONG VirtualDeviceId
)
17 ULONG Count
, BytesReturned
, Index
, NumPins
;
19 KSPIN_COMMUNICATION Communication
;
20 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
23 Pin
.Property
.Set
= KSPROPSETID_Sysaudio
;
24 Pin
.Property
.Id
= KSPROPERTY_SYSAUDIO_DEVICE_COUNT
;
25 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
27 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
29 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSPROPERTY
), (PVOID
)&Count
, sizeof(ULONG
), &BytesReturned
);
30 if (!NT_SUCCESS(Status
))
33 if (VirtualDeviceId
>= Count
)
36 /* query number of pins */
37 Pin
.Reserved
= VirtualDeviceId
; // see sysaudio
38 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
39 Pin
.Property
.Set
= KSPROPSETID_Pin
;
40 Pin
.Property
.Id
= KSPROPERTY_PIN_CTYPES
;
43 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&NumPins
, sizeof(ULONG
), &BytesReturned
);
44 if (!NT_SUCCESS(Status
))
47 /* enumerate now all pins */
49 for(Index
= 0; Index
< NumPins
; Index
++)
52 Pin
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
53 Communication
= KSPIN_COMMUNICATION_NONE
;
55 /* get pin communication type */
56 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
57 if (NT_SUCCESS(Status
))
59 if (Communication
== KSPIN_COMMUNICATION_NONE
)
65 if (MixerPinCount
== NumPins
)
67 /* filter has no pins which can be instantiated -> topology filter */
75 GetNumOfMixerPinsFromTopologyFilter(
76 IN PDEVICE_OBJECT DeviceObject
,
77 ULONG VirtualDeviceId
)
80 ULONG BytesReturned
, Index
, NumPins
;
82 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
83 PKSMULTIPLE_ITEM MultipleItem
;
84 PKSTOPOLOGY_CONNECTION Conn
;
87 Pin
.Reserved
= VirtualDeviceId
;
88 Pin
.Property
.Set
= KSPROPSETID_Topology
;
89 Pin
.Property
.Id
= KSPROPERTY_TOPOLOGY_CONNECTIONS
;
90 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
92 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
95 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)NULL
, 0, &BytesReturned
);
97 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
100 MultipleItem
= ExAllocatePool(NonPagedPool
, BytesReturned
);
104 RtlZeroMemory(MultipleItem
, BytesReturned
);
106 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)MultipleItem
, BytesReturned
, &BytesReturned
);
107 if (!NT_SUCCESS(Status
))
109 ExFreePool(MultipleItem
);
113 Conn
= (PKSTOPOLOGY_CONNECTION
)(MultipleItem
+ 1);
115 for (Index
= 0; Index
< MultipleItem
->Count
; Index
++)
117 if (Conn
[Index
].ToNode
== PCFILTER_NODE
)
123 ExFreePool(MultipleItem
);
128 GetNumOfMixerDevices(
129 IN PDEVICE_OBJECT DeviceObject
)
132 ULONG Count
, BytesReturned
, Index
, NumPins
;
134 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
136 Pin
.Property
.Set
= KSPROPSETID_Sysaudio
;
137 Pin
.Property
.Id
= KSPROPERTY_SYSAUDIO_DEVICE_COUNT
;
138 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
140 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
143 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSPROPERTY
), (PVOID
)&Count
, sizeof(ULONG
), &BytesReturned
);
144 if (!NT_SUCCESS(Status
) || !Count
)
148 for(Index
= 0; Index
< Count
; Index
++)
150 if (IsVirtualDeviceATopologyFilter(DeviceObject
, Index
))
152 NumPins
+= GetNumOfMixerPinsFromTopologyFilter(DeviceObject
, Index
);
160 WdmAudControlOpenMixer(
161 IN PDEVICE_OBJECT DeviceObject
,
163 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
164 IN PWDMAUD_CLIENT ClientInfo
)
167 PWDMAUD_HANDLE Handels
;
169 if (DeviceInfo
->DeviceIndex
>= GetNumOfMixerDevices(DeviceObject
))
171 /* mixer index doesnt exist */
172 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
175 for(Index
= 0; Index
< ClientInfo
->NumPins
; Index
++)
177 if (ClientInfo
->hPins
[Index
].Handle
== (HANDLE
)DeviceInfo
->DeviceIndex
&& ClientInfo
->hPins
[Index
].Type
== MIXER_DEVICE_TYPE
)
179 /* re-use pseudo handle */
180 DeviceInfo
->hDevice
= (HANDLE
)DeviceInfo
->DeviceIndex
;
181 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
185 Handels
= ExAllocatePool(NonPagedPool
, sizeof(WDMAUD_HANDLE
) * (ClientInfo
->NumPins
+1));
189 if (ClientInfo
->NumPins
)
191 RtlMoveMemory(Handels
, ClientInfo
->hPins
, sizeof(WDMAUD_HANDLE
) * ClientInfo
->NumPins
);
192 ExFreePool(ClientInfo
->hPins
);
195 ClientInfo
->hPins
= Handels
;
196 ClientInfo
->hPins
[ClientInfo
->NumPins
].Handle
= (HANDLE
)DeviceInfo
->DeviceIndex
;
197 ClientInfo
->hPins
[ClientInfo
->NumPins
].Type
= MIXER_DEVICE_TYPE
;
198 ClientInfo
->NumPins
++;
202 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, sizeof(WDMAUD_DEVICE_INFO
));
204 DeviceInfo
->hDevice
= (HANDLE
)DeviceInfo
->DeviceIndex
;
206 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));