📄 ac97prop.cpp
字号:
// Prepare the property structure sent down.
AC97Property.Set = KSPROPSETID_Private;
AC97Property.Flags = KSPROPERTY_TYPE_SET;
AC97Property.Id = KSPROPERTY_AC97_SAMPLE_SET;
// Make the final call.
fSuccess = DeviceIoControl (hTopology, IOCTL_KS_PROPERTY,
&AC97Property, sizeof (AC97Property),
&dwData, sizeof (dwData),
&ulBytesReturned, NULL);
// We don't need the handle anymore.
CloseHandle (hTopology);
// Check for error.
if (!fSuccess)
{
dbgError (TEXT("AC97ShowSet: DeviceIoControl: "));
}
return; // We don't care about the return value.
}
#endif
/////////////////////////////////////////////////////////////////////////////////
// GetAC97Features
/////////////////////////////////////////////////////////////////////////////////
// This function gets called by the property page provider (in this module) to
// get all the AC97 features that are normally not displayed by the drivers.
// To get the AC97Features structure we pass down the private property. As you
// can see this is fairly easy.
//
// Arguments:
// pDeviceInterfaceDetailData - device interface details (path to device driver)
// pAC97Features - pointer to AC97 features structure.
//
// Return Value:
// BOOL: FALSE if we couldn't get the information, TRUE on success.
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: "));
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;
}
/////////////////////////////////////////////////////////////////////////////////
// GetDeviceInterfaceDetail
/////////////////////////////////////////////////////////////////////////////////
// This function gets called by the property page provider (in this module) to
// get the device interface details. The device interface detail contains a
// path to the device driver that can be used to open the device driver.
// When we parse the driver we look for the topology interface since this
// interface exposes the private property.
//
// Arguments:
// pPropPageRequest - points to SP_PROPSHEETPAGE_REQUEST
// pDeviceInterfaceDetailData - device interface details returned.
//
// Return Value:
// BOOL: FALSE if something went wrong, TRUE on success.
BOOL GetDeviceInterfaceDetail (PSP_PROPSHEETPAGE_REQUEST pPropPageRequest,
PSP_DEVICE_INTERFACE_DETAIL_DATA *ppDeviceInterfaceDetailData)
{
BOOL fSuccess;
ULONG ulDeviceInstanceIdSize = 0;
PTSTR pDeviceInstanceID = NULL;
HDEVINFO hDevInfoWithInterface;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
ULONG ulDeviceInterfaceDetailDataSize = 0;
// Get the device instance id (PnP string). The first call will retrieve
// the buffer length in characters. fSuccess will be FALSE.
fSuccess = SetupDiGetDeviceInstanceId (pPropPageRequest->DeviceInfoSet,
pPropPageRequest->DeviceInfoData,
NULL,
0,
&ulDeviceInstanceIdSize);
// Check for error.
if ((GetLastError () != ERROR_INSUFFICIENT_BUFFER) || (!ulDeviceInstanceIdSize))
{
dbgError (TEXT("GetDeviceInterfaceDetail: SetupDiGetDeviceInstanceId: "));
return FALSE;
}
// Allocate the buffer for the device instance ID (PnP string).
pDeviceInstanceID = (PTSTR)LocalAlloc (LPTR, ulDeviceInstanceIdSize * sizeof (TCHAR));
if (!pDeviceInstanceID)
{
dbgError (TEXT("GetDeviceInterfaceDetail: LocalAlloc: "));
return FALSE;
}
// Now call again, this time with all parameters.
fSuccess = SetupDiGetDeviceInstanceId (pPropPageRequest->DeviceInfoSet,
pPropPageRequest->DeviceInfoData,
pDeviceInstanceID,
ulDeviceInstanceIdSize,
NULL);
// Check for error.
if (!fSuccess)
{
dbgError (TEXT("GetDeviceInterfaceDetail: SetupDiGetDeviceInstanceId: "));
LocalFree (pDeviceInstanceID);
return FALSE;
}
// Now we can get the handle to the dev info with interface.
// We parse the device specifically for topology interfaces.
hDevInfoWithInterface = SetupDiGetClassDevs (&KSCATEGORY_TOPOLOGY,
pDeviceInstanceID,
NULL,
DIGCF_DEVICEINTERFACE);
// We don't need pDeviceInstanceID anymore.
LocalFree (pDeviceInstanceID);
// Check for error.
if (hDevInfoWithInterface == INVALID_HANDLE_VALUE)
{
dbgError (TEXT("GetDeviceInterfaceDetail: SetupDiGetClassDevs: "));
return FALSE;
}
// Go through the list of topology device interface of this device.
// We assume that there is only one topology device interface and
// we will store the device details in our private structure.
DeviceInterfaceData.cbSize = sizeof (DeviceInterfaceData);
fSuccess = SetupDiEnumDeviceInterfaces (hDevInfoWithInterface,
NULL,
&KSCATEGORY_TOPOLOGY,
0,
&DeviceInterfaceData);
// Check for error.
if (!fSuccess)
{
dbgError (TEXT("GetDeviceInterfaceDetail: SetupDiEnumDeviceInterfaces: "));
SetupDiDestroyDeviceInfoList (hDevInfoWithInterface);
return FALSE;
}
// Get the details for this device interface. The first call will retrieve
// the buffer length in characters. fSuccess will be FALSE.
fSuccess = SetupDiGetDeviceInterfaceDetail (hDevInfoWithInterface,
&DeviceInterfaceData,
NULL,
0,
&ulDeviceInterfaceDetailDataSize,
NULL);
// Check for error.
if ((GetLastError () != ERROR_INSUFFICIENT_BUFFER) || (!ulDeviceInterfaceDetailDataSize))
{
dbgError (TEXT("GetDeviceInterfaceDetail: SetupDiGetDeviceInterfaceDetail: "));
SetupDiDestroyDeviceInfoList (hDevInfoWithInterface);
return FALSE;
}
// Allocate the buffer for the device interface detail data.
if (!(*ppDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)
LocalAlloc (LPTR, ulDeviceInterfaceDetailDataSize)))
{
dbgError (TEXT("GetDeviceInterfaceDetail: LocalAlloc: "));
SetupDiDestroyDeviceInfoList (hDevInfoWithInterface);
return FALSE;
}
// The size contains only the structure, not the additional path.
(*ppDeviceInterfaceDetailData)->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
// Get the details for this device interface, this time with all paramters.
fSuccess = SetupDiGetDeviceInterfaceDetail (hDevInfoWithInterface,
&DeviceInterfaceData,
*ppDeviceInterfaceDetailData,
ulDeviceInterfaceDetailDataSize,
NULL,
NULL);
// We don't need the handle anymore.
SetupDiDestroyDeviceInfoList (hDevInfoWithInterface);
if (!fSuccess)
{
dbgError (TEXT("GetDeviceInterfaceDetail: SetupDiGetDeviceInterfaceDetail: "));
LocalFree (*ppDeviceInterfaceDetailData), *ppDeviceInterfaceDetailData = NULL;
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////
// AC97PropPageProvider
/////////////////////////////////////////////////////////////////////////////////
// This function gets called by the device manager when it asks for additional
// property sheet pages. The parameter fAddFunc is the function that we call to
// add the sheet page to the dialog.
// This routine gets called because the registry entry "EnumPropPage32" tells
// the device manager that there is a dll with a exported function that will add
// a property sheet page.
// Because we want to fail this function (not create the sheet) if the driver
// doesn't support the private property, we have to do all the work here, that
// means we open the device and get all the information, then we close the
// device and return.
//
// Arguments:
// pPropPageRequest - points to SP_PROPSHEETPAGE_REQUEST
// fAddFunc - function ptr to call to add sheet.
// lparam - add sheet functions private data handle.
//
// Return Value:
// BOOL: FALSE if pages could not be added, TRUE on success
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -