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.
I changed into application level.
//
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-
sizeof (szServiceName), NULL))
{
dbgError (TEXT("Test:
SetupDiGetDeviceRegistryProperty: "));
SetupDiDestroyDeviceInfoList (pspRequest-
}
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;
}
// 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-
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,
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;
}
pDeviceInterfaceDetailData->DevicePath values is \\\\?\
\pci#ven_1102&dev_0005&subsys_00311102&rev_00#4&35 fae160&0&00f0#{dda54a40-1e4c-11d1-
a050-405705c10000}\\spdifouttopo.
then we got some error
: “GetAC97Features: CreateFile: can’t find the file specified.”
also,
I checked winobj utility in sysinternals.com.
It’s shows follow :
Name :
pci#ven_1102&dev_0005&subsys_00311102&rev_00#4&35f ae160&0&00f0#{dda54a40-1e4c-11d1-
a050-405705c10000}
Type : SymbolicLink
SymLink : \Device\NTPNP_PCI0022
tried to stuff...
hTopology = CreateFile (TEXT("\\\\?\
\pci#ven_1102&dev_0005&subsys_00311102&rev_00#4&35 fae160&0&00f0#{dda54a40-1e4c-11d1-
a050-405705c10000}\\Topology", ......
thease case, we got success. but, can't control DeviceIoControl.
which do I use symbolink name?
Thanks.
Eric Ahn