加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(131)

发布时间:2020-12-15 04:59:39 所属栏目:百科 来源:网络整理
导读:VfatRead 函数用来读取 FAT 文件系统里的文件数据,如果缓冲区里有数据就直接从缓冲区里读取,否则就从磁盘上读

VfatRead函数用来读取FAT文件系统里的文件数据,如果缓冲区里有数据就直接从缓冲区里读取,否则就从磁盘上读取。具体实现如下:

#001 NTSTATUS

#002 VfatRead(PVFAT_IRP_CONTEXT IrpContext)

#003 {

#004 NTSTATUS Status;

#005 PVFATFCB Fcb;

#006 ULONG Length = 0;

#007 ULONG ReturnedLength = 0;

#008 PERESOURCE Resource = NULL;

#009 LARGE_INTEGER ByteOffset;

#010 PVOID Buffer;

#011 PDEVICE_OBJECT DeviceToVerify;

#012 ULONG BytesPerSector;

#013

#014 ASSERT(IrpContext);

#015

#016 DPRINT("VfatRead(IrpContext %p)/n",IrpContext);

#017

#018 ASSERT(IrpContext->DeviceObject);

#019

如果是主设备对象,是不允许进行读取的操作。

#020 // This request is not allowed on the main device object

#021 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)

#022 {

#023 DPRINT("VfatRead is called with the main device object./n");

#024 Status = STATUS_INVALID_DEVICE_REQUEST;

#025 goto ByeBye;

#026 }

#027

获取当前文件对象的文件控制块。

#028 ASSERT(IrpContext->DeviceExt);

#029 ASSERT(IrpContext->FileObject);

#030 Fcb = IrpContext->FileObject->FsContext;

#031 ASSERT(Fcb);

#032

#033 DPRINT("<%wZ>/n",&Fcb->PathNameU);

#034

如果当前文件是分页文件,就直接传送给下层驱动程序。

#035 if (Fcb->Flags & FCB_IS_PAGE_FILE)

#036 {

#037 PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;

#038 IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;

#039 IoSkipCurrentIrpStackLocation(IrpContext->Irp);

#040 DPRINT("Read from page file,disk offset %I64x/n",IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart);

#041 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice,IrpContext->Irp);

#042 VfatFreeIrpContext(IrpContext);

#043 return Status;

#044 }

#045

获取读取的偏移位置。

#046 ByteOffset = IrpContext->Stack->Parameters.Read.ByteOffset;

获取读取的长度。

#047 Length = IrpContext->Stack->Parameters.Read.Length;

获取每个扇区的大小。

#048 BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;

#049

如果当前是目录,但没有页可以读取,就返回出错。

#050 /* fail if file is a directory and no paged read */

#051 if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))

#052 {

#053 Status = STATUS_INVALID_PARAMETER;

#054 goto ByeBye;

#055 }

#056

#057

#058 DPRINT("'%wZ',Offset: %d,Length %d/n",&Fcb->PathNameU,ByteOffset.u.LowPart,Length);

#059

#060 if (ByteOffset.u.HighPart && !(Fcb->Flags & FCB_IS_VOLUME))

#061 {

#062 Status = STATUS_INVALID_PARAMETER;

#063 goto ByeBye;

#064 }

#065 if (ByteOffset.QuadPart >= Fcb->RFCB.FileSize.QuadPart)

#066 {

#067 IrpContext->Irp->IoStatus.Information = 0;

#068 Status = STATUS_END_OF_FILE;

#069 goto ByeBye;

#070 }

#071 if (IrpContext->Irp->Flags & (IRP_PAGING_IO | IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME))

#072 {

#073 if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)

#074 {

#075 DPRINT("%d %d/n",Length);

#076 // non cached read must be sector aligned

#077 Status = STATUS_INVALID_PARAMETER;

#078 goto ByeBye;

#079 }

#080 }

#081 if (Length == 0)

#082 {

#083 IrpContext->Irp->IoStatus.Information = 0;

#084 Status = STATUS_SUCCESS;

#085 goto ByeBye;

#086 }

#087

获取共享资源。

#088 if (Fcb->Flags & FCB_IS_VOLUME)

#089 {

#090 Resource = &IrpContext->DeviceExt->DirResource;

#091 }

#092 else if (IrpContext->Irp->Flags & IRP_PAGING_IO)

#093 {

#094 Resource = &Fcb->PagingIoResource;

#095 }

#096 else

#097 {

#098 Resource = &Fcb->MainResource;

#099 }

判断共享资源是否允许读取。

#100 if (!ExAcquireResourceSharedLite(Resource,

#101 IrpContext->Flags & IRPCONTEXT_CANWAIT ? TRUE : FALSE))

#102 {

#103 Resource = NULL;

#104 Status = STATUS_PENDING;

#105 goto ByeBye;

#106 }

#107

#108 if (!(IrpContext->Irp->Flags & IRP_PAGING_IO) &&

