微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

reactos操作系统实现(136)

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,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}

原文地址:https://www.jb51.cc/react/308388.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