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

reactos操作系统实现(136)

2009-11-19 23:28 232 查看
VfatMount函数主要用来安装FAT文件卷,具体实现代码如下:

#001 static NTSTATUS

#002 VfatMount (PVFAT_IRP_CONTEXT
IrpContext)

#003 /*

#004 * FUNCTION: Mount the
filesystem

#005 */

#006 {

#007 PDEVICE_OBJECT
DeviceObject = NULL;

#008 PDEVICE_EXTENSION
DeviceExt = NULL;

#009 BOOLEAN RecognizedFS;

#010 NTSTATUS Status;

#011 PVFATFCB Fcb = NULL;

#012 PVFATFCB VolumeFcb =
NULL;

#013 PVFATCCB Ccb = NULL;

#014 PDEVICE_OBJECT
DeviceToMount;

#015 PVPB Vpb;

FAT的文件系统名称。

#016 UNICODE_STRING NameU =
RTL_CONSTANT_STRING(L"//$$Fat$$");

操作系统文件卷名称。

#017 UNICODE_STRING
VolumeNameU = RTL_CONSTANT_STRING(L"//$$Volume$$");

#018 ULONG HashTableSize;

#019 ULONG eocMark;

#020 FATINFO FatInfo;

#021

#022
DPRINT("VfatMount(IrpContext %p)/n", IrpContext);

#023

#024 ASSERT(IrpContext);

#025

如果当前请求的设备与FAT的设备不一致,就返回出错。

#026 if
(IrpContext->DeviceObject != VfatGlobalData->DeviceObject)

#027 {

#028 Status =
STATUS_INVALID_DEVICE_REQUEST;

#029 goto ByeBye;

#030 }

#031

获取当前要加载的设备。

#032 DeviceToMount =
IrpContext->Stack->Parameters.MountVolume.DeviceObject;

获取卷描述信息。

#033 Vpb =
IrpContext->Stack->Parameters.MountVolume.Vpb;

#034

在这里调用函数VfatHasFileSystem来判断要加载的设备是否为FAT文件系统设备,如果为FAT文件系统,RecognizedFS就返回TRUE,并且FatInfo返回FAT文件系统描述信息。

#035 Status =
VfatHasFileSystem (DeviceToMount, &RecognizedFS, &FatInfo);

#036 if (!NT_SUCCESS(Status))

#037 {

#038 goto ByeBye;

#039 }

#040

如果不认识这个FAT的文件系统,就返回出错。

#041 if (RecognizedFS ==
FALSE)

#042 {

#043 DPRINT("VFAT:
Unrecognized Volume/n");

#044 Status =
STATUS_UNRECOGNIZED_VOLUME;

#045 goto ByeBye;

#046 }

#047

根据文件系统的类型来设置HASH表项的大小。

#048 /* Use prime numbers for
the table size */

#049 if (FatInfo.FatType ==
FAT12)

#050 {

#051 HashTableSize = 4099;
// 4096 = 4 * 1024

#052 }

#053 else if (FatInfo.FatType
== FAT16 ||

#054 FatInfo.FatType
== FATX16)

#055 {

#056 HashTableSize = 16411;
// 16384 = 16 * 1024

#057 }

#058 else

#059 {

#060 HashTableSize = 65537;
// 65536 = 64 * 1024;

#061 }

#062 HashTableSize =
FCB_HASH_TABLE_SIZE;

#063 DPRINT("VFAT:
Recognized volume/n");

为当前的文件卷创建一个文件设备。

#064 Status =
IoCreateDevice(VfatGlobalData->DriverObject,

#065
ROUND_UP(sizeof (DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*)
* HashTableSize,

#066
NULL,

#067 FILE_DEVICE_DISK_FILE_SYSTEM,

#068
0,

#069
FALSE,

#070
&DeviceObject);

#071 if (!NT_SUCCESS(Status))

#072 {

#073 goto ByeBye;

#074 }

#075

设置设备属性。

#076 DeviceObject->Flags =
DeviceObject->Flags | DO_DIRECT_IO;

#077 DeviceExt = (PVOID)
DeviceObject->DeviceExtension;

#078 RtlZeroMemory(DeviceExt,
ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) *
HashTableSize);

#079
DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt +
ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)));

#080
DeviceExt->HashTableSize = HashTableSize;

#081

文件卷设备和磁盘设备使用同样的VPB。

#082 /* use same vpb as device
disk */

#083 DeviceObject->Vpb = Vpb;

#084 DeviceToMount->Vpb =
Vpb;

#085

安装磁盘设备到这个文件卷功能设备上。

#086 Status =
VfatMountDevice(DeviceExt, DeviceToMount);

#087 if (!NT_SUCCESS(Status))

#088 {

#089 /* FIXME: delete
device object */

#090 goto ByeBye;

#091 }

#092

#093
DPRINT("BytesPerSector:
%d/n", DeviceExt->FatInfo.BytesPerSector);

#094
DPRINT("SectorsPerCluster:
%d/n", DeviceExt->FatInfo.SectorsPerCluster);

#095
DPRINT("FATCount:
%d/n", DeviceExt->FatInfo.FATCount);

#096
DPRINT("FATSectors:
%d/n", DeviceExt->FatInfo.FATSectors);

#097
DPRINT("RootStart:
%d/n", DeviceExt->FatInfo.rootStart);

#098
DPRINT("DataStart:
%d/n", DeviceExt->FatInfo.dataStart);

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

#100 {

#101
DPRINT("RootCluster:
%d/n", DeviceExt->FatInfo.RootCluster);

#102 }

#103

根据不同的文件系统类型来进行回调函数设置。

#104 switch
(DeviceExt->FatInfo.FatType)

#105 {

#106 case FAT12:

#107 DeviceExt->GetNextCluster
= FAT12GetNextCluster;

#108
DeviceExt->FindAndMarkAvailableCluster =
FAT12FindAndMarkAvailableCluster;

#109
DeviceExt->WriteCluster = FAT12WriteCluster;

#110
DeviceExt->CleanShutBitMask = 0;

#111 break;

#112

#113 case FAT16:

#114 case FATX16:

#115
DeviceExt->GetNextCluster = FAT16GetNextCluster;

#116
DeviceExt->FindAndMarkAvailableCluster =
FAT16FindAndMarkAvailableCluster;

#117
DeviceExt->WriteCluster = FAT16WriteCluster;

#118
DeviceExt->CleanShutBitMask = 0x8000;

#119 break;

#120

#121 case FAT32:

#122 case FATX32:

#123
DeviceExt->GetNextCluster = FAT32GetNextCluster;

#124
DeviceExt->FindAndMarkAvailableCluster =
FAT32FindAndMarkAvailableCluster;

#125
DeviceExt->WriteCluster = FAT32WriteCluster;

#126
DeviceExt->CleanShutBitMask = 0x80000000;

#127 break;

#128 }

#129

#130 if
(DeviceExt->FatInfo.FatType == FATX16

#131 ||
DeviceExt->FatInfo.FatType == FATX32)

#132 {

#133 DeviceExt->Flags |=
VCB_IS_FATX;

#134
DeviceExt->GetNextDirEntry = FATXGetNextDirEntry;

#135
DeviceExt->BaseDateYear = 2000;

#136 }

#137 else

#138 {

#139
DeviceExt->GetNextDirEntry = FATGetNextDirEntry;

#140
DeviceExt->BaseDateYear = 1980;

#141 }

#142

设置文件系统功能设备的底层设备,以便把IRP传送给底层驱动处理。

#143
DeviceExt->StorageDevice = DeviceToMount;

#144
DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;

#145
DeviceExt->StorageDevice->Vpb->RealDevice =
DeviceExt->StorageDevice;

#146 DeviceExt->StorageDevice->Vpb->Flags
|= VPB_MOUNTED;

#147
DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize +
1;

#148 DeviceObject->Flags
&= ~DO_DEVICE_INITIALIZING;

#149

#150
DPRINT("FsDeviceObject %p/n", DeviceObject);

#151

初始化设备清除使用的共享资源。

#152 /* Initialize this
resource early ... it's used in VfatCleanup */

#153
ExInitializeResourceLite(&DeviceExt->DirResource);

#154

创建流文件对象用来表示一个文件卷。

#155
DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL,
DeviceExt->StorageDevice);

创建一块文件控制块。

#156 Fcb =
vfatNewFCB(DeviceExt, &NameU);

#157 if (Fcb == NULL)

#158 {

#159 Status =
STATUS_INSUFFICIENT_RESOURCES;

#160 goto ByeBye;

#161 }

#162 Ccb =
ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);

#163 if (Ccb == NULL)

#164 {

#165 Status = STATUS_INSUFFICIENT_RESOURCES;

#166 goto ByeBye;

#167 }

#168

设置扩展属性。

#169 RtlZeroMemory(Ccb, sizeof
(VFATCCB));

#170
DeviceExt->FATFileObject->FsContext = Fcb;

#171
DeviceExt->FATFileObject->FsContext2 = Ccb;

#172
DeviceExt->FATFileObject->SectionObjectPointer =
&Fcb->SectionObjectPointers;

#173
DeviceExt->FATFileObject->PrivateCacheMap = NULL;

#174
DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;

#175 Fcb->FileObject =
DeviceExt->FATFileObject;

#176

设置为FAT标识。

#177 Fcb->Flags |=
FCB_IS_FAT;

#178

#179
Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors *
DeviceExt->FatInfo.BytesPerSector;

#180
Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;

#181
Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;

#182

初始化文件读写的缓冲区。

#183
CcInitializeCacheMap(DeviceExt->FATFileObject,

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

#185
TRUE,

#186
&VfatGlobalData->CacheMgrCallbacks,

#187
Fcb);

#188

#189
DeviceExt->LastAvailableCluster = 2;

#190
ExInitializeResourceLite(&DeviceExt->FatResource);

#191

#192
InitializeListHead(&DeviceExt->FcbListHead);

#193

创建文件卷控制块。

#194 VolumeFcb =
vfatNewFCB(DeviceExt, &VolumeNameU);

#195 if (VolumeFcb == NULL)

#196 {

#197 Status =
STATUS_INSUFFICIENT_RESOURCES;

#198 goto ByeBye;

#199 }

#200 VolumeFcb->Flags =
FCB_IS_VOLUME;

#201
VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors *
DeviceExt->FatInfo.BytesPerSector;

#202
VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize;

#203
VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize;

#204 DeviceExt->VolumeFcb =
VolumeFcb;

#205

#206
ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock,
TRUE);

#207
InsertHeadList(&VfatGlobalData->VolumeListHead,
&DeviceExt->VolumeListEntry);

#208
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);

#209

读取文件卷序号。

#210 /* read serial number */

#211
DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID;

#212

读取文件卷标。

#213 /* read volume label */

#214
ReadVolumeLabel(DeviceExt,
DeviceObject->Vpb);

#215

读取并清除关闭标志。

#216 /* read clean shutdown bit
status */

#217 Status =
GetNextCluster(DeviceExt, 1, &eocMark);

#218 if (NT_SUCCESS(Status))

#219 {

#220 if (eocMark &
DeviceExt->CleanShutBitMask)

#221 {

#222 /* unset clean
shutdown bit */

#223 eocMark &= ~DeviceExt->CleanShutBitMask;

#224
WriteCluster(DeviceExt, 1, eocMark);

#225 VolumeFcb->Flags
|= VCB_CLEAR_DIRTY;

#226 }

#227 }

#228 VolumeFcb->Flags |=
VCB_IS_DIRTY;

#229

#230 Status = STATUS_SUCCESS;

#231 ByeBye:

#232

#233 if (!NT_SUCCESS(Status))

#234 {

#235 // cleanup

#236 if (DeviceExt
&& DeviceExt->FATFileObject)

#237 ObDereferenceObject
(DeviceExt->FATFileObject);

#238 if (Fcb)

#239 vfatDestroyFCB(Fcb);

#240 if (Ccb)

#241 vfatDestroyCCB(Ccb);

#242 if (DeviceObject)

#243
IoDeleteDevice(DeviceObject);

#244 if (VolumeFcb)

#245
vfatDestroyFCB(VolumeFcb);

#246 }

#247 return Status;

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