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} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |