NTSTATUS NtfsFCBInitializeCache(PNTFS_VCB Vcb, PNTFS_FCB Fcb) { PFILE_OBJECT FileObject; NTSTATUS Status; PNTFS_CCB newCCB; FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice); newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB); if (newCCB == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(newCCB, sizeof(NTFS_CCB)); newCCB->Identifier.Type = NTFS_TYPE_CCB; newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB); FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; FileObject->FsContext = Fcb; FileObject->FsContext2 = newCCB; newCCB->PtrFileObject = FileObject; Fcb->FileObject = FileObject; Fcb->Vcb = Vcb; Status = STATUS_SUCCESS; _SEH2_TRY { CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), FALSE, &(NtfsGlobalData->CacheMgrCallbacks), Fcb); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { FileObject->FsContext2 = NULL; ExFreePoolWithTag(newCCB, TAG_CCB); ObDereferenceObject(FileObject); Fcb->FileObject = NULL; return _SEH2_GetExceptionCode(); } _SEH2_END; ObDereferenceObject(FileObject); Fcb->Flags |= FCB_CACHE_INITIALIZED; return Status; }
NTSTATUS CdfsFCBInitializeCache(PVCB Vcb, PFCB Fcb) { PFILE_OBJECT FileObject; PCCB newCCB; FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice); newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB); if (newCCB == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(newCCB, sizeof(CCB)); FileObject->ReadAccess = TRUE; FileObject->WriteAccess = FALSE; FileObject->DeleteAccess = FALSE; FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; FileObject->FsContext = Fcb; FileObject->FsContext2 = newCCB; newCCB->PtrFileObject = FileObject; Fcb->FileObject = FileObject; Fcb->DevExt = Vcb; CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), FALSE, &(CdfsGlobalData->CacheMgrCallbacks), Fcb); ObDereferenceObject(FileObject); Fcb->Flags |= FCB_CACHE_INITIALIZED; return STATUS_SUCCESS; }
/************************************************************************* * * Function: Ext2MountVolume() * * Description: * This routine verifies and mounts the volume; * Called by FSCTRL IRP handler to attempt a * volume mount. * * Expected Interrupt Level (for execution) : * * IRQL_PASSIVE_LEVEL * * * Arguments: * * Irp - Supplies the Irp being processed * IrpSp - Irp Stack Location pointer * * Return Value: * * NTSTATUS - The Mount status * *************************************************************************/ NTSTATUS Ext2MountVolume ( IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp ) { // Volume Parameter Block PVPB PtrVPB; // The target device object PDEVICE_OBJECT TargetDeviceObject = NULL; // The new volume device object (to be created if partition is Ext2) PDEVICE_OBJECT PtrVolumeDeviceObject = NULL; // Return Status NTSTATUS Status = STATUS_UNRECOGNIZED_VOLUME; // Number of bytes to read for Volume verification... unsigned long NumberOfBytesToRead = 0; // Starting Offset for 'read' LONGLONG StartingOffset = 0; // Boot Sector information... PPACKED_BOOT_SECTOR BootSector = NULL; // Ext2 Super Block information... PEXT2_SUPER_BLOCK SuperBlock = NULL; // Volume Control Block PtrExt2VCB PtrVCB = NULL; // The File Object for the root directory PFILE_OBJECT PtrRootFileObject = NULL; // Flag int WeClearedVerifyRequiredBit; // Used by a for loop... unsigned int i; // LARGE_INTEGER VolumeByteOffset; unsigned long LogicalBlockSize = 0; // Buffer Control Block PBCB PtrBCB = NULL; // Cache Buffer - used for pinned access of volume... PVOID PtrCacheBuffer = NULL; PEXT2_GROUP_DESCRIPTOR PtrGroupDescriptor = NULL; // Inititalising variables PtrVPB = IrpSp->Parameters.MountVolume.Vpb; TargetDeviceObject = IrpSp->Parameters.MountVolume.DeviceObject; try { // // 1. Reading in Volume meta data // // Temporarily clear the DO_VERIFY_VOLUME Flag WeClearedVerifyRequiredBit = 0; if ( Ext2IsFlagOn( PtrVPB->RealDevice->Flags, DO_VERIFY_VOLUME ) ) { Ext2ClearFlag( PtrVPB->RealDevice->Flags, DO_VERIFY_VOLUME ); WeClearedVerifyRequiredBit = 1; } // Allocating memory for reading in Boot Sector... NumberOfBytesToRead = Ext2Align( sizeof( EXT2_SUPER_BLOCK ), TargetDeviceObject->SectorSize ); BootSector = Ext2AllocatePool( PagedPool, NumberOfBytesToRead ); RtlZeroMemory( BootSector, NumberOfBytesToRead ); // Reading in Boot Sector StartingOffset = 0L; Ext2PerformVerifyDiskRead ( TargetDeviceObject, BootSector, StartingOffset, NumberOfBytesToRead ); // Reject a volume that contains fat artifacts DebugTrace(DEBUG_TRACE_MOUNT, "OEM[%s]", BootSector->Oem); if (BootSector->Oem[0]) { try_return(); } // Allocating memory for reading in Super Block... SuperBlock = Ext2AllocatePool( PagedPool, NumberOfBytesToRead ); RtlZeroMemory( SuperBlock, NumberOfBytesToRead ); StartingOffset = 1024; // Reading in the Super Block... Ext2PerformVerifyDiskRead ( TargetDeviceObject, SuperBlock, StartingOffset, NumberOfBytesToRead ); // Resetting the DO_VERIFY_VOLUME Flag if( WeClearedVerifyRequiredBit ) { PtrVPB->RealDevice->Flags |= DO_VERIFY_VOLUME; } // Verifying the Super Block.. if( SuperBlock->s_magic == EXT2_SUPER_MAGIC ) { // // Found a valid super block. // No more tests for now. // Assuming that this is an ext2 partition... // Going ahead with mount. // DebugTrace(DEBUG_TRACE_MOUNT, "Valid Ext2 partition detected\nMounting %s...", SuperBlock->s_volume_name); // // 2. Creating a volume device object // if (!NT_SUCCESS( IoCreateDevice( Ext2GlobalData.Ext2DriverObject, // (This) Driver object Ext2QuadAlign( sizeof(Ext2VCB) ), // Device Extension NULL, // Device Name - no name ;) FILE_DEVICE_DISK_FILE_SYSTEM, // Disk File System 0, // DeviceCharacteristics FALSE, // Not an exclusive device (PDEVICE_OBJECT *)&PtrVolumeDeviceObject)) // The Volume Device Object ) { try_return(); } // // Our alignment requirement is the larger of the processor alignment requirement // already in the volume device object and that in the TargetDeviceObject // if (TargetDeviceObject->AlignmentRequirement > PtrVolumeDeviceObject->AlignmentRequirement) { PtrVolumeDeviceObject->AlignmentRequirement = TargetDeviceObject->AlignmentRequirement; } // // Clearing the Device Initialising Flag // Ext2ClearFlag( PtrVolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING); // // Setting the Stack Size for the newly created Volume Device Object // PtrVolumeDeviceObject->StackSize = (CCHAR)(TargetDeviceObject->StackSize + 1); // // 3. Creating the link between Target Device Object // and the Volume Device Object via the Volume Parameter Block // PtrVPB->DeviceObject = PtrVolumeDeviceObject; // Remembring the Volume parameters in the VPB bock for( i = 0; i < 16 ; i++ ) { PtrVPB->VolumeLabel[i] = SuperBlock->s_volume_name[i]; if( SuperBlock->s_volume_name[i] == 0 ) break; } PtrVPB->VolumeLabelLength = i * 2; PtrVPB->SerialNumber = ((ULONG*)SuperBlock->s_uuid)[0]; // // 4. Initialise the Volume Comtrol Block // { LARGE_INTEGER AllocationSize; AllocationSize .QuadPart = ( EXT2_MIN_BLOCK_SIZE << SuperBlock->s_log_block_size ) * SuperBlock->s_blocks_count; Ext2InitializeVCB( PtrVolumeDeviceObject, TargetDeviceObject, PtrVPB, &AllocationSize); PtrVCB = (PtrExt2VCB)(PtrVolumeDeviceObject->DeviceExtension); ASSERT( PtrVCB ); } PtrVCB->InodesCount = SuperBlock->s_inodes_count; PtrVCB->BlocksCount = SuperBlock->s_blocks_count; PtrVCB->ReservedBlocksCount = SuperBlock->s_r_blocks_count; PtrVCB->FreeBlocksCount = SuperBlock->s_free_blocks_count; PtrVCB->FreeInodesCount = SuperBlock->s_free_inodes_count; PtrVCB->LogBlockSize = SuperBlock->s_log_block_size; PtrVCB->InodesPerGroup = SuperBlock->s_inodes_per_group; PtrVCB->BlocksPerGroup = SuperBlock->s_blocks_per_group; PtrVCB->NoOfGroups = ( SuperBlock->s_blocks_count - SuperBlock->s_first_data_block + SuperBlock->s_blocks_per_group - 1 ) / SuperBlock->s_blocks_per_group; if( SuperBlock->s_rev_level ) { PtrVCB->InodeSize = SuperBlock->s_inode_size; } else { PtrVCB->InodeSize = sizeof( EXT2_INODE ); } PtrVCB->PtrGroupDescriptors = Ext2AllocatePool( NonPagedPool, sizeof( Ext2GroupDescriptors ) * PtrVCB->NoOfGroups ); RtlZeroMemory( PtrVCB->PtrGroupDescriptors , sizeof( Ext2GroupDescriptors ) * PtrVCB->NoOfGroups ); // // Attempting to Read in some matadata from the Cache... // using pin access... // LogicalBlockSize = EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize; // // Reading Group Descriptors... // if( PtrVCB->LogBlockSize ) { // First block contains the descriptors... VolumeByteOffset.QuadPart = LogicalBlockSize; } else { // Second block contains the descriptors... VolumeByteOffset.QuadPart = LogicalBlockSize * 2; } NumberOfBytesToRead = PtrVCB->NoOfGroups * sizeof( struct ext2_group_desc ); NumberOfBytesToRead = Ext2Align( NumberOfBytesToRead, LogicalBlockSize ); if (!CcMapData( PtrVCB->PtrStreamFileObject, &VolumeByteOffset, NumberOfBytesToRead, TRUE, &PtrBCB, &PtrCacheBuffer )) { DebugTrace(DEBUG_TRACE_ERROR, "Cache read failiure while reading in volume meta data", 0); try_return( Status = STATUS_INSUFFICIENT_RESOURCES ); } else { // // Saving up Often Used Group Descriptor Information in the VCB... // unsigned int DescIndex ; DebugTrace(DEBUG_TRACE_MISC, "Cache hit while reading in volume meta data", 0); PtrGroupDescriptor = (PEXT2_GROUP_DESCRIPTOR )PtrCacheBuffer; for( DescIndex = 0; DescIndex < PtrVCB->NoOfGroups; DescIndex++ ) { PtrVCB->PtrGroupDescriptors[ DescIndex ].InodeTablesBlock = PtrGroupDescriptor[ DescIndex ].bg_inode_table; PtrVCB->PtrGroupDescriptors[ DescIndex ].InodeBitmapBlock = PtrGroupDescriptor[ DescIndex ].bg_inode_bitmap ; PtrVCB->PtrGroupDescriptors[ DescIndex ].BlockBitmapBlock = PtrGroupDescriptor[ DescIndex ].bg_block_bitmap ; PtrVCB->PtrGroupDescriptors[ DescIndex ].FreeBlocksCount = PtrGroupDescriptor[ DescIndex ].bg_free_blocks_count; PtrVCB->PtrGroupDescriptors[ DescIndex ].FreeInodesCount = PtrGroupDescriptor[ DescIndex ].bg_free_inodes_count; } CcUnpinData( PtrBCB ); PtrBCB = NULL; } // // 5. Creating a Root Directory FCB // PtrRootFileObject = IoCreateStreamFileObject(NULL, TargetDeviceObject ); if( !PtrRootFileObject ) { try_return(); } // // Associate the file stream with the Volume parameter block... // I do it now // PtrRootFileObject->Vpb = PtrVCB->PtrVPB; PtrRootFileObject->ReadAccess = TRUE; PtrRootFileObject->WriteAccess = TRUE; { PtrExt2ObjectName PtrObjectName; LARGE_INTEGER ZeroSize; PtrObjectName = Ext2AllocateObjectName(); RtlInitUnicodeString( &PtrObjectName->ObjectName, L"\\" ); Ext2CopyWideCharToUnicodeString( &PtrObjectName->ObjectName, L"\\" ); ZeroSize.QuadPart = 0; if ( !NT_SUCCESS( Ext2CreateNewFCB( &PtrVCB->PtrRootDirectoryFCB, // Root FCB ZeroSize, // AllocationSize, ZeroSize, // EndOfFile, PtrRootFileObject, // The Root Dircetory File Object PtrVCB, PtrObjectName ) ) ) { try_return(); } PtrVCB->PtrRootDirectoryFCB->FCBFlags |= EXT2_FCB_DIRECTORY | EXT2_FCB_ROOT_DIRECTORY; } PtrVCB->PtrRootDirectoryFCB->DcbFcb.Dcb.PtrDirFileObject = PtrRootFileObject; PtrVCB->PtrRootDirectoryFCB->INodeNo = EXT2_ROOT_INO; PtrRootFileObject->SectionObjectPointer = &(PtrVCB->PtrRootDirectoryFCB->NTRequiredFCB.SectionObject); RtlInitUnicodeString( &PtrRootFileObject->FileName, L"\\" ); Ext2InitializeFCBInodeInfo( PtrVCB->PtrRootDirectoryFCB ); // // Initiating caching for root directory... // CcInitializeCacheMap(PtrRootFileObject, (PCC_FILE_SIZES)(&(PtrVCB->PtrRootDirectoryFCB->NTRequiredFCB.CommonFCBHeader.AllocationSize)), TRUE, // We will utilize pin access for directories &(Ext2GlobalData.CacheMgrCallBacks), // callbacks PtrVCB->PtrRootDirectoryFCB ); // The context used in callbacks // // 6. Update the VCB Flags // PtrVCB->VCBFlags |= EXT2_VCB_FLAGS_VOLUME_MOUNTED ; // | EXT2_VCB_FLAGS_VOLUME_READ_ONLY; // // 7. Mount Success // Status = STATUS_SUCCESS; { // // This block is for testing.... // To be removed... /* EXT2_INODE Inode ; Ext2ReadInode( PtrVCB, 100, &Inode ); DebugTrace( DEBUG_TRACE_MISC, "Inode size= %lX [FS Ctrl]", Inode.i_size ); Ext2DeallocInode( NULL, PtrVCB, 0xfb6 ); */ } // ObDereferenceObject( TargetDeviceObject ); } else { DebugTrace(DEBUG_TRACE_MOUNT, "Failing mount. Partition not Ext2...", 0); } try_exit: NOTHING; } finally { // Freeing Allocated Memory... if( SuperBlock != NULL ) { DebugTrace( DEBUG_TRACE_FREE, "Freeing = %lX [FS Ctrl]", SuperBlock ); ExFreePool( SuperBlock ); } if( BootSector != NULL ) { DebugTrace( DEBUG_TRACE_FREE, "Freeing = %lX [FS Ctrl]", BootSector); ExFreePool( BootSector ); } // start unwinding if we were unsuccessful if (!NT_SUCCESS( Status )) { } } return Status; }
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; PVPB Vpb; 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 %p)\n", IrpContext); ASSERT(IrpContext); if (IrpContext->DeviceObject != VfatGlobalData->DeviceObject) { Status = STATUS_INVALID_DEVICE_REQUEST; goto ByeBye; } DeviceToMount = IrpContext->Stack->Parameters.MountVolume.DeviceObject; Vpb = IrpContext->Stack->Parameters.MountVolume.Vpb; 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_DISK_FILE_SYSTEM, DeviceToMount->Characteristics, 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 = Vpb; DeviceToMount->Vpb = 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 %p\n", DeviceObject); /* Initialize this resource early ... it's used in VfatCleanup */ ExInitializeResourceLite(&DeviceExt->DirResource); 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; CcInitializeCacheMap(DeviceExt->FATFileObject, (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), TRUE, &VfatGlobalData->CacheMgrCallbacks, Fcb); DeviceExt->LastAvailableCluster = 2; 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; FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT); 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; }
static NTSTATUS NtfsMountVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_OBJECT NewDeviceObject = NULL; PDEVICE_OBJECT DeviceToMount; PIO_STACK_LOCATION Stack; PNTFS_FCB Fcb = NULL; PNTFS_CCB Ccb = NULL; PNTFS_VCB Vcb = NULL; NTSTATUS Status; DPRINT1("NtfsMountVolume() called\n"); if (DeviceObject != NtfsGlobalData->DeviceObject) { Status = STATUS_INVALID_DEVICE_REQUEST; goto ByeBye; } Stack = IoGetCurrentIrpStackLocation(Irp); DeviceToMount = Stack->Parameters.MountVolume.DeviceObject; Status = NtfsHasFileSystem(DeviceToMount); if (!NT_SUCCESS(Status)) { goto ByeBye; } Status = IoCreateDevice(NtfsGlobalData->DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &NewDeviceObject); if (!NT_SUCCESS(Status)) goto ByeBye; NewDeviceObject->Flags |= DO_DIRECT_IO; Vcb = (PVOID)NewDeviceObject->DeviceExtension; RtlZeroMemory(Vcb, sizeof(NTFS_VCB)); Vcb->Identifier.Type = NTFS_TYPE_VCB; Vcb->Identifier.Size = sizeof(NTFS_TYPE_VCB); Status = NtfsGetVolumeData(DeviceToMount, Vcb); if (!NT_SUCCESS(Status)) goto ByeBye; NewDeviceObject->Vpb = DeviceToMount->Vpb; Vcb->StorageDevice = DeviceToMount; Vcb->StorageDevice->Vpb->DeviceObject = NewDeviceObject; Vcb->StorageDevice->Vpb->RealDevice = Vcb->StorageDevice; Vcb->StorageDevice->Vpb->Flags |= VPB_MOUNTED; NewDeviceObject->StackSize = Vcb->StorageDevice->StackSize + 1; NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; Vcb->StreamFileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice); InitializeListHead(&Vcb->FcbListHead); Fcb = NtfsCreateFCB(NULL, Vcb); if (Fcb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB); if (Ccb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } RtlZeroMemory(Ccb, sizeof(NTFS_CCB)); Ccb->Identifier.Type = NTFS_TYPE_CCB; Ccb->Identifier.Size = sizeof(NTFS_TYPE_CCB); Vcb->StreamFileObject->FsContext = Fcb; Vcb->StreamFileObject->FsContext2 = Ccb; Vcb->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; Vcb->StreamFileObject->PrivateCacheMap = NULL; Vcb->StreamFileObject->Vpb = Vcb->Vpb; Ccb->PtrFileObject = Vcb->StreamFileObject; Fcb->FileObject = Vcb->StreamFileObject; Fcb->Vcb = (PDEVICE_EXTENSION)Vcb->StorageDevice; Fcb->Flags = FCB_IS_VOLUME_STREAM; Fcb->RFCB.FileSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; Fcb->RFCB.ValidDataLength.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; Fcb->RFCB.AllocationSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; /* Correct? */ // Fcb->Entry.ExtentLocationL = 0; // Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE; CcInitializeCacheMap(Vcb->StreamFileObject, (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), FALSE, &(NtfsGlobalData->CacheMgrCallbacks), Fcb); ExInitializeResourceLite(&Vcb->DirResource); KeInitializeSpinLock(&Vcb->FcbListLock); /* Get serial number */ NewDeviceObject->Vpb->SerialNumber = Vcb->NtfsInfo.SerialNumber; /* Get volume label */ NewDeviceObject->Vpb->VolumeLabelLength = Vcb->NtfsInfo.VolumeLabelLength; RtlCopyMemory(NewDeviceObject->Vpb->VolumeLabel, Vcb->NtfsInfo.VolumeLabel, Vcb->NtfsInfo.VolumeLabelLength); Status = STATUS_SUCCESS; ByeBye: if (!NT_SUCCESS(Status)) { /* Cleanup */ if (Vcb && Vcb->StreamFileObject) ObDereferenceObject(Vcb->StreamFileObject); if (Fcb) ExFreePool(Fcb); if (Ccb) ExFreePool(Ccb); if (NewDeviceObject) IoDeleteDevice(NewDeviceObject); } DPRINT("NtfsMountVolume() done (Status: %lx)\n", Status); return Status; }
NTSTATUS FFSInitializeVcb( IN PFFS_IRP_CONTEXT IrpContext, IN PFFS_VCB Vcb, IN PFFS_SUPER_BLOCK FFSSb, IN PDEVICE_OBJECT TargetDevice, IN PDEVICE_OBJECT VolumeDevice, IN PVPB Vpb) { BOOLEAN VcbResourceInitialized = FALSE; USHORT VolumeLabelLength; ULONG IoctlSize; BOOLEAN NotifySyncInitialized = FALSE; LONGLONG DiskSize; LONGLONG PartSize; NTSTATUS Status = STATUS_UNSUCCESSFUL; UNICODE_STRING RootNode; USHORT Buffer[2]; ULONG ChangeCount; __try { if (!Vpb) { Status = STATUS_DEVICE_NOT_READY; __leave; } Buffer[0] = L'\\'; Buffer[1] = 0; RootNode.Buffer = Buffer; RootNode.MaximumLength = RootNode.Length = 2; Vcb->McbTree = FFSAllocateMcb(Vcb, &RootNode, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL); if (!Vcb->McbTree) { __leave; } #if FFS_READ_ONLY SetFlag(Vcb->Flags, VCB_READ_ONLY); #endif //READ_ONLY if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) { SetFlag(Vcb->Flags, VCB_REMOVABLE_MEDIA); } if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) { SetFlag(Vcb->Flags, VCB_FLOPPY_DISK); } #if 0 if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING)) { if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING)) { ClearFlag(Vcb->Flags, VCB_READ_ONLY); } else { SetFlag(Vcb->Flags, VCB_READ_ONLY); } } else #endif { SetFlag(Vcb->Flags, VCB_READ_ONLY); } ExInitializeResourceLite(&Vcb->MainResource); ExInitializeResourceLite(&Vcb->PagingIoResource); ExInitializeResourceLite(&Vcb->McbResource); VcbResourceInitialized = TRUE; Vcb->McbTree->Inode = FFS_ROOT_INO; Vcb->Vpb = Vpb; Vcb->RealDevice = Vpb->RealDevice; Vpb->DeviceObject = VolumeDevice; { UNICODE_STRING LabelName; OEM_STRING OemName; LabelName.MaximumLength = 16 * 2; LabelName.Length = 0; LabelName.Buffer = Vcb->Vpb->VolumeLabel; RtlZeroMemory(LabelName.Buffer, LabelName.MaximumLength); VolumeLabelLength = 16; while((VolumeLabelLength > 0) && ((FFSSb->fs_volname[VolumeLabelLength-1] == 0x00) || (FFSSb->fs_volname[VolumeLabelLength-1] == 0x20))) { VolumeLabelLength--; } OemName.Buffer = FFSSb->fs_volname; OemName.MaximumLength = 16; OemName.Length = VolumeLabelLength; Status = FFSOEMToUnicode(&LabelName, &OemName); if (!NT_SUCCESS(Status)) { __leave; } Vpb->VolumeLabelLength = LabelName.Length; } Vpb->SerialNumber = ((ULONG*)FFSSb->fs_id)[0] + ((ULONG*)FFSSb->fs_id)[1] + ((ULONG*)FFSSb->fs_id)[2]; Vcb->StreamObj = IoCreateStreamFileObject(NULL, Vcb->Vpb->RealDevice); if (Vcb->StreamObj) { Vcb->StreamObj->SectionObjectPointer = &(Vcb->SectionObject); Vcb->StreamObj->Vpb = Vcb->Vpb; Vcb->StreamObj->ReadAccess = TRUE; if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) { Vcb->StreamObj->WriteAccess = TRUE; Vcb->StreamObj->DeleteAccess = TRUE; } else { Vcb->StreamObj->WriteAccess = TRUE; Vcb->StreamObj->DeleteAccess = TRUE; } Vcb->StreamObj->FsContext = (PVOID) Vcb; Vcb->StreamObj->FsContext2 = NULL; Vcb->StreamObj->Vpb = Vcb->Vpb; SetFlag(Vcb->StreamObj->Flags, FO_NO_INTERMEDIATE_BUFFERING); } else { __leave; } InitializeListHead(&Vcb->FcbList); InitializeListHead(&Vcb->NotifyList); FsRtlNotifyInitializeSync(&Vcb->NotifySync); NotifySyncInitialized = TRUE; Vcb->DeviceObject = VolumeDevice; Vcb->TargetDeviceObject = TargetDevice; Vcb->OpenFileHandleCount = 0; Vcb->ReferenceCount = 0; Vcb->ffs_super_block = FFSSb; Vcb->Header.NodeTypeCode = (USHORT) FFSVCB; Vcb->Header.NodeByteSize = sizeof(FFS_VCB); Vcb->Header.IsFastIoPossible = FastIoIsNotPossible; Vcb->Header.Resource = &(Vcb->MainResource); Vcb->Header.PagingIoResource = &(Vcb->PagingIoResource); Vcb->Vpb->SerialNumber = 'PS'; DiskSize = Vcb->DiskGeometry.Cylinders.QuadPart * Vcb->DiskGeometry.TracksPerCylinder * Vcb->DiskGeometry.SectorsPerTrack * Vcb->DiskGeometry.BytesPerSector; IoctlSize = sizeof(PARTITION_INFORMATION); Status = FFSDiskIoControl( TargetDevice, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &Vcb->PartitionInformation, &IoctlSize); PartSize = Vcb->PartitionInformation.PartitionLength.QuadPart; if (!NT_SUCCESS(Status)) { Vcb->PartitionInformation.StartingOffset.QuadPart = 0; Vcb->PartitionInformation.PartitionLength.QuadPart = DiskSize; PartSize = DiskSize; Status = STATUS_SUCCESS; } IoctlSize = sizeof(ULONG); Status = FFSDiskIoControl( TargetDevice, IOCTL_DISK_CHECK_VERIFY, NULL, 0, &ChangeCount, &IoctlSize); if (!NT_SUCCESS(Status)) { __leave; } Vcb->ChangeCount = ChangeCount; Vcb->Header.AllocationSize.QuadPart = Vcb->Header.FileSize.QuadPart = PartSize; Vcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff); /* Vcb->Header.AllocationSize.QuadPart = (LONGLONG)(ffs_super_block->s_blocks_count - ffs_super_block->s_free_blocks_count) * (FFS_MIN_BLOCK << ffs_super_block->s_log_block_size); Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart; Vcb->Header.ValidDataLength.QuadPart = Vcb->Header.AllocationSize.QuadPart; */ { CC_FILE_SIZES FileSizes; FileSizes.AllocationSize.QuadPart = FileSizes.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart; FileSizes.ValidDataLength.QuadPart= (LONGLONG)(0x7fffffffffffffff); CcInitializeCacheMap(Vcb->StreamObj, &FileSizes, TRUE, &(FFSGlobal->CacheManagerNoOpCallbacks), Vcb); } #if 0 // LoadGroup XXX if (!FFSLoadGroup(Vcb)) { Status = STATUS_UNSUCCESSFUL; __leave; } #endif FsRtlInitializeLargeMcb(&(Vcb->DirtyMcbs), PagedPool); InitializeListHead(&(Vcb->McbList)); if (IsFlagOn(FFSGlobal->Flags, FFS_CHECKING_BITMAP)) { FFSCheckBitmapConsistency(IrpContext, Vcb); } { ULONG dwData[FFS_BLOCK_TYPES] = {NDADDR, 1, 1, 1}; ULONG dwMeta[FFS_BLOCK_TYPES] = {0, 0, 0, 0}; ULONG i; if (FS_VERSION == 1) { for (i = 0; i < FFS_BLOCK_TYPES; i++) { dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i); if (i > 0) { dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2)); } Vcb->dwData[i] = dwData[i]; Vcb->dwMeta[i] = dwMeta[i]; } } else { for (i = 0; i < FFS_BLOCK_TYPES; i++) { dwData[i] = dwData[i] << ((BLOCK_BITS - 3) * i); if (i > 0) { dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 3)); } Vcb->dwData[i] = dwData[i]; Vcb->dwMeta[i] = dwMeta[i]; } } } SetFlag(Vcb->Flags, VCB_INITIALIZED); } __finally { if (!NT_SUCCESS(Status)) { if (NotifySyncInitialized) { FsRtlNotifyUninitializeSync(&Vcb->NotifySync); } if (Vcb->ffs_super_block) { ExFreePool(Vcb->ffs_super_block); Vcb->ffs_super_block = NULL; } if (VcbResourceInitialized) { ExDeleteResourceLite(&Vcb->MainResource); ExDeleteResourceLite(&Vcb->PagingIoResource); } } } return Status; }
VOID FatOpenDirectoryFile ( IN PIRP_CONTEXT IrpContext, IN PDCB Dcb ) /*++ Routine Description: This routine opens a new directory file if one is not already open. Arguments: Dcb - Pointer to the DCB for the directory Return Value: None. --*/ { PAGED_CODE(); DebugTrace(+1, Dbg, "FatOpenDirectoryFile\n", 0); DebugTrace( 0, Dbg, "Dcb = %08lx\n", Dcb); // // If we don't have some hold on this Dcb (there are several ways), there is nothing // to prevent child files from closing and tearing this branch of the tree down in the // midst of our slapping this reference onto it. // // I really wish we had a proper Fcb synchronization model (like CDFS/UDFS/NTFS). // ASSERT( FatIsCurrentOperationSynchedForDcbTeardown( IrpContext, Dcb )); // // If we haven't yet set the correct AllocationSize, do so. // if (Dcb->Header.AllocationSize.QuadPart == FCB_LOOKUP_ALLOCATIONSIZE_HINT) { FatLookupFileAllocationSize( IrpContext, Dcb ); Dcb->Header.FileSize.LowPart = Dcb->Header.AllocationSize.LowPart; } // // Setup the Bitmap buffer if it is not big enough already // FatCheckFreeDirentBitmap( IrpContext, Dcb ); // // Check if we need to create a directory file. // // We first do a spot check and then synchronize and check again. // if (Dcb->Specific.Dcb.DirectoryFile == NULL) { PFILE_OBJECT DirectoryFileObject = NULL; FatAcquireDirectoryFileMutex( Dcb->Vcb ); try { if (Dcb->Specific.Dcb.DirectoryFile == NULL) { PDEVICE_OBJECT RealDevice; // // Create the special file object for the directory file, and set // up its pointers back to the Dcb and the section object pointer. // Note that setting the DirectoryFile pointer in the Dcb has // to be the last thing done. // // Preallocate a close context since we have no Ccb for this object. // RealDevice = Dcb->Vcb->CurrentDevice; DirectoryFileObject = IoCreateStreamFileObject( NULL, RealDevice ); FatPreallocateCloseContext(); FatSetFileObject( DirectoryFileObject, DirectoryFile, Dcb, NULL ); // // Remember this internal open. // InterlockedIncrement( &(Dcb->Vcb->InternalOpenCount) ); // // If this is the root directory, it is also a residual open. // if (NodeType( Dcb ) == FAT_NTC_ROOT_DCB) { InterlockedIncrement( &(Dcb->Vcb->ResidualOpenCount) ); } DirectoryFileObject->SectionObjectPointer = &Dcb->NonPaged->SectionObjectPointers; DirectoryFileObject->ReadAccess = TRUE; DirectoryFileObject->WriteAccess = TRUE; DirectoryFileObject->DeleteAccess = TRUE; InterlockedIncrement( &Dcb->Specific.Dcb.DirectoryFileOpenCount ); Dcb->Specific.Dcb.DirectoryFile = DirectoryFileObject; // // Indicate we're happy with the fileobject now. // DirectoryFileObject = NULL; } } finally { FatReleaseDirectoryFileMutex( Dcb->Vcb ); // // Rip the object up if we couldn't get the close context. // if (DirectoryFileObject) { ObDereferenceObject( DirectoryFileObject ); } } }
static NTSTATUS CdfsMountVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION DeviceExt = NULL; PDEVICE_OBJECT NewDeviceObject = NULL; PDEVICE_OBJECT DeviceToMount; PIO_STACK_LOCATION Stack; PFCB Fcb = NULL; PCCB Ccb = NULL; PVPB Vpb; NTSTATUS Status; CDINFO CdInfo; DPRINT("CdfsMountVolume() called\n"); if (DeviceObject != CdfsGlobalData->DeviceObject) { Status = STATUS_INVALID_DEVICE_REQUEST; goto ByeBye; } Stack = IoGetCurrentIrpStackLocation(Irp); DeviceToMount = Stack->Parameters.MountVolume.DeviceObject; Vpb = Stack->Parameters.MountVolume.Vpb; Status = CdfsGetVolumeData(DeviceToMount, &CdInfo); if (!NT_SUCCESS(Status)) { goto ByeBye; } Status = IoCreateDevice(CdfsGlobalData->DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_CD_ROM_FILE_SYSTEM, DeviceToMount->Characteristics, FALSE, &NewDeviceObject); if (!NT_SUCCESS(Status)) goto ByeBye; NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO; NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME; DeviceExt = (PVOID)NewDeviceObject->DeviceExtension; RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION)); Vpb->SerialNumber = CdInfo.SerialNumber; Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength; RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength); RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO)); NewDeviceObject->Vpb = DeviceToMount->Vpb; DeviceExt->VolumeDevice = NewDeviceObject; DeviceExt->StorageDevice = DeviceToMount; DeviceExt->StorageDevice->Vpb->DeviceObject = NewDeviceObject; DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice; DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED; NewDeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1; NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; /* Close (and cleanup) might be called from IoCreateStreamFileObject * but we use this resource from CdfsCleanup, therefore it should be * initialized no later than this. */ ExInitializeResourceLite(&DeviceExt->DirResource); DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice); Fcb = CdfsCreateFCB(NULL); if (Fcb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB); if (Ccb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } RtlZeroMemory(Ccb, sizeof(CCB)); DeviceExt->StreamFileObject->ReadAccess = TRUE; DeviceExt->StreamFileObject->WriteAccess = FALSE; DeviceExt->StreamFileObject->DeleteAccess = FALSE; DeviceExt->StreamFileObject->FsContext = Fcb; DeviceExt->StreamFileObject->FsContext2 = Ccb; DeviceExt->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; DeviceExt->StreamFileObject->PrivateCacheMap = NULL; DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb; Ccb->PtrFileObject = DeviceExt->StreamFileObject; Fcb->FileObject = DeviceExt->StreamFileObject; Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; Fcb->Flags = FCB_IS_VOLUME_STREAM; Fcb->RFCB.FileSize.QuadPart = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE; Fcb->RFCB.ValidDataLength = Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize; Fcb->Entry.ExtentLocationL = 0; Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE; CcInitializeCacheMap(DeviceExt->StreamFileObject, (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), TRUE, &(CdfsGlobalData->CacheMgrCallbacks), Fcb); ExInitializeResourceLite(&DeviceExt->VcbResource); KeInitializeSpinLock(&DeviceExt->FcbListLock); InitializeListHead(&DeviceExt->FcbListHead); FsRtlNotifyInitializeSync(&DeviceExt->NotifySync); InitializeListHead(&DeviceExt->NotifyList); Status = STATUS_SUCCESS; ByeBye: if (!NT_SUCCESS(Status)) { /* Cleanup */ if (DeviceExt && DeviceExt->StreamFileObject) ObDereferenceObject(DeviceExt->StreamFileObject); if (Fcb) ExFreePool(Fcb); if (NewDeviceObject) IoDeleteDevice(NewDeviceObject); } DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status); return(Status); }