reactos操作系统实现(133)
VfatReadDiskPartial函数主要用来构造一个IRP给底层驱动程序去读取数据返回。具体实现代码如下: #001 NTSTATUS #002 VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext, #003 IN PLARGE_INTEGER ReadOffset, #004 IN ULONG ReadLength, #005 ULONG BufferOffset, #006 IN BOOLEAN Wait) #007 { #008 PIRP Irp; #009 PIO_STACK_LOCATION StackPtr; #010 NTSTATUS Status; #011 PVOID Buffer; #012 #013 DPRINT ("VfatReadDiskPartial(IrpContext %p,ReadOffset %I64x,ReadLength %d,BufferOffset %x,Wait %d)/n", #014 IrpContext,ReadOffset->QuadPart,ReadLength,BufferOffset,Wait); #015 #016 DPRINT ("Building asynchronous FSD Request.../n"); #017
从IRP的MDL地址获取内存缓冲区。 #018 Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset; #019
创建一个新的IRP。 #020 Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize,TRUE); #021 if (Irp == NULL) #022 { #023 DPRINT("IoAllocateIrp failed/n"); #024 return(STATUS_UNSUCCESSFUL); #025 } #026
设置IRP属性。 #027 Irp->UserIosb = NULL; #028 Irp->Tail.Overlay.Thread = PsGetCurrentThread(); #029 #030 StackPtr = IoGetNextIrpStackLocation(Irp); #031 StackPtr->MajorFunction = IRP_MJ_READ; #032 StackPtr->MinorFunction = 0; #033 StackPtr->Flags = 0; #034 StackPtr->Control = 0;
设置访问设备对象。 #035 StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice; #036 StackPtr->FileObject = NULL; #037 StackPtr->CompletionRoutine = NULL; #038 StackPtr->Parameters.Read.Length = ReadLength; #039 StackPtr->Parameters.Read.ByteOffset = *ReadOffset; #040
创建一个直接内存访问MDL。 #041 if (!IoAllocateMdl(Buffer,FALSE,Irp)) #042 { #043 DPRINT("IoAllocateMdl failed/n"); #044 IoFreeIrp(Irp); #045 return STATUS_UNSUCCESSFUL; #046 } #047 #048 IoBuildPartialMdl(IrpContext->Irp->MdlAddress,Irp->MdlAddress,Buffer,ReadLength); #049
设置I/O完成端口函数。 #050 IoSetCompletionRoutine(Irp, #051 VfatReadWritePartialCompletion, #052 IrpContext, #053 TRUE, #054 TRUE, #055 TRUE); #056 #057 if (Wait) #058 { #059 KeInitializeEvent(&IrpContext->Event,NotificationEvent,FALSE); #060 IrpContext->RefCount = 1; #061 } #062 else #063 { #064 InterlockedIncrement((PLONG)&IrpContext->RefCount); #065 } #066
调储存驱动程序来读取文件数据。 #067 DPRINT ("Calling IO Driver... with irp %p/n",Irp); #068 Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice,Irp); #069
如果读取数据在阻塞状态,就等底层驱动程序完成。 #070 if (Wait && Status == STATUS_PENDING) #071 { #072 KeWaitForSingleObject(&IrpContext->Event,Executive,KernelMode,NULL); #073 Status = IrpContext->Irp->IoStatus.Status; #074 } #075 #076 DPRINT("%x/n",Status); #077 return Status; #078} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |