Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevicelist.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Configuration of network devices 00004 * FILE: dll/directx/dsound_new/devicelist.c 00005 * PURPOSE: Enumeration of audio devices 00006 * 00007 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) 00008 */ 00009 00010 #include "precomp.h" 00011 00012 ULONG 00013 GetPinIdFromFilter( 00014 LPFILTERINFO Filter, 00015 BOOL bCapture, 00016 ULONG Offset) 00017 { 00018 ULONG Index; 00019 00020 for(Index = Offset; Index < Filter->PinCount; Index++) 00021 { 00022 if (Filter->Pin[Index] == PIN_TYPE_PLAYBACK && !bCapture) 00023 return Index; 00024 00025 if (Filter->Pin[Index] == PIN_TYPE_RECORDING && bCapture) 00026 return Index; 00027 } 00028 return ULONG_MAX; 00029 } 00030 00031 00032 DWORD 00033 OpenDeviceList( 00034 IN LPGUID InterfaceGuid, 00035 OUT HDEVINFO * OutHandle) 00036 { 00037 HDEVINFO DeviceHandle; 00038 00039 DeviceHandle = SetupDiGetClassDevs(InterfaceGuid, 00040 NULL, 00041 NULL, 00042 DIGCF_DEVICEINTERFACE); //DIGCF_PRESENT 00043 00044 /* check for success */ 00045 if (DeviceHandle == INVALID_HANDLE_VALUE) 00046 { 00047 /* failed to create device list */ 00048 return GetLastError(); 00049 } 00050 00051 /* store result */ 00052 *OutHandle = DeviceHandle; 00053 00054 return ERROR_SUCCESS; 00055 } 00056 00057 BOOL 00058 CloseDeviceList( 00059 HDEVINFO Handle) 00060 { 00061 return SetupDiDestroyDeviceInfoList(Handle); 00062 } 00063 00064 BOOL 00065 GetDeviceListInterfaces( 00066 HDEVINFO DeviceHandle, 00067 IN LPGUID InterfaceGuid, 00068 LPFILTERINFO *OutPath) 00069 { 00070 ULONG Length, Index = 0; 00071 SP_DEVICE_INTERFACE_DATA InterfaceData; 00072 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData; 00073 SP_DEVINFO_DATA DeviceData; 00074 LPFILTERINFO LastDevice = NULL, RootDevice = NULL, CurDevice; 00075 BOOL Result; 00076 00077 00078 do 00079 { 00080 InterfaceData.cbSize = sizeof(InterfaceData); 00081 InterfaceData.Reserved = 0; 00082 00083 /* query device interface */ 00084 Result = SetupDiEnumDeviceInterfaces(DeviceHandle, 00085 NULL, 00086 InterfaceGuid, 00087 Index, 00088 &InterfaceData); 00089 00090 if (!Result) 00091 { 00092 /* failed */ 00093 DPRINT("SetupDiEnumDeviceInterfaces Index %u failed with %lx\n", Index, GetLastError()); 00094 break; 00095 } 00096 00097 /* allocate device interface struct */ 00098 Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR); 00099 DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 00100 HEAP_ZERO_MEMORY, 00101 Length); 00102 00103 if (!DetailData) 00104 { 00105 /* insufficient memory */ 00106 break; 00107 } 00108 00109 /* initialize device interface detail struct */ 00110 DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); 00111 00112 DeviceData.cbSize = sizeof(DeviceData); 00113 DeviceData.Reserved = 0; 00114 00115 Result = SetupDiGetDeviceInterfaceDetailW(DeviceHandle, 00116 &InterfaceData, 00117 DetailData, 00118 Length, 00119 NULL, 00120 &DeviceData); 00121 00122 if (!Result) 00123 { 00124 /* failed */ 00125 DPRINT("SetupDiGetDeviceInterfaceDetail failed with %x\n", GetLastError()); 00126 HeapFree(GetProcessHeap(), 0, DetailData); 00127 00128 break; 00129 } 00130 00131 /* allocate device path struct */ 00132 CurDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILTERINFO)); 00133 if (!CurDevice) 00134 { 00135 /* no memory */ 00136 HeapFree(GetProcessHeap(), 0, DetailData); 00137 break; 00138 } 00139 00140 /* store device path */ 00141 CopyMemory(&CurDevice->DeviceData, &DeviceData, sizeof(SP_DEVINFO_DATA)); 00142 wcscpy(CurDevice->DevicePath, DetailData->DevicePath); 00143 CurDevice->MappedId[0] = ULONG_MAX; 00144 CurDevice->MappedId[1] = ULONG_MAX; 00145 00146 DPRINT("DevicePath %S\n", CurDevice->DevicePath); 00147 00148 if (!RootDevice) 00149 RootDevice = CurDevice; 00150 00151 if (LastDevice) 00152 { 00153 LastDevice->lpNext = CurDevice; 00154 } 00155 00156 /* set as last device */ 00157 LastDevice = CurDevice; 00158 00159 /* free device interface struct */ 00160 HeapFree(GetProcessHeap(), 0, DetailData); 00161 00162 /* increment device interface index */ 00163 Index++; 00164 }while(TRUE); 00165 00166 /* store result */ 00167 *OutPath = RootDevice; 00168 00169 if (!RootDevice) 00170 return FALSE; 00171 00172 00173 return TRUE; 00174 } 00175 00176 DWORD 00177 OpenDeviceKey( 00178 HDEVINFO Handle, 00179 PSP_DEVINFO_DATA FILTERINFOData, 00180 DWORD KeyType, 00181 REGSAM DesiredAccess, 00182 OUT HKEY * OutKey) 00183 { 00184 HKEY hKey; 00185 00186 /* try open device registry key */ 00187 hKey = SetupDiOpenDevRegKey(Handle, FILTERINFOData, DICS_FLAG_CONFIGSPECIFIC, 0, KeyType, DesiredAccess); 00188 00189 if (hKey == INVALID_HANDLE_VALUE) 00190 return GetLastError(); 00191 00192 /* store result */ 00193 *OutKey = hKey; 00194 00195 return ERROR_SUCCESS; 00196 } 00197 00198 VOID 00199 FindAudioFilterPins( 00200 LPFILTERINFO CurInfo, 00201 OUT PULONG WaveInPins, 00202 OUT PULONG WaveOutPins) 00203 { 00204 ULONG Index; 00205 KSPIN_COMMUNICATION Communication; 00206 KSPIN_DATAFLOW DataFlow; 00207 00208 *WaveInPins = 0; 00209 *WaveOutPins = 0; 00210 00211 /* traverse all pins */ 00212 for(Index = 0; Index < CurInfo->PinCount; Index++) 00213 { 00214 if (GetFilterPinCommunication(CurInfo->hFilter, Index, &Communication) == ERROR_SUCCESS && 00215 GetFilterPinDataFlow(CurInfo->hFilter, Index, &DataFlow) == ERROR_SUCCESS) 00216 { 00217 if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN) 00218 { 00219 /* found a wave out device */ 00220 CurInfo->Pin[Index] = PIN_TYPE_PLAYBACK; 00221 (*WaveOutPins)++; 00222 } 00223 else if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT) 00224 { 00225 /* found a wave in device */ 00226 CurInfo->Pin[Index] = PIN_TYPE_RECORDING; 00227 (*WaveInPins)++; 00228 } 00229 else 00230 { 00231 /* bridge pin / topology pin etc */ 00232 CurInfo->Pin[Index] = PIN_TYPE_NONE; 00233 } 00234 } 00235 else 00236 { 00237 /* bridge pin / topology pin etc */ 00238 CurInfo->Pin[Index] = PIN_TYPE_NONE; 00239 } 00240 } 00241 } 00242 00243 BOOL 00244 FindWinMMDeviceIndex( 00245 LPFILTERINFO CurInfo, 00246 BOOL bRecord) 00247 { 00248 ULONG DeviceCount, Index; 00249 WCHAR Buffer[MAX_PATH]; 00250 DWORD Size, dwResult; 00251 00252 if (bRecord) 00253 DeviceCount = waveInGetNumDevs(); 00254 else 00255 DeviceCount = waveOutGetNumDevs(); 00256 00257 /* sanity check */ 00258 //ASSERT(DeviceCount); 00259 00260 for(Index = 0; Index < DeviceCount; Index++) 00261 { 00262 Size = 0; 00263 00264 /* query device interface size */ 00265 if (bRecord) 00266 dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0); 00267 else 00268 dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0); 00269 00270 if (dwResult != MMSYSERR_NOERROR) 00271 { 00272 DPRINT("Failed DRV_QUERYDEVICEINTERFACESIZE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index); 00273 continue; 00274 } 00275 00276 /* sanity check */ 00277 ASSERT(Size < MAX_PATH); 00278 00279 /* now get the device interface string */ 00280 if (bRecord) 00281 dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH); 00282 else 00283 dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH); 00284 00285 if (dwResult != MMSYSERR_NOERROR) 00286 { 00287 DPRINT("Failed DRV_QUERYDEVICEINTERFACE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index); 00288 continue; 00289 } 00290 00291 if (!wcsicmp(CurInfo->DevicePath, Buffer)) 00292 { 00293 if (bRecord) 00294 CurInfo->MappedId[0] = Index; 00295 else 00296 CurInfo->MappedId[1] = Index; 00297 00298 return TRUE; 00299 } 00300 } 00301 00302 DPRINT1("Failed to find device %ws bRecord %u Count %u\n", CurInfo->DevicePath, bRecord, DeviceCount); 00303 00304 // HACK 00305 if (bRecord) 00306 CurInfo->MappedId[0] = 0; 00307 else 00308 CurInfo->MappedId[1] = 0; 00309 00310 00311 return TRUE; 00312 } 00313 00314 HRESULT 00315 EnumerateAudioFilter( 00316 LPFILTERINFO CurInfo, 00317 OUT PULONG WaveInCount, 00318 OUT PULONG WaveOutCount) 00319 { 00320 DWORD Status; 00321 ULONG PinCount, WaveInPins, WaveOutPins; 00322 00323 /* first step open filter */ 00324 Status = OpenFilter((LPCWSTR)CurInfo->DevicePath, &CurInfo->hFilter); 00325 if (Status != ERROR_SUCCESS) 00326 { 00327 DPRINT("Failed to open filter with %lx Path %ws\n", Status, CurInfo->DevicePath); 00328 return E_FAIL; 00329 } 00330 00331 /* get filter pin count */ 00332 Status = GetFilterPinCount(CurInfo->hFilter, &PinCount); 00333 if (Status != ERROR_SUCCESS) 00334 { 00335 DPRINT("Failed to get pin count with %lx\n", Status); 00336 return E_FAIL; 00337 } 00338 00339 /* sanity check */ 00340 ASSERT(PinCount); 00341 00342 /* store pin count */ 00343 CurInfo->PinCount = PinCount; 00344 00345 /* now allocate an pin array */ 00346 CurInfo->Pin = HeapAlloc(GetProcessHeap(), 0, PinCount * sizeof(ULONG)); 00347 if (!CurInfo->Pin) 00348 { 00349 /* no memory */ 00350 return E_FAIL; 00351 } 00352 00353 /* no try to find playback / recording pins */ 00354 FindAudioFilterPins(CurInfo, &WaveInPins, &WaveOutPins); 00355 00356 DPRINT("WaveInPins %u WaveOutPins %u %S\n", WaveInPins, WaveOutPins, CurInfo->DevicePath); 00357 00358 if (WaveOutPins) 00359 { 00360 /* create a unique guid for this playback device */ 00361 if (FindWinMMDeviceIndex(CurInfo, TRUE)) 00362 { 00363 (*WaveOutCount)++; 00364 INIT_GUID(CurInfo->DeviceGuid[0], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveInCount); 00365 } 00366 } 00367 00368 00369 if (WaveInPins) 00370 { 00371 if (FindWinMMDeviceIndex(CurInfo, FALSE)) 00372 { 00373 /* create a unique guid for this record device */ 00374 (*WaveInCount)++; 00375 INIT_GUID(CurInfo->DeviceGuid[1], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveOutCount); 00376 } 00377 } 00378 00379 return S_OK; 00380 } 00381 00382 00383 HRESULT 00384 EnumAudioDeviceInterfaces( 00385 LPFILTERINFO *OutRootInfo) 00386 { 00387 HDEVINFO hList; 00388 DWORD Status; 00389 HRESULT hResult; 00390 ULONG WaveOutCount, WaveInCount; 00391 GUID AudioDeviceGuid = {STATIC_KSCATEGORY_AUDIO}; 00392 LPFILTERINFO CurInfo; 00393 00394 /* try open the device list */ 00395 Status = OpenDeviceList(&AudioDeviceGuid, &hList); 00396 00397 if (Status != ERROR_SUCCESS) 00398 { 00399 DPRINT1("OpenDeviceList failed with %lx\n", Status); 00400 return E_FAIL; 00401 } 00402 00403 if (!GetDeviceListInterfaces(hList, &AudioDeviceGuid, OutRootInfo)) 00404 { 00405 DPRINT1("No devices found\n"); 00406 CloseDeviceList(hList); 00407 return S_FALSE; 00408 } 00409 00410 /* sanity check */ 00411 ASSERT(*OutRootInfo); 00412 00413 CurInfo = *OutRootInfo; 00414 00415 WaveOutCount = 0; 00416 WaveInCount = 0; 00417 00418 /* now check all audio filters */ 00419 while(CurInfo) 00420 { 00421 /* now check details of the audio filter */ 00422 hResult = EnumerateAudioFilter(CurInfo, &WaveInCount, &WaveOutCount); 00423 00424 if (hResult != S_OK) 00425 { 00426 DPRINT1("EnumerateAudioFilter failed with %lx\n", Status); 00427 break; 00428 } 00429 00430 /* move to next filter */ 00431 CurInfo = CurInfo->lpNext; 00432 } 00433 00434 /* close device list */ 00435 CloseDeviceList(hList); 00436 00437 /* done */ 00438 return hResult; 00439 } 00440 00441 BOOL 00442 FindDeviceByMappedId( 00443 IN ULONG DeviceID, 00444 LPFILTERINFO *Filter, 00445 BOOL bPlayback) 00446 { 00447 LPFILTERINFO CurInfo; 00448 if (!RootInfo) 00449 return FALSE; 00450 00451 /* get first entry */ 00452 CurInfo = RootInfo; 00453 00454 while(CurInfo) 00455 { 00456 if ((bPlayback && CurInfo->MappedId[1] == DeviceID) || 00457 (!bPlayback && CurInfo->MappedId[0] == DeviceID)) 00458 { 00459 /* found filter */ 00460 *Filter = CurInfo; 00461 return TRUE; 00462 } 00463 00464 CurInfo = CurInfo->lpNext; 00465 } 00466 return FALSE; 00467 } 00468 00469 BOOL 00470 FindDeviceByGuid( 00471 LPCGUID pGuidSrc, 00472 LPFILTERINFO *Filter) 00473 { 00474 LPFILTERINFO CurInfo; 00475 if (!RootInfo) 00476 return FALSE; 00477 00478 /* get first entry */ 00479 CurInfo = RootInfo; 00480 00481 while(CurInfo) 00482 { 00483 if (IsEqualGUID(&CurInfo->DeviceGuid[0], pGuidSrc) || 00484 IsEqualGUID(&CurInfo->DeviceGuid[1], pGuidSrc)) 00485 { 00486 /* found filter */ 00487 *Filter = CurInfo; 00488 return TRUE; 00489 } 00490 00491 CurInfo = CurInfo->lpNext; 00492 } 00493 00494 return FALSE; 00495 } Generated on Sat May 26 2012 04:20:14 for ReactOS by
1.7.6.1
|