Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenioctl.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS Floppy Driver 00003 * Copyright (C) 2004, Vizzini (vizzini@plasmic.com) 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 * 00019 * PROJECT: ReactOS Floppy Driver 00020 * FILE: ioctl.c 00021 * PURPOSE: IOCTL Routines 00022 * PROGRAMMER: Vizzini (vizzini@plasmic.com) 00023 * REVISIONS: 00024 * 15-Feb-2004 vizzini - Created 00025 * NOTES: 00026 * - All IOCTL documentation taken from the DDK 00027 * - This driver tries to support all of the IOCTLs that the DDK floppy 00028 * sample does 00029 * 00030 * TODO: Add support to GET_MEDIA_TYPES for non-1.44 disks 00031 * TODO: Implement format 00032 */ 00033 00034 #include "precomp.h" 00035 00036 00037 NTSTATUS NTAPI 00038 DeviceIoctl(PDEVICE_OBJECT DeviceObject, PIRP Irp) 00039 /* 00040 * FUNCTION: Queue IOCTL IRPs 00041 * ARGUMENTS: 00042 * DeviceObject: DeviceObject that is the target of the IRP 00043 * Irp: IRP to process 00044 * RETURNS: 00045 * STATUS_SUCCESS in all cases, so far 00046 * NOTES: 00047 * - We can't just service these immediately because, even though some 00048 * are able to run at DISPATCH, they'll get out of sync with other 00049 * read/write or ioctl irps. 00050 */ 00051 { 00052 ASSERT(DeviceObject); 00053 ASSERT(Irp); 00054 00055 Irp->Tail.Overlay.DriverContext[0] = DeviceObject; 00056 IoCsqInsertIrp(&Csq, Irp, NULL); 00057 00058 return STATUS_PENDING; 00059 } 00060 00061 00062 VOID NTAPI 00063 DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp) 00064 /* 00065 * FUNCTION: Handlees IOCTL requests at PASSIVE_LEVEL 00066 * ARGUMENTS: 00067 * DriveInfo: Drive that the IOCTL is directed at 00068 * Irp: IRP with the request in it 00069 */ 00070 { 00071 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); 00072 ULONG OutputLength = Stack->Parameters.DeviceIoControl.OutputBufferLength; 00073 PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer; 00074 ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode; 00075 BOOLEAN DiskChanged; 00076 00077 TRACE_(FLOPPY, "DeviceIoctl called\n"); 00078 Irp->IoStatus.Status = STATUS_SUCCESS; 00079 Irp->IoStatus.Information = 0; 00080 00081 /* 00082 * First the non-change-sensitive ioctls 00083 */ 00084 if(Code == IOCTL_DISK_GET_MEDIA_TYPES) 00085 { 00086 PDISK_GEOMETRY Geometry = OutputBuffer; 00087 INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES Called\n"); 00088 00089 if(OutputLength < sizeof(DISK_GEOMETRY)) 00090 { 00091 INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES: insufficient buffer; returning STATUS_INVALID_PARAMETER\n"); 00092 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 00093 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00094 return; 00095 } 00096 00097 /* 00098 * for now, this driver only supports 3.5" HD media 00099 */ 00100 Geometry->MediaType = F3_1Pt44_512; 00101 Geometry->Cylinders.QuadPart = 80; 00102 Geometry->TracksPerCylinder = 2 * 18; 00103 Geometry->SectorsPerTrack = 18; 00104 Geometry->BytesPerSector = 512; 00105 00106 Irp->IoStatus.Status = STATUS_SUCCESS; 00107 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY); 00108 INFO_(FLOPPY, "Ioctl: completing with STATUS_SUCCESS\n"); 00109 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00110 00111 return; 00112 } 00113 00114 /* 00115 * Now, check to see if the volume needs to be verified. If so, 00116 * return STATUS_VERIFY_REQUIRED. 00117 * 00118 * NOTE: This code, which is outside of the switch and if/else blocks, 00119 * will implicity catch and correctly service IOCTL_DISK_CHECK_VERIFY. 00120 * Therefore if we see one below in the switch, we can return STATUS_SUCCESS 00121 * immediately. 00122 */ 00123 if(DriveInfo->DeviceObject->Flags & DO_VERIFY_VOLUME && !(Stack->Flags & SL_OVERRIDE_VERIFY_VOLUME)) 00124 { 00125 INFO_(FLOPPY, "DeviceIoctl(): completing with STATUS_VERIFY_REQUIRED\n"); 00126 Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED; 00127 Irp->IoStatus.Information = 0; 00128 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00129 return; 00130 } 00131 00132 /* 00133 * Start the drive to see if the disk has changed 00134 */ 00135 StartMotor(DriveInfo); 00136 00137 /* 00138 * Check the change line, and if it's set, return 00139 */ 00140 if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS) 00141 { 00142 WARN_(FLOPPY, "DeviceIoctl(): unable to sense disk change; completing with STATUS_UNSUCCESSFUL\n"); 00143 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00144 Irp->IoStatus.Information = 0; 00145 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00146 StopMotor(DriveInfo->ControllerInfo); 00147 return; 00148 } 00149 00150 if(DiskChanged) 00151 { 00152 INFO_(FLOPPY, "DeviceIoctl(): detected disk changed; signalling media change and completing\n"); 00153 SignalMediaChanged(DriveInfo->DeviceObject, Irp); 00154 00155 /* 00156 * Just guessing here - I have a choice of returning NO_MEDIA or VERIFY_REQUIRED. If there's 00157 * really no disk in the drive, I'm thinking I can save time by just reporting that fact, rather 00158 * than forcing windows to ask me twice. If this doesn't work, we'll need to split this up and 00159 * handle the CHECK_VERIFY IOCTL separately. 00160 */ 00161 if(ResetChangeFlag(DriveInfo) == STATUS_NO_MEDIA_IN_DEVICE) 00162 Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE; 00163 00164 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00165 StopMotor(DriveInfo->ControllerInfo); 00166 return; 00167 } 00168 00169 switch(Code) 00170 { 00171 case IOCTL_DISK_IS_WRITABLE: 00172 { 00173 UCHAR Status; 00174 00175 INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE Called\n"); 00176 00177 /* This IRP always has 0 information */ 00178 Irp->IoStatus.Information = 0; 00179 00180 if(HwSenseDriveStatus(DriveInfo) != STATUS_SUCCESS) 00181 { 00182 WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to sense drive status\n"); 00183 Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 00184 break; 00185 } 00186 00187 /* Now, read the drive's status back */ 00188 if(HwSenseDriveStatusResult(DriveInfo->ControllerInfo, &Status) != STATUS_SUCCESS) 00189 { 00190 WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to read drive status result\n"); 00191 Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 00192 break; 00193 } 00194 00195 /* Check to see if the write flag is set. */ 00196 if(Status & SR3_WRITE_PROTECT_STATUS_SIGNAL) 00197 { 00198 INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE: disk is write protected\n"); 00199 Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED; 00200 } 00201 else 00202 Irp->IoStatus.Status = STATUS_SUCCESS; 00203 } 00204 break; 00205 00206 case IOCTL_DISK_CHECK_VERIFY: 00207 INFO_(FLOPPY, "IOCTL_DISK_CHECK_VERIFY called\n"); 00208 if (OutputLength != 0) 00209 { 00210 if (OutputLength < sizeof(ULONG)) 00211 { 00212 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 00213 Irp->IoStatus.Information = 0; 00214 } 00215 else 00216 { 00217 *((PULONG)OutputBuffer) = DriveInfo->DiskChangeCount; 00218 Irp->IoStatus.Status = STATUS_SUCCESS; 00219 Irp->IoStatus.Information = sizeof(ULONG); 00220 } 00221 } 00222 else 00223 { 00224 Irp->IoStatus.Status = STATUS_SUCCESS; 00225 Irp->IoStatus.Information = 0; 00226 } 00227 break; 00228 00229 case IOCTL_DISK_GET_DRIVE_GEOMETRY: 00230 { 00231 INFO_(FLOPPY, "IOCTL_DISK_GET_DRIVE_GEOMETRY Called\n"); 00232 if(OutputLength < sizeof(DISK_GEOMETRY)) 00233 { 00234 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 00235 break; 00236 } 00237 00238 /* This still works right even if DriveInfo->DiskGeometry->MediaType = Unknown */ 00239 memcpy(OutputBuffer, &DriveInfo->DiskGeometry, sizeof(DISK_GEOMETRY)); 00240 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY); 00241 break; 00242 } 00243 00244 case IOCTL_DISK_FORMAT_TRACKS: 00245 case IOCTL_DISK_FORMAT_TRACKS_EX: 00246 ERR_(FLOPPY, "Format called; not supported yet\n"); 00247 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 00248 Irp->IoStatus.Information = 0; 00249 break; 00250 00251 case IOCTL_DISK_GET_PARTITION_INFO: 00252 INFO_(FLOPPY, "IOCTL_DISK_GET_PARTITION_INFO Called; not supported by a floppy driver\n"); 00253 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 00254 Irp->IoStatus.Information = 0; 00255 break; 00256 00257 default: 00258 ERR_(FLOPPY, "UNKNOWN IOCTL CODE: 0x%x\n", Code); 00259 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 00260 Irp->IoStatus.Information = 0; 00261 break; 00262 } 00263 00264 INFO_(FLOPPY, "ioctl: completing with status 0x%x\n", Irp->IoStatus.Status); 00265 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00266 00267 StopMotor(DriveInfo->ControllerInfo); 00268 return; 00269 } 00270 Generated on Sun May 27 2012 04:27:10 for ReactOS by
1.7.6.1
|