+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS File System Recognizer
- * FILE: drivers/filesystems/fs_rec/blockdev.c
- * PURPOSE: Generic Helper Functions
- * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
- * Eric Kohl
- */
-
-/* INCLUDES *****************************************************************/
-
-#include "fs_rec.h"
-
-#include <ntdddisk.h>
-#include <ntddcdrm.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* FUNCTIONS ****************************************************************/
-
-BOOLEAN
-NTAPI
-FsRecGetDeviceSectors(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SectorSize,
- OUT PLARGE_INTEGER SectorCount)
-{
- PARTITION_INFORMATION PartitionInfo;
- IO_STATUS_BLOCK IoStatusBlock;
- KEVENT Event;
- PIRP Irp;
- NTSTATUS Status;
- ULONG Remainder;
- PAGED_CODE();
-
- /* Only needed for disks */
- if (DeviceObject->DeviceType != FILE_DEVICE_DISK) return FALSE;
-
- /* Build the information IRP */
- KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
- Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
- DeviceObject,
- NULL,
- 0,
- &PartitionInfo,
- sizeof(PARTITION_INFORMATION),
- FALSE,
- &Event,
- &IoStatusBlock);
- if (!Irp) return FALSE;
-
- /* Override verification */
- IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
-
- /* Do the request */
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- /* Wait for completion */
- KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = IoStatusBlock.Status;
- }
-
- /* Fail if we couldn't get the data */
- if (!NT_SUCCESS(Status)) return FALSE;
-
- /* Otherwise, return the number of sectors */
- *SectorCount = RtlExtendedLargeIntegerDivide(PartitionInfo.PartitionLength,
- SectorSize,
- &Remainder);
- return TRUE;
-}
-
-BOOLEAN
-NTAPI
-FsRecGetDeviceSectorSize(IN PDEVICE_OBJECT DeviceObject,
- OUT PULONG SectorSize)
-{
- DISK_GEOMETRY DiskGeometry;
- IO_STATUS_BLOCK IoStatusBlock;
- KEVENT Event;
- PIRP Irp;
- NTSTATUS Status;
- ULONG ControlCode;
- PAGED_CODE();
-
- /* Check what device we have */
- switch (DeviceObject->DeviceType)
- {
- case FILE_DEVICE_CD_ROM:
-
- /* Use the CD IOCTL */
- ControlCode = IOCTL_CDROM_GET_DRIVE_GEOMETRY;
- break;
-
- case FILE_DEVICE_DISK:
-
- /* Use the Disk IOCTL */
- ControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY;
- break;
-
- default:
-
- /* Invalid device type */
- return FALSE;
- }
-
- /* Build the information IRP */
- KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
- Irp = IoBuildDeviceIoControlRequest(ControlCode,
- DeviceObject,
- NULL,
- 0,
- &DiskGeometry,
- sizeof(DISK_GEOMETRY),
- FALSE,
- &Event,
- &IoStatusBlock);
- if (!Irp) return FALSE;
-
- /* Override verification */
- IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
-
- /* Do the request */
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- /* Wait for completion */
- KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = IoStatusBlock.Status;
- }
-
- /* Fail if we couldn't get the data */
- if (!NT_SUCCESS(Status)) return FALSE;
-
- /* Return the sector size if it's valid */
- if (!DiskGeometry.BytesPerSector) return FALSE;
- *SectorSize = DiskGeometry.BytesPerSector;
- return TRUE;
-}
-
-BOOLEAN
-NTAPI
-FsRecReadBlock(IN PDEVICE_OBJECT DeviceObject,
- IN PLARGE_INTEGER Offset,
- IN ULONG Length,
- IN ULONG SectorSize,
- IN OUT PVOID *Buffer,
- OUT PBOOLEAN DeviceError OPTIONAL)
-{
- IO_STATUS_BLOCK IoStatusBlock;
- KEVENT Event;
- PIRP Irp;
- NTSTATUS Status;
- PAGED_CODE();
-
- /* Assume failure */
- if (DeviceError) *DeviceError = FALSE;
-
- /* Check if the caller requested too little */
- if (Length < SectorSize)
- {
- /* Read at least the sector size */
- Length = SectorSize;
- }
- else
- {
- /* Otherwise, just round up the request to sector size */
- Length = ROUND_UP(Length, SectorSize);
- }
-
- /* Check if the caller gave us a buffer */
- if (!*Buffer)
- {
- /* He didn't, allocate one */
- *Buffer = ExAllocatePoolWithTag(NonPagedPool,
- ROUND_TO_PAGES(Length),
- FSREC_TAG);
- if (!*Buffer) return FALSE;
- }
-
- /* Build the IRP */
- KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
- DeviceObject,
- *Buffer,
- Length,
- Offset,
- &Event,
- &IoStatusBlock);
- if (!Irp) return FALSE;
-
- /* Override verification */
- IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
-
- /* Do the request */
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- /* Wait for completion */
- KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = IoStatusBlock.Status;
- }
-
- /* Check if we couldn't get the data */
- if (!NT_SUCCESS(Status))
- {
- /* Check if caller wanted to know about the device and fail */
- if (DeviceError) *DeviceError = TRUE;
- return FALSE;
- }
-
- /* All went well */
- return TRUE;
-}