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