Patch by tinus.Fix media change support for CDROMs. This fixes bug #471.
Patch by tinus.
Modified: trunk/reactos/drivers/fs/cdfs/common.c
Modified: trunk/reactos/drivers/fs/cdfs/create.c
Modified: trunk/reactos/drivers/fs/cdfs/fsctl.c
Modified: trunk/reactos/drivers/storage/cdrom/cdrom.c
Modified: trunk/reactos/drivers/storage/class2/class2.c
_____
Modified: trunk/reactos/drivers/fs/cdfs/common.c
--- trunk/reactos/drivers/fs/cdfs/common.c 2005-01-17 10:20:03 UTC
(rev 13096)
+++ trunk/reactos/drivers/fs/cdfs/common.c 2005-01-17 14:30:31 UTC
(rev 13097)
@@ -191,6 +191,19 @@
*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;
_____
Modified: trunk/reactos/drivers/fs/cdfs/create.c
--- trunk/reactos/drivers/fs/cdfs/create.c 2005-01-17 10:20:03 UTC
(rev 13096)
+++ trunk/reactos/drivers/fs/cdfs/create.c 2005-01-17 14:30:31 UTC
(rev 13097)
@@ -140,29 +140,10 @@
0,
NULL,
0,
- TRUE);
+ FALSE);
DPRINT ("Status %lx\n", Status);
- if (Status == STATUS_VERIFY_REQUIRED)
+ if (!NT_SUCCESS(Status))
{
- 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))
- {
DPRINT1 ("Status %lx\n", Status);
return Status;
}
_____
Modified: trunk/reactos/drivers/fs/cdfs/fsctl.c
--- trunk/reactos/drivers/fs/cdfs/fsctl.c 2005-01-17 10:20:03 UTC
(rev 13096)
+++ trunk/reactos/drivers/fs/cdfs/fsctl.c 2005-01-17 14:30:31 UTC
(rev 13097)
@@ -345,6 +345,7 @@
goto ByeBye;
NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO;
+ NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
DeviceExt = (PVOID)NewDeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExt,
sizeof(DEVICE_EXTENSION));
_____
Modified: trunk/reactos/drivers/storage/cdrom/cdrom.c
--- trunk/reactos/drivers/storage/cdrom/cdrom.c 2005-01-17 10:20:03 UTC
(rev 13096)
+++ trunk/reactos/drivers/storage/cdrom/cdrom.c 2005-01-17 14:30:31 UTC
(rev 13097)
@@ -134,7 +134,11 @@
CdromTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context);
+VOID
+CdromWorkItem(IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context);
+
/* FUNCTIONS
****************************************************************/
/**********************************************************************
@@ -1203,7 +1207,10 @@
Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
/* FIXME: Update drive capacity */
-
+ IoCompleteRequest (Irp,
+ IO_DISK_INCREMENT);
+ IoStartNextPacket (DeviceObject,
+ FALSE);
return;
}
}
@@ -1614,11 +1621,68 @@
VOID STDCALL
-CdromTimerRoutine(PDEVICE_OBJECT DeviceObject,
- PVOID Context)
+CdromTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
{
+ 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 */
_____
Modified: trunk/reactos/drivers/storage/class2/class2.c
--- trunk/reactos/drivers/storage/class2/class2.c 2005-01-17
10:20:03 UTC (rev 13096)
+++ trunk/reactos/drivers/storage/class2/class2.c 2005-01-17
14:30:31 UTC (rev 13097)
@@ -1027,6 +1027,46 @@
/*
+ * 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
*/
BOOLEAN STDCALL
@@ -1106,9 +1146,12 @@
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 @@
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: