{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
ULONG OutputLength = Stack->Parameters.DeviceIoControl.OutputBufferLength;
PVOIDOutputBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONGCode = 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)
{
caseIOCTL_DISK_IS_WRITABLE:
{
UCHARStatus;
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;
}
elseIrp->IoStatus.Status = STATUS_SUCCESS;
}
break;
caseIOCTL_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;
caseIOCTL_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;
}
caseIOCTL_DISK_FORMAT_TRACKS:
caseIOCTL_DISK_FORMAT_TRACKS_EX:
ERR_(FLOPPY, "Format called; not supported yet\n");
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
break;
caseIOCTL_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
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.