+MajorFunction_DEVICE_CONTROL() handling IRP_MJ_DEVICE_CONTROL
authorshort <>
Wed, 6 Nov 2002 14:01:11 +0000 (14:01 +0000)
committershort <>
Wed, 6 Nov 2002 14:01:11 +0000 (14:01 +0000)
+IOCTL_CDROM_CHECK_VERIFY handler
+cdrom_DiskGeometry for DeviceExtension->DiskGeometry

src/libcaptive/storage/cdrom.c

index 09adaa1..7cfefac 100644 (file)
 
 
 static DRIVER_OBJECT cdrom_DriverObject;
+static DISK_GEOMETRY cdrom_DiskGeometry;
+static DISK_GEOMETRY cdrom_DiskGeometry_check; /* for g_assert() checking against foreign modifications */
 static int Image_fd=-1;
 static off_t Image_size;       /* FIXME: lseek64() */
 
 
+/* FIXME: We should comply with PDRIVER_DISPATCH prototype but unfortunately
+ * CAPTIVE_STDCALL prevents us to do so at least in RedHat gcc-3.2-4 (gcc bug?).
+ */
+#define MajorFunction_DEVICE_CONTROL ((PDRIVER_DISPATCH)MajorFunction_DEVICE_CONTROL_func)
+static NTSTATUS CAPTIVE_STDCALL MajorFunction_DEVICE_CONTROL_func(IN DEVICE_OBJECT *DeviceObject,IN IRP *Irp)
+{
+IO_STACK_LOCATION *IrpStack;
+DEVICE_EXTENSION *DeviceExtension;
+
+       g_return_val_if_fail(DeviceObject!=NULL,STATUS_INVALID_PARAMETER);
+       g_return_val_if_fail(Irp!=NULL,STATUS_INVALID_PARAMETER);
+       g_return_val_if_fail(DeviceObject->DriverObject==&cdrom_DriverObject,STATUS_INVALID_PARAMETER);
+
+       IrpStack=IoGetCurrentIrpStackLocation(Irp);
+       g_assert(IrpStack->MajorFunction==IRP_MJ_DEVICE_CONTROL);
+       Irp->IoStatus.Information=0;    /* request-specific, may get overriden later */
+       DeviceExtension=DeviceObject->DeviceExtension;
+
+       switch (IrpStack->Parameters.DeviceIoControl.IoControlCode) {
+               
+               case IOCTL_CDROM_CHECK_VERIFY: {
+DISK_GEOMETRY *DiskGeometry=DeviceExtension->DiskGeometry;
+
+                       if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength) {
+                               if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength<sizeof(ULONG)) {
+                                       Irp->IoStatus.Status=STATUS_BUFFER_TOO_SMALL;
+                                       Irp->IoStatus.Information=sizeof(ULONG);
+                                       g_assert_not_reached();
+                                       goto done;
+                                       }
+                               *(ULONG *)Irp->AssociatedIrp.SystemBuffer=0;    /* MediaChangeCount */
+                               }
+                       g_assert(DiskGeometry==&cdrom_DiskGeometry);
+                       g_assert(DiskGeometry->MediaType==cdrom_DiskGeometry_check.MediaType);
+                       g_assert(DiskGeometry->TracksPerCylinder==cdrom_DiskGeometry_check.TracksPerCylinder);
+                       g_assert(DiskGeometry->SectorsPerTrack==cdrom_DiskGeometry_check.SectorsPerTrack);
+                       g_assert(DiskGeometry->BytesPerSector==cdrom_DiskGeometry_check.BytesPerSector);
+                       g_assert(DiskGeometry->Cylinders.QuadPart==cdrom_DiskGeometry_check.Cylinders.QuadPart);
+                       g_assert(DeviceExtension->PartitionLength.QuadPart==Image_size);
+                       } break;
+
+               default:
+                       Irp->IoStatus.Status=STATUS_INVALID_DEVICE_REQUEST;
+                       g_assert_not_reached();
+                       goto done;
+               }
+       /* PASSTHRU */
+
+done:  /* 'err:' but we flow here even during success */
+       /* required for removable media only */
+       if (!NT_SUCCESS(Irp->IoStatus.Status) && IoIsErrorUserInduced(Irp->IoStatus.Status)) {
+               g_assert(Irp->Tail.Overlay.Thread!=NULL);       /* FIXME: Error should be postponed to first !=NULL Irp later */
+               IoSetHardErrorOrVerifyDevice(Irp,DeviceObject);
+               Irp->IoStatus.Information=0;    /* may got set during some processing before error occured */
+               }
+
+       IoCompleteRequest(Irp,IO_NO_INCREMENT); /* I hope it won't corrupt our Irp->IoStatus.Status */
+       return Irp->IoStatus.Status;
+}
+
 
 /* similiar to drivers/storage/cdrom/cdrom.c/DriverEntry()->...
  * ...->CdromClassCreateDeviceObject()->
@@ -100,7 +162,19 @@ NTSTATUS err;
        DeviceExtension->TargetId=0;
        DeviceExtension->Lun=0;
 
-       /* FIXME: DriverObject->MajorFunction[IRP_MJ_CREATE] = ...; ... */
+       cdrom_DiskGeometry.MediaType=RemovableMedia;
+       cdrom_DiskGeometry.TracksPerCylinder=64;
+       cdrom_DiskGeometry.SectorsPerTrack=32;
+       cdrom_DiskGeometry.BytesPerSector=2048;
+       cdrom_DiskGeometry.Cylinders.QuadPart=Image_size
+                       /cdrom_DiskGeometry.BytesPerSector
+                       /cdrom_DiskGeometry.SectorsPerTrack
+                       /cdrom_DiskGeometry.TracksPerCylinder;
+       /* 'DeviceExtension->DiskGeometry' is NULL! */
+       cdrom_DiskGeometry_check=cdrom_DiskGeometry;    /* for g_assert() checking against foreign modifications */
+       DeviceExtension->DiskGeometry=&cdrom_DiskGeometry;
+
+       DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MajorFunction_DEVICE_CONTROL;
 
        return STATUS_SUCCESS;
 }