2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS File System Recognizer
4 * FILE: drivers/filesystems/fs_rec/blockdev.c
5 * PURPOSE: Generic Helper Functions
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
10 /* INCLUDES *****************************************************************/
16 /* FUNCTIONS ****************************************************************/
20 FsRecGetDeviceSectors(IN PDEVICE_OBJECT DeviceObject
,
22 OUT PLARGE_INTEGER SectorCount
)
24 PARTITION_INFORMATION PartitionInfo
;
25 IO_STATUS_BLOCK IoStatusBlock
;
32 /* Only needed for disks */
33 if (DeviceObject
->DeviceType
!= FILE_DEVICE_DISK
) return FALSE
;
35 /* Build the information IRP */
36 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
37 Irp
= IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO
,
42 sizeof(PARTITION_INFORMATION
),
46 if (!Irp
) return FALSE
;
48 /* Override verification */
49 IoGetNextIrpStackLocation(Irp
)->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
52 Status
= IoCallDriver(DeviceObject
, Irp
);
53 if (Status
== STATUS_PENDING
)
55 /* Wait for completion */
56 KeWaitForSingleObject(&Event
,
61 Status
= IoStatusBlock
.Status
;
64 /* Fail if we couldn't get the data */
65 if (!NT_SUCCESS(Status
)) return FALSE
;
67 /* Otherwise, return the number of sectors */
68 *SectorCount
= RtlExtendedLargeIntegerDivide(PartitionInfo
.PartitionLength
,
76 FsRecGetDeviceSectorSize(IN PDEVICE_OBJECT DeviceObject
,
77 OUT PULONG SectorSize
)
79 DISK_GEOMETRY DiskGeometry
;
80 IO_STATUS_BLOCK IoStatusBlock
;
87 /* Check what device we have */
88 switch (DeviceObject
->DeviceType
)
90 case FILE_DEVICE_CD_ROM
:
92 /* Use the CD IOCTL */
93 ControlCode
= IOCTL_CDROM_GET_DRIVE_GEOMETRY
;
96 case FILE_DEVICE_DISK
:
98 /* Use the Disk IOCTL */
99 ControlCode
= IOCTL_DISK_GET_DRIVE_GEOMETRY
;
104 /* Invalid device type */
108 /* Build the information IRP */
109 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
110 Irp
= IoBuildDeviceIoControlRequest(ControlCode
,
115 sizeof(DISK_GEOMETRY
),
119 if (!Irp
) return FALSE
;
121 /* Override verification */
122 IoGetNextIrpStackLocation(Irp
)->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
125 Status
= IoCallDriver(DeviceObject
, Irp
);
126 if (Status
== STATUS_PENDING
)
128 /* Wait for completion */
129 KeWaitForSingleObject(&Event
,
134 Status
= IoStatusBlock
.Status
;
137 /* Fail if we couldn't get the data */
138 if (!NT_SUCCESS(Status
)) return FALSE
;
140 /* Return the sector size if it's valid */
141 if (!DiskGeometry
.BytesPerSector
) return FALSE
;
142 *SectorSize
= DiskGeometry
.BytesPerSector
;
148 FsRecReadBlock(IN PDEVICE_OBJECT DeviceObject
,
149 IN PLARGE_INTEGER Offset
,
152 IN OUT PVOID
*Buffer
,
153 OUT PBOOLEAN DeviceError OPTIONAL
)
155 IO_STATUS_BLOCK IoStatusBlock
;
162 if (DeviceError
) *DeviceError
= FALSE
;
164 /* Check if the caller requested too little */
165 if (Length
< SectorSize
)
167 /* Read at least the sector size */
172 /* Otherwise, just round up the request to sector size */
173 Length
= ROUND_UP(Length
, SectorSize
);
176 /* Check if the caller gave us a buffer */
179 /* He didn't, allocate one */
180 *Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
181 ROUND_TO_PAGES(Length
),
183 if (!*Buffer
) return FALSE
;
187 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
188 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
195 if (!Irp
) return FALSE
;
197 /* Override verification */
198 IoGetNextIrpStackLocation(Irp
)->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
201 Status
= IoCallDriver(DeviceObject
, Irp
);
202 if (Status
== STATUS_PENDING
)
204 /* Wait for completion */
205 KeWaitForSingleObject(&Event
,
210 Status
= IoStatusBlock
.Status
;
213 /* Check if we couldn't get the data */
214 if (!NT_SUCCESS(Status
))
216 /* Check if caller wanted to know about the device and fail */
217 if (DeviceError
) *DeviceError
= TRUE
;