1 /*************************************************************************
5 * Module: Ext2 File System Driver (Kernel mode execution only)
8 * Should contain code to handle Disk IO.
11 * Author: Manoj Paul Joseph
14 *************************************************************************/
18 #define EXT2_BUG_CHECK_ID EXT2_FILE_DISK_IO
20 #define DEBUG_LEVEL ( DEBUG_TRACE_DISKIO )
23 /*************************************************************************
25 * Function: Ext2ReadLogicalBlocks()
28 * The higherlevel functions will use this to read in logical blocks
29 * This function deals with the logical to physical block translation
31 * LogicalBlock - This is a 1 based index.
32 * That is, the first block is Block 1
34 * Expected Interrupt Level (for execution) :
38 * Return Value: The Status of the Read IO
40 *************************************************************************/
41 NTSTATUS
Ext2ReadLogicalBlocks (
42 PDEVICE_OBJECT PtrTargetDeviceObject
, // the Target Device Object
43 VOID
*Buffer
, // The Buffer that takes the data read in
44 LARGE_INTEGER StartLogicalBlock
, // The logical block from which reading is to start
45 unsigned int NoOfLogicalBlocks
// The no. of logical blocks to be read
48 // The Status to be returned...
49 NTSTATUS Status
= STATUS_SUCCESS
;
51 // The Device Object representing the mounted volume
52 PDEVICE_OBJECT PtrVolumeDeviceObject
= NULL
;
54 // Volume Control Block
55 PtrExt2VCB PtrVCB
= NULL
;
58 ULONG LogicalBlockSize
;
60 // Physical Block Size
61 ULONG PhysicalBlockSize
;
63 // The starting Physical Block No...
64 LARGE_INTEGER StartPhysicalBlock
;
66 unsigned int NoOfPhysicalBlocks
;
70 // Done with declerations...
71 // Now for some code ;)
73 // Getting the Logical and Physical Sector sizes
74 PtrVolumeDeviceObject
= PtrTargetDeviceObject
->Vpb
->DeviceObject
;
75 ASSERT( PtrVolumeDeviceObject
);
76 PtrVCB
= (PtrExt2VCB
)(PtrVolumeDeviceObject
->DeviceExtension
);
78 ASSERT(PtrVCB
->NodeIdentifier
.NodeType
== EXT2_NODE_TYPE_VCB
);
80 LogicalBlockSize
= EXT2_MIN_BLOCK_SIZE
<< PtrVCB
->LogBlockSize
;
81 PhysicalBlockSize
= PtrTargetDeviceObject
->SectorSize
;
83 NoOfPhysicalBlocks
= NoOfLogicalBlocks
* LogicalBlockSize
/ PhysicalBlockSize
;
85 StartPhysicalBlock
.QuadPart
= ( StartLogicalBlock
.QuadPart
) *
86 ( LogicalBlockSize
/ PhysicalBlockSize
);
88 Status
= Ext2ReadPhysicalBlocks( PtrTargetDeviceObject
,
89 Buffer
, StartPhysicalBlock
, NoOfPhysicalBlocks
);
94 /*************************************************************************
96 * Function: Ext2ReadPhysicalBlocks()
99 * The higherlevel functions will use this to read in physical blocks
101 * PhysicalBlock - This is a 0 based number.
102 * That is, the first block is Block 0
104 * Expected Interrupt Level (for execution) :
108 * Return Value: The Status of the Read IO
110 *************************************************************************/
111 NTSTATUS
Ext2ReadPhysicalBlocks (
112 PDEVICE_OBJECT PtrTargetDeviceObject
, // the Target Device Object
113 VOID
*Buffer
, // The Buffer that takes the data read in
114 LARGE_INTEGER StartPhysicalBlock
, // The block from which reading is to start
115 unsigned int NoOfBlocks
// The no. of blocks to be read
118 // The Status to be returned...
119 NTSTATUS Status
= STATUS_SUCCESS
;
121 // Physical Block Size
122 ULONG PhysicalBlockSize
;
124 // No of bytes to read
125 ULONG NumberOfBytesToRead
;
127 // Synchronisation Event
134 IO_STATUS_BLOCK Iosb
;
137 LARGE_INTEGER ByteOffset
;
139 // Done with declerations...
140 // Now for some code ;)
142 // Getting the Physical Sector size
143 PhysicalBlockSize
= PtrTargetDeviceObject
->SectorSize
;
145 NumberOfBytesToRead
= PhysicalBlockSize
* NoOfBlocks
;
147 ByteOffset
.QuadPart
= StartPhysicalBlock
.QuadPart
* PhysicalBlockSize
;
152 // Initialize the event we're going to use
154 KeInitializeEvent( &Event
, NotificationEvent
, FALSE
);
157 // Build the irp for the operation and also set the overrride flag
159 Irp
= IoBuildSynchronousFsdRequest( IRP_MJ_READ
,
160 PtrTargetDeviceObject
,
169 DebugTrace(DEBUG_TRACE_MISC
, " !!!! Unable to create an IRP", 0 );
170 Status
= STATUS_INSUFFICIENT_RESOURCES
;
171 try_return( Status
);
175 // Call the device to do the read and wait for it to finish.
177 Status
= IoCallDriver( PtrTargetDeviceObject
, Irp
);
180 // Check if it is done already!!!!
182 if (Status
== STATUS_PENDING
)
185 // Read not done yet...
186 // Wait till it is...
188 (VOID
)KeWaitForSingleObject( &Event
, Executive
, KernelMode
, FALSE
, (PLARGE_INTEGER
)NULL
);
189 Status
= Iosb
.Status
;
196 if (!NT_SUCCESS(Status
))
198 if( Status
== STATUS_VERIFY_REQUIRED
)
200 DebugTrace(DEBUG_TRACE_MISC
, " !!!! Verify Required! Failed to read disk",0 );
202 else if (Status
== STATUS_INVALID_PARAMETER
)
204 DebugTrace(DEBUG_TRACE_MISC
, " !!!! Invalid Parameter! Failed to read disk",0 );
208 DebugTrace(DEBUG_TRACE_MISC
, " !!!! Failed to read disk! Status returned = %d", Status
);