ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

devicelist.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.