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

ioctl.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 doxygen 1.7.6.1

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