提交 36168501 创建 作者: 群组管理员's avatar 群组管理员

Merge branch '4a59f84e' into 'master'

35862 See merge request !2
...@@ -9,8 +9,6 @@ Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。 ...@@ -9,8 +9,6 @@ Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
描述: FAT12 文件系统驱动的实现。 描述: FAT12 文件系统驱动的实现。
*******************************************************************************/ *******************************************************************************/
#include "iop.h" #include "iop.h"
...@@ -30,6 +28,7 @@ FatInitializeDriver( ...@@ -30,6 +28,7 @@ FatInitializeDriver(
DriverObject->Set = FatSet; DriverObject->Set = FatSet;
} }
// //
// 驱动程序的 AddDevice 功能函数。 // 驱动程序的 AddDevice 功能函数。
// //
...@@ -820,43 +819,94 @@ FatReadFile( ...@@ -820,43 +819,94 @@ FatReadFile(
} }
} }
STATUS STATUS
FatWriteFile( FatWriteFile(
IN PVCB Vcb, IN PVCB Vcb,
IN PFCB File, IN PFCB File,
IN ULONG Offset, IN ULONG Offset,
IN ULONG BytesToWrite, IN ULONG BytesToWrite,
IN PVOID Buffer, OUT PVOID Buffer,
OUT PULONG BytesWriten OUT PULONG BytesWriten
) )
/*++ {
STATUS Status;
功能描述: // 由于在将新分配的簇插入簇链尾部时,必须知道前一个簇的簇号,
在文件指定的偏移位置开始写数据,如果偏移位置小于文件大小则覆盖原有内容,如果 // 所以定义了“前一个簇号”和“当前簇号”两个变量。
写范围超出文件大小则自动增加文件大小,如果文件大小增加后超过文件占用的磁盘空 USHORT PrevClusterNum, CurrentClusterNum;
间大小则自动为文件分配新的簇,增加文件占用的磁盘空间。 USHORT NewClusterNum;
这里注意两个概念,文件大小和文件占用磁盘空间。因为文件占用磁盘空间是以簇为单 ULONG ClusterIndex;
位的,而文件大小的单位是字节,所以文件大小 <= 文件占用磁盘空间,所以当文件长 ULONG FirstSectorOfCluster;
度增加时,并不一定要增加磁盘占用空间。例如一个文件当前只有1字节,那么它占用了 ULONG OffsetInSector;
一个簇的磁盘空间。当文件大小增加到10字节时,它占用的磁盘空间仍然为一个簇。当
它的大小增加到超过一个簇的大小时,那么就需要为它增加磁盘空间了。 ULONG i;
参数: // 写入的起始位置不能超出文件大小(并不影响增加文件大小或增加簇,想想原因?)
Vcb -- 卷控制块指针。 if (Offset > File->FileSize)
File -- 文件控制块指针。 return STATUS_SUCCESS;
Offset -- 开始写的偏移位置。
BytesToWrite -- 写的字节数。
Buffer -- 指向存放要写的数据。
BytesWriten -- 指针,指向用于保存实际完成写的字节数的变量。
返回值: // 根据簇的大小,计算写入的起始位置在簇链的第几个簇中(从 0 开始计数)
如果成功则返回STATUS_SUCCESS。 ClusterIndex = Offset / FatBytesPerCluster(&Vcb->Bpb);
// 顺着簇链向后查找写入的起始位置所在簇的簇号。
PrevClusterNum = 0;
CurrentClusterNum = File->FirstCluster;
for (i = ClusterIndex; i > 0; i--) {
PrevClusterNum = CurrentClusterNum;
CurrentClusterNum = FatGetFatEntryValue(Vcb, PrevClusterNum);
}
--*/ // 如果写入的起始位置还没有对应的簇,就增加簇
{ if (0 == CurrentClusterNum || CurrentClusterNum >= 0xFF8) {
return STATUS_NOT_SUPPORTED;
// 为文件分配一个空闲簇
FatAllocateOneCluster(Vcb, &NewClusterNum);
// 将新分配的簇安装到簇链中
if (0 == File->FirstCluster)
File->FirstCluster = NewClusterNum;
else
FatSetFatEntryValue(Vcb, PrevClusterNum, NewClusterNum);
CurrentClusterNum = NewClusterNum;
}
// 计算当前簇的第一个扇区的扇区号。簇从 2 开始计数。
FirstSectorOfCluster = Vcb->FirstDataSector + (CurrentClusterNum - 2) * Vcb->Bpb.SectorsPerCluster;
// 计算写位置在扇区内的字节偏移。
OffsetInSector = Offset % Vcb->Bpb.BytesPerSector;
// 为了简单,暂时只处理一个簇包含一个扇区的情况。
// 并且只处理写入的数据在一个扇区范围内的情况。
Status = IopReadWriteSector( Vcb->DiskDevice,
FirstSectorOfCluster,
OffsetInSector,
(PCHAR)Buffer,
BytesToWrite,
FALSE );
if (!EOS_SUCCESS(Status))
return Status;
// 如果文件长度增加了则必须修改文件的长度。
if (Offset + BytesToWrite > File->FileSize) {
File->FileSize = Offset + BytesToWrite;
// 如果是数据文件则需要同步修改文件在磁盘上对应的 DIRENT 结构
// 体。目录文件的 DIRENT 结构体中的 FileSize 永远为 0,无需修改。
if (!File->AttrDirectory)
FatWriteDirEntry(Vcb, File);
}
// 返回实际写入的字节数量
*BytesWriten = BytesToWrite;
return STATUS_SUCCESS;
} }
STATUS STATUS
FatOpenFileInDirectory( FatOpenFileInDirectory(
IN PVCB Vcb, IN PVCB Vcb,
......
没有这种文件类型的预览
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论