ReactOS  0.4.14-dev-376-gaedba84
cdrom.h File Reference
#include <ntddk.h>
#include <ntddcdvd.h>
#include <classpnp.h>
#include <ntddmmc.h>
#include "trace.h"
Include dependency graph for cdrom.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _XA_CONTEXT
 
struct  _ERROR_RECOVERY_DATA
 
struct  _ERROR_RECOVERY_DATA10
 
struct  _CDROM_DRIVER_EXTENSION
 
struct  _CDROM_MMC_EXTENSION
 
struct  _CDROM_DATA
 

Macros

#define CDROM_GET_CONFIGURATION_TIMEOUT   (0x4)
 
#define CDROM_HACK_DEC_RRD   (0x00000001)
 
#define CDROM_HACK_FUJITSU_FMCD_10x   (0x00000002)
 
#define CDROM_HACK_HITACHI_1750   (0x00000004)
 
#define CDROM_HACK_HITACHI_GD_2000   (0x00000008)
 
#define CDROM_HACK_TOSHIBA_SD_W1101   (0x00000010)
 
#define CDROM_HACK_TOSHIBA_XM_3xx   (0x00000020)
 
#define CDROM_HACK_NEC_CDDA   (0x00000040)
 
#define CDROM_HACK_PLEXTOR_CDDA   (0x00000080)
 
#define CDROM_HACK_BAD_GET_CONFIG_SUPPORT   (0x00000100)
 
#define CDROM_HACK_FORCE_READ_CD_DETECTION   (0x00000200)
 
#define CDROM_HACK_READ_CD_SUPPORTED   (0x00000400)
 
#define CDROM_HACK_LOCKED_PAGES   (0x80000000)
 
#define CDROM_HACK_VALID_FLAGS   (0x000007ff)
 
#define CDROM_HACK_INVALID_FLAGS   (~CDROM_HACK_VALID_FLAGS)
 
#define CdromMmcUpdateComplete   0
 
#define CdromMmcUpdateRequired   1
 
#define CdromMmcUpdateStarted   2
 
#define CDROM_DRIVER_EXTENSION_ID   CdRomAddDevice
 
#define DEVICE_EXTENSION_SIZE   sizeof(FUNCTIONAL_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 CDROM_SRB_LIST_SIZE   4
 
#define PLAY_ACTIVE(x)   (((PCDROM_DATA)(x->CommonExtension.DriverData))->PlayActive)
 
#define MSF_TO_LBA(Minutes, Seconds, Frames)   (ULONG)((60 * 75 * (Minutes)) + (75 * (Seconds)) + ((Frames) - 150))
 
#define LBA_TO_MSF(Lba, Minutes, Seconds, Frames)
 
#define DEC_TO_BCD(x)   (((x / 10) << 4) + (x % 10))
 
#define XA_USE_6_BYTE   0x01
 
#define XA_USE_10_BYTE   0x02
 
#define XA_NOT_SUPPORTED   0x10
 
#define XA_USE_READ_CD   0x20
 
#define XA_PLEXTOR_CDDA   0x40
 
#define XA_NEC_CDDA   0x80
 
#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
 
#define MAX_COPY_PROTECT_AGID   4
 
#define CDROM_TAG_GET_CONFIG   'cCcS'
 
#define CDROM_TAG_DC_EVENT   'ECcS'
 
#define CDROM_TAG_FEATURE   'FCcS'
 
#define CDROM_TAG_DISK_GEOM   'GCcS'
 
#define CDROM_TAG_HITACHI_ERROR   'HCcS'
 
#define CDROM_TAG_SENSE_INFO   'ICcS'
 
#define CDROM_TAG_POWER_IRP   'iCcS'
 
#define CDROM_TAG_SRB   'SCcS'
 
#define CDROM_TAG_STRINGS   'sCcS'
 
#define CDROM_TAG_MODE_DATA   'MCcS'
 
#define CDROM_TAG_READ_CAP   'PCcS'
 
#define CDROM_TAG_PLAY_ACTIVE   'pCcS'
 
#define CDROM_TAG_SUB_Q   'QCcS'
 
#define CDROM_TAG_RAW   'RCcS'
 
#define CDROM_TAG_TOC   'TCcS'
 
#define CDROM_TAG_TOSHIBA_ERROR   'tCcS'
 
#define CDROM_TAG_DEC_ERROR   'dCcS'
 
#define CDROM_TAG_UPDATE_CAP   'UCcS'
 
#define CDROM_TAG_VOLUME   'VCcS'
 
#define CDROM_TAG_VOLUME_INT   'vCcS'
 
#define DVD_TAG_READ_STRUCTURE   'SVcS'
 
#define DVD_TAG_READ_KEY   'kVcS'
 
#define DVD_TAG_SEND_KEY   'KVcS'
 
#define DVD_TAG_RPC2_CHECK   'sVcS'
 
#define DVD_TAG_DVD_REGION   'tVcS'
 
#define DVD_TAG_SECURITY   'XVcS'
 
#define CDROM_SUBKEY_NAME   (L"CdRom")
 
#define CDROM_READ_CD_NAME   (L"ReadCD")
 
#define CDROM_NON_MMC_DRIVE_NAME   (L"NonMmc")
 
#define DVD_DEFAULT_REGION   (L"DefaultDvdRegion")
 
#define DVD_CURRENT_REGION   (L"DvdR")
 
#define DVD_REGION_RESET_COUNT   (L"DvdRCnt")
 
#define DVD_MAX_REGION_RESET_COUNT   2
 
#define DVD_MAX_REGION   8
 
#define BAIL_OUT(Irp)
 

Typedefs

typedef struct _XA_CONTEXT XA_CONTEXT
 
typedef struct _XA_CONTEXTPXA_CONTEXT
 
typedef struct _ERROR_RECOVERY_DATA ERROR_RECOVERY_DATA
 
typedef struct _ERROR_RECOVERY_DATAPERROR_RECOVERY_DATA
 
typedef struct _ERROR_RECOVERY_DATA10 ERROR_RECOVERY_DATA10
 
typedef struct _ERROR_RECOVERY_DATA10PERROR_RECOVERY_DATA10
 
typedef struct _CDROM_DRIVER_EXTENSION CDROM_DRIVER_EXTENSION
 
typedef struct _CDROM_DRIVER_EXTENSIONPCDROM_DRIVER_EXTENSION
 
typedef struct _CDROM_MMC_EXTENSION CDROM_MMC_EXTENSION
 
typedef struct _CDROM_MMC_EXTENSIONPCDROM_MMC_EXTENSION
 
typedef struct _CDROM_DATA CDROM_DATA
 
typedef struct _CDROM_DATAPCDROM_DATA
 

Enumerations

enum  CdromError {
  CdromDebugError = 0, CdromDebugWarning = 1, CdromDebugTrace = 2, CdromDebugInfo = 3,
  CdromDebugFeatures = 32
}
 

Functions

static VOID CdRomCompleteIrpAndStartNextPacketSafely (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI CdRomDeviceControlDvdReadStructure (IN PDEVICE_OBJECT DeviceObject, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI CdRomDeviceControlDvdEndSession (IN PDEVICE_OBJECT DeviceObject, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI CdRomDeviceControlDvdStartSessionReadKey (IN PDEVICE_OBJECT DeviceObject, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI CdRomDeviceControlDvdSendKey (IN PDEVICE_OBJECT DeviceObject, IN PIRP OriginalIrp, IN PIRP NewIrp, IN PSCSI_REQUEST_BLOCK Srb)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
VOID NTAPI CdRomUnload (IN PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI CdRomAddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo)
 
NTSTATUS NTAPI CdRomOpenClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CdRomReadWriteVerification (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CdRomSwitchMode (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN PIRP OriginalRequest)
 
NTSTATUS NTAPI CdRomDeviceControlDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CdRomDeviceControlCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomSetVolumeIntermediateCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomSwitchModeCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomXACompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomClassIoctlCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
VOID NTAPI CdRomStartIo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI CdRomTickHandler (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI CdRomUpdateCapacity (IN PFUNCTIONAL_DEVICE_EXTENSION DeviceExtension, IN PIRP IrpToComplete, IN OPTIONAL PKEVENT IoctlEvent)
 
NTSTATUS NTAPI CdRomCreateDeviceObject (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo)
 
VOID NTAPI ScanForSpecialHandler (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, ULONG_PTR HackFlags)
 
VOID NTAPI ScanForSpecial (PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI CdRomIsPlayActive (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI CdRomErrorHandler (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
VOID NTAPI HitachiProcessErrorGD2000 (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
VOID NTAPI HitachiProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
VOID NTAPI ToshibaProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
NTSTATUS NTAPI ToshibaProcessErrorCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
VOID NTAPI CdRomCreateNamedEvent (IN PFUNCTIONAL_DEVICE_EXTENSION DeviceExtension, IN ULONG DeviceNumber)
 
NTSTATUS NTAPI CdRomInitDevice (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI CdRomStartDevice (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI CdRomStopDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
NTSTATUS NTAPI CdRomRemoveDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
NTSTATUS NTAPI CdRomDvdEndAllSessionsCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomDvdReadDiskKeyCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
DEVICE_TYPE NTAPI CdRomGetDeviceType (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI CdRomCreateWellKnownName (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI CdRomDeleteWellKnownName (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI CdRomGetDeviceParameter (IN PDEVICE_OBJECT DeviceObject, IN PWSTR ParameterName, IN OUT PULONG ParameterValue)
 
NTSTATUS NTAPI CdRomSetDeviceParameter (IN PDEVICE_OBJECT DeviceObject, IN PWSTR ParameterName, IN ULONG ParameterValue)
 
VOID NTAPI CdRomPickDvdRegion (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI CdRomRetryRequest (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PIRP Irp, IN ULONG Delay, IN BOOLEAN ResendIrp)
 
NTSTATUS NTAPI CdRomRerunRequest (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN OPTIONAL PIRP Irp, IN BOOLEAN ResendIrp)
 
NTSTATUS NTAPI CdRomGetRpc0Settings (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI CdRomSetRpc0Settings (IN PDEVICE_OBJECT Fdo, IN UCHAR NewRegion)
 
NTSTATUS NTAPI CdRomShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI CdRomIsDeviceMmcDevice (IN PDEVICE_OBJECT Fdo, OUT PBOOLEAN IsMmc)
 
VOID NTAPI CdRomMmcErrorHandler (IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, OUT PNTSTATUS Status, OUT PBOOLEAN Retry)
 
PVOID NTAPI CdRomFindFeaturePage (IN PGET_CONFIGURATION_HEADER FeatureBuffer, IN ULONG Length, IN FEATURE_NUMBER Feature)
 
NTSTATUS NTAPI CdRomGetConfiguration (IN PDEVICE_OBJECT Fdo, OUT PGET_CONFIGURATION_HEADER *Buffer, OUT PULONG BytesReturned, IN FEATURE_NUMBER StartingFeature, IN ULONG RequestedType)
 
VOID NTAPI CdRomUpdateMmcDriveCapabilities (IN PDEVICE_OBJECT Fdo, IN PVOID Context)
 
VOID NTAPI CdRomFindProfileInProfiles (IN PFEATURE_DATA_PROFILE_LIST ProfileHeader, IN FEATURE_PROFILE_TYPE ProfileToFind, OUT PBOOLEAN Exists)
 
NTSTATUS NTAPI CdRomAllocateMmcResources (IN PDEVICE_OBJECT Fdo)
 
VOID NTAPI CdRomDeAllocateMmcResources (IN PDEVICE_OBJECT Fdo)
 
VOID NTAPI CdromFakePartitionInfo (IN PCOMMON_DEVICE_EXTENSION CommonExtension, IN PIRP Irp)
 
VOID NTAPI CdRomInterpretReadCapacity (IN PDEVICE_OBJECT Fdo, IN PREAD_CAPACITY_DATA ReadCapacityBuffer)
 
NTSTATUS NTAPI CdRomShutdownFlushCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIRP Context)
 
VOID NTAPI CdRompFlushDelayedList (IN PDEVICE_OBJECT Fdo, IN PCDROM_MMC_EXTENSION MmcData, IN NTSTATUS Status, IN BOOLEAN CalledFromWorkItem)
 

Variables

CLASSPNP_SCAN_FOR_SPECIAL_INFO CdromHackItems []
 

Macro Definition Documentation

◆ ANY_SECTOR

#define ANY_SECTOR   0

Definition at line 307 of file cdrom.h.

◆ BAIL_OUT

#define BAIL_OUT (   Irp)
Value:
DebugPrint((2, "Cdrom: [%p] Bailing with status " \
" %lx at line %x file %s\n", \
(Irp), (Irp)->IoStatus.Status, \
__LINE__, __FILE__))
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
_In_ PIRP Irp
Definition: csq.h:116
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23

Definition at line 362 of file cdrom.h.

◆ CD_DA_SECTOR

#define CD_DA_SECTOR   1

Definition at line 308 of file cdrom.h.

◆ CDROM_DRIVER_EXTENSION_ID

#define CDROM_DRIVER_EXTENSION_ID   CdRomAddDevice

Definition at line 141 of file cdrom.h.

◆ CDROM_GET_CONFIGURATION_TIMEOUT

#define CDROM_GET_CONFIGURATION_TIMEOUT   (0x4)

Definition at line 54 of file cdrom.h.

◆ CDROM_HACK_BAD_GET_CONFIG_SUPPORT

#define CDROM_HACK_BAD_GET_CONFIG_SUPPORT   (0x00000100)

Definition at line 64 of file cdrom.h.

◆ CDROM_HACK_DEC_RRD

#define CDROM_HACK_DEC_RRD   (0x00000001)

Definition at line 56 of file cdrom.h.

◆ CDROM_HACK_FORCE_READ_CD_DETECTION

#define CDROM_HACK_FORCE_READ_CD_DETECTION   (0x00000200)

Definition at line 65 of file cdrom.h.

◆ CDROM_HACK_FUJITSU_FMCD_10x

#define CDROM_HACK_FUJITSU_FMCD_10x   (0x00000002)

Definition at line 57 of file cdrom.h.

◆ CDROM_HACK_HITACHI_1750

#define CDROM_HACK_HITACHI_1750   (0x00000004)

Definition at line 58 of file cdrom.h.

◆ CDROM_HACK_HITACHI_GD_2000

#define CDROM_HACK_HITACHI_GD_2000   (0x00000008)

Definition at line 59 of file cdrom.h.

◆ CDROM_HACK_INVALID_FLAGS

#define CDROM_HACK_INVALID_FLAGS   (~CDROM_HACK_VALID_FLAGS)

Definition at line 70 of file cdrom.h.

◆ CDROM_HACK_LOCKED_PAGES

#define CDROM_HACK_LOCKED_PAGES   (0x80000000)

Definition at line 67 of file cdrom.h.

◆ CDROM_HACK_NEC_CDDA

#define CDROM_HACK_NEC_CDDA   (0x00000040)

Definition at line 62 of file cdrom.h.

◆ CDROM_HACK_PLEXTOR_CDDA

#define CDROM_HACK_PLEXTOR_CDDA   (0x00000080)

Definition at line 63 of file cdrom.h.

◆ CDROM_HACK_READ_CD_SUPPORTED

#define CDROM_HACK_READ_CD_SUPPORTED   (0x00000400)

Definition at line 66 of file cdrom.h.

◆ CDROM_HACK_TOSHIBA_SD_W1101

#define CDROM_HACK_TOSHIBA_SD_W1101   (0x00000010)

Definition at line 60 of file cdrom.h.

◆ CDROM_HACK_TOSHIBA_XM_3xx

#define CDROM_HACK_TOSHIBA_XM_3xx   (0x00000020)

Definition at line 61 of file cdrom.h.

◆ CDROM_HACK_VALID_FLAGS

#define CDROM_HACK_VALID_FLAGS   (0x000007ff)

Definition at line 69 of file cdrom.h.

◆ CDROM_NON_MMC_DRIVE_NAME

#define CDROM_NON_MMC_DRIVE_NAME   (L"NonMmc")

Definition at line 352 of file cdrom.h.

◆ CDROM_READ_CD_NAME

#define CDROM_READ_CD_NAME   (L"ReadCD")

Definition at line 351 of file cdrom.h.

◆ CDROM_SRB_LIST_SIZE

#define CDROM_SRB_LIST_SIZE   4

Definition at line 275 of file cdrom.h.

◆ CDROM_SUBKEY_NAME

#define CDROM_SUBKEY_NAME   (L"CdRom")

Definition at line 350 of file cdrom.h.

◆ CDROM_TAG_DC_EVENT

#define CDROM_TAG_DC_EVENT   'ECcS'

Definition at line 322 of file cdrom.h.

◆ CDROM_TAG_DEC_ERROR

#define CDROM_TAG_DEC_ERROR   'dCcS'

Definition at line 337 of file cdrom.h.

◆ CDROM_TAG_DISK_GEOM

#define CDROM_TAG_DISK_GEOM   'GCcS'

Definition at line 324 of file cdrom.h.

◆ CDROM_TAG_FEATURE

#define CDROM_TAG_FEATURE   'FCcS'

Definition at line 323 of file cdrom.h.

◆ CDROM_TAG_GET_CONFIG

#define CDROM_TAG_GET_CONFIG   'cCcS'

Definition at line 321 of file cdrom.h.

◆ CDROM_TAG_HITACHI_ERROR

#define CDROM_TAG_HITACHI_ERROR   'HCcS'

Definition at line 325 of file cdrom.h.

◆ CDROM_TAG_MODE_DATA

#define CDROM_TAG_MODE_DATA   'MCcS'

Definition at line 330 of file cdrom.h.

◆ CDROM_TAG_PLAY_ACTIVE

#define CDROM_TAG_PLAY_ACTIVE   'pCcS'

Definition at line 332 of file cdrom.h.

◆ CDROM_TAG_POWER_IRP

#define CDROM_TAG_POWER_IRP   'iCcS'

Definition at line 327 of file cdrom.h.

◆ CDROM_TAG_RAW

#define CDROM_TAG_RAW   'RCcS'

Definition at line 334 of file cdrom.h.

◆ CDROM_TAG_READ_CAP

#define CDROM_TAG_READ_CAP   'PCcS'

Definition at line 331 of file cdrom.h.

◆ CDROM_TAG_SENSE_INFO

#define CDROM_TAG_SENSE_INFO   'ICcS'

Definition at line 326 of file cdrom.h.

◆ CDROM_TAG_SRB

#define CDROM_TAG_SRB   'SCcS'

Definition at line 328 of file cdrom.h.

◆ CDROM_TAG_STRINGS

#define CDROM_TAG_STRINGS   'sCcS'

Definition at line 329 of file cdrom.h.

◆ CDROM_TAG_SUB_Q

#define CDROM_TAG_SUB_Q   'QCcS'

Definition at line 333 of file cdrom.h.

◆ CDROM_TAG_TOC

#define CDROM_TAG_TOC   'TCcS'

Definition at line 335 of file cdrom.h.

◆ CDROM_TAG_TOSHIBA_ERROR

#define CDROM_TAG_TOSHIBA_ERROR   'tCcS'

Definition at line 336 of file cdrom.h.

◆ CDROM_TAG_UPDATE_CAP

#define CDROM_TAG_UPDATE_CAP   'UCcS'

Definition at line 338 of file cdrom.h.

◆ CDROM_TAG_VOLUME

#define CDROM_TAG_VOLUME   'VCcS'

Definition at line 339 of file cdrom.h.

◆ CDROM_TAG_VOLUME_INT

#define CDROM_TAG_VOLUME_INT   'vCcS'

Definition at line 340 of file cdrom.h.

◆ CdromMmcUpdateComplete

#define CdromMmcUpdateComplete   0

Definition at line 116 of file cdrom.h.

◆ CdromMmcUpdateRequired

#define CdromMmcUpdateRequired   1

Definition at line 117 of file cdrom.h.

◆ CdromMmcUpdateStarted

#define CdromMmcUpdateStarted   2

Definition at line 118 of file cdrom.h.

◆ COOKED_SECTOR_SIZE

#define COOKED_SECTOR_SIZE   2048

Definition at line 274 of file cdrom.h.

◆ DEC_TO_BCD

#define DEC_TO_BCD (   x)    (((x / 10) << 4) + (x % 10))

Definition at line 289 of file cdrom.h.

◆ DEVICE_EXTENSION_SIZE

#define DEVICE_EXTENSION_SIZE   sizeof(FUNCTIONAL_DEVICE_EXTENSION) + sizeof(CDROM_DATA)

Definition at line 268 of file cdrom.h.

◆ DVD_CURRENT_REGION

#define DVD_CURRENT_REGION   (L"DvdR")

Definition at line 357 of file cdrom.h.

◆ DVD_DEFAULT_REGION

#define DVD_DEFAULT_REGION   (L"DefaultDvdRegion")

Definition at line 356 of file cdrom.h.

◆ DVD_MAX_REGION

#define DVD_MAX_REGION   8

Definition at line 360 of file cdrom.h.

◆ DVD_MAX_REGION_RESET_COUNT

#define DVD_MAX_REGION_RESET_COUNT   2

Definition at line 359 of file cdrom.h.

◆ DVD_REGION_RESET_COUNT

#define DVD_REGION_RESET_COUNT   (L"DvdRCnt")

Definition at line 358 of file cdrom.h.

◆ DVD_TAG_DVD_REGION

#define DVD_TAG_DVD_REGION   'tVcS'

Definition at line 346 of file cdrom.h.

◆ DVD_TAG_READ_KEY

#define DVD_TAG_READ_KEY   'kVcS'

Definition at line 343 of file cdrom.h.

◆ DVD_TAG_READ_STRUCTURE

#define DVD_TAG_READ_STRUCTURE   'SVcS'

Definition at line 342 of file cdrom.h.

◆ DVD_TAG_RPC2_CHECK

#define DVD_TAG_RPC2_CHECK   'sVcS'

Definition at line 345 of file cdrom.h.

◆ DVD_TAG_SECURITY

#define DVD_TAG_SECURITY   'XVcS'

Definition at line 347 of file cdrom.h.

◆ DVD_TAG_SEND_KEY

#define DVD_TAG_SEND_KEY   'KVcS'

Definition at line 344 of file cdrom.h.

◆ FORM2_MODE1_SECTOR

#define FORM2_MODE1_SECTOR   4

Definition at line 311 of file cdrom.h.

◆ FORM2_MODE2_SECTOR

#define FORM2_MODE2_SECTOR   5

Definition at line 312 of file cdrom.h.

◆ HITACHI_MODE_DATA_SIZE

#define HITACHI_MODE_DATA_SIZE   12

Definition at line 271 of file cdrom.h.

◆ LBA_TO_MSF

#define LBA_TO_MSF (   Lba,
  Minutes,
  Seconds,
  Frames 
)
Value:
{ \
(Minutes) = (UCHAR)(Lba / (60 * 75)); \
(Seconds) = (UCHAR)((Lba % (60 * 75)) / 75); \
(Frames) = (UCHAR)((Lba % (60 * 75)) % 75); \
}
unsigned char UCHAR
Definition: xmlstorage.h:181

Definition at line 282 of file cdrom.h.

◆ MAX_COPY_PROTECT_AGID

#define MAX_COPY_PROTECT_AGID   4

Definition at line 314 of file cdrom.h.

◆ MODE_DATA_SIZE

#define MODE_DATA_SIZE   64

Definition at line 272 of file cdrom.h.

◆ MSF_TO_LBA

#define MSF_TO_LBA (   Minutes,
  Seconds,
  Frames 
)    (ULONG)((60 * 75 * (Minutes)) + (75 * (Seconds)) + ((Frames) - 150))

Definition at line 279 of file cdrom.h.

◆ PLAY_ACTIVE

#define PLAY_ACTIVE (   x)    (((PCDROM_DATA)(x->CommonExtension.DriverData))->PlayActive)

Definition at line 277 of file cdrom.h.

◆ RAW_SECTOR_SIZE

#define RAW_SECTOR_SIZE   2352

Definition at line 273 of file cdrom.h.

◆ SCSI_CDROM_TIMEOUT

#define SCSI_CDROM_TIMEOUT   10

Definition at line 269 of file cdrom.h.

◆ SCSI_CHANGER_BONUS_TIMEOUT

#define SCSI_CHANGER_BONUS_TIMEOUT   10

Definition at line 270 of file cdrom.h.

◆ XA_NEC_CDDA

#define XA_NEC_CDDA   0x80

Definition at line 301 of file cdrom.h.

◆ XA_NOT_SUPPORTED

#define XA_NOT_SUPPORTED   0x10

Definition at line 298 of file cdrom.h.

◆ XA_PLEXTOR_CDDA

#define XA_PLEXTOR_CDDA   0x40

Definition at line 300 of file cdrom.h.

◆ XA_USE_10_BYTE

#define XA_USE_10_BYTE   0x02

Definition at line 296 of file cdrom.h.

◆ XA_USE_6_BYTE

#define XA_USE_6_BYTE   0x01

Definition at line 295 of file cdrom.h.

◆ XA_USE_READ_CD

#define XA_USE_READ_CD   0x20

Definition at line 299 of file cdrom.h.

◆ YELLOW_MODE1_SECTOR

#define YELLOW_MODE1_SECTOR   2

Definition at line 309 of file cdrom.h.

◆ YELLOW_MODE2_SECTOR

#define YELLOW_MODE2_SECTOR   3

Definition at line 310 of file cdrom.h.

Typedef Documentation

◆ CDROM_DATA

◆ CDROM_DRIVER_EXTENSION

◆ CDROM_MMC_EXTENSION

◆ ERROR_RECOVERY_DATA

◆ ERROR_RECOVERY_DATA10

◆ PCDROM_DATA

◆ PCDROM_DRIVER_EXTENSION

◆ PCDROM_MMC_EXTENSION

◆ PERROR_RECOVERY_DATA

◆ PERROR_RECOVERY_DATA10

◆ PXA_CONTEXT

◆ XA_CONTEXT

Enumeration Type Documentation

◆ CdromError

Enumerator
CdromDebugError 
CdromDebugWarning 
CdromDebugTrace 
CdromDebugInfo 
CdromDebugFeatures 

Definition at line 40 of file cdrom.h.

40  {
41  CdromDebugError = 0, // always printed
42  CdromDebugWarning = 1, // set bit 0x00000001 in nt!kd_cdrom_mask
43  CdromDebugTrace = 2, // set bit 0x00000002 in nt!kd_cdrom_mask
44  CdromDebugInfo = 3, // set bit 0x00000004 in nt!kd_cdrom_mask
45 #if 0
46  CdromDebug = z, // set bit 0x00000000 in nt!kd_cdrom_mask
47  CdromDebug = z, // set bit 0x00000000 in nt!kd_cdrom_mask
48  CdromDebug = z, // set bit 0x00000000 in nt!kd_cdrom_mask
49  CdromDebug = z, // set bit 0x00000000 in nt!kd_cdrom_mask
50 #endif
51  CdromDebugFeatures = 32 // set bit 0x80000000 in nt!kd_cdrom_mask
52 }CdromError;
GLdouble GLdouble z
Definition: glext.h:5874
CdromError
Definition: cdrom.h:40

Function Documentation

◆ CdRomAddDevice()

NTSTATUS NTAPI CdRomAddDevice ( IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT  Pdo 
)

Definition at line 183 of file cdrom.c.

208 {
210 
211  PAGED_CODE();
212 
213  //
214  // Get the address of the count of the number of cdroms already initialized.
215  //
216  DbgPrint("add device\n");
217 
220 
221  //
222  // Note: this always increments driver extension counter
223  // it will eventually wrap, and fail additions
224  // if an existing cdrom has the given number.
225  // so unlikely that we won't even bother considering
226  // this case, since the cure is quite likely worse
227  // than the symptoms.
228  //
229 
230  if(NT_SUCCESS(status)) {
231 
232  //
233  // keep track of the total number of active cdroms in IoGet(),
234  // as some programs use this to determine when they have found
235  // all the cdroms in the system.
236  //
237 
238  TraceLog((CdromDebugTrace, "CDROM.SYS Add succeeded\n"));
240 
241  } else {
242 
244  "CDROM.SYS Add failed! %x\n", status));
245 
246  }
247 
248  return status;
249 }
#define DbgPrint
Definition: loader.c:25
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
#define PAGED_CODE()
Definition: video.h:57
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define TraceLog(x)
Definition: trace.h:14
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI CdRomCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: cdrom.c:253
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by DriverEntry().

◆ CdRomAllocateMmcResources()

NTSTATUS NTAPI CdRomAllocateMmcResources ( IN PDEVICE_OBJECT  Fdo)

Definition at line 1369 of file mmc.c.

1372 {
1373  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
1374  PCDROM_DATA cddata = commonExtension->DriverData;
1375  PCDROM_MMC_EXTENSION mmcData = &cddata->Mmc;
1376  PIO_STACK_LOCATION irpStack;
1377  NTSTATUS status;
1378 
1379  ASSERT(mmcData->CapabilitiesWorkItem == NULL);
1380  ASSERT(mmcData->CapabilitiesIrp == NULL);
1381  ASSERT(mmcData->CapabilitiesMdl == NULL);
1382  ASSERT(mmcData->CapabilitiesBuffer == NULL);
1383  ASSERT(mmcData->CapabilitiesBufferSize == 0);
1384 
1386  &mmcData->CapabilitiesBuffer,
1387  &mmcData->CapabilitiesBufferSize,
1390  if (!NT_SUCCESS(status)) {
1391  ASSERT(mmcData->CapabilitiesBuffer == NULL);
1392  ASSERT(mmcData->CapabilitiesBufferSize == 0);
1393  return status;
1394  }
1395  ASSERT(mmcData->CapabilitiesBuffer != NULL);
1396  ASSERT(mmcData->CapabilitiesBufferSize != 0);
1397 
1398  mmcData->CapabilitiesMdl = IoAllocateMdl(mmcData->CapabilitiesBuffer,
1399  mmcData->CapabilitiesBufferSize,
1400  FALSE, FALSE, NULL);
1401  if (mmcData->CapabilitiesMdl == NULL) {
1402  ExFreePool(mmcData->CapabilitiesBuffer);
1403  mmcData->CapabilitiesBufferSize = 0;
1405  }
1406 
1407 
1408  mmcData->CapabilitiesIrp = IoAllocateIrp(Fdo->StackSize + 2, FALSE);
1409  if (mmcData->CapabilitiesIrp == NULL) {
1410  IoFreeMdl(mmcData->CapabilitiesMdl);
1411  ExFreePool(mmcData->CapabilitiesBuffer);
1412  mmcData->CapabilitiesBufferSize = 0;
1414  }
1415 
1416  mmcData->CapabilitiesWorkItem = IoAllocateWorkItem(Fdo);
1417  if (mmcData->CapabilitiesWorkItem == NULL) {
1418  IoFreeIrp(mmcData->CapabilitiesIrp);
1419  IoFreeMdl(mmcData->CapabilitiesMdl);
1420  ExFreePool(mmcData->CapabilitiesBuffer);
1421  mmcData->CapabilitiesBufferSize = 0;
1423  }
1424 
1425  //
1426  // everything has been allocated, so now prepare it all....
1427  //
1428 
1431  KeInitializeSpinLock(&mmcData->DelayedLock);
1432 
1433  //
1434  // use the extra stack for internal bookkeeping
1435  //
1437  irpStack = IoGetCurrentIrpStackLocation(mmcData->CapabilitiesIrp);
1438  irpStack->Parameters.Others.Argument1 = Fdo;
1439  irpStack->Parameters.Others.Argument2 = mmcData->CapabilitiesBuffer;
1440  irpStack->Parameters.Others.Argument3 = &(mmcData->CapabilitiesSrb);
1441  // arg 4 is the retry count
1442 
1443  //
1444  // set the completion event to FALSE for now
1445  //
1446 
1449  return STATUS_SUCCESS;
1450 
1451 }
NTSTATUS NTAPI CdRomGetConfiguration(IN PDEVICE_OBJECT Fdo, OUT PGET_CONFIGURATION_HEADER *Buffer, OUT PULONG BytesReturned, IN FEATURE_NUMBER StartingFeature, IN ULONG RequestedType)
Definition: mmc.c:292
KEVENT CapabilitiesEvent
Definition: cdrom.h:135
PMDL CapabilitiesMdl
Definition: cdrom.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
LONG NTSTATUS
Definition: precomp.h:26
PIO_WORKITEM CapabilitiesWorkItem
Definition: cdrom.h:130
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
SCSI_REQUEST_BLOCK CapabilitiesSrb
Definition: cdrom.h:136
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL
Definition: ntddmmc.h:15
ULONG CapabilitiesBufferSize
Definition: cdrom.h:134
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
SLIST_HEADER DelayedIrps
Definition: cdrom.h:127
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:157
KSPIN_LOCK DelayedLock
Definition: cdrom.h:128
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define ExInitializeSListHead
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
PGET_CONFIGURATION_HEADER CapabilitiesBuffer
Definition: cdrom.h:133
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
PIRP CapabilitiesIrp
Definition: cdrom.h:131
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by CdRomInitDevice().

◆ CdRomClassIoctlCompletion()

NTSTATUS NTAPI CdRomClassIoctlCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 7322 of file cdrom.c.

7349 {
7350  PKEVENT syncEvent = (PKEVENT) Context;
7351 
7352  DebugPrint((2, "CdRomClassIoctlCompletion: setting event for irp %#08lx\n",
7353  Irp
7354  ));
7355 
7356  KeSetEvent(syncEvent, IO_DISK_INCREMENT, FALSE);
7357 
7359 }
struct _KEVENT * PKEVENT
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23

Referenced by CdRomDeviceControlDispatch().

◆ CdRomCompleteIrpAndStartNextPacketSafely()

static VOID CdRomCompleteIrpAndStartNextPacketSafely ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
inlinestatic

Definition at line 407 of file cdrom.h.

411 {
412  UCHAR uniqueAddress;
413  KIRQL oldIrql = KeGetCurrentIrql();
414 
415  ClassAcquireRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
418 
419  if (oldIrql > DISPATCH_LEVEL) {
420  ASSERT(!"Cannot call IoStartNextPacket at raised IRQL!");
421  } else if (oldIrql < DISPATCH_LEVEL) {
423  } else { // (oldIrql == DISPATCH_LEVEL)
424  NOTHING;
425  }
426 
428 
429  if (oldIrql > DISPATCH_LEVEL) {
430  ASSERT(!"Cannot call IoStartNextPacket at raised IRQL!");
431  } else if (oldIrql < DISPATCH_LEVEL) {
432  KeLowerIrql(oldIrql);
433  } else { // (oldIrql == DISPATCH_LEVEL)
434  NOTHING;
435  }
436 
437  ClassReleaseRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
438 
439 
440  return;
441 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
_In_ PIRP Irp
Definition: csq.h:116
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define NOTHING
Definition: env_spec_w32.h:461
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define IO_CD_ROM_INCREMENT
Definition: iotypes.h:567
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847

Referenced by CdRomDeviceControlCompletion(), CdRomDeviceControlDvdSendKey(), CdRomDeviceControlDvdStartSessionReadKey(), CdromFakePartitionInfo(), CdRomSetVolumeIntermediateCompletion(), CdRomShutdownFlushCompletion(), CdRomStartIo(), CdRomSwitchModeCompletion(), CdRomUpdateCapacity(), and CdRomUpdateGeometryCompletion().

◆ CdRomCreateDeviceObject()

NTSTATUS NTAPI CdRomCreateDeviceObject ( IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT  Pdo 
)

Definition at line 253 of file cdrom.c.

279 {
280  UCHAR ntNameBuffer[64];
281  //STRING ntNameString;
283 
284  PDEVICE_OBJECT lowerDevice = NULL;
285  PDEVICE_OBJECT deviceObject = NULL;
286  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
287  PCDROM_DATA cdData = NULL;
288  PCDROM_DRIVER_EXTENSION driverExtension = NULL;
289  ULONG deviceNumber;
290 
291  //CCHAR dosNameBuffer[64];
292  //CCHAR deviceNameBuffer[64];
293  //STRING deviceNameString;
294  //STRING dosString;
295  //UNICODE_STRING dosUnicodeString;
296  //UNICODE_STRING unicodeString;
297 
298  PAGED_CODE();
299 
300  //
301  // Claim the device. Note that any errors after this
302  // will goto the generic handler, where the device will
303  // be released.
304  //
305 
307 
308  status = ClassClaimDevice(lowerDevice, FALSE);
309 
310  if(!NT_SUCCESS(status)) {
311 
312  //
313  // Someone already had this device - we're in trouble
314  //
315 
316  ObDereferenceObject(lowerDevice);
317  return status;
318  }
319 
320  //
321  // Create device object for this device by first getting a unique name
322  // for the device and then creating it.
323  //
324 
325  driverExtension = IoGetDriverObjectExtension(DriverObject,
327  ASSERT(driverExtension != NULL);
328 
329  //
330  // InterlockedCdRomCounter is biased by 1.
331  //
332 
333  deviceNumber = InterlockedIncrement(&driverExtension->InterlockedCdRomCounter) - 1;
334  sprintf(ntNameBuffer, "\\Device\\CdRom%d", deviceNumber);
335 
336 
338  ntNameBuffer,
340  TRUE,
341  &deviceObject);
342 
343  if (!NT_SUCCESS(status)) {
345  "CreateCdRomDeviceObjects: Can not create device %s\n",
346  ntNameBuffer));
347 
348  goto CreateCdRomDeviceObjectExit;
349  }
350 
351  //
352  // Indicate that IRPs should include MDLs.
353  //
354 
355  SET_FLAG(deviceObject->Flags, DO_DIRECT_IO);
356 
357  fdoExtension = deviceObject->DeviceExtension;
358 
359  //
360  // Back pointer to device object.
361  //
362 
363  fdoExtension->CommonExtension.DeviceObject = deviceObject;
364 
365  //
366  // This is the physical device.
367  //
368 
369  fdoExtension->CommonExtension.PartitionZeroExtension = fdoExtension;
370 
371  //
372  // Initialize lock count to zero. The lock count is used to
373  // disable the ejection mechanism when media is mounted.
374  //
375 
376  fdoExtension->LockCount = 0;
377 
378  //
379  // Save system cdrom number
380  //
381 
382  fdoExtension->DeviceNumber = deviceNumber;
383 
384  //
385  // Set the alignment requirements for the device based on the
386  // host adapter requirements
387  //
388 
389  if (lowerDevice->AlignmentRequirement > deviceObject->AlignmentRequirement) {
390  deviceObject->AlignmentRequirement = lowerDevice->AlignmentRequirement;
391  }
392 
393  //
394  // Save the device descriptors
395  //
396 
397  fdoExtension->AdapterDescriptor = NULL;
398 
399  fdoExtension->DeviceDescriptor = NULL;
400 
401  //
402  // Clear the SrbFlags and disable synchronous transfers
403  //
404 
406 
407  //
408  // Finally, attach to the PDO
409  //
410 
411  fdoExtension->LowerPdo = PhysicalDeviceObject;
412 
413  fdoExtension->CommonExtension.LowerDeviceObject =
415 
416  if(fdoExtension->CommonExtension.LowerDeviceObject == NULL) {
417 
418  //
419  // Uh - oh, we couldn't attach
420  // cleanup and return
421  //
422 
424  goto CreateCdRomDeviceObjectExit;
425  }
426 
427  //
428  // CdRom uses an extra stack location for synchronizing it's start io
429  // routine
430  //
431 
432  deviceObject->StackSize++;
433 
434  //
435  // cdData is used a few times below
436  //
437 
438  cdData = fdoExtension->CommonExtension.DriverData;
439 
440  //
441  // For NTMS to be able to easily determine drives-drv. letter matches.
442  //
443 
444  status = CdRomCreateWellKnownName( deviceObject );
445 
446  if (!NT_SUCCESS(status)) {
448  "CdromCreateDeviceObjects: unable to create symbolic "
449  "link for device %wZ\n", &fdoExtension->CommonExtension.DeviceName));
451  "CdromCreateDeviceObjects: (non-fatal error)\n"));
452  }
453 
454  ClassUpdateInformationInRegistry(deviceObject, "CdRom",
455  fdoExtension->DeviceNumber, NULL, 0);
456 
457  //
458  // from above IoGetAttachedDeviceReference
459  //
460 
461  ObDereferenceObject(lowerDevice);
462 
463  //
464  // need to init timerlist here in case a remove occurs
465  // without a start, since we check the list is empty on remove.
466  //
467 
468  cdData->DelayedRetryIrp = NULL;
469  cdData->DelayedRetryInterval = 0;
470 
471  //
472  // need this to be initialized for RPC Phase 1 drives (rpc0)
473  //
474 
475  KeInitializeMutex(&cdData->Rpc0RegionMutex, 0);
476 
477  //
478  // The device is initialized properly - mark it as such.
479  //
480 
481  CLEAR_FLAG(deviceObject->Flags, DO_DEVICE_INITIALIZING);
482 
483  return(STATUS_SUCCESS);
484 
485 CreateCdRomDeviceObjectExit:
486 
487  //
488  // Release the device since an error occured.
489  //
490 
491  // ClassClaimDevice(PortDeviceObject,
492  // LunInfo,
493  // TRUE,
494  // NULL);
495 
496  //
497  // from above IoGetAttachedDeviceReference
498  //
499 
500  ObDereferenceObject(lowerDevice);
501 
502  if (deviceObject != NULL) {
503  IoDeleteDevice(deviceObject);
504  }
505 
506  return status;
507 
508 } // end CreateCdRomDeviceObject()
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
#define PAGED_CODE()
Definition: video.h:57
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define sprintf(buf, format,...)
Definition: sprintf.c:55
PDEVICE_OBJECT DeviceObject
Definition: kstypes.h:153
#define CDROM_DRIVER_EXTENSION_ID
Definition: cdrom.h:141
ULONG DelayedRetryInterval
Definition: cdrom.h:209
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
#define CLEAR_FLAG(Flags, Bit)
Definition: classpnp.h:155
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, IN PCCHAR ObjectNameBuffer, IN PDEVICE_OBJECT LowerDevice, IN BOOLEAN IsFdo, IN OUT PDEVICE_OBJECT *DeviceObject)
Definition: class.c:5687
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define TraceLog(x)
Definition: trace.h:14
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KMUTEX Rpc0RegionMutex
Definition: cdrom.h:251
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:699
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:698
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
PIRP DelayedRetryIrp
Definition: cdrom.h:207
NTSTATUS NTAPI CdRomCreateWellKnownName(IN PDEVICE_OBJECT DeviceObject)
Definition: cdrom.c:5620
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:697
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
NTSTATUS NTAPI ClassClaimDevice(IN PDEVICE_OBJECT LowerDeviceObject, IN BOOLEAN Release)
Definition: class.c:5985
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define InterlockedIncrement
Definition: armddk.h:53
ULONG InterlockedCdRomCounter
Definition: cdrom.h:112
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI ClassUpdateInformationInRegistry(IN PDEVICE_OBJECT Fdo, IN PCHAR DeviceName, IN ULONG DeviceNumber, IN PINQUIRYDATA InquiryData, IN ULONG InquiryDataLength)
Definition: class.c:7322
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by CdRomAddDevice().

◆ CdRomCreateNamedEvent()

VOID NTAPI CdRomCreateNamedEvent ( IN PFUNCTIONAL_DEVICE_EXTENSION  DeviceExtension,
IN ULONG  DeviceNumber 
)

◆ CdRomCreateWellKnownName()

NTSTATUS NTAPI CdRomCreateWellKnownName ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 5620 of file cdrom.c.

5642 {
5645  PCDROM_DATA cdromData = commonExtension->DriverData;
5646 
5647  UNICODE_STRING unicodeLinkName;
5648  WCHAR wideLinkName[64];
5649  PWCHAR savedName;
5650 
5651  LONG cdromNumber = fdoExtension->DeviceNumber;
5652 
5653  NTSTATUS status;
5654 
5655  //
5656  // if already linked, assert then return
5657  //
5658 
5659  if (cdromData->WellKnownName.Buffer != NULL) {
5660 
5662  "CdRomCreateWellKnownName: link already exists %p\n",
5663  cdromData->WellKnownName.Buffer));
5664  ASSERT(FALSE);
5665  return STATUS_UNSUCCESSFUL;
5666 
5667  }
5668 
5669  //
5670  // find an unused CdRomNN to link to
5671  //
5672 
5673  do {
5674 
5675  swprintf(wideLinkName, L"\\DosDevices\\CdRom%d", cdromNumber);
5676  RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
5677  status = IoCreateSymbolicLink(&unicodeLinkName,
5678  &(commonExtension->DeviceName));
5679 
5680  cdromNumber++;
5681 
5682  } while((status == STATUS_OBJECT_NAME_COLLISION) ||
5684 
5685  if (!NT_SUCCESS(status)) {
5686 
5688  "CdRomCreateWellKnownName: Error %lx linking %wZ to "
5689  "device %wZ\n",
5690  status,
5691  &unicodeLinkName,
5692  &(commonExtension->DeviceName)));
5693  return status;
5694 
5695  }
5696 
5698  "CdRomCreateWellKnownName: successfully linked %wZ "
5699  "to device %wZ\n",
5700  &unicodeLinkName,
5701  &(commonExtension->DeviceName)));
5702 
5703  //
5704  // Save away the symbolic link name in the driver data block. We need
5705  // it so we can delete the link when the device is removed.
5706  //
5707 
5708  savedName = ExAllocatePoolWithTag(PagedPool,
5709  unicodeLinkName.MaximumLength,
5711 
5712  if (savedName == NULL) {
5713  IoDeleteSymbolicLink(&unicodeLinkName);
5715  }
5716 
5717  RtlCopyMemory(savedName,
5718  unicodeLinkName.Buffer,
5719  unicodeLinkName.MaximumLength);
5720 
5721  RtlInitUnicodeString(&(cdromData->WellKnownName), savedName);
5722 
5723  //
5724  // the name was saved and the link created
5725  //
5726 
5727  return STATUS_SUCCESS;
5728 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
UNICODE_STRING WellKnownName
Definition: cdrom.h:231
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
long LONG
Definition: pedump.c:60
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
UNICODE_STRING DeviceName
Definition: classpnp.h:591
#define TraceLog(x)
Definition: trace.h:14
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define CDROM_TAG_STRINGS
Definition: cdrom.h:329
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by CdRomCreateDeviceObject().

◆ CdRomDeAllocateMmcResources()

VOID NTAPI CdRomDeAllocateMmcResources ( IN PDEVICE_OBJECT  Fdo)

Definition at line 1335 of file mmc.c.

1338 {
1339  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
1340  PCDROM_DATA cddata = commonExtension->DriverData;
1341  PCDROM_MMC_EXTENSION mmcData = &cddata->Mmc;
1342  //NTSTATUS status;
1343 
1344  if (mmcData->CapabilitiesWorkItem) {
1346  mmcData->CapabilitiesWorkItem = NULL;
1347  }
1348  if (mmcData->CapabilitiesIrp) {
1349  IoFreeIrp(mmcData->CapabilitiesIrp);
1350  mmcData->CapabilitiesIrp = NULL;
1351  }
1352  if (mmcData->CapabilitiesMdl) {
1353  IoFreeMdl(mmcData->CapabilitiesMdl);
1354  mmcData->CapabilitiesMdl = NULL;
1355  }
1356  if (mmcData->CapabilitiesBuffer) {
1357  ExFreePool(mmcData->CapabilitiesBuffer);
1358  mmcData->CapabilitiesBuffer = NULL;
1359  }
1360  mmcData->CapabilitiesBuffer = 0;
1361  mmcData->IsMmc = FALSE;
1362  mmcData->WriteAllowed = FALSE;
1363 
1364  return;
1365 }
PMDL CapabilitiesMdl
Definition: cdrom.h:132
PIO_WORKITEM CapabilitiesWorkItem
Definition: cdrom.h:130
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
smooth NULL
Definition: ftsmooth.c:416
ULONG WriteAllowed
Definition: cdrom.h:123
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:157
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PGET_CONFIGURATION_HEADER CapabilitiesBuffer
Definition: cdrom.h:133
PIRP CapabilitiesIrp
Definition: cdrom.h:131
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by CdRomInitDevice(), and CdRomRemoveDevice().

◆ CdRomDeleteWellKnownName()

VOID NTAPI CdRomDeleteWellKnownName ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 5732 of file cdrom.c.

5735 {
5737  PCDROM_DATA cdromData = commonExtension->DriverData;
5738 
5739  if(cdromData->WellKnownName.Buffer != NULL) {
5740 
5741  IoDeleteSymbolicLink(&(cdromData->WellKnownName));
5742  ExFreePool(cdromData->WellKnownName.Buffer);
5743  cdromData->WellKnownName.Buffer = NULL;
5744  cdromData->WellKnownName.Length = 0;
5745  cdromData->WellKnownName.MaximumLength = 0;
5746 
5747  }
5748  return;
5749 }
UNICODE_STRING WellKnownName
Definition: cdrom.h:231
USHORT MaximumLength
Definition: env_spec_w32.h:370
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by CdRomRemoveDevice().

◆ CdRomDeviceControlCompletion()

NTSTATUS NTAPI CdRomDeviceControlCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 2996 of file cdrom.c.

3001 {
3002  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3003  PDEVICE_EXTENSION physicalExtension = deviceExtension->PhysicalDevice->DeviceExtension;
3005  PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension + 1);
3006  BOOLEAN use6Byte = cdData->XAFlags & XA_USE_6_BYTE;
3007  PIO_STACK_LOCATION realIrpStack;
3008  PIO_STACK_LOCATION realIrpNextStack;
3010  PIRP realIrp = NULL;
3011  NTSTATUS status;
3012  BOOLEAN retry;
3013 
3014  //
3015  // Extract the 'real' irp from the irpstack.
3016  //
3017 
3018  realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
3019  realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
3020  realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
3021 
3022  //
3023  // Check SRB status for success of completing request.
3024  //
3025 
3026  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
3027 
3028  DebugPrint((2,
3029  "CdRomDeviceControlCompletion: Irp %lx, Srb %lx Real Irp %lx Status %lx\n",
3030  Irp,
3031  srb,
3032  realIrp,
3033  srb->SrbStatus));
3034 
3035  //
3036  // Release the queue if it is frozen.
3037  //
3038 
3039  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
3040  DebugPrint((2, "CdRomDeviceControlCompletion: Releasing Queue\n"));
3042  }
3043 
3044 
3046  srb,
3047  irpStack->MajorFunction,
3048  irpStack->Parameters.DeviceIoControl.IoControlCode,
3049  MAXIMUM_RETRIES - ((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
3050  &status);
3051 
3052  DebugPrint((2, "CdRomDeviceControlCompletion: IRP will %sbe retried\n",
3053  (retry ? "" : "not ")));
3054 
3055  //
3056  // Some of the Device Controls need special cases on non-Success status's.
3057  //
3058 
3059  if (realIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
3060  if ((realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_GET_LAST_SESSION) ||
3061  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_READ_TOC) ||
3062  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_GET_CONTROL) ||
3063  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_GET_VOLUME)) {
3064 
3065  if (status == STATUS_DATA_OVERRUN) {
3067  retry = FALSE;
3068  }
3069  }
3070 
3071  if (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_READ_Q_CHANNEL) {
3072  PLAY_ACTIVE(deviceExtension) = FALSE;
3073  }
3074  }
3075 
3076  //
3077  // If the status is verified required and the this request
3078  // should bypass verify required then retry the request.
3079  //
3080 
3081  if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
3083 
3084  if (((realIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) ||
3085  (realIrpStack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)) &&
3086  (realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_CHECK_VERIFY)) {
3087 
3089  if (srb->DataBuffer) {
3090  ExFreePool(srb->DataBuffer);
3091  }
3092  ExFreePool(srb);
3093  if (Irp->MdlAddress) {
3094  IoFreeMdl(Irp->MdlAddress);
3095  }
3096 
3097  IoFreeIrp(Irp);
3098 
3099  //
3100  // Update the geometry information, as the media could have changed.
3101  // The completion routine for this will complete the real irp and start
3102  // the next packet.
3103  //
3104 
3105  status = CdRomUpdateCapacity(deviceExtension,realIrp, NULL);
3106  DebugPrint((2, "CdRomDeviceControlCompletion: [%lx] CdRomUpdateCapacity completed with status %lx\n", realIrp, status));
3108 
3110 
3111  } else {
3112 
3114  retry = TRUE;
3115  }
3116 
3117  }
3118 
3119  if (retry && (realIrpNextStack->Parameters.Others.Argument1 = (PVOID)((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1-1))) {
3120 
3121 
3122  if (((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
3123 
3124  //
3125  // Retry request.
3126  //
3127 
3128  DebugPrint((1, "Retry request %lx - Calling StartIo\n", Irp));
3129 
3130 
3132  if (srb->DataBuffer) {
3133  ExFreePool(srb->DataBuffer);
3134  }
3135  ExFreePool(srb);
3136  if (Irp->MdlAddress) {
3137  IoFreeMdl(Irp->MdlAddress);
3138  }
3139 
3140  IoFreeIrp(Irp);
3141 
3142  //
3143  // Call StartIo directly since IoStartNextPacket hasn't been called,
3144  // the serialisation is still intact.
3145  //
3146 
3147  ScsiCdRomStartIo(DeviceObject, realIrp);
3149 
3150  }
3151 
3152  //
3153  // Exhausted retries. Fall through and complete the request with the appropriate status.
3154  //
3155 
3156  }
3157  } else {
3158 
3159  //
3160  // Set status for successful request.
3161  //
3162 
3164  }
3165 
3166  if (NT_SUCCESS(status)) {
3167 
3168  switch (realIrpStack->Parameters.DeviceIoControl.IoControlCode) {
3169 
3171 
3172  PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
3173  ULONG lastSector;
3174  ULONG bps;
3175  ULONG lastBit;
3176  ULONG tmp;
3177 
3178  //
3179  // Swizzle bytes from Read Capacity and translate into
3180  // the necessary geometry information in the device extension.
3181  //
3182 
3183  tmp = readCapacityBuffer->BytesPerBlock;
3184  ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
3185  ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
3186  ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
3187  ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
3188 
3189  //
3190  // Insure that bps is a power of 2.
3191  // This corrects a problem with the HP 4020i CDR where it
3192  // returns an incorrect number for bytes per sector.
3193  //
3194 
3195  if (!bps) {
3196  bps = 2048;
3197  } else {
3198  lastBit = (ULONG) -1;
3199  while (bps) {
3200  lastBit++;
3201  bps = bps >> 1;
3202  }
3203 
3204  bps = 1 << lastBit;
3205  }
3206  deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
3207 
3208  DebugPrint((2,
3209  "CdRomDeviceControlCompletion: Calculated bps %#x\n",
3210  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
3211 
3212  //
3213  // Copy last sector in reverse byte order.
3214  //
3215 
3216  tmp = readCapacityBuffer->LogicalBlockAddress;
3217  ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
3218  ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
3219  ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
3220  ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
3221 
3222  //
3223  // Calculate sector to byte shift.
3224  //
3225 
3226  WHICH_BIT(bps, deviceExtension->SectorShift);
3227 
3228  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is %d\n",
3229  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
3230 
3231  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is %d\n",
3232  lastSector + 1));
3233 
3234  //
3235  // Calculate media capacity in bytes.
3236  //
3237 
3238  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
3239 
3240  //
3241  // Calculate number of cylinders.
3242  //
3243 
3244  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(32 * 64));
3245 
3246  deviceExtension->PartitionLength.QuadPart =
3247  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
3248 
3249  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
3250 
3251  //
3252  // This device supports removable media.
3253  //
3254 
3255  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
3256 
3257  } else {
3258 
3259  //
3260  // Assume media type is fixed disk.
3261  //
3262 
3263  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
3264  }
3265 
3266  //
3267  // Assume sectors per track are 32;
3268  //
3269 
3270  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
3271 
3272  //
3273  // Assume tracks per cylinder (number of heads) is 64.
3274  //
3275 
3276  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
3277 
3278  //
3279  // Copy the device extension's geometry info into the user buffer.
3280  //
3281 
3282  RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
3283  &deviceExtension->PartitionLength,
3284  sizeof(GET_LENGTH_INFORMATION));
3285 
3286  //
3287  // update information field.
3288  //
3289 
3290  realIrp->IoStatus.Information = sizeof(DISK_GEOMETRY);
3291  break;
3292  }
3293 
3296 
3297  PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
3298  ULONG lastSector;
3299  ULONG bps;
3300  ULONG lastBit;
3301  ULONG tmp;
3302  PDISK_GEOMETRY_EX geometryEx;
3303 
3304  //
3305  // Swizzle bytes from Read Capacity and translate into
3306  // the necessary geometry information in the device extension.
3307  //
3308 
3309  tmp = readCapacityBuffer->BytesPerBlock;
3310  ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
3311  ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
3312  ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
3313  ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
3314 
3315  //
3316  // Insure that bps is a power of 2.
3317  // This corrects a problem with the HP 4020i CDR where it
3318  // returns an incorrect number for bytes per sector.
3319  //
3320 
3321  if (!bps) {
3322  bps = 2048;
3323  } else {
3324  lastBit = (ULONG) -1;
3325  while (bps) {
3326  lastBit++;
3327  bps = bps >> 1;
3328  }
3329 
3330  bps = 1 << lastBit;
3331  }
3332  deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
3333 
3334  DebugPrint((2,
3335  "CdRomDeviceControlCompletion: Calculated bps %#x\n",
3336  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
3337 
3338  //
3339  // Copy last sector in reverse byte order.
3340  //
3341 
3342  tmp = readCapacityBuffer->LogicalBlockAddress;
3343  ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
3344  ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
3345  ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
3346  ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
3347 
3348  //
3349  // Calculate sector to byte shift.
3350  //
3351 
3352  WHICH_BIT(bps, deviceExtension->SectorShift);
3353 
3354  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is %d\n",
3355  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
3356 
3357  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is %d\n",
3358  lastSector + 1));
3359 
3360  //
3361  // Calculate media capacity in bytes.
3362  //
3363 
3364  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
3365 
3366  //
3367  // Calculate number of cylinders.
3368  //
3369 
3370  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(32 * 64));
3371 
3372  deviceExtension->PartitionLength.QuadPart =
3373  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
3374 
3375  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
3376 
3377  //
3378  // This device supports removable media.
3379  //
3380 
3381  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
3382 
3383  } else {
3384 
3385  //
3386  // Assume media type is fixed disk.
3387  //
3388 
3389  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
3390  }
3391 
3392  //
3393  // Assume sectors per track are 32;
3394  //
3395 
3396  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
3397 
3398  //
3399  // Assume tracks per cylinder (number of heads) is 64.
3400  //
3401 
3402  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
3403 
3404  //
3405  // Copy the device extension's geometry info into the user buffer.
3406  //
3407 
3408  geometryEx = realIrp->AssociatedIrp.SystemBuffer;
3409  RtlMoveMemory(&geometryEx->Geometry,
3410  &deviceExtension->DiskGeometry->Geometry,
3411  sizeof(DISK_GEOMETRY));
3412 
3413  //
3414  // Copy the extended information
3415  //
3416 
3417  geometryEx->DiskSize = deviceExtension->PartitionLength;
3418 
3419  //
3420  // update information field.
3421  //
3422 
3423  realIrp->IoStatus.Information = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
3424  break;
3425  }
3426 
3429 
3430  PREAD_CAPACITY_DATA readCapacityBuffer = srb->DataBuffer;
3431  ULONG lastSector;
3432  ULONG bps;
3433  ULONG lastBit;
3434  ULONG tmp;
3435 
3436  //
3437  // Swizzle bytes from Read Capacity and translate into
3438  // the necessary geometry information in the device extension.
3439  //
3440 
3441  tmp = readCapacityBuffer->BytesPerBlock;
3442  ((PFOUR_BYTE)&bps)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
3443  ((PFOUR_BYTE)&bps)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
3444  ((PFOUR_BYTE)&bps)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
3445  ((PFOUR_BYTE)&bps)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
3446 
3447  //
3448  // Insure that bps is a power of 2.
3449  // This corrects a problem with the HP 4020i CDR where it
3450  // returns an incorrect number for bytes per sector.
3451  //
3452 
3453  if (!bps) {
3454  bps = 2048;
3455  } else {
3456  lastBit = (ULONG) -1;
3457  while (bps) {
3458  lastBit++;
3459  bps = bps >> 1;
3460  }
3461 
3462  bps = 1 << lastBit;
3463  }
3464  deviceExtension->DiskGeometry->Geometry.BytesPerSector = bps;
3465 
3466  DebugPrint((2,
3467  "CdRomDeviceControlCompletion: Calculated bps %#x\n",
3468  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
3469 
3470  //
3471  // Copy last sector in reverse byte order.
3472  //
3473 
3474  tmp = readCapacityBuffer->LogicalBlockAddress;
3475  ((PFOUR_BYTE)&lastSector)->Byte0 = ((PFOUR_BYTE)&tmp)->Byte3;
3476  ((PFOUR_BYTE)&lastSector)->Byte1 = ((PFOUR_BYTE)&tmp)->Byte2;
3477  ((PFOUR_BYTE)&lastSector)->Byte2 = ((PFOUR_BYTE)&tmp)->Byte1;
3478  ((PFOUR_BYTE)&lastSector)->Byte3 = ((PFOUR_BYTE)&tmp)->Byte0;
3479 
3480  //
3481  // Calculate sector to byte shift.
3482  //
3483 
3484  WHICH_BIT(bps, deviceExtension->SectorShift);
3485 
3486  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is %d\n",
3487  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
3488 
3489  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is %d\n",
3490  lastSector + 1));
3491 
3492  //
3493  // Calculate media capacity in bytes.
3494  //
3495 
3496  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
3497 
3498  //
3499  // Calculate number of cylinders.
3500  //
3501 
3502  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(32 * 64));
3503 
3504  deviceExtension->PartitionLength.QuadPart =
3505  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
3506 
3507  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
3508 
3509  //
3510  // This device supports removable media.
3511  //
3512 
3513  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
3514 
3515  } else {
3516 
3517  //
3518  // Assume media type is fixed disk.
3519  //
3520 
3521  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
3522  }
3523 
3524  //
3525  // Assume sectors per track are 32;
3526  //
3527 
3528  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
3529 
3530  //
3531  // Assume tracks per cylinder (number of heads) is 64.
3532  //
3533 
3534  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
3535 
3536  //
3537  // Copy the device extension's geometry info into the user buffer.
3538  //
3539 
3540  RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
3541  deviceExtension->DiskGeometry,
3542  sizeof(DISK_GEOMETRY));
3543 
3544  //
3545  // update information field.
3546  //
3547 
3548  realIrp->IoStatus.Information = sizeof(DISK_GEOMETRY);
3549  break;
3550  }
3551 
3553 
3554  if((realIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_CHECK_VERIFY) &&
3555  (realIrpStack->Parameters.DeviceIoControl.OutputBufferLength)) {
3556 
3557  *((PULONG)realIrp->AssociatedIrp.SystemBuffer) =
3558  physicalExtension->MediaChangeCount;
3559  realIrp->IoStatus.Information = sizeof(ULONG);
3560  } else {
3561  realIrp->IoStatus.Information = 0;
3562  }
3563 
3564  DebugPrint((2, "CdRomDeviceControlCompletion: [%lx] completing CHECK_VERIFY buddy irp %lx\n", realIrp, Irp));
3565  break;
3566 
3568  case IOCTL_CDROM_READ_TOC: {
3569 
3570  PCDROM_TOC toc = srb->DataBuffer;
3571 
3572  //
3573  // Copy the device extension's geometry info into the user buffer.
3574  //
3575 
3576  RtlMoveMemory(realIrp->AssociatedIrp.SystemBuffer,
3577  toc,
3578  srb->DataTransferLength);
3579 
3580  //
3581  // update information field.
3582  //
3583 
3584  realIrp->IoStatus.Information = srb->DataTransferLength;
3585  break;
3586  }
3587 
3589 
3590  PLAY_ACTIVE(deviceExtension) = TRUE;
3591 
3592  break;
3593 
3595 
3596  PSUB_Q_CHANNEL_DATA userChannelData = realIrp->AssociatedIrp.SystemBuffer;
3597 #if DBG
3598  PCDROM_SUB_Q_DATA_FORMAT inputBuffer = realIrp->AssociatedIrp.SystemBuffer;
3599 #endif
3600  PSUB_Q_CHANNEL_DATA subQPtr = srb->DataBuffer;
3601 
3602 #if DBG
3603  switch( inputBuffer->Format ) {
3604 
3606  DebugPrint((2,"CdRomDeviceControlCompletion: Audio Status is %u\n", subQPtr->CurrentPosition.Header.AudioStatus ));
3607  DebugPrint((2,"CdRomDeviceControlCompletion: ADR = 0x%x\n", subQPtr->CurrentPosition.ADR ));
3608  DebugPrint((2,"CdRomDeviceControlCompletion: Control = 0x%x\n", subQPtr->CurrentPosition.Control ));
3609  DebugPrint((2,"CdRomDeviceControlCompletion: Track = %u\n", subQPtr->CurrentPosition.TrackNumber ));
3610  DebugPrint((2,"CdRomDeviceControlCompletion: Index = %u\n", subQPtr->CurrentPosition.IndexNumber ));
3611  DebugPrint((2,"CdRomDeviceControlCompletion: Absolute Address = %x\n", *((PULONG)subQPtr->CurrentPosition.AbsoluteAddress) ));
3612  DebugPrint((2,"CdRomDeviceControlCompletion: Relative Address = %x\n", *((PULONG)subQPtr->CurrentPosition.TrackRelativeAddress) ));
3613  break;
3614 
3616  DebugPrint((2,"CdRomDeviceControlCompletion: Audio Status is %u\n", subQPtr->MediaCatalog.Header.AudioStatus ));
3617  DebugPrint((2,"CdRomDeviceControlCompletion: Mcval is %u\n", subQPtr->MediaCatalog.Mcval ));
3618  break;
3619 
3621  DebugPrint((2,"CdRomDeviceControlCompletion: Audio Status is %u\n", subQPtr->TrackIsrc.Header.AudioStatus ));
3622  DebugPrint((2,"CdRomDeviceControlCompletion: Tcval is %u\n", subQPtr->TrackIsrc.Tcval ));
3623  break;
3624 
3625  }
3626 #endif
3627 
3628  //
3629  // Update the play active status.
3630  //
3631 
3633 
3634  PLAY_ACTIVE(deviceExtension) = TRUE;
3635 
3636  } else {
3637 
3638  PLAY_ACTIVE(deviceExtension) = FALSE;
3639 
3640  }
3641 
3642  //
3643  // Check if output buffer is large enough to contain
3644  // the data.
3645  //
3646 
3647  if (realIrpStack->Parameters.DeviceIoControl.OutputBufferLength <
3648  srb->DataTransferLength) {
3649 
3650  srb->DataTransferLength =
3651  realIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
3652  }
3653 
3654  //
3655  // Copy our buffer into users.
3656  //
3657 
3658  RtlMoveMemory(userChannelData,
3659  subQPtr,
3660  srb->DataTransferLength);
3661 
3662  realIrp->IoStatus.Information = srb->DataTransferLength;
3663  break;
3664  }
3665 
3667 
3668  PLAY_ACTIVE(deviceExtension) = FALSE;
3669  realIrp->IoStatus.Information = 0;
3670  break;
3671 
3673 
3674  realIrp->IoStatus.Information = 0;
3675  break;
3676 
3678 
3679  realIrp->IoStatus.Information = 0;
3680  break;
3681 
3683 
3684  PLAY_ACTIVE(deviceExtension) = FALSE;
3685 
3686  realIrp->IoStatus.Information = 0;
3687  break;
3688 
3689  case IOCTL_CDROM_GET_CONTROL: {
3690 
3691  PCDROM_AUDIO_CONTROL audioControl = srb->DataBuffer;
3692  PAUDIO_OUTPUT audioOutput;
3693  ULONG bytesTransferred;
3694 
3695  audioOutput = ScsiClassFindModePage((PCHAR)audioControl,
3696  srb->DataTransferLength,
3698  use6Byte);
3699  //
3700  // Verify the page is as big as expected.
3701  //
3702 
3703  bytesTransferred = (PCHAR) audioOutput - (PCHAR) audioControl +
3704  sizeof(AUDIO_OUTPUT);
3705 
3706  if (audioOutput != NULL &&
3707  srb->DataTransferLength >= bytesTransferred) {
3708 
3709  audioControl->LbaFormat = audioOutput->LbaFormat;
3710 
3711  audioControl->LogicalBlocksPerSecond =
3712  (audioOutput->LogicalBlocksPerSecond[0] << (UCHAR)8) |
3713  audioOutput->LogicalBlocksPerSecond[1];
3714 
3715  realIrp->IoStatus.Information = sizeof(CDROM_AUDIO_CONTROL);
3716 
3717  } else {
3718  realIrp->IoStatus.Information = 0;
3720  }
3721  break;
3722  }
3723 
3724  case IOCTL_CDROM_GET_VOLUME: {
3725 
3726  PAUDIO_OUTPUT audioOutput;
3727  PVOLUME_CONTROL volumeControl = srb->DataBuffer;
3728  ULONG i,bytesTransferred;
3729 
3730  audioOutput = ScsiClassFindModePage((PCHAR)volumeControl,
3731  srb->DataTransferLength,
3733  use6Byte);
3734 
3735  //
3736  // Verify the page is as big as expected.
3737  //
3738 
3739  bytesTransferred = (PCHAR) audioOutput - (PCHAR) volumeControl +
3740  sizeof(AUDIO_OUTPUT);
3741 
3742  if (audioOutput != NULL &&
3743  srb->DataTransferLength >= bytesTransferred) {
3744 
3745  for (i=0; i<4; i++) {
3746  volumeControl->PortVolume[i] =
3747  audioOutput->PortOutput[i].Volume;
3748  }
3749 
3750  //
3751  // Set bytes transferred in IRP.
3752  //
3753 
3754  realIrp->IoStatus.Information = sizeof(VOLUME_CONTROL);
3755 
3756  } else {
3757  realIrp->IoStatus.Information = 0;
3759  }
3760 
3761  break;
3762  }
3763 
3765 
3766  realIrp->IoStatus.Information = sizeof(VOLUME_CONTROL);
3767  break;
3768 
3769  default:
3770 
3771  ASSERT(FALSE);
3772  realIrp->IoStatus.Information = 0;
3774 
3775  } // end switch()
3776  }
3777 
3778  //
3779  // Deallocate srb and sense buffer.
3780  //
3781 
3782  if (srb) {
3783  if (srb->DataBuffer) {
3784  ExFreePool(srb->DataBuffer);
3785  }
3786  if (srb->SenseInfoBuffer) {
3788  }
3789  ExFreePool(srb);
3790  }
3791 
3792  if (realIrp->PendingReturned) {
3793  IoMarkIrpPending(realIrp);
3794  }
3795 
3796  if (Irp->MdlAddress) {
3797  IoFreeMdl(Irp->MdlAddress);
3798  }
3799 
3800  IoFreeIrp(Irp);
3801 
3802  //
3803  // Set status in completing IRP.
3804  //
3805 
3806  realIrp->IoStatus.Status = status;
3807 
3808  //
3809  // Set the hard error if necessary.
3810  //
3811 
3813 
3814  //
3815  // Store DeviceObject for filesystem, and clear
3816  // in IoStatus.Information field.
3817  //
3818 
3819  DebugPrint((1, "CdRomDeviceCompletion - Setting Hard Error on realIrp %lx\n",
3820  realIrp));
3822  realIrp->IoStatus.Information = 0;
3823  }
3824 
3826 
3828 
3830 }
signed char * PCHAR
Definition: retypes.h:7
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
struct _FOUR_BYTE * PFOUR_BYTE
#define IOCTL_CDROM_GET_CONTROL
Definition: ntddcdrm.h:43
#define TRUE
Definition: types.h:120
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
PVOID DataBuffer
Definition: srb.h:255
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:34
SUB_Q_HEADER Header
Definition: ntddcdrm.h:314
ULONG DataTransferLength
Definition: srb.h:253
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:52
#define CDROM_AUDIO_CONTROL_PAGE
Definition: scsi.h:728
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
ULONG LogicalBlockAddress
Definition: cdrw_hw.h:1471
VOID ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:938
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define WHICH_BIT(Data, Bit)
Definition: tools.h:80
UCHAR LbaFormat
Definition: scsi.h:2613
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID NTAPI ScsiCdRomStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cdrom.c:1495
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX
Definition: ntddcdrm.h:49
#define IOCTL_CDROM_SET_VOLUME
Definition: ntddcdrm.h:85
uint32_t ULONG_PTR
Definition: typedefs.h:63
LARGE_INTEGER DiskSize
Definition: ntdddisk.h:386
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _AUDIO_OUTPUT AUDIO_OUTPUT
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define IOCTL_CDROM_MEDIA_CATALOG
Definition: cdrw_usr.h:1355
PVOID NTAPI ScsiClassFindModePage(IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
Definition: class2.c:3295
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:91
DISK_GEOMETRY Geometry
Definition: ntdddisk.h:385
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:82
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:61
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define MAXIMUM_RETRIES
Definition: class2.h:14
#define AUDIO_STATUS_IN_PROGRESS
Definition: ntddcdrm.h:281
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
PORT_OUTPUT PortOutput[4]
Definition: scsi.h:2615
#define PCHAR
Definition: match.c:90
int64_t LONGLONG
Definition: typedefs.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:46
#define IOCTL_CDROM_GET_VOLUME
Definition: ntddcdrm.h:55
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
UCHAR Volume
Definition: scsi.h:2605
UCHAR AbsoluteAddress[4]
Definition: ntddcdrm.h:320
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
UCHAR PortVolume[4]
Definition: ntddcdrm.h:342
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2147
#define IOCTL_CDROM_PAUSE_AUDIO
Definition: ntddcdrm.h:58
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
SUB_Q_TRACK_ISRC TrackIsrc
Definition: ntddcdrm.h:327
#define IOCTL_CDROM_RESUME_AUDIO
Definition: ntddcdrm.h:79
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _DISK_GEOMETRY DISK_GEOMETRY
USHORT XAFlags
Definition: cdrom.c:82
SUB_Q_HEADER Header
Definition: ntddcdrm.h:303
UCHAR AudioStatus
Definition: ntddcdrm.h:289
SUB_Q_CURRENT_POSITION CurrentPosition
Definition: ntddcdrm.h:325
#define IOCTL_CDROM_TRACK_ISRC
Definition: cdrw_usr.h:1356
#define XA_USE_6_BYTE
Definition: cdrom.c:208
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
struct _CDROM_AUDIO_CONTROL CDROM_AUDIO_CONTROL
unsigned int * PULONG
Definition: retypes.h:1
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog
Definition: ntddcdrm.h:326
UCHAR TrackRelativeAddress[4]
Definition: ntddcdrm.h:321
PVOID SenseInfoBuffer
Definition: srb.h:256
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PVOID PIRP
Definition: usb.h:38
struct tagContext Context
Definition: acpixf.h:1030
unsigned int ULONG
Definition: retypes.h:1
#define PLAY_ACTIVE(DeviceExtension)
Definition: cdrom.c:190
NTSTATUS NTAPI CdRomUpdateCapacity(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP IrpToComplete, IN OPTIONAL PKEVENT IoctlEvent)
Definition: cdrom.c:7151
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:73
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:70
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
struct _VOLUME_CONTROL VOLUME_CONTROL
UCHAR LogicalBlocksPerSecond[2]
Definition: scsi.h:2614
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
USHORT LogicalBlocksPerSecond
Definition: ntddcdrm.h:338
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

Referenced by CdRomSetVolumeIntermediateCompletion().

◆ CdRomDeviceControlDispatch()

NTSTATUS NTAPI CdRomDeviceControlDispatch ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 45 of file ioctl.c.

66 {
69 
71  PIO_STACK_LOCATION nextStack;
72  PCDROM_DATA cdData = (PCDROM_DATA)(commonExtension->DriverData);
73 
74  //BOOLEAN use6Byte = TEST_FLAG(cdData->XAFlags, XA_USE_6_BYTE);
76  PCDB cdb = (PCDB)srb.Cdb;
77  //PVOID outputBuffer;
78  //ULONG bytesTransferred = 0;
80  //NTSTATUS status2;
81  KIRQL irql;
82 
83  ULONG ioctlCode;
84  ULONG baseCode;
85  ULONG functionCode;
86 
87 RetryControl:
88 
89  //
90  // Zero the SRB on stack.
91  //
92 
93  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
94 
95  Irp->IoStatus.Information = 0;
96 
97  //
98  // if this is a class driver ioctl then we need to change the base code
99  // to IOCTL_CDROM_BASE so that the switch statement can handle it.
100  //
101  // WARNING - currently the scsi class ioctl function codes are between
102  // 0x200 & 0x300. this routine depends on that fact
103  //
104 
105  ioctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
106  baseCode = ioctlCode >> 16;
107  functionCode = (ioctlCode & (~0xffffc003)) >> 2;
108 
110  "CdRomDeviceControl: Ioctl Code = %lx, Base Code = %lx,"
111  " Function Code = %lx\n",
112  ioctlCode,
113  baseCode,
114  functionCode
115  ));
116 
117  if((functionCode >= 0x200) && (functionCode <= 0x300)) {
118 
119  ioctlCode = (ioctlCode & 0x0000ffff) | CTL_CODE(IOCTL_CDROM_BASE, 0, 0, 0);
120 
122  "CdRomDeviceControl: Class Code - new ioctl code is %lx\n",
123  ioctlCode));
124 
125  irpStack->Parameters.DeviceIoControl.IoControlCode = ioctlCode;
126 
127  }
128 
129  switch (ioctlCode) {
130 
132 
133  PGET_MEDIA_TYPES mediaTypes = Irp->AssociatedIrp.SystemBuffer;
134  PDEVICE_MEDIA_INFO mediaInfo = &mediaTypes->MediaInfo[0];
135  ULONG sizeNeeded;
136 
137  sizeNeeded = sizeof(GET_MEDIA_TYPES);
138 
139  //
140  // IsMmc is static...
141  //
142 
143  if (cdData->Mmc.IsMmc) {
144  sizeNeeded += sizeof(DEVICE_MEDIA_INFO) * 1; // return two media types
145  }
146 
147  //
148  // Ensure that buffer is large enough.
149  //
150 
151  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
152  sizeNeeded) {
153 
154  //
155  // Buffer too small.
156  //
157 
158  Irp->IoStatus.Information = sizeNeeded;
160  break;
161  }
162 
163  RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, sizeNeeded);
164 
165  //
166  // ISSUE-2000/5/11-henrygab - need to update GET_MEDIA_TYPES_EX
167  //
168 
170 
171  mediaTypes->MediaInfoCount = 1;
172  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = CD_ROM;
173  mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
174  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_ONLY;
175  mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
176  mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
177  mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
178  mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
179 
180  if (cdData->Mmc.IsMmc) {
181 
182  //
183  // also report a removable disk
184  //
185  mediaTypes->MediaInfoCount += 1;
186 
187  mediaInfo++;
188  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = RemovableMedia;
189  mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
190  mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_WRITE;
191  mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
192  mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
193  mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
194  mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
195  mediaInfo--;
196 
197  }
198 
199  //
200  // Status will either be success, if media is present, or no media.
201  // It would be optimal to base from density code and medium type, but not all devices
202  // have values for these fields.
203  //
204 
205  //
206  // Send a TUR to determine if media is present.
207  //
208 
209  srb.CdbLength = 6;
210  cdb = (PCDB)srb.Cdb;
211  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
212 
213  //
214  // Set timeout value.
215  //
216 
217  srb.TimeOutValue = fdoExtension->TimeOutValue;
218 
220  &srb,
221  NULL,
222  0,
223  FALSE);
224 
225 
227  "CdRomDeviceControl: GET_MEDIA_TYPES status of TUR - %lx\n",
228  status));
229 
230  if (NT_SUCCESS(status)) {
231 
232  //
233  // set the disk's media as current if we can write to it.
234  //
235 
236  if (cdData->Mmc.IsMmc && cdData->Mmc.WriteAllowed) {
237 
238  mediaInfo++;
239  SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics,
241  mediaInfo--;
242 
243 
244  } else {
245 
246  SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics,
248 
249  }
250 
251  }
252 
253  Irp->IoStatus.Information = sizeNeeded;
255  break;
256  }
257 
258 
259  case IOCTL_CDROM_RAW_READ: {
260 
261  LARGE_INTEGER startingOffset;
262  ULONGLONG transferBytes;
263  ULONGLONG endOffset;
264  ULONGLONG mdlBytes;
265  //ULONG startingSector;
266  PRAW_READ_INFO rawReadInfo = (PRAW_READ_INFO)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
267 
268  //
269  // Ensure that XA reads are supported.
270  //
271 
272  if (TEST_FLAG(cdData->XAFlags, XA_NOT_SUPPORTED)) {
274  "CdRomDeviceControl: XA Reads not supported. Flags (%x)\n",
275  cdData->XAFlags));
277  break;
278  }
279 
280  //
281  // Check that ending sector is on disc and buffers are there and of
282  // correct size.
283  //
284 
285  if (rawReadInfo == NULL) {
286 
287  //
288  // Called from user space. Save the userbuffer in the
289  // Type3InputBuffer so we can reduce the number of code paths.
290  //
291 
292  irpStack->Parameters.DeviceIoControl.Type3InputBuffer =
293  Irp->AssociatedIrp.SystemBuffer;
294 
295  //
296  // Called from user space. Validate the buffers.
297  //
298 
299  rawReadInfo = (PRAW_READ_INFO)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
300 
301  if (rawReadInfo == NULL) {
302 
304  "CdRomDeviceControl: Invalid I/O parameters for "
305  "XA Read (No extent info\n"));
307  break;
308 
309  }
310 
311  if (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
312  sizeof(RAW_READ_INFO)) {
313 
315  "CdRomDeviceControl: Invalid I/O parameters for "
316  "XA Read (Invalid info buffer\n"));
318  break;
319 
320  }
321  }
322 
323  //
324  // if they don't request any data, just fail the request
325  //
326 
327  if (rawReadInfo->SectorCount == 0) {
328 
330  break;
331 
332  }
333 
334  startingOffset.QuadPart = rawReadInfo->DiskOffset.QuadPart;
335  /* startingSector = (ULONG)(rawReadInfo->DiskOffset.QuadPart >>
336  fdoExtension->SectorShift); */
337  transferBytes = (ULONGLONG)rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
338 
339  endOffset = (ULONGLONG)rawReadInfo->SectorCount * COOKED_SECTOR_SIZE;
340  endOffset += startingOffset.QuadPart;
341 
342  //
343  // check for overflows....
344  //
345 
346  if (transferBytes < (ULONGLONG)(rawReadInfo->SectorCount)) {
348  "CdRomDeviceControl: Invalid I/O parameters for XA "
349  "Read (TransferBytes Overflow)\n"));
351  break;
352  }
353  if (endOffset < (ULONGLONG)startingOffset.QuadPart) {
355  "CdRomDeviceControl: Invalid I/O parameters for XA "
356  "Read (EndingOffset Overflow)\n"));
358  break;
359  }
360  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
361  transferBytes) {
363  "CdRomDeviceControl: Invalid I/O parameters for XA "
364  "Read (Bad buffer size)\n"));
366  break;
367  }
368  if (endOffset > (ULONGLONG)commonExtension->PartitionLength.QuadPart) {
370  "CdRomDeviceControl: Invalid I/O parameters for XA "
371  "Read (Request Out of Bounds)\n"));
373  break;
374  }
375 
376  //
377  // cannot validate the MdlAddress, since it is not included in any
378  // other location per the DDK and file system calls.
379  //
380 
381  //
382  // validate the mdl describes at least the number of bytes
383  // requested from us.
384  //
385 
386  mdlBytes = (ULONGLONG)MmGetMdlByteCount(Irp->MdlAddress);
387  if (mdlBytes < transferBytes) {
389  "CdRomDeviceControl: Invalid MDL %s, Irp %p\n",
390  "size (5)", Irp));
392  break;
393  }
394 
395  //
396  // HACKHACK - REF #0001
397  // The retry count will be in this irp's IRP_MN function,
398  // as the new irp was freed, and we therefore cannot use
399  // this irp's next stack location for this function.
400  // This may be a good location to store this info for
401  // when we remove RAW_READ (mode switching), as we will
402  // no longer have the nextIrpStackLocation to play with
403  // when that occurs
404  //
405  // once XA_READ is removed, then this hack can also be
406  // removed.
407  //
408  irpStack->MinorFunction = MAXIMUM_RETRIES; // HACKHACK - REF #0001
409 
412 
413  return STATUS_PENDING;
414  }
415 
419  "CdRomDeviceControl: Get drive geometryEx\n"));
420  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
423  Irp->IoStatus.Information = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
424  break;
425  }
428  return STATUS_PENDING;
429  }
430 
433 
435  "CdRomDeviceControl: Get drive geometry\n"));
436 
437  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
438  sizeof( DISK_GEOMETRY ) ) {
439 
441  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
442  break;
443  }
444 
447 
448  return STATUS_PENDING;
449  }
450 
452 
453  PCDROM_READ_TOC_EX inputBuffer;
454 
457  break;
458  }
459 
460  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
461  sizeof(CDROM_READ_TOC_EX)) {
463  break;
464  }
465 
466  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
469  Irp->IoStatus.Information = MINIMUM_CDROM_READ_TOC_EX_SIZE;
470  break;
471  }
472 
473  if (irpStack->Parameters.Read.Length > ((USHORT)-1)) {
475  break;
476  }
477 
478  inputBuffer = Irp->AssociatedIrp.SystemBuffer;
479 
480  if ((inputBuffer->Reserved1 != 0) ||
481  (inputBuffer->Reserved2 != 0) ||
482  (inputBuffer->Reserved3 != 0)) {
484  break;
485  }
486 
487  //
488  // NOTE: when adding new formats, ensure that first two bytes
489  // specify the amount of additional data available.
490  //
491 
492  if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_TOC ) ||
493  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_FULL_TOC) ||
494  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_CDTEXT )) {
495 
496  // SessionTrack field is used
497 
498  } else
499  if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_SESSION) ||
500  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_PMA) ||
501  (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_ATIP)) {
502 
503  // SessionTrack field is reserved
504 
505  if (inputBuffer->SessionTrack != 0) {
507  break;
508  }
509 
510  } else {
512  break;
513  }
514 
517  return STATUS_PENDING;
518  }
519 
521 
522  //
523  // If the cd is playing music then reject this request.
524  //
525 
528  break;
529  }
530 
531  //
532  // Make sure the caller is requesting enough data to make this worth
533  // our while.
534  //
535 
536  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
537  sizeof(CDROM_TOC_SESSION_DATA)) {
538 
539  //
540  // they didn't request the entire TOC -- use _EX version
541  // for partial transfers and such.
542  //
543 
545  Irp->IoStatus.Information = sizeof(CDROM_TOC_SESSION_DATA);
546  break;
547  }
548 
551 
552  return STATUS_PENDING;
553  }
554 
555  case IOCTL_CDROM_READ_TOC: {
556 
557  //
558  // If the cd is playing music then reject this request.
559  //
560 
563  break;
564  }
565 
566  //
567  // Make sure the caller is requesting enough data to make this worth
568  // our while.
569  //
570 
571  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
572  sizeof(CDROM_TOC)) {
573 
574  //
575  // they didn't request the entire TOC -- use _EX version
576  // for partial transfers and such.
577  //
578 
580  Irp->IoStatus.Information = sizeof(CDROM_TOC);
581  break;
582  }
583 
586 
587  return STATUS_PENDING;
588  }
589 
591 
592  //
593  // Play Audio MSF
594  //
595 
597  "CdRomDeviceControl: Play audio MSF\n"));
598 
599  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
600  sizeof(CDROM_PLAY_AUDIO_MSF)) {
601 
602  //
603  // Indicate unsuccessful status.
604  //
605 
607  break;
608  }
609 
612 
613  return STATUS_PENDING;
614  }
615 
617 
618 
619  //
620  // Seek Audio MSF
621  //
622 
624  "CdRomDeviceControl: Seek audio MSF\n"));
625 
626  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
627  sizeof(CDROM_SEEK_AUDIO_MSF)) {
628 
629  //
630  // Indicate unsuccessful status.
631  //
632 
634  break;
635  }
636 
639  return STATUS_PENDING;
640 
641  }
642 
644 
645  //
646  // Pause audio
647  //
648 
650  "CdRomDeviceControl: Pause audio\n"));
651 
654 
655  return STATUS_PENDING;
656 
657  break;
658  }
659 
661 
662  //
663  // Resume audio
664  //
665 
667  "CdRomDeviceControl: Resume audio\n"));
668 
671 
672  return STATUS_PENDING;
673  }
674 
676 
677  PCDROM_SUB_Q_DATA_FORMAT inputBuffer =
678  Irp->AssociatedIrp.SystemBuffer;
679 
680  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
681  sizeof(CDROM_SUB_Q_DATA_FORMAT)) {
682 
684  break;
685  }
686 
687  //
688  // check for all valid types of request
689  //
690 
691  if (inputBuffer->Format != IOCTL_CDROM_CURRENT_POSITION &&
692  inputBuffer->Format != IOCTL_CDROM_MEDIA_CATALOG &&
693  inputBuffer->Format != IOCTL_CDROM_TRACK_ISRC ) {
695  Irp->IoStatus.Information = 0;
696  break;
697  }
698 
701 
702  return STATUS_PENDING;
703  }
704 
706 
708  "CdRomDeviceControl: Get audio control\n"));
709 
710  //
711  // Verify user buffer is large enough for the data.
712  //
713 
714  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
715  sizeof(CDROM_AUDIO_CONTROL)) {
716 
717  //
718  // Indicate unsuccessful status and no data transferred.
719  //
720 
722  Irp->IoStatus.Information = sizeof(CDROM_AUDIO_CONTROL);
723  break;
724 
725  }
726 
729 
730  return STATUS_PENDING;
731  }
732 
733  case IOCTL_CDROM_GET_VOLUME: {
734 
736  "CdRomDeviceControl: Get volume control\n"));
737 
738  //
739  // Verify user buffer is large enough for data.
740  //
741 
742  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
743  sizeof(VOLUME_CONTROL)) {
744 
745  //
746  // Indicate unsuccessful status and no data transferred.
747  //
748 
750  Irp->IoStatus.Information = sizeof(VOLUME_CONTROL);
751  break;
752 
753  }
754 
757 
758  return STATUS_PENDING;
759  }
760 
761  case IOCTL_CDROM_SET_VOLUME: {
762 
764  "CdRomDeviceControl: Set volume control\n"));
765 
766  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
767  sizeof(VOLUME_CONTROL)) {
768 
769  //
770  // Indicate unsuccessful status.
771  //
772 
774  break;
775 
776  }
777 
780 
781  return STATUS_PENDING;
782  }
783 
784  case IOCTL_CDROM_STOP_AUDIO: {
785 
786  //
787  // Stop play.
788  //
789 
791  "CdRomDeviceControl: Stop audio\n"));
792 
795 
796  return STATUS_PENDING;
797  }
798 
802 
804  "CdRomDeviceControl: [%p] Check Verify\n", Irp));
805 
806  if((irpStack->Parameters.DeviceIoControl.OutputBufferLength) &&
807  (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))) {
808 
810  "CdRomDeviceControl: Check Verify: media count "
811  "buffer too small\n"));
812 
814  Irp->IoStatus.Information = sizeof(ULONG);
815  break;
816  }
817 
820 
821  return STATUS_PENDING;
822  }
823 
825 
827  "DvdDeviceControl: [%p] IOCTL_DVD_READ_STRUCTURE\n", Irp));
828 
829  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
831  "DvdDeviceControl: License Failure\n"));
833  break;
834  }
835 
836  if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
837  //
838  // if currently in-progress, this will just return.
839  // prevents looping by doing that interlockedExchange()
840  //
842  "DvdDeviceControl: PickRegion() from "
843  "READ_STRUCTURE\n"));
845  }
846 
847 
848  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
849  sizeof(DVD_READ_STRUCTURE)) {
850 
852  "DvdDeviceControl - READ_STRUCTURE: input buffer "
853  "length too small (was %d should be %d)\n",
854  irpStack->Parameters.DeviceIoControl.InputBufferLength,
855  sizeof(DVD_READ_STRUCTURE)));
857  break;
858  }
859 
860  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
861  sizeof(READ_DVD_STRUCTURES_HEADER)) {
862 
864  "DvdDeviceControl - READ_STRUCTURE: output buffer "
865  "cannot hold header information\n"));
867  Irp->IoStatus.Information = sizeof(READ_DVD_STRUCTURES_HEADER);
868  break;
869  }
870 
871  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength >
872  MAXUSHORT) {
873 
874  //
875  // key length must fit in two bytes
876  //
878  "DvdDeviceControl - READ_STRUCTURE: output buffer "
879  "too large\n"));
881  break;
882  }
883 
886 
887  return STATUS_PENDING;
888  }
889 
891 
893  "DvdDeviceControl: [%p] IOCTL_DVD_START_SESSION\n", Irp));
894 
895  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
897  "DvdDeviceControl: License Failure\n"));
899  break;
900  }
901 
902  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
903  sizeof(DVD_SESSION_ID)) {
904 
906  "DvdDeviceControl: DVD_START_SESSION - output "
907  "buffer too small\n"));
909  Irp->IoStatus.Information = sizeof(DVD_SESSION_ID);
910  break;
911  }
912 
915 
916  return STATUS_PENDING;
917  }
918 
919  case IOCTL_DVD_SEND_KEY:
920  case IOCTL_DVD_SEND_KEY2: {
921 
922  PDVD_COPY_PROTECT_KEY key = Irp->AssociatedIrp.SystemBuffer;
923  //ULONG keyLength;
924 
926  "DvdDeviceControl: [%p] IOCTL_DVD_SEND_KEY\n", Irp));
927 
928  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
930  "DvdDeviceControl: License Failure\n"));
932  break;
933  }
934 
935  if((irpStack->Parameters.DeviceIoControl.InputBufferLength <
936  sizeof(DVD_COPY_PROTECT_KEY)) ||
937  (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
938  key->KeyLength)) {
939 
940  //
941  // Key is too small to have a header or the key length doesn't
942  // match the input buffer length. Key must be invalid
943  //
944 
946  "DvdDeviceControl: [%p] IOCTL_DVD_SEND_KEY - "
947  "key is too small or does not match KeyLength\n",
948  Irp));
950  break;
951  }
952 
953  //
954  // allow only certain key type (non-destructive) to go through
955  // IOCTL_DVD_SEND_KEY (which only requires READ access to the device
956  //
957  if (ioctlCode == IOCTL_DVD_SEND_KEY) {
958 
959  if ((key->KeyType != DvdChallengeKey) &&
960  (key->KeyType != DvdBusKey2) &&
961  (key->KeyType != DvdInvalidateAGID)) {
962 
964  break;
965  }
966  }
967 
968  if (cdData->DvdRpc0Device) {
969 
970  if (key->KeyType == DvdSetRpcKey) {
971 
972  PDVD_SET_RPC_KEY rpcKey = (PDVD_SET_RPC_KEY) key->KeyData;
973 
974  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
976 
978  break;
979  }
980 
981  //
982  // we have a request to set region code
983  // on a RPC0 device which doesn't support
984  // region coding.
985  //
986  // we have to fake it.
987  //
988 
990  &cdData->Rpc0RegionMutex,
991  UserRequest,
992  KernelMode,
993  FALSE,
994  NULL
995  );
996 
997  if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
998  //
999  // if currently in-progress, this will just return.
1000  // prevents looping by doing that interlockedExchange()
1001  //
1003  "DvdDeviceControl: PickRegion() from "
1004  "SEND_KEY\n"));
1006  }
1007 
1008  if (cdData->Rpc0SystemRegion == rpcKey->PreferredDriveRegionCode) {
1009 
1010  //
1011  // nothing to change
1012  //
1014  "DvdDeviceControl (%p) => not changing "
1015  "regions -- requesting current region\n",
1016  DeviceObject));
1018 
1019  } else if (cdData->Rpc0SystemRegionResetCount == 0) {
1020 
1021  //
1022  // not allowed to change it again
1023  //
1024 
1026  "DvdDeviceControl (%p) => no more region "
1027  "changes are allowed for this device\n",
1028  DeviceObject));
1030 
1031  } else {
1032 
1033  //ULONG i;
1034  UCHAR mask;
1035  ULONG bufferLen;
1036  PDVD_READ_STRUCTURE dvdReadStructure;
1037  PDVD_COPYRIGHT_DESCRIPTOR dvdCopyRight;
1038  IO_STATUS_BLOCK ioStatus;
1039  UCHAR mediaRegionData;
1040 
1041  mask = ~rpcKey->PreferredDriveRegionCode;
1042 
1043  if (CountOfSetBitsUChar(mask) != 1) {
1044 
1046  break;
1047  }
1048 
1049  //
1050  // this test will always be TRUE except during initial
1051  // automatic selection of the first region.
1052  //
1053 
1054  if (cdData->Rpc0SystemRegion != 0xff) {
1055 
1056  //
1057  // make sure we have a media in the drive with the same
1058  // region code if the drive is already has a region set
1059  //
1060 
1062  "DvdDeviceControl (%p) => Checking "
1063  "media region\n",
1064  DeviceObject));
1065 
1066  bufferLen = max(sizeof(DVD_DESCRIPTOR_HEADER) +
1067  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1068  sizeof(DVD_READ_STRUCTURE)
1069  );
1070 
1071  dvdReadStructure = (PDVD_READ_STRUCTURE)
1073  bufferLen,
1075 
1076  if (dvdReadStructure == NULL) {
1079  break;
1080  }
1081 
1082  dvdCopyRight = (PDVD_COPYRIGHT_DESCRIPTOR)
1083  ((PDVD_DESCRIPTOR_HEADER) dvdReadStructure)->Data;
1084 
1085  //
1086  // check to see if we have a DVD device
1087  //
1088 
1089  RtlZeroMemory (dvdReadStructure, bufferLen);
1090  dvdReadStructure->Format = DvdCopyrightDescriptor;
1091 
1092  //
1093  // Build a request for READ_KEY
1094  //
1097  DeviceObject,
1098  dvdReadStructure,
1099  sizeof(DVD_READ_STRUCTURE),
1100  sizeof(DVD_DESCRIPTOR_HEADER) +
1101  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1102  FALSE,
1103  &ioStatus);
1104 
1105  //
1106  // this is just to prevent bugs from creeping in
1107  // if status is not set later in development
1108  //
1109 
1110  status = ioStatus.Status;
1111 
1112  //
1113  // handle errors
1114  //
1115 
1116  if (!NT_SUCCESS(status)) {
1118  ExFreePool(dvdReadStructure);
1120  break;
1121  }
1122 
1123  //
1124  // save the mediaRegionData before freeing the
1125  // allocated memory
1126  //
1127 
1128  mediaRegionData =
1129  dvdCopyRight->RegionManagementInformation;
1130  ExFreePool(dvdReadStructure);
1131 
1133  "DvdDeviceControl (%p) => new mask is %x"
1134  " MediaRegionData is %x\n", DeviceObject,
1135  rpcKey->PreferredDriveRegionCode,
1136  mediaRegionData));
1137 
1138  //
1139  // the media region must match the requested region
1140  // for RPC0 drives for initial region selection
1141  //
1142 
1143  if (((UCHAR)~(mediaRegionData | rpcKey->PreferredDriveRegionCode)) == 0) {
1146  break;
1147  }
1148 
1149  }
1150 
1151  //
1152  // now try to set the region
1153  //
1154 
1156  "DvdDeviceControl (%p) => Soft-Setting "
1157  "region of RPC1 device to %x\n",
1158  DeviceObject,
1159  rpcKey->PreferredDriveRegionCode
1160  ));
1161 
1163  rpcKey->PreferredDriveRegionCode);
1164 
1165  if (!NT_SUCCESS(status)) {
1167  "DvdDeviceControl (%p) => Could not "
1168  "set region code (%x)\n",
1170  ));
1171  } else {
1172 
1174  "DvdDeviceControl (%p) => New region set "
1175  " for RPC1 drive\n", DeviceObject));
1176 
1177  //
1178  // if it worked, our extension is already updated.
1179  // release the mutex
1180  //
1181 
1182  DebugPrint ((4, "DvdDeviceControl (%p) => DVD current "
1183  "region bitmap 0x%x\n", DeviceObject,
1184  cdData->Rpc0SystemRegion));
1185  DebugPrint ((4, "DvdDeviceControl (%p) => DVD region "
1186  " reset Count 0x%x\n", DeviceObject,
1187  cdData->Rpc0SystemRegionResetCount));
1188  }
1189 
1190  }
1191 
1193  break;
1194  } // end of key->KeyType == DvdSetRpcKey
1195  } // end of Rpc0Device hacks
1196 
1199  return STATUS_PENDING;
1200  }
1201 
1202  case IOCTL_DVD_READ_KEY: {
1203 
1204  PDVD_COPY_PROTECT_KEY keyParameters = Irp->AssociatedIrp.SystemBuffer;
1205  ULONG keyLength;
1206 
1208  "DvdDeviceControl: [%p] IOCTL_DVD_READ_KEY\n", Irp));
1209 
1210  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
1212  "DvdDeviceControl: License Failure\n"));
1214  break;
1215  }
1216 
1217  if (cdData->DvdRpc0Device && cdData->Rpc0RetryRegistryCallback) {
1219  "DvdDeviceControl: PickRegion() from READ_KEY\n"));
1221  }
1222 
1223 
1224  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
1225  sizeof(DVD_COPY_PROTECT_KEY)) {
1226 
1228  "DvdDeviceControl: EstablishDriveKey - challenge "
1229  "key buffer too small\n"));
1230 
1232  break;
1233 
1234  }
1235 
1236 
1237  switch(keyParameters->KeyType) {
1238 
1239  case DvdChallengeKey:
1240  keyLength = DVD_CHALLENGE_KEY_LENGTH;
1241  break;
1242 
1243  case DvdBusKey1:
1244  case DvdBusKey2:
1245 
1246  keyLength = DVD_BUS_KEY_LENGTH;
1247  break;
1248 
1249  case DvdTitleKey:
1250  keyLength = DVD_TITLE_KEY_LENGTH;
1251  break;
1252 
1253  case DvdAsf:
1254  keyLength = DVD_ASF_LENGTH;
1255  break;
1256 
1257  case DvdDiskKey:
1258  keyLength = DVD_DISK_KEY_LENGTH;
1259  break;
1260 
1261  case DvdGetRpcKey:
1262  keyLength = DVD_RPC_KEY_LENGTH;
1263  break;
1264 
1265  default:
1266  keyLength = sizeof(DVD_COPY_PROTECT_KEY);
1267  break;
1268  }
1269 
1270  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1271  keyLength) {
1272 
1274  "DvdDeviceControl: EstablishDriveKey - output "
1275  "buffer too small\n"));
1277  Irp->IoStatus.Information = keyLength;
1278  break;
1279  }
1280 
1281  if (keyParameters->KeyType == DvdGetRpcKey) {
1282 
1284  }
1285 
1286  if ((keyParameters->KeyType == DvdGetRpcKey) &&
1287  (cdData->DvdRpc0Device)) {
1288 
1289  PDVD_RPC_KEY rpcKey;
1290  rpcKey = (PDVD_RPC_KEY)keyParameters->KeyData;
1291  RtlZeroMemory (rpcKey, sizeof (*rpcKey));
1292 
1294  &cdData->Rpc0RegionMutex,
1295  UserRequest,
1296  KernelMode,
1297  FALSE,
1298  NULL
1299  );
1300 
1301  //
1302  // make up the data
1303  //
1305  rpcKey->ManufacturerResetsAvailable = 0;
1306  if (cdData->Rpc0SystemRegion == 0xff) {
1307  rpcKey->TypeCode = 0;
1308  } else {
1309  rpcKey->TypeCode = 1;
1310  }
1311  rpcKey->RegionMask = (UCHAR) cdData->Rpc0SystemRegion;
1312  rpcKey->RpcScheme = 1;
1313 
1315  &cdData->Rpc0RegionMutex,
1316  FALSE
1317  );
1318 
1319  Irp->IoStatus.Information = DVD_RPC_KEY_LENGTH;
1321  break;
1322 
1323  } else if (keyParameters->KeyType == DvdDiskKey) {
1324 
1325  PDVD_COPY_PROTECT_KEY keyHeader;
1326  PDVD_READ_STRUCTURE readStructureRequest;
1327 
1328  //
1329  // Special case - build a request to get the dvd structure
1330  // so we can get the disk key.
1331  //
1332 
1333  //
1334  // save the key header so we can restore the interesting
1335  // parts later
1336  //
1337 
1338  keyHeader = ExAllocatePoolWithTag(NonPagedPool,
1339  sizeof(DVD_COPY_PROTECT_KEY),
1341 
1342  if(keyHeader == NULL) {
1343 
1344  //
1345  // Can't save the context so return an error
1346  //
1347 
1349  "DvdDeviceControl - READ_KEY: unable to "
1350  "allocate context\n"));
1352  break;
1353  }
1354 
1355  RtlCopyMemory(keyHeader,
1356  Irp->AssociatedIrp.SystemBuffer,
1357  sizeof(DVD_COPY_PROTECT_KEY));
1358 
1360 
1361  nextStack = IoGetNextIrpStackLocation(Irp);
1362 
1363  nextStack->Parameters.DeviceIoControl.IoControlCode =
1365 
1366  readStructureRequest = Irp->AssociatedIrp.SystemBuffer;
1367  readStructureRequest->Format = DvdDiskKeyDescriptor;
1368  readStructureRequest->BlockByteOffset.QuadPart = 0;
1369  readStructureRequest->LayerNumber = 0;
1370  readStructureRequest->SessionId = keyHeader->SessionId;
1371 
1372  nextStack->Parameters.DeviceIoControl.InputBufferLength =
1373  sizeof(DVD_READ_STRUCTURE);
1374 
1375  nextStack->Parameters.DeviceIoControl.OutputBufferLength =
1377 
1380  (PVOID) keyHeader,
1381  TRUE,
1382  TRUE,
1383  TRUE);
1384 
1385  {
1386  UCHAR uniqueAddress;
1387  ClassAcquireRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1389 
1391  IoCallDriver(commonExtension->DeviceObject, Irp);
1393 
1394  ClassReleaseRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1395  }
1396 
1397  return STATUS_PENDING;
1398 
1399  } else {
1400 
1403 
1404  }
1405  return STATUS_PENDING;
1406  }
1407 
1408  case IOCTL_DVD_END_SESSION: {
1409 
1410  PDVD_SESSION_ID sessionId = Irp->AssociatedIrp.SystemBuffer;
1411 
1413  "DvdDeviceControl: [%p] END_SESSION\n", Irp));
1414 
1415  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
1417  "DvdDeviceControl: License Failure\n"));
1419  break;
1420  }
1421 
1422  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
1423  sizeof(DVD_SESSION_ID)) {
1424 
1426  "DvdDeviceControl: EndSession - input buffer too "
1427  "small\n"));
1429  break;
1430  }
1431 
1433 
1434  if(*sessionId == DVD_END_ALL_SESSIONS) {
1435 
1437 
1438  if(status == STATUS_SUCCESS) {
1439 
1440  //
1441  // Just complete the request - it was never issued to the
1442  // lower device
1443  //
1444 
1445  break;
1446 
1447  } else {
1448 
1449  return STATUS_PENDING;
1450 
1451  }
1452  }
1453 
1455 
1456  return STATUS_PENDING;
1457  }
1458 
1459  case IOCTL_DVD_GET_REGION: {
1460 
1461  PDVD_COPY_PROTECT_KEY copyProtectKey;
1462  ULONG keyLength;
1463  IO_STATUS_BLOCK ioStatus;
1464  PDVD_DESCRIPTOR_HEADER dvdHeader;
1465  PDVD_COPYRIGHT_DESCRIPTOR copyRightDescriptor;
1466  PDVD_REGION dvdRegion;
1467  PDVD_READ_STRUCTURE readStructure;
1468  PDVD_RPC_KEY rpcKey;
1469 
1471  "DvdDeviceControl: [%p] IOCTL_DVD_GET_REGION\n", Irp));
1472 
1473  if (cdData->DvdRpc0Device && cdData->DvdRpc0LicenseFailure) {
1475  "DvdDeviceControl: License Failure\n"));
1477  break;
1478  }
1479 
1480  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1481  sizeof(DVD_REGION)) {
1482 
1484  "DvdDeviceControl: output buffer DVD_REGION too small\n"));
1486  break;
1487  }
1488 
1489  //
1490  // figure out how much data buffer we need
1491  //
1492 
1493  keyLength = max(sizeof(DVD_DESCRIPTOR_HEADER) +
1494  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1495  sizeof(DVD_READ_STRUCTURE)
1496  );
1497  keyLength = max(keyLength,
1499  );
1500 
1501  //
1502  // round the size to nearest ULONGLONG -- why?
1503  //
1504 
1505  keyLength += sizeof(ULONGLONG) - (keyLength & (sizeof(ULONGLONG) - 1));
1506 
1507  readStructure = ExAllocatePoolWithTag(NonPagedPool,
1508  keyLength,
1510  if (readStructure == NULL) {
1512  break;
1513  }
1514 
1515  RtlZeroMemory (readStructure, keyLength);
1516  readStructure->Format = DvdCopyrightDescriptor;
1517 
1518  //
1519  // Build a request for READ_STRUCTURE
1520  //
1521 
1524  DeviceObject,
1525  readStructure,
1526  keyLength,
1527  sizeof(DVD_DESCRIPTOR_HEADER) +
1528  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
1529  FALSE,
1530  &ioStatus);
1531 
1532  status = ioStatus.Status;
1533 
1534  if (!NT_SUCCESS(status)) {
1536  "CdRomDvdGetRegion => read structure failed %x\n",
1537  status));
1538  ExFreePool(readStructure);
1539  break;
1540  }
1541 
1542  //
1543  // we got the copyright descriptor, so now get the region if possible
1544  //
1545 
1546  dvdHeader = (PDVD_DESCRIPTOR_HEADER) readStructure;
1547  copyRightDescriptor = (PDVD_COPYRIGHT_DESCRIPTOR) dvdHeader->Data;
1548 
1549  //
1550  // the original irp's systembuffer has a copy of the info that
1551  // should be passed down in the request
1552  //
1553 
1554  dvdRegion = Irp->AssociatedIrp.SystemBuffer;
1555 
1556  dvdRegion->CopySystem = copyRightDescriptor->CopyrightProtectionType;
1557  dvdRegion->RegionData = copyRightDescriptor->RegionManagementInformation;
1558 
1559  //
1560  // now reuse the buffer to request the copy protection info
1561  //
1562 
1563  copyProtectKey = (PDVD_COPY_PROTECT_KEY) readStructure;
1564  RtlZeroMemory (copyProtectKey, DVD_RPC_KEY_LENGTH);
1565  copyProtectKey->KeyLength = DVD_RPC_KEY_LENGTH;
1566  copyProtectKey->KeyType = DvdGetRpcKey;
1567 
1568  //
1569  // send a request for READ_KEY
1570  //
1571 
1574  DeviceObject,
1575  copyProtectKey,
1578  FALSE,
1579  &ioStatus);
1580  status = ioStatus.Status;
1581 
1582  if (!NT_SUCCESS(status)) {
1584  "CdRomDvdGetRegion => read key failed %x\n",
1585  status));
1586  ExFreePool(readStructure);
1587  break;
1588  }
1589 
1590  //
1591  // the request succeeded. if a supported scheme is returned,
1592  // then return the information to the caller
1593  //
1594 
1595  rpcKey = (PDVD_RPC_KEY) copyProtectKey->KeyData;
1596 
1597  if (rpcKey->RpcScheme == 1) {
1598 
1599  if (rpcKey->TypeCode) {
1600 
1601  dvdRegion->SystemRegion = ~rpcKey->RegionMask;
1602  dvdRegion->ResetCount = rpcKey->UserResetsAvailable;
1603 
1604  } else {
1605 
1606  //
1607  // the drive has not been set for any region
1608  //
1609 
1610  dvdRegion->SystemRegion = 0;
1611  dvdRegion->ResetCount = rpcKey->UserResetsAvailable;
1612  }
1613  Irp->IoStatus.Information = sizeof(DVD_REGION);
1614 
1615  } else {
1616 
1618  "CdRomDvdGetRegion => rpcKey->RpcScheme != 1\n"));
1620  }
1621 
1622  ExFreePool(readStructure);
1623  break;
1624  }
1625 
1626 
1628 
1629  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
1630  sizeof(STORAGE_SET_READ_AHEAD)) {
1631 
1633  "DvdDeviceControl: SetReadAhead buffer too small\n"));
1635  break;
1636  }
1637 
1640 
1641  return STATUS_PENDING;
1642  }
1643 
1644  case IOCTL_DISK_IS_WRITABLE: {
1645 
1648 
1649  return STATUS_PENDING;
1650 
1651  }
1652 
1654 
1655  ULONG size;
1656 
1657  //
1658  // we always fake zero or one partitions, and one partition
1659  // structure is included in DRIVE_LAYOUT_INFORMATION
1660  //
1661 
1662  size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[1]);
1663 
1664 
1666  "CdRomDeviceControl: Get drive layout\n"));
1667  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < size) {
1669  Irp->IoStatus.Information = size;
1670  break;
1671  }
1672 
1675  return STATUS_PENDING;
1676 
1677 
1678  }
1680 
1681  ULONG size;
1682 
1683  //
1684  // we always fake zero or one partitions, and one partition
1685  // structure is included in DRIVE_LAYOUT_INFORMATION_EX
1686  //
1687 
1688  size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[1]);
1689 
1691  "CdRomDeviceControl: Get drive layout ex\n"));
1692  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < size) {
1694  Irp->IoStatus.Information = size;
1695  break;
1696  }
1697 
1700  return STATUS_PENDING;
1701 
1702  }
1703 
1704 
1706 
1707  //
1708  // Check that the buffer is large enough.
1709  //
1710 
1711  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1712  sizeof(PARTITION_INFORMATION)) {
1713 
1715  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
1716  break;
1717  }
1718 
1721  return STATUS_PENDING;
1722 
1723  }
1725 
1726  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1727  sizeof(PARTITION_INFORMATION_EX)) {
1728 
1730  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
1731  break;
1732  }
1733 
1736  return STATUS_PENDING;
1737  }
1738 
1739  case IOCTL_DISK_VERIFY: {
1740 
1742  "IOCTL_DISK_VERIFY to device %p through irp %p\n",
1743  DeviceObject, Irp));
1744 
1745  //
1746  // Validate buffer length.
1747  //
1748 
1749  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
1750  sizeof(VERIFY_INFORMATION)) {
1751 
1753  break;
1754  }
1757  return STATUS_PENDING;
1758  }
1759 
1761 
1762  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1763  sizeof(GET_LENGTH_INFORMATION)) {
1765  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
1766  break;
1767  }
1770  return STATUS_PENDING;
1771  }
1772 
1774 
1775  PGET_CONFIGURATION_IOCTL_INPUT inputBuffer;
1776 
1778  "IOCTL_CDROM_GET_CONFIGURATION to via irp %p\n", Irp));
1779 
1780  //
1781  // Validate buffer length.
1782  //
1783 
1784  if (irpStack->Parameters.DeviceIoControl.InputBufferLength !=
1787  break;
1788  }
1789  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1790  sizeof(GET_CONFIGURATION_HEADER)) {
1792  Irp->IoStatus.Information = sizeof(GET_CONFIGURATION_HEADER);
1793  break;
1794  }
1795  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength > 0xffff) {
1796  // output buffer is too large
1798  break;
1799  }
1800 
1801  //
1802  // also verify the arguments are reasonable.
1803  //
1804 
1805  inputBuffer = Irp->AssociatedIrp.SystemBuffer;
1806  if (inputBuffer->Feature > 0xffff) {
1808  break;
1809  }
1810  if ((inputBuffer->RequestType != SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE) &&
1814  break;
1815  }
1816  if (inputBuffer->Reserved[0] || inputBuffer->Reserved[1]) {
1818  break;
1819  }
1820 
1823  return STATUS_PENDING;
1824 
1825  }
1826 
1827  default: {
1828 
1829  BOOLEAN synchronize = (KeGetCurrentIrql() == PASSIVE_LEVEL);
1830  PKEVENT deviceControlEvent;
1831 
1832  //
1833  // If the ioctl has come in at passive level then we will synchronize
1834  // with our start-io routine when sending the ioctl. If the ioctl
1835  // has come in at a higher interrupt level and it was not handled
1836  // above then it's unlikely to be a request for the class DLL - however
1837  // we'll still use it's common code to forward the request through.
1838  //
1839 
1840  if (synchronize) {
1841 
1842  deviceControlEvent = ExAllocatePoolWithTag(NonPagedPool,
1843  sizeof(KEVENT),
1845 
1846  if (deviceControlEvent == NULL) {
1847 
1848  //
1849  // must complete this irp unsuccessful here
1850  //
1852  break;
1853 
1854  } else {
1855 
1856  //PIO_STACK_LOCATION currentStack;
1857 
1858  KeInitializeEvent(deviceControlEvent, NotificationEvent, FALSE);
1859 
1860  //currentStack = IoGetCurrentIrpStackLocation(Irp);
1861  nextStack = IoGetNextIrpStackLocation(Irp);
1862 
1863  //
1864  // Copy the stack down a notch
1865  //
1866 
1868 
1870  Irp,
1872  deviceControlEvent,
1873  TRUE,
1874  TRUE,
1875  TRUE
1876  );
1877 
1879 
1880  Irp->IoStatus.Status = STATUS_SUCCESS;
1881  Irp->IoStatus.Information = 0;
1882 
1883  //
1884  // Override volume verifies on this stack location so that we
1885  // will be forced through the synchronization. Once this
1886  // location goes away we get the old value back
1887  //
1888 
1890 
1892 
1893  //
1894  // Wait for CdRomClassIoctlCompletion to set the event. This
1895  // ensures serialization remains intact for these unhandled device
1896  // controls.
1897  //
1898 
1900  deviceControlEvent,
1901  Executive,
1902  KernelMode,
1903  FALSE,
1904  NULL);
1905 
1906  ExFreePool(deviceControlEvent);
1907 
1909  "CdRomDeviceControl: irp %p synchronized\n", Irp));
1910 
1911  status = Irp->IoStatus.Status;
1912  }
1913 
1914  } else {
1916  }
1917 
1918  //
1919  // If an error occured then propagate that back up - we are no longer
1920  // guaranteed synchronization and the upper layers will have to
1921  // retry.
1922  //
1923  // If no error occured, call down to the class driver directly
1924  // then start up the next request.
1925  //
1926 
1927  if (NT_SUCCESS(status)) {
1928 
1929  UCHAR uniqueAddress;
1930 
1931  //
1932  // The class device control routine will release the remove
1933  // lock for this Irp. We need to make sure we have one
1934  // available so that it's safe to call IoStartNextPacket
1935  //
1936 
1937  if(synchronize) {
1938 
1939  ClassAcquireRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1940 
1941  }
1942 
1944 
1945  if(synchronize) {
1948  KeLowerIrql(irql);
1949  ClassReleaseRemoveLock(DeviceObject, (PIRP)&uniqueAddress);
1950  }
1951  return status;
1952 
1953  }
1954 
1955  //
1956  // an error occurred (either STATUS_INSUFFICIENT_RESOURCES from
1957  // attempting to synchronize or StartIo() error'd this one
1958  // out), so we need to finish the irp, which is
1959  // done at the end of this routine.
1960  //
1961  break;
1962 
1963  } // end default case
1964 
1965  } // end switch()
1966 
1967  if (status == STATUS_VERIFY_REQUIRED) {
1968 
1969  //
1970  // If the status is verified required and this request
1971  // should bypass verify required then retry the request.
1972  //
1973 
1974  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME) {
1975 
1977  goto RetryControl;
1978 
1979  }
1980  }
1981 
1983 
1984  if (Irp->Tail.Overlay.Thread) {
1986  }
1987 
1988  }
1989 
1990  //
1991  // Update IRP with completion status.
1992  //
1993 
1994  Irp->IoStatus.Status = status;
1995 
1996  //
1997  // Complete the request.
1998  //
1999 
2003  "CdRomDeviceControl: Status is %lx\n", status));
2004  return status;
2005 
2006 } // end CdRomDeviceControl()
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define IOCTL_CDROM_GET_CONTROL
Definition: ntddcdrm.h:43
ULONG * PDVD_SESSION_ID
Definition: cdrw_usr.h:1544
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC
Definition: ntddcdrm.h:131
#define IOCTL_STORAGE_SET_READ_AHEAD
Definition: cdrw_usr.h:186
LARGE_INTEGER PartitionLength
Definition: classpnp.h:594
#define DVD_TITLE_KEY_LENGTH
Definition: cdrw_usr.h:1595
#define max(a, b)
Definition: svc.c:63
UCHAR Rpc0SystemRegionResetCount
Definition: cdrom.h:247
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define XA_NOT_SUPPORTED
Definition: cdrom.c:211
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
UCHAR Cdb[16]
Definition: srb.h:271
#define KeWaitForMutexObject
Definition: kefuncs.h:568
union _DEVICE_MEDIA_INFO::@3060 DeviceSpecific
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:704
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:34
#define IOCTL_CDROM_GET_CONFIGURATION
Definition: ntddcdrm.h:40
ULONG Rpc0RetryRegistryCallback
Definition: cdrom.h:249
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR PreferredDriveRegionCode
Definition: ntddcdvd.h:193
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
NTSTATUS NTAPI CdRomDvdReadDiskKeyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:3247
VOID NTAPI ClassSendDeviceIoControlSynchronous(IN ULONG IoControlCode, IN PDEVICE_OBJECT TargetDeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG InputBufferLength, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, OUT PIO_STATUS_BLOCK IoStatus)
Definition: class.c:7660
#define MINIMUM_CDROM_READ_TOC_EX_SIZE
Definition: ntddcdrm.h:100
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:52
ULONG SectorCount
Definition: ntddcdrm.h:353
LARGE_INTEGER BlockByteOffset
Definition: ntddcdvd.h:80
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
UCHAR CdbLength
Definition: srb.h:250
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
UCHAR SystemRegion
Definition: ntddcdvd.h:206
#define DVD_TAG_READ_KEY
Definition: cdrom.h:343
UCHAR RpcScheme
Definition: scsi.h:2927
DVD_SESSION_ID SessionId
Definition: ntddcdvd.h:82
ULONG BytesPerSector
Definition: ntdddisk.h:381
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
struct _PARTITION_INFORMATION PARTITION_INFORMATION
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
ULONG TimeOutValue
Definition: srb.h:254
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define DVD_ASF_LENGTH
Definition: cdrw_usr.h:1599
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX
Definition: ntddcdrm.h:49
#define IOCTL_CDROM_RAW_READ
Definition: ntddcdrm.h:64
struct __RAW_READ_INFO * PRAW_READ_INFO
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IOCTL_CDROM_SET_VOLUME
Definition: ntddcdrm.h:85
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT
Definition: ntddmmc.h:16
struct _DVD_COPYRIGHT_DESCRIPTOR * PDVD_COPYRIGHT_DESCRIPTOR
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define DVD_BUS_KEY_LENGTH
Definition: cdrw_usr.h:1594
VOID NTAPI CdRomPickDvdRegion(IN PDEVICE_OBJECT Fdo)
Definition: cdrom.c:5890
struct _DEVICE_MEDIA_INFO::@3060::@3062 RemovableDiskInfo
NTSTATUS NTAPI ClassSendSrbSynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:2648
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
GLenum GLint GLuint mask
Definition: glext.h:6028
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
struct _DVD_RPC_KEY * PDVD_RPC_KEY
__inline ULONG CountOfSetBitsUChar(UCHAR _X)
Definition: tools.h:150
#define IOCTL_CDROM_MEDIA_CATALOG
Definition: cdrw_usr.h:1355
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
UCHAR UserResetsAvailable
Definition: scsi.h:2923
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:91
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:82
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_CSS_RESETS_EXHAUSTED
Definition: ntstatus.h:873
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT
Definition: ntddcdrm.h:134
union _CDB * PCDB
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:61
#define IOCTL_DVD_END_SESSION
Definition: cdrw_usr.h:162
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
struct _READ_DVD_STRUCTURES_HEADER READ_DVD_STRUCTURES_HEADER
#define CDROM_READ_TOC_EX_FORMAT_PMA
Definition: ntddcdrm.h:132
#define MAXIMUM_RETRIES
Definition: class2.h:14
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define TraceLog(x)
Definition: trace.h:14
BOOLEAN DvdRpc0Device
Definition: cdrom.h:244
BOOLEAN DvdRpc0LicenseFailure
Definition: cdrom.h:245
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
NTSTATUS NTAPI CdRomDvdEndAllSessionsCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: ioctl.c:3173
struct _GET_MEDIA_TYPES GET_MEDIA_TYPES
#define CTL_CODE(DeviceType, Function, Method, Access)
Definition: nt_native.h:586
PDEVICE_OBJECT DeviceObject
Definition: pci.h:42
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
UCHAR Rpc0SystemRegion
Definition: cdrom.h:246
struct _DVD_REGION DVD_REGION
GLsizeiptr size
Definition: glext.h:5919
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:46
uint64_t ULONGLONG
Definition: typedefs.h:65
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:377
#define COOKED_SECTOR_SIZE
Definition: cdrom.c:175