2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of network devices
4 * FILE: dll/directx/dsound_new/devicelist.c
5 * PURPOSE: Enumeration of audio devices
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
20 for(Index
= Offset
; Index
< Filter
->PinCount
; Index
++)
22 if (Filter
->Pin
[Index
] == PIN_TYPE_PLAYBACK
&& !bCapture
)
25 if (Filter
->Pin
[Index
] == PIN_TYPE_RECORDING
&& bCapture
)
34 IN LPGUID InterfaceGuid
,
35 OUT HDEVINFO
* OutHandle
)
37 HDEVINFO DeviceHandle
;
39 DeviceHandle
= SetupDiGetClassDevs(InterfaceGuid
,
42 DIGCF_DEVICEINTERFACE
); //DIGCF_PRESENT
44 /* check for success */
45 if (DeviceHandle
== INVALID_HANDLE_VALUE
)
47 /* failed to create device list */
48 return GetLastError();
52 *OutHandle
= DeviceHandle
;
61 return SetupDiDestroyDeviceInfoList(Handle
);
65 GetDeviceListInterfaces(
66 HDEVINFO DeviceHandle
,
67 IN LPGUID InterfaceGuid
,
68 LPFILTERINFO
*OutPath
)
70 ULONG Length
, Index
= 0;
71 SP_DEVICE_INTERFACE_DATA InterfaceData
;
72 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData
;
73 SP_DEVINFO_DATA DeviceData
;
74 LPFILTERINFO LastDevice
= NULL
, RootDevice
= NULL
, CurDevice
;
80 InterfaceData
.cbSize
= sizeof(InterfaceData
);
81 InterfaceData
.Reserved
= 0;
83 /* query device interface */
84 Result
= SetupDiEnumDeviceInterfaces(DeviceHandle
,
93 DPRINT("SetupDiEnumDeviceInterfaces Index %u failed with %lx\n", Index
, GetLastError());
97 /* allocate device interface struct */
98 Length
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
) + MAX_PATH
* sizeof(WCHAR
);
99 DetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA_W
)HeapAlloc(GetProcessHeap(),
105 /* insufficient memory */
109 /* initialize device interface detail struct */
110 DetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
);
112 DeviceData
.cbSize
= sizeof(DeviceData
);
113 DeviceData
.Reserved
= 0;
115 Result
= SetupDiGetDeviceInterfaceDetailW(DeviceHandle
,
125 DPRINT("SetupDiGetDeviceInterfaceDetail failed with %x\n", GetLastError());
126 HeapFree(GetProcessHeap(), 0, DetailData
);
131 /* allocate device path struct */
132 CurDevice
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(FILTERINFO
));
136 HeapFree(GetProcessHeap(), 0, DetailData
);
140 /* store device path */
141 CopyMemory(&CurDevice
->DeviceData
, &DeviceData
, sizeof(SP_DEVINFO_DATA
));
142 wcscpy(CurDevice
->DevicePath
, DetailData
->DevicePath
);
143 CurDevice
->MappedId
[0] = ULONG_MAX
;
144 CurDevice
->MappedId
[1] = ULONG_MAX
;
146 DPRINT("DevicePath %S\n", CurDevice
->DevicePath
);
149 RootDevice
= CurDevice
;
153 LastDevice
->lpNext
= CurDevice
;
156 /* set as last device */
157 LastDevice
= CurDevice
;
159 /* free device interface struct */
160 HeapFree(GetProcessHeap(), 0, DetailData
);
162 /* increment device interface index */
167 *OutPath
= RootDevice
;
179 PSP_DEVINFO_DATA FILTERINFOData
,
181 REGSAM DesiredAccess
,
186 /* try open device registry key */
187 hKey
= SetupDiOpenDevRegKey(Handle
, FILTERINFOData
, DICS_FLAG_CONFIGSPECIFIC
, 0, KeyType
, DesiredAccess
);
189 if (hKey
== INVALID_HANDLE_VALUE
)
190 return GetLastError();
195 return ERROR_SUCCESS
;
200 LPFILTERINFO CurInfo
,
201 OUT PULONG WaveInPins
,
202 OUT PULONG WaveOutPins
)
205 KSPIN_COMMUNICATION Communication
;
206 KSPIN_DATAFLOW DataFlow
;
211 /* traverse all pins */
212 for(Index
= 0; Index
< CurInfo
->PinCount
; Index
++)
214 if (GetFilterPinCommunication(CurInfo
->hFilter
, Index
, &Communication
) == ERROR_SUCCESS
&&
215 GetFilterPinDataFlow(CurInfo
->hFilter
, Index
, &DataFlow
) == ERROR_SUCCESS
)
217 if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_IN
)
219 /* found a wave out device */
220 CurInfo
->Pin
[Index
] = PIN_TYPE_PLAYBACK
;
223 else if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_OUT
)
225 /* found a wave in device */
226 CurInfo
->Pin
[Index
] = PIN_TYPE_RECORDING
;
231 /* bridge pin / topology pin etc */
232 CurInfo
->Pin
[Index
] = PIN_TYPE_NONE
;
237 /* bridge pin / topology pin etc */
238 CurInfo
->Pin
[Index
] = PIN_TYPE_NONE
;
244 FindWinMMDeviceIndex(
245 LPFILTERINFO CurInfo
,
248 ULONG DeviceCount
, Index
;
249 WCHAR Buffer
[MAX_PATH
];
250 DWORD Size
, dwResult
;
253 DeviceCount
= waveInGetNumDevs();
255 DeviceCount
= waveOutGetNumDevs();
258 //ASSERT(DeviceCount);
260 for(Index
= 0; Index
< DeviceCount
; Index
++)
264 /* query device interface size */
266 dwResult
= waveInMessage(UlongToHandle(Index
), DRV_QUERYDEVICEINTERFACESIZE
, (DWORD_PTR
)&Size
, 0);
268 dwResult
= waveOutMessage(UlongToHandle(Index
), DRV_QUERYDEVICEINTERFACESIZE
, (DWORD_PTR
)&Size
, 0);
270 if (dwResult
!= MMSYSERR_NOERROR
)
272 DPRINT("Failed DRV_QUERYDEVICEINTERFACESIZE with %lx bRecord %u Index %u\n", dwResult
, bRecord
, Index
);
277 ASSERT(Size
< MAX_PATH
);
279 /* now get the device interface string */
281 dwResult
= waveInMessage(UlongToHandle(Index
), DRV_QUERYDEVICEINTERFACE
, (DWORD_PTR
)Buffer
, MAX_PATH
);
283 dwResult
= waveOutMessage(UlongToHandle(Index
), DRV_QUERYDEVICEINTERFACE
, (DWORD_PTR
)Buffer
, MAX_PATH
);
285 if (dwResult
!= MMSYSERR_NOERROR
)
287 DPRINT("Failed DRV_QUERYDEVICEINTERFACE with %lx bRecord %u Index %u\n", dwResult
, bRecord
, Index
);
291 if (!wcsicmp(CurInfo
->DevicePath
, Buffer
))
294 CurInfo
->MappedId
[0] = Index
;
296 CurInfo
->MappedId
[1] = Index
;
302 DPRINT1("Failed to find device %ws bRecord %u Count %u\n", CurInfo
->DevicePath
, bRecord
, DeviceCount
);
306 CurInfo
->MappedId
[0] = 0;
308 CurInfo
->MappedId
[1] = 0;
315 EnumerateAudioFilter(
316 LPFILTERINFO CurInfo
,
317 OUT PULONG WaveInCount
,
318 OUT PULONG WaveOutCount
)
321 ULONG PinCount
, WaveInPins
, WaveOutPins
;
323 /* first step open filter */
324 Status
= OpenFilter((LPCWSTR
)CurInfo
->DevicePath
, &CurInfo
->hFilter
);
325 if (Status
!= ERROR_SUCCESS
)
327 DPRINT("Failed to open filter with %lx Path %ws\n", Status
, CurInfo
->DevicePath
);
331 /* get filter pin count */
332 Status
= GetFilterPinCount(CurInfo
->hFilter
, &PinCount
);
333 if (Status
!= ERROR_SUCCESS
)
335 DPRINT("Failed to get pin count with %lx\n", Status
);
342 /* store pin count */
343 CurInfo
->PinCount
= PinCount
;
345 /* now allocate an pin array */
346 CurInfo
->Pin
= HeapAlloc(GetProcessHeap(), 0, PinCount
* sizeof(ULONG
));
353 /* no try to find playback / recording pins */
354 FindAudioFilterPins(CurInfo
, &WaveInPins
, &WaveOutPins
);
356 DPRINT("WaveInPins %u WaveOutPins %u %S\n", WaveInPins
, WaveOutPins
, CurInfo
->DevicePath
);
360 /* create a unique guid for this playback device */
361 if (FindWinMMDeviceIndex(CurInfo
, TRUE
))
364 INIT_GUID(CurInfo
->DeviceGuid
[0], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveInCount
);
371 if (FindWinMMDeviceIndex(CurInfo
, FALSE
))
373 /* create a unique guid for this record device */
375 INIT_GUID(CurInfo
->DeviceGuid
[1], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveOutCount
);
384 EnumAudioDeviceInterfaces(
385 LPFILTERINFO
*OutRootInfo
)
390 ULONG WaveOutCount
, WaveInCount
;
391 GUID AudioDeviceGuid
= {STATIC_KSCATEGORY_AUDIO
};
392 LPFILTERINFO CurInfo
;
394 /* try open the device list */
395 Status
= OpenDeviceList(&AudioDeviceGuid
, &hList
);
397 if (Status
!= ERROR_SUCCESS
)
399 DPRINT1("OpenDeviceList failed with %lx\n", Status
);
403 if (!GetDeviceListInterfaces(hList
, &AudioDeviceGuid
, OutRootInfo
))
405 DPRINT1("No devices found\n");
406 CloseDeviceList(hList
);
413 CurInfo
= *OutRootInfo
;
418 /* now check all audio filters */
421 /* now check details of the audio filter */
422 hResult
= EnumerateAudioFilter(CurInfo
, &WaveInCount
, &WaveOutCount
);
426 DPRINT1("EnumerateAudioFilter failed with %lx\n", Status
);
430 /* move to next filter */
431 CurInfo
= CurInfo
->lpNext
;
434 /* close device list */
435 CloseDeviceList(hList
);
442 FindDeviceByMappedId(
444 LPFILTERINFO
*Filter
,
447 LPFILTERINFO CurInfo
;
451 /* get first entry */
456 if ((bPlayback
&& CurInfo
->MappedId
[1] == DeviceID
) ||
457 (!bPlayback
&& CurInfo
->MappedId
[0] == DeviceID
))
464 CurInfo
= CurInfo
->lpNext
;
472 LPFILTERINFO
*Filter
)
474 LPFILTERINFO CurInfo
;
478 /* get first entry */
483 if (IsEqualGUID(&CurInfo
->DeviceGuid
[0], pGuidSrc
) ||
484 IsEqualGUID(&CurInfo
->DeviceGuid
[1], pGuidSrc
))
491 CurInfo
= CurInfo
->lpNext
;