Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenvolinfo.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
1.7.6.1
|