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