ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

blockdev.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:        See COPYING in the top level directory
00003  * PROJECT:          ReactOS File System Recognizer
00004  * FILE:             drivers/filesystems/fs_rec/blockdev.c
00005  * PURPOSE:          Generic Helper Functions
00006  * PROGRAMMER:       Alex Ionescu (alex.ionescu@reactos.org)
00007  *                   Eric Kohl
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #include "fs_rec.h"
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* FUNCTIONS ****************************************************************/
00017 
00018 BOOLEAN
00019 NTAPI
00020 FsRecGetDeviceSectors(IN PDEVICE_OBJECT DeviceObject,
00021                       IN ULONG SectorSize,
00022                       OUT PLARGE_INTEGER SectorCount)
00023 {
00024     PARTITION_INFORMATION PartitionInfo;
00025     IO_STATUS_BLOCK IoStatusBlock;
00026     KEVENT Event;
00027     PIRP Irp;
00028     NTSTATUS Status;
00029     ULONG Remainder;
00030     PAGED_CODE();
00031 
00032     /* Only needed for disks */
00033     if (DeviceObject->DeviceType != FILE_DEVICE_DISK) return FALSE;
00034 
00035     /* Build the information IRP */
00036     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
00037     Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
00038                                         DeviceObject,
00039                                         NULL,
00040                                         0,
00041                                         &PartitionInfo,
00042                                         sizeof(PARTITION_INFORMATION),
00043                                         FALSE,
00044                                         &Event,
00045                                         &IoStatusBlock);
00046     if (!Irp) return FALSE;
00047 
00048     /* Override verification */
00049     IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
00050 
00051     /* Do the request */
00052     Status = IoCallDriver(DeviceObject, Irp);
00053     if (Status == STATUS_PENDING)
00054     {
00055         /* Wait for completion */
00056         KeWaitForSingleObject(&Event,
00057                               Executive,
00058                               KernelMode,
00059                               FALSE,
00060                               NULL);
00061         Status = IoStatusBlock.Status;
00062     }
00063 
00064     /* Fail if we couldn't get the data */
00065     if (!NT_SUCCESS(Status)) return FALSE;
00066 
00067     /* Otherwise, return the number of sectors */
00068     *SectorCount = RtlExtendedLargeIntegerDivide(PartitionInfo.PartitionLength,
00069                                                  SectorSize,
00070                                                  &Remainder);
00071     return TRUE;
00072 }
00073 
00074 BOOLEAN
00075 NTAPI
00076 FsRecGetDeviceSectorSize(IN PDEVICE_OBJECT DeviceObject,
00077                          OUT PULONG SectorSize)
00078 {
00079     DISK_GEOMETRY DiskGeometry;
00080     IO_STATUS_BLOCK IoStatusBlock;
00081     KEVENT Event;
00082     PIRP Irp;
00083     NTSTATUS Status;
00084     ULONG ControlCode;
00085     PAGED_CODE();
00086 
00087     /* Check what device we have */
00088     switch (DeviceObject->DeviceType)
00089     {
00090         case FILE_DEVICE_CD_ROM:
00091 
00092             /* Use the CD IOCTL */
00093             ControlCode = IOCTL_CDROM_GET_DRIVE_GEOMETRY;
00094             break;
00095 
00096         case FILE_DEVICE_DISK:
00097 
00098             /* Use the Disk IOCTL */
00099             ControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY;
00100             break;
00101 
00102         default:
00103 
00104             /* Invalid device type */
00105             return FALSE;
00106     }
00107 
00108     /* Build the information IRP */
00109     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
00110     Irp = IoBuildDeviceIoControlRequest(ControlCode,
00111                                         DeviceObject,
00112                                         NULL,
00113                                         0,
00114                                         &DiskGeometry,
00115                                         sizeof(DISK_GEOMETRY),
00116                                         FALSE,
00117                                         &Event,
00118                                         &IoStatusBlock);
00119     if (!Irp) return FALSE;
00120 
00121     /* Override verification */
00122     IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
00123 
00124     /* Do the request */
00125     Status = IoCallDriver(DeviceObject, Irp);
00126     if (Status == STATUS_PENDING)
00127     {
00128         /* Wait for completion */
00129         KeWaitForSingleObject(&Event,
00130                               Executive,
00131                               KernelMode,
00132                               FALSE,
00133                               NULL);
00134         Status = IoStatusBlock.Status;
00135     }
00136 
00137     /* Fail if we couldn't get the data */
00138     if (!NT_SUCCESS(Status)) return FALSE;
00139 
00140     /* Return the sector size if it's valid */
00141     if (!DiskGeometry.BytesPerSector) return FALSE;
00142     *SectorSize = DiskGeometry.BytesPerSector;
00143     return TRUE;
00144 }
00145 
00146 BOOLEAN
00147 NTAPI
00148 FsRecReadBlock(IN PDEVICE_OBJECT DeviceObject,
00149                IN PLARGE_INTEGER Offset,
00150                IN ULONG Length,
00151                IN ULONG SectorSize,
00152                IN OUT PVOID *Buffer,
00153                OUT PBOOLEAN DeviceError OPTIONAL)
00154 {
00155     IO_STATUS_BLOCK IoStatusBlock;
00156     KEVENT Event;
00157     PIRP Irp;
00158     NTSTATUS Status;
00159     PAGED_CODE();
00160 
00161     /* Assume failure */
00162     if (DeviceError) *DeviceError = FALSE;
00163 
00164     /* Check if the caller requested too little */
00165     if (Length < SectorSize)
00166     {
00167         /* Read at least the sector size */
00168         Length = SectorSize;
00169     }
00170     else
00171     {
00172         /* Otherwise, just round up the request to sector size */
00173         Length = ROUND_UP(Length, SectorSize);
00174     }
00175 
00176     /* Check if the caller gave us a buffer */
00177     if (!*Buffer)
00178     {
00179         /* He didn't, allocate one */
00180         *Buffer = ExAllocatePoolWithTag(NonPagedPool,
00181                                         ROUND_TO_PAGES(Length),
00182                                         FSREC_TAG);
00183         if (!*Buffer) return FALSE;
00184     }
00185 
00186     /* Build the IRP */
00187     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
00188     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
00189                                        DeviceObject,
00190                                        *Buffer,
00191                                        Length,
00192                                        Offset,
00193                                        &Event,
00194                                        &IoStatusBlock);
00195     if (!Irp) return FALSE;
00196 
00197     /* Override verification */
00198     IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
00199 
00200     /* Do the request */
00201     Status = IoCallDriver(DeviceObject, Irp);
00202     if (Status == STATUS_PENDING)
00203     {
00204         /* Wait for completion */
00205         KeWaitForSingleObject(&Event,
00206                               Executive,
00207                               KernelMode,
00208                               FALSE,
00209                               NULL);
00210         Status = IoStatusBlock.Status;
00211     }
00212 
00213     /* Check if we couldn't get the data */
00214     if (!NT_SUCCESS(Status))
00215     {
00216         /* Check if caller wanted to know about the device and fail */
00217         if (DeviceError) *DeviceError = TRUE;
00218         return FALSE;
00219     }
00220 
00221     /* All went well */
00222     return TRUE;
00223 }
00224 

Generated on Sun May 27 2012 04:27:44 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.