mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 15:52:57 +00:00
Implemented asynchronous IOCTL_CDROM_CHECK_VERIFY.
Disabled buggy capability detection code. svn path=/trunk/; revision=6556
This commit is contained in:
parent
bdd2fef02f
commit
0082ae8bd6
1 changed files with 250 additions and 10 deletions
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: cdrom.c,v 1.22 2003/07/17 16:57:38 silverblade Exp $
|
/* $Id: cdrom.c,v 1.23 2003/11/07 12:56:26 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -121,6 +121,11 @@ VOID STDCALL
|
||||||
CdromClassStartIo (IN PDEVICE_OBJECT DeviceObject,
|
CdromClassStartIo (IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp);
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
CdromDeviceControlCompletion (IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context);
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
CdromTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
|
CdromTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PVOID Context);
|
IN PVOID Context);
|
||||||
|
@ -492,6 +497,7 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
|
||||||
DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
|
DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
|
||||||
DiskDeviceExtension->LockCount = 0;
|
DiskDeviceExtension->LockCount = 0;
|
||||||
DiskDeviceExtension->DeviceNumber = DeviceNumber;
|
DiskDeviceExtension->DeviceNumber = DeviceNumber;
|
||||||
|
DiskDeviceExtension->DeviceObject = DiskDeviceObject;
|
||||||
DiskDeviceExtension->PortDeviceObject = PortDeviceObject;
|
DiskDeviceExtension->PortDeviceObject = PortDeviceObject;
|
||||||
DiskDeviceExtension->PhysicalDevice = DiskDeviceObject;
|
DiskDeviceExtension->PhysicalDevice = DiskDeviceObject;
|
||||||
DiskDeviceExtension->PortCapabilities = Capabilities;
|
DiskDeviceExtension->PortCapabilities = Capabilities;
|
||||||
|
@ -586,6 +592,7 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
|
||||||
CdromData->XaFlags |= XA_USE_6_BYTE;
|
CdromData->XaFlags |= XA_USE_6_BYTE;
|
||||||
|
|
||||||
/* Read 'error recovery page' to get additional drive capabilities */
|
/* Read 'error recovery page' to get additional drive capabilities */
|
||||||
|
#if 0
|
||||||
Length = sizeof(MODE_READ_RECOVERY_PAGE) +
|
Length = sizeof(MODE_READ_RECOVERY_PAGE) +
|
||||||
MODE_BLOCK_DESC_LENGTH +
|
MODE_BLOCK_DESC_LENGTH +
|
||||||
MODE_HEADER_LENGTH;
|
MODE_HEADER_LENGTH;
|
||||||
|
@ -672,6 +679,7 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
|
||||||
CdromData->RecoveryData.Data6.Header.ModeDataLength = 0;
|
CdromData->RecoveryData.Data6.Header.ModeDataLength = 0;
|
||||||
}
|
}
|
||||||
ExFreePool (Buffer);
|
ExFreePool (Buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize device timer */
|
/* Initialize device timer */
|
||||||
IoInitializeTimer(DiskDeviceObject,
|
IoInitializeTimer(DiskDeviceObject,
|
||||||
|
@ -810,7 +818,8 @@ CdromClassDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
DPRINT("IOCTL_CDROM_GET_DRIVE_GEOMETRY\n");
|
DPRINT("IOCTL_CDROM_GET_DRIVE_GEOMETRY\n");
|
||||||
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
|
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
|
||||||
{
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -836,6 +845,21 @@ CdromClassDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IOCTL_CDROM_CHECK_VERIFY:
|
||||||
|
DPRINT ("IOCTL_CDROM_CHECK_VERIFY\n");
|
||||||
|
if (OutputLength != 0 && OutputLength < sizeof (ULONG))
|
||||||
|
{
|
||||||
|
DPRINT1("Buffer too small\n");
|
||||||
|
Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
IoMarkIrpPending (Irp);
|
||||||
|
IoStartPacket (DeviceObject,
|
||||||
|
Irp,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
return STATUS_PENDING;
|
||||||
|
|
||||||
case IOCTL_CDROM_READ_TOC:
|
case IOCTL_CDROM_READ_TOC:
|
||||||
DPRINT("IOCTL_CDROM_READ_TOC\n");
|
DPRINT("IOCTL_CDROM_READ_TOC\n");
|
||||||
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC))
|
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC))
|
||||||
|
@ -916,9 +940,9 @@ CdromClassDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = Information;
|
Irp->IoStatus.Information = Information;
|
||||||
IoCompleteRequest(Irp,
|
IoCompleteRequest(Irp,
|
||||||
IO_NO_INCREMENT);
|
IO_DISK_INCREMENT);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -946,8 +970,13 @@ CdromClassStartIo (IN PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
PDEVICE_EXTENSION DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
PIO_STACK_LOCATION IrpStack;
|
PIO_STACK_LOCATION IrpStack;
|
||||||
|
PIO_STACK_LOCATION SubIrpStack;
|
||||||
ULONG MaximumTransferLength;
|
ULONG MaximumTransferLength;
|
||||||
ULONG TransferPages;
|
ULONG TransferPages;
|
||||||
|
PSCSI_REQUEST_BLOCK Srb;
|
||||||
|
PIRP SubIrp;
|
||||||
|
PUCHAR SenseBuffer;
|
||||||
|
PCDB Cdb;
|
||||||
|
|
||||||
DPRINT("CdromClassStartIo() called!\n");
|
DPRINT("CdromClassStartIo() called!\n");
|
||||||
|
|
||||||
|
@ -958,7 +987,7 @@ CdromClassStartIo (IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (IrpStack->MajorFunction == IRP_MJ_READ)
|
if (IrpStack->MajorFunction == IRP_MJ_READ)
|
||||||
{
|
{
|
||||||
DPRINT(" IRP_MJ_READ\n");
|
DPRINT ("CdromClassStartIo: IRP_MJ_READ\n");
|
||||||
|
|
||||||
TransferPages =
|
TransferPages =
|
||||||
ADDRESS_AND_SIZE_TO_SPAN_PAGES (MmGetMdlVirtualAddress(Irp->MdlAddress),
|
ADDRESS_AND_SIZE_TO_SPAN_PAGES (MmGetMdlVirtualAddress(Irp->MdlAddress),
|
||||||
|
@ -994,19 +1023,114 @@ CdromClassStartIo (IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
else if (IrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
else if (IrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
||||||
{
|
{
|
||||||
DPRINT1(" IRP_MJ_IRP_MJ_DEVICE_CONTROL\n");
|
DPRINT ("CdromClassStartIo: IRP_MJ_IRP_MJ_DEVICE_CONTROL\n");
|
||||||
|
|
||||||
|
/* Allocate an IRP for sending requests to the port driver */
|
||||||
|
SubIrp = IoAllocateIrp ((CCHAR)(DeviceObject->StackSize + 1),
|
||||||
|
FALSE);
|
||||||
|
if (SubIrp == NULL)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
IoCompleteRequest (Irp,
|
||||||
|
IO_DISK_INCREMENT);
|
||||||
|
IoStartNextPacket (DeviceObject,
|
||||||
|
FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate an SRB */
|
||||||
|
Srb = ExAllocatePool (NonPagedPool,
|
||||||
|
sizeof (SCSI_REQUEST_BLOCK));
|
||||||
|
if (Srb == NULL)
|
||||||
|
{
|
||||||
|
IoFreeIrp (SubIrp);
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
IoCompleteRequest (Irp,
|
||||||
|
IO_DISK_INCREMENT);
|
||||||
|
IoStartNextPacket (DeviceObject,
|
||||||
|
FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocte a sense buffer */
|
||||||
|
SenseBuffer = ExAllocatePool (NonPagedPoolCacheAligned,
|
||||||
|
SENSE_BUFFER_SIZE);
|
||||||
|
if (SenseBuffer == NULL)
|
||||||
|
{
|
||||||
|
ExFreePool (Srb);
|
||||||
|
IoFreeIrp (SubIrp);
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
IoCompleteRequest (Irp,
|
||||||
|
IO_DISK_INCREMENT);
|
||||||
|
IoStartNextPacket (DeviceObject,
|
||||||
|
FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the IRP */
|
||||||
|
IoSetNextIrpStackLocation (SubIrp);
|
||||||
|
SubIrp->IoStatus.Information = 0;
|
||||||
|
SubIrp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
SubIrp->Flags = 0;
|
||||||
|
SubIrp->UserBuffer = NULL;
|
||||||
|
|
||||||
|
SubIrpStack = IoGetCurrentIrpStackLocation (SubIrp);
|
||||||
|
SubIrpStack->DeviceObject = DeviceExtension->DeviceObject;
|
||||||
|
SubIrpStack->Parameters.Others.Argument2 = (PVOID)Irp;
|
||||||
|
|
||||||
|
/* Initialize next stack location */
|
||||||
|
SubIrpStack = IoGetNextIrpStackLocation (SubIrp);
|
||||||
|
SubIrpStack->MajorFunction = IRP_MJ_SCSI;
|
||||||
|
SubIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
|
||||||
|
SubIrpStack->Parameters.Scsi.Srb = Srb;
|
||||||
|
|
||||||
|
/* Initialize the SRB */
|
||||||
|
RtlZeroMemory(Srb,
|
||||||
|
sizeof (SCSI_REQUEST_BLOCK));
|
||||||
|
Srb->Length = sizeof (SCSI_REQUEST_BLOCK);
|
||||||
|
Srb->PathId = DeviceExtension->PathId;
|
||||||
|
Srb->TargetId = DeviceExtension->TargetId;
|
||||||
|
Srb->Lun = DeviceExtension->Lun;
|
||||||
|
Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
|
||||||
|
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||||
|
Srb->ScsiStatus = 0;
|
||||||
|
Srb->NextSrb = 0;
|
||||||
|
Srb->OriginalRequest = SubIrp;
|
||||||
|
Srb->SenseInfoBuffer = SenseBuffer;
|
||||||
|
Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
|
||||||
|
|
||||||
|
/* Initialize the CDB */
|
||||||
|
Cdb = (PCDB)Srb->Cdb;
|
||||||
|
|
||||||
|
/* Set the completion routine */
|
||||||
|
IoSetCompletionRoutine (SubIrp,
|
||||||
|
CdromDeviceControlCompletion,
|
||||||
|
Srb,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
#if 0
|
|
||||||
switch (IrpStack->Parameters.DeviceIoControl.IoControlCode)
|
switch (IrpStack->Parameters.DeviceIoControl.IoControlCode)
|
||||||
{
|
{
|
||||||
|
case IOCTL_CDROM_CHECK_VERIFY:
|
||||||
|
DPRINT ("CdromClassStartIo: IOCTL_CDROM_CHECK_VERIFY\n");
|
||||||
|
Srb->CdbLength = 6;
|
||||||
|
Srb->TimeOutValue = DeviceExtension->TimeOutValue * 2;
|
||||||
|
Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
|
||||||
|
|
||||||
|
Cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
|
||||||
|
IoCallDriver (DeviceExtension->PortDeviceObject,
|
||||||
|
SubIrp);
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
IoCompleteRequest (Irp,
|
IoCompleteRequest (Irp,
|
||||||
IO_NO_INCREMENT);
|
IO_NO_INCREMENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the SCSI port driver */
|
/* Call the SCSI port driver */
|
||||||
|
@ -1015,11 +1139,127 @@ CdromClassStartIo (IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
CdromDeviceControlCompletion (IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
|
PDEVICE_EXTENSION PhysicalExtension;
|
||||||
|
PIO_STACK_LOCATION IrpStack;
|
||||||
|
PIO_STACK_LOCATION OrigCurrentIrpStack;
|
||||||
|
PIO_STACK_LOCATION OrigNextIrpStack;
|
||||||
|
PSCSI_REQUEST_BLOCK Srb;
|
||||||
|
PIRP OrigIrp;
|
||||||
|
BOOLEAN Retry;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT ("CdromDeviceControlCompletion() called\n");
|
||||||
|
|
||||||
|
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
PhysicalExtension = (PDEVICE_EXTENSION)DeviceExtension->PhysicalDevice->DeviceExtension;
|
||||||
|
Srb = (PSCSI_REQUEST_BLOCK) Context;
|
||||||
|
|
||||||
|
IrpStack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
|
|
||||||
|
/* Get the original IRP */
|
||||||
|
OrigIrp = (PIRP)IrpStack->Parameters.Others.Argument2;
|
||||||
|
OrigCurrentIrpStack = IoGetCurrentIrpStackLocation (OrigIrp);
|
||||||
|
OrigNextIrpStack = IoGetNextIrpStackLocation (OrigIrp);
|
||||||
|
|
||||||
|
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT ("SrbStatus %lx\n", Srb->SrbStatus);
|
||||||
|
|
||||||
|
/* Interpret sense info */
|
||||||
|
Retry = ScsiClassInterpretSenseInfo (DeviceObject,
|
||||||
|
Srb,
|
||||||
|
IrpStack->MajorFunction,
|
||||||
|
IrpStack->Parameters.DeviceIoControl.IoControlCode,
|
||||||
|
MAXIMUM_RETRIES - (ULONG)OrigNextIrpStack->Parameters.Others.Argument1,
|
||||||
|
&Status);
|
||||||
|
DPRINT ("Retry %u\n", Retry);
|
||||||
|
|
||||||
|
|
||||||
|
DPRINT ("Status %lx\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS (Status))
|
||||||
|
{
|
||||||
|
switch (OrigCurrentIrpStack->Parameters.DeviceIoControl.IoControlCode)
|
||||||
|
{
|
||||||
|
case IOCTL_CDROM_CHECK_VERIFY:
|
||||||
|
DPRINT ("CdromDeviceControlCompletion: IOCTL_CDROM_CHECK_VERIFY\n");
|
||||||
|
if (OrigCurrentIrpStack->Parameters.DeviceIoControl.OutputBufferLength != 0)
|
||||||
|
{
|
||||||
|
/* Return the media change counter */
|
||||||
|
*((PULONG)(OrigIrp->AssociatedIrp.SystemBuffer)) =
|
||||||
|
PhysicalExtension->MediaChangeCount;
|
||||||
|
OrigIrp->IoStatus.Information = sizeof(ULONG);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OrigIrp->IoStatus.Information = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
OrigIrp->IoStatus.Information = 0;
|
||||||
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the SRB and associated buffers */
|
||||||
|
if (Srb != NULL)
|
||||||
|
{
|
||||||
|
DPRINT("Srb %p\n", Srb);
|
||||||
|
|
||||||
|
if (Srb->SenseInfoBuffer != NULL)
|
||||||
|
ExFreePool (Srb->SenseInfoBuffer);
|
||||||
|
|
||||||
|
ExFreePool (Srb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OrigIrp->PendingReturned)
|
||||||
|
{
|
||||||
|
IoMarkIrpPending (OrigIrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the sub irp */
|
||||||
|
IoFreeIrp (Irp);
|
||||||
|
|
||||||
|
/* Set io status information */
|
||||||
|
OrigIrp->IoStatus.Status = Status;
|
||||||
|
if (!NT_SUCCESS(Status) && IoIsErrorUserInduced (Status))
|
||||||
|
{
|
||||||
|
IoSetHardErrorOrVerifyDevice (OrigIrp,
|
||||||
|
DeviceObject);
|
||||||
|
OrigIrp->IoStatus.Information = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Complete the original IRP */
|
||||||
|
IoCompleteRequest (OrigIrp,
|
||||||
|
IO_DISK_INCREMENT);
|
||||||
|
IoStartNextPacket (DeviceObject,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
DPRINT ("CdromDeviceControlCompletion() done\n");
|
||||||
|
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
CdromTimerRoutine(PDEVICE_OBJECT DeviceObject,
|
CdromTimerRoutine(PDEVICE_OBJECT DeviceObject,
|
||||||
PVOID Context)
|
PVOID Context)
|
||||||
{
|
{
|
||||||
DPRINT("CdromTimerRoutine() called\n");
|
DPRINT ("CdromTimerRoutine() called\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue