fsctl.c
来自「一个类似windows」· C语言 代码 · 共 928 行 · 第 1/3 页
C
928 行
DPRINT("FATX32\n");
FatInfo.FatType = FATX32;
}
FatInfo.VolumeID = BootFatX->VolumeID;
FatInfo.FATStart = sizeof(struct _BootSectorFatX) / DiskGeometry.BytesPerSector;
FatInfo.FATCount = BootFatX->FATCount;
FatInfo.FATSectors =
ROUND_UP(FatInfo.Sectors / FatInfo.SectorsPerCluster * (FatInfo.FatType == FATX16 ? 2 : 4), 4096) /
FatInfo.BytesPerSector;
FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
FatInfo.RootCluster = (FatInfo.rootStart - 1) / FatInfo.SectorsPerCluster;
FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
FatInfo.NumberOfClusters = (FatInfo.Sectors - FatInfo.dataStart) / FatInfo.SectorsPerCluster;
if (pFatInfo && *RecognizedFS)
{
*pFatInfo = FatInfo;
}
}
}
ExFreePool(BootFatX);
}
DPRINT("VfatHasFileSystem done\n");
return Status;
}
static NTSTATUS
VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
PDEVICE_OBJECT DeviceToMount)
/*
* FUNCTION: Mounts the device
*/
{
NTSTATUS Status;
BOOLEAN RecognizedFS;
DPRINT("Mounting VFAT device...\n");
Status = VfatHasFileSystem(DeviceToMount, &RecognizedFS, &DeviceExt->FatInfo);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DPRINT("MountVfatdev %d, PAGE_SIZE = %d\n", DeviceExt->FatInfo.BytesPerCluster, PAGE_SIZE);
return(STATUS_SUCCESS);
}
static NTSTATUS
VfatMount (PVFAT_IRP_CONTEXT IrpContext)
/*
* FUNCTION: Mount the filesystem
*/
{
PDEVICE_OBJECT DeviceObject = NULL;
PDEVICE_EXTENSION DeviceExt = NULL;
BOOLEAN RecognizedFS;
NTSTATUS Status;
PVFATFCB Fcb = NULL;
PVFATFCB VolumeFcb = NULL;
PVFATCCB Ccb = NULL;
PDEVICE_OBJECT DeviceToMount;
UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\$$Fat$$");
UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"\\$$Volume$$");
ULONG HashTableSize;
ULONG eocMark;
FATINFO FatInfo;
DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
ASSERT(IrpContext);
if (IrpContext->DeviceObject != VfatGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
DeviceToMount = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS, &FatInfo);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
if (RecognizedFS == FALSE)
{
DPRINT("VFAT: Unrecognized Volume\n");
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
/* Use prime numbers for the table size */
if (FatInfo.FatType == FAT12)
{
HashTableSize = 4099; // 4096 = 4 * 1024
}
else if (FatInfo.FatType == FAT16 ||
FatInfo.FatType == FATX16)
{
HashTableSize = 16411; // 16384 = 16 * 1024
}
else
{
HashTableSize = 65537; // 65536 = 64 * 1024;
}
HashTableSize = FCB_HASH_TABLE_SIZE;
DPRINT("VFAT: Recognized volume\n");
Status = IoCreateDevice(VfatGlobalData->DriverObject,
ROUND_UP(sizeof (DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize,
NULL,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
DeviceExt = (PVOID) DeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExt, ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize);
DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)));
DeviceExt->HashTableSize = HashTableSize;
/* use same vpb as device disk */
DeviceObject->Vpb = DeviceToMount->Vpb;
Status = VfatMountDevice(DeviceExt, DeviceToMount);
if (!NT_SUCCESS(Status))
{
/* FIXME: delete device object */
goto ByeBye;
}
DPRINT("BytesPerSector: %d\n", DeviceExt->FatInfo.BytesPerSector);
DPRINT("SectorsPerCluster: %d\n", DeviceExt->FatInfo.SectorsPerCluster);
DPRINT("FATCount: %d\n", DeviceExt->FatInfo.FATCount);
DPRINT("FATSectors: %d\n", DeviceExt->FatInfo.FATSectors);
DPRINT("RootStart: %d\n", DeviceExt->FatInfo.rootStart);
DPRINT("DataStart: %d\n", DeviceExt->FatInfo.dataStart);
if (DeviceExt->FatInfo.FatType == FAT32)
{
DPRINT("RootCluster: %d\n", DeviceExt->FatInfo.RootCluster);
}
switch (DeviceExt->FatInfo.FatType)
{
case FAT12:
DeviceExt->GetNextCluster = FAT12GetNextCluster;
DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
DeviceExt->WriteCluster = FAT12WriteCluster;
DeviceExt->CleanShutBitMask = 0;
break;
case FAT16:
case FATX16:
DeviceExt->GetNextCluster = FAT16GetNextCluster;
DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
DeviceExt->WriteCluster = FAT16WriteCluster;
DeviceExt->CleanShutBitMask = 0x8000;
break;
case FAT32:
case FATX32:
DeviceExt->GetNextCluster = FAT32GetNextCluster;
DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
DeviceExt->WriteCluster = FAT32WriteCluster;
DeviceExt->CleanShutBitMask = 0x80000000;
break;
}
if (DeviceExt->FatInfo.FatType == FATX16
|| DeviceExt->FatInfo.FatType == FATX32)
{
DeviceExt->Flags |= VCB_IS_FATX;
DeviceExt->GetNextDirEntry = FATXGetNextDirEntry;
DeviceExt->BaseDateYear = 2000;
}
else
{
DeviceExt->GetNextDirEntry = FATGetNextDirEntry;
DeviceExt->BaseDateYear = 1980;
}
DeviceExt->StorageDevice = DeviceToMount;
DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
DPRINT("FsDeviceObject %lx\n", DeviceObject);
DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
Fcb = vfatNewFCB(DeviceExt, &NameU);
if (Fcb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
if (Ccb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
RtlZeroMemory(Ccb, sizeof (VFATCCB));
DeviceExt->FATFileObject->FsContext = Fcb;
DeviceExt->FATFileObject->FsContext2 = Ccb;
DeviceExt->FATFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
DeviceExt->FATFileObject->PrivateCacheMap = NULL;
DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
Fcb->FileObject = DeviceExt->FATFileObject;
Fcb->Flags |= FCB_IS_FAT;
Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
#ifdef USE_ROS_CC_AND_FS
if (DeviceExt->FatInfo.FatType != FAT12)
{
Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, CACHEPAGESIZE(DeviceExt));
}
else
{
Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, 2 * PAGE_SIZE);
}
if (!NT_SUCCESS (Status))
{
DPRINT1 ("CcRosInitializeFileCache failed\n");
goto ByeBye;
}
#else
/* FIXME: Guard by SEH. */
CcInitializeCacheMap(DeviceExt->FATFileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
&VfatGlobalData->CacheMgrCallbacks,
Fcb);
#endif
DeviceExt->LastAvailableCluster = 2;
ExInitializeResourceLite(&DeviceExt->DirResource);
ExInitializeResourceLite(&DeviceExt->FatResource);
InitializeListHead(&DeviceExt->FcbListHead);
VolumeFcb = vfatNewFCB(DeviceExt, &VolumeNameU);
if (VolumeFcb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
VolumeFcb->Flags = FCB_IS_VOLUME;
VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors * DeviceExt->FatInfo.BytesPerSector;
VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize;
VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize;
DeviceExt->VolumeFcb = VolumeFcb;
ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
InsertHeadList(&VfatGlobalData->VolumeListHead, &DeviceExt->VolumeListEntry);
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
/* read serial number */
DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID;
/* read volume label */
ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
/* read clean shutdown bit status */
Status = GetNextCluster(DeviceExt, 1, &eocMark);
if (NT_SUCCESS(Status))
{
if (eocMark & DeviceExt->CleanShutBitMask)
{
/* unset clean shutdown bit */
eocMark &= ~DeviceExt->CleanShutBitMask;
WriteCluster(DeviceExt, 1, eocMark);
VolumeFcb->Flags |= VCB_CLEAR_DIRTY;
}
}
VolumeFcb->Flags |= VCB_IS_DIRTY;
Status = STATUS_SUCCESS;
ByeBye:
if (!NT_SUCCESS(Status))
{
// cleanup
if (DeviceExt && DeviceExt->FATFileObject)
ObDereferenceObject (DeviceExt->FATFileObject);
if (Fcb)
vfatDestroyFCB(Fcb);
if (Ccb)
vfatDestroyCCB(Ccb);
if (DeviceObject)
IoDeleteDevice(DeviceObject);
if (VolumeFcb)
vfatDestroyFCB(VolumeFcb);
}
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?