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()->
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;
}