10 MIXER_CONTEXT MixerContext
;
11 GUID CategoryGuid
= {STATIC_KSCATEGORY_AUDIO
};
13 PVOID
Alloc(ULONG NumBytes
)
15 //printf("Alloc: %lu\n", NumBytes);
16 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, NumBytes
);
22 //printf("Close: Handle %p\n", hDevice);
23 if (CloseHandle(hDevice
))
24 return MM_STATUS_SUCCESS
;
26 return MM_STATUS_UNSUCCESSFUL
;
32 //printf("Free: %p\n", Block);
33 HeapFree(GetProcessHeap(), 0, Block
);
37 Copy(PVOID Src
, PVOID Dst
, ULONG NumBytes
)
39 //printf("Copy: Src %p Dst %p NumBytes %lu\n", Src, Dst, NumBytes);
40 CopyMemory(Src
, Dst
, NumBytes
);
48 DevicePath
[1] = L
'\\';
49 *hDevice
= CreateFileW(DevicePath
,
50 GENERIC_READ
| GENERIC_WRITE
,
56 if (*hDevice
== INVALID_HANDLE_VALUE
)
58 //wprintf(L" Failed to open %s Error %lu\n", DevicePath, GetLastError());
59 return MM_STATUS_UNSUCCESSFUL
;
61 wprintf(L
"Open: %s hDevice %p\n", DevicePath
, *hDevice
);
63 return MM_STATUS_SUCCESS
;
69 IN ULONG dwIoControlCode
,
71 IN ULONG nInBufferSize
,
72 OUT PVOID lpOutBuffer
,
74 PULONG lpBytesReturned
)
76 OVERLAPPED Overlapped
;
78 DWORD Transferred
= 0;
80 //printf("hMixer %p dwIoControlCode %lx lpInBuffer %p nInBufferSize %lu lpOutBuffer %p nOutBufferSize %lu lpBytesReturned %p\n",
81 // hMixer, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned);
83 /* Overlapped I/O is done here - this is used for waiting for completion */
84 ZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
85 Overlapped
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
87 if ( ! Overlapped
.hEvent
)
88 return MM_STATUS_NO_MEMORY
;
90 /* Talk to the device */
91 IoResult
= DeviceIoControl(hMixer
,
100 /* If failure occurs, make sure it's not just due to the overlapped I/O */
103 if ( GetLastError() != ERROR_IO_PENDING
)
105 CloseHandle(Overlapped
.hEvent
);
107 //printf("Control: Failed with %lu Transferred %lu\n", GetLastError(), Transferred);
109 if (GetLastError() == ERROR_MORE_DATA
|| GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
111 if ( lpBytesReturned
)
112 *lpBytesReturned
= Transferred
;
113 return MM_STATUS_MORE_ENTRIES
;
116 return MM_STATUS_UNSUCCESSFUL
;
120 /* Wait for the I/O to complete */
121 IoResult
= GetOverlappedResult(hMixer
,
126 /* Don't need this any more */
127 CloseHandle(Overlapped
.hEvent
);
130 return MM_STATUS_UNSUCCESSFUL
;
132 //printf("Transferred %lu bytes in Sync overlapped I/O\n", Transferred);
134 if ( lpBytesReturned
)
135 *lpBytesReturned
= Transferred
;
137 return MM_STATUS_SUCCESS
;
142 IN PVOID EnumContext
,
143 IN ULONG DeviceIndex
,
144 OUT LPWSTR
* DeviceName
,
145 OUT PHANDLE OutHandle
)
147 SP_DEVICE_INTERFACE_DATA InterfaceData
;
148 SP_DEVINFO_DATA DeviceData
;
149 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData
;
153 //printf("Enum EnumContext %p DeviceIndex %lu OutHandle %p\n", EnumContext, DeviceIndex, OutHandle);
155 InterfaceData
.cbSize
= sizeof(InterfaceData
);
156 InterfaceData
.Reserved
= 0;
158 Result
= SetupDiEnumDeviceInterfaces(EnumContext
,
166 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
168 printf("LastDevice\n");
169 return MM_STATUS_NO_MORE_DEVICES
;
171 printf("SetupDiEnumDeviceInterfaces failed with %lu\n", GetLastError());
172 return MM_STATUS_UNSUCCESSFUL
;
175 Length
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
) + MAX_PATH
* sizeof(WCHAR
);
176 DetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA_W
)HeapAlloc(GetProcessHeap(),
179 DetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
);
180 DeviceData
.cbSize
= sizeof(DeviceData
);
181 DeviceData
.Reserved
= 0;
183 Result
= SetupDiGetDeviceInterfaceDetailW(EnumContext
,
192 printf("SetupDiGetDeviceInterfaceDetailW failed with %lu\n", GetLastError());
193 return MM_STATUS_UNSUCCESSFUL
;
197 *DeviceName
= (LPWSTR
)&DetailData
->DevicePath
[0];
198 return Open(DetailData
->DevicePath
, OutHandle
);
202 int main(int argc
, char**argv
)
205 HDEVINFO DeviceHandle
;
206 MIXERCAPSW MixCaps1
, MixCaps2
;
207 ULONG Index
, SubIndex
;
210 MIXERLINEW MixerLine1
, MixerLine2
;
211 MIXERLINECONTROLS Controls1
, Controls2
;
213 ZeroMemory(&MixerContext
, sizeof(MIXER_CONTEXT
));
215 DeviceHandle
= SetupDiGetClassDevs(&CategoryGuid
,
218 DIGCF_DEVICEINTERFACE
|DIGCF_PRESENT
);
219 if (DeviceHandle
== INVALID_HANDLE_VALUE
)
221 printf("SetupDiGetClassDevs failed with %lx\n", GetLastError());
225 printf("DeviceHandle %p\n", DeviceHandle
);
227 MixerContext
.SizeOfStruct
= sizeof(MIXER_CONTEXT
);
228 MixerContext
.Alloc
= Alloc
;
229 MixerContext
.Close
= Close
;
230 MixerContext
.Control
= Control
;
231 MixerContext
.Copy
= Copy
;
232 MixerContext
.Free
= Free
;
233 MixerContext
.Open
= Open
;
235 Status
= MMixerInitialize(&MixerContext
, Enum
, (PVOID
)DeviceHandle
);
237 printf("Status %x\n", Status
);
238 printf("NumberOfMixers %lu mixerGetNumDevs %u\n", MMixerGetCount(&MixerContext
), mixerGetNumDevs());
240 for(Index
= 0; Index
< MMixerGetCount(&MixerContext
); Index
++)
242 mixerGetDevCapsW(Index
, &MixCaps1
, sizeof(MIXERCAPSW
));
243 wprintf(L
"WINM: cDestination %u fdwSupport %lx szPname %s vDriverVersion %u wMid %x wPid %x\n", MixCaps1
.cDestinations
, MixCaps1
.fdwSupport
, MixCaps1
.szPname
, MixCaps1
.vDriverVersion
, MixCaps1
.wMid
, MixCaps1
.wPid
);
244 MMixerGetCapabilities(&MixerContext
, Index
, &MixCaps2
);
245 wprintf(L
"MMIX: cDestination %u fdwSupport %lx szPname %s vDriverVersion %u wMid %x wPid %x\n", MixCaps2
.cDestinations
, MixCaps2
.fdwSupport
, MixCaps2
.szPname
, MixCaps2
.vDriverVersion
, MixCaps2
.wMid
, MixCaps2
.wPid
);
247 mixerOpen(&hMixer1
, Index
, 0, 0, MIXER_OBJECTF_HMIXER
);
248 MMixerOpen(&MixerContext
, Index
, NULL
, NULL
, &hMixer2
);
250 ZeroMemory(&MixerLine1
, sizeof(MIXERLINEW
));
251 ZeroMemory(&MixerLine2
, sizeof(MIXERLINEW
));
252 MixerLine1
.cbStruct
= sizeof(MIXERLINEW
);
253 MixerLine2
.cbStruct
= sizeof(MIXERLINEW
);
254 mixerGetLineInfoW((HMIXEROBJ
)hMixer1
, &MixerLine1
, MIXER_GETLINEINFOF_DESTINATION
);
255 MMixerGetLineInfo(&MixerContext
, hMixer2
, MIXER_GETLINEINFOF_DESTINATION
, &MixerLine2
);
257 wprintf(L
"WINM: dwDestination %lx dwSource %lx dwLineID %lx dwUser %lx dwComponentType %lx cChannels %lx cConnections %lx cControls %lx szShortName %s szName %s\n\n",
258 MixerLine1
.dwDestination
, MixerLine1
.dwSource
, MixerLine1
.dwLineID
, MixerLine1
.dwUser
, MixerLine1
.dwComponentType
, MixerLine1
.cChannels
, MixerLine1
.cConnections
, MixerLine1
.cControls
, MixerLine1
.szShortName
, MixerLine1
.szName
);
260 wprintf(L
"MMIX: dwDestination %lx dwSource %lx dwLineID %lx dwUser %lx dwComponentType %lx cChannels %lx cConnections %lx cControls %lx szShortName %s szName %s\n\n",
261 MixerLine2
.dwDestination
, MixerLine2
.dwSource
, MixerLine2
.dwLineID
, MixerLine2
.dwUser
, MixerLine2
.dwComponentType
, MixerLine2
.cChannels
, MixerLine2
.cConnections
, MixerLine2
.cControls
, MixerLine2
.szShortName
, MixerLine2
.szName
);
263 Controls1
.cbStruct
= sizeof(MIXERLINECONTROLS
);
264 Controls2
.cbStruct
= sizeof(MIXERLINECONTROLS
);
266 Controls1
.cbmxctrl
= sizeof(MIXERCONTROL
);
267 Controls2
.cbmxctrl
= sizeof(MIXERCONTROL
);
269 Controls1
.cControls
= MixerLine1
.cControls
;
270 Controls2
.cControls
= MixerLine2
.cControls
;
272 Controls1
.dwLineID
= MixerLine1
.dwLineID
;
273 Controls2
.dwLineID
= MixerLine2
.dwLineID
;
277 Controls1
.pamxctrl
= (LPMIXERCONTROL
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(MIXERCONTROL
) * Controls1
.cControls
);
278 Controls2
.pamxctrl
= (LPMIXERCONTROL
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(MIXERCONTROL
) * Controls2
.cControls
);
280 for(SubIndex
= 0; SubIndex
< Controls1
.cControls
; SubIndex
++)
281 Controls1
.pamxctrl
[SubIndex
].cbStruct
= sizeof(MIXERCONTROL
);
283 for(SubIndex
= 0; SubIndex
< Controls2
.cControls
; SubIndex
++)
284 Controls2
.pamxctrl
[SubIndex
].cbStruct
= sizeof(MIXERCONTROL
);
286 mixerGetLineControls((HMIXEROBJ
)hMixer1
, &Controls1
, MIXER_GETLINECONTROLSF_ALL
);
288 wprintf(L
"----------------------------------------\n");
289 for(SubIndex
= 0; SubIndex
< Controls1
.cControls
; SubIndex
++)
291 wprintf(L
"WINM: Index %d dwControlID %lx dwControlType %lx fdwControl %lx cMultipleItems %lx szName %s szShortName %s \n", SubIndex
, Controls1
.pamxctrl
[SubIndex
].dwControlID
, Controls1
.pamxctrl
[SubIndex
].dwControlType
, Controls1
.pamxctrl
[SubIndex
].fdwControl
, Controls1
.pamxctrl
[SubIndex
].cMultipleItems
, Controls1
.pamxctrl
[SubIndex
].szName
, Controls1
.pamxctrl
[SubIndex
].szShortName
);
293 wprintf(L
"----------------------------------------\n");
296 wprintf(L
"=======================\n");