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

你可能感兴趣的:(react)