KS源码分析
+ -

KsInitializeDevice之GetBusInterfaceStandard

2025-03-05 5 0

KsAddDevice调用KsInitializeDevice初始化设备,在其调用GetBusInterfaceStandard获取总线信息。

GetBusInterfaceStandard实际上是发送一个IRP到下层总线驱动,其主功能码为IRP_MN_QUERY_INTERFACE,这里也对应起了我们以前抓的包 https://www.usbzh.com/article/detail-463.html

NTSTATUS CKsDevice::GetBusInterfaceStandard()
{
    //
    // There is no file object associated with this Irp, so the event may be
    // located on the stack as a non-object manager object.
    //
    KEVENT event;
    KeInitializeEvent(&event, NotificationEvent, FALSE);
    IO_STATUS_BLOCK ioStatusBlock;
    PIRP irp = IoBuildSynchronousFsdRequest(
        IRP_MJ_PNP,
        m_Ext.Public.NextDeviceObject,
        NULL,
        0,
        NULL,
        &event,
        &ioStatusBlock);
    NTSTATUS status;
    if (irp) {
        irp->RequestorMode = KernelMode;
        irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
        PIO_STACK_LOCATION irpStackNext = IoGetNextIrpStackLocation(irp);
        //
        // Create an interface query out of the Irp.
        //
        irpStackNext->MinorFunction = IRP_MN_QUERY_INTERFACE;
        irpStackNext->Parameters.QueryInterface.InterfaceType = &GUID_BUS_INTERFACE_STANDARD;
        irpStackNext->Parameters.QueryInterface.Size = sizeof(m_BusInterfaceStandard);
        irpStackNext->Parameters.QueryInterface.Version = 1;
        irpStackNext->Parameters.QueryInterface.Interface = reinterpret_cast<PINTERFACE>(&m_BusInterfaceStandard);
        irpStackNext->Parameters.QueryInterface.InterfaceSpecificData = NULL;
        status = IoCallDriver(m_Ext.Public.NextDeviceObject, irp);
        if (status == STATUS_PENDING) {
            //
            // This waits using KernelMode, so that the stack, and therefore the
            // event on that stack, is not paged out.
            //
            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
            status = ioStatusBlock.Status;
        }
        if (!NT_SUCCESS(status)) {
            //
            // HACKHACK: (WRM 8/23/99)
            //
            // Unfortunately, the Millennium PCI Bus drivers don't support
            // processing of WDM Irps (CONFIG_IRP) and thus return
            // STATUS_NOT_IMPLEMENTED.  A Ks2.0 hardware driver won't be
            // able to use Ks functions to touch the bus under Millennium.
            // This is why STATUS_NOT_IMPLEMENTED is handled like this.
            //
            if (status == STATUS_NOT_SUPPORTED ||
                status == STATUS_NOT_IMPLEMENTED) {
                status = STATUS_SUCCESS;
            }
            //
            // In case the bus decided to write in values, then return an error.
            // non-NULL values are asserted in later calls, and used to determine
            // if the interface was acquired during object destruction.
            // Also possible here that Millennium PCI bus drivers did not
            // support the query.
            //
            RtlZeroMemory(&m_BusInterfaceStandard, sizeof(m_BusInterfaceStandard));
        }
    } else {
        status = STATUS_INSUFFICIENT_RESOURCES;
    }
    return status;
}

从实际的代码来看,还必须得支持,并且得返回 STATUS_SUCCESS,至于返回STATUS_NOT_SUPPORTED或STATUS_NOT_IMPLEMENTED的影响,还得实际测试。

这个结构体的定义:

typedef struct _BUS_INTERFACE_STANDARD {
  // generic interface header
  USHORT  Size;
  USHORT  Version;
  PVOID  Context;
  PINTERFACE_REFERENCE  InterfaceReference;
  PINTERFACE_DEREFERENCE  InterfaceDereference;
  // standard bus interface
  PTRANSLATE_BUS_ADDRESS  TranslateBusAddress;
  PGET_DMA_ADAPTER  GetDmaAdapter;
  PGET_SET_DEVICE_DATA  SetBusData;
  PGET_SET_DEVICE_DATA  GetBusData;
} BUS_INTERFACE_STANDARD, *PBUS_INTERFACE_STANDARD;

0 篇笔记 写笔记

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

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

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