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

reactos操作系统实现(140)

发布时间:2020-12-15 04:59:29 所属栏目:百科 来源:网络整理
导读:在创建文件成功后,然后就往文件里写入数据,而写入数据说明就需要文件系统给文件分配储存空间,以便保存这些数据到磁盘里,下面就来分析分配文件大小的函数,如下: #001 NTSTATUS #002 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, #003 PV

在创建文件成功后,然后就往文件里写入数据,而写入数据说明就需要文件系统给文件分配储存空间,以便保存这些数据到磁盘里,下面就来分析分配文件大小的函数,如下:

#001 NTSTATUS

#002 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,

#003 PVFATFCB Fcb,

#004 PDEVICE_EXTENSION DeviceExt,

#005 PLARGE_INTEGER AllocationSize)

#006 {

#007 ULONG OldSize;

#008 ULONG Cluster,FirstCluster;

#009 NTSTATUS Status;

#010

获取每簇分配多少字节。

#011 ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;

获取需要分配的大小字节。

#012 ULONG NewSize = AllocationSize->u.LowPart;

#013 ULONG NCluster;

#014 BOOLEAN AllocSizeChanged = FALSE;

#015

#016 DPRINT("VfatSetAllocationSizeInformation(File <%wZ>,AllocationSize %d %d)/n",&Fcb->PathNameU,

#017 AllocationSize->HighPart,AllocationSize->LowPart);

#018

获取原来文件的大小。

#019 if (Fcb->Flags & FCB_IS_FATX_ENTRY)

#020 OldSize = Fcb->entry.FatX.FileSize;

#021 else

#022 OldSize = Fcb->entry.Fat.FileSize;

如果请求分配超过32位大小,就返回出错,不支持这样的大小。

#023 if (AllocationSize->u.HighPart > 0)

#024 {

#025 return STATUS_INVALID_PARAMETER;

#026 }

如果文件的大小与新需求的大小一样,说明它已经分配成功了。

#027 if (OldSize == NewSize)

#028 {

#029 return(STATUS_SUCCESS);

#030 }

#031

从目录项里获取文件的首簇开始位置。

#032 FirstCluster = vfatDirEntryGetFirstCluster (DeviceExt,&Fcb->entry);

#033

如果请求的大小大于已经分配的大小,说明需要重新分配更大的空间。

#034 if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)

#035 {

标志分配文件大小发生了改变。

#036 AllocSizeChanged = TRUE;

如果首簇为0,说明从第一项开始。

#037 if (FirstCluster == 0)

#038 {

#039 Fcb->LastCluster = Fcb->LastOffset = 0;

获取下一簇的标识来判断磁盘是否满了。

#040 Status = NextCluster (DeviceExt,FirstCluster,&FirstCluster,TRUE);

#041 if (!NT_SUCCESS(Status))

#042 {

#043 DPRINT1("NextCluster failed. Status = %x/n",Status);

#044 return Status;

#045 }

如果下一簇就已经标记为已满标志,说明磁盘已经写满,不能再写入任何数据,直接返回出错。

#046 if (FirstCluster == 0xffffffff)

#047 {

#048 return STATUS_DISK_FULL;

#049 }

计算文件需要分配大小的最后簇号。

#050 Status = OffsetToCluster(DeviceExt,

#051 ROUND_DOWN(NewSize - 1,ClusterSize),

#052 &NCluster,TRUE);

如果尝试分配不成功,说明磁盘已经满了,不能再保存数据。

#053 if (NCluster == 0xffffffff || !NT_SUCCESS(Status))

#054 {

#055 /* disk is full */

#056 NCluster = Cluster = FirstCluster;

#057 Status = STATUS_SUCCESS;

清空所有分配的簇。

#058 while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)

#059 {

#060 Status = NextCluster (DeviceExt,&NCluster,FALSE);

#061 WriteCluster (DeviceExt,Cluster,0);

#062 Cluster = NCluster;

#063 }

#064 return STATUS_DISK_FULL;

#065 }

到这里已经分配文件需要的大小成功,设置文件控制块指向分配的首簇号。

#066 if (Fcb->Flags & FCB_IS_FATX_ENTRY)

#067 {

#068 Fcb->entry.FatX.FirstCluster = FirstCluster;

#069 }

#070 else

#071 {

#072 if (DeviceExt->FatInfo.FatType == FAT32)

#073 {

#074 Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);

#075 Fcb->entry.Fat.FirstClusterHigh = FirstCluster >> 16;

#076 }

#077 else

#078 {

#079 ASSERT((FirstCluster >> 16) == 0);

#080 Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);

#081 }

#082 }

#083 }

#084 else

#085 {

以下进行不首簇的文件分配。

#086 if (Fcb->LastCluster > 0)

#087 {

#088 if (Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize == Fcb->LastOffset)

#089 {

#090 Cluster = Fcb->LastCluster;

#091 Status = STATUS_SUCCESS;

#092 }

#093 else

#094 {

#095 Status = OffsetToCluster(DeviceExt,Fcb->LastCluster,

#096 Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize - Fcb->LastOffset,

#097 &Cluster,FALSE);

#098 }

#099 }

#100 else

#101 {

#102 Status = OffsetToCluster(DeviceExt,

#103 Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,

#104 &Cluster,FALSE);

#105 }

#106 if (!NT_SUCCESS(Status))

#107 {

#108 return Status;

#109 }

#110

#111 Fcb->LastCluster = Cluster;

#112 Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;

#113

#114 /* FIXME: Check status */

#115 /* Cluster points now to the last cluster within the chain */

#116 Status = OffsetToCluster(DeviceExt,

#117 ROUND_DOWN(NewSize - 1,ClusterSize) - Fcb->LastOffset,

#118 &NCluster,TRUE);

#119 if (NCluster == 0xffffffff || !NT_SUCCESS(Status))

#120 {

#121 /* disk is full */

#122 NCluster = Cluster;

#123 Status = NextCluster (DeviceExt,FALSE);

#124 WriteCluster(DeviceExt,0xffffffff);

#125 Cluster = NCluster;

#126 while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)

#127 {

#128 Status = NextCluster (DeviceExt,FALSE);

#129 WriteCluster (DeviceExt,0);

#130 Cluster = NCluster;

#131 }

#132 return STATUS_DISK_FULL;

#133 }

#134 }

#135 UpdateFileSize(FileObject,Fcb,NewSize,ClusterSize);

#136 }

#137 else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)

#138 {

下面进行文件减小的分配。

#139 AllocSizeChanged = TRUE;

#140 /* FIXME: Use the cached cluster/offset better way. */

#141 Fcb->LastCluster = Fcb->LastOffset = 0;

#142 UpdateFileSize(FileObject,ClusterSize);

#143 if (NewSize > 0)

#144 {

#145 Status = OffsetToCluster(DeviceExt,

#146 ROUND_DOWN(NewSize - 1,

#147 &Cluster,FALSE);

#148

#149 NCluster = Cluster;

#150 Status = NextCluster (DeviceExt,FALSE);

#151 WriteCluster(DeviceExt,0xffffffff);

#152 Cluster = NCluster;

#153 }

#154 else

#155 {

#156 if (Fcb->Flags & FCB_IS_FATX_ENTRY)

#157 {

#158 Fcb->entry.FatX.FirstCluster = 0;

#159 }

#160 else

#161 {

#162 if (DeviceExt->FatInfo.FatType == FAT32)

#163 {

#164 Fcb->entry.Fat.FirstCluster = 0;

#165 Fcb->entry.Fat.FirstClusterHigh = 0;

#166 }

#167 else

#168 {

#169 Fcb->entry.Fat.FirstCluster = 0;

#170 }

#171 }

#172

#173 NCluster = Cluster = FirstCluster;

#174 Status = STATUS_SUCCESS;

#175 }

#176 while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)

#177 {

#178 Status = NextCluster (DeviceExt,FALSE);

#179 WriteCluster (DeviceExt,0);

#180 Cluster = NCluster;

#181 }

#182 }

#183 else

#184 {

更新文件的大小。

#185 UpdateFileSize(FileObject,ClusterSize);

#186 }

更新文件的大小到目录项。

#187 /* Update the on-disk directory entry */

#188 Fcb->Flags |= FCB_IS_DIRTY;

#189 if (AllocSizeChanged)

#190 {

#191 VfatUpdateEntry(Fcb);

#192 }

#193 return STATUS_SUCCESS;

#194}

(编辑:李大同)

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

    推荐文章
      热点阅读