ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fsctrl.c
Go to the documentation of this file.
00001 /*************************************************************************
00002 *
00003 * File: fsctrl.c
00004 *
00005 * Module: Ext2 File System Driver (Kernel mode execution only)
00006 *
00007 * Description:
00008 *   Contains code to handle the various File System Control calls.
00009 *
00010 * Author: Manoj Paul Joseph
00011 *
00012 *
00013 *************************************************************************/
00014 
00015 
00016 
00017 #include "ext2fsd.h"
00018 
00019 
00020 
00021 // define the file specific bug-check id
00022 #define         EXT2_BUG_CHECK_ID               EXT2_FILE_FILE_CONTROL
00023 #define         DEBUG_LEVEL                     (DEBUG_TRACE_FSCTRL)
00024 
00025 
00026 NTSTATUS
00027 Ext2MountVolume(
00028     IN PIRP Irp,
00029     IN PIO_STACK_LOCATION IrpSp );
00030 
00031 NTSTATUS
00032 Ext2GetPartitionInfo(
00033     IN PDEVICE_OBJECT TargetDeviceObject,
00034     IN PPARTITION_INFORMATION PartitionInformation
00035     );
00036 
00037 NTSTATUS
00038 Ext2GetDriveLayout(
00039     IN PDEVICE_OBJECT TargetDeviceObject,
00040     IN PDRIVE_LAYOUT_INFORMATION DriveLayoutInformation,
00041     IN int BufferSize
00042     );
00043 
00044 BOOLEAN
00045 Ext2PerformVerifyDiskRead(
00046     IN PDEVICE_OBJECT TargetDeviceObject,
00047     IN PVOID Buffer,
00048     IN LONGLONG Lbo,
00049     IN ULONG NumberOfBytesToRead
00050     );
00051 
00052 NTSTATUS Ext2UserFileSystemRequest( 
00053     IN PIRP Irp,
00054     IN PIO_STACK_LOCATION IrpSp );
00055 
00056 
00057 /*************************************************************************
00058 *
00059 * Function: Ext2FileSystemControl
00060 *
00061 * Description:
00062 *   The I/O Manager will invoke this routine to handle a 
00063 *   File System Control IRP
00064 *
00065 * Expected Interrupt Level (for execution) :
00066 *  
00067 *   ???
00068 *
00069 * Arguments:
00070 *
00071 *    DeviceObject - Supplies the volume device object where the
00072 *                   file exists
00073 *
00074 *    Irp - Supplies the Irp being processed
00075 *
00076 *
00077 * Return Value:
00078 *
00079 *    NTSTATUS - The FSD status for the IRP
00080 *
00081 *************************************************************************/
00082 NTSTATUS NTAPI
00083 Ext2FileSystemControl(
00084     IN PDEVICE_OBJECT DeviceObject,
00085     IN PIRP Irp
00086     )
00087 {
00088   
00089     NTSTATUS Status = STATUS_SUCCESS;
00090     PIO_STACK_LOCATION IrpSp;
00091     
00092     DebugTrace(DEBUG_TRACE_IRP_ENTRY,   "File System Control IRP Received...", 0);
00093         
00094     //  Ext2BreakPoint();
00095 
00096     FsRtlEnterFileSystem();
00097 
00098     ASSERT(DeviceObject);
00099     ASSERT(Irp);
00100 
00101     //
00102     //  Get a pointer to the current Irp stack location
00103     //
00104     IrpSp = IoGetCurrentIrpStackLocation( Irp );
00105     
00106 
00107     if( IrpSp->MinorFunction == IRP_MN_MOUNT_VOLUME )
00108     {
00109         DebugTrace(DEBUG_TRACE_MOUNT,   "Mount Request Received...", 0);
00110         Status = Ext2MountVolume ( Irp, IrpSp );
00111         Ext2CompleteRequest( Irp, Status );
00112     }
00113     else if( IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST )
00114     {
00115         DebugTrace(DEBUG_TRACE_FSCTRL,   "IRP_MN_USER_FS_REQUEST received...", 0);
00116         Status = Ext2UserFileSystemRequest( Irp, IrpSp );
00117         Ext2CompleteRequest( Irp, Status );
00118     }
00119     else 
00120     {
00121         if( IrpSp->MinorFunction == IRP_MN_VERIFY_VOLUME )
00122         {
00123             DebugTrace(DEBUG_TRACE_FSCTRL,   "IRP_MN_VERIFY_VOLUME received...", 0);
00124         }
00125         else if( IrpSp->MinorFunction == IRP_MN_LOAD_FILE_SYSTEM )
00126         {
00127             DebugTrace(DEBUG_TRACE_FSCTRL,   "IRP_MN_LOAD_FILE_SYSTEM received...", 0);
00128         }
00129         else
00130         {
00131             DebugTrace(DEBUG_TRACE_FSCTRL,   "Unknown Minor IRP code received...", 0);
00132         }
00133 
00134         Status = STATUS_INVALID_DEVICE_REQUEST;
00135         Ext2CompleteRequest( Irp, Status );
00136     }
00137     
00138     FsRtlExitFileSystem();
00139 
00140     return Status;
00141 }
00142 
00143 
00144 
00145 /*************************************************************************
00146 *
00147 * Function: Ext2MountVolume()
00148 *
00149 * Description:
00150 *   This routine verifies and mounts the volume; 
00151 *   Called by FSCTRL IRP handler to attempt a 
00152 *       volume mount.
00153 *
00154 * Expected Interrupt Level (for execution) :
00155 *
00156 *  IRQL_PASSIVE_LEVEL 
00157 *
00158 *
00159 * Arguments:
00160 *
00161 *    Irp - Supplies the Irp being processed
00162 *    IrpSp - Irp Stack Location pointer
00163 *
00164 * Return Value: 
00165 *
00166 *   NTSTATUS - The Mount status
00167 *
00168 *************************************************************************/
00169 NTSTATUS
00170 Ext2MountVolume ( 
00171     IN PIRP Irp,
00172     IN PIO_STACK_LOCATION IrpSp )
00173 {
00174     
00175     //  Volume Parameter Block
00176     PVPB PtrVPB;
00177 
00178     //  The target device object
00179     PDEVICE_OBJECT TargetDeviceObject = NULL;
00180 
00181     // The new volume device object (to be created if partition is Ext2)
00182     PDEVICE_OBJECT PtrVolumeDeviceObject = NULL;
00183     
00184     //  Return Status
00185     NTSTATUS Status = STATUS_UNRECOGNIZED_VOLUME;
00186 
00187     // Number of bytes to read for Volume verification...
00188     unsigned long NumberOfBytesToRead = 0;
00189     
00190     //  Starting Offset for 'read'
00191     LONGLONG StartingOffset = 0;
00192 
00193     //  Boot Sector information...
00194     PPACKED_BOOT_SECTOR BootSector = NULL;
00195     
00196     //  Ext2 Super Block information...
00197     PEXT2_SUPER_BLOCK SuperBlock = NULL;
00198 
00199     //  Volume Control Block
00200     PtrExt2VCB          PtrVCB = NULL;
00201 
00202     //  The File Object for the root directory
00203     PFILE_OBJECT PtrRootFileObject = NULL;
00204     
00205     //  Flag
00206     int WeClearedVerifyRequiredBit;
00207     
00208     //  Used by a for loop...
00209     unsigned int i;
00210     
00211     //  
00212     LARGE_INTEGER VolumeByteOffset;
00213 
00214     unsigned long LogicalBlockSize = 0;
00215 
00216     //  Buffer Control Block
00217     PBCB PtrBCB = NULL;
00218             
00219     //  Cache Buffer - used for pinned access of volume...
00220     PVOID PtrCacheBuffer = NULL;
00221     
00222     PEXT2_GROUP_DESCRIPTOR  PtrGroupDescriptor = NULL;
00223 
00224     // Inititalising variables
00225     
00226     PtrVPB = IrpSp->Parameters.MountVolume.Vpb;
00227     TargetDeviceObject = IrpSp->Parameters.MountVolume.DeviceObject;
00228     
00229     try
00230     {
00231         //
00232         //  1. Reading in Volume meta data
00233         //
00234 
00235         //  Temporarily clear the DO_VERIFY_VOLUME Flag
00236         WeClearedVerifyRequiredBit = 0;
00237         if ( Ext2IsFlagOn( PtrVPB->RealDevice->Flags, DO_VERIFY_VOLUME ) ) 
00238         {
00239             Ext2ClearFlag( PtrVPB->RealDevice->Flags, DO_VERIFY_VOLUME );
00240             WeClearedVerifyRequiredBit = 1;
00241         }
00242 
00243         //  Allocating memory for reading in Boot Sector...
00244         NumberOfBytesToRead = Ext2Align( sizeof( EXT2_SUPER_BLOCK ), TargetDeviceObject->SectorSize );
00245         BootSector = Ext2AllocatePool( PagedPool, NumberOfBytesToRead  );
00246         RtlZeroMemory( BootSector, NumberOfBytesToRead );
00247 
00248         //  Reading in Boot Sector
00249         StartingOffset = 0L;
00250         Ext2PerformVerifyDiskRead ( TargetDeviceObject,
00251             BootSector, StartingOffset, NumberOfBytesToRead );
00252 
00253         // Reject a volume that contains fat artifacts
00254         
00255         DebugTrace(DEBUG_TRACE_MOUNT, "OEM[%s]", BootSector->Oem);
00256         if (BootSector->Oem[0])
00257         {
00258             try_return();
00259         }
00260 
00261         //  Allocating memory for reading in Super Block...
00262         
00263         SuperBlock = Ext2AllocatePool( PagedPool, NumberOfBytesToRead  );
00264         RtlZeroMemory( SuperBlock, NumberOfBytesToRead );
00265         StartingOffset = 1024;
00266 
00267         //  Reading in the Super Block...
00268         Ext2PerformVerifyDiskRead ( TargetDeviceObject,
00269             SuperBlock, StartingOffset, NumberOfBytesToRead );
00270 
00271         //  Resetting the DO_VERIFY_VOLUME Flag
00272         if( WeClearedVerifyRequiredBit ) 
00273         {
00274             PtrVPB->RealDevice->Flags |= DO_VERIFY_VOLUME;
00275         }
00276 
00277         // Verifying the Super Block..
00278         if( SuperBlock->s_magic == EXT2_SUPER_MAGIC )
00279         {
00280             //
00281             //  Found a valid super block.
00282             //  No more tests for now.
00283             //  Assuming that this is an ext2 partition...
00284             //  Going ahead with mount.
00285             //
00286             DebugTrace(DEBUG_TRACE_MOUNT,   "Valid Ext2 partition detected\nMounting %s...", SuperBlock->s_volume_name);
00287             //
00288             //  2. Creating a volume device object
00289             //
00290             if (!NT_SUCCESS( IoCreateDevice( 
00291                     Ext2GlobalData.Ext2DriverObject,    //  (This) Driver object
00292                     Ext2QuadAlign( sizeof(Ext2VCB) ),   //  Device Extension
00293                     NULL,                               //  Device Name - no name ;)
00294                     FILE_DEVICE_DISK_FILE_SYSTEM,       //  Disk File System
00295                     0,                                  //  DeviceCharacteristics
00296                     FALSE,                              //  Not an exclusive device
00297                     (PDEVICE_OBJECT *)&PtrVolumeDeviceObject)) //   The Volume Device Object
00298                     ) 
00299             {
00300                 try_return();
00301             }
00302 
00303             //  
00304             //  Our alignment requirement is the larger of the processor alignment requirement
00305             //  already in the volume device object and that in the TargetDeviceObject
00306             //
00307 
00308             if (TargetDeviceObject->AlignmentRequirement > PtrVolumeDeviceObject->AlignmentRequirement) 
00309             {
00310                 PtrVolumeDeviceObject->AlignmentRequirement = TargetDeviceObject->AlignmentRequirement;
00311             }
00312             
00313             //
00314             //  Clearing the Device Initialising Flag
00315             //
00316             Ext2ClearFlag( PtrVolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
00317 
00318 
00319             //
00320             //  Setting the Stack Size for the newly created Volume Device Object
00321             //
00322             PtrVolumeDeviceObject->StackSize = (CCHAR)(TargetDeviceObject->StackSize + 1);
00323             
00324 
00325             //
00326             //  3. Creating the link between Target Device Object 
00327             //  and the Volume Device Object via the Volume Parameter Block
00328             //
00329             PtrVPB->DeviceObject = PtrVolumeDeviceObject;
00330             
00331             //  Remembring the Volume parameters in the VPB bock
00332             for( i = 0; i < 16 ; i++ )
00333             {
00334                 PtrVPB->VolumeLabel[i] = SuperBlock->s_volume_name[i];
00335                 if( SuperBlock->s_volume_name[i] == 0 )
00336                     break;
00337             }
00338             PtrVPB->VolumeLabelLength = i * 2;
00339             PtrVPB->SerialNumber = ((ULONG*)SuperBlock->s_uuid)[0];
00340                 
00341             //
00342             //  4. Initialise the Volume Comtrol Block
00343             //
00344             {
00345                 LARGE_INTEGER AllocationSize;
00346 
00347                 AllocationSize .QuadPart = 
00348                     ( EXT2_MIN_BLOCK_SIZE << SuperBlock->s_log_block_size ) * 
00349                     SuperBlock->s_blocks_count;
00350 
00351                 Ext2InitializeVCB(
00352                     PtrVolumeDeviceObject, 
00353                     TargetDeviceObject,
00354                     PtrVPB,
00355                     &AllocationSize);
00356                 PtrVCB = (PtrExt2VCB)(PtrVolumeDeviceObject->DeviceExtension);
00357                 ASSERT( PtrVCB );
00358             }
00359 
00360             PtrVCB->InodesCount = SuperBlock->s_inodes_count;
00361             PtrVCB->BlocksCount = SuperBlock->s_blocks_count;
00362             PtrVCB->ReservedBlocksCount = SuperBlock->s_r_blocks_count;
00363             PtrVCB->FreeBlocksCount = SuperBlock->s_free_blocks_count;
00364             PtrVCB->FreeInodesCount = SuperBlock->s_free_inodes_count;
00365             PtrVCB->LogBlockSize = SuperBlock->s_log_block_size;
00366             PtrVCB->InodesPerGroup = SuperBlock->s_inodes_per_group;
00367             PtrVCB->BlocksPerGroup = SuperBlock->s_blocks_per_group;
00368             PtrVCB->NoOfGroups = ( SuperBlock->s_blocks_count - SuperBlock->s_first_data_block 
00369                                 + SuperBlock->s_blocks_per_group - 1 ) 
00370                                 / SuperBlock->s_blocks_per_group;
00371             if( SuperBlock->s_rev_level )
00372             {
00373                 PtrVCB->InodeSize = SuperBlock->s_inode_size;
00374             }
00375             else
00376             {
00377                 PtrVCB->InodeSize = sizeof( EXT2_INODE );
00378             }
00379 
00380             PtrVCB->PtrGroupDescriptors = Ext2AllocatePool( NonPagedPool, sizeof( Ext2GroupDescriptors ) * PtrVCB->NoOfGroups  );
00381             
00382             RtlZeroMemory( PtrVCB->PtrGroupDescriptors , sizeof( Ext2GroupDescriptors ) * PtrVCB->NoOfGroups );
00383 
00384             //
00385             //  Attempting to Read in some matadata from the Cache...
00386             //  using pin access...
00387             //
00388             LogicalBlockSize = EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize;
00389     
00390             //
00391             //  Reading Group Descriptors...
00392             //
00393             if( PtrVCB->LogBlockSize )
00394             {
00395                 //  First block contains the descriptors...
00396                 VolumeByteOffset.QuadPart = LogicalBlockSize;
00397             }
00398             else
00399             {
00400                 //  Second block contains the descriptors...
00401                 VolumeByteOffset.QuadPart = LogicalBlockSize * 2;
00402             }
00403 
00404             NumberOfBytesToRead = PtrVCB->NoOfGroups * sizeof( struct ext2_group_desc );
00405             NumberOfBytesToRead = Ext2Align( NumberOfBytesToRead, LogicalBlockSize );
00406 
00407             if (!CcMapData( PtrVCB->PtrStreamFileObject,
00408                    &VolumeByteOffset,
00409                    NumberOfBytesToRead,
00410                    TRUE,
00411                    &PtrBCB,
00412                    &PtrCacheBuffer )) 
00413             {
00414                 DebugTrace(DEBUG_TRACE_ERROR,   "Cache read failiure while reading in volume meta data", 0);
00415                 try_return( Status = STATUS_INSUFFICIENT_RESOURCES );
00416             }
00417             else
00418             {
00419                 //  
00420                 //  Saving up Often Used Group Descriptor Information in the VCB...
00421                 //
00422                 unsigned int DescIndex ;
00423 
00424                 DebugTrace(DEBUG_TRACE_MISC,   "Cache hit while reading in volume meta data", 0);
00425                 PtrGroupDescriptor = (PEXT2_GROUP_DESCRIPTOR )PtrCacheBuffer;
00426                 for( DescIndex = 0; DescIndex < PtrVCB->NoOfGroups; DescIndex++ )
00427                 {
00428                     PtrVCB->PtrGroupDescriptors[ DescIndex ].InodeTablesBlock 
00429                         = PtrGroupDescriptor[ DescIndex ].bg_inode_table;
00430 
00431                     PtrVCB->PtrGroupDescriptors[ DescIndex ].InodeBitmapBlock 
00432                         = PtrGroupDescriptor[ DescIndex ].bg_inode_bitmap
00433                         ;
00434                     PtrVCB->PtrGroupDescriptors[ DescIndex ].BlockBitmapBlock 
00435                         = PtrGroupDescriptor[ DescIndex ].bg_block_bitmap
00436                         ;
00437                     PtrVCB->PtrGroupDescriptors[ DescIndex ].FreeBlocksCount 
00438                         = PtrGroupDescriptor[ DescIndex ].bg_free_blocks_count;
00439 
00440                     PtrVCB->PtrGroupDescriptors[ DescIndex ].FreeInodesCount 
00441                         = PtrGroupDescriptor[ DescIndex ].bg_free_inodes_count;
00442                 }
00443                 CcUnpinData( PtrBCB );
00444                 PtrBCB = NULL;
00445             }
00446 
00447             //
00448             //  5. Creating a Root Directory FCB
00449             //
00450             PtrRootFileObject = IoCreateStreamFileObject(NULL, TargetDeviceObject );
00451             if( !PtrRootFileObject )
00452             {
00453                 try_return();
00454             }
00455             //
00456             //  Associate the file stream with the Volume parameter block...
00457             //  I do it now
00458             //
00459             PtrRootFileObject->Vpb = PtrVCB->PtrVPB;
00460 
00461             PtrRootFileObject->ReadAccess = TRUE;
00462             PtrRootFileObject->WriteAccess = TRUE;
00463 
00464             {
00465                 PtrExt2ObjectName       PtrObjectName;
00466                 LARGE_INTEGER ZeroSize;
00467 
00468                 PtrObjectName = Ext2AllocateObjectName();
00469                 RtlInitUnicodeString( &PtrObjectName->ObjectName, L"\\" );
00470                 Ext2CopyWideCharToUnicodeString( &PtrObjectName->ObjectName, L"\\" );
00471 
00472 
00473                 ZeroSize.QuadPart = 0;
00474                 if ( !NT_SUCCESS( Ext2CreateNewFCB( 
00475                         &PtrVCB->PtrRootDirectoryFCB,   //  Root FCB
00476                         ZeroSize,           //  AllocationSize,
00477                         ZeroSize,           //  EndOfFile,
00478                         PtrRootFileObject,      //  The Root Dircetory File Object
00479                         PtrVCB,
00480                         PtrObjectName  )  )  )
00481                 {
00482                     try_return();
00483                 }
00484                 
00485 
00486                 PtrVCB->PtrRootDirectoryFCB->FCBFlags |= EXT2_FCB_DIRECTORY | EXT2_FCB_ROOT_DIRECTORY;
00487 
00488 
00489             }
00490 
00491             PtrVCB->PtrRootDirectoryFCB->DcbFcb.Dcb.PtrDirFileObject = PtrRootFileObject;
00492             PtrVCB->PtrRootDirectoryFCB->INodeNo = EXT2_ROOT_INO;
00493             PtrRootFileObject->SectionObjectPointer = &(PtrVCB->PtrRootDirectoryFCB->NTRequiredFCB.SectionObject);
00494             RtlInitUnicodeString( &PtrRootFileObject->FileName, L"\\" );
00495 
00496             Ext2InitializeFCBInodeInfo( PtrVCB->PtrRootDirectoryFCB );
00497 
00498             //  
00499             //  Initiating caching for root directory...
00500             //
00501 
00502             CcInitializeCacheMap(PtrRootFileObject, 
00503                 (PCC_FILE_SIZES)(&(PtrVCB->PtrRootDirectoryFCB->NTRequiredFCB.CommonFCBHeader.AllocationSize)),
00504                 TRUE,       // We will utilize pin access for directories
00505                 &(Ext2GlobalData.CacheMgrCallBacks), // callbacks
00506                 PtrVCB->PtrRootDirectoryFCB );      // The context used in callbacks
00507 
00508 
00509             //
00510             //  6. Update the VCB Flags
00511             //
00512             PtrVCB->VCBFlags |= EXT2_VCB_FLAGS_VOLUME_MOUNTED ; //  | EXT2_VCB_FLAGS_VOLUME_READ_ONLY;
00513 
00514 
00515             //
00516             //  7. Mount Success
00517             //
00518             Status = STATUS_SUCCESS;
00519             
00520             {
00521                 //
00522                 //  This block is for testing....
00523                 //  To be removed...
00524 
00525                 /*
00526                 EXT2_INODE  Inode ;
00527                 Ext2ReadInode( PtrVCB, 100, &Inode );
00528                 DebugTrace( DEBUG_TRACE_MISC, "Inode size= %lX [FS Ctrl]", Inode.i_size );
00529                 Ext2DeallocInode( NULL, PtrVCB, 0xfb6 );
00530                 */
00531             }
00532             
00533             //   ObDereferenceObject( TargetDeviceObject );
00534         }
00535         else
00536         {
00537             DebugTrace(DEBUG_TRACE_MOUNT,   "Failing mount. Partition not Ext2...", 0);
00538         }
00539 
00540         try_exit: NOTHING;
00541     }
00542     finally 
00543     {
00544         //  Freeing Allocated Memory...
00545         if( SuperBlock != NULL )
00546         {
00547             DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [FS Ctrl]", SuperBlock );
00548             ExFreePool( SuperBlock );
00549         }
00550         if( BootSector != NULL )
00551         {
00552             DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [FS Ctrl]", BootSector);
00553             ExFreePool( BootSector );
00554         }
00555 
00556         // start unwinding if we were unsuccessful
00557         if (!NT_SUCCESS( Status )) 
00558         {
00559                         
00560         }
00561     }
00562     
00563     return Status;
00564 }
00565 
00566 /*************************************************************************
00567 *
00568 * Function: Ext2MountVolume()
00569 *
00570 * Description:
00571 *   This routine is used for querying the partition information.
00572 *
00573 * Expected Interrupt Level (for execution) :
00574 *  IRQL_PASSIVE_LEVEL 
00575 *
00576 * Arguments:
00577 *
00578 *   TargetDeviceObject - The target of the query
00579 *   PartitionInformation - Receives the result of the query
00580 *
00581 * Return Value:
00582 *
00583 *   NTSTATUS - The return status for the operation
00584 *
00585 *************************************************************************/
00586 NTSTATUS
00587 Ext2GetPartitionInfo (
00588     IN PDEVICE_OBJECT TargetDeviceObject,
00589     IN PPARTITION_INFORMATION PartitionInformation
00590     )
00591 {
00592     PIRP Irp;
00593     KEVENT *PtrEvent = NULL;
00594     NTSTATUS Status;
00595     IO_STATUS_BLOCK Iosb;
00596 
00597     //
00598     //  Query the partition table
00599     //
00600     PtrEvent = ( KEVENT * )Ext2AllocatePool( NonPagedPool, Ext2QuadAlign( sizeof( KEVENT ) )  );
00601     
00602 
00603 
00604 
00605     KeInitializeEvent( PtrEvent, NotificationEvent, FALSE );
00606     
00607     Irp = IoBuildDeviceIoControlRequest( IOCTL_DISK_GET_PARTITION_INFO,
00608                                          TargetDeviceObject,
00609                                          NULL,
00610                                          0,
00611                                          PartitionInformation,
00612                                          sizeof(PARTITION_INFORMATION),
00613                                          FALSE,
00614                                          PtrEvent,
00615                                          &Iosb );
00616 
00617     if ( Irp == NULL ) 
00618     {
00619         DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [FS Ctrl]", PtrEvent);
00620         ExFreePool( PtrEvent );
00621         return 0;
00622     }
00623 
00624     Status = IoCallDriver( TargetDeviceObject, Irp );
00625 
00626     if ( Status == STATUS_PENDING ) {
00627 
00628         (VOID) KeWaitForSingleObject( PtrEvent,
00629                                       Executive,
00630                                       KernelMode,
00631                                       FALSE,
00632                                       (PLARGE_INTEGER)NULL );
00633 
00634         Status = Iosb.Status;
00635     }
00636     DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [FS Ctrl]", PtrEvent);
00637     ExFreePool( PtrEvent );
00638     return Status;
00639 }
00640 
00641 /*************************************************************************
00642 *
00643 * Function: Ext2MountVolume()
00644 *
00645 * Description:
00646 *   This routine is used for querying the Drive Layout Information.
00647 *
00648 * Expected Interrupt Level (for execution) :
00649 *  IRQL_PASSIVE_LEVEL 
00650 *
00651 * Arguments:
00652 *
00653 *   TargetDeviceObject - The target of the query
00654 *   PartitionInformation - Receives the result of the query
00655 *
00656 * Return Value:
00657 *
00658 *   NTSTATUS - The return status for the operation
00659 *
00660 *************************************************************************/
00661 NTSTATUS Ext2GetDriveLayout (
00662     IN PDEVICE_OBJECT TargetDeviceObject,
00663     IN PDRIVE_LAYOUT_INFORMATION DriveLayoutInformation,
00664     IN int BufferSize
00665     )
00666 {
00667     PIRP Irp;
00668     KEVENT *PtrEvent = NULL;
00669     NTSTATUS Status;
00670     IO_STATUS_BLOCK Iosb;
00671 
00672     //
00673     //  Query the partition table
00674     //
00675     PtrEvent = ( KEVENT * )Ext2AllocatePool( NonPagedPool, Ext2QuadAlign( sizeof( KEVENT ) )  );
00676     KeInitializeEvent( PtrEvent, NotificationEvent, FALSE );
00677     Irp = IoBuildDeviceIoControlRequest( IOCTL_DISK_GET_DRIVE_LAYOUT,
00678                                          TargetDeviceObject,
00679                                          NULL,
00680                                          0,
00681                                          DriveLayoutInformation,
00682                                          BufferSize,
00683                                          FALSE,
00684                                          PtrEvent,
00685                                          &Iosb );
00686 
00687     if ( Irp == NULL ) 
00688     {
00689         DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [FS Ctrl]", PtrEvent);
00690         ExFreePool( PtrEvent );
00691         return 0;
00692     }
00693 
00694     Status = IoCallDriver( TargetDeviceObject, Irp );
00695 
00696     if ( Status == STATUS_PENDING ) {
00697 
00698         (VOID) KeWaitForSingleObject( PtrEvent,
00699                                       Executive,
00700                                       KernelMode,
00701                                       FALSE,
00702                                       (PLARGE_INTEGER)NULL );
00703 
00704         Status = Iosb.Status;
00705     }
00706     DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [FS Ctrl]", PtrEvent);
00707     ExFreePool( PtrEvent );
00708     return Status;
00709 }
00710 
00711 
00712 /*************************************************************************
00713 *
00714 * Function: Ext2MountVolume()
00715 *
00716 * Description:
00717 *   This routine is used for performing a verify read...
00718 *
00719 * Expected Interrupt Level (for execution) :
00720 *  IRQL_PASSIVE_LEVEL 
00721 *
00722 * Arguments:
00723 *   TargetDeviceObject - The target of the query
00724 *   PartitionInformation - Receives the result of the query
00725 *
00726 * Return Value:
00727 *   NTSTATUS - The return status for the operation
00728 *
00729 *************************************************************************/
00730 BOOLEAN Ext2PerformVerifyDiskRead(
00731     IN PDEVICE_OBJECT TargetDeviceObject,
00732     IN PVOID Buffer,
00733     IN LONGLONG Lbo,
00734     IN ULONG NumberOfBytesToRead )
00735 {
00736     KEVENT Event;
00737     PIRP Irp;
00738     LARGE_INTEGER ByteOffset;
00739     NTSTATUS Status;
00740     IO_STATUS_BLOCK Iosb;
00741 
00742     //
00743     //  Initialize the event we're going to use
00744     //
00745     KeInitializeEvent( &Event, NotificationEvent, FALSE );
00746 
00747     //
00748     //  Build the irp for the operation
00749     //
00750     ByteOffset.QuadPart = Lbo;
00751     Irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ,
00752                                         TargetDeviceObject,
00753                                         Buffer,
00754                                         NumberOfBytesToRead,
00755                                         &ByteOffset,
00756                                         &Event,
00757                                         &Iosb );
00758 
00759     if ( Irp == NULL ) 
00760     {
00761         Status = FALSE;
00762     }
00763 
00764     Ext2SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME );
00765 
00766     //
00767     //  Call the device to do the read and wait for it to finish.
00768     //
00769     Status = IoCallDriver( TargetDeviceObject, Irp );
00770     if (Status == STATUS_PENDING) 
00771     {
00772         (VOID)KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL );
00773         Status = Iosb.Status;
00774     }
00775 
00776     ASSERT(Status != STATUS_VERIFY_REQUIRED);
00777 
00778     //
00779     //  Special case this error code because this probably means we used
00780     //  the wrong sector size and we want to reject STATUS_WRONG_VOLUME.
00781     //
00782 
00783     if (Status == STATUS_INVALID_PARAMETER) 
00784     {
00785 
00786         return FALSE;
00787     }
00788 
00789     //
00790     //  If it doesn't succeed then either return or raise the error.
00791     //
00792 
00793     if (!NT_SUCCESS(Status)) 
00794     {
00795             return FALSE;
00796     }
00797 
00798     //
00799     //  And return to our caller
00800     //
00801     return TRUE;
00802 }
00803 
00804 /*************************************************************************
00805 *
00806 * Function: Ext2UserFileSystemRequest()
00807 *
00808 * Description:
00809 *   This routine handles User File System Requests
00810 *
00811 * Expected Interrupt Level (for execution) :
00812 *
00813 *  IRQL_PASSIVE_LEVEL 
00814 *
00815 *
00816 * Arguments:
00817 *
00818 *    Irp - Supplies the Irp being processed
00819 *    IrpSp - Irp Stack Location pointer
00820 *
00821 * Return Value: NT_STATUS
00822 *
00823 *************************************************************************/
00824 NTSTATUS Ext2UserFileSystemRequest ( 
00825     IN PIRP Irp,
00826     IN PIO_STACK_LOCATION IrpSp )
00827 {
00828     NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
00829     ULONG FsControlCode;
00830 
00831     IrpSp = IoGetCurrentIrpStackLocation( Irp );
00832     
00833     try
00834     {
00835 #ifdef _GNU_NTIFS_
00836         FsControlCode = ((PEXTENDED_IO_STACK_LOCATION)IrpSp)->Parameters.FileSystemControl.FsControlCode;
00837 #else
00838         FsControlCode = IrpSp->Parameters.FileSystemControl.FsControlCode;
00839 #endif
00840 
00841         switch ( FsControlCode ) 
00842         {
00843 
00844         case FSCTL_REQUEST_OPLOCK_LEVEL_1:
00845             DebugTrace(DEBUG_TRACE_FSCTRL,   "FSCTL_REQUEST_OPLOCK_LEVEL_1", 0);
00846             break;
00847         case FSCTL_REQUEST_OPLOCK_LEVEL_2:
00848             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL ", 0);
00849             break;
00850         case FSCTL_REQUEST_BATCH_OPLOCK:
00851             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_REQUEST_OPLOCK_LEVEL_2 ", 0);
00852             break;
00853         case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
00854             DebugTrace(DEBUG_TRACE_MISC,   " FSCTL_OPLOCK_BREAK_ACKNOWLEDGE ", 0);
00855             break;
00856         case FSCTL_OPBATCH_ACK_CLOSE_PENDING:
00857             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_OPBATCH_ACK_CLOSE_PENDING ", 0);
00858             break;
00859         case FSCTL_OPLOCK_BREAK_NOTIFY:
00860             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_OPLOCK_BREAK_NOTIFY ", 0);
00861             break;
00862         case FSCTL_OPLOCK_BREAK_ACK_NO_2:
00863             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_OPLOCK_BREAK_ACK_NO_2 ", 0);
00864             break;
00865         case FSCTL_LOCK_VOLUME:
00866             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_LOCK_VOLUME ", 0);
00867             break;
00868         case FSCTL_UNLOCK_VOLUME:
00869             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_UNLOCK_VOLUME ", 0);
00870             break;
00871         case FSCTL_DISMOUNT_VOLUME:
00872             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_DISMOUNT_VOLUME ", 0);
00873             break;
00874         case FSCTL_MARK_VOLUME_DIRTY:
00875             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_MARK_VOLUME_DIRTY ", 0);
00876             break;
00877         case FSCTL_IS_VOLUME_DIRTY:
00878             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_IS_VOLUME_DIRTY ", 0);
00879             break;
00880         case FSCTL_IS_VOLUME_MOUNTED:
00881             Status = Ext2VerifyVolume(Irp, IrpSp );
00882             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_IS_VOLUME_MOUNTED ", 0);
00883             break;
00884         case FSCTL_IS_PATHNAME_VALID:
00885             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_IS_PATHNAME_VALID ", 0);
00886             break;
00887         case FSCTL_QUERY_RETRIEVAL_POINTERS:
00888             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_QUERY_RETRIEVAL_POINTERS ", 0);
00889             break;
00890         case FSCTL_QUERY_FAT_BPB:
00891             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_QUERY_FAT_BPB ", 0);
00892             break;
00893         case FSCTL_FILESYSTEM_GET_STATISTICS:
00894             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_FILESYSTEM_GET_STATISTICS ", 0);
00895             break;
00896         case FSCTL_GET_VOLUME_BITMAP:
00897             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_GET_VOLUME_BITMAP ", 0);
00898             break;
00899         case FSCTL_GET_RETRIEVAL_POINTERS:
00900             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_GET_RETRIEVAL_POINTERS ", 0);
00901             break;
00902         case FSCTL_MOVE_FILE:
00903             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_MOVE_FILE ", 0);
00904             break;
00905         case FSCTL_ALLOW_EXTENDED_DASD_IO:
00906             DebugTrace(DEBUG_TRACE_FSCTRL,   " FSCTL_ALLOW_EXTENDED_DASD_IO ", 0);
00907             break;
00908         default :
00909             DebugTrace(DEBUG_TRACE_FSCTRL,   "Unknown FSCTRL !!!", 0);
00910 
00911         }
00912     }
00913     finally
00914     {
00915 
00916     }
00917     return Status;
00918 }
00919 
00920 
00921 
00922 NTSTATUS NTAPI Ext2VerifyVolume (
00923     IN PIRP Irp,
00924     IN PIO_STACK_LOCATION IrpSp )
00925 {
00926 
00927     PVPB PtrVPB;
00928     
00929     PtrVPB = IrpSp->Parameters.VerifyVolume.Vpb;
00930     if( IrpSp->FileObject )
00931     {
00932         PtrVPB = IrpSp->FileObject->Vpb;
00933     }
00934     if( !PtrVPB )
00935     {
00936         PtrVPB = IrpSp->Parameters.VerifyVolume.Vpb;
00937     }
00938 
00939     if( !PtrVPB )
00940     {
00941         return STATUS_WRONG_VOLUME;
00942     }
00943 
00944 
00945     if ( Ext2IsFlagOn( PtrVPB->RealDevice->Flags, DO_VERIFY_VOLUME ) ) 
00946     {
00947         //
00948         //  Not doing a verify!
00949         //  Just acting as if everyting is fine!
00950         //  THis should do for now
00951         //
00952         Ext2ClearFlag( PtrVPB->RealDevice->Flags, DO_VERIFY_VOLUME );
00953         
00954     }
00955     return STATUS_SUCCESS;
00956 }

Generated on Sat May 26 2012 04:26:19 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.