WDM驱动相同硬件相同驱动接口区分
2021-07-01
90
0
在项目开发的时候,经常会做一些设备驱动,一块主板上安装上多块相同的板卡,(例如:同一PC机的主板上会插多块PCI 串口板卡。)这时在驱动开发的时候,在AddDevice回调函数中会以设备类的方式注册设备。
DEFINE_GUID(PCI_DEVICE, 0x5f655dad, 0x16d4, 0x4d67, 0xa1, 0xe4, 0x53, 0xe7, 0x12, 0x9, 0x6d, 0x58);
#pragma PAGEDCODE
NTSTATUS DispatchAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)
{
PAGED_CODE();
KdPrint(("Enter DispatchAddDEvice"));
PDEVICE_EXTENSION pdx =(PDEVICE_EXTENSION)fdo->DeviceExtension;
RtlZeroMemory(pdx,sizeof(DEVICE_EXTENSION));
status = IoRegisterDeviceInterface(PhysicalDeviceObject, &PCI_DEVICE, NULL, &pdx->interfaceName);
if( !NT_SUCCESS(status))
{
KdPrint(("IoRegisterDeviceInterface erro"));
IoDeleteDevice(fdo);
return status;
}
...
}
由于以类的方式注册设备接口名,故设备链接名是随机生成的,所以在应用层应按枚举的方式获取设备名,而同型号不同版卡的定位可使用板卡上的拨码开关读硬件标识寄存器来确定。
#include <winioctl.h>
#include <setupapi.h>
#include <initguid.h>
#pragma comment(lib,"Setupapi.lib ")
DEFINE_GUID(PCI_DEVICE, 0x5f655dad, 0x16d4, 0x4d67, 0xa1, 0xe4, 0x53, 0xe7, 0x12, 0x9, 0x6d, 0x58);
BOOL PciEnumDevice(OUT PCHAR pDeviceName,IN int instance)
{
const GUID* pGuid = &(PCI_DEVICE);
HDEVINFO info = SetupDiGetClassDevs((GUID*)pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if(info==INVALID_HANDLE_VALUE)
{
printf("No HDEVINFO available for this GUID");
return FALSE;
}
// Get interface data for the requested instance
SP_INTERFACE_DEVICE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if(!SetupDiEnumDeviceInterfaces(info, NULL, (GUID*)pGuid, instance, &ifdata))
{
printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance");
SetupDiDestroyDeviceInfoList(info);
return FALSE;
}
// Get size of symbolic link name
DWORD ReqLen;
SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
if( ifDetail==NULL)
{
SetupDiDestroyDeviceInfoList(info);
return FALSE;
}
// Get symbolic link name
ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if( !SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
{
SetupDiDestroyDeviceInfoList(info);
delete ifDetail;
return FALSE;
}
printf("Symbolic link is %s",ifDetail->DevicePath);
memcpy(pDeviceName,ifDetail->DevicePath,strlen(ifDetail->DevicePath));
pDeviceName[strlen(ifDetail->DevicePath)] = '';
delete ifDetail;
SetupDiDestroyDeviceInfoList(info);
return TRUE;
}