ReactOS 0.4.16-dev-87-g3dfbe52
devicelist.c
Go to the documentation of this file.
1/*
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
6 *
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9
10#include "precomp.h"
11
15 BOOL bCapture,
17{
19
20 for(Index = Offset; Index < Filter->PinCount; Index++)
21 {
22 if (Filter->Pin[Index] == PIN_TYPE_PLAYBACK && !bCapture)
23 return Index;
24
25 if (Filter->Pin[Index] == PIN_TYPE_RECORDING && bCapture)
26 return Index;
27 }
28 return ULONG_MAX;
29}
30
31
35 OUT HDEVINFO * OutHandle)
36{
38
40 NULL,
41 NULL,
42 DIGCF_DEVICEINTERFACE); //DIGCF_PRESENT
43
44 /* check for success */
46 {
47 /* failed to create device list */
48 return GetLastError();
49 }
50
51 /* store result */
52 *OutHandle = DeviceHandle;
53
54 return ERROR_SUCCESS;
55}
56
57BOOL
60{
62}
63
64BOOL
68 LPFILTERINFO *OutPath)
69{
70 ULONG Length, Index = 0;
71 SP_DEVICE_INTERFACE_DATA InterfaceData;
74 LPFILTERINFO LastDevice = NULL, RootDevice = NULL, CurDevice;
76
77
78 do
79 {
80 InterfaceData.cbSize = sizeof(InterfaceData);
81 InterfaceData.Reserved = 0;
82
83 /* query device interface */
85 NULL,
87 Index,
88 &InterfaceData);
89
90 if (!Result)
91 {
92 /* failed */
93 DPRINT("SetupDiEnumDeviceInterfaces Index %u failed with %lx\n", Index, GetLastError());
94 break;
95 }
96
97 /* allocate device interface struct */
101 Length);
102
103 if (!DetailData)
104 {
105 /* insufficient memory */
106 break;
107 }
108
109 /* initialize device interface detail struct */
110 DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
111
112 DeviceData.cbSize = sizeof(DeviceData);
113 DeviceData.Reserved = 0;
114
116 &InterfaceData,
117 DetailData,
118 Length,
119 NULL,
120 &DeviceData);
121
122 if (!Result)
123 {
124 /* failed */
125 DPRINT("SetupDiGetDeviceInterfaceDetail failed with %x\n", GetLastError());
126 HeapFree(GetProcessHeap(), 0, DetailData);
127
128 break;
129 }
130
131 /* allocate device path struct */
132 CurDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILTERINFO));
133 if (!CurDevice)
134 {
135 /* no memory */
136 HeapFree(GetProcessHeap(), 0, DetailData);
137 break;
138 }
139
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;
145
146 DPRINT("DevicePath %S\n", CurDevice->DevicePath);
147
148 if (!RootDevice)
149 RootDevice = CurDevice;
150
151 if (LastDevice)
152 {
153 LastDevice->lpNext = CurDevice;
154 }
155
156 /* set as last device */
157 LastDevice = CurDevice;
158
159 /* free device interface struct */
160 HeapFree(GetProcessHeap(), 0, DetailData);
161
162 /* increment device interface index */
163 Index++;
164 }while(TRUE);
165
166 /* store result */
167 *OutPath = RootDevice;
168
169 if (!RootDevice)
170 return FALSE;
171
172
173 return TRUE;
174}
175
176DWORD
179 PSP_DEVINFO_DATA FILTERINFOData,
180 DWORD KeyType,
182 OUT HKEY * OutKey)
183{
184 HKEY hKey;
185
186 /* try open device registry key */
188
190 return GetLastError();
191
192 /* store result */
193 *OutKey = hKey;
194
195 return ERROR_SUCCESS;
196}
197
198VOID
200 LPFILTERINFO CurInfo,
201 OUT PULONG WaveInPins,
202 OUT PULONG WaveOutPins)
203{
204 ULONG Index;
205 KSPIN_COMMUNICATION Communication;
207
208 *WaveInPins = 0;
209 *WaveOutPins = 0;
210
211 /* traverse all pins */
212 for(Index = 0; Index < CurInfo->PinCount; Index++)
213 {
214 if (GetFilterPinCommunication(CurInfo->hFilter, Index, &Communication) == ERROR_SUCCESS &&
216 {
217 if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
218 {
219 /* found a wave out device */
220 CurInfo->Pin[Index] = PIN_TYPE_PLAYBACK;
221 (*WaveOutPins)++;
222 }
223 else if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
224 {
225 /* found a wave in device */
226 CurInfo->Pin[Index] = PIN_TYPE_RECORDING;
227 (*WaveInPins)++;
228 }
229 else
230 {
231 /* bridge pin / topology pin etc */
232 CurInfo->Pin[Index] = PIN_TYPE_NONE;
233 }
234 }
235 else
236 {
237 /* bridge pin / topology pin etc */
238 CurInfo->Pin[Index] = PIN_TYPE_NONE;
239 }
240 }
241}
242
243BOOL
245 LPFILTERINFO CurInfo,
246 BOOL bRecord)
247{
250 DWORD Size, dwResult;
251
252 if (bRecord)
254 else
256
257 /* sanity check */
258 //ASSERT(DeviceCount);
259
260 for(Index = 0; Index < DeviceCount; Index++)
261 {
262 Size = 0;
263
264 /* query device interface size */
265 if (bRecord)
267 else
269
270 if (dwResult != MMSYSERR_NOERROR)
271 {
272 DPRINT("Failed DRV_QUERYDEVICEINTERFACESIZE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index);
273 continue;
274 }
275
276 /* sanity check */
278
279 /* now get the device interface string */
280 if (bRecord)
282 else
284
285 if (dwResult != MMSYSERR_NOERROR)
286 {
287 DPRINT("Failed DRV_QUERYDEVICEINTERFACE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index);
288 continue;
289 }
290
291 if (!wcsicmp(CurInfo->DevicePath, Buffer))
292 {
293 if (bRecord)
294 CurInfo->MappedId[0] = Index;
295 else
296 CurInfo->MappedId[1] = Index;
297
298 return TRUE;
299 }
300 }
301
302 DPRINT1("Failed to find device %ws bRecord %u Count %u\n", CurInfo->DevicePath, bRecord, DeviceCount);
303
304 // HACK
305 if (bRecord)
306 CurInfo->MappedId[0] = 0;
307 else
308 CurInfo->MappedId[1] = 0;
309
310
311 return TRUE;
312}
313
316 LPFILTERINFO CurInfo,
317 OUT PULONG WaveInCount,
318 OUT PULONG WaveOutCount)
319{
321 ULONG PinCount, WaveInPins, WaveOutPins;
322
323 /* first step open filter */
324 Status = OpenFilter((LPCWSTR)CurInfo->DevicePath, &CurInfo->hFilter);
325 if (Status != ERROR_SUCCESS)
326 {
327 DPRINT("Failed to open filter with %lx Path %ws\n", Status, CurInfo->DevicePath);
328 return E_FAIL;
329 }
330
331 /* get filter pin count */
333 if (Status != ERROR_SUCCESS)
334 {
335 DPRINT("Failed to get pin count with %lx\n", Status);
336 return E_FAIL;
337 }
338
339 /* sanity check */
341
342 /* store pin count */
343 CurInfo->PinCount = PinCount;
344
345 /* now allocate an pin array */
346 CurInfo->Pin = HeapAlloc(GetProcessHeap(), 0, PinCount * sizeof(ULONG));
347 if (!CurInfo->Pin)
348 {
349 /* no memory */
350 return E_FAIL;
351 }
352
353 /* no try to find playback / recording pins */
354 FindAudioFilterPins(CurInfo, &WaveInPins, &WaveOutPins);
355
356 DPRINT("WaveInPins %u WaveOutPins %u %S\n", WaveInPins, WaveOutPins, CurInfo->DevicePath);
357
358 if (WaveOutPins)
359 {
360 /* create a unique guid for this playback device */
361 if (FindWinMMDeviceIndex(CurInfo, TRUE))
362 {
363 (*WaveOutCount)++;
364 INIT_GUID(CurInfo->DeviceGuid[0], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveInCount);
365 }
366 }
367
368
369 if (WaveInPins)
370 {
371 if (FindWinMMDeviceIndex(CurInfo, FALSE))
372 {
373 /* create a unique guid for this record device */
374 (*WaveInCount)++;
375 INIT_GUID(CurInfo->DeviceGuid[1], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveOutCount);
376 }
377 }
378
379 return S_OK;
380}
381
382
385 LPFILTERINFO *OutRootInfo)
386{
389 HRESULT hResult;
390 ULONG WaveOutCount, WaveInCount;
391 GUID AudioDeviceGuid = {STATIC_KSCATEGORY_AUDIO};
392 LPFILTERINFO CurInfo;
393
394 /* try open the device list */
395 Status = OpenDeviceList(&AudioDeviceGuid, &hList);
396
397 if (Status != ERROR_SUCCESS)
398 {
399 DPRINT1("OpenDeviceList failed with %lx\n", Status);
400 return E_FAIL;
401 }
402
403 if (!GetDeviceListInterfaces(hList, &AudioDeviceGuid, OutRootInfo))
404 {
405 DPRINT1("No devices found\n");
407 return S_FALSE;
408 }
409
410 /* sanity check */
411 ASSERT(*OutRootInfo);
412
413 CurInfo = *OutRootInfo;
414
415 WaveOutCount = 0;
416 WaveInCount = 0;
417
418 /* now check all audio filters */
419 while(CurInfo)
420 {
421 /* now check details of the audio filter */
422 hResult = EnumerateAudioFilter(CurInfo, &WaveInCount, &WaveOutCount);
423
424 if (hResult != S_OK)
425 {
426 DPRINT1("EnumerateAudioFilter failed with %lx\n", Status);
427 break;
428 }
429
430 /* move to next filter */
431 CurInfo = CurInfo->lpNext;
432 }
433
434 /* close device list */
436
437 /* done */
438 return hResult;
439}
440
441BOOL
445 BOOL bPlayback)
446{
447 LPFILTERINFO CurInfo;
448 if (!RootInfo)
449 return FALSE;
450
451 /* get first entry */
452 CurInfo = RootInfo;
453
454 while(CurInfo)
455 {
456 if ((bPlayback && CurInfo->MappedId[1] == DeviceID) ||
457 (!bPlayback && CurInfo->MappedId[0] == DeviceID))
458 {
459 /* found filter */
460 *Filter = CurInfo;
461 return TRUE;
462 }
463
464 CurInfo = CurInfo->lpNext;
465 }
466 return FALSE;
467}
468
469BOOL
471 LPCGUID pGuidSrc,
473{
474 LPFILTERINFO CurInfo;
475 if (!RootInfo)
476 return FALSE;
477
478 /* get first entry */
479 CurInfo = RootInfo;
480
481 while(CurInfo)
482 {
483 if (IsEqualGUID(&CurInfo->DeviceGuid[0], pGuidSrc) ||
484 IsEqualGUID(&CurInfo->DeviceGuid[1], pGuidSrc))
485 {
486 /* found filter */
487 *Filter = CurInfo;
488 return TRUE;
489 }
490
491 CurInfo = CurInfo->lpNext;
492 }
493
494 return FALSE;
495}
#define DPRINT1
Definition: precomp.h:8
#define UlongToHandle(ul)
Definition: basetsd.h:97
Definition: bufpool.h:45
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
DataFlow
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL FindWinMMDeviceIndex(LPFILTERINFO CurInfo, BOOL bRecord)
Definition: devicelist.c:244
VOID FindAudioFilterPins(LPFILTERINFO CurInfo, OUT PULONG WaveInPins, OUT PULONG WaveOutPins)
Definition: devicelist.c:199
DWORD OpenDeviceKey(HDEVINFO Handle, PSP_DEVINFO_DATA FILTERINFOData, DWORD KeyType, REGSAM DesiredAccess, OUT HKEY *OutKey)
Definition: devicelist.c:177
HRESULT EnumAudioDeviceInterfaces(LPFILTERINFO *OutRootInfo)
Definition: devicelist.c:384
HRESULT EnumerateAudioFilter(LPFILTERINFO CurInfo, OUT PULONG WaveInCount, OUT PULONG WaveOutCount)
Definition: devicelist.c:315
DWORD OpenDeviceList(IN LPGUID InterfaceGuid, OUT HDEVINFO *OutHandle)
Definition: devicelist.c:33
BOOL FindDeviceByMappedId(IN ULONG DeviceID, LPFILTERINFO *Filter, BOOL bPlayback)
Definition: devicelist.c:442
BOOL GetDeviceListInterfaces(HDEVINFO DeviceHandle, IN LPGUID InterfaceGuid, LPFILTERINFO *OutPath)
Definition: devicelist.c:65
BOOL CloseDeviceList(HDEVINFO Handle)
Definition: devicelist.c:58
BOOL FindDeviceByGuid(LPCGUID pGuidSrc, LPFILTERINFO *Filter)
Definition: devicelist.c:470
ULONG GetPinIdFromFilter(LPFILTERINFO Filter, BOOL bCapture, ULONG Offset)
Definition: devicelist.c:13
LPFILTERINFO RootInfo
Definition: dsound.c:13
DWORD GetFilterPinCommunication(IN HANDLE hFilter, IN ULONG PinId, OUT PKSPIN_COMMUNICATION Communication)
Definition: misc.c:427
DWORD OpenFilter(IN LPCWSTR lpFileName, IN PHANDLE OutHandle)
Definition: misc.c:277
DWORD GetFilterPinCount(IN HANDLE hFilter, OUT PULONG NumPins)
Definition: misc.c:357
DWORD GetFilterPinDataFlow(IN HANDLE hFilter, IN ULONG PinId, OUT PKSPIN_DATAFLOW DataFlow)
Definition: misc.c:444
@ PIN_TYPE_PLAYBACK
Definition: precomp.h:60
@ PIN_TYPE_RECORDING
Definition: precomp.h:61
@ PIN_TYPE_NONE
Definition: precomp.h:59
#define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: precomp.h:51
#define GetProcessHeap()
Definition: compat.h:736
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define wcsicmp
Definition: compat.h:15
#define DRV_QUERYDEVICEINTERFACESIZE
Definition: mmddk.h:97
#define DRV_QUERYDEVICEINTERFACE
Definition: mmddk.h:96
BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, CONST GUID *InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:2780
HKEY WINAPI SetupDiOpenDevRegKey(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, REGSAM samDesired)
Definition: devinst.c:5934
BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:3011
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2893
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
FxAutoRegKey hKey
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
#define ULONG_MAX
Definition: limits.h:44
#define S_OK
Definition: intsafe.h:52
KSPIN_DATAFLOW
Definition: ks.h:1248
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
KSPIN_COMMUNICATION
Definition: ks.h:1253
@ KSPIN_COMMUNICATION_SINK
Definition: ks.h:1255
#define STATIC_KSCATEGORY_AUDIO
Definition: ksmedia.h:169
HWND hList
Definition: livecd.c:10
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define ASSERT(a)
Definition: mode.c:44
ULONG DeviceCount
Definition: mpu401.c:26
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define DIGCF_DEVICEINTERFACE
Definition: setupapi.h:174
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_DEVICE_INTERFACE_DETAIL_DATA_W
#define DICS_FLAG_CONFIGSPECIFIC
Definition: setupapi.h:115
#define SetupDiGetClassDevs
Definition: setupapi.h:2593
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W * PSP_DEVICE_INTERFACE_DETAIL_DATA_W
#define DPRINT
Definition: sndvol32.h:73
_In_ const GUID _In_ ULONG PinCount
Definition: strmini.h:505
WCHAR DevicePath[ANYSIZE_ARRAY]
Definition: setupapi.h:855
struct tagFILTERINFO * lpNext
Definition: precomp.h:48
ULONG PinCount
Definition: precomp.h:43
WCHAR DevicePath[MAX_PATH]
Definition: precomp.h:41
PULONG Pin
Definition: precomp.h:44
GUID DeviceGuid[2]
Definition: precomp.h:45
HANDLE hFilter
Definition: precomp.h:42
ULONG MappedId[2]
Definition: precomp.h:46
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceID
Definition: wdfpdo.h:278
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CopyMemory
Definition: winbase.h:1710
#define S_FALSE
Definition: winerror.h:2357
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2565
UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2813
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2538
ACCESS_MASK REGSAM
Definition: winreg.h:69
static const GUID InterfaceGuid
Definition: wlanapi.c:25
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185