#109 FsRtlAreThereCurrentFileLocks(&Fcb->FileLock))

#110 {

#111 if (!FsRtlCheckLockForReadAccess(&Fcb->FileLock,IrpContext->Irp))

#112 {

#113 Status = STATUS_FILE_LOCK_CONFLICT;

#114 goto ByeBye;

#115 }

#116 }

#117

获取用户接收数据的缓冲区。

#118 Buffer = VfatGetUserBuffer(IrpContext->Irp);

#119 if (!Buffer)

#120 {

#121 Status = STATUS_INVALID_USER_BUFFER;

#122 goto ByeBye;

#123 }

#124

#125 if (!(IrpContext->Irp->Flags & (IRP_NOCACHE|IRP_PAGING_IO)) &&

#126 !(Fcb->Flags & (FCB_IS_PAGE_FILE|FCB_IS_VOLUME)))

#127 {

#128 // cached read

#129 Status = STATUS_SUCCESS;

#130 if (ByteOffset.u.LowPart + Length > Fcb->RFCB.FileSize.u.LowPart)

#131 {

#132 Length = Fcb->RFCB.FileSize.u.LowPart - ByteOffset.u.LowPart;

#133 Status = /*STATUS_END_OF_FILE*/STATUS_SUCCESS;

#134 }

#135

#136 if (IrpContext->FileObject->PrivateCacheMap == NULL)

#137 {

#138 CcInitializeCacheMap(IrpContext->FileObject,

#139 (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),

#140 FALSE,

#141 &(VfatGlobalData->CacheMgrCallbacks),

#142 Fcb);

#143 }

从缓存里读取磁盘数据。

#144 if (!CcCopyRead(IrpContext->FileObject,&ByteOffset,Length,

#145 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT),Buffer,

#146 &IrpContext->Irp->IoStatus))

#147 {

#148 Status = STATUS_PENDING;

#149 goto ByeBye;

#150 }

#151 if (!NT_SUCCESS(IrpContext->Irp->IoStatus.Status))

#152 {

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

#154 }

#155 }

#156 else

#157 {

否则从磁盘文件里读取。

#158 // non cached read

#159 if (ByteOffset.QuadPart + Length > ROUND_UP(Fcb->RFCB.FileSize.QuadPart,BytesPerSector))

#160 {

#161 Length = (ULONG)(ROUND_UP(Fcb->RFCB.FileSize.QuadPart,BytesPerSector) - ByteOffset.QuadPart);

#162 }

#163

#164 Status = VfatLockUserBuffer(IrpContext->Irp,IoWriteAccess);

#165 if (!NT_SUCCESS(Status))

#166 {

#167 goto ByeBye;

#168 }

#169

FAT管理的磁盘里读取文件数据。

#170 Status = VfatReadFileData(IrpContext,ByteOffset,&ReturnedLength);

#171 /**/

#172 if (Status == STATUS_VERIFY_REQUIRED)

#173 {

如果有校验的请求,就进行校验。

#174 DPRINT("VfatReadFile returned STATUS_VERIFY_REQUIRED/n");

#175 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());

#176 IoSetDeviceToVerify(PsGetCurrentThread(),DeviceToVerify);

#177 Status = IoVerifyVolume (DeviceToVerify,FALSE);

#178

#179 if (NT_SUCCESS(Status))

#180 {

#181 Status = VfatReadFileData(IrpContext,

#182 ByteOffset,&ReturnedLength);

#183 }

#184

#185 }

#186 /**/

#187 if (NT_SUCCESS(Status))

#188 {

#189 IrpContext->Irp->IoStatus.Information = ReturnedLength;

#190 }

#191 }

#192

下面是退出处理。

#193 ByeBye:

#194 if (Resource)

#195 {

#196 ExReleaseResourceLite(Resource);

#197 }

#198

如果读取的操作,还在阻塞状态,就进行等待队列。

#199 if (Status == STATUS_PENDING)

#200 {

#201 Status = VfatLockUserBuffer(IrpContext->Irp,IoWriteAccess);

#202 if (NT_SUCCESS(Status))

#203 {

#204 Status = VfatQueueRequest(IrpContext);

#205 }

#206 else

#207 {

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

#209 IoCompleteRequest(IrpContext->Irp,IO_NO_INCREMENT);

#210 VfatFreeIrpContext(IrpContext);

#211 }

#212 }

#213 else

#214 {

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

#216 if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO &&

#217 !(IrpContext->Irp->Flags & IRP_PAGING_IO) &&

#218 (NT_SUCCESS(Status) || Status==STATUS_END_OF_FILE))

#219 {

#220 IrpContext->FileObject->CurrentByteOffset.QuadPart =

#221 ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;

#222 }

#223

完成这个IRP请求。

#224 IoCompleteRequest(IrpContext->Irp,

#225 (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));

#226 VfatFreeIrpContext(IrpContext);

#227 }

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

#229 return Status;

#230}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读