https://git.reactos.org/?p=reactos.git;a=commitdiff;h=49444127fd4ca7f488c42…
commit 49444127fd4ca7f488c429e3b8a3253865243e39
Author: Victor Perevertkin <victor.perevertkin(a)reactos.org>
AuthorDate: Sun Aug 8 01:15:10 2021 +0300
Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org>
CommitDate: Sun Aug 8 02:42:30 2021 +0300
[CDROM][CLASS2][DISK] Remove the old class drivers stack
These drivers are based on NT4 DDK sample code, were originally
started by Alexey Bragin and then constantly patched by Pierre
Schweitzer to fix compatibility with NT5+ storage stack.
Replaced with Microsoft drivers published on GitHub by an open
license.
These drivers were originally added as part of
4e7b22b216725e1e7c0dff19ab0312039ff5005c
---
drivers/storage/class/cdrom/CMakeLists.txt | 15 -
drivers/storage/class/cdrom/cdrom.c | 7359 ---------------------------
drivers/storage/class/cdrom/cdrom.inf | 122 -
drivers/storage/class/cdrom/cdrom.rc | 5 -
drivers/storage/class/cdrom/cdrom_reg.inf | 7 -
drivers/storage/class/cdrom/findscsi.c | 308 --
drivers/storage/class/cdrom/license.txt | 53 -
drivers/storage/class/cdrom/precomp.h | 9 -
drivers/storage/class/class2/CMakeLists.txt | 13 -
drivers/storage/class/class2/class2.c | 5007 ------------------
drivers/storage/class/class2/class2.rc | 5 -
drivers/storage/class/class2/class2.spec | 22 -
drivers/storage/class/class2/license.txt | 53 -
drivers/storage/class/disk/CMakeLists.txt | 8 -
drivers/storage/class/disk/disk.c | 5440 --------------------
drivers/storage/class/disk/disk.inf | 136 -
drivers/storage/class/disk/disk.rc | 5 -
drivers/storage/class/disk/disk_reg.inf | 7 -
drivers/storage/class/disk/license.txt | 53 -
drivers/storage/class/include/class2.h | 267 -
drivers/storage/inc/class.h | 374 --
drivers/storage/inc/ide.h | 495 --
drivers/storage/inc/ideuser.h | 132 -
drivers/storage/inc/physlogi.h | 115 -
drivers/storage/inc/rbc.h | 180 -
drivers/storage/inc/tape.h | 312 --
26 files changed, 20502 deletions(-)
diff --git a/drivers/storage/class/cdrom/CMakeLists.txt
b/drivers/storage/class/cdrom/CMakeLists.txt
deleted file mode 100644
index 97b7a2431df..00000000000
--- a/drivers/storage/class/cdrom/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-include_directories(${REACTOS_SOURCE_DIR}/drivers/storage/class)
-
-list(APPEND SOURCE
- cdrom.c
- findscsi.c
- precomp.h)
-
-add_library(cdrom MODULE ${SOURCE} cdrom.rc)
-set_module_type(cdrom kernelmodedriver)
-add_importlibs(cdrom class2 scsiport ntoskrnl hal)
-add_pch(cdrom precomp.h SOURCE)
-add_cd_file(TARGET cdrom DESTINATION reactos/system32/drivers NO_CAB FOR all)
-add_registry_inf(cdrom_reg.inf)
-add_driver_inf(cdrom cdrom.inf)
diff --git a/drivers/storage/class/cdrom/cdrom.c b/drivers/storage/class/cdrom/cdrom.c
deleted file mode 100644
index 2794e62f2ea..00000000000
--- a/drivers/storage/class/cdrom/cdrom.c
+++ /dev/null
@@ -1,7359 +0,0 @@
-/*
- * PROJECT: ReactOS Storage Stack
- * LICENSE: DDK - see license.txt in the root dir
- * FILE: drivers/storage/cdrom/cdrom.c
- * PURPOSE: CDROM driver
- * PROGRAMMERS: Based on a source code sample from Microsoft NT4 DDK
- */
-
-#include "precomp.h"
-
-#include <ntddk.h>
-#include <scsi.h>
-#include <ntdddisk.h>
-#include <ntddcdrm.h>
-#include <include/class2.h>
-#include <stdio.h>
-
-//#define NDEBUG
-#include <debug.h>
-
-#define CDB12GENERIC_LENGTH 12
-
-typedef struct _XA_CONTEXT {
-
- //
- // Pointer to the device object.
- //
-
- PDEVICE_OBJECT DeviceObject;
-
- //
- // Pointer to the original request when
- // a mode select must be sent.
- //
-
- PIRP OriginalRequest;
-
- //
- // Pointer to the mode select srb.
- //
-
- PSCSI_REQUEST_BLOCK Srb;
-} XA_CONTEXT, *PXA_CONTEXT;
-
-typedef struct _ERROR_RECOVERY_DATA {
- MODE_PARAMETER_HEADER Header;
- MODE_PARAMETER_BLOCK BlockDescriptor;
- MODE_READ_RECOVERY_PAGE ReadRecoveryPage;
-} ERROR_RECOVERY_DATA, *PERROR_RECOVERY_DATA;
-
-typedef struct _ERROR_RECOVERY_DATA10 {
- MODE_PARAMETER_HEADER10 Header10;
- MODE_PARAMETER_BLOCK BlockDescriptor10;
- MODE_READ_RECOVERY_PAGE ReadRecoveryPage10;
-} ERROR_RECOVERY_DATA10, *PERROR_RECOVERY_DATA10;
-
-//
-// CdRom specific addition to device extension.
-//
-
-typedef struct _CDROM_DATA {
-
- //
- // Indicates whether an audio play operation
- // is currently being performed.
- //
-
- BOOLEAN PlayActive;
-
- //
- // Indicates whether the blocksize used for user data
- // is 2048 or 2352.
- //
-
- BOOLEAN RawAccess;
-
- //
- // Indicates whether 6 or 10 byte mode sense/select
- // should be used.
- //
-
- USHORT XAFlags;
-
- //
- // Storage for the error recovery page. This is used
- // as an easy method to switch block sizes.
- //
-
- union {
- ERROR_RECOVERY_DATA u1;
- ERROR_RECOVERY_DATA10 u2;
- };
-
-
- //
- // Pointer to the original irp for the raw read.
- //
-
- PIRP SavedReadIrp;
-
- //
- // Used to protect accesses to the RawAccess flag.
- //
-
- KSPIN_LOCK FormSpinLock;
-
- //
- // Even if media change support is requested, there are some devices
- // that are not supported. This flag will indicate that such a device
- // is present when it is FALSE.
- //
-
- BOOLEAN MediaChangeSupported;
-
- //
- // The media change event is being supported. The media change timer
- // should be running whenever this is true.
- //
-
- BOOLEAN MediaChange;
-
- //
- // The timer value to support media change events. This is a countdown
- // value used to determine when to poll the device for a media change.
- // The max value for the timer is 255 seconds.
- //
-
- UCHAR MediaChangeCountDown;
-
-#if DBG
- //
- // Second timer to keep track of how long the media change IRP has been
- // in use. If this value exceeds the timeout (#defined) then we should
- // print out a message to the user and set the MediaChangeIrpLost flag
- //
-
- SHORT MediaChangeIrpTimeInUse;
-
- //
- // Set by CdRomTickHandler when we determine that the media change irp has
- // been lost
- //
-
- BOOLEAN MediaChangeIrpLost;
-#endif
-
- UCHAR PadReserve; // use this for new flags.
-
- //
- // An IRP is allocated and kept for the duration that media change
- // detection is in effect. If this is NULL and MediaChange is TRUE,
- // the detection is in progress. This should always be NULL when
- // MediaChange is FALSE.
- //
-
- PIRP MediaChangeIrp;
-
- //
- // The timer work list is a collection of IRPS that are prepared for
- // submission, but need to allow some time to pass before they are
- // run.
- //
-
- LIST_ENTRY TimerIrpList;
- KSPIN_LOCK TimerIrpSpinLock;
-
-} CDROM_DATA, *PCDROM_DATA;
-
-#define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION) + sizeof(CDROM_DATA)
-#define SCSI_CDROM_TIMEOUT 10
-#define SCSI_CHANGER_BONUS_TIMEOUT 10
-#define HITACHI_MODE_DATA_SIZE 12
-#define MODE_DATA_SIZE 64
-#define RAW_SECTOR_SIZE 2352
-#define COOKED_SECTOR_SIZE 2048
-#define MEDIA_CHANGE_DEFAULT_TIME 4
-#define CDROM_SRB_LIST_SIZE 4
-
-
-#if DBG
-
-//
-// Used to detect the loss of the autorun irp. The driver prints out a message
-// (debug level 0) if this timeout ever occurs
-//
-#define MEDIA_CHANGE_TIMEOUT_TIME 300
-
-#endif
-
-#define PLAY_ACTIVE(DeviceExtension) (((PCDROM_DATA)(DeviceExtension +
1))->PlayActive)
-
-#define MSF_TO_LBA(Minutes,Seconds,Frames) \
- (ULONG)((60 * 75 * (Minutes)) + (75 * (Seconds)) + ((Frames) - 150))
-
-#define LBA_TO_MSF(Lba,Minutes,Seconds,Frames) \
-{ \
- (Minutes) = (UCHAR)(Lba / (60 * 75)); \
- (Seconds) = (UCHAR)((Lba % (60 * 75)) / 75); \
- (Frames) = (UCHAR)((Lba % (60 * 75)) % 75); \
-}
-
-#define DEC_TO_BCD(x) (((x / 10) << 4) + (x % 10))
-
-//
-// Define flags for XA, CDDA, and Mode Select/Sense
-//
-
-#define XA_USE_6_BYTE 0x01
-#define XA_USE_10_BYTE 0x02
-#define XA_USE_READ_CD 0x04
-#define XA_NOT_SUPPORTED 0x08
-
-#define PLEXTOR_CDDA 0x10
-#define NEC_CDDA 0x20
-
-//
-// Sector types for READ_CD
-//
-
-#define ANY_SECTOR 0
-#define CD_DA_SECTOR 1
-#define YELLOW_MODE1_SECTOR 2
-#define YELLOW_MODE2_SECTOR 3
-#define FORM2_MODE1_SECTOR 4
-#define FORM2_MODE2_SECTOR 5
-
-
-#ifdef POOL_TAGGING
-#ifdef ExAllocatePool
-#undef ExAllocatePool
-#endif
-#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'CscS')
-#endif
-
-NTSTATUS
-NTAPI
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- );
-
-BOOLEAN
-NTAPI
-ScsiCdRomFindDevices(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath,
- IN PCLASS_INIT_DATA InitializationData,
- IN PDEVICE_OBJECT PortDeviceObject,
- IN ULONG PortNumber
- );
-
-NTSTATUS
-NTAPI
-ScsiCdRomOpenClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-NTAPI
-ScsiCdRomReadVerification(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-NTSTATUS
-NTAPI
-ScsiCdRomSwitchMode(
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SectorSize,
- IN PIRP OriginalRequest
- );
-
-NTSTATUS
-NTAPI
-CdRomDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-IO_COMPLETION_ROUTINE CdRomDeviceControlCompletion;
-NTSTATUS
-NTAPI
-CdRomDeviceControlCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-IO_COMPLETION_ROUTINE CdRomSetVolumeIntermediateCompletion;
-NTSTATUS
-NTAPI
-CdRomSetVolumeIntermediateCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-IO_COMPLETION_ROUTINE CdRomSwitchModeCompletion;
-NTSTATUS
-NTAPI
-CdRomSwitchModeCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-IO_COMPLETION_ROUTINE CdRomXACompletion;
-NTSTATUS
-NTAPI
-CdRomXACompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-IO_COMPLETION_ROUTINE CdRomClassIoctlCompletion;
-NTSTATUS
-NTAPI
-CdRomClassIoctlCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- );
-
-VOID
-NTAPI
-ScsiCdRomStartIo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-VOID
-NTAPI
-CdRomTickHandler(
- IN PDEVICE_OBJECT DeviceObject,
- IN PVOID Context
- );
-
-BOOLEAN
-NTAPI
-CdRomCheckRegistryForMediaChangeValue(
- IN PUNICODE_STRING RegistryPath,
- IN ULONG DeviceNumber
- );
-
-NTSTATUS
-NTAPI
-CdRomUpdateCapacity(
- IN PDEVICE_EXTENSION DeviceExtension,
- IN PIRP IrpToComplete,
- IN OPTIONAL PKEVENT IoctlEvent
- );
-
-NTSTATUS
-NTAPI
-CreateCdRomDeviceObject(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT PortDeviceObject,
- IN ULONG PortNumber,
- IN PULONG DeviceCount,
- PIO_SCSI_CAPABILITIES PortCapabilities,
- IN PSCSI_INQUIRY_DATA LunInfo,
- IN PCLASS_INIT_DATA InitializationData,
- IN PUNICODE_STRING RegistryPath
- );
-
-VOID
-NTAPI
-ScanForSpecial(
- PDEVICE_OBJECT DeviceObject,
- PINQUIRYDATA InquiryData,
- PIO_SCSI_CAPABILITIES PortCapabilities
- );
-
-BOOLEAN
-NTAPI
-CdRomIsPlayActive(
- IN PDEVICE_OBJECT DeviceObject
- );
-
-VOID
-NTAPI
-HitachProcessError(
- PDEVICE_OBJECT DeviceObject,
- PSCSI_REQUEST_BLOCK Srb,
- NTSTATUS *Status,
- BOOLEAN *Retry
- );
-
-IO_COMPLETION_ROUTINE ToshibaProcessErrorCompletion;
-VOID
-NTAPI
-ToshibaProcessError(
- PDEVICE_OBJECT DeviceObject,
- PSCSI_REQUEST_BLOCK Srb,
- NTSTATUS *Status,
- BOOLEAN *Retry
- );
-
-BOOLEAN
-NTAPI
-IsThisAnAtapiChanger(
- IN PDEVICE_OBJECT DeviceObject,
- OUT PULONG DiscsPresent
- );
-
-BOOLEAN
-NTAPI
-IsThisASanyo(
- IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR PathId,
- IN UCHAR TargetId
- );
-
-BOOLEAN
-NTAPI
-IsThisAMultiLunDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PDEVICE_OBJECT PortDeviceObject
- );
-
-VOID
-NTAPI
-CdRomCreateNamedEvent(
- IN PDEVICE_EXTENSION DeviceExtension,
- IN ULONG DeviceNumber
- );
-
-#ifdef _PPC_
-NTSTATUS
-FindScsiAdapter (
- IN HANDLE KeyHandle,
- IN UNICODE_STRING ScsiUnicodeString[],
- OUT PUCHAR IntermediateController
- );
-#endif
-
-#ifdef ALLOC_PRAGMA
-#pragma alloc_text(PAGE, DriverEntry)
-#pragma alloc_text(PAGE, ScsiCdRomFindDevices)
-#pragma alloc_text(PAGE, CreateCdRomDeviceObject)
-#pragma alloc_text(PAGE, ScanForSpecial)
-//#pragma alloc_text(PAGE, CdRomDeviceControl)
-#pragma alloc_text(PAGE, HitachProcessError)
-#pragma alloc_text(PAGE, CdRomIsPlayActive)
-#pragma alloc_text(PAGE, ScsiCdRomReadVerification)
-#pragma alloc_text(INIT, CdRomCheckRegistryForMediaChangeValue)
-#pragma alloc_text(INIT, IsThisAnAtapiChanger)
-#pragma alloc_text(INIT, IsThisASanyo)
-#pragma alloc_text(INIT, IsThisAMultiLunDevice)
-#pragma alloc_text(INIT, CdRomCreateNamedEvent)
-#ifdef _PPC_
-#pragma alloc_text(PAGE, FindScsiAdapter)
-#endif
-#endif
-
-ULONG NoLoad = 0;
-
-NTSTATUS
-NTAPI
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
-
-/*++
-
-Routine Description:
-
- This routine initializes the cdrom class driver.
-
-Arguments:
-
- DriverObject - Pointer to driver object created by system.
-
- RegistryPath - Pointer to the name of the services node for this driver.
-
-Return Value:
-
- The function value is the final status from the initialization operation.
-
---*/
-
-{
- CLASS_INIT_DATA InitializationData;
-
- if(NoLoad) {
- return STATUS_NO_SUCH_DEVICE;
- }
-
- //
- // Zero InitData
- //
-
- RtlZeroMemory (&InitializationData, sizeof(CLASS_INIT_DATA));
-
- //
- // Set sizes
- //
-
- InitializationData.InitializationDataSize = sizeof(CLASS_INIT_DATA);
- InitializationData.DeviceExtensionSize = DEVICE_EXTENSION_SIZE;
-
- InitializationData.DeviceType = FILE_DEVICE_CD_ROM;
- InitializationData.DeviceCharacteristics = FILE_REMOVABLE_MEDIA |
FILE_READ_ONLY_DEVICE;
-
- //
- // Set entry points
- //
-
- InitializationData.ClassReadWriteVerification = ScsiCdRomReadVerification;
- InitializationData.ClassDeviceControl = CdRomDeviceControl;
- InitializationData.ClassFindDevices = ScsiCdRomFindDevices;
- InitializationData.ClassShutdownFlush = NULL;
- InitializationData.ClassCreateClose = NULL;
- InitializationData.ClassStartIo = ScsiCdRomStartIo;
-
- //
- // Call the class init routine
- //
-
- return ScsiClassInitialize( DriverObject, RegistryPath, &InitializationData);
-
-} // end DriverEntry()
-
-BOOLEAN
-NTAPI
-ScsiCdRomFindDevices(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath,
- IN PCLASS_INIT_DATA InitializationData,
- IN PDEVICE_OBJECT PortDeviceObject,
- IN ULONG PortNumber
- )
-
-/*++
-
-Routine Description:
-
- Connect to SCSI port driver. Get adapter capabilities and
- SCSI bus configuration information. Search inquiry data
- for CDROM devices to process.
-
-Arguments:
-
- DriverObject - CDROM class driver object.
- PortDeviceObject - SCSI port driver device object.
- PortNumber - The system ordinal for this scsi adapter.
-
-Return Value:
-
- TRUE if CDROM device present on this SCSI adapter.
-
---*/
-
-{
- PIO_SCSI_CAPABILITIES portCapabilities;
- PULONG cdRomCount;
- PCHAR buffer;
- PSCSI_INQUIRY_DATA lunInfo;
- PSCSI_ADAPTER_BUS_INFO adapterInfo;
- PINQUIRYDATA inquiryData;
- ULONG scsiBus;
- NTSTATUS status;
- BOOLEAN foundDevice = FALSE;
-
- //
- // Call port driver to get adapter capabilities.
- //
-
- status = ScsiClassGetCapabilities(PortDeviceObject, &portCapabilities);
-
- if (!NT_SUCCESS(status)) {
- DebugPrint((1,"FindScsiDevices: ScsiClassGetCapabilities failed\n"));
- return foundDevice;
- }
-
- //
- // Call port driver to get inquiry information to find cdroms.
- //
-
- status = ScsiClassGetInquiryData(PortDeviceObject, (PSCSI_ADAPTER_BUS_INFO *)
&buffer);
-
- if (!NT_SUCCESS(status)) {
- DebugPrint((1,"FindScsiDevices: ScsiClassGetInquiryData failed\n"));
- return foundDevice;
- }
-
- //
- // Get the address of the count of the number of cdroms already initialized.
- //
-
- cdRomCount = &IoGetConfigurationInformation()->CdRomCount;
- adapterInfo = (PVOID) buffer;
-
- //
- // For each SCSI bus this adapter supports ...
- //
-
- for (scsiBus=0; scsiBus < adapterInfo->NumberOfBuses; scsiBus++) {
-
- //
- // Get the SCSI bus scan data for this bus.
- //
-
- lunInfo = (PVOID) (buffer + adapterInfo->BusData[scsiBus].InquiryDataOffset);
-
- //
- // Search list for unclaimed disk devices.
- //
-
- while (adapterInfo->BusData[scsiBus].InquiryDataOffset) {
-
- inquiryData = (PVOID)lunInfo->InquiryData;
-
- if ((inquiryData->DeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE)
&&
- (inquiryData->DeviceTypeQualifier == 0) &&
- (!lunInfo->DeviceClaimed)) {
-
- DebugPrint((1,"FindScsiDevices: Vendor string is %.24s\n",
- inquiryData->VendorId));
-
- //
- // Create device objects for cdrom
- //
-
- status = CreateCdRomDeviceObject(DriverObject,
- PortDeviceObject,
- PortNumber,
- cdRomCount,
- portCapabilities,
- lunInfo,
- InitializationData,
- RegistryPath);
-
- if (NT_SUCCESS(status)) {
-
- //
- // Increment system cdrom device count.
- //
-
- (*cdRomCount)++;
-
- //
- // Indicate that a cdrom device was found.
- //
-
- foundDevice = TRUE;
- }
- }
-
- //
- // Get next LunInfo.
- //
-
- if (lunInfo->NextInquiryDataOffset == 0) {
- break;
- }
-
- lunInfo = (PVOID) (buffer + lunInfo->NextInquiryDataOffset);
- }
- }
-
- ExFreePool(buffer);
-
-
- return foundDevice;
-
-} // end FindScsiCdRoms()
-
-VOID
-NTAPI
-CdRomCreateNamedEvent(
- IN PDEVICE_EXTENSION DeviceExtension,
- IN ULONG DeviceNumber
- )
-
-/*++
-
-Routine Description:
-
- Create the named synchronization event for notification of media change
- events to the system. The event is reset before this function returns.
-
-Arguments:
-
- DeviceExtension - the device extension pointer for storage of the event pointer.
-
-Return Value:
-
- None.
-
---*/
-
-{
- UNICODE_STRING unicodeString;
- OBJECT_ATTRIBUTES objectAttributes;
- CCHAR eventNameBuffer[MAXIMUM_FILENAME_LENGTH];
- STRING eventNameString;
- HANDLE handle;
- NTSTATUS status;
-
-
- sprintf(eventNameBuffer,"\\Device\\MediaChangeEvent%ld",
- DeviceNumber);
-
- RtlInitString(&eventNameString,
- eventNameBuffer);
-
- status = RtlAnsiStringToUnicodeString(&unicodeString,
- &eventNameString,
- TRUE);
-
- if (!NT_SUCCESS(status)) {
- return;
- }
-
- InitializeObjectAttributes(&objectAttributes,
- &unicodeString,
- OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
- NULL,
- NULL);
-
- DeviceExtension->MediaChangeEvent =
IoCreateSynchronizationEvent(&unicodeString,
- &handle);
- DeviceExtension->MediaChangeEventHandle = handle;
-
- KeClearEvent(DeviceExtension->MediaChangeEvent);
-
- RtlFreeUnicodeString(&unicodeString);
-}
-
-
-VOID
-NTAPI
-ReportToMountMgr(
- IN PDEVICE_OBJECT CdDeviceObject
- )
-
-/*++
-
-Routine Description:
-
- This routine reports the creation of a cdrom device object to the
- MountMgr to fake PnP.
-
-Arguments:
-
- CdDeviceObject - Pointer to the created cdrom device.
-
-Return Value:
-
- VOID
-
---*/
-{
- NTSTATUS status;
- UNICODE_STRING mountMgrDevice;
- PDEVICE_OBJECT deviceObject;
- PFILE_OBJECT fileObject;
- PMOUNTMGR_TARGET_NAME mountTarget;
- ULONG cdLen;
- PDEVICE_EXTENSION deviceExtension;
- PIRP irp;
- KEVENT event;
- IO_STATUS_BLOCK ioStatus;
-
- //
- // First, get MountMgr DeviceObject.
- //
-
- RtlInitUnicodeString(&mountMgrDevice, MOUNTMGR_DEVICE_NAME);
- status = IoGetDeviceObjectPointer(&mountMgrDevice, FILE_READ_ATTRIBUTES,
- &fileObject, &deviceObject);
-
- if (!NT_SUCCESS(status)) {
-
- DebugPrint((1,
- "ReportToMountMgr: Can't get MountMgr pointers %lx\n",
- status));
-
- return;
- }
-
- deviceExtension = CdDeviceObject->DeviceExtension;
- cdLen = deviceExtension->DeviceName.Length;
-
- //
- // Allocate input buffer to report our partition device.
- //
-
- mountTarget = ExAllocatePool(NonPagedPool,
- sizeof(MOUNTMGR_TARGET_NAME) + cdLen);
-
- if (!mountTarget) {
-
- DebugPrint((1,
- "ReportToMountMgr: Allocation of mountTarget failed\n"));
-
- ObDereferenceObject(fileObject);
- return;
- }
-
- mountTarget->DeviceNameLength = cdLen;
- RtlCopyMemory(mountTarget->DeviceName, deviceExtension->DeviceName.Buffer,
cdLen);
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
-
- //
- // Build the IRP used to communicate with the MountMgr.
- //
-
- irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
- deviceObject,
- mountTarget,
- sizeof(MOUNTMGR_TARGET_NAME) + cdLen,
- NULL,
- 0,
- FALSE,
- &event,
- &ioStatus);
-
- if (!irp) {
-
- DebugPrint((1,
- "ReportToMountMgr: Allocation of irp failed\n"));
-
- ExFreePool(mountTarget);
- ObDereferenceObject(fileObject);
- return;
- }
-
- //
- // Call the MountMgr.
- //
-
- status = IoCallDriver(deviceObject, irp);
-
- if (status == STATUS_PENDING) {
- KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
- status = ioStatus.Status;
- }
-
- //
- // We're done.
- //
-
- DPRINT1("Reported to the MountMgr: %lx\n", status);
-
- ExFreePool(mountTarget);
- ObDereferenceObject(fileObject);
-
- return;
-}
-
-
-NTSTATUS
-NTAPI
-CreateCdRomDeviceObject(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT PortDeviceObject,
- IN ULONG PortNumber,
- IN PULONG DeviceCount,
- IN PIO_SCSI_CAPABILITIES PortCapabilities,
- IN PSCSI_INQUIRY_DATA LunInfo,
- IN PCLASS_INIT_DATA InitializationData,
- IN PUNICODE_STRING RegistryPath
- )
-
-/*++
-
-Routine Description:
-
- This routine creates an object for the device and then calls the
- SCSI port driver for media capacity and sector size.
-
-Arguments:
-
- DriverObject - Pointer to driver object created by system.
- PortDeviceObject - to connect to SCSI port driver.
- DeviceCount - Number of previously installed CDROMs.
- PortCapabilities - Pointer to structure returned by SCSI port
- driver describing adapter capabilities (and limitations).
- LunInfo - Pointer to configuration information for this device.
-
-Return Value:
-
- NTSTATUS
-
---*/
-{
- CHAR ntNameBuffer[64];
- NTSTATUS status;
- BOOLEAN changerDevice;
- SCSI_REQUEST_BLOCK srb;
- ULONG length;
- PCDROM_DATA cddata;
- PCDB cdb;
- PVOID senseData = NULL;
- PDEVICE_OBJECT deviceObject = NULL;
- PDEVICE_EXTENSION deviceExtension = NULL;
- PUCHAR buffer;
- ULONG bps;
- ULONG lastBit;
- ULONG timeOut;
- BOOLEAN srbListInitialized = FALSE;
-
- //
- // Claim the device. Note that any errors after this
- // will goto the generic handler, where the device will
- // be released.
- //
-
- status = ScsiClassClaimDevice(PortDeviceObject,
- LunInfo,
- FALSE,
- &PortDeviceObject);
-
- if (!NT_SUCCESS(status)) {
- return(status);
- }
-
- //
- // Create device object for this device.
- //
-
- sprintf(ntNameBuffer,
- "\\Device\\CdRom%lu",
- *DeviceCount);
-
- status = ScsiClassCreateDeviceObject(DriverObject,
- ntNameBuffer,
- NULL,
- &deviceObject,
- InitializationData);
-
- if (!NT_SUCCESS(status)) {
- DebugPrint((1,"CreateCdRomDeviceObjects: Can not create device %s\n",
- ntNameBuffer));
-
- goto CreateCdRomDeviceObjectExit;
- }
-
- //
- // Indicate that IRPs should include MDLs.
- //
-
- deviceObject->Flags |= DO_DIRECT_IO;
-
- //
- // Set up required stack size in device object.
- //
-
- deviceObject->StackSize = PortDeviceObject->StackSize + 2;
-
- deviceExtension = deviceObject->DeviceExtension;
-
- //
- // Allocate spinlock for split request completion.
- //
-
- KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);
-
- //
- // This is the physical device.
- //
-
- deviceExtension->PhysicalDevice = deviceObject;
-
- //
- // Initialize lock count to zero. The lock count is used to
- // disable the ejection mechanism when media is mounted.
- //
-
- deviceExtension->LockCount = 0;
-
- //
- // Save system cdrom number
- //
-
- deviceExtension->DeviceNumber = *DeviceCount;
-
- //
- // Copy port device object to device extension.
- //
-
- deviceExtension->PortDeviceObject = PortDeviceObject;
-
- //
- // Set the alignment requirements for the device based on the
- // host adapter requirements
- //
-
- if (PortDeviceObject->AlignmentRequirement >
deviceObject->AlignmentRequirement) {
- deviceObject->AlignmentRequirement =
PortDeviceObject->AlignmentRequirement;
- }
-
- //
- // Save address of port driver capabilities.
- //
-
- deviceExtension->PortCapabilities = PortCapabilities;
-
- //
- // Clear SRB flags.
- //
-
- deviceExtension->SrbFlags = 0;
- deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
-
- //
- // Allocate request sense buffer.
- //
-
- senseData = ExAllocatePool(NonPagedPoolCacheAligned, SENSE_BUFFER_SIZE);
-
- if (senseData == NULL) {
-
- //
- // The buffer cannot be allocated.
- //
-
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto CreateCdRomDeviceObjectExit;
- }
-
- //
- // Set the sense data pointer in the device extension.
- //
-
- deviceExtension->SenseData = senseData;
-
- //
- // CDROMs are not partitionable so starting offset is 0.
- //
-
- deviceExtension->StartingOffset.LowPart = 0;
- deviceExtension->StartingOffset.HighPart = 0;
-
- //
- // Path/TargetId/LUN describes a device location on the SCSI bus.
- // This information comes from the LunInfo buffer.
- //
-
- deviceExtension->PortNumber = (UCHAR)PortNumber;
- deviceExtension->PathId = LunInfo->PathId;
- deviceExtension->TargetId = LunInfo->TargetId;
- deviceExtension->Lun = LunInfo->Lun;
-
- //
- // Set timeout value in seconds.
- //
-
- timeOut = ScsiClassQueryTimeOutRegistryValue(RegistryPath);
- if (timeOut) {
- deviceExtension->TimeOutValue = timeOut;
- } else {
- deviceExtension->TimeOutValue = SCSI_CDROM_TIMEOUT;
- }
-
- //
- // Build the lookaside list for srb's for the physical disk. Should only
- // need a couple.
- //
-
- ScsiClassInitializeSrbLookasideList(deviceExtension,
- CDROM_SRB_LIST_SIZE);
-
- srbListInitialized = TRUE;
-
- //
- // Back pointer to device object.
- //
-
- deviceExtension->DeviceObject = deviceObject;
-
- //
- // Allocate buffer for drive geometry.
- //
-
- deviceExtension->DiskGeometry =
- ExAllocatePool(NonPagedPool, sizeof(DISK_GEOMETRY_EX));
-
- if (deviceExtension->DiskGeometry == NULL) {
-
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto CreateCdRomDeviceObjectExit;
- }
-
- //
- // Set up media change support defaults.
- //
-
- cddata = (PCDROM_DATA)(deviceExtension + 1);
-
- KeInitializeSpinLock(&cddata->FormSpinLock);
- KeInitializeSpinLock(&cddata->TimerIrpSpinLock);
- InitializeListHead(&cddata->TimerIrpList);
-
- cddata->MediaChangeCountDown = MEDIA_CHANGE_DEFAULT_TIME;
- cddata->MediaChangeSupported = FALSE;
- cddata->MediaChange = FALSE;
-
- //
- // Assume that there is initially no media in the device
- // only notify upper layers if there is something there
- //
-
- deviceExtension->MediaChangeNoMedia = TRUE;
- cddata->MediaChangeIrp = NULL;
-#if DBG
- cddata->MediaChangeIrpTimeInUse = 0;
- cddata->MediaChangeIrpLost = FALSE;
-#endif
-
- //
- // Scan for Scsi controllers that require special processing.
- //
-
- ScanForSpecial(deviceObject,
- (PINQUIRYDATA) LunInfo->InquiryData,
- PortCapabilities);
-
- //
- // Do READ CAPACITY. This SCSI command
- // returns the last sector address on the device
- // and the bytes per sector.
- // These are used to calculate the drive capacity
- // in bytes.
- //
-
- status = ScsiClassReadDriveCapacity(deviceObject);
- bps = deviceExtension->DiskGeometry->Geometry.BytesPerSector;
-
- if (!NT_SUCCESS(status) || !bps) {
-
- DebugPrint((1,
- "CreateCdRomDeviceObjects: Can't read capacity for device
%s\n",
- ntNameBuffer));
-
- //
- // Set disk geometry to default values (per ISO 9660).
- //
-
- bps = 2048;
- deviceExtension->SectorShift = 11;
- deviceExtension->PartitionLength.QuadPart = (LONGLONG)(0x7fffffff);
- } else {
-
- //
- // Insure that bytes per sector is a power of 2
- // This corrects a problem with the HP 4020i CDR where it
- // returns an incorrect number for bytes per sector.
- //
-
- lastBit = (ULONG) -1;
- while (bps) {
- lastBit++;
- bps = bps >> 1;
- }
-
- bps = 1 << lastBit;
- }
- deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
- DebugPrint((2, "CreateCdRomDeviceObject: Calc'd bps = %x\n", bps));
-
- //
- // Check to see if this is some sort of changer device
- //
-
- changerDevice = FALSE;
-
- //
- // Search for devices that have special requirements for media
- // change support.
- //
-
- if (deviceExtension->Lun > 0) {
- changerDevice = TRUE;
- }
-
- if (!changerDevice) {
- changerDevice = IsThisASanyo(deviceObject, deviceExtension->PathId,
- deviceExtension->TargetId);
- }
-
- if (!changerDevice) {
- ULONG tmp;
- changerDevice = IsThisAnAtapiChanger(deviceObject, &tmp);
- }
-
- if (!changerDevice) {
- changerDevice = IsThisAMultiLunDevice(deviceObject, PortDeviceObject);
- }
-
- //
- // If it is a changer device, increment the timeout to take platter-swapping
- // time into account
- //
-
- if(changerDevice) {
- deviceExtension->TimeOutValue += SCSI_CHANGER_BONUS_TIMEOUT;
- }
-
- //
- // Create the media change named event. If this succeeds then continue
- // initializing the media change support data items.
- //
-
- CdRomCreateNamedEvent(deviceExtension,*DeviceCount);
- if (deviceExtension->MediaChangeEvent) {
-
- //
- // If this is not a changer, get an IRP for the timer request
- // and initialize the timer.
- //
-
- if (!changerDevice) {
-
- //
- // Not a changer device - continue with media change initialization.
- // Determine if the user actually wants media change events.
- //
-
- if (CdRomCheckRegistryForMediaChangeValue(RegistryPath, *DeviceCount)) {
- PIO_STACK_LOCATION irpStack;
- PSCSI_REQUEST_BLOCK srb;
- PIRP irp;
-
- //
- // User wants it - preallocate IRP and SRB.
- //
-
- irp = IoAllocateIrp((CCHAR)(deviceObject->StackSize+1),
- FALSE);
- if (irp) {
- PVOID buffer;
-
- srb = ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK));
- buffer = ExAllocatePool(NonPagedPoolCacheAligned,
SENSE_BUFFER_SIZE);
-
- if (srb && buffer) {
- PCDB cdb;
-
- //
- // All resources have been allocated set up the IRP.
- //
-
- IoSetNextIrpStackLocation(irp);
- irpStack = IoGetCurrentIrpStackLocation(irp);
- irpStack->DeviceObject = deviceObject;
- irpStack = IoGetNextIrpStackLocation(irp);
- cddata->MediaChangeIrp = irp;
- irpStack->Parameters.Scsi.Srb = srb;
-
- //
- // Initialize the SRB
- //
-
- RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
-
- srb->CdbLength = 6;
- srb->TimeOutValue = deviceExtension->TimeOutValue * 2;
- srb->QueueTag = SP_UNTAGGED;
- srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
- srb->Length = SCSI_REQUEST_BLOCK_SIZE;
- srb->PathId = deviceExtension->PathId;
- srb->TargetId = deviceExtension->TargetId;
- srb->Lun = deviceExtension->Lun;
- srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
-
- //
- // Initialize and set up the sense information buffer
- //
-
- RtlZeroMemory(buffer, SENSE_BUFFER_SIZE);
- srb->SenseInfoBuffer = buffer;
- srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
-
- //
- // Initialize the CDB
- //
-
- cdb = (PCDB)&srb->Cdb[0];
- cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
- cdb->CDB6GENERIC.LogicalUnitNumber = deviceExtension->Lun;
-
- //
- // It is ok to support media change events on this device.
- //
-
- cddata->MediaChangeSupported = TRUE;
- cddata->MediaChange = TRUE;
-
- } else {
-
- if (srb) {
- ExFreePool(srb);
- }
- if (buffer) {
- ExFreePool(buffer);
- }
- IoFreeIrp(irp);
- }
- }
- } else {
- deviceExtension->MediaChangeEvent = NULL;
- }
- } else {
- deviceExtension->MediaChangeEvent = NULL;
- }
- }
-
- //
- // Assume use of 6-byte mode sense/select for now.
- //
-
- cddata->XAFlags |= XA_USE_6_BYTE;
-
- //
- // Build and issue mode sense with Read error recovery page. This will be used to
change
- // block size in case of any raw reads (Mode 2, Form 2).
- //
-
- length = (sizeof(MODE_READ_RECOVERY_PAGE) + MODE_BLOCK_DESC_LENGTH +
MODE_HEADER_LENGTH);
-
- RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
-
- srb.CdbLength = 6;
- cdb = (PCDB)srb.Cdb;
-
- //
- // Set timeout value from device extension.
- //
-
- srb.TimeOutValue = deviceExtension->TimeOutValue;
-
- //
- // Build the MODE SENSE CDB. The data returned will be kept in the device extension
- // and used to set block size.
- //
-
- cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
- cdb->MODE_SENSE.PageCode = 0x1;
- cdb->MODE_SENSE.AllocationLength = (UCHAR)length;
-
- buffer = ExAllocatePool(NonPagedPoolCacheAligned, (sizeof(MODE_READ_RECOVERY_PAGE) +
MODE_BLOCK_DESC_LENGTH + MODE_HEADER_LENGTH10));
- if (!buffer) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto CreateCdRomDeviceObjectExit;
- }
-
- status = ScsiClassSendSrbSynchronous(deviceObject,
- &srb,
- buffer,
- length,
- FALSE);
- if (!NT_SUCCESS(status)) {
-
- //
- // May be Atapi, try 10-byte.
- //
-
- length = (sizeof(MODE_READ_RECOVERY_PAGE) + MODE_BLOCK_DESC_LENGTH +
MODE_HEADER_LENGTH10);
-
- RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
-
- //
- // Build the MODE SENSE CDB.
- //
-
- srb.CdbLength = 10;
- cdb = (PCDB)srb.Cdb;
-
- //
- // Set timeout value from device extension.
- //
-
- srb.TimeOutValue = deviceExtension->TimeOutValue;
-
- cdb->MODE_SENSE10.OperationCode = SCSIOP_MODE_SENSE10;
- cdb->MODE_SENSE10.PageCode = 0x1;
-
- cdb->MODE_SENSE10.AllocationLength[0] = (UCHAR)(length >> 8);
- cdb->MODE_SENSE10.AllocationLength[1] = (UCHAR)(length & 0xFF);
-
- status = ScsiClassSendSrbSynchronous(deviceObject,
- &srb,
- buffer,
- length,
- FALSE);
- if (status == STATUS_DATA_OVERRUN) {
-
- //
- // Build and issue the ReadCd command to ensure that this device supports
it.
- //
-
- RtlZeroMemory(cdb, 12);
-
- cdb->READ_CD.OperationCode = SCSIOP_READ_CD;
-
- status = ScsiClassSendSrbSynchronous(deviceObject,
- &srb,
- NULL,
- 0,
- FALSE);
-
- //
- // If the command wasn't rejected then support the READ_CD.
- //
-
- if (NT_SUCCESS(status) || (status == STATUS_NO_MEDIA_IN_DEVICE)) {
-
- //
- // Using Read CD precludes issuing a mode select to
- // set the user data size. So, no buffer copy is
- // necessary.
- //
-
- cddata->XAFlags &= ~XA_USE_6_BYTE;
- cddata->XAFlags |= XA_USE_READ_CD | XA_USE_10_BYTE;
- } else {
-
- RtlCopyMemory(&cddata->u1.Header, buffer,
sizeof(ERROR_RECOVERY_DATA10));
- cddata->u1.Header.ModeDataLength = 0;
-
- cddata->XAFlags &= ~XA_USE_6_BYTE;
- cddata->XAFlags |= XA_USE_10_BYTE;
- }
-
- } else if (NT_SUCCESS(status)) {
-
- RtlCopyMemory(&cddata->u1.Header, buffer,
sizeof(ERROR_RECOVERY_DATA10));
- cddata->u1.Header.ModeDataLength = 0;
-
- cddata->XAFlags &= ~XA_USE_6_BYTE;
- cddata->XAFlags |= XA_USE_10_BYTE;
-
- } else {
- cddata->XAFlags |= XA_NOT_SUPPORTED;
- }
- } else {
- RtlCopyMemory(&cddata->u1.Header, buffer, sizeof(ERROR_RECOVERY_DATA));
- cddata->u1.Header.ModeDataLength = 0;
- }
-
- ExFreePool(buffer);
-
- ReportToMountMgr(deviceObject);
-
- //
- // Start the timer now regardless of if Autorun is enabled.
- // The timer must run forever since IoStopTimer faults.
- //
-
- IoInitializeTimer(deviceObject, CdRomTickHandler, NULL);
- IoStartTimer(deviceObject);
-
- return(STATUS_SUCCESS);
-
-CreateCdRomDeviceObjectExit:
-
- //
- // Release the device since an error occured.
- //
-
- ScsiClassClaimDevice(PortDeviceObject,
- LunInfo,
- TRUE,
- NULL);
-
- if (senseData != NULL) {
- ExFreePool(senseData);
- }
-
- if (deviceExtension->DiskGeometry != NULL) {
- ExFreePool(deviceExtension->DiskGeometry);
- }
-
- if (deviceObject != NULL) {
- if (srbListInitialized) {
- ExDeleteNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
- }
- IoDeleteDevice(deviceObject);
- }
-
-
- return status;
-
-} // end CreateCdRomDeviceObject()
-
-VOID
-NTAPI
-ScsiCdRomStartIo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
-
- PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
- PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
- PIO_STACK_LOCATION irpStack;
- PIRP irp2 = NULL;
- ULONG transferPages;
- ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
- ULONG maximumTransferLength =
deviceExtension->PortCapabilities->MaximumTransferLength;
- PCDROM_DATA cdData;
- PSCSI_REQUEST_BLOCK srb = NULL;
- PCDB cdb;
- PUCHAR senseBuffer = NULL;
- PVOID dataBuffer;
- NTSTATUS status;
- BOOLEAN use6Byte;
-
- //
- // Mark IRP with status pending.
- //
-
- IoMarkIrpPending(Irp);
-
- //
- // If the flag is set in the device object, force a verify.
- //
-
- if (DeviceObject->Flags & DO_VERIFY_VOLUME) {
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] Volume needs verified\n",
Irp));
- if (!(currentIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME)) {
-
- if (Irp->Tail.Overlay.Thread) {
- IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
- }
-
- Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
-
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] Calling UpdateCapacity - "
- "ioctl event = %lx\n",
- Irp,
- nextIrpStack->Parameters.Others.Argument1
- ));
-
- //
- // our device control dispatch routine stores an event in the next
- // stack location to signal when startio has completed. We need to
- // pass this in so that the update capacity completion routine can
- // set it rather than completing the Irp.
- //
-
- status = CdRomUpdateCapacity(deviceExtension,
- Irp,
- nextIrpStack->Parameters.Others.Argument1
- );
-
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] UpdateCapacity returned
%lx\n", Irp, status));
- ASSERT(status == STATUS_PENDING);
- return;
- }
- }
-
- cdData = (PCDROM_DATA)(deviceExtension + 1);
- use6Byte = cdData->XAFlags & XA_USE_6_BYTE;
-
- if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
-
- //
- // Add partition byte offset to make starting byte relative to
- // beginning of disk. In addition, add in skew for DM Driver, if any.
- //
-
- currentIrpStack->Parameters.Read.ByteOffset.QuadPart +=
(deviceExtension->StartingOffset.QuadPart);
-
- //
- // Calculate number of pages in this transfer.
- //
-
- transferPages =
ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
-
currentIrpStack->Parameters.Read.Length);
-
- //
- // Check if request length is greater than the maximum number of
- // bytes that the hardware can transfer.
- //
-
- if (cdData->RawAccess) {
-
- ASSERT(!(cdData->XAFlags & XA_USE_READ_CD));
-
- //
- // Fire off a mode select to switch back to cooked sectors.
- //
-
- irp2 =
IoAllocateIrp((CCHAR)(deviceExtension->DeviceObject->StackSize+1),
- FALSE);
-
- if (!irp2) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- srb = ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK));
- if (!srb) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
-
- cdb = (PCDB)srb->Cdb;
-
- //
- // Allocate sense buffer.
- //
-
- senseBuffer = ExAllocatePool(NonPagedPoolCacheAligned, SENSE_BUFFER_SIZE);
-
- if (!senseBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- //
- // Set up the irp.
- //
-
- IoSetNextIrpStackLocation(irp2);
- irp2->IoStatus.Status = STATUS_SUCCESS;
- irp2->IoStatus.Information = 0;
- irp2->Flags = 0;
- irp2->UserBuffer = NULL;
-
- //
- // Save the device object and irp in a private stack location.
- //
-
- irpStack = IoGetCurrentIrpStackLocation(irp2);
- irpStack->DeviceObject = deviceExtension->DeviceObject;
- irpStack->Parameters.Others.Argument2 = (PVOID) Irp;
-
- //
- // The retry count will be in the real Irp, as the retry logic will
- // recreate our private irp.
- //
-
- if (!(nextIrpStack->Parameters.Others.Argument1)) {
-
- //
- // Only jam this in if it doesn't exist. The completion routines can
- // call StartIo directly in the case of retries and resetting it will
- // cause infinite loops.
- //
-
- nextIrpStack->Parameters.Others.Argument1 = (PVOID) MAXIMUM_RETRIES;
- }
-
- //
- // Construct the IRP stack for the lower level driver.
- //
-
- irpStack = IoGetNextIrpStackLocation(irp2);
- irpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- irpStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_SCSI_EXECUTE_IN;
- irpStack->Parameters.Scsi.Srb = srb;
-
- srb->Length = SCSI_REQUEST_BLOCK_SIZE;
- srb->PathId = deviceExtension->PathId;
- srb->TargetId = deviceExtension->TargetId;
- srb->Lun = deviceExtension->Lun;
- srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
- srb->Cdb[1] |= deviceExtension->Lun << 5;
- srb->SrbStatus = srb->ScsiStatus = 0;
- srb->NextSrb = 0;
- srb->OriginalRequest = irp2;
- srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
- srb->SenseInfoBuffer = senseBuffer;
-
- transferByteCount = (use6Byte) ? sizeof(ERROR_RECOVERY_DATA) :
sizeof(ERROR_RECOVERY_DATA10);
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned, transferByteCount );
- if (!dataBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
-
- }
-
- irp2->MdlAddress = IoAllocateMdl(dataBuffer,
- transferByteCount,
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!irp2->MdlAddress) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- //
- // Prepare the MDL
- //
-
- MmBuildMdlForNonPagedPool(irp2->MdlAddress);
-
- srb->DataBuffer = dataBuffer;
-
- //
- // Set the new block size in the descriptor.
- //
-
- cdData->u1.BlockDescriptor.BlockLength[0] = (UCHAR)(COOKED_SECTOR_SIZE
>> 16) & 0xFF;
- cdData->u1.BlockDescriptor.BlockLength[1] = (UCHAR)(COOKED_SECTOR_SIZE
>> 8) & 0xFF;
- cdData->u1.BlockDescriptor.BlockLength[2] = (UCHAR)(COOKED_SECTOR_SIZE
& 0xFF);
-
- //
- // Move error page into dataBuffer.
- //
-
- RtlCopyMemory(srb->DataBuffer, &cdData->u1.Header,
transferByteCount);
-
- //
- // Build and send a mode select to switch into raw mode.
- //
-
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_OUT);
- srb->DataTransferLength = transferByteCount;
- srb->TimeOutValue = deviceExtension->TimeOutValue * 2;
-
- if (use6Byte) {
- srb->CdbLength = 6;
- cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
- cdb->MODE_SELECT.PFBit = 1;
- cdb->MODE_SELECT.ParameterListLength = (UCHAR)transferByteCount;
- } else {
-
- srb->CdbLength = 10;
- cdb->MODE_SELECT10.OperationCode = SCSIOP_MODE_SELECT10;
- cdb->MODE_SELECT10.PFBit = 1;
- cdb->MODE_SELECT10.ParameterListLength[0] = (UCHAR)(transferByteCount
>> 8);
- cdb->MODE_SELECT10.ParameterListLength[1] = (UCHAR)(transferByteCount
& 0xFF);
- }
-
- //
- // Update completion routine.
- //
-
- IoSetCompletionRoutine(irp2,
- CdRomSwitchModeCompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
- }
-
- if ((currentIrpStack->Parameters.Read.Length > maximumTransferLength) ||
- (transferPages >
- deviceExtension->PortCapabilities->MaximumPhysicalPages)) {
-
- //
- // Request needs to be split. Completion of each portion of the
- // request will fire off the next portion. The final request will
- // signal Io to send a new request.
- //
-
- transferPages =
- deviceExtension->PortCapabilities->MaximumPhysicalPages - 1;
-
- if(maximumTransferLength > transferPages << PAGE_SHIFT) {
- maximumTransferLength = transferPages << PAGE_SHIFT;
- }
-
- //
- // Check that the maximum transfer size is not zero
- //
-
- if(maximumTransferLength == 0) {
- maximumTransferLength = PAGE_SIZE;
- }
-
- ScsiClassSplitRequest(DeviceObject, Irp, maximumTransferLength);
- return;
-
- } else {
-
- //
- // Build SRB and CDB for this IRP.
- //
-
- ScsiClassBuildRequest(DeviceObject, Irp);
-
- }
-
-
- } else if (currentIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
-
- //
- // Allocate an irp, srb and associated structures.
- //
-
- irp2 = IoAllocateIrp((CCHAR)(deviceExtension->DeviceObject->StackSize+1),
- FALSE);
-
- if (!irp2) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- IoStartNextPacket(DeviceObject, FALSE);
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] bailing with status %lx at line
%s\n", Irp, Irp->IoStatus.Status, __LINE__));
- return;
- }
-
- srb = ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK));
- if (!srb) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] bailing with status %lx at line
%s\n", Irp, Irp->IoStatus.Status, __LINE__));
- return;
- }
-
- RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
-
- cdb = (PCDB)srb->Cdb;
-
- //
- // Allocate sense buffer.
- //
-
- senseBuffer = ExAllocatePool(NonPagedPoolCacheAligned, SENSE_BUFFER_SIZE);
-
- if (!senseBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] bailing with status %lx at line
%s\n", Irp, Irp->IoStatus.Status, __LINE__));
- return;
- }
-
- //
- // Set up the irp.
- //
-
- IoSetNextIrpStackLocation(irp2);
- irp2->IoStatus.Status = STATUS_SUCCESS;
- irp2->IoStatus.Information = 0;
- irp2->Flags = 0;
- irp2->UserBuffer = NULL;
-
- //
- // Save the device object and irp in a private stack location.
- //
-
- irpStack = IoGetCurrentIrpStackLocation(irp2);
- irpStack->DeviceObject = deviceExtension->DeviceObject;
- irpStack->Parameters.Others.Argument2 = (PVOID) Irp;
-
- //
- // The retry count will be in the real Irp, as the retry logic will
- // recreate our private irp.
- //
-
- if (!(nextIrpStack->Parameters.Others.Argument1)) {
-
- //
- // Only jam this in if it doesn't exist. The completion routines can
- // call StartIo directly in the case of retries and resetting it will
- // cause infinite loops.
- //
-
- nextIrpStack->Parameters.Others.Argument1 = (PVOID) MAXIMUM_RETRIES;
- }
-
- //
- // Construct the IRP stack for the lower level driver.
- //
-
- irpStack = IoGetNextIrpStackLocation(irp2);
- irpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
- irpStack->Parameters.Scsi.Srb = srb;
-
- IoSetCompletionRoutine(irp2,
- CdRomDeviceControlCompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
- //
- // Setup those fields that are generic to all requests.
- //
-
- srb->Length = SCSI_REQUEST_BLOCK_SIZE;
- srb->PathId = deviceExtension->PathId;
- srb->TargetId = deviceExtension->TargetId;
- srb->Lun = deviceExtension->Lun;
- srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
- srb->Cdb[1] |= deviceExtension->Lun << 5;
- srb->SrbStatus = srb->ScsiStatus = 0;
- srb->NextSrb = 0;
- srb->OriginalRequest = irp2;
- srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
- srb->SenseInfoBuffer = senseBuffer;
-
- switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode) {
-
- case IOCTL_CDROM_RAW_READ: {
-
- //
- // Determine whether the drive is currently in raw or cooked mode,
- // and which command to use to read the data.
- //
-
- if (!(cdData->XAFlags & XA_USE_READ_CD)) {
-
- PRAW_READ_INFO rawReadInfo =
-
(PRAW_READ_INFO)currentIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
- ULONG maximumTransferLength;
- ULONG transferPages;
-
- if (cdData->RawAccess) {
-
- ULONG startingSector;
-
- //
- // Free the recently allocated irp, as we don't need it.
- //
-
- IoFreeIrp(irp2);
-
- cdb = (PCDB)srb->Cdb;
- RtlZeroMemory(cdb, 12);
-
- //
- // Calculate starting offset.
- //
-
- startingSector = (ULONG)(rawReadInfo->DiskOffset.QuadPart >>
deviceExtension->SectorShift);
- transferByteCount = rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
- maximumTransferLength =
deviceExtension->PortCapabilities->MaximumTransferLength;
- transferPages =
ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
- transferByteCount);
-
- //
- // Determine if request is within limits imposed by miniport.
- //
-
- if (transferByteCount > maximumTransferLength ||
- transferPages >
deviceExtension->PortCapabilities->MaximumPhysicalPages) {
-
- //
- // The claim is that this won't happen, and is backed up by
- // ActiveMovie usage, which does unbuffered XA reads of 0x18000,
yet
- // we get only 4 sector requests.
- //
-
-
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
-
- }
-
- srb->OriginalRequest = Irp;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_DATA_IN);
- srb->DataTransferLength = transferByteCount;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->CdbLength = 10;
- srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
-
- if (rawReadInfo->TrackMode == CDDA) {
- if (cdData->XAFlags & PLEXTOR_CDDA) {
-
- srb->CdbLength = 12;
-
- cdb->PLXTR_READ_CDDA.LogicalUnitNumber =
deviceExtension->Lun;
- cdb->PLXTR_READ_CDDA.LogicalBlockByte3 = (UCHAR)
(startingSector & 0xFF);
- cdb->PLXTR_READ_CDDA.LogicalBlockByte2 = (UCHAR)
((startingSector >> 8) & 0xFF);
- cdb->PLXTR_READ_CDDA.LogicalBlockByte1 = (UCHAR)
((startingSector >> 16) & 0xFF);
- cdb->PLXTR_READ_CDDA.LogicalBlockByte0 = (UCHAR)
((startingSector >> 24) & 0xFF);
-
- cdb->PLXTR_READ_CDDA.TransferBlockByte3 = (UCHAR)
(rawReadInfo->SectorCount & 0xFF);
- cdb->PLXTR_READ_CDDA.TransferBlockByte2 = (UCHAR)
(rawReadInfo->SectorCount >> 8);
- cdb->PLXTR_READ_CDDA.TransferBlockByte1 = 0;
- cdb->PLXTR_READ_CDDA.TransferBlockByte0 = 0;
-
- cdb->PLXTR_READ_CDDA.SubCode = 0;
- cdb->PLXTR_READ_CDDA.OperationCode = 0xD8;
-
- } else if (cdData->XAFlags & NEC_CDDA) {
-
- cdb->NEC_READ_CDDA.LogicalBlockByte3 = (UCHAR)
(startingSector & 0xFF);
- cdb->NEC_READ_CDDA.LogicalBlockByte2 = (UCHAR)
((startingSector >> 8) & 0xFF);
- cdb->NEC_READ_CDDA.LogicalBlockByte1 = (UCHAR)
((startingSector >> 16) & 0xFF);
- cdb->NEC_READ_CDDA.LogicalBlockByte0 = (UCHAR)
((startingSector >> 24) & 0xFF);
-
- cdb->NEC_READ_CDDA.TransferBlockByte1 = (UCHAR)
(rawReadInfo->SectorCount & 0xFF);
- cdb->NEC_READ_CDDA.TransferBlockByte0 = (UCHAR)
(rawReadInfo->SectorCount >> 8);
-
- cdb->NEC_READ_CDDA.OperationCode = 0xD4;
- }
- } else {
-
- cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
-
- cdb->CDB10.TransferBlocksMsb = (UCHAR)
(rawReadInfo->SectorCount >> 8);
- cdb->CDB10.TransferBlocksLsb = (UCHAR)
(rawReadInfo->SectorCount & 0xFF);
-
- cdb->CDB10.LogicalBlockByte3 = (UCHAR) (startingSector &
0xFF);
- cdb->CDB10.LogicalBlockByte2 = (UCHAR) ((startingSector
>> 8) & 0xFF);
- cdb->CDB10.LogicalBlockByte1 = (UCHAR) ((startingSector
>> 16) & 0xFF);
- cdb->CDB10.LogicalBlockByte0 = (UCHAR) ((startingSector
>> 24) & 0xFF);
-
- cdb->CDB10.OperationCode = SCSIOP_READ;
- }
-
- srb->SrbStatus = srb->ScsiStatus = 0;
-
- nextIrpStack->MajorFunction = IRP_MJ_SCSI;
- nextIrpStack->Parameters.Scsi.Srb = srb;
-
- if (!(nextIrpStack->Parameters.Others.Argument1)) {
-
- //
- // Only jam this in if it doesn't exist. The completion
routines can
- // call StartIo directly in the case of retries and resetting it
will
- // cause infinite loops.
- //
-
- nextIrpStack->Parameters.Others.Argument1 = (PVOID)
MAXIMUM_RETRIES;
- }
-
- //
- // Set up IoCompletion routine address.
- //
-
- IoSetCompletionRoutine(Irp,
- CdRomXACompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
-
- IoCallDriver(deviceExtension->PortDeviceObject, Irp);
- return;
-
- } else {
-
- transferByteCount = (use6Byte) ? sizeof(ERROR_RECOVERY_DATA) :
sizeof(ERROR_RECOVERY_DATA10);
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
transferByteCount );
- if (!dataBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
-
- }
-
- irp2->MdlAddress = IoAllocateMdl(dataBuffer,
- transferByteCount,
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!irp2->MdlAddress) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- //
- // Prepare the MDL
- //
-
- MmBuildMdlForNonPagedPool(irp2->MdlAddress);
-
- srb->DataBuffer = dataBuffer;
-
- //
- // Set the new block size in the descriptor.
- //
-
- cdData->u1.BlockDescriptor.BlockLength[0] =
(UCHAR)(RAW_SECTOR_SIZE >> 16) & 0xFF;
- cdData->u1.BlockDescriptor.BlockLength[1] =
(UCHAR)(RAW_SECTOR_SIZE >> 8) & 0xFF;
- cdData->u1.BlockDescriptor.BlockLength[2] =
(UCHAR)(RAW_SECTOR_SIZE & 0xFF);
-
-
- //
- // TODO: Set density code, based on operation
- //
-
- cdData->u1.BlockDescriptor.DensityCode = 0;
-
-
- //
- // Move error page into dataBuffer.
- //
-
- RtlCopyMemory(srb->DataBuffer, &cdData->u1.Header,
transferByteCount);
-
-
- //
- // Build and send a mode select to switch into raw mode.
- //
-
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_DATA_OUT);
- srb->DataTransferLength = transferByteCount;
- srb->TimeOutValue = deviceExtension->TimeOutValue * 2;
-
- if (use6Byte) {
- srb->CdbLength = 6;
- cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
- cdb->MODE_SELECT.PFBit = 1;
- cdb->MODE_SELECT.ParameterListLength =
(UCHAR)transferByteCount;
- } else {
-
- srb->CdbLength = 10;
- cdb->MODE_SELECT10.OperationCode = SCSIOP_MODE_SELECT10;
- cdb->MODE_SELECT10.PFBit = 1;
- cdb->MODE_SELECT10.ParameterListLength[0] =
(UCHAR)(transferByteCount >> 8);
- cdb->MODE_SELECT10.ParameterListLength[1] =
(UCHAR)(transferByteCount & 0xFF);
- }
-
- //
- // Update completion routine.
- //
-
- IoSetCompletionRoutine(irp2,
- CdRomSwitchModeCompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
-
- }
-
- } else {
-
- PRAW_READ_INFO rawReadInfo =
-
(PRAW_READ_INFO)currentIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
- ULONG startingSector;
-
- //
- // Free the recently allocated irp, as we don't need it.
- //
-
- IoFreeIrp(irp2);
-
- cdb = (PCDB)srb->Cdb;
- RtlZeroMemory(cdb, 12);
-
-
- //
- // Calculate starting offset.
- //
-
- startingSector = (ULONG)(rawReadInfo->DiskOffset.QuadPart >>
deviceExtension->SectorShift);
- transferByteCount = rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
-
-
- srb->OriginalRequest = Irp;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_DATA_IN);
- srb->DataTransferLength = transferByteCount;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
- srb->CdbLength = 12;
- srb->SrbStatus = srb->ScsiStatus = 0;
-
- //
- // Fill in CDB fields.
- //
-
- cdb = (PCDB)srb->Cdb;
-
-
- cdb->READ_CD.TransferBlocks[2] = (UCHAR) (rawReadInfo->SectorCount
& 0xFF);
- cdb->READ_CD.TransferBlocks[1] = (UCHAR) (rawReadInfo->SectorCount
>> 8 );
- cdb->READ_CD.TransferBlocks[0] = (UCHAR) (rawReadInfo->SectorCount
>> 16);
-
-
- cdb->READ_CD.StartingLBA[3] = (UCHAR) (startingSector & 0xFF);
- cdb->READ_CD.StartingLBA[2] = (UCHAR) ((startingSector >>
8));
- cdb->READ_CD.StartingLBA[1] = (UCHAR) ((startingSector >>
16));
- cdb->READ_CD.StartingLBA[0] = (UCHAR) ((startingSector >>
24));
-
- //
- // Setup cdb depending upon the sector type we want.
- //
-
- switch (rawReadInfo->TrackMode) {
- case CDDA:
-
- cdb->READ_CD.ExpectedSectorType = CD_DA_SECTOR;
- cdb->READ_CD.IncludeUserData = 1;
- cdb->READ_CD.HeaderCode = 3;
- cdb->READ_CD.IncludeSyncData = 1;
- break;
-
- case YellowMode2:
-
- cdb->READ_CD.ExpectedSectorType = YELLOW_MODE2_SECTOR;
- cdb->READ_CD.IncludeUserData = 1;
- cdb->READ_CD.HeaderCode = 1;
- cdb->READ_CD.IncludeSyncData = 1;
- break;
-
- case XAForm2:
-
- cdb->READ_CD.ExpectedSectorType = FORM2_MODE2_SECTOR;
- cdb->READ_CD.IncludeUserData = 1;
- cdb->READ_CD.HeaderCode = 3;
- cdb->READ_CD.IncludeSyncData = 1;
- break;
-
- default:
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoStartNextPacket(DeviceObject, FALSE);
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] bailing with status %lx
at line %s\n", Irp, Irp->IoStatus.Status, __LINE__));
- return;
- }
-
- cdb->READ_CD.OperationCode = SCSIOP_READ_CD;
-
- nextIrpStack->MajorFunction = IRP_MJ_SCSI;
- nextIrpStack->Parameters.Scsi.Srb = srb;
-
- if (!(nextIrpStack->Parameters.Others.Argument1)) {
-
- //
- // Only jam this in if it doesn't exist. The completion routines
can
- // call StartIo directly in the case of retries and resetting it
will
- // cause infinite loops.
- //
-
- nextIrpStack->Parameters.Others.Argument1 = (PVOID)
MAXIMUM_RETRIES;
- }
-
- //
- // Set up IoCompletion routine address.
- //
-
- IoSetCompletionRoutine(Irp,
- CdRomXACompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
-
- IoCallDriver(deviceExtension->PortDeviceObject, Irp);
- return;
-
- }
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
- }
-
- case IOCTL_DISK_GET_LENGTH_INFO:
- case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX:
- case IOCTL_DISK_GET_DRIVE_GEOMETRY:
- case IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX:
- case IOCTL_CDROM_GET_DRIVE_GEOMETRY: {
-
- //
- // Issue ReadCapacity to update device extension
- // with information for current media.
- //
-
- DebugPrint((3,
- "CdRomStartIo: Get drive capacity\n"));
-
- //
- // setup remaining srb and cdb parameters.
- //
-
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_IN);
- srb->DataTransferLength = sizeof(READ_CAPACITY_DATA);
- srb->CdbLength = 10;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
-
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
sizeof(READ_CAPACITY_DATA));
- if (!dataBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] bailing with status %lx at
line %s\n", Irp, Irp->IoStatus.Status, __LINE__));
- return;
-
- }
-
- irp2->MdlAddress = IoAllocateMdl(dataBuffer,
- sizeof(READ_CAPACITY_DATA),
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!irp2->MdlAddress) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] bailing with status %lx at
line %s\n", Irp, Irp->IoStatus.Status, __LINE__));
- return;
- }
-
- //
- // Prepare the MDL
- //
-
- MmBuildMdlForNonPagedPool(irp2->MdlAddress);
-
- srb->DataBuffer = dataBuffer;
- cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
- }
-
- case IOCTL_CDROM_CHECK_VERIFY: {
-
- //
- // Since a test unit ready is about to be performed, reset the timer
- // value to decrease the opportunities for it to race with this code.
- //
-
- cdData->MediaChangeCountDown = MEDIA_CHANGE_DEFAULT_TIME;
-
- //
- // Set up the SRB/CDB
- //
-
- srb->CdbLength = 6;
- cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
- srb->TimeOutValue = deviceExtension->TimeOutValue * 2;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_NO_DATA_TRANSFER);
-
- DebugPrint((2, "ScsiCdRomStartIo: [%lx] Sending CHECK_VERIFY irp
%lx\n", Irp, irp2));
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
- }
-
- case IOCTL_CDROM_GET_LAST_SESSION:
-
- //
- // Set format to return first and last session numbers.
- //
-
- cdb->READ_TOC.Format = GET_LAST_SESSION;
-
- //
- // Fall through to READ TOC code.
- //
-
- case IOCTL_CDROM_READ_TOC: {
-
-
- if (currentIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_READ_TOC) {
-
- //
- // Use MSF addressing if not request for session information.
- //
-
- cdb->READ_TOC.Msf = CDB_USE_MSF;
- }
-
- //
- // Set size of TOC structure.
- //
-
- transferByteCount =
- currentIrpStack->Parameters.Read.Length >
- sizeof(CDROM_TOC) ? sizeof(CDROM_TOC):
- currentIrpStack->Parameters.Read.Length;
-
- cdb->READ_TOC.AllocationLength[0] = (UCHAR) (transferByteCount >>
8);
- cdb->READ_TOC.AllocationLength[1] = (UCHAR) (transferByteCount &
0xFF);
-
- cdb->READ_TOC.Control = 0;
-
- //
- // Start at beginning of disc.
- //
-
- cdb->READ_TOC.StartingTrack = 0;
-
- //
- // setup remaining srb and cdb parameters.
- //
-
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_IN);
- srb->DataTransferLength = transferByteCount;
- srb->CdbLength = 10;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
-
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned, transferByteCount);
- if (!dataBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
-
- }
-
- irp2->MdlAddress = IoAllocateMdl(dataBuffer,
- transferByteCount,
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!irp2->MdlAddress) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- //
- // Prepare the MDL
- //
-
- MmBuildMdlForNonPagedPool(irp2->MdlAddress);
-
- srb->DataBuffer = dataBuffer;
- cdb->READ_TOC.OperationCode = SCSIOP_READ_TOC;
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
-
- }
-
- case IOCTL_CDROM_PLAY_AUDIO_MSF: {
-
- PCDROM_PLAY_AUDIO_MSF inputBuffer = Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Set up the SRB/CDB
- //
-
- srb->CdbLength = 10;
- cdb->PLAY_AUDIO_MSF.OperationCode = SCSIOP_PLAY_AUDIO_MSF;
-
- cdb->PLAY_AUDIO_MSF.StartingM = inputBuffer->StartingM;
- cdb->PLAY_AUDIO_MSF.StartingS = inputBuffer->StartingS;
- cdb->PLAY_AUDIO_MSF.StartingF = inputBuffer->StartingF;
-
- cdb->PLAY_AUDIO_MSF.EndingM = inputBuffer->EndingM;
- cdb->PLAY_AUDIO_MSF.EndingS = inputBuffer->EndingS;
- cdb->PLAY_AUDIO_MSF.EndingF = inputBuffer->EndingF;
-
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_NO_DATA_TRANSFER);
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
-
- }
-
- case IOCTL_CDROM_READ_Q_CHANNEL: {
-
- PCDROM_SUB_Q_DATA_FORMAT inputBuffer =
- Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Allocate buffer for subq channel information.
- //
-
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
- sizeof(SUB_Q_CHANNEL_DATA));
-
- if (!dataBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
-
- }
-
- irp2->MdlAddress = IoAllocateMdl(dataBuffer,
- transferByteCount,
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!irp2->MdlAddress) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- //
- // Prepare the MDL
- //
-
- MmBuildMdlForNonPagedPool(irp2->MdlAddress);
-
- srb->DataBuffer = dataBuffer;
-
- //
- // Always logical unit 0, but only use MSF addressing
- // for IOCTL_CDROM_CURRENT_POSITION
- //
-
- if (inputBuffer->Format==IOCTL_CDROM_CURRENT_POSITION)
- cdb->SUBCHANNEL.Msf = CDB_USE_MSF;
-
- //
- // Return subchannel data
- //
-
- cdb->SUBCHANNEL.SubQ = CDB_SUBCHANNEL_BLOCK;
-
- //
- // Specify format of information to return
- //
-
- cdb->SUBCHANNEL.Format = inputBuffer->Format;
-
- //
- // Specify which track to access (only used by Track ISRC reads)
- //
-
- if (inputBuffer->Format==IOCTL_CDROM_TRACK_ISRC) {
- cdb->SUBCHANNEL.TrackNumber = inputBuffer->Track;
- }
-
- //
- // Set size of channel data -- however, this is dependent on
- // what information we are requesting (which Format)
- //
-
- switch( inputBuffer->Format ) {
-
- case IOCTL_CDROM_CURRENT_POSITION:
- transferByteCount = sizeof(SUB_Q_CURRENT_POSITION);
- break;
-
- case IOCTL_CDROM_MEDIA_CATALOG:
- transferByteCount = sizeof(SUB_Q_MEDIA_CATALOG_NUMBER);
- break;
-
- case IOCTL_CDROM_TRACK_ISRC:
- transferByteCount = sizeof(SUB_Q_TRACK_ISRC);
- break;
- }
-
- cdb->SUBCHANNEL.AllocationLength[0] = (UCHAR) (transferByteCount >>
8);
- cdb->SUBCHANNEL.AllocationLength[1] = (UCHAR) (transferByteCount &
0xFF);
- cdb->SUBCHANNEL.OperationCode = SCSIOP_READ_SUB_CHANNEL;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_IN);
- srb->DataTransferLength = transferByteCount;
- srb->CdbLength = 10;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
-
- }
-
- case IOCTL_CDROM_PAUSE_AUDIO: {
-
- cdb->PAUSE_RESUME.OperationCode = SCSIOP_PAUSE_RESUME;
- cdb->PAUSE_RESUME.Action = CDB_AUDIO_PAUSE;
-
- srb->CdbLength = 10;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_NO_DATA_TRANSFER);
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
- }
-
- case IOCTL_CDROM_RESUME_AUDIO: {
-
- cdb->PAUSE_RESUME.OperationCode = SCSIOP_PAUSE_RESUME;
- cdb->PAUSE_RESUME.Action = CDB_AUDIO_RESUME;
-
- srb->CdbLength = 10;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_NO_DATA_TRANSFER);
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
- }
-
- case IOCTL_CDROM_SEEK_AUDIO_MSF: {
-
- PCDROM_SEEK_AUDIO_MSF inputBuffer = Irp->AssociatedIrp.SystemBuffer;
- ULONG logicalBlockAddress;
-
- logicalBlockAddress = MSF_TO_LBA(inputBuffer->M, inputBuffer->S,
inputBuffer->F);
-
- cdb->SEEK.OperationCode = SCSIOP_SEEK;
- cdb->SEEK.LogicalBlockAddress[0] =
((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
- cdb->SEEK.LogicalBlockAddress[1] =
((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
- cdb->SEEK.LogicalBlockAddress[2] =
((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
- cdb->SEEK.LogicalBlockAddress[3] =
((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
-
- srb->CdbLength = 10;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_NO_DATA_TRANSFER);
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
-
- }
-
- case IOCTL_CDROM_STOP_AUDIO: {
-
- cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
- cdb->START_STOP.Immediate = 1;
- cdb->START_STOP.Start = 0;
- cdb->START_STOP.LoadEject = 0;
-
- srb->CdbLength = 6;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
-
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
SRB_FLAGS_NO_DATA_TRANSFER);
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
- }
-
- case IOCTL_CDROM_GET_CONTROL: {
- //
- // Allocate buffer for volume control information.
- //
-
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
- MODE_DATA_SIZE);
-
- if (!dataBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
-
- }
-
- irp2->MdlAddress = IoAllocateMdl(dataBuffer,
- MODE_DATA_SIZE,
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!irp2->MdlAddress) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- //
- // Prepare the MDL
- //
-
- MmBuildMdlForNonPagedPool(irp2->MdlAddress);
- srb->DataBuffer = dataBuffer;
-
- RtlZeroMemory(dataBuffer, MODE_DATA_SIZE);
-
- //
- // Setup for either 6 or 10 byte CDBs.
- //
-
- if (use6Byte) {
-
- cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
- cdb->MODE_SENSE.PageCode = CDROM_AUDIO_CONTROL_PAGE;
- cdb->MODE_SENSE.AllocationLength = MODE_DATA_SIZE;
-
- //
- // Disable block descriptors.
- //
-
- cdb->MODE_SENSE.Dbd = TRUE;
-
- srb->CdbLength = 6;
- } else {
-
- cdb->MODE_SENSE10.OperationCode = SCSIOP_MODE_SENSE10;
- cdb->MODE_SENSE10.PageCode = CDROM_AUDIO_CONTROL_PAGE;
- cdb->MODE_SENSE10.AllocationLength[0] = (UCHAR)(MODE_DATA_SIZE
>> 8);
- cdb->MODE_SENSE10.AllocationLength[1] = (UCHAR)(MODE_DATA_SIZE &
0xFF);
-
- //
- // Disable block descriptors.
- //
-
- cdb->MODE_SENSE10.Dbd = TRUE;
-
- srb->CdbLength = 10;
- }
-
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->DataTransferLength = MODE_DATA_SIZE;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_IN);
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
-
- }
-
- case IOCTL_CDROM_GET_VOLUME:
- case IOCTL_CDROM_SET_VOLUME: {
-
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
- MODE_DATA_SIZE);
-
- if (!dataBuffer) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- irp2->MdlAddress = IoAllocateMdl(dataBuffer,
- MODE_DATA_SIZE,
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!irp2->MdlAddress) {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(irp2);
- IoStartNextPacket(DeviceObject, FALSE);
- return;
- }
-
- //
- // Prepare the MDL
- //
-
- MmBuildMdlForNonPagedPool(irp2->MdlAddress);
- srb->DataBuffer = dataBuffer;
-
- RtlZeroMemory(dataBuffer, MODE_DATA_SIZE);
-
-
- if (use6Byte) {
- cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
- cdb->MODE_SENSE.PageCode = CDROM_AUDIO_CONTROL_PAGE;
- cdb->MODE_SENSE.AllocationLength = MODE_DATA_SIZE;
-
- srb->CdbLength = 6;
-
- } else {
-
- cdb->MODE_SENSE10.OperationCode = SCSIOP_MODE_SENSE10;
- cdb->MODE_SENSE10.PageCode = CDROM_AUDIO_CONTROL_PAGE;
- cdb->MODE_SENSE10.AllocationLength[0] = (UCHAR)(MODE_DATA_SIZE
>> 8);
- cdb->MODE_SENSE10.AllocationLength[1] = (UCHAR)(MODE_DATA_SIZE &
0xFF);
-
- srb->CdbLength = 10;
- }
-
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->DataTransferLength = MODE_DATA_SIZE;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_IN);
-
- if (currentIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_SET_VOLUME) {
-
- //
- // Setup a different completion routine as the mode sense data is needed
in order
- // to send the mode select.
- //
-
- IoSetCompletionRoutine(irp2,
- CdRomSetVolumeIntermediateCompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
-
- }
-
- IoCallDriver(deviceExtension->PortDeviceObject, irp2);
- return;
-
- }
-
- default:
-
- //
- // Just complete the request - CdRomClassIoctlCompletion will take
- // care of it for us
- //
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- ExFreePool(senseBuffer);
- ExFreePool(srb);
- IoFreeIrp(irp2);
- return;
-
- } // end switch()
- }
-
- //
- // If a read or an unhandled IRP_MJ_XX, end up here. The unhandled IRP_MJ's
- // are expected and composed of AutoRun Irps, at present.
- //
-
- IoCallDriver(deviceExtension->PortDeviceObject, Irp);
- return;
-}
-
-
-NTSTATUS
-NTAPI
-ScsiCdRomReadVerification(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-
-/*++
-
-Routine Description:
-
- This is the entry called by the I/O system for read requests.
- It builds the SRB and sends it to the port driver.
-
-Arguments:
-
- DeviceObject - the system object for the device.
- Irp - IRP involved.
-
-Return Value:
-
- NT Status
-
---*/
-
-{
- PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
- ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
- LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
-
- //
- // If the cd is playing music then reject this request.
- //
-
- if (PLAY_ACTIVE(deviceExtension)) {
- Irp->IoStatus.Status = STATUS_DEVICE_BUSY;
- return STATUS_DEVICE_BUSY;
- }
-
- //
- // Verify parameters of this request.
- // Check that ending sector is on disc and
- // that number of bytes to transfer is a multiple of
- // the sector size.
- //
-
- startingOffset.QuadPart = currentIrpStack->Parameters.Read.ByteOffset.QuadPart +
- transferByteCount;
-
- if (!deviceExtension->DiskGeometry->Geometry.BytesPerSector) {
- deviceExtension->DiskGeometry->Geometry.BytesPerSector = 2048;
- }
-
- if ((startingOffset.QuadPart > deviceExtension->PartitionLength.QuadPart) ||
- (transferByteCount &
(deviceExtension->DiskGeometry->Geometry.BytesPerSector - 1))) {
-
- DebugPrint((1,"ScsiCdRomRead: Invalid I/O parameters\n"));
- DebugPrint((1, "\toffset %x:%x, Length %x:%x\n",
- startingOffset.u.HighPart,
- startingOffset.u.LowPart,
- deviceExtension->PartitionLength.u.HighPart,
- deviceExtension->PartitionLength.u.LowPart));
- DebugPrint((1, "\tbps %x\n",
deviceExtension->DiskGeometry->Geometry.BytesPerSector));
-
- //
- // Fail request with status of invalid parameters.
- //
-
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
-
- return STATUS_INVALID_PARAMETER;
- }
-
-
- return STATUS_SUCCESS;
-
-} // end ScsiCdRomReadVerification()
-
-
-NTSTATUS
-NTAPI
-CdRomDeviceControlCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
- PDEVICE_EXTENSION physicalExtension =
deviceExtension->PhysicalDevice->DeviceExtension;
- PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
- PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension + 1);
- BOOLEAN use6Byte = cdData->XAFlags & XA_USE_6_BYTE;
- PIO_STACK_LOCATION realIrpStack;
- PIO_STACK_LOCATION realIrpNextStack;
- PSCSI_REQUEST_BLOCK srb = Context;
- PIRP realIrp = NULL;
- NTSTATUS status;
- BOOLEAN retry;
-
- //
- // Extract the 'real' irp from the irpstack.
- //
-
- realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
- realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
- realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
-
- //
- // Check SRB status for success of completing request.
- //
-
- if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
-
- DebugPrint((2,
- "CdRomDeviceControlCompletion: Irp %lx, Srb %lx Real Irp %lx
Status %lx\n",
- Irp,
- srb,
- realIrp,
- srb->SrbStatus));
-
- //
- // Release the queue if it is frozen.
- //
-
- if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
- DebugPrint((2, "CdRomDeviceControlCompletion: Releasing
Queue\n"));
- ScsiClassReleaseQueue(DeviceObject);
- }
-
-
- retry = ScsiClassInterpretSenseInfo(DeviceObject,
- srb,
- irpStack->MajorFunction,
-
irpStack->Parameters.DeviceIoControl.IoControlCode,
- MAXIMUM_RETRIES -
((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
- &status);
-
- DebugPrint((2, "CdRomDeviceControlCompletion: IRP will %sbe
retried\n",
- (retry ? "" : "not ")));
-
- //
- // Some of the Device Controls need special cases on non-Success status's.
- //
-
- if (realIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
- if ((realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_GET_LAST_SESSION) ||
- (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_READ_TOC) ||
- (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_GET_CONTROL) ||
- (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_GET_VOLUME)) {
-
- if (status == STATUS_DATA_OVERRUN) {
- status = STATUS_SUCCESS;
- retry = FALSE;
- }
- }
-
- if (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_READ_Q_CHANNEL) {
- PLAY_ACTIVE(deviceExtension) = FALSE;
- }
- }
-
- //
- // If the status is verified required and the this request
- // should bypass verify required then retry the request.
- //
-
- if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
- status == STATUS_VERIFY_REQUIRED) {
-
- if (((realIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) ||
- (realIrpStack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL))
&&
- (realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_CHECK_VERIFY)) {
-
- ExFreePool(srb->SenseInfoBuffer);
- if (srb->DataBuffer) {
- ExFreePool(srb->DataBuffer);
- }
- ExFreePool(srb);
- if (Irp->MdlAddress) {
- IoFreeMdl(Irp->MdlAddress);
- }
-
- IoFreeIrp(Irp);
-
- //
- // Update the geometry information, as the media could have changed.
- // The completion routine for this will complete the real irp and start
- // the next packet.
- //
-
- status = CdRomUpdateCapacity(deviceExtension,realIrp, NULL);
- DebugPrint((2, "CdRomDeviceControlCompletion: [%lx]
CdRomUpdateCapacity completed with status %lx\n", realIrp, status));
- ASSERT(status == STATUS_PENDING);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- } else {
-
- status = STATUS_IO_DEVICE_ERROR;
- retry = TRUE;
- }
-
- }
-
- if (retry && (realIrpNextStack->Parameters.Others.Argument1 =
(PVOID)((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1-1))) {
-
-
- if (((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
-
- //
- // Retry request.
- //
-
- DebugPrint((1, "Retry request %lx - Calling StartIo\n", Irp));
-
-
- ExFreePool(srb->SenseInfoBuffer);
- if (srb->DataBuffer) {
- ExFreePool(srb->DataBuffer);
- }
- ExFreePool(srb);
- if (Irp->MdlAddress) {
- IoFreeMdl(Irp->MdlAddress);
- }
-
- IoFreeIrp(Irp);
-
- //
- // Call StartIo directly since IoStartNextPacket hasn't been called,
- // the serialisation is still intact.
- //
-
- ScsiCdRomStartIo(DeviceObject, realIrp);
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- }
-
- //
- // Exhausted retries. Fall through and complete the request with the
appropriate status.
- //
-
- }
- } else {
-
- //
- // Set status for successful request.
- //
-
- status = STATUS_SUCCESS;
- }
-
- if (NT_SUCCESS(status)) {
-
- switch (realIrpStack->Parameters.DeviceIoControl.IoControlCode) {
-
- case IOCTL_DISK_GET_LENGTH_INFO: {
-
- PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
- ULONG lastSector;
- ULONG bps;
- ULONG lastBit;
- ULONG tmp;
-
- //
- // Swizzle bytes from Read Capacity and translate into
- // the necessary geometry information in the device extension.
- //
-
- tmp = readCapacityBuffer->BytesPerBlock;
- ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
- ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
- ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
- ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
-
- //
- // Insure that bps is a power of 2.
- // This corrects a problem with the HP 4020i CDR where it
- // returns an incorrect number for bytes per sector.
- //
-
- if (!bps) {
- bps = 2048;
- } else {
- lastBit = (ULONG) -1;
- while (bps) {
- lastBit++;
- bps = bps >> 1;
- }
-
- bps = 1 << lastBit;
- }
- deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
-
- DebugPrint((2,
- "CdRomDeviceControlCompletion: Calculated bps %#x\n",
- deviceExtension->DiskGeometry->Geometry.BytesPerSector));
-
- //
- // Copy last sector in reverse byte order.
- //
-
- tmp = readCapacityBuffer->LogicalBlockAddress;
- ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
- ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
- ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
- ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
-
- //
- // Calculate sector to byte shift.
- //
-
- WHICH_BIT(bps, deviceExtension->SectorShift);
-
- DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is
%d\n",
- deviceExtension->DiskGeometry->Geometry.BytesPerSector));
-
- DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is
%d\n",
- lastSector + 1));
-
- //
- // Calculate media capacity in bytes.
- //
-
- deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
-
- //
- // Calculate number of cylinders.
- //
-
- deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart =
(LONGLONG)((lastSector + 1)/(32 * 64));
-
- deviceExtension->PartitionLength.QuadPart =
- (deviceExtension->PartitionLength.QuadPart <<
deviceExtension->SectorShift);
-
- if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
-
- //
- // This device supports removable media.
- //
-
- deviceExtension->DiskGeometry->Geometry.MediaType =
RemovableMedia;
-
- } else {
-
- //
- // Assume media type is fixed disk.
- //
-
- deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
- }
-
- //
- // Assume sectors per track are 32;
- //
-
- deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
-
- //
- // Assume tracks per cylinder (number of heads) is 64.
- //
-
- deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
-
- //
- // Copy the device extension's geometry info into the user buffer.
- //
-
- RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
- &deviceExtension->PartitionLength,
- sizeof(GET_LENGTH_INFORMATION));
-
- //
- // update information field.
- //
-
- realIrp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
- break;
- }
-
- case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX:
- case IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX: {
-
- PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
- ULONG lastSector;
- ULONG bps;
- ULONG lastBit;
- ULONG tmp;
- PDISK_GEOMETRY_EX geometryEx;
-
- //
- // Swizzle bytes from Read Capacity and translate into
- // the necessary geometry information in the device extension.
- //
-
- tmp = readCapacityBuffer->BytesPerBlock;
- ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
- ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
- ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
- ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
-
- //
- // Insure that bps is a power of 2.
- // This corrects a problem with the HP 4020i CDR where it
- // returns an incorrect number for bytes per sector.
- //
-
- if (!bps) {
- bps = 2048;
- } else {
- lastBit = (ULONG) -1;
- while (bps) {
- lastBit++;
- bps = bps >> 1;
- }
-
- bps = 1 << lastBit;
- }
- deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
-
- DebugPrint((2,
- "CdRomDeviceControlCompletion: Calculated bps %#x\n",
- deviceExtension->DiskGeometry->Geometry.BytesPerSector));
-
- //
- // Copy last sector in reverse byte order.
- //
-
- tmp = readCapacityBuffer->LogicalBlockAddress;
- ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
- ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
- ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
- ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
-
- //
- // Calculate sector to byte shift.
- //
-
- WHICH_BIT(bps, deviceExtension->SectorShift);
-
- DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is
%d\n",
- deviceExtension->DiskGeometry->Geometry.BytesPerSector));
-
- DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is
%d\n",
- lastSector + 1));
-
- //
- // Calculate media capacity in bytes.
- //
-
- deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
-
- //
- // Calculate number of cylinders.
- //
-
- deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart =
(LONGLONG)((lastSector + 1)/(32 * 64));
-
- deviceExtension->PartitionLength.QuadPart =
- (deviceExtension->PartitionLength.QuadPart <<
deviceExtension->SectorShift);
-
- if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
-
- //
- // This device supports removable media.
- //
-
- deviceExtension->DiskGeometry->Geometry.MediaType =
RemovableMedia;
-
- } else {
-
- //
- // Assume media type is fixed disk.
- //
-
- deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
- }
-
- //
- // Assume sectors per track are 32;
- //
-
- deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
-
- //
- // Assume tracks per cylinder (number of heads) is 64.
- //
-
- deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
-
- //
- // Copy the device extension's geometry info into the user buffer.
- //
-
- geometryEx = realIrp->AssociatedIrp.SystemBuffer;
- RtlMoveMemory(&geometryEx->Geometry,
- &deviceExtension->DiskGeometry->Geometry,
- sizeof(DISK_GEOMETRY));
-
- //
- // Copy the extended information
- //
-
- geometryEx->DiskSize = deviceExtension->PartitionLength;
-
- //
- // update information field.
- //
-
- realIrp->IoStatus.Information = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
- break;
- }
-
- case IOCTL_DISK_GET_DRIVE_GEOMETRY:
- case IOCTL_CDROM_GET_DRIVE_GEOMETRY: {
-
- PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
- ULONG lastSector;
- ULONG bps;
- ULONG lastBit;
- ULONG tmp;
-
- //
- // Swizzle bytes from Read Capacity and translate into
- // the necessary geometry information in the device extension.
- //
-
- tmp = readCapacityBuffer->BytesPerBlock;
- ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
- ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
- ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
- ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
-
- //
- // Insure that bps is a power of 2.
- // This corrects a problem with the HP 4020i CDR where it
- // returns an incorrect number for bytes per sector.
- //
-
- if (!bps) {
- bps = 2048;
- } else {
- lastBit = (ULONG) -1;
- while (bps) {
- lastBit++;
- bps = bps >> 1;
- }
-
- bps = 1 << lastBit;
- }
- deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
-
- DebugPrint((2,
- "CdRomDeviceControlCompletion: Calculated bps %#x\n",
- deviceExtension->DiskGeometry->Geometry.BytesPerSector));
-
- //
- // Copy last sector in reverse byte order.
- //
-
- tmp = readCapacityBuffer->LogicalBlockAddress;
- ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
- ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
- ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
- ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
-
- //
- // Calculate sector to byte shift.
- //
-
- WHICH_BIT(bps, deviceExtension->SectorShift);
-
- DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is
%d\n",
- deviceExtension->DiskGeometry->Geometry.BytesPerSector));
-
- DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is
%d\n",
- lastSector + 1));
-
- //
- // Calculate media capacity in bytes.
- //
-
- deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
-
- //
- // Calculate number of cylinders.
- //
-
- deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart =
(LONGLONG)((lastSector + 1)/(32 * 64));
-
- deviceExtension->PartitionLength.QuadPart =
- (deviceExtension->PartitionLength.QuadPart <<
deviceExtension->SectorShift);
-
- if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
-
- //
- // This device supports removable media.
- //
-
- deviceExtension->DiskGeometry->Geometry.MediaType =
RemovableMedia;
-
- } else {
-
- //
- // Assume media type is fixed disk.
- //
-
- deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
- }
-
- //
- // Assume sectors per track are 32;
- //
-
- deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
-
- //
- // Assume tracks per cylinder (number of heads) is 64.
- //
-
- deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
-
- //
- // Copy the device extension's geometry info into the user buffer.
- //
-
- RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
- deviceExtension->DiskGeometry,
- sizeof(DISK_GEOMETRY));
-
- //
- // update information field.
- //
-
- realIrp->IoStatus.Information = sizeof(DISK_GEOMETRY);
- break;
- }
-
- case IOCTL_CDROM_CHECK_VERIFY:
-
- if((realIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_CDROM_CHECK_VERIFY) &&
- (realIrpStack->Parameters.DeviceIoControl.OutputBufferLength)) {
-
- *((PULONG)realIrp->AssociatedIrp.SystemBuffer) =
- physicalExtension->MediaChangeCount;
- realIrp->IoStatus.Information = sizeof(ULONG);
- } else {
- realIrp->IoStatus.Information = 0;
- }
-
- DebugPrint((2, "CdRomDeviceControlCompletion: [%lx] completing
CHECK_VERIFY buddy irp %lx\n", realIrp, Irp));
- break;
-
- case IOCTL_CDROM_GET_LAST_SESSION:
- case IOCTL_CDROM_READ_TOC: {
-
- PCDROM_TOC toc = srb->DataBuffer;
-
- //
- // Copy the device extension's geometry info into the user buffer.
- //
-
- RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
- toc,
- srb->DataTransferLength);
-
- //
- // update information field.
- //
-
- realIrp->IoStatus.Information = srb->DataTransferLength;
- break;
- }
-
- case IOCTL_CDROM_PLAY_AUDIO_MSF:
-
- PLAY_ACTIVE(deviceExtension) = TRUE;
-
- break;
-
- case IOCTL_CDROM_READ_Q_CHANNEL: {
-
- PSUB_Q_CHANNEL_DATA userChannelData =
realIrp->AssociatedIrp.SystemBuffer;
-#if DBG
- PCDROM_SUB_Q_DATA_FORMAT inputBuffer =
realIrp->AssociatedIrp.SystemBuffer;
-#endif
- PSUB_Q_CHANNEL_DATA subQPtr = srb->DataBuffer;
-
-#if DBG
- switch( inputBuffer->Format ) {
-
- case IOCTL_CDROM_CURRENT_POSITION:
- DebugPrint((2,"CdRomDeviceControlCompletion: Audio Status is
%u\n", subQPtr->CurrentPosition.Header.AudioStatus ));
- DebugPrint((2,"CdRomDeviceControlCompletion: ADR = 0x%x\n",
subQPtr->CurrentPosition.ADR ));
- DebugPrint((2,"CdRomDeviceControlCompletion: Control = 0x%x\n",
subQPtr->CurrentPosition.Control ));
- DebugPrint((2,"CdRomDeviceControlCompletion: Track = %u\n",
subQPtr->CurrentPosition.TrackNumber ));
- DebugPrint((2,"CdRomDeviceControlCompletion: Index = %u\n",
subQPtr->CurrentPosition.IndexNumber ));
- DebugPrint((2,"CdRomDeviceControlCompletion: Absolute Address =
%x\n", *((PULONG)subQPtr->CurrentPosition.AbsoluteAddress) ));
- DebugPrint((2,"CdRomDeviceControlCompletion: Relative Address =
%x\n", *((PULONG)subQPtr->CurrentPosition.TrackRelativeAddress) ));
- break;
-
- case IOCTL_CDROM_MEDIA_CATALOG:
- DebugPrint((2,"CdRomDeviceControlCompletion: Audio Status is
%u\n", subQPtr->MediaCatalog.Header.AudioStatus ));
- DebugPrint((2,"CdRomDeviceControlCompletion: Mcval is %u\n",
subQPtr->MediaCatalog.Mcval ));
- break;
-
- case IOCTL_CDROM_TRACK_ISRC:
- DebugPrint((2,"CdRomDeviceControlCompletion: Audio Status is
%u\n", subQPtr->TrackIsrc.Header.AudioStatus ));
- DebugPrint((2,"CdRomDeviceControlCompletion: Tcval is %u\n",
subQPtr->TrackIsrc.Tcval ));
- break;
-
- }
-#endif
-
- //
- // Update the play active status.
- //
-
- if (subQPtr->CurrentPosition.Header.AudioStatus ==
AUDIO_STATUS_IN_PROGRESS) {
-
- PLAY_ACTIVE(deviceExtension) = TRUE;
-
- } else {
-
- PLAY_ACTIVE(deviceExtension) = FALSE;
-
- }
-
- //
- // Check if output buffer is large enough to contain
- // the data.
- //
-
- if (realIrpStack->Parameters.DeviceIoControl.OutputBufferLength <
- srb->DataTransferLength) {
-
- srb->DataTransferLength =
- realIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
- }
-
- //
- // Copy our buffer into users.
- //
-
- RtlMoveMemory(userChannelData,
- subQPtr,
- srb->DataTransferLength);
-
- realIrp->IoStatus.Information = srb->DataTransferLength;
- break;
- }
-
- case IOCTL_CDROM_PAUSE_AUDIO:
-
- PLAY_ACTIVE(deviceExtension) = FALSE;
- realIrp->IoStatus.Information = 0;
- break;
-
- case IOCTL_CDROM_RESUME_AUDIO:
-
- realIrp->IoStatus.Information = 0;
- break;
-
- case IOCTL_CDROM_SEEK_AUDIO_MSF:
-
- realIrp->IoStatus.Information = 0;
- break;
-
- case IOCTL_CDROM_STOP_AUDIO:
-
- PLAY_ACTIVE(deviceExtension) = FALSE;
-
- realIrp->IoStatus.Information = 0;
- break;
-
- case IOCTL_CDROM_GET_CONTROL: {
-
- PCDROM_AUDIO_CONTROL audioControl = srb->DataBuffer;
- PAUDIO_OUTPUT audioOutput;
- ULONG bytesTransferred;
-
- audioOutput = ScsiClassFindModePage((PCHAR)audioControl,
- srb->DataTransferLength,
- CDROM_AUDIO_CONTROL_PAGE,
- use6Byte);
- //
- // Verify the page is as big as expected.
- //
-
- bytesTransferred = (PCHAR) audioOutput - (PCHAR) audioControl +
- sizeof(AUDIO_OUTPUT);
-
- if (audioOutput != NULL &&
- srb->DataTransferLength >= bytesTransferred) {
-
- audioControl->LbaFormat = audioOutput->LbaFormat;
-
- audioControl->LogicalBlocksPerSecond =
- (audioOutput->LogicalBlocksPerSecond[0] << (UCHAR)8) |
- audioOutput->LogicalBlocksPerSecond[1];
-
- realIrp->IoStatus.Information = sizeof(CDROM_AUDIO_CONTROL);
-
- } else {
- realIrp->IoStatus.Information = 0;
- status = STATUS_INVALID_DEVICE_REQUEST;
- }
- break;
- }
-
- case IOCTL_CDROM_GET_VOLUME: {
-
- PAUDIO_OUTPUT audioOutput;
- PVOLUME_CONTROL volumeControl = srb->DataBuffer;
- ULONG i,bytesTransferred;
-
- audioOutput = ScsiClassFindModePage((PCHAR)volumeControl,
- srb->DataTransferLength,
- CDROM_AUDIO_CONTROL_PAGE,
- use6Byte);
-
- //
- // Verify the page is as big as expected.
- //
-
- bytesTransferred = (PCHAR) audioOutput - (PCHAR) volumeControl +
- sizeof(AUDIO_OUTPUT);
-
- if (audioOutput != NULL &&
- srb->DataTransferLength >= bytesTransferred) {
-
- for (i=0; i<4; i++) {
- volumeControl->PortVolume[i] =
- audioOutput->PortOutput[i].Volume;
- }
-
- //
- // Set bytes transferred in IRP.
- //
-
- realIrp->IoStatus.Information = sizeof(VOLUME_CONTROL);
-
- } else {
- realIrp->IoStatus.Information = 0;
- status = STATUS_INVALID_DEVICE_REQUEST;
- }
-
- break;
- }
-
- case IOCTL_CDROM_SET_VOLUME:
-
- realIrp->IoStatus.Information = sizeof(VOLUME_CONTROL);
- break;
-
- default:
-
- ASSERT(FALSE);
- realIrp->IoStatus.Information = 0;
- status = STATUS_INVALID_DEVICE_REQUEST;
-
- } // end switch()
- }
-
- //
- // Deallocate srb and sense buffer.
- //
-
- if (srb) {
- if (srb->DataBuffer) {
- ExFreePool(srb->DataBuffer);
- }
- if (srb->SenseInfoBuffer) {
- ExFreePool(srb->SenseInfoBuffer);
- }
- ExFreePool(srb);
- }
-
- if (realIrp->PendingReturned) {
- IoMarkIrpPending(realIrp);
- }
-
- if (Irp->MdlAddress) {
- IoFreeMdl(Irp->MdlAddress);
- }
-
- IoFreeIrp(Irp);
-
- //
- // Set status in completing IRP.
- //
-
- realIrp->IoStatus.Status = status;
-
- //
- // Set the hard error if necessary.
- //
-
- if (!NT_SUCCESS(status) && IoIsErrorUserInduced(status)) {
-
- //
- // Store DeviceObject for filesystem, and clear
- // in IoStatus.Information field.
- //
-
- DebugPrint((1, "CdRomDeviceCompletion - Setting Hard Error on realIrp
%lx\n",
- realIrp));
- IoSetHardErrorOrVerifyDevice(realIrp, DeviceObject);
- realIrp->IoStatus.Information = 0;
- }
-
- IoCompleteRequest(realIrp, IO_DISK_INCREMENT);
-
- IoStartNextPacket(DeviceObject, FALSE);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS
-NTAPI
-CdRomSetVolumeIntermediateCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
- PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension + 1);
- BOOLEAN use6Byte = cdData->XAFlags & XA_USE_6_BYTE;
- PIO_STACK_LOCATION realIrpStack;
- PIO_STACK_LOCATION realIrpNextStack;
- PSCSI_REQUEST_BLOCK srb = Context;
- PIRP realIrp = NULL;
- NTSTATUS status;
- BOOLEAN retry;
-
- //
- // Extract the 'real' irp from the irpstack.
- //
-
- realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
- realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
- realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
-
- //
- // Check SRB status for success of completing request.
- //
-
- if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
-
- DebugPrint((2,
- "CdRomSetVolumeIntermediateCompletion: Irp %lx, Srb %lx Real
Irp\n",
- Irp,
- srb,
- realIrp));
-
- //
- // Release the queue if it is frozen.
- //
-
- if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
- ScsiClassReleaseQueue(DeviceObject);
- }
-
-
- retry = ScsiClassInterpretSenseInfo(DeviceObject,
- srb,
- irpStack->MajorFunction,
-
irpStack->Parameters.DeviceIoControl.IoControlCode,
- MAXIMUM_RETRIES -
((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
- &status);
-
- if (status == STATUS_DATA_OVERRUN) {
- status = STATUS_SUCCESS;
- retry = FALSE;
- }
-
- //
- // If the status is verified required and the this request
- // should bypass verify required then retry the request.
- //
-
- if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
- status == STATUS_VERIFY_REQUIRED) {
-
- status = STATUS_IO_DEVICE_ERROR;
- retry = TRUE;
- }
-
- if (retry && (realIrpNextStack->Parameters.Others.Argument1 =
(PVOID)((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1-1))) {
-
- if (((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
-
- //
- // Retry request.
- //
-
- DebugPrint((1, "Retry request %lx - Calling StartIo\n", Irp));
-
-
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb->DataBuffer);
- ExFreePool(srb);
- if (Irp->MdlAddress) {
- IoFreeMdl(Irp->MdlAddress);
- }
-
- IoFreeIrp(Irp);
-
- //
- // Call StartIo directly since IoStartNextPacket hasn't been called,
- // the serialisation is still intact.
- //
- ScsiCdRomStartIo(DeviceObject, realIrp);
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- }
-
- //
- // Exhausted retries. Fall through and complete the request with the
appropriate status.
- //
-
- }
- } else {
-
- //
- // Set status for successful request.
- //
-
- status = STATUS_SUCCESS;
- }
-
- if (NT_SUCCESS(status)) {
-
- PAUDIO_OUTPUT audioInput = NULL;
- PAUDIO_OUTPUT audioOutput;
- PVOLUME_CONTROL volumeControl = realIrp->AssociatedIrp.SystemBuffer;
- ULONG i,bytesTransferred,headerLength;
- PVOID dataBuffer;
- PCDB cdb;
-
- audioInput = ScsiClassFindModePage((PCHAR)srb->DataBuffer,
- srb->DataTransferLength,
- CDROM_AUDIO_CONTROL_PAGE,
- use6Byte);
-
- //
- // Check to make sure the mode sense data is valid before we go on
- //
-
- if(audioInput == NULL) {
-
- DebugPrint((1, "Mode Sense Page %d not found\n",
- CDROM_AUDIO_CONTROL_PAGE));
-
- realIrp->IoStatus.Information = 0;
- realIrp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
- IoCompleteRequest(realIrp, IO_DISK_INCREMENT);
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb);
- IoFreeMdl(Irp->MdlAddress);
- IoFreeIrp(Irp);
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
-
- if (use6Byte) {
- headerLength = sizeof(MODE_PARAMETER_HEADER);
- } else {
- headerLength = sizeof(MODE_PARAMETER_HEADER10);
- }
-
- bytesTransferred = sizeof(AUDIO_OUTPUT) + headerLength;
-
- //
- // Allocate a new buffer for the mode select.
- //
-
- dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned, bytesTransferred);
-
- if (!dataBuffer) {
- realIrp->IoStatus.Information = 0;
- realIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(realIrp, IO_DISK_INCREMENT);
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb);
- IoFreeMdl(Irp->MdlAddress);
- IoFreeIrp(Irp);
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
-
- RtlZeroMemory(dataBuffer, bytesTransferred);
-
- //
- // Rebuild the data buffer to include the user requested values.
- //
-
- audioOutput = (PAUDIO_OUTPUT) ((PCHAR) dataBuffer + headerLength);
-
- for (i=0; i<4; i++) {
- audioOutput->PortOutput[i].Volume =
- volumeControl->PortVolume[i];
- audioOutput->PortOutput[i].ChannelSelection =
- audioInput->PortOutput[i].ChannelSelection;
- }
-
- audioOutput->CodePage = CDROM_AUDIO_CONTROL_PAGE;
- audioOutput->ParameterLength = sizeof(AUDIO_OUTPUT) - 2;
- audioOutput->Immediate = MODE_SELECT_IMMEDIATE;
-
- //
- // Free the old data buffer, mdl.
- //
-
- ExFreePool(srb->DataBuffer);
- IoFreeMdl(Irp->MdlAddress);
-
- //
- // rebuild the srb.
- //
-
- cdb = (PCDB)srb->Cdb;
- RtlZeroMemory(cdb, CDB12GENERIC_LENGTH);
-
- srb->SrbStatus = srb->ScsiStatus = 0;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_OUT);
- srb->DataTransferLength = bytesTransferred;
-
- if (use6Byte) {
-
- cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
- cdb->MODE_SELECT.ParameterListLength = (UCHAR) bytesTransferred;
- cdb->MODE_SELECT.PFBit = 1;
- srb->CdbLength = 6;
- } else {
-
- cdb->MODE_SELECT10.OperationCode = SCSIOP_MODE_SELECT10;
- cdb->MODE_SELECT10.ParameterListLength[0] = (UCHAR) (bytesTransferred
>> 8);
- cdb->MODE_SELECT10.ParameterListLength[1] = (UCHAR) (bytesTransferred
& 0xFF);
- cdb->MODE_SELECT10.PFBit = 1;
- srb->CdbLength = 10;
- }
-
- //
- // Prepare the MDL
- //
-
- Irp->MdlAddress = IoAllocateMdl(dataBuffer,
- bytesTransferred,
- FALSE,
- FALSE,
- (PIRP) NULL);
-
- if (!Irp->MdlAddress) {
- realIrp->IoStatus.Information = 0;
- realIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(realIrp, IO_DISK_INCREMENT);
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb);
- ExFreePool(dataBuffer);
- IoFreeIrp(Irp);
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- }
-
- MmBuildMdlForNonPagedPool(Irp->MdlAddress);
- srb->DataBuffer = dataBuffer;
-
- irpStack = IoGetNextIrpStackLocation(Irp);
- irpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
- irpStack->Parameters.Scsi.Srb = srb;
-
- //
- // reset the irp completion.
- //
-
- IoSetCompletionRoutine(Irp,
- CdRomDeviceControlCompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
- //
- // Call the port driver.
- //
-
- IoCallDriver(deviceExtension->PortDeviceObject, Irp);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
-
- //
- // Deallocate srb and sense buffer.
- //
-
- if (srb) {
- if (srb->DataBuffer) {
- ExFreePool(srb->DataBuffer);
- }
- if (srb->SenseInfoBuffer) {
- ExFreePool(srb->SenseInfoBuffer);
- }
- ExFreePool(srb);
- }
-
- if (Irp->PendingReturned) {
- IoMarkIrpPending(Irp);
- }
-
- if (realIrp->PendingReturned) {
- IoMarkIrpPending(realIrp);
- }
-
- if (Irp->MdlAddress) {
- IoFreeMdl(Irp->MdlAddress);
- }
-
- IoFreeIrp(Irp);
-
- //
- // Set status in completing IRP.
- //
-
- realIrp->IoStatus.Status = status;
-
- //
- // Set the hard error if necessary.
- //
-
- if (!NT_SUCCESS(status) && IoIsErrorUserInduced(status)) {
-
- //
- // Store DeviceObject for filesystem, and clear
- // in IoStatus.Information field.
- //
-
- IoSetHardErrorOrVerifyDevice(realIrp, DeviceObject);
- realIrp->IoStatus.Information = 0;
- }
-
- IoCompleteRequest(realIrp, IO_DISK_INCREMENT);
-
- IoStartNextPacket(DeviceObject, FALSE);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-
-NTSTATUS
-NTAPI
-CdRomSwitchModeCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
- PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension + 1);
- PIO_STACK_LOCATION realIrpStack;
- PIO_STACK_LOCATION realIrpNextStack;
- PSCSI_REQUEST_BLOCK srb = Context;
- PIRP realIrp = NULL;
- NTSTATUS status;
- BOOLEAN retry;
-
- //
- // Extract the 'real' irp from the irpstack.
- //
-
- realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
- realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
- realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
-
- //
- // Check SRB status for success of completing request.
- //
-
- if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
-
- DebugPrint((2,
- "CdRomSetVolumeIntermediateCompletion: Irp %lx, Srb %lx Real
Irp\n",
- Irp,
- srb,
- realIrp));
-
- //
- // Release the queue if it is frozen.
- //
-
- if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
- ScsiClassReleaseQueue(DeviceObject);
- }
-
-
- retry = ScsiClassInterpretSenseInfo(DeviceObject,
- srb,
- irpStack->MajorFunction,
-
irpStack->Parameters.DeviceIoControl.IoControlCode,
- MAXIMUM_RETRIES -
((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
- &status);
-
- //
- // If the status is verified required and the this request
- // should bypass verify required then retry the request.
- //
-
- if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
- status == STATUS_VERIFY_REQUIRED) {
-
- status = STATUS_IO_DEVICE_ERROR;
- retry = TRUE;
- }
-
- if (retry && (realIrpNextStack->Parameters.Others.Argument1 =
(PVOID)((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1-1))) {
-
- if (((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
-
- //
- // Retry request.
- //
-
- DebugPrint((1, "Retry request %lx - Calling StartIo\n", Irp));
-
-
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb->DataBuffer);
- ExFreePool(srb);
- if (Irp->MdlAddress) {
- IoFreeMdl(Irp->MdlAddress);
- }
-
- IoFreeIrp(Irp);
-
- //
- // Call StartIo directly since IoStartNextPacket hasn't been called,
- // the serialisation is still intact.
- //
-
- ScsiCdRomStartIo(DeviceObject, realIrp);
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- }
-
- //
- // Exhausted retries. Fall through and complete the request with the
appropriate status.
- //
- }
- } else {
-
- //
- // Set status for successful request.
- //
-
- status = STATUS_SUCCESS;
- }
-
- if (NT_SUCCESS(status)) {
-
- ULONG sectorSize, startingSector, transferByteCount;
- PCDB cdb;
-
- //
- // Update device ext. to show which mode we are currently using.
- //
-
- sectorSize = cdData->u1.BlockDescriptor.BlockLength[0] << 16;
- sectorSize |= (cdData->u1.BlockDescriptor.BlockLength[1] << 8);
- sectorSize |= (cdData->u1.BlockDescriptor.BlockLength[2]);
-
- cdData->RawAccess = (sectorSize == RAW_SECTOR_SIZE) ? TRUE : FALSE;
-
- //
- // Free the old data buffer, mdl.
- //
-
- ExFreePool(srb->DataBuffer);
- IoFreeMdl(Irp->MdlAddress);
- IoFreeIrp(Irp);
-
- //
- // rebuild the srb.
- //
-
- cdb = (PCDB)srb->Cdb;
- RtlZeroMemory(cdb, CDB12GENERIC_LENGTH);
-
-
- if (cdData->RawAccess) {
-
- PRAW_READ_INFO rawReadInfo =
-
(PRAW_READ_INFO)realIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
-
- ULONG maximumTransferLength;
- ULONG transferPages;
-
- //
- // Calculate starting offset.
- //
-
- startingSector = (ULONG)(rawReadInfo->DiskOffset.QuadPart >>
deviceExtension->SectorShift);
- transferByteCount = rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
- maximumTransferLength =
deviceExtension->PortCapabilities->MaximumTransferLength;
- transferPages =
ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(realIrp->MdlAddress),
- transferByteCount);
-
- //
- // Determine if request is within limits imposed by miniport.
- // If the request is larger than the miniport's capabilities, split it.
- //
-
- if (transferByteCount > maximumTransferLength ||
- transferPages >
deviceExtension->PortCapabilities->MaximumPhysicalPages) {
-
- realIrp->IoStatus.Information = 0;
- realIrp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- IoCompleteRequest(realIrp, IO_DISK_INCREMENT);
-
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb);
-
- IoStartNextPacket(DeviceObject, FALSE);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
-
- srb->OriginalRequest = realIrp;
- srb->SrbFlags = deviceExtension->SrbFlags;
- srb->SrbFlags |= (SRB_FLAGS_DISABLE_SYNCH_TRANSFER | SRB_FLAGS_DATA_IN);
- srb->DataTransferLength = transferByteCount;
- srb->TimeOutValue = deviceExtension->TimeOutValue;
- srb->CdbLength = 10;
- srb->DataBuffer = MmGetMdlVirtualAddress(realIrp->MdlAddress);
-
- if (rawReadInfo->TrackMode == CDDA) {
- if (cdData->XAFlags & PLEXTOR_CDDA) {
-
- srb->CdbLength = 12;
-
- cdb->PLXTR_READ_CDDA.LogicalUnitNumber = deviceExtension->Lun;
- cdb->PLXTR_READ_CDDA.LogicalBlockByte3 = (UCHAR) (startingSector
& 0xFF);
- cdb->PLXTR_READ_CDDA.LogicalBlockByte2 = (UCHAR) ((startingSector
>> 8) & 0xFF);
- cdb->PLXTR_READ_CDDA.LogicalBlockByte1 = (UCHAR) ((startingSector
>> 16) & 0xFF);
- cdb->PLXTR_READ_CDDA.LogicalBlockByte0 = (UCHAR) ((startingSector
>> 24) & 0xFF);
-
- cdb->PLXTR_READ_CDDA.TransferBlockByte3 = (UCHAR)
(rawReadInfo->SectorCount & 0xFF);
- cdb->PLXTR_READ_CDDA.TransferBlockByte2 = (UCHAR)
(rawReadInfo->SectorCount >> 8);
- cdb->PLXTR_READ_CDDA.TransferBlockByte1 = 0;
- cdb->PLXTR_READ_CDDA.TransferBlockByte0 = 0;
-
- cdb->PLXTR_READ_CDDA.SubCode = 0;
- cdb->PLXTR_READ_CDDA.OperationCode = 0xD8;
-
- } else if (cdData->XAFlags & NEC_CDDA) {
-
- cdb->NEC_READ_CDDA.LogicalBlockByte3 = (UCHAR) (startingSector
& 0xFF);
- cdb->NEC_READ_CDDA.LogicalBlockByte2 = (UCHAR) ((startingSector
>> 8) & 0xFF);
- cdb->NEC_READ_CDDA.LogicalBlockByte1 = (UCHAR) ((startingSector
>> 16) & 0xFF);
- cdb->NEC_READ_CDDA.LogicalBlockByte0 = (UCHAR) ((startingSector
>> 24) & 0xFF);
-
- cdb->NEC_READ_CDDA.TransferBlockByte1 = (UCHAR)
(rawReadInfo->SectorCount & 0xFF);
- cdb->NEC_READ_CDDA.TransferBlockByte0 = (UCHAR)
(rawReadInfo->SectorCount >> 8);
-
- cdb->NEC_READ_CDDA.OperationCode = 0xD4;
- }
- } else {
- cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
-
- cdb->CDB10.TransferBlocksMsb = (UCHAR) (rawReadInfo->SectorCount
>> 8);
- cdb->CDB10.TransferBlocksLsb = (UCHAR) (rawReadInfo->SectorCount
& 0xFF);
-
- cdb->CDB10.LogicalBlockByte3 = (UCHAR) (startingSector & 0xFF);
- cdb->CDB10.LogicalBlockByte2 = (UCHAR) ((startingSector >> 8)
& 0xFF);
- cdb->CDB10.LogicalBlockByte1 = (UCHAR) ((startingSector >> 16)
& 0xFF);
- cdb->CDB10.LogicalBlockByte0 = (UCHAR) ((startingSector >> 24)
& 0xFF);
-
- cdb->CDB10.OperationCode = SCSIOP_READ;
- }
-
- srb->SrbStatus = srb->ScsiStatus = 0;
-
-
- irpStack = IoGetNextIrpStackLocation(realIrp);
- irpStack->MajorFunction = IRP_MJ_SCSI;
- irpStack->Parameters.Scsi.Srb = srb;
-
- if (!(irpStack->Parameters.Others.Argument1)) {
-
- //
- // Only jam this in if it doesn't exist. The completion routines can
- // call StartIo directly in the case of retries and resetting it will
- // cause infinite loops.
- //
-
- irpStack->Parameters.Others.Argument1 = (PVOID) MAXIMUM_RETRIES;
- }
-
- //
- // Set up IoCompletion routine address.
- //
-
- IoSetCompletionRoutine(realIrp,
- CdRomXACompletion,
- srb,
- TRUE,
- TRUE,
- TRUE);
- } else {
-
- ULONG maximumTransferLength =
deviceExtension->PortCapabilities->MaximumTransferLength;
- ULONG transferPages =
ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(realIrp->MdlAddress),
-
realIrpStack->Parameters.Read.Length);
- //
- // Back to cooked sectors. Build and send a normal read.
- // The real work for setting offsets and checking for splitrequests was
- // done in startio
- //
-
- if ((realIrpStack->Parameters.Read.Length > maximumTransferLength) ||
- (transferPages >
deviceExtension->PortCapabilities->MaximumPhysicalPages)) {
-
- //
- // Request needs to be split. Completion of each portion of the request
will
- // fire off the next portion. The final request will signal Io to send a
new request.
- //
-
- ScsiClassSplitRequest(DeviceObject, realIrp, maximumTransferLength);
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- } else {
-
- //
- // Build SRB and CDB for this IRP.
- //
-
- ScsiClassBuildRequest(DeviceObject, realIrp);
-
- }
- }
-
- //
- // Call the port driver.
- //
-
- IoCallDriver(deviceExtension->PortDeviceObject, realIrp);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
-
- //
- // Update device Extension flags to indicate that XA isn't supported.
- //
-
- cdData->XAFlags |= XA_NOT_SUPPORTED;
-
- //
- // Deallocate srb and sense buffer.
- //
-
- if (srb) {
- if (srb->DataBuffer) {
- ExFreePool(srb->DataBuffer);
- }
- if (srb->SenseInfoBuffer) {
- ExFreePool(srb->SenseInfoBuffer);
- }
- ExFreePool(srb);
- }
-
- if (Irp->PendingReturned) {
- IoMarkIrpPending(Irp);
- }
-
- if (realIrp->PendingReturned) {
- IoMarkIrpPending(realIrp);
- }
-
- if (Irp->MdlAddress) {
- IoFreeMdl(Irp->MdlAddress);
- }
-
- IoFreeIrp(Irp);
-
- //
- // Set status in completing IRP.
- //
-
- realIrp->IoStatus.Status = status;
-
- //
- // Set the hard error if necessary.
- //
-
- if (!NT_SUCCESS(status) && IoIsErrorUserInduced(status)) {
-
- //
- // Store DeviceObject for filesystem, and clear
- // in IoStatus.Information field.
- //
-
- IoSetHardErrorOrVerifyDevice(realIrp, DeviceObject);
- realIrp->IoStatus.Information = 0;
- }
-
- IoCompleteRequest(realIrp, IO_DISK_INCREMENT);
-
- IoStartNextPacket(DeviceObject, FALSE);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS
-NTAPI
-CdRomXACompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-
-/*++
-
-Routine Description:
-
- This routine executes when the port driver has completed a request.
- It looks at the SRB status in the completing SRB and if not success
- it checks for valid request sense buffer information. If valid, the
- info is used to update status with more precise message of type of
- error. This routine deallocates the SRB.
-
-Arguments:
-
- DeviceObject - Supplies the device object which represents the logical
- unit.
-
- Irp - Supplies the Irp which has completed.
-
- Context - Supplies a pointer to the SRB.
-
-Return Value:
-
- NT status
-
---*/
-
-{
- PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
- PIO_STACK_LOCATION irpNextStack = IoGetNextIrpStackLocation(Irp);
- PSCSI_REQUEST_BLOCK srb = Context;
- NTSTATUS status;
- BOOLEAN retry;
-
- //
- // Check SRB status for success of completing request.
- //
-
- if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
-
- DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
-
- //
- // Release the queue if it is frozen.
- //
-
- if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
- ScsiClassReleaseQueue(DeviceObject);
- }
-
- retry = ScsiClassInterpretSenseInfo(
- DeviceObject,
- srb,
- irpStack->MajorFunction,
- irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ?
irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
- MAXIMUM_RETRIES - ((ULONG_PTR)irpNextStack->Parameters.Others.Argument1),
- &status);
-
- //
- // If the status is verified required and the this request
- // should bypass verify required then retry the request.
- //
-
- if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
- status == STATUS_VERIFY_REQUIRED) {
-
- status = STATUS_IO_DEVICE_ERROR;
- retry = TRUE;
- }
-
- if (retry && (irpNextStack->Parameters.Others.Argument1 =
(PVOID)((ULONG_PTR)irpNextStack->Parameters.Others.Argument1-1))) {
-
- if (((ULONG_PTR)irpNextStack->Parameters.Others.Argument1)) {
-
- //
- // Retry request.
- //
-
- DebugPrint((1, "CdRomXACompletion: Retry request %lx - Calling
StartIo\n", Irp));
-
-
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb->DataBuffer);
- ExFreePool(srb);
-
- //
- // Call StartIo directly since IoStartNextPacket hasn't been called,
- // the serialisation is still intact.
- //
-
- ScsiCdRomStartIo(DeviceObject, Irp);
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- }
-
- //
- // Exhausted retries. Fall through and complete the request with the
appropriate status.
- //
- }
- } else {
-
- //
- // Set status for successful request.
- //
-
- status = STATUS_SUCCESS;
-
- } // end if (SRB_STATUS(srb->SrbStatus) ...
-
- //
- // Return SRB to nonpaged pool.
- //
-
- ExFreePool(srb);
-
- //
- // Set status in completing IRP.
- //
-
- Irp->IoStatus.Status = status;
-
- //
- // Set the hard error if necessary.
- //
-
- if (!NT_SUCCESS(status) && IoIsErrorUserInduced(status)) {
-
- //
- // Store DeviceObject for filesystem, and clear
- // in IoStatus.Information field.
- //
-
- IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
- Irp->IoStatus.Information = 0;
- }
-
- //
- // If pending has be returned for this irp then mark the current stack as
- // pending.
- //
-
- if (Irp->PendingReturned) {
- IoMarkIrpPending(Irp);
- }
-
- //IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- IoStartNextPacket(DeviceObject, FALSE);
-
- return status;
-}
-
-NTSTATUS
-NTAPI
-CdRomDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-
-/*++
-
-Routine Description:
-
- This is the NT device control handler for CDROMs.
-
-Arguments:
-
- DeviceObject - for this CDROM
-
- Irp - IO Request packet
-
-Return Value:
-
- NTSTATUS
-
---*/
-
-{
- PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
- PIO_STACK_LOCATION nextStack;
- PKEVENT deviceControlEvent;
- PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
- PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension+1);
- SCSI_REQUEST_BLOCK srb;
- NTSTATUS status;
- KIRQL irql;
-
- ULONG ioctlCode;
- ULONG baseCode;
- ULONG functionCode;
-
-RetryControl:
-
- //
- // Zero the SRB on stack.
- //
-
- RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
-
- Irp->IoStatus.Information = 0;
-
- //
- // if this is a class driver ioctl then we need to change the base code
- // to IOCTL_CDROM_BASE so that the switch statement can handle it.
- //
- // WARNING - currently the scsi class ioctl function codes are between
- // 0x200 & 0x300. this routine depends on that fact
- //
-
- ioctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
- baseCode = ioctlCode >> 16;
- functionCode = (ioctlCode & (~0xffffc003)) >> 2;
-
- DebugPrint((1, "CdRomDeviceControl: Ioctl Code = %#08lx, Base Code =
%#lx,"
- " Function Code = %#lx\n",
- ioctlCode,
- baseCode,
- functionCode
- ));
-
- if((functionCode >= 0x200) && (functionCode <= 0x300)) {
-
- ioctlCode = (ioctlCode & 0x0000ffff) | CTL_CODE(IOCTL_CDROM_BASE, 0, 0, 0);
-
- DebugPrint((1, "CdRomDeviceControl: Class Code - new ioctl code is
%#08lx\n",
- ioctlCode));
-
- irpStack->Parameters.DeviceIoControl.IoControlCode = ioctlCode;
-
- }
-
- switch (ioctlCode) {
-
- case IOCTL_CDROM_RAW_READ: {
-
- LARGE_INTEGER startingOffset;
- ULONG transferBytes;
- PRAW_READ_INFO rawReadInfo =
(PRAW_READ_INFO)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
- PUCHAR userData = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Ensure that XA reads are supported.
- //
-
- if (cdData->XAFlags & XA_NOT_SUPPORTED) {
-
- DebugPrint((1,
- "CdRomDeviceControl: XA Reads not supported. Flags
(%x)\n",
- cdData->XAFlags));
-
- status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
-
- //
- // Check that ending sector is on disc and buffers are there and of
- // correct size.
- //
-
- if (rawReadInfo == NULL) {
-
- //
- // Called from user space. Validate the buffers.
- //
-
- rawReadInfo = (PRAW_READ_INFO)userData;
- irpStack->Parameters.DeviceIoControl.Type3InputBuffer = (PVOID)userData;
-
- if (rawReadInfo == NULL) {
-
- DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA
Read (No extent info\n"));
-
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
sizeof(RAW_READ_INFO)) {
-
- DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA
Read (Invalid info buffer\n"));
-
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INVALID_PARAMETER;
- }
- }
-
- startingOffset.QuadPart = rawReadInfo->DiskOffset.QuadPart;
- transferBytes = rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
-
- if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
transferBytes) {
-
- DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA Read
(Bad buffer size)\n"));
-
- //
- // Fail request with status of invalid parameters.
- //
-
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INVALID_PARAMETER;
- }
-
- if ((startingOffset.QuadPart + transferBytes) >
deviceExtension->PartitionLength.QuadPart) {
-
- DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA Read
(Request Out of Bounds)\n"));
-
- //
- // Fail request with status of invalid parameters.
- //
-
- status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- IoMarkIrpPending(Irp);
- IoStartPacket(DeviceObject, Irp, NULL, NULL);
-
- return STATUS_PENDING;
- }
-
- case IOCTL_DISK_GET_DRIVE_GEOMETRY:
- case IOCTL_CDROM_GET_DRIVE_GEOMETRY: {
-
- DebugPrint((2,"CdRomDeviceControl: Get drive geometry\n"));
-
- if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof( DISK_GEOMETRY ) ) {
-
- status = STATUS_INFO_LENGTH_MISMATCH;
- break;
- }
-
- IoMarkIrpPending(Irp);
- IoStartPacket(DeviceObject,Irp, NULL,NULL);
-
- return STATUS_PENDING;
- }
-
- case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX:
- case IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX: {
-
- DebugPrint((2,"CdRomDeviceControl: Get drive geometry ex\n"));
-
- if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof( DISK_GEOMETRY_EX ) ) {
-
- status = STATUS_INFO_LENGTH_MISMATCH;
- break;
- }
-
- IoMarkIrpPending(Irp);
- IoStartPacket(DeviceObject,Irp, NULL,NULL);
-
- return STATUS_PENDING;
- }
-
- case IOCTL_DISK_GET_LENGTH_INFO: {
-
- DebugPrint((2,"CdRomDeviceControl: Get length info\n"));
-
- if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof( GET_LENGTH_INFORMATION ) ) {
-
- status = STATUS_INFO_LENGTH_MISMATCH;
- break;
- }
-
- IoMarkIrpPending(Irp);
- IoStartPacket(DeviceObject,Irp, NULL,NULL);
-
- return STATUS_PENDING;
- }
-
- case IOCTL_CDROM_GET_LAST_SESSION:
- case IOCTL_CDROM_READ_TOC: {
-
- //
- // If the cd is playing music then reject this request.
- //
-
- if (CdRomIsPlayActive(DeviceObject)) {
- Irp->IoStatus.Status = STATUS_DEVICE_BUSY;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_DEVICE_BUSY;
- }
-
- IoMarkIrpPending(Irp);
- IoStartPacket(DeviceObject, Irp, NULL, NULL);
-
- return STATUS_PENDING;
- }
-
- case IOCTL_CDROM_PLAY_AUDIO_MSF: {
-
- //
... 15701 lines suppressed ...