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;