Esempio n. 1
0
File: fcb.c Progetto: GYGit/reactos
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/*************************************************************************
*
* 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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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 );
            }
        }
    }
Esempio n. 8
0
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);
}