NtReadFile为例,
1. 建立irp
PIRP
IopAllocateIrpPrivate(
IN CCHAR StackSize,
IN BOOLEAN ChargeQuota
)
//如果大小小于IopLargeIrpStackLocations,那么从prcb->PPLookasideList[number].P;这个快查表里面拿一个,如果大于这个值则构造一个
//然后初始化
#define IopInitializeIrp( Irp, PacketSize, StackSize ) { \
RtlZeroMemory( (Irp), (PacketSize) ); \
(Irp)->Type = (CSHORT) IO_TYPE_IRP; \
(Irp)->Size = (USHORT) ((PacketSize)); \
(Irp)->StackCount = (CCHAR) ((StackSize)); \
(Irp)->CurrentLocation = (CCHAR) ((StackSize) + 1); \
(Irp)->ApcEnvironment = KeGetCurrentApcEnvironment(); \
InitializeListHead (&(Irp)->ThreadListEntry); \
(Irp)->Tail.Overlay.CurrentStackLocation = \
((PIO_STACK_LOCATION) ((UCHAR *) (Irp) + \
sizeof( IRP ) + \
( (StackSize) * sizeof( IO_STACK_LOCATION )))); }
2.调用IopSynchronousServiceTail派发irp
NTSTATUS
IopSynchronousServiceTail(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PFILE_OBJECT FileObject,
IN BOOLEAN DeferredIoCompletion,
IN KPROCESSOR_MODE RequestorMode,
IN BOOLEAN SynchronousIo,
IN TRANSFER_TYPE TransferType
)
{
NTSTATUS status;
PAGED_CODE();
//异步操作要插入irp的thread->irpList
if (!SynchronousIo) {
IopQueueThreadIrp( Irp );
}
//……
//
// 向设备发irp
//
status = IoCallDriver( DeviceObject, Irp );
if (DeferredIoCompletion) {
if (status != STATUS_PENDING) {
PKNORMAL_ROUTINE normalRoutine;
PVOID normalContext;
KIRQL irql = PASSIVE_LEVEL; // Just to shut up the compiler
ASSERT( !Irp->PendingReturned );
if (!SynchronousIo) {
KeRaiseIrql( APC_LEVEL, &irql );
}
//完成请求
IopCompleteRequest( &Irp->Tail.Apc,
&normalRoutine,
&normalContext,
(PVOID *) &FileObject,
&normalContext );
if (!SynchronousIo) {
KeLowerIrql( irql );
}
}
}
//同步下等待irp完成
if (SynchronousIo) {
if (status == STATUS_PENDING) {