以下是IoCallDriver接口的源码(基于WRK1.2)
NTSTATUS
IoCallDriver(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
{
return IofCallDriver (DeviceObject, Irp);
}
而IofCallDriver的源码如下:
NTSTATUS
FASTCALL
IofCallDriver(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
{
if (pIofCallDriver != NULL) {
//
// This routine will either jump immediately to IovCallDriver or
// IoPerfCallDriver.
//
return pIofCallDriver(DeviceObject, Irp, _ReturnAddress());
}
return IopfCallDriver(DeviceObject, Irp);
}
pIofCallDriver的原型如下,是一个回调。
extern PIO_CALL_DRIVER pIofCallDriver;
而PIO_CALL_DRIVER的定义如下,
typedef
NTSTATUS
(FASTCALL *PIO_CALL_DRIVER) (
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN PVOID ReturnAddress
);
IofCallDriver 的源码如下:
NTSTATUS
FORCEINLINE
IopfCallDriver(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Routine Description:
This routine is invoked to pass an I/O Request Packet (IRP) to another
driver at its dispatch routine.
Arguments:
DeviceObject - Pointer to device object to which the IRP should be passed.
Irp - Pointer to IRP for request.
Return Value:
Return status from driver's dispatch routine.
--*/
{
PIO_STACK_LOCATION irpSp;
PDRIVER_OBJECT driverObject;
NTSTATUS status;
//
// Ensure that this is really an I/O Request Packet.
//
ASSERT( Irp->Type == IO_TYPE_IRP ); //务必确保IRP是IO类型
//
// Update the IRP stack to point to the next location.
//
Irp->CurrentLocation--;
if (Irp->CurrentLocation <= 0) {
KiBugCheck3( NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR) Irp, 0, 0 );
}
irpSp = IoGetNextIrpStackLocation( Irp );
Irp->Tail.Overlay.CurrentStackLocation = irpSp;
//
// Save a pointer to the device object for this request so that it can
// be used later in completion.
//
irpSp->DeviceObject = DeviceObject;
//
// Invoke the driver at its dispatch routine entry point.
//
driverObject = DeviceObject->DriverObject;
//
// Prevent the driver from unloading.
// 调用该备的驱动的MajorFunction接口.
status = driverObject->MajorFunction[irpSp->MajorFunction]( DeviceObject,
Irp );
return status;
}