您的位置:首页 > Web前端 > React

reactos操作系统实现(133)

2009-11-15 22:23 477 查看
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,
ReadLength, FALSE, 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,
FALSE, NULL);

#073 Status =
IrpContext->Irp->IoStatus.Status;

#074 }

#075

#076 DPRINT("%x/n",
Status);

#077 return Status;

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