Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenblockdev.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
1.7.6.1
|