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: