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

reactos操作系统实现(136)

2009-11-19 23:28 141 查看
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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: