Windows驱动
+ -

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;
}

0 篇笔记 写笔记

作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!