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 *****************************************************************/
20 /* FUNCTIONS ****************************************************************/
24 FsRecGetDeviceSectors(IN PDEVICE_OBJECT DeviceObject
,
26 OUT PLARGE_INTEGER SectorCount
)
28 PARTITION_INFORMATION PartitionInfo
;
29 IO_STATUS_BLOCK IoStatusBlock
;
36 /* Only needed for disks */
37 if (DeviceObject
->DeviceType
!= FILE_DEVICE_DISK
) return FALSE
;
39 /* Build the information IRP */
40 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
41 Irp
= IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO
,
46 sizeof(PARTITION_INFORMATION
),
50 if (!Irp
) return FALSE
;
52 /* Override verification */
53 IoGetNextIrpStackLocation(Irp
)->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
56 Status
= IoCallDriver(DeviceObject
, Irp
);
57 if (Status
== STATUS_PENDING
)
59 /* Wait for completion */
60 KeWaitForSingleObject(&Event
,
65 Status
= IoStatusBlock
.Status
;
68 /* Fail if we couldn't get the data */
69 if (!NT_SUCCESS(Status
)) return FALSE
;
71 /* Otherwise, return the number of sectors */
72 *SectorCount
= RtlExtendedLargeIntegerDivide(PartitionInfo
.PartitionLength
,
80 FsRecGetDeviceSectorSize(IN PDEVICE_OBJECT DeviceObject
,
81 OUT PULONG SectorSize
)
83 DISK_GEOMETRY DiskGeometry
;
84 IO_STATUS_BLOCK IoStatusBlock
;
91 /* Check what device we have */
92 switch (DeviceObject
->DeviceType
)
94 case FILE_DEVICE_CD_ROM
:
96 /* Use the CD IOCTL */
97 ControlCode
= IOCTL_CDROM_GET_DRIVE_GEOMETRY
;
100 case FILE_DEVICE_DISK
:
102 /* Use the Disk IOCTL */
103 ControlCode
= IOCTL_DISK_GET_DRIVE_GEOMETRY
;
108 /* Invalid device type */
112 /* Build the information IRP */
113 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
114 Irp
= IoBuildDeviceIoControlRequest(ControlCode
,
119 sizeof(DISK_GEOMETRY
),
123 if (!Irp
) return FALSE
;
125 /* Override verification */
126 IoGetNextIrpStackLocation(Irp
)->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
129 Status
= IoCallDriver(DeviceObject
, Irp
);
130 if (Status
== STATUS_PENDING
)
132 /* Wait for completion */
133 KeWaitForSingleObject(&Event
,
138 Status
= IoStatusBlock
.Status
;
141 /* Fail if we couldn't get the data */
142 if (!NT_SUCCESS(Status
)) return FALSE
;
144 /* Return the sector size if it's valid */
145 if (!DiskGeometry
.BytesPerSector
) return FALSE
;
146 *SectorSize
= DiskGeometry
.BytesPerSector
;
152 FsRecReadBlock(IN PDEVICE_OBJECT DeviceObject
,
153 IN PLARGE_INTEGER Offset
,
156 IN OUT PVOID
*Buffer
,
157 OUT PBOOLEAN DeviceError OPTIONAL
)
159 IO_STATUS_BLOCK IoStatusBlock
;
166 if (DeviceError
) *DeviceError
= FALSE
;
168 /* Check if the caller requested too little */
169 if (Length
< SectorSize
)
171 /* Read at least the sector size */
176 /* Otherwise, just round up the request to sector size */
177 Length
= ROUND_UP(Length
, SectorSize
);
180 /* Check if the caller gave us a buffer */
183 /* He didn't, allocate one */
184 *Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
185 ROUND_TO_PAGES(Length
),
187 if (!*Buffer
) return FALSE
;
191 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
192 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
199 if (!Irp
) return FALSE
;
201 /* Override verification */
202 IoGetNextIrpStackLocation(Irp
)->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
205 Status
= IoCallDriver(DeviceObject
, Irp
);
206 if (Status
== STATUS_PENDING
)
208 /* Wait for completion */
209 KeWaitForSingleObject(&Event
,
214 Status
= IoStatusBlock
.Status
;
217 /* Check if we couldn't get the data */
218 if (!NT_SUCCESS(Status
))
220 /* Check if caller wanted to know about the device and fail */
221 if (DeviceError
) *DeviceError
= TRUE
;