mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Patch by tinus.Fix media change support for CDROMs. This fixes bug #471. Patch by tinus.
svn path=/trunk/; revision=13097
This commit is contained in:
parent
968f3f7c24
commit
69688ce6ab
5 changed files with 132 additions and 43 deletions
|
@ -191,6 +191,19 @@ CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
|
|||
*OutputBufferSize = IoStatus.Information;
|
||||
}
|
||||
|
||||
if (Status == STATUS_VERIFY_REQUIRED)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
NTSTATUS NewStatus;
|
||||
|
||||
DPRINT1("STATUS_VERIFY_REQUIRED\n");
|
||||
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
|
||||
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
|
||||
|
||||
NewStatus = IoVerifyVolume(DeviceToVerify, FALSE);
|
||||
DPRINT1("IoVerifyVolume() retuned (Status %lx)\n", NewStatus);
|
||||
}
|
||||
|
||||
DPRINT("Returning Status %x\n", Status);
|
||||
|
||||
return Status;
|
||||
|
|
|
@ -140,28 +140,9 @@ CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
|
|||
0,
|
||||
NULL,
|
||||
0,
|
||||
TRUE);
|
||||
FALSE);
|
||||
DPRINT ("Status %lx\n", Status);
|
||||
if (Status == STATUS_VERIFY_REQUIRED)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
|
||||
DPRINT1 ("Media change detected!\n");
|
||||
DPRINT1 ("Device %p\n", DeviceExt->VolumeDevice);
|
||||
|
||||
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
|
||||
IoSetDeviceToVerify (PsGetCurrentThread (),
|
||||
NULL);
|
||||
|
||||
Status = IoVerifyVolume (DeviceToVerify,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("Status %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else if (!NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("Status %lx\n", Status);
|
||||
return Status;
|
||||
|
|
|
@ -345,6 +345,7 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
|||
goto ByeBye;
|
||||
|
||||
NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO;
|
||||
NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
|
||||
DeviceExt = (PVOID)NewDeviceObject->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExt,
|
||||
sizeof(DEVICE_EXTENSION));
|
||||
|
|
|
@ -134,6 +134,10 @@ VOID STDCALL
|
|||
CdromTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID Context);
|
||||
|
||||
VOID
|
||||
CdromWorkItem(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID Context);
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
@ -1203,7 +1207,10 @@ CdromClassStartIo (IN PDEVICE_OBJECT DeviceObject,
|
|||
Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
|
||||
|
||||
/* FIXME: Update drive capacity */
|
||||
|
||||
IoCompleteRequest (Irp,
|
||||
IO_DISK_INCREMENT);
|
||||
IoStartNextPacket (DeviceObject,
|
||||
FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1614,11 +1621,68 @@ CdromDeviceControlCompletion (IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
|
||||
VOID STDCALL
|
||||
CdromTimerRoutine(PDEVICE_OBJECT DeviceObject,
|
||||
PVOID Context)
|
||||
CdromTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID Context)
|
||||
{
|
||||
DPRINT ("CdromTimerRoutine() called\n");
|
||||
PIO_WORKITEM WorkItem;
|
||||
|
||||
DPRINT ("CdromTimerRoutine() called\n");
|
||||
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||
if (!WorkItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IoQueueWorkItem(WorkItem,
|
||||
CdromWorkItem,
|
||||
DelayedWorkQueue,
|
||||
WorkItem);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CdromWorkItem(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID Context)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("CdromWorkItem() called\n");
|
||||
|
||||
IoFreeWorkItem((PIO_WORKITEM) Context);
|
||||
|
||||
KeInitializeEvent(&Event,
|
||||
NotificationEvent,
|
||||
FALSE);
|
||||
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_CDROM_CHECK_VERIFY,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
DPRINT("IoBuildDeviceIoControlRequest failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
DPRINT("Status: %x\n", Status);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event,
|
||||
Suspended,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1026,6 +1026,46 @@ ScsiClassInternalIoControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implements part of the directives on:
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kmarch/hh/kmarch/other_c694d732-fa95-4841-8d61-2a55ee787905.xml.asp
|
||||
*/
|
||||
static VOID
|
||||
ScsiClassInvalidateMedia(IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT NTSTATUS *Status)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_EXTENSION PhysicalExtension;
|
||||
|
||||
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
PhysicalExtension = (PDEVICE_EXTENSION)DeviceExtension->PhysicalDevice->DeviceExtension;
|
||||
|
||||
if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
|
||||
{
|
||||
DPRINT("Invalidate: test char yields TRUE\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Invalidate: test char yields FALSE\n");
|
||||
}
|
||||
|
||||
if ((DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
|
||||
(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
||||
{
|
||||
DPRINT("Set DO_VERIFY_VOLUME\n");
|
||||
DeviceObject->Flags |= DO_VERIFY_VOLUME;
|
||||
*Status = STATUS_VERIFY_REQUIRED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Status = STATUS_IO_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
/* Increment the media change count */
|
||||
PhysicalExtension->MediaChangeCount++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -1106,9 +1146,12 @@ ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
case SCSI_ADSENSE_NO_MEDIA_IN_DEVICE:
|
||||
DPRINT("SCSI_ADSENSE_NO_MEDIA_IN_DEVICE\n");
|
||||
*Status = STATUS_NO_MEDIA_IN_DEVICE;
|
||||
ScsiClassInvalidateMedia(DeviceObject,
|
||||
Status);
|
||||
|
||||
*Status = STATUS_NO_MEDIA_IN_DEVICE;
|
||||
Retry = FALSE;
|
||||
|
||||
|
||||
if((DeviceExtension->MediaChangeEvent != NULL) &&
|
||||
(!DeviceExtension->MediaChangeEvent))
|
||||
{
|
||||
|
@ -1200,22 +1243,9 @@ ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject,
|
|||
break;
|
||||
}
|
||||
|
||||
if ((DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
|
||||
(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
||||
{
|
||||
DPRINT("SCSI_SENSE_UNIT_ATTENTION set DoVerifyVol\n");
|
||||
|
||||
DeviceObject->Flags |= DO_VERIFY_VOLUME;
|
||||
*Status = STATUS_VERIFY_REQUIRED;
|
||||
Retry = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Status = STATUS_IO_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
/* Increment the media change count */
|
||||
PhysicalExtension->MediaChangeCount++;
|
||||
ScsiClassInvalidateMedia(DeviceObject,
|
||||
Status);
|
||||
Retry = FALSE;
|
||||
break;
|
||||
|
||||
case SCSI_SENSE_DATA_PROTECT:
|
||||
|
|
Loading…
Reference in a new issue