VfatMount@H_502_3@函数主要用来安装FAT文件卷,具体实现代码如下:
#001@H_502_3@ static NTSTATUS
#002@H_502_3@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
#003@H_502_3@ /*
#004@H_502_3@ * FUNCTION: Mount the filesystem
#005@H_502_3@ */
#006@H_502_3@ {
#007@H_502_3@ PDEVICE_OBJECT DeviceObject = NULL;
#008@H_502_3@ PDEVICE_EXTENSION DeviceExt = NULL;
#009@H_502_3@ BOOLEAN RecognizedFS;
#010@H_502_3@ NTSTATUS Status;
#011@H_502_3@ PVFATFCB Fcb = NULL;
#012@H_502_3@ PVFATFCB VolumeFcb = NULL;
#013@H_502_3@ PVFATCCB Ccb = NULL;
#014@H_502_3@ PDEVICE_OBJECT DeviceToMount;
#015@H_502_3@ PVPB Vpb;
#016@H_502_3@ UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"//$$Fat$$");
#017@H_502_3@ UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"//$$Volume$$");
#018@H_502_3@ ULONG HashTableSize;
#019@H_502_3@ ULONG eocMark;
#020@H_502_3@ FATINFO FatInfo;
#021@H_502_3@
#022@H_502_3@ DPRINT("VfatMount(IrpContext %p)/n",IrpContext);
#023@H_502_3@
#024@H_502_3@ ASSERT(IrpContext);
#025@H_502_3@
@H_502_3@如果当前请求的设备与FAT的设备不一致,就返回出错。
#026@H_502_3@ if (IrpContext->DeviceObject != VfatGlobalData->DeviceObject)
#027@H_502_3@ {
#028@H_502_3@ Status = STATUS_INVALID_DEVICE_REQUEST;
#029@H_502_3@ goto ByeBye;
#031@H_502_3@
#032@H_502_3@ DeviceToMount = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
#033@H_502_3@ Vpb = IrpContext->Stack->Parameters.MountVolume.Vpb;
#034
@H_502_3@在这里调用函数VfatHasFileSystem来判断要加载的设备是否为FAT文件系统设备,如果为FAT文件系统,RecognizedFS就返回TRUE,并且FatInfo返回FAT文件系统描述信息。
#035@H_502_3@ Status = VfatHasFileSystem (DeviceToMount,&RecognizedFS,&FatInfo);
#036@H_502_3@ if (!NT_SUCCESS(Status))
#037@H_502_3@ {
#038@H_502_3@ goto ByeBye;
#039@H_502_3@ }
#040
@H_502_3@如果不认识这个FAT的文件系统,就返回出错。
#041@H_502_3@ if (RecognizedFS == FALSE)
#042@H_502_3@ {
#043@H_502_3@ DPRINT("VFAT: Unrecognized Volume/n");
#044@H_502_3@ Status = STATUS_UNRECOGNIZED_VOLUME;
#045@H_502_3@ goto ByeBye;
#046@H_502_3@ }
#047@H_502_3@
@H_502_3@根据文件系统的类型来设置HASH表项的大小。
#048@H_502_3@ /* Use prime numbers for the table size */
#049@H_502_3@ if (FatInfo.FatType == FAT12)
#050@H_502_3@ {
#051@H_502_3@ HashTableSize = 4099; // 4096 = 4 * 1024
#052@H_502_3@ }
#053@H_502_3@ else if (FatInfo.FatType == FAT16 ||
#054@H_502_3@ FatInfo.FatType == FATX16)
#055@H_502_3@ {
#056@H_502_3@ HashTableSize = 16411; // 16384 = 16 * 1024
#057@H_502_3@ }
#058@H_502_3@ else
#059@H_502_3@ {
#060@H_502_3@ HashTableSize = 65537; // 65536 = 64 * 1024;
#061@H_502_3@ }
#062@H_502_3@ HashTableSize = FCB_HASH_TABLE_SIZE;
#063@H_502_3@ DPRINT("VFAT: Recognized volume/n");
#064@H_502_3@ Status = IoCreateDevice(VfatGlobalData->DriverObject,
#065@H_502_3@ ROUND_UP(sizeof (DEVICE_EXTENSION),sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize,
#066@H_502_3@ NULL,
#067@H_502_3@ @H_502_3@FILE_DEVICE_DISK_FILE_SYSTEM,
#068@H_502_3@ 0,
#069@H_502_3@ FALSE,
#070@H_502_3@ &DeviceObject);
#071@H_502_3@ if (!NT_SUCCESS(Status))
#072@H_502_3@ {
#073@H_502_3@ goto ByeBye;
#074@H_502_3@ }
#075@H_502_3@
#076@H_502_3@ DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
#077@H_502_3@ DeviceExt = (PVOID) DeviceObject->DeviceExtension;
#078@H_502_3@ RtlZeroMemory(DeviceExt,ROUND_UP(sizeof(DEVICE_EXTENSION),sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize);
#079@H_502_3@ DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + ROUND_UP(sizeof(DEVICE_EXTENSION),sizeof(ULONG)));
#080@H_502_3@ DeviceExt->HashTableSize = HashTableSize;
#081@H_502_3@
#082@H_502_3@ /* use same vpb as device disk */
#083@H_502_3@ @H_502_3@DeviceObject->Vpb = Vpb;
#084@H_502_3@ DeviceToMount->Vpb = Vpb;
#085@H_502_3@
#086@H_502_3@ Status = VfatMountDevice(DeviceExt,DeviceToMount);
#087@H_502_3@ if (!NT_SUCCESS(Status))
#088@H_502_3@ {
#089@H_502_3@ /* FIXME: delete device object */
#090@H_502_3@ goto ByeBye;
#091@H_502_3@ }
#092@H_502_3@
#093@H_502_3@ DPRINT("BytesPerSector:@H_502_3@ %d/n",DeviceExt->FatInfo.BytesPerSector);
#094@H_502_3@ DPRINT("SectorsPerCluster:@H_502_3@ %d/n",DeviceExt->FatInfo.SectorsPerCluster);
#095@H_502_3@ DPRINT("FATCount:@H_502_3@ %d/n",DeviceExt->FatInfo.FATCount);
#096@H_502_3@ DPRINT("FATSectors:@H_502_3@ %d/n",DeviceExt->FatInfo.FATSectors);
#097@H_502_3@ DPRINT("RootStart:@H_502_3@ %d/n",DeviceExt->FatInfo.rootStart);
#098@H_502_3@ DPRINT("DataStart:@H_502_3@ %d/n",DeviceExt->FatInfo.dataStart);
#099@H_502_3@ if (DeviceExt->FatInfo.FatType == FAT32)
#100@H_502_3@ {
#101@H_502_3@ DPRINT("RootCluster:@H_502_3@ %d/n",DeviceExt->FatInfo.RootCluster);
#102@H_502_3@ }
#103@H_502_3@
@H_502_3@根据不同的文件系统类型来进行回调函数设置。
#104@H_502_3@ switch (DeviceExt->FatInfo.FatType)
#105@H_502_3@ {
#106@H_502_3@ case FAT12:
#107@H_502_3@ DeviceExt->GetNextCluster = FAT12GetNextCluster;
#108@H_502_3@ DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
#109@H_502_3@ DeviceExt->WriteCluster = FAT12WriteCluster;
#110@H_502_3@ DeviceExt->CleanShutBitMask = 0;
#112@H_502_3@
#113@H_502_3@ case FAT16:
#114@H_502_3@ case FATX16:
#115@H_502_3@ DeviceExt->GetNextCluster = FAT16GetNextCluster;
#116@H_502_3@ DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
#117@H_502_3@ DeviceExt->WriteCluster = FAT16WriteCluster;
#118@H_502_3@ DeviceExt->CleanShutBitMask = 0x8000;
#119@H_502_3@ break;
#120@H_502_3@
#121@H_502_3@ case FAT32:
#122@H_502_3@ case FATX32:
#123@H_502_3@ DeviceExt->GetNextCluster = FAT32GetNextCluster;
#124@H_502_3@ DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
#125@H_502_3@ DeviceExt->WriteCluster = FAT32WriteCluster;
#126@H_502_3@ DeviceExt->CleanShutBitMask = 0x80000000;
#127@H_502_3@ break;
#128@H_502_3@ }
#129@H_502_3@
#130@H_502_3@ if (DeviceExt->FatInfo.FatType == FATX16
#131@H_502_3@ || DeviceExt->FatInfo.FatType == FATX32)
#132@H_502_3@ {
#133@H_502_3@ DeviceExt->Flags |= VCB_IS_FATX;
#134@H_502_3@ DeviceExt->GetNextDirEntry = FATXGetNextDirEntry;
#135@H_502_3@ DeviceExt->BaseDateYear = 2000;
#136@H_502_3@ }
#137@H_502_3@ else
#138@H_502_3@ {
#139@H_502_3@ DeviceExt->GetNextDirEntry = FATGetNextDirEntry;
#140@H_502_3@ DeviceExt->BaseDateYear = 1980;
#141@H_502_3@ }
#142@H_502_3@
@H_502_3@设置文件系统功能设备的底层设备,以便把IRP传送给底层驱动处理。
#143@H_502_3@ DeviceExt->StorageDevice = DeviceToMount;
#144@H_502_3@ DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
#145@H_502_3@ DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
#146@H_502_3@ DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
#147@H_502_3@ DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
#148@H_502_3@ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
#149@H_502_3@
#150@H_502_3@ DPRINT("FsDeviceObject %p/n",DeviceObject);
#151@H_502_3@
@H_502_3@初始化设备清除使用的共享资源。
#152@H_502_3@ /* Initialize this resource early ... it's used in VfatCleanup */
#153@H_502_3@ ExInitializeResourceLite(&DeviceExt->DirResource);
#154@H_502_3@
#155@H_502_3@ DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL,DeviceExt->StorageDevice);
#156@H_502_3@ Fcb = vfatNewFCB(DeviceExt,&NameU);
#157@H_502_3@ if (Fcb == NULL)
#158@H_502_3@ {
#159@H_502_3@ Status = STATUS_INSUFFICIENT_RESOURCES;
#160@H_502_3@ goto ByeBye;
#161@H_502_3@ }
#162@H_502_3@ Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
#163@H_502_3@ if (Ccb == NULL)
#164@H_502_3@ {
#165@H_502_3@ Status =@H_502_3@ STATUS_INSUFFICIENT_RESOURCES;
#166@H_502_3@ goto ByeBye;
#167@H_502_3@ }
#168@H_502_3@
#169@H_502_3@ RtlZeroMemory(Ccb,sizeof (VFATCCB));
#170@H_502_3@ DeviceExt->FATFileObject->FsContext = Fcb;
#171@H_502_3@ DeviceExt->FATFileObject->FsContext2 = Ccb;
#172@H_502_3@ DeviceExt->FATFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
#173@H_502_3@ DeviceExt->FATFileObject->PrivateCacheMap = NULL;
#174@H_502_3@ DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
#175@H_502_3@ Fcb->FileObject = DeviceExt->FATFileObject;
#176@H_502_3@
@H_502_3@设置为FAT标识。
#177@H_502_3@ Fcb->Flags |= FCB_IS_FAT;
#178@H_502_3@
#179@H_502_3@ Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
#180@H_502_3@ Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
#181@H_502_3@ Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
#182@H_502_3@
#183@H_502_3@ CcInitializeCacheMap(DeviceExt->FATFileObject,
#184@H_502_3@ (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
#185@H_502_3@ TRUE,
#186@H_502_3@ &VfatGlobalData->CacheMgrCallbacks,
#187@H_502_3@ Fcb);
#188@H_502_3@
#189@H_502_3@ DeviceExt->LastAvailableCluster = 2;
#190@H_502_3@ ExInitializeResourceLite(&DeviceExt->FatResource);
#191@H_502_3@
#192@H_502_3@ InitializeListHead(&DeviceExt->FcbListHead);
#193@H_502_3@
#194@H_502_3@ VolumeFcb = vfatNewFCB(DeviceExt,&VolumeNameU);
#195@H_502_3@ if (VolumeFcb == NULL)
#196@H_502_3@ {
#197@H_502_3@ Status = STATUS_INSUFFICIENT_RESOURCES;
#198@H_502_3@ goto ByeBye;
#199@H_502_3@ }
#200@H_502_3@ VolumeFcb->Flags = FCB_IS_VOLUME;
#201@H_502_3@ VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors * DeviceExt->FatInfo.BytesPerSector;
#202@H_502_3@ VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize;
#203@H_502_3@ VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize;
#204@H_502_3@ DeviceExt->VolumeFcb = VolumeFcb;
#205@H_502_3@
#206@H_502_3@ ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock,TRUE);
#207@H_502_3@ InsertHeadList(&VfatGlobalData->VolumeListHead,&DeviceExt->VolumeListEntry);
#208@H_502_3@ ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
#209
#210@H_502_3@ @H_502_3@/* read serial number */
#211@H_502_3@ DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID;
#212@H_502_3@
#213@H_502_3@ /* read volume label */
#214@H_502_3@ ReadVolumeLabel(DeviceExt,@H_502_3@ DeviceObject->Vpb);
#215@H_502_3@
#216@H_502_3@ /* read clean shutdown bit status */
#217@H_502_3@ Status = GetNextCluster(DeviceExt,1,&eocMark);
#218@H_502_3@ if (NT_SUCCESS(Status))
#219@H_502_3@ {
#220@H_502_3@ if (eocMark & DeviceExt->CleanShutBitMask)
#221@H_502_3@ {
#222@H_502_3@ /* unset clean shutdown bit */
#223@H_502_3@ eocMark &= ~DeviceExt->CleanShutBitMask;
#224@H_502_3@ WriteCluster(DeviceExt,eocMark);
#225@H_502_3@ VolumeFcb->Flags |= VCB_CLEAR_DIRTY;
#226@H_502_3@ }
#227@H_502_3@ }
#228@H_502_3@ VolumeFcb->Flags |= VCB_IS_DIRTY;
#229@H_502_3@
#230@H_502_3@ Status = STATUS_SUCCESS;
#231@H_502_3@ ByeBye:
#232@H_502_3@
#233@H_502_3@ if (!NT_SUCCESS(Status))
#234@H_502_3@ {
#235@H_502_3@ // cleanup
#236@H_502_3@ if (DeviceExt && DeviceExt->FATFileObject)
#237@H_502_3@ ObDereferenceObject (DeviceExt->FATFileObject);
#238@H_502_3@ if (Fcb)
#239@H_502_3@ vfatDestroyFCB(Fcb);
#240@H_502_3@ if (Ccb)
#241@H_502_3@ vfatDestroyCCB(Ccb);
#242@H_502_3@ if (DeviceObject)
#243@H_502_3@ IoDeleteDevice(DeviceObject);
#244@H_502_3@ if (VolumeFcb)
#245@H_502_3@ vfatDestroyFCB(VolumeFcb);
#246@H_502_3@ }
#247@H_502_3@ return Status;
#248}