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

VOID NTAPI DeviceIoctlPassive ( PDRIVE_INFO  DriveInfo,
PIRP  Irp 
)

Definition at line 63 of file ioctl.c.

Referenced by QueueThread().

{
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
    ULONG OutputLength = Stack->Parameters.DeviceIoControl.OutputBufferLength;
    PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
    ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode;
    BOOLEAN DiskChanged;

    TRACE_(FLOPPY, "DeviceIoctl called\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    /*
     * First the non-change-sensitive ioctls
     */
    if(Code == IOCTL_DISK_GET_MEDIA_TYPES)
    {
        PDISK_GEOMETRY Geometry = OutputBuffer;
        INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES Called\n");

        if(OutputLength < sizeof(DISK_GEOMETRY))
        {
            INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES: insufficient buffer; returning STATUS_INVALID_PARAMETER\n");
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return;
        }

        /*
         * for now, this driver only supports 3.5" HD media
         */
        Geometry->MediaType = F3_1Pt44_512;
        Geometry->Cylinders.QuadPart = 80;
        Geometry->TracksPerCylinder = 2 * 18;
        Geometry->SectorsPerTrack = 18;
        Geometry->BytesPerSector = 512;

        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
        INFO_(FLOPPY, "Ioctl: completing with STATUS_SUCCESS\n");
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return;
    }

    /*
     * Now, check to see if the volume needs to be verified.  If so,
     * return STATUS_VERIFY_REQUIRED.
     *
     * NOTE:  This code, which is outside of the switch and if/else blocks,
     * will implicity catch and correctly service IOCTL_DISK_CHECK_VERIFY.
     * Therefore if we see one below in the switch, we can return STATUS_SUCCESS
     * immediately.
     */
    if(DriveInfo->DeviceObject->Flags & DO_VERIFY_VOLUME && !(Stack->Flags & SL_OVERRIDE_VERIFY_VOLUME))
    {
        INFO_(FLOPPY, "DeviceIoctl(): completing with STATUS_VERIFY_REQUIRED\n");
        Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return;
    }

    /*
     * Start the drive to see if the disk has changed
     */
    StartMotor(DriveInfo);

    /*
     * Check the change line, and if it's set, return
     */
    if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
    {
        WARN_(FLOPPY, "DeviceIoctl(): unable to sense disk change; completing with STATUS_UNSUCCESSFUL\n");
        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        StopMotor(DriveInfo->ControllerInfo);
        return;
    }

    if(DiskChanged)
    {
        INFO_(FLOPPY, "DeviceIoctl(): detected disk changed; signalling media change and completing\n");
        SignalMediaChanged(DriveInfo->DeviceObject, Irp);

        /*
         * Just guessing here - I have a choice of returning NO_MEDIA or VERIFY_REQUIRED.  If there's
         * really no disk in the drive, I'm thinking I can save time by just reporting that fact, rather
         * than forcing windows to ask me twice.  If this doesn't work, we'll need to split this up and
         * handle the CHECK_VERIFY IOCTL separately.
         */
        if(ResetChangeFlag(DriveInfo) == STATUS_NO_MEDIA_IN_DEVICE)
            Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        StopMotor(DriveInfo->ControllerInfo);
        return;
    }

    switch(Code)
    {
    case IOCTL_DISK_IS_WRITABLE:
    {
        UCHAR Status;

        INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE Called\n");

        /* This IRP always has 0 information */
        Irp->IoStatus.Information = 0;

        if(HwSenseDriveStatus(DriveInfo) != STATUS_SUCCESS)
        {
            WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to sense drive status\n");
            Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
            break;
        }

        /* Now, read the drive's status back */
        if(HwSenseDriveStatusResult(DriveInfo->ControllerInfo, &Status) != STATUS_SUCCESS)
        {
            WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to read drive status result\n");
            Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
            break;
        }

        /* Check to see if the write flag is set. */
        if(Status & SR3_WRITE_PROTECT_STATUS_SIGNAL)
        {
            INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE: disk is write protected\n");
            Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
        }
        else
            Irp->IoStatus.Status = STATUS_SUCCESS;
    }
    break;

    case IOCTL_DISK_CHECK_VERIFY:
        INFO_(FLOPPY, "IOCTL_DISK_CHECK_VERIFY called\n");
        if (OutputLength != 0)
        {
            if (OutputLength < sizeof(ULONG))
            {
                Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                Irp->IoStatus.Information = 0;
            }
            else
            {
                *((PULONG)OutputBuffer) = DriveInfo->DiskChangeCount;
                Irp->IoStatus.Status = STATUS_SUCCESS;
                Irp->IoStatus.Information = sizeof(ULONG);
            }
        }
        else
        {
            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = 0;
        }
        break;

    case IOCTL_DISK_GET_DRIVE_GEOMETRY:
    {
        INFO_(FLOPPY, "IOCTL_DISK_GET_DRIVE_GEOMETRY Called\n");
        if(OutputLength < sizeof(DISK_GEOMETRY))
        {
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            break;
        }

        /* This still works right even if DriveInfo->DiskGeometry->MediaType = Unknown */
        memcpy(OutputBuffer, &DriveInfo->DiskGeometry, sizeof(DISK_GEOMETRY));
        Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
        break;
    }

    case IOCTL_DISK_FORMAT_TRACKS:
    case IOCTL_DISK_FORMAT_TRACKS_EX:
        ERR_(FLOPPY, "Format called; not supported yet\n");
        Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
        Irp->IoStatus.Information = 0;
        break;

    case IOCTL_DISK_GET_PARTITION_INFO:
        INFO_(FLOPPY, "IOCTL_DISK_GET_PARTITION_INFO Called; not supported by a floppy driver\n");
        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;
        break;

    default:
        ERR_(FLOPPY, "UNKNOWN IOCTL CODE: 0x%x\n", Code);
        Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
        Irp->IoStatus.Information = 0;
        break;
    }

    INFO_(FLOPPY, "ioctl: completing with status 0x%x\n", Irp->IoStatus.Status);
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    StopMotor(DriveInfo->ControllerInfo);
    return;
}

Generated on Sun May 27 2012 05:21:19 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.