[wdmaudiodev] is it possible to check a SPDIF endpoint ?

  • From: "Eric Ahn" <byungwook.ahn@xxxxxxxxx>
  • To: <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Mon, 30 Jun 2008 20:45:08 +0900

Hi~ 

 

I am going to check SPDIF Line-out endpoint.

 

I used in winddk. ("C:\WinDDK\6001.18001\src\audio\ac97")

That example is a sample of window control panel.

 

// some application

 

BOOL FindSupportingSPDIFOutAudioDevice (PSP_PROPSHEETPAGE_REQUEST
pspRequest,

                                       PSP_DEVINFO_DATA DeviceInfoData)

{

        TCHAR           szServiceName[128];

 

        //

        // Prepare the pspRequest structure...

        //

        pspRequest->cbSize = sizeof (SP_PROPSHEETPAGE_REQUEST);

        pspRequest->DeviceInfoData = DeviceInfoData;

        pspRequest->PageRequested = SPPSR_ENUM_ADV_DEVICE_PROPERTIES;

 

        // ...and the DeviceInfoData structure.

        DeviceInfoData->cbSize = sizeof (SP_DEVINFO_DATA);

 

        // Create a list of devices with Topology interface.

        pspRequest->DeviceInfoSet = SetupDiGetClassDevs
(&KSCATEGORY_TOPOLOGY,

               NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

 

        // None found?

        if (pspRequest->DeviceInfoSet == INVALID_HANDLE_VALUE)

        {

               dbgError (TEXT("Test: SetupDiGetClassDevs: "));

               return FALSE;

        }

 

        //

        // Go through the list of all devices found.

        //

        int nIndex = 0;

 

        while (SetupDiEnumDeviceInfo (pspRequest->DeviceInfoSet, nIndex,
DeviceInfoData))

        {

               //

               // Get the service name for that device.

               //

               if (!SetupDiGetDeviceRegistryProperty
(pspRequest->DeviceInfoSet, DeviceInfoData,

                       SPDRP_SERVICE, NULL, (PBYTE)szServiceName,

                       sizeof (szServiceName), NULL))

               {

                       dbgError (TEXT("Test:
SetupDiGetDeviceRegistryProperty: "));

                       SetupDiDestroyDeviceInfoList
(pspRequest->DeviceInfoSet);

                       return FALSE;

               }

 

               DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,
SUBLANG_ENGLISH_US), SORT_DEFAULT);

 

               TRACE(_T("servicename : %s\n"), szServiceName);  //STHDA
ctaud2k

               //STHDA ; sigmatel

               //ctaud2k : x-fi

               if (CompareString (lcid, NORM_IGNORECASE, szServiceName,

                       -1, TEXT("ctaud2k"), -1) == CSTR_EQUAL)

// I have "SB X-Fi Aduio" sound card with SPDIF-out. It called "ctaud2k"
service name.

               {

                       //

                       // We found it! The information is already stored,
just return.

                       // Note that we have the device list still open - we
have to destroy

                       // the list later.

                       //

                       return TRUE;

               }

 

               // Take the next in the list.

               nIndex++;

        }

 

        //

        // We did not find the service.

        //

        SetupDiDestroyDeviceInfoList (pspRequest->DeviceInfoSet);

        return FALSE;

}

 

BOOL GetDLLInfo (HMODULE *phDLL, LPFNADDPROPSHEETPAGES
*pAC97PropPageProvider)

{

        TCHAR                   szLoadPath[MAX_PATH];

        TCHAR                   szWinSysPath[MAX_PATH];

 

        GetSystemDirectory(szWinSysPath, MAX_PATH);

        if(FAILED(StringCbPrintf(szLoadPath, MAX_PATH * sizeof(TCHAR),
TEXT("%s\\%s"), szWinSysPath, TEXT("ac97prop.dll"))))

        {

               dbgError (TEXT("DisplayPropertySheet: Can't build DLL
path\n"));

               return FALSE;

        }

// And I compiled "C:\WinDDK\6001.18001\src\audio\ac97\proppage", then move
to c:/windows/system32/ ac97prop.DLL

 

        // Load the library.

        *phDLL = LoadLibrary (szLoadPath);

        if (!*phDLL)

        {

               dbgError (TEXT("DisplayPropertySheet: LoadLibrary"));

               return FALSE;

        }

 

        // Get the address of the function.

        *pAC97PropPageProvider = (LPFNADDPROPSHEETPAGES)GetProcAddress
(*phDLL,

               "AC97PropPageProvider");

        if (!*pAC97PropPageProvider)

        {

               dbgError (TEXT("DisplayPropertySheet: GetProcAddress"));

               FreeLibrary (*phDLL);

               return FALSE;

        }

 

        return TRUE;

}

 

void GetSoundInfo(HWND hWnd)

{

        SP_PROPSHEETPAGE_REQUEST    pspRequest;         // structure passed
to ac97prop

        SP_DEVINFO_DATA             DeviceInfoData;     // pspRequest points
to it.

        HMODULE                     hDLL;               // Module handle of
library

        LPFNADDPROPSHEETPAGES       AC97PropPageProvider; // function to be
called.

        PROPSHEETHEADER             psh;

 

        if (!FindSupportingSPDIFOutAudioDevice(&pspRequest,
&DeviceInfoData))

        {

               MessageBox (hWnd, TEXT("can't find supporint SPDIF-OUT audio
device"),

                       AppletName, MB_ICONSTOP | MB_OK);

               return;

        }

 

        // Load the library and get the function pointer.

        if (!GetDLLInfo (&hDLL, &AC97PropPageProvider))

        {

               MessageBox (hWnd, TEXT("The property page DLL could not
load."),

                       AppletName, MB_ICONSTOP | MB_OK);

               SetupDiDestroyDeviceInfoList (pspRequest.DeviceInfoSet);

               return;

        }

    ..

..

}

 

 

// AC97PropPageProvider in ac97prop.DLL

 

BOOL APIENTRY AC97PropPageProvider

(

    PSP_PROPSHEETPAGE_REQUEST   pPropPageRequest,

    LPFNADDPROPSHEETPAGE        fAddFunc,

    LPARAM                      lParam

)

{

    PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData;

    tAC97Features                    *pAC97Features;

    PROPSHEETPAGE                    PropSheetPage;

    HPROPSHEETPAGE                   hPropSheetPage;

 

    // Check page requested

    if (pPropPageRequest->PageRequested != SPPSR_ENUM_ADV_DEVICE_PROPERTIES)

    {

        return FALSE;

    }

 

    // Check device info set and data

    if ((!pPropPageRequest->DeviceInfoSet) ||
(!pPropPageRequest->DeviceInfoData))

    {

        return FALSE;

    }

 

    // Allocate the memory for the AC97 features.

    pAC97Features = (tAC97Features *) LocalAlloc (LPTR, sizeof
(tAC97Features));

    if (!pAC97Features)

    {

        dbgError (TEXT("AC97PropPageProvider: LocalAlloc: "));

        return FALSE;

    }

    

    // Get the device interface detail which return a path to the device

    // driver that we need to open the device.

    if (!GetDeviceInterfaceDetail (pPropPageRequest,
&pDeviceInterfaceDetailData))

    {

        LocalFree (pAC97Features);

        return FALSE;

    }

 

    // Get the AC97 features through the private property call.

    if (!GetAC97Features (pDeviceInterfaceDetailData, pAC97Features))

    {

        LocalFree (pDeviceInterfaceDetailData);

        LocalFree (pAC97Features);

        return FALSE;

    }

 

#ifdef PROPERTY_SHOW_SET

    // Show how we would set something in the driver

    AC97ShowSet (pDeviceInterfaceDetailData);

#endif

    

    // We don't need the device interface details any more, get rid of it
now!

    LocalFree (pDeviceInterfaceDetailData);

 

    // initialize the property page

    PropSheetPage.dwSize        = sizeof(PROPSHEETPAGE);

    PropSheetPage.dwFlags       = 0;

    PropSheetPage.hInstance     = ghInstance;

    PropSheetPage.pszTemplate   = MAKEINTRESOURCE(DLG_AC97FEATURES);

    PropSheetPage.pfnDlgProc    = AC97DlgProc;

    PropSheetPage.lParam        = (LPARAM)pAC97Features;

    PropSheetPage.pfnCallback   = NULL;

 

    // create the page and get back a handle

    hPropSheetPage = CreatePropertySheetPage (&PropSheetPage);

    if (!hPropSheetPage)

    {

        LocalFree (pAC97Features);

        return FALSE;

    }

 

    // add the property page

    if (!(*fAddFunc)(hPropSheetPage, lParam))

    {

        DestroyPropertySheetPage (hPropSheetPage);

        LocalFree (pAC97Features);

        return FALSE;

    }

 

    return TRUE;

}

 

BOOL GetAC97Features (PSP_DEVICE_INTERFACE_DETAIL_DATA
pDeviceInterfaceDetailData,

                      tAC97Features *pAC97Features)

{

    HANDLE          hTopology;

    KSPROPERTY      AC97Property;

    ULONG           ulBytesReturned;

    BOOL            fSuccess;

 

    // Open the topology filter.

    hTopology = CreateFile (pDeviceInterfaceDetailData->DevicePath,

        //
"##?#PCI#VEN_1102&DEV_0005&SUBSYS_00311102&REV_00#4&35FAE160&0&00F0#{dda54a4
0-1e4c-11d1-a050-405705c10000}\#SpdifOutTopo",

                            GENERIC_READ, FILE_SHARE_READ,// |
FILE_SHARE_WRITE,

                            NULL, OPEN_EXISTING, 0, NULL);

    // Check for error. 

    if (hTopology == INVALID_HANDLE_VALUE)

    {

        dbgError (TEXT("GetAC97Features: CreateFile: "));

 

//

//

// have error : can't find the file specified.

//

//

//

//

        return FALSE;

    }

 

    // Fill the KSPROPERTY structure.

    AC97Property.Set = KSPROPSETID_Private;

    AC97Property.Flags = KSPROPERTY_TYPE_GET;

    AC97Property.Id = KSPROPERTY_AC97_FEATURES;

 

    fSuccess = DeviceIoControl (hTopology, IOCTL_KS_PROPERTY,

                                &AC97Property, sizeof (AC97Property),

                                pAC97Features, sizeof (tAC97Features),

                                &ulBytesReturned, NULL);

    // We don't need the handle anymore.

    CloseHandle (hTopology);

    

    // Check for error.

    if (!fSuccess)

    {

        dbgError (TEXT("GetAC97Features: DeviceIoControl: "));

        return FALSE;

    }

 

    return TRUE;

}

 

 

What is mean "GetAC97Features: CreateFile: can't find the file specified."?

pDeviceInterfaceDetailData->DevicePath values is \\?\pci#ven_1102
<file:///\\%3f\pci%23ven_1102&dev_0005&subsys_00311102&rev_00%234&35fae160&0
&00f0%23%7bdda54a40-1e4c-11d1-a050-405705c10000%7d\spdifouttopo>
&dev_0005&subsys_00311102&rev_00#4&35fae160&0&00f0#{dda54a40-1e4c-11d1-a050-
405705c10000}\spdifouttopo.

I checked winobj utility in sysinternals.com.

 

It's shows follow :

Name :
pci#ven_1102&dev_0005&subsys_00311102&rev_00#4&35fae160&0&00f0#{dda54a40-1e4
c-11d1-a050-405705c10000}\spdifouttopo

Type : SymbolicLink

SymLink : \Device\NTPNP_PCI0022

 

Hm, 

Which do I CreateFile, winobj Name or pDeviceInterfaceDetailData->DevicePath
values?

 

Thanks.

 

 

Eric Ahn 

 

E-Mail  : byungwook.ahn@xxxxxxxxx

 

 

PNG image

Other related posts: