3 Copyright (C) Microsoft Corporation, 1991 - 1999
11 Private header file for cdrom.sys. This contains private
12 structure and function declarations as well as constant
13 values which do not need to be exported.
38 extern CLASSPNP_SCAN_FOR_SPECIAL_INFO CdromHackItems
[];
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
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
51 CdromDebugFeatures
= 32 // set bit 0x80000000 in nt!kd_cdrom_mask
54 #define CDROM_GET_CONFIGURATION_TIMEOUT (0x4)
56 #define CDROM_HACK_DEC_RRD (0x00000001)
57 #define CDROM_HACK_FUJITSU_FMCD_10x (0x00000002)
58 #define CDROM_HACK_HITACHI_1750 (0x00000004)
59 #define CDROM_HACK_HITACHI_GD_2000 (0x00000008)
60 #define CDROM_HACK_TOSHIBA_SD_W1101 (0x00000010)
61 #define CDROM_HACK_TOSHIBA_XM_3xx (0x00000020)
62 #define CDROM_HACK_NEC_CDDA (0x00000040)
63 #define CDROM_HACK_PLEXTOR_CDDA (0x00000080)
64 #define CDROM_HACK_BAD_GET_CONFIG_SUPPORT (0x00000100)
65 #define CDROM_HACK_FORCE_READ_CD_DETECTION (0x00000200)
66 #define CDROM_HACK_READ_CD_SUPPORTED (0x00000400)
67 #define CDROM_HACK_LOCKED_PAGES (0x80000000) // not a valid flag to save
69 #define CDROM_HACK_VALID_FLAGS (0x000007ff)
70 #define CDROM_HACK_INVALID_FLAGS (~CDROM_HACK_VALID_FLAGS)
73 typedef struct _XA_CONTEXT
{
76 // Pointer to the device object.
79 PDEVICE_OBJECT DeviceObject
;
82 // Pointer to the original request when
83 // a mode select must be sent.
89 // Pointer to the mode select srb.
92 PSCSI_REQUEST_BLOCK Srb
;
93 } XA_CONTEXT
, *PXA_CONTEXT
;
95 typedef struct _ERROR_RECOVERY_DATA
{
96 MODE_PARAMETER_HEADER Header
;
97 MODE_PARAMETER_BLOCK BlockDescriptor
;
98 MODE_READ_RECOVERY_PAGE ReadRecoveryPage
;
99 } ERROR_RECOVERY_DATA
, *PERROR_RECOVERY_DATA
;
101 typedef struct _ERROR_RECOVERY_DATA10
{
102 MODE_PARAMETER_HEADER10 Header10
;
103 MODE_PARAMETER_BLOCK BlockDescriptor10
;
104 MODE_READ_RECOVERY_PAGE ReadRecoveryPage10
;
105 } ERROR_RECOVERY_DATA10
, *PERROR_RECOVERY_DATA10
;
108 // CdRom specific addition to device extension.
111 typedef struct _CDROM_DRIVER_EXTENSION
{
112 ULONG InterlockedCdRomCounter
;
114 } CDROM_DRIVER_EXTENSION
, *PCDROM_DRIVER_EXTENSION
;
116 #define CdromMmcUpdateComplete 0
117 #define CdromMmcUpdateRequired 1
118 #define CdromMmcUpdateStarted 2
120 typedef struct _CDROM_MMC_EXTENSION
{
122 ULONG IsMmc
; // allow quick checks
127 SLIST_HEADER DelayedIrps
; // irps delayed due to
128 KSPIN_LOCK DelayedLock
; // lock for delayed irps
130 PIO_WORKITEM CapabilitiesWorkItem
;
131 PIRP CapabilitiesIrp
;
132 PMDL CapabilitiesMdl
;
133 PGET_CONFIGURATION_HEADER CapabilitiesBuffer
;
134 ULONG CapabilitiesBufferSize
;
135 KEVENT CapabilitiesEvent
;
136 SCSI_REQUEST_BLOCK CapabilitiesSrb
;
138 } CDROM_MMC_EXTENSION
, *PCDROM_MMC_EXTENSION
;
141 #define CDROM_DRIVER_EXTENSION_ID CdRomAddDevice
143 typedef struct _CDROM_DATA
{
146 // Pointer to the cdrom driver extension
149 PCDROM_DRIVER_EXTENSION DriverExtension
;
153 // These bits allow detection of when to requery the
154 // drive's capabilities.
157 CDROM_MMC_EXTENSION Mmc
;
160 // hack flags for ScanForSpecial routines
166 // the error handling routines need to be per-device,
167 // not per-driver....
170 PCLASS_ERROR ErrorHandler
;
173 // Indicates whether an audio play operation
174 // is currently being performed.
175 // Only thing this does is prevent reads and
176 // toc requests while playing audio.
182 // Indicates whether the blocksize used for user data
189 // Indicates that this is a DEC RRD cdrom.
190 // This drive requires software to fix responses
191 // from the faulty firmware
197 // This points to an irp which needs to be delayed for a bit before a
198 // retry can be attempted. The interval counter is set by the deferring
199 // routine and will be decremented to zero in the tick handler. Once
200 // the counter goes to zero the irp will be issued again.
201 // DelayedRetryResend controls whether the irp is resent to the lower
202 // driver (TRUE) or reissued into the startio routine (FALSE)
205 BOOLEAN DelayedRetryResend
;
207 PIRP DelayedRetryIrp
;
209 ULONG DelayedRetryInterval
;
211 KSPIN_LOCK DelayedRetrySpinLock
;
214 // indicate we need to pick a default dvd region
215 // for the user if we can
221 // The interface strings registered for this device.
224 UNICODE_STRING CdromInterfaceString
;
225 UNICODE_STRING VolumeInterfaceString
;
228 // The well known name link for this device.
231 UNICODE_STRING WellKnownName
;
234 // Indicates whether 6 or 10 bytes mode sense/select
241 // keep track of what type of DVD device we are
244 BOOLEAN DvdRpc0Device
;
245 BOOLEAN DvdRpc0LicenseFailure
;
246 UCHAR Rpc0SystemRegion
; // bitmask, one means prevent play
247 UCHAR Rpc0SystemRegionResetCount
;
249 ULONG Rpc0RetryRegistryCallback
; // one until initial region chosen
251 KMUTEX Rpc0RegionMutex
;
254 // Storage for the error recovery page. This is used
255 // as an easy method to switch block sizes.
257 // NOTE - doubly unnamed structs just aren't very clean looking code - this
258 // should get cleaned up at some point in the future.
263 ERROR_RECOVERY_DATA10
;
266 } CDROM_DATA
, *PCDROM_DATA
;
268 #define DEVICE_EXTENSION_SIZE sizeof(FUNCTIONAL_DEVICE_EXTENSION) + sizeof(CDROM_DATA)
269 #define SCSI_CDROM_TIMEOUT 10
270 #define SCSI_CHANGER_BONUS_TIMEOUT 10
271 #define HITACHI_MODE_DATA_SIZE 12
272 #define MODE_DATA_SIZE 64
273 #define RAW_SECTOR_SIZE 2352
274 #define COOKED_SECTOR_SIZE 2048
275 #define CDROM_SRB_LIST_SIZE 4
277 #define PLAY_ACTIVE(x) (((PCDROM_DATA)(x->CommonExtension.DriverData))->PlayActive)
279 #define MSF_TO_LBA(Minutes,Seconds,Frames) \
280 (ULONG)((60 * 75 * (Minutes)) + (75 * (Seconds)) + ((Frames) - 150))
282 #define LBA_TO_MSF(Lba,Minutes,Seconds,Frames) \
284 (Minutes) = (UCHAR)(Lba / (60 * 75)); \
285 (Seconds) = (UCHAR)((Lba % (60 * 75)) / 75); \
286 (Frames) = (UCHAR)((Lba % (60 * 75)) % 75); \
289 #define DEC_TO_BCD(x) (((x / 10) << 4) + (x % 10))
292 // Define flags for XA, CDDA, and Mode Select/Sense
295 #define XA_USE_6_BYTE 0x01
296 #define XA_USE_10_BYTE 0x02
298 #define XA_NOT_SUPPORTED 0x10
299 #define XA_USE_READ_CD 0x20
300 #define XA_PLEXTOR_CDDA 0x40
301 #define XA_NEC_CDDA 0x80
304 // Sector types for READ_CD
308 #define CD_DA_SECTOR 1
309 #define YELLOW_MODE1_SECTOR 2
310 #define YELLOW_MODE2_SECTOR 3
311 #define FORM2_MODE1_SECTOR 4
312 #define FORM2_MODE2_SECTOR 5
314 #define MAX_COPY_PROTECT_AGID 4
316 #ifdef ExAllocatePool
317 #undef ExAllocatePool
318 #define ExAllocatePool #assert(FALSE)
321 #define CDROM_TAG_GET_CONFIG 'cCcS' // "ScCc" - ioctl GET_CONFIGURATION
322 #define CDROM_TAG_DC_EVENT 'ECcS' // "ScCE" - device control synch event
323 #define CDROM_TAG_FEATURE 'FCcS' // "ScCF" - allocated by CdRomGetConfiguration(), free'd by caller
324 #define CDROM_TAG_DISK_GEOM 'GCcS' // "ScCG" - disk geometry buffer
325 #define CDROM_TAG_HITACHI_ERROR 'HCcS' // "ScCH" - hitachi error buffer
326 #define CDROM_TAG_SENSE_INFO 'ICcS' // "ScCI" - sense info buffers
327 #define CDROM_TAG_POWER_IRP 'iCcS' // "ScCi" - irp for power request
328 #define CDROM_TAG_SRB 'SCcS' // "ScCS" - srb allocation
329 #define CDROM_TAG_STRINGS 'sCcS' // "ScCs" - assorted string data
330 #define CDROM_TAG_MODE_DATA 'MCcS' // "ScCM" - mode data buffer
331 #define CDROM_TAG_READ_CAP 'PCcS' // "ScCP" - read capacity buffer
332 #define CDROM_TAG_PLAY_ACTIVE 'pCcS' // "ScCp" - play active checks
333 #define CDROM_TAG_SUB_Q 'QCcS' // "ScCQ" - read sub q buffer
334 #define CDROM_TAG_RAW 'RCcS' // "ScCR" - raw mode read buffer
335 #define CDROM_TAG_TOC 'TCcS' // "ScCT" - read toc buffer
336 #define CDROM_TAG_TOSHIBA_ERROR 'tCcS' // "ScCt" - toshiba error buffer
337 #define CDROM_TAG_DEC_ERROR 'dCcS' // "ScCt" - DEC error buffer
338 #define CDROM_TAG_UPDATE_CAP 'UCcS' // "ScCU" - update capacity path
339 #define CDROM_TAG_VOLUME 'VCcS' // "ScCV" - volume control buffer
340 #define CDROM_TAG_VOLUME_INT 'vCcS' // "ScCv" - volume control buffer
342 #define DVD_TAG_READ_STRUCTURE 'SVcS' // "ScVS" - used for dvd structure reads
343 #define DVD_TAG_READ_KEY 'kVcS' // "ScVk" - read buffer for dvd key
344 #define DVD_TAG_SEND_KEY 'KVcS' // "ScVK" - write buffer for dvd key
345 #define DVD_TAG_RPC2_CHECK 'sVcS' // "ScVs" - read buffer for dvd/rpc2 check
346 #define DVD_TAG_DVD_REGION 'tVcS' // "ScVt" - read buffer for rpc2 check
347 #define DVD_TAG_SECURITY 'XVcS' // "ScVX" - security descriptor
350 #define CDROM_SUBKEY_NAME (L"CdRom") // store new settings here
351 #define CDROM_READ_CD_NAME (L"ReadCD") // READ_CD support previously detected
352 #define CDROM_NON_MMC_DRIVE_NAME (L"NonMmc") // MMC commands hang
354 // DVD Registry Value Names for RPC0 Device
356 #define DVD_DEFAULT_REGION (L"DefaultDvdRegion") // this is init. by the dvd class installer
357 #define DVD_CURRENT_REGION (L"DvdR")
358 #define DVD_REGION_RESET_COUNT (L"DvdRCnt")
359 #define DVD_MAX_REGION_RESET_COUNT 2
360 #define DVD_MAX_REGION 8
362 #define BAIL_OUT(Irp) \
363 DebugPrint((2, "Cdrom: [%p] Bailing with status " \
364 " %lx at line %x file %s\n", \
365 (Irp), (Irp)->IoStatus.Status, \
373 This routine grabs an extra remove lock using a local variable
374 for a unique tag. It then completes the irp in question, and
375 the just-acquired removelock guarantees that it is still safe
376 to call IoStartNextPacket(). When that finishes, we release
377 the newly acquired RemoveLock and return.
381 DeviceObject - the device object for the StartIo queue
382 Irp - the request we are completing
390 This is implemented as an inline function to allow the compiler
391 to optimize this as either a function call or as actual inline code.
393 This routine will not work with IoXxxRemoveLock() calls, as the
394 behavior is different. ClassXxxRemoveLock() calls succeed until
395 the remove has completed, while IoXxxRemoveLock() calls fail as
396 soon as the call to IoReleaseRemoveLockAndWait() has been called.
397 The Class version allows this routine to work in a safe manner.
399 replaces the following two lines:
400 IoStartNextPacket(DeviceObject, FALSE);
401 ClassReleaseRemoveLock(DeviceObject, Irp);
402 and raises irql as needed to call IoStartNextPacket()
407 CdRomCompleteIrpAndStartNextPacketSafely(
408 IN PDEVICE_OBJECT DeviceObject
,
413 KIRQL oldIrql
= KeGetCurrentIrql();
415 ClassAcquireRemoveLock(DeviceObject
, (PIRP
)&uniqueAddress
);
416 ClassReleaseRemoveLock(DeviceObject
, Irp
);
417 ClassCompleteRequest(DeviceObject
, Irp
, IO_CD_ROM_INCREMENT
);
419 if (oldIrql
> DISPATCH_LEVEL
) {
420 ASSERT(!"Cannot call IoStartNextPacket at raised IRQL!");
421 } else if (oldIrql
< DISPATCH_LEVEL
) {
422 KeRaiseIrqlToDpcLevel();
423 } else { // (oldIrql == DISPATCH_LEVEL)
427 IoStartNextPacket(DeviceObject
, FALSE
);
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)
437 ClassReleaseRemoveLock(DeviceObject
, (PIRP
)&uniqueAddress
);
445 CdRomDeviceControlDvdReadStructure(
446 IN PDEVICE_OBJECT DeviceObject
,
449 IN PSCSI_REQUEST_BLOCK Srb
454 CdRomDeviceControlDvdEndSession(
455 IN PDEVICE_OBJECT DeviceObject
,
458 IN PSCSI_REQUEST_BLOCK Srb
463 CdRomDeviceControlDvdStartSessionReadKey(
464 IN PDEVICE_OBJECT DeviceObject
,
467 IN PSCSI_REQUEST_BLOCK Srb
472 CdRomDeviceControlDvdSendKey(
473 IN PDEVICE_OBJECT DeviceObject
,
476 IN PSCSI_REQUEST_BLOCK Srb
482 IN PDRIVER_OBJECT DriverObject
,
483 IN PUNICODE_STRING RegistryPath
489 IN PDRIVER_OBJECT DriverObject
495 IN PDRIVER_OBJECT DriverObject
,
496 IN PDEVICE_OBJECT Pdo
502 IN PDEVICE_OBJECT DeviceObject
,
508 CdRomReadWriteVerification(
509 IN PDEVICE_OBJECT DeviceObject
,
516 IN PDEVICE_OBJECT DeviceObject
,
518 IN PIRP OriginalRequest
523 CdRomDeviceControlDispatch(
524 IN PDEVICE_OBJECT DeviceObject
,
530 CdRomDeviceControlCompletion(
531 IN PDEVICE_OBJECT DeviceObject
,
538 CdRomSetVolumeIntermediateCompletion(
539 IN PDEVICE_OBJECT DeviceObject
,
546 CdRomSwitchModeCompletion(
547 IN PDEVICE_OBJECT DeviceObject
,
555 IN PDEVICE_OBJECT DeviceObject
,
562 CdRomClassIoctlCompletion(
563 IN PDEVICE_OBJECT DeviceObject
,
571 IN PDEVICE_OBJECT DeviceObject
,
578 IN PDEVICE_OBJECT DeviceObject
584 IN PFUNCTIONAL_DEVICE_EXTENSION DeviceExtension
,
585 IN PIRP IrpToComplete
,
586 IN OPTIONAL PKEVENT IoctlEvent
591 CdRomCreateDeviceObject(
592 IN PDRIVER_OBJECT DriverObject
,
593 IN PDEVICE_OBJECT Pdo
598 ScanForSpecialHandler(
599 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
606 PDEVICE_OBJECT DeviceObject
612 IN PDEVICE_OBJECT DeviceObject
618 PDEVICE_OBJECT DeviceObject
,
619 PSCSI_REQUEST_BLOCK Srb
,
626 HitachiProcessErrorGD2000(
627 PDEVICE_OBJECT DeviceObject
,
628 PSCSI_REQUEST_BLOCK Srb
,
636 PDEVICE_OBJECT DeviceObject
,
637 PSCSI_REQUEST_BLOCK Srb
,
645 PDEVICE_OBJECT DeviceObject
,
646 PSCSI_REQUEST_BLOCK Srb
,
653 ToshibaProcessErrorCompletion(
654 PDEVICE_OBJECT DeviceObject
,
661 CdRomCreateNamedEvent(
662 IN PFUNCTIONAL_DEVICE_EXTENSION DeviceExtension
,
663 IN ULONG DeviceNumber
669 IN PDEVICE_OBJECT Fdo
675 IN PDEVICE_OBJECT Fdo
681 IN PDEVICE_OBJECT DeviceObject
,
688 IN PDEVICE_OBJECT DeviceObject
,
694 CdRomDvdEndAllSessionsCompletion(
695 IN PDEVICE_OBJECT DeviceObject
,
702 CdRomDvdReadDiskKeyCompletion(
703 IN PDEVICE_OBJECT DeviceObject
,
711 IN PDEVICE_OBJECT DeviceObject
716 CdRomCreateWellKnownName(
717 IN PDEVICE_OBJECT DeviceObject
722 CdRomDeleteWellKnownName(
723 IN PDEVICE_OBJECT DeviceObject
728 CdRomGetDeviceParameter (
729 IN PDEVICE_OBJECT DeviceObject
,
730 IN PWSTR ParameterName
,
731 IN OUT PULONG ParameterValue
736 CdRomSetDeviceParameter (
737 IN PDEVICE_OBJECT DeviceObject
,
738 IN PWSTR ParameterName
,
739 IN ULONG ParameterValue
745 IN PDEVICE_OBJECT Fdo
751 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
760 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
761 IN OPTIONAL PIRP Irp
,
767 CdRomGetRpc0Settings(
768 IN PDEVICE_OBJECT Fdo
773 CdRomSetRpc0Settings(
774 IN PDEVICE_OBJECT Fdo
,
781 IN PDEVICE_OBJECT DeviceObject
,
785 ////////////////////////////////////////////////////////////////////////////////
789 CdRomIsDeviceMmcDevice(
790 IN PDEVICE_OBJECT Fdo
,
796 CdRomMmcErrorHandler(
797 IN PDEVICE_OBJECT Fdo
,
798 IN PSCSI_REQUEST_BLOCK Srb
,
799 OUT PNTSTATUS Status
,
805 CdRomFindFeaturePage(
806 IN PGET_CONFIGURATION_HEADER FeatureBuffer
,
808 IN FEATURE_NUMBER Feature
813 CdRomGetConfiguration(
814 IN PDEVICE_OBJECT Fdo
,
815 OUT PGET_CONFIGURATION_HEADER
*Buffer
,
816 OUT PULONG BytesReturned
,
817 IN FEATURE_NUMBER StartingFeature
,
818 IN ULONG RequestedType
823 CdRomUpdateMmcDriveCapabilities(
824 IN PDEVICE_OBJECT Fdo
,
825 IN PVOID Context
// RESERVED == NULL
830 CdRomFindProfileInProfiles(
831 IN PFEATURE_DATA_PROFILE_LIST ProfileHeader
,
832 IN FEATURE_PROFILE_TYPE ProfileToFind
,
838 CdRomAllocateMmcResources(
839 IN PDEVICE_OBJECT Fdo
844 CdRomDeAllocateMmcResources(
845 IN PDEVICE_OBJECT Fdo
850 CdromFakePartitionInfo(
851 IN PCOMMON_DEVICE_EXTENSION CommonExtension
,
857 CdRomInterpretReadCapacity(
858 IN PDEVICE_OBJECT Fdo
,
859 IN PREAD_CAPACITY_DATA ReadCapacityBuffer
864 CdRomShutdownFlushCompletion(
865 IN PDEVICE_OBJECT DeviceObject
,
872 CdRompFlushDelayedList(
873 IN PDEVICE_OBJECT Fdo
,
874 IN PCDROM_MMC_EXTENSION MmcData
,
876 IN BOOLEAN CalledFromWorkItem
879 #endif /* __CDROMP_H__ */