您的位置:首页 > 其它

IRP 同步IO、异步IO及延迟IO完成

2017-03-17 17:24 411 查看
同步与异步

kernel32.dll

CreateFileW

  /* translate the flags that need no validation */

  if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))

 {

   /* yes, nonalert is correct! apc's are not delivered   

  while waiting for file io to complete */

 

    

  Flags |= FILE_SYNCHRONOUS_IO_NONALERT

 }

NtCreateFile间接调用IopParseDevice来创建FileObject

status = ObCreateObject( KernelMode,

                                 IoFileObjectType,

                                 &objectAttributes,

                                 AccessMode,

                                 (PVOID) NULL,

                                 fileObjectSize,

                                 0,

                                 0,

                                 (PVOID *) &fileObject );

        if (!NT_SUCCESS( status )) {

            IoFreeIrp( irp );

            IopDecrementDeviceObjectRef( parseDeviceObject, FALSE, FALSE );

            if (vpb) {

               IopDereferenceVpbAndFree(vpb);

            }

            return op->FinalStatus = status;

        }

        IopPerfLogFileCreate(fileObject, CompleteName);

        RtlZeroMemory( fileObject, sizeof( FILE_OBJECT ) );

        if (op->CreateOptions & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) {

            fileObject->Flags = FO_SYNCHRONOUS_IO;

            if (op->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) {

                fileObject->Flags |= FO_ALERTABLE_IO;

            }

        }

NtDeviceIoControlFile

IopXxxControlFile

 if (fileObject->Flags & FO_SYNCHRONOUS_IO) {

        ...

        synchronousIo = TRUE;

    } else {

        synchronousIo = FALSE;

}

延迟IO完成(IRP_DEFER_IO_COMPLETION)

IoCompleteRequest

IopfCompleteRequest

调用完上层的完成例程后,如果是同步完成,并且IRP_DEFER_IO_COMPLETION 则直接返回

  if (Irp->Flags & IRP_DEFER_IO_COMPLETION && !Irp->PendingReturned) {

        if ((Irp->IoStatus.Status == STATUS_REPARSE )  &&

            (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)) {

            //

            // For name junctions we reinstate the address of the appropriate

            // buffer. It is freed in parse.c

            //

            Irp->Tail.Overlay.AuxiliaryBuffer = saveAuxiliaryPointer;

        }

        return;

    }

IopSynchronousServiceTail

status = IoCallDriver( DeviceObject, Irp );

    // 如果是同步完成,并且IRP_DEFER_IO_COMPLETION标志设置,则延迟到这里来完成IRP

    if (DeferredIoCompletion) {

        if (status != STATUS_PENDING) {

            //

            // The I/O operation was completed without returning a status of

            // pending.  This means that at this point, the IRP has not been

            // fully completed.  Complete it now.

            //

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

            }

        }

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: