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

volinfo.c
Go to the documentation of this file.
00001 /*************************************************************************
00002 *
00003 * File: volinfo.c
00004 *
00005 * Module: Ext2 File System Driver (Kernel mode execution only)
00006 *
00007 * Description:
00008 *   Contains code to handle the various Volume Information related calls.
00009 *
00010 * Author: Manoj Paul Joseph
00011 *
00012 *
00013 *************************************************************************/
00014 
00015 
00016 
00017 #include "ext2fsd.h"
00018 
00019 
00020 
00021 
00022 // define the file specific bug-check id
00023 #define         EXT2_BUG_CHECK_ID               EXT2_FILE_VOL_INFORMATION
00024 #define         DEBUG_LEVEL                     (DEBUG_TRACE_VOLINFO)
00025 
00026 
00027 /*************************************************************************
00028 *
00029 * Function: Ext2QueryVolInfo()
00030 *
00031 * Description:
00032 *   The I/O Manager will invoke this routine to handle a 
00033 *   Query Volume Info IRP
00034 *
00035 * Expected Interrupt Level (for execution) :
00036 *  
00037 *   ???
00038 *
00039 * Arguments:
00040 *
00041 *    DeviceObject - Supplies the volume device object where the
00042 *                   file exists
00043 *
00044 *    Irp - Supplies the Irp being processed
00045 *
00046 *
00047 * Return Value:
00048 *
00049 *    NTSTATUS - The FSD status for the IRP
00050 *
00051 *************************************************************************/
00052 NTSTATUS NTAPI Ext2QueryVolInfo (
00053     IN PDEVICE_OBJECT   DeviceObject,
00054     IN PIRP Irp)
00055 {
00056 
00057     //  The Return Status
00058     NTSTATUS Status = STATUS_SUCCESS;
00059 
00060     //  The IRP Stack Location
00061     PIO_STACK_LOCATION  IrpSp = NULL;
00062 
00063     //  Volume Control Block
00064     PtrExt2VCB          PtrVCB = NULL;
00065     
00066     //  The class of the query IRP
00067     FS_INFORMATION_CLASS FsInformationClass;
00068     
00069     //  The System Buffer Pointer
00070     PVOID Buffer = NULL;
00071     
00072     //  Parameter Length
00073     ULONG Length = 0;
00074     
00075     //  Bytes copied...
00076     ULONG BytesCopied = 0;
00077 
00078     //  Pointers to the Output Information...
00079     PFILE_FS_VOLUME_INFORMATION     PtrVolumeInformation    = NULL;
00080     PFILE_FS_SIZE_INFORMATION       PtrSizeInformation      = NULL;
00081     PFILE_FS_ATTRIBUTE_INFORMATION  PtrAttributeInformation = NULL;
00082     PFILE_FS_DEVICE_INFORMATION     PtrDeviceInformation    = NULL;
00083     PFILE_FS_FULL_SIZE_INFORMATION  PtrFullSizeInformation  = NULL;
00084 
00085 
00086     //  Now for the handler code...
00087     DebugTrace(DEBUG_TRACE_IRP_ENTRY,   "QueryVolumeInformation IRP", 0);
00088 
00089     FsRtlEnterFileSystem();
00090 
00091     try 
00092     {
00093         // Getting a pointer to the current I/O stack location
00094         IrpSp = IoGetCurrentIrpStackLocation(Irp);
00095         ASSERT( IrpSp );
00096         
00097         //  Getting the VCB and Verifying it...
00098         PtrVCB = ( PtrExt2VCB )( DeviceObject->DeviceExtension );
00099         ASSERT(PtrVCB);
00100         ASSERT(PtrVCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB);
00101         
00102         //  Getting the query parameters...
00103         Length = IrpSp->Parameters.QueryVolume.Length;
00104         FsInformationClass = IrpSp->Parameters.QueryVolume.FsInformationClass;
00105         Buffer = Irp->AssociatedIrp.SystemBuffer;
00106 
00107         //  Now servicing the request depending on the type...
00108         switch (FsInformationClass) 
00109         {
00110         case FileFsVolumeInformation:
00111             DebugTrace(DEBUG_TRACE_MISC,   "Query Volume - FileFsVolumeInformation", 0);
00112             PtrVolumeInformation = Buffer;
00113             PtrVolumeInformation->SupportsObjects = FALSE;
00114             PtrVolumeInformation->VolumeCreationTime.QuadPart = 0;
00115             RtlCopyMemory( 
00116                 PtrVolumeInformation->VolumeLabel,  //  destination
00117                 PtrVCB->PtrVPB->VolumeLabel,        //  source
00118                 PtrVCB->PtrVPB->VolumeLabelLength );
00119             PtrVolumeInformation->VolumeLabelLength = PtrVCB->PtrVPB->VolumeLabelLength;
00120             PtrVolumeInformation->VolumeSerialNumber = PtrVCB->PtrVPB->SerialNumber;
00121             BytesCopied = sizeof( FILE_FS_VOLUME_INFORMATION ) + PtrVolumeInformation->VolumeLabelLength - sizeof( WCHAR);
00122             break;
00123 
00124         case FileFsSizeInformation:
00125             DebugTrace(DEBUG_TRACE_MISC,   "Query Volume - FileFsSizeInformation", 0);
00126             PtrSizeInformation = Buffer;
00127             PtrSizeInformation->BytesPerSector = DeviceObject->SectorSize;
00128             PtrSizeInformation->AvailableAllocationUnits.QuadPart   = PtrVCB->FreeBlocksCount;
00129             PtrSizeInformation->SectorsPerAllocationUnit    = ( EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize) / DeviceObject->SectorSize;
00130             PtrSizeInformation->TotalAllocationUnits.QuadPart       = PtrVCB->BlocksCount;
00131             BytesCopied = sizeof( FILE_FS_SIZE_INFORMATION );
00132             break;
00133 
00134         case FileFsDeviceInformation:
00135             DebugTrace(DEBUG_TRACE_MISC,   "Query Volume - FileFsDeviceInformation", 0);
00136             PtrDeviceInformation = Buffer;
00137             PtrDeviceInformation->DeviceType = FILE_DEVICE_DISK;
00138             PtrDeviceInformation->Characteristics = FILE_DEVICE_IS_MOUNTED;
00139             BytesCopied = sizeof( FILE_FS_DEVICE_INFORMATION );
00140             break;
00141 
00142         case FileFsAttributeInformation:
00143             DebugTrace(DEBUG_TRACE_MISC,   "Query Volume - FileFsAttributeInformation", 0);
00144             PtrAttributeInformation = Buffer;
00145             RtlCopyMemory( PtrAttributeInformation->FileSystemName, L"EXT2", 10 );
00146             PtrAttributeInformation->FileSystemNameLength = 8;
00147             PtrAttributeInformation->MaximumComponentNameLength = 255;
00148             PtrAttributeInformation->FileSystemAttributes  = 
00149                 FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
00150             BytesCopied = sizeof( FILE_FS_ATTRIBUTE_INFORMATION ) + 8; 
00151 
00152             break;
00153 
00154         case FileFsFullSizeInformation:
00155             DebugTrace(DEBUG_TRACE_MISC,   "Query Volume - FileFsFullSizeInformation", 0);
00156             PtrFullSizeInformation = Buffer;
00157             PtrFullSizeInformation->BytesPerSector = DeviceObject->SectorSize;
00158             PtrFullSizeInformation->ActualAvailableAllocationUnits.QuadPart = PtrVCB->FreeBlocksCount;
00159             PtrFullSizeInformation->SectorsPerAllocationUnit    = (EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize) / DeviceObject->SectorSize;
00160             PtrFullSizeInformation->TotalAllocationUnits.QuadPart       = PtrVCB->BlocksCount;
00161             PtrFullSizeInformation->CallerAvailableAllocationUnits.QuadPart = PtrVCB->FreeBlocksCount - PtrVCB->ReservedBlocksCount;
00162             BytesCopied = sizeof( FILE_FS_FULL_SIZE_INFORMATION );
00163             break;
00164 
00165         default:
00166             Status = STATUS_INVALID_PARAMETER;
00167             DebugTrace(DEBUG_TRACE_MISC,   "Query Volume - STATUS_INVALID_PARAMETER", 0);
00168             break;
00169         }
00170         
00171         if( IrpSp->Parameters.QueryVolume.Length < BytesCopied )    
00172         {
00173             BytesCopied = IrpSp->Parameters.QueryVolume.Length;
00174             Status = STATUS_BUFFER_OVERFLOW;
00175             DebugTrace(DEBUG_TRACE_MISC,   " === Buffer insufficient", 0);
00176         }
00177     }
00178     finally
00179     {
00180         Irp->IoStatus.Information = BytesCopied;
00181         Ext2CompleteRequest( Irp, Status );
00182     }
00183     FsRtlExitFileSystem();
00184 
00185     //
00186     //  Now return to the caller
00187     //
00188 
00189     return Status;
00190 }
00191 
00192 
00193 
00194 NTSTATUS NTAPI Ext2SetVolInfo(
00195     IN PDEVICE_OBJECT   DeviceObject,
00196     IN PIRP Irp)
00197 {
00198     //  The Return Status
00199     NTSTATUS Status = STATUS_SUCCESS;
00200 
00201     //  The IRP Stack Location
00202     PIO_STACK_LOCATION  IrpSp = NULL;
00203 
00204     //  Volume Control Block
00205     PtrExt2VCB          PtrVCB = NULL;
00206     
00207     //  The class of the query IRP
00208     FS_INFORMATION_CLASS FsInformationClass;
00209     
00210     //  Pointers to the Output Information...
00211     PFILE_FS_LABEL_INFORMATION      PtrVolumeLabelInformation = NULL;
00212 
00213     //  Now for the handler code...
00214     DebugTrace(DEBUG_TRACE_IRP_ENTRY,   "Set Volume Information IRP", 0);
00215 
00216     FsRtlEnterFileSystem();
00217 
00218     try 
00219     {
00220         // Getting a pointer to the current I/O stack location
00221         IrpSp = IoGetCurrentIrpStackLocation(Irp);
00222         ASSERT( IrpSp );
00223         
00224         //  Getting the VCB and Verifying it...
00225         PtrVCB = ( PtrExt2VCB )( DeviceObject->DeviceExtension );
00226         AssertVCB(PtrVCB);
00227         
00228         //  Getting the query parameters...
00229         //  Length = IrpSp->Parameters.SetVolume.Length;
00230 #ifdef _GNU_NTIFS_
00231         FsInformationClass = ((PEXTENDED_IO_STACK_LOCATION)IrpSp)->Parameters.SetVolume.FsInformationClass;
00232 #else
00233         FsInformationClass = IrpSp->Parameters.SetVolume.FsInformationClass;
00234 #endif
00235 
00236         //  Now servicing the request depending on the type...
00237         switch (FsInformationClass) 
00238         {
00239         case FileFsLabelInformation:
00240             PtrVolumeLabelInformation = Irp->AssociatedIrp.SystemBuffer;
00241             if( PtrVolumeLabelInformation->VolumeLabelLength > MAXIMUM_VOLUME_LABEL_LENGTH ||   //  This is the maximum that the 
00242                                                                                                 //  VPB can take...
00243                 PtrVolumeLabelInformation->VolumeLabelLength > 32 ) //  this is the maximum that Ext2 FS can support..
00244             {
00245                 try_return( Status = STATUS_INVALID_VOLUME_LABEL );
00246             }
00247 
00248             PtrVCB->PtrVPB->VolumeLabelLength = (USHORT)PtrVolumeLabelInformation->VolumeLabelLength ;
00249             RtlCopyMemory( 
00250                 PtrVCB->PtrVPB->VolumeLabel,        //  destination
00251                 PtrVolumeLabelInformation->VolumeLabel, //  source  
00252                 PtrVolumeLabelInformation->VolumeLabelLength );
00253             
00254             {
00255                 //  Now update the volume's super block...
00256 
00257                 PEXT2_SUPER_BLOCK   PtrSuperBlock = NULL;
00258                 PBCB                PtrSuperBlockBCB = NULL;
00259                 LARGE_INTEGER       VolumeByteOffset;
00260                 ULONG               LogicalBlockSize = 0;
00261                 ULONG               NumberOfBytesToRead = 0;
00262 
00263 
00264                 //  Reading in the super block...
00265                 VolumeByteOffset.QuadPart = 1024;
00266 
00267                 LogicalBlockSize = EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize;
00268 
00269                 //  THis shouldn't be more than a block in size...
00270                 NumberOfBytesToRead = Ext2Align( sizeof( EXT2_SUPER_BLOCK ), LogicalBlockSize );
00271 
00272                 if( !CcPinRead( PtrVCB->PtrStreamFileObject,
00273                        &VolumeByteOffset,
00274                        NumberOfBytesToRead,
00275                        TRUE,
00276                        &PtrSuperBlockBCB,
00277                        (PVOID*)&PtrSuperBlock ) )
00278                 {
00279                     DebugTrace(DEBUG_TRACE_ERROR,   "Cache read failiure while reading in volume meta data", 0);
00280                     try_return( Status = STATUS_INVALID_VOLUME_LABEL );
00281                 }
00282                 else
00283                 {
00284                     ULONG i;
00285                     for( i = 0; i < (PtrVolumeLabelInformation->VolumeLabelLength/2) ; i++ )
00286                     {
00287                         PtrSuperBlock->s_volume_name[i] = 
00288                             (char) PtrVolumeLabelInformation->VolumeLabel[i] ;
00289                         if( PtrSuperBlock->s_volume_name[i] == 0 )
00290                         {
00291                             break;
00292                         }
00293                     }
00294                     if( i < 16 )
00295                     {
00296                         PtrSuperBlock->s_volume_name[i] = 0;
00297                     }
00298 
00299 
00300                     CcSetDirtyPinnedData( PtrSuperBlockBCB, NULL );
00301                     
00302                     //  Not saving and flushing this information synchronously...
00303                     //  This is not a critical information..
00304                     //  Settling for lazy writing of this information
00305 
00306                     //  Ext2SaveBCB( PtrIrpContext, PtrSuperBlockBCB, PtrVCB->PtrStreamFileObject );
00307                     
00308                     if( PtrSuperBlockBCB )
00309                     {
00310                         CcUnpinData( PtrSuperBlockBCB );
00311                         PtrSuperBlockBCB = NULL;
00312                     }
00313                     
00314                 }
00315             }
00316 
00317             break;
00318         default:
00319             Status = STATUS_INVALID_PARAMETER;
00320             DebugTrace(DEBUG_TRACE_MISC,   "Query Volume - STATUS_INVALID_PARAMETER", 0);
00321             break;
00322         }
00323         
00324         try_exit: NOTHING;
00325     }
00326     finally
00327     {
00328         Irp->IoStatus.Information = 0;
00329         Ext2CompleteRequest( Irp, Status );
00330     }
00331     FsRtlExitFileSystem();
00332 
00333     //
00334     //  Now return to the caller
00335     //
00336 
00337     return Status;
00338 }

Generated on Sat May 26 2012 04:26:17 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.