ReactOS  0.4.14-dev-1233-gf5658fd
cdrom.c File Reference
#include "cdrom.h"
Include dependency graph for cdrom.c:

Go to the source code of this file.

Macros

#define IS_WRITE_REQUEST(irpStack)   (irpStack->MajorFunction == IRP_MJ_WRITE)
 
#define IS_READ_WRITE_REQUEST(irpStack)
 

Functions

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 PhysicalDeviceObject)
 
NTSTATUS NTAPI CdRomCreateDeviceObject (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
 
NTSTATUS NTAPI CdRomInitDevice (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI CdRomStartDevice (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI CdRomStopDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
VOID NTAPI CdRomStartIo (IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
 
NTSTATUS NTAPI CdRomReadWriteVerification (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CdRomSwitchModeCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
VOID NTAPI ScanForSpecialHandler (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, ULONG_PTR HackFlags)
 
VOID NTAPI ScanForSpecial (PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI HitachiProcessErrorGD2000 (PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK OriginalSrb, NTSTATUS *Status, BOOLEAN *Retry)
 
VOID NTAPI HitachiProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
NTSTATUS NTAPI ToshibaProcessErrorCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
VOID NTAPI ToshibaProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
BOOLEAN NTAPI CdRomIsPlayActive (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI CdRomTickHandler (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI CdRomUpdateGeometryCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
NTSTATUS NTAPI CdRomUpdateCapacity (IN PFUNCTIONAL_DEVICE_EXTENSION DeviceExtension, IN PIRP IrpToComplete, IN OPTIONAL PKEVENT IoctlEvent)
 
NTSTATUS NTAPI CdRomRemoveDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
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 Fdo, IN PWSTR ParameterName, IN OUT PULONG ParameterValue)
 
NTSTATUS NTAPI CdRomSetDeviceParameter (IN PDEVICE_OBJECT Fdo, 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)
 
VOID NTAPI CdRomMmcErrorHandler (IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, OUT PNTSTATUS Status, OUT PBOOLEAN Retry)
 
VOID NTAPI CdRomErrorHandler (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
NTSTATUS NTAPI CdRomShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CdRomShutdownFlushCompletion (IN PDEVICE_OBJECT Fdo, IN PIRP NewIrp, IN PIRP OriginalIrp)
 
VOID NTAPI CdromFakePartitionInfo (IN PCOMMON_DEVICE_EXTENSION CommonExtension, IN PIRP Irp)
 

Macro Definition Documentation

◆ IS_READ_WRITE_REQUEST

#define IS_READ_WRITE_REQUEST (   irpStack)
Value:
((irpStack->MajorFunction == IRP_MJ_READ) || \
(irpStack->MajorFunction == IRP_MJ_WRITE) || \
((irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) && \
(irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_RAW_READ)))
#define IOCTL_CDROM_RAW_READ
Definition: ntddcdrm.h:64
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52

Definition at line 58 of file cdrom.c.

◆ IS_WRITE_REQUEST

#define IS_WRITE_REQUEST (   irpStack)    (irpStack->MajorFunction == IRP_MJ_WRITE)

Definition at line 55 of file cdrom.c.

Function Documentation

◆ CdRomAddDevice()

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

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().

◆ CdRomCreateDeviceObject()

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

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
NTSTATUS NTAPI ClassClaimDevice(IN PDEVICE_OBJECT LowerDeviceObject, IN BOOLEAN Release)
Definition: class.c:5985
#define TRUE
Definition: types.h:120
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
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
VOID NTAPI ClassUpdateInformationInRegistry(IN PDEVICE_OBJECT Fdo, IN PCHAR DeviceName, IN ULONG DeviceNumber, IN PINQUIRYDATA InquiryData, IN ULONG InquiryDataLength)
Definition: class.c:7322
#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
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:1857
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
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
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by CdRomAddDevice().

◆ 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:55
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().

◆ 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().

◆ CdRomErrorHandler()

VOID NTAPI CdRomErrorHandler ( PDEVICE_OBJECT  DeviceObject,
PSCSI_REQUEST_BLOCK  Srb,
NTSTATUS Status,
BOOLEAN Retry 
)

Definition at line 6621 of file cdrom.c.

6627 {
6629  PCDROM_DATA cddata = (PCDROM_DATA)commonExtension->DriverData;
6630  PSENSE_DATA sense = Srb->SenseInfoBuffer;
6631 
6632  if ((Srb->SenseInfoBufferLength >=
6633  RTL_SIZEOF_THROUGH_FIELD(SENSE_DATA,AdditionalSenseCodeQualifier)) &&
6634  TEST_FLAG(Srb->SrbStatus, SRB_STATUS_AUTOSENSE_VALID)) {
6635 
6636  //
6637  // Many non-WHQL certified drives (mostly CD-RW) return
6638  // 2/4/0 when they have no media instead of the obvious
6639  // choice of:
6640  //
6641  // SCSI_SENSE_NOT_READY/SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
6642  //
6643  // These drives should not pass WHQL certification due
6644  // to this discrepancy.
6645  //
6646  // However, we have to retry on 2/4/0 (Not ready, LUN not ready,
6647  // no info) and also 3/2/0 (no seek complete).
6648  //
6649  // These conditions occur when the shell tries to examine an
6650  // injected CD (e.g. for autoplay) before the CD is spun up.
6651  //
6652  // The drive should be returning an ASCQ of SCSI_SENSEQ_BECOMING_READY
6653  // (0x01) in order to comply with WHQL standards.
6654  //
6655  // The default retry timeout of one second is acceptable to balance
6656  // these discrepancies. don't modify the status, though....
6657  //
6658 
6659  if (((sense->SenseKey & 0xf) == SCSI_SENSE_NOT_READY) &&
6660  (sense->AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY) &&
6661  (sense->AdditionalSenseCodeQualifier == SCSI_SENSEQ_CAUSE_NOT_REPORTABLE)
6662  ) {
6663 
6664  *Retry = TRUE;
6665 
6666  } else if (((sense->SenseKey & 0xf) == SCSI_SENSE_MEDIUM_ERROR) &&
6667  (sense->AdditionalSenseCode == 0x2) &&
6668  (sense->AdditionalSenseCodeQualifier == 0x0)
6669  ) {
6670 
6671  *Retry = TRUE;
6672 
6673  } else if ((sense->AdditionalSenseCode == 0x57) &&
6674  (sense->AdditionalSenseCodeQualifier == 0x00)
6675  ) {
6676 
6677  //
6678  // UNABLE_TO_RECOVER_TABLE_OF_CONTENTS
6679  // the Matshita CR-585 returns this for all read commands
6680  // on blank CD-R and CD-RW media, and we need to handle
6681  // this for READ_CD detection ability.
6682  //
6683 
6684  *Retry = FALSE;
6686 
6687  }
6688 
6689  }
6690 
6691  //
6692  // tail recursion in both cases takes no stack
6693  //
6694 
6695  if (cddata->ErrorHandler) {
6697  }
6698  return;
6699 }
PCLASS_ERROR ErrorHandler
Definition: cdrom.h:170
#define TRUE
Definition: types.h:120
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
PVOID DeviceExtension
Definition: env_spec_w32.h:418
struct _CDROM_DATA * PCDROM_DATA
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:679
#define SCSI_SENSEQ_CAUSE_NOT_REPORTABLE
Definition: cdrw_hw.h:1312
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49

Referenced by DriverEntry().

◆ CdromFakePartitionInfo()

VOID NTAPI CdromFakePartitionInfo ( IN PCOMMON_DEVICE_EXTENSION  CommonExtension,
IN PIRP  Irp 
)

Definition at line 7005 of file cdrom.c.

7009 {
7011  ULONG ioctl = currentIrpStack->Parameters.DeviceIoControl.IoControlCode;
7012  PVOID systemBuffer = Irp->AssociatedIrp.SystemBuffer;
7013 
7014  ASSERT(systemBuffer);
7015 
7021  "CdromFakePartitionInfo: unhandled ioctl %x\n", ioctl));
7022  Irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
7023  Irp->IoStatus.Information = 0;
7024  CdRomCompleteIrpAndStartNextPacketSafely(CommonExtension->DeviceObject,
7025  Irp);
7026  return;
7027  }
7028 
7029  //
7030  // nothing to fail from this point on, so set the size appropriately
7031  // and set irp's status to success.
7032  //
7033 
7035  "CdromFakePartitionInfo: incoming ioctl %x\n", ioctl));
7036 
7037 
7038  Irp->IoStatus.Status = STATUS_SUCCESS;
7039  switch (ioctl) {
7041  Irp->IoStatus.Information = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION,
7042  PartitionEntry[1]);
7044  PartitionEntry[1]));
7045  break;
7047  Irp->IoStatus.Information = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX,
7048  PartitionEntry[1]);
7050  PartitionEntry[1]));
7051  break;
7053  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
7054  RtlZeroMemory(systemBuffer, sizeof(PARTITION_INFORMATION));
7055  break;
7057  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
7058  RtlZeroMemory(systemBuffer, sizeof(PARTITION_INFORMATION_EX));
7059  break;
7060  default:
7061  ASSERT(!"Invalid ioctl should not have reached this point\n");
7062  break;
7063  }
7064 
7065  //
7066  // if we are getting the drive layout, then we need to start by
7067  // adding some of the non-partition stuff that says we have
7068  // exactly one partition available.
7069  //
7070 
7071 
7073 
7075  layout = (PDRIVE_LAYOUT_INFORMATION)systemBuffer;
7076  layout->PartitionCount = 1;
7077  layout->Signature = 1;
7078  systemBuffer = (PVOID)(layout->PartitionEntry);
7080 
7081  } else if (ioctl == IOCTL_DISK_GET_DRIVE_LAYOUT_EX) {
7082 
7084  layoutEx = (PDRIVE_LAYOUT_INFORMATION_EX)systemBuffer;
7085  layoutEx->PartitionStyle = PARTITION_STYLE_MBR;
7086  layoutEx->PartitionCount = 1;
7087  layoutEx->Mbr.Signature = 1;
7088  systemBuffer = (PVOID)(layoutEx->PartitionEntry);
7090 
7091  }
7092 
7093  //
7094  // NOTE: the local var 'ioctl' is now modified to either EX or
7095  // non-EX version. the local var 'systemBuffer' is now pointing
7096  // to the partition information structure.
7097  //
7098 
7100 
7101  PPARTITION_INFORMATION partitionInfo;
7102  partitionInfo = (PPARTITION_INFORMATION)systemBuffer;
7103  partitionInfo->RewritePartition = FALSE;
7104  partitionInfo->RecognizedPartition = TRUE;
7105  partitionInfo->PartitionType = PARTITION_FAT32;
7106  partitionInfo->BootIndicator = FALSE;
7107  partitionInfo->HiddenSectors = 0;
7108  partitionInfo->StartingOffset.QuadPart = 0;
7109  partitionInfo->PartitionLength = CommonExtension->PartitionLength;
7110  partitionInfo->PartitionNumber = 0;
7111 
7112  } else {
7113 
7114  PPARTITION_INFORMATION_EX partitionInfo;
7115  partitionInfo = (PPARTITION_INFORMATION_EX)systemBuffer;
7116  partitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
7117  partitionInfo->RewritePartition = FALSE;
7118  partitionInfo->Mbr.RecognizedPartition = TRUE;
7119  partitionInfo->Mbr.PartitionType = PARTITION_FAT32;
7120  partitionInfo->Mbr.BootIndicator = FALSE;
7121  partitionInfo->Mbr.HiddenSectors = 0;
7122  partitionInfo->StartingOffset.QuadPart = 0;
7123  partitionInfo->PartitionLength = CommonExtension->PartitionLength;
7124  partitionInfo->PartitionNumber = 0;
7125 
7126  }
7128  "CdromFakePartitionInfo: finishing ioctl %x\n",
7129  currentIrpStack->Parameters.DeviceIoControl.IoControlCode));
7130 
7131  //
7132  // complete the irp
7133  //
7134 
7135  CdRomCompleteIrpAndStartNextPacketSafely(CommonExtension->DeviceObject,
7136  Irp);
7137  return;
7138 
7139 }
#define PARTITION_FAT32
Definition: disk.h:95
#define TRUE
Definition: types.h:120
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:399
_In_ PIRP Irp
Definition: csq.h:116
static VOID CdRomCompleteIrpAndStartNextPacketSafely(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cdrom.h:407
struct _PARTITION_INFORMATION PARTITION_INFORMATION
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
PARTITION_STYLE PartitionStyle
Definition: imports.h:220
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define ioctl
Definition: wintirpc.h:60
void * PVOID
Definition: retypes.h:9
#define TraceLog(x)
Definition: trace.h:14
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:398
DRIVE_LAYOUT_INFORMATION_MBR Mbr
Definition: ntdddisk.h:494
LARGE_INTEGER PartitionLength
Definition: imports.h:222
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN RewritePartition
Definition: ntdddisk.h:405
LARGE_INTEGER StartingOffset
Definition: imports.h:221
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:88
static DWORD layout
Definition: bitmap.c:46
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:76
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _PARTITION_INFORMATION * PPARTITION_INFORMATION
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
struct _DRIVE_LAYOUT_INFORMATION * PDRIVE_LAYOUT_INFORMATION
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
PARTITION_INFORMATION_EX PartitionEntry[1]
Definition: ntdddisk.h:497
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:404
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
struct _DRIVE_LAYOUT_INFORMATION_EX * PDRIVE_LAYOUT_INFORMATION_EX
struct _PARTITION_INFORMATION_EX * PPARTITION_INFORMATION_EX
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
LONGLONG QuadPart
Definition: typedefs.h:113

Referenced by CdRomStartIo().

◆ CdRomGetDeviceParameter()

NTSTATUS NTAPI CdRomGetDeviceParameter ( IN PDEVICE_OBJECT  Fdo,
IN PWSTR  ParameterName,
IN OUT PULONG  ParameterValue 
)

Definition at line 5753 of file cdrom.c.

5777 {
5778  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
5779  NTSTATUS status;
5780  HANDLE deviceParameterHandle;
5781  RTL_QUERY_REGISTRY_TABLE queryTable[2];
5782  ULONG defaultParameterValue;
5783 
5784  PAGED_CODE();
5785 
5786  //
5787  // open the given parameter
5788  //
5789  status = IoOpenDeviceRegistryKey(fdoExtension->LowerPdo,
5791  KEY_READ,
5792  &deviceParameterHandle);
5793 
5794  if(NT_SUCCESS(status)) {
5795 
5796  RtlZeroMemory(queryTable, sizeof(queryTable));
5797 
5798  defaultParameterValue = *ParameterValue;
5799 
5801  queryTable->Name = ParameterName;
5802  queryTable->EntryContext = ParameterValue;
5803  queryTable->DefaultType = REG_NONE;
5804  queryTable->DefaultData = NULL;
5805  queryTable->DefaultLength = 0;
5806 
5808  (PWSTR) deviceParameterHandle,
5809  queryTable,
5810  NULL,
5811  NULL);
5812  if (!NT_SUCCESS(status)) {
5813 
5814  *ParameterValue = defaultParameterValue;
5815  }
5816 
5817  //
5818  // close what we open
5819  //
5820  ZwClose(deviceParameterHandle);
5821  }
5822 
5823  return status;
5824 
5825 } // CdRomGetDeviceParameter
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:55
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_opt_ PWSTR _In_ PWSTR _Inout_ PULONG ParameterValue
Definition: classpnp.h:1209
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:697
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define PLUGPLAY_REGKEY_DRIVER
Definition: usbd.c:42
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: classpnp.h:1209
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:4658
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
static SERVICE_STATUS status
Definition: service.c:31
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
Definition: ps.c:97

Referenced by CdRomPickDvdRegion().

◆ CdRomGetDeviceType()

DEVICE_TYPE NTAPI CdRomGetDeviceType ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 5493 of file cdrom.c.

5513 {
5514  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
5515  PCDROM_DATA cdromExtension;
5516  ULONG bufLength;
5517  SCSI_REQUEST_BLOCK srb;
5518  PCDB cdb;
5519  PMODE_PARAMETER_HEADER10 modePageHeader;
5520  PCDVD_CAPABILITIES_PAGE capPage;
5521  ULONG capPageOffset;
5522  DEVICE_TYPE deviceType;
5523  NTSTATUS status;
5524  BOOLEAN use6Byte;
5525 
5526  PAGED_CODE();
5527 
5528  //
5529  // NOTE: don't cache this until understand how it affects GetMediaTypes()
5530  //
5531 
5532  //
5533  // default device type
5534  //
5535 
5536  deviceType = FILE_DEVICE_CD_ROM;
5537 
5538  fdoExtension = DeviceObject->DeviceExtension;
5539 
5540  cdromExtension = fdoExtension->CommonExtension.DriverData;
5541 
5542  use6Byte = TEST_FLAG(cdromExtension->XAFlags, XA_USE_6_BYTE);
5543 
5544  RtlZeroMemory(&srb, sizeof(srb));
5545  cdb = (PCDB)srb.Cdb;
5546 
5547  //
5548  // Build the MODE SENSE CDB. The data returned will be kept in the
5549  // device extension and used to set block size.
5550  //
5551  if (use6Byte) {
5552 
5553  bufLength = sizeof(CDVD_CAPABILITIES_PAGE) +
5554  sizeof(MODE_PARAMETER_HEADER);
5555 
5556  capPageOffset = sizeof(MODE_PARAMETER_HEADER);
5557 
5558  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
5559  cdb->MODE_SENSE.Dbd = 1;
5560  cdb->MODE_SENSE.PageCode = MODE_PAGE_CAPABILITIES;
5561  cdb->MODE_SENSE.AllocationLength = (UCHAR)bufLength;
5562  srb.CdbLength = 6;
5563  } else {
5564 
5565  bufLength = sizeof(CDVD_CAPABILITIES_PAGE) +
5566  sizeof(MODE_PARAMETER_HEADER10);
5567 
5568  capPageOffset = sizeof(MODE_PARAMETER_HEADER10);
5569 
5570  cdb->MODE_SENSE10.OperationCode = SCSIOP_MODE_SENSE10;
5571  cdb->MODE_SENSE10.Dbd = 1;
5572  cdb->MODE_SENSE10.PageCode = MODE_PAGE_CAPABILITIES;
5573  cdb->MODE_SENSE10.AllocationLength[0] = (UCHAR)(bufLength >> 8);
5574  cdb->MODE_SENSE10.AllocationLength[1] = (UCHAR)(bufLength >> 0);
5575  srb.CdbLength = 10;
5576  }
5577 
5578  //
5579  // Set timeout value from device extension.
5580  //
5581  srb.TimeOutValue = fdoExtension->TimeOutValue;
5582 
5584  bufLength,
5586  if (modePageHeader) {
5587 
5588  RtlZeroMemory(modePageHeader, bufLength);
5589 
5591  DeviceObject,
5592  &srb,
5593  modePageHeader,
5594  bufLength,
5595  FALSE);
5596 
5597  if (NT_SUCCESS(status) ||
5598  (status == STATUS_DATA_OVERRUN) ||
5600  ) {
5601 
5602  capPage = (PCDVD_CAPABILITIES_PAGE) (((PUCHAR) modePageHeader) + capPageOffset);
5603 
5604  if ((capPage->PageCode == MODE_PAGE_CAPABILITIES) &&
5605  (capPage->DVDROMRead || capPage->DVDRRead ||
5606  capPage->DVDRAMRead || capPage->DVDRWrite ||
5607  capPage->DVDRAMWrite)) {
5608 
5609  deviceType = FILE_DEVICE_DVD;
5610  }
5611  }
5612  ExFreePool (modePageHeader);
5613  }
5614 
5615  return deviceType;
5616 }
struct _CDVD_CAPABILITIES_PAGE CDVD_CAPABILITIES_PAGE
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
UCHAR Cdb[16]
Definition: srb.h:271
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
struct _CDB::_MODE_SENSE10 MODE_SENSE10
UCHAR CdbLength
Definition: srb.h:250
ULONG TimeOutValue
Definition: srb.h:254
#define PAGED_CODE()
Definition: video.h:57
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
struct _CDVD_CAPABILITIES_PAGE * PCDVD_CAPABILITIES_PAGE
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define SCSIOP_MODE_SENSE10
Definition: cdrw_hw.h:946
union _CDB * PCDB
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
struct _CDB::_MODE_SENSE MODE_SENSE
if(!(yy_init))
Definition: macro.lex.yy.c:714
NTSTATUS NTAPI ClassSendSrbSynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:2648
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MODE_PAGE_CAPABILITIES
Definition: cdrw_hw.h:854
unsigned char UCHAR
Definition: xmlstorage.h:181
#define CDROM_TAG_MODE_DATA
Definition: cdrom.h:330
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
USHORT XAFlags
Definition: cdrom.c:82
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define FILE_DEVICE_DVD
Definition: winioctl.h:156
#define XA_USE_6_BYTE
Definition: cdrom.c:208
#define DEVICE_TYPE
Definition: guid.c:10
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by CdRomDeviceControlDispatch(), CdRomInitDevice(), and CdRomStartDevice().

◆ CdRomInitDevice()

NTSTATUS NTAPI CdRomInitDevice ( IN PDEVICE_OBJECT  Fdo)

Definition at line 512 of file cdrom.c.

537 {
538  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
539  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
540 #if 0
542  Fdo->DriverObject);
543 #endif
544 
545  PVOID senseData = NULL;
546 
547  ULONG timeOut;
548  PCDROM_DATA cddata = NULL;
549 
550  //BOOLEAN changerDevice;
551  BOOLEAN isMmcDevice = FALSE;
552 
553  ULONG bps;
554  ULONG lastBit;
555 
556 
558 
559  PAGED_CODE();
560 
561  //
562  // Build the lookaside list for srb's for the physical disk. Should only
563  // need a couple.
564  //
565 
568 
569  //
570  // Allocate request sense buffer.
571  //
572 
576 
577  if (senseData == NULL) {
578 
579  //
580  // The buffer cannot be allocated.
581  //
582 
584  goto CdRomInitDeviceExit;
585  }
586 
587  //
588  // Set the sense data pointer in the device extension.
589  //
590 
591  fdoExtension->SenseData = senseData;
592 
593  //
594  // CDROMs are not partitionable so starting offset is 0.
595  //
596 
597  commonExtension->StartingOffset.LowPart = 0;
598  commonExtension->StartingOffset.HighPart = 0;
599 
600  //
601  // Set timeout value in seconds.
602  //
603 
604  timeOut = ClassQueryTimeOutRegistryValue(Fdo);
605  if (timeOut) {
606  fdoExtension->TimeOutValue = timeOut;
607  } else {
608  fdoExtension->TimeOutValue = SCSI_CDROM_TIMEOUT;
609  }
610 
611  cddata = (PCDROM_DATA)(commonExtension->DriverData);
612 
613  //
614  // Set up media change support defaults.
615  //
616 
618 
619  cddata->DelayedRetryIrp = NULL;
620  cddata->DelayedRetryInterval = 0;
621  cddata->Mmc.WriteAllowed = FALSE;
622 
623  //
624  // Scan for controllers that require special processing.
625  //
626 
627  ScanForSpecial(Fdo);
628 
629  //
630  // Determine if the drive is MMC-Capable
631  //
632 
633  CdRomIsDeviceMmcDevice(Fdo, &isMmcDevice);
634 
635  if (!isMmcDevice) {
636 
637  SET_FLAG(Fdo->Characteristics, FILE_READ_ONLY_DEVICE);
638 
639  } else {
640 
641  //
642  // the drive supports at least a subset of MMC commands
643  // (and therefore supports READ_CD, etc...)
644  //
645 
646  cddata->Mmc.IsMmc = TRUE;
647 
648  //
649  // allocate a buffer for all the capabilities and such
650  //
651 
653  if (!NT_SUCCESS(status)) {
654  goto CdRomInitDeviceExit;
655  }
656 
657 
658 #if 0
659  //
660  // determine all the various media types from the profiles feature
661  //
662  {
663  PFEATURE_DATA_PROFILE_LIST profileHeader;
664  ULONG mediaTypes = 0;
665  ULONG i;
666 
668  "Checking all profiles for media types supported.\n"
669  ));
670 
671  profileHeader = CdRomFindFeaturePage(cddata->Mmc.CapabilitiesBuffer,
672  cddata->Mmc.CapabilitiesBufferSize,
674  if (profileHeader == NULL) {
675 
676  //
677  // if profiles don't exist, there is something seriously
678  // wrong with this command -- it's either not a cdrom or
679  // one that hasn't implemented the spec correctly. exit
680  // now while we have the chance to do so safely.
681  //
683  "CdromDevice supports GET_CONFIGURATION, but "
684  "doesn't provide profiles for PDO %p!\n",
685  fdoExtension->LowerPdo));
687  goto CdRomInitDeviceExit;
688 
689  }
690 
691  for (i = 0; i < MAX_CDROM_MEDIA_TYPES; i++) {
692 
693  BOOLEAN profileFound;
694  CdRomFindProfileInProfiles(profileHeader,
695  MediaProfileMatch[i].Profile,
696  &profileFound);
697  if (profileFound) {
698 
700  "CdromInit -> Found Profile %x => Media %x "
701  "(%x total)\n",
702  MediaProfileMatch[i].Profile,
703  MediaProfileMatch[i].Media,
704  mediaTypes + 1
705  ));
706 
707  cddata->Mmc.MediaProfileMatches[mediaTypes] =
708  MediaProfileMatch[i];
709  mediaTypes++;
710 
711  }
712 
713  }
714 
715  if (mediaTypes == 0) {
716 
717  //
718  // if profiles don't exist, there is something seriously
719  // wrong with this command -- it's either not a cdrom or
720  // one that hasn't implemented the spec correctly. exit
721  // now while we have the chance to do so safely.
722  //
724  "CdromDevice supports GET_CONFIGURATION, but "
725  "doesn't support any of the standard profiles "
726  "for PDO %p!\n", fdoExtension->LowerPdo));
728  goto CdRomInitDeviceExit;
729 
730  }
731 
732  cddata->Mmc.MediaTypes = mediaTypes;
733 
734 
735  }
736 #endif // media checks, and all failure paths due to bad firmware.
737 
738  //
739  // if the drive supports target defect management and sector-addressable
740  // writes, then we should allow writes to the media.
741  //
742 
744  cddata->Mmc.CapabilitiesBufferSize,
747  cddata->Mmc.CapabilitiesBufferSize,
749 
750  //
751  // the drive is target defect managed, and supports random writes
752  // on sector-alignment. allow writes to occur by setting the error
753  // handler to point to a private media change detection handler.
754  //
755 
757  "Found a WRITE capable device: %p\n", Fdo));
758 
759  //
760  // the write specific pages have been found --
761  // set the error handler and set it to require an update!
762  //
763 
766 
767  }
768 
769  //
770  // ISSUE-2000/4/4-henrygab - mmc-compliant compliant drives should
771  // be initialized based upon reported
772  // capabilities, such as CSS, Analogue Audio,
773  // READ_CD capabilities, and (possibly) even
774  // drive capacity information.
775  //
776 
778  "Defaulting to READ_CD because device %p is MMC compliant\n",
779  Fdo));
780  SET_FLAG(fdoExtension->DeviceFlags, DEV_SAFE_START_UNIT);
781  SET_FLAG(cddata->XAFlags, XA_USE_READ_CD);
782 
783  }
784 
785 
786  //
787  // Set the default geometry for the cdrom to match what NT 4 used.
788  // Classpnp will use these values to compute the cylinder count rather
789  // than using it's NT 5.0 defaults.
790  //
791 
792  fdoExtension->DiskGeometry.TracksPerCylinder = 0x40;
793  fdoExtension->DiskGeometry.SectorsPerTrack = 0x20;
794 
795  //
796  // Do READ CAPACITY. This SCSI command returns the last sector address
797  // on the device and the bytes per sector. These are used to calculate
798  // the drive capacity in bytes.
799  //
800  // NOTE: This should be change to send the Srb synchronously, then
801  // call CdRomInterpretReadCapacity() to properly setup the defaults.
802  //
803 
805 
806  bps = fdoExtension->DiskGeometry.BytesPerSector;
807 
808  if (!NT_SUCCESS(status) || !bps) {
809 
811  "CdRomStartDevice: Can't read capacity for device %wZ\n",
812  &(fdoExtension->CommonExtension.DeviceName)));
813 
814  //
815  // Set disk geometry to default values (per ISO 9660).
816  //
817 
818  bps = 2048;
819  fdoExtension->SectorShift = 11;
820  commonExtension->PartitionLength.QuadPart = (LONGLONG)(0x7fffffff);
821 
822  } else {
823 
824  //
825  // Insure that bytes per sector is a power of 2
826  // This corrects a problem with the HP 4020i CDR where it
827  // returns an incorrect number for bytes per sector.
828  //
829 
830  lastBit = (ULONG) -1;
831  while (bps) {
832  lastBit++;
833  bps = bps >> 1;
834  }
835 
836  bps = 1 << lastBit;
837  }
838  fdoExtension->DiskGeometry.BytesPerSector = bps;
839  TraceLog((CdromDebugTrace, "CdRomInitDevice: Calc'd bps = %x\n", bps));
840 
841 
842  ClassInitializeMediaChangeDetection(fdoExtension, "CdRom");
843 
844 
845  //
846  // test for audio read capabilities
847  //
848 
850  "Detecting XA_READ capabilities\n"));
851 
852  if (CdRomGetDeviceType(Fdo) == FILE_DEVICE_DVD) {
853 
855  "CdRomInitDevice: DVD Devices require START_UNIT\n"));
856 
857 
858  //
859  // all DVD devices must support the READ_CD command
860  //
861 
863  "CdRomDetermineRawReadCapabilities: DVD devices "
864  "support READ_CD command for FDO %p\n", Fdo));
865  SET_FLAG(fdoExtension->DeviceFlags, DEV_SAFE_START_UNIT);
866  SET_FLAG(cddata->XAFlags, XA_USE_READ_CD);
867 
868 
870 
871  } else if ((fdoExtension->DeviceDescriptor->BusType != BusTypeScsi) &&
872  (fdoExtension->DeviceDescriptor->BusType != BusTypeAta) &&
873  (fdoExtension->DeviceDescriptor->BusType != BusTypeAtapi) &&
874  (fdoExtension->DeviceDescriptor->BusType != BusTypeUnknown)
875  ) {
876 
877  //
878  // devices on the newer busses must support READ_CD command
879  //
880 
882  "CdRomDetermineRawReadCapabilities: Devices for newer "
883  "busses must support READ_CD command for FDO %p, Bus %x\n",
884  Fdo, fdoExtension->DeviceDescriptor->BusType));
885  SET_FLAG(fdoExtension->DeviceFlags, DEV_SAFE_START_UNIT);
886  SET_FLAG(cddata->XAFlags, XA_USE_READ_CD);
887 
888  }
889 
890  //
891  // now clear all our READ_CD flags if the drive should have supported
892  // it, but we are not sure it actually does. we still won't query
893  // the drive more than one time if it supports the command.
894  //
895 
897 
899  "Forcing detection of READ_CD for FDO %p because "
900  "testing showed some firmware did not properly support it\n",
901  Fdo));
903 
904  }
905 
906 
907  //
908  // read our READ_CD support in the registry if it was seeded.
909  //
910  {
911  ULONG readCdSupported = 0;
912 
913  ClassGetDeviceParameter(fdoExtension,
916  &readCdSupported
917  );
918 
919  if (readCdSupported != 0) {
920 
922  "Defaulting to READ_CD because previously detected "
923  "that the device supports it for Fdo %p.\n",
924  Fdo
925  ));
926  SET_FLAG(cddata->XAFlags, XA_USE_READ_CD);
927 
928  }
929 
930  }
931 
932 
933  //
934  // backwards-compatible hackish attempt to determine if the drive
935  // supports any method of reading digital audio from the disc.
936  //
937 
938  if (!TEST_FLAG(cddata->XAFlags, XA_USE_READ_CD)) {
939 
940  SCSI_REQUEST_BLOCK srb;
941  PCDB cdb;
942  ULONG length;
943  PUCHAR buffer = NULL;
944  ULONG count;
945 
946  //
947  // ISSUE-2000/07/05-henrygab - use the mode page to determine
948  // READ_CD support, then fall back on the below
949  // (unreliable?) hack.
950  //
951 
952  //
953  // Build the MODE SENSE CDB. The data returned will be kept in the
954  // device extension and used to set block size.
955  //
956 
958 
960  length,
962 
963  if (!buffer) {
965  "CdRomDetermineRawReadCapabilities: cannot allocate "
966  "buffer, so leaving for FDO %p\n", Fdo));
968  goto CdRomInitDeviceExit;
969  }
970 
971  for (count = 0; count < 2; count++) {
972 
973  if (count == 0) {
974  length = sizeof(ERROR_RECOVERY_DATA);
975  } else {
976  length = sizeof(ERROR_RECOVERY_DATA10);
977  }
978 
980  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
981  cdb = (PCDB)srb.Cdb;
982 
983  srb.TimeOutValue = fdoExtension->TimeOutValue;
984 
985  if (count == 0) {
986  srb.CdbLength = 6;
987  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
988  cdb->MODE_SENSE.PageCode = 0x1;
989  // note: not setting DBD in order to get the block descriptor!
990  cdb->MODE_SENSE.AllocationLength = (UCHAR)length;
991  } else {
992  srb.CdbLength = 10;
993  cdb->MODE_SENSE10.OperationCode = SCSIOP_MODE_SENSE10;
994  cdb->MODE_SENSE10.PageCode = 0x1;
995  // note: not setting DBD in order to get the block descriptor!
996  cdb->MODE_SENSE10.AllocationLength[0] = (UCHAR)(length >> 8);
997  cdb->MODE_SENSE10.AllocationLength[1] = (UCHAR)(length & 0xFF);
998  }
999 
1001  &srb,
1002  buffer,
1003  length,
1004  FALSE);
1005 
1006 
1008 
1009  //
1010  // STATUS_DATA_OVERRUN means it's a newer drive with more info
1011  // to tell us, so it's probably able to support READ_CD
1012  //
1013 
1015 
1016  srb.CdbLength = 12;
1017  cdb->READ_CD.OperationCode = SCSIOP_READ_CD;
1018 
1020  &srb,
1021  NULL,
1022  0,
1023  FALSE);
1024 
1025  if (NT_SUCCESS(status) ||
1029  ) {
1030 
1031  //
1032  // READ_CD works
1033  //
1034 
1036  "CdRomDetermineRawReadCapabilities: Using "
1037  "READ_CD for FDO %p due to status %x\n",
1038  Fdo,
1039  status));
1040  SET_FLAG(cddata->XAFlags, XA_USE_READ_CD);
1041 
1042  //
1043  // ignore errors in saving this info
1044  //
1045 
1046  ClassSetDeviceParameter(fdoExtension,
1049  1
1050  );
1051 
1052 
1053  break; // out of the for loop
1054 
1055  }
1056 
1058  "CdRomDetermineRawReadCapabilities: Using "
1059  "%s-byte mode switching for FDO %p due to status "
1060  "%x returned for READ_CD\n",
1061  ((count == 0) ? "6" : "10"), Fdo, status));
1062 
1063  if (count == 0) {
1064  SET_FLAG(cddata->XAFlags, XA_USE_6_BYTE);
1065  RtlCopyMemory(&cddata->Header,
1066  buffer,
1067  sizeof(ERROR_RECOVERY_DATA));
1068  cddata->Header.ModeDataLength = 0;
1069  } else {
1070  SET_FLAG(cddata->XAFlags, XA_USE_10_BYTE);
1071  RtlCopyMemory(&cddata->Header10,
1072  buffer,
1073  sizeof(ERROR_RECOVERY_DATA10));
1074  cddata->Header10.ModeDataLength[0] = 0;
1075  cddata->Header10.ModeDataLength[1] = 0;
1076  }
1077  break; // out of for loop
1078 
1079  }
1081  "FDO %p failed %x byte mode sense, status %x\n",
1082  Fdo,
1083  ((count == 0) ? 6 : 10),
1084  status
1085  ));
1086 
1087  //
1088  // mode sense failed
1089  //
1090 
1091  } // end of for loop to try 6 and 10-byte mode sense
1092 
1093  if (count == 2) {
1094 
1095  //
1096  // nothing worked. we probably cannot support digital
1097  // audio extraction from this drive
1098  //
1099 
1101  "CdRomDetermineRawReadCapabilities: FDO %p "
1102  "cannot support READ_CD\n", Fdo));
1104  CLEAR_FLAG(cddata->XAFlags, XA_NEC_CDDA);
1105  SET_FLAG(cddata->XAFlags, XA_NOT_SUPPORTED);
1106 
1107  } // end of count == 2
1108 
1109  //
1110  // free our resources
1111  //
1112 
1113  ExFreePool(buffer);
1114 
1115  //
1116  // set a successful status
1117  // (in case someone later checks this)
1118  //
1119 
1121 
1122  }
1123 
1124  //
1125  // Register interfaces for this device.
1126  //
1127 
1128  {
1129  UNICODE_STRING interfaceName;
1130 
1131  RtlInitUnicodeString(&interfaceName, NULL);
1132 
1133  status = IoRegisterDeviceInterface(fdoExtension->LowerPdo,
1134  (LPGUID) &CdRomClassGuid,
1135  NULL,
1136  &interfaceName);
1137 
1138  if(NT_SUCCESS(status)) {
1139 
1140  cddata->CdromInterfaceString = interfaceName;
1141 
1143  &interfaceName,
1144  TRUE);
1145 
1146  if(!NT_SUCCESS(status)) {
1147 
1149  "CdromInitDevice: Unable to register cdrom "
1150  "DCA for fdo %p [%lx]\n",
1151  Fdo, status));
1152  }
1153  }
1154  }
1155 
1156  return(STATUS_SUCCESS);
1157 
1158 CdRomInitDeviceExit:
1159 
1161  RtlZeroMemory(&(cddata->Mmc), sizeof(CDROM_MMC_EXTENSION));
1162 
1163  return status;
1164 
1165 }
#define CDB12GENERIC_LENGTH
Definition: cdrom.c:21
LARGE_INTEGER PartitionLength
Definition: classpnp.h:594
#define CDROM_READ_CD_NAME
Definition: cdrom.h:351
#define max(a, b)
Definition: svc.c:63
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
PCLASS_ERROR ErrorHandler
Definition: cdrom.h:170
#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 STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI ScanForSpecial(PDEVICE_OBJECT DeviceObject, PINQUIRYDATA InquiryData, PIO_SCSI_CAPABILITIES PortCapabilities)
Definition: cdrom.c:5271
UCHAR Cdb[16]
Definition: srb.h:271
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
UNICODE_STRING CdromInterfaceString
Definition: cdrom.h:224
PVOID NTAPI CdRomFindFeaturePage(IN PGET_CONFIGURATION_HEADER FeatureBuffer, IN ULONG Length, IN FEATURE_NUMBER Feature)
Definition: mmc.c:115
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:704
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define CDROM_SUBKEY_NAME
Definition: cdrom.h:350
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
#define CDROM_SRB_LIST_SIZE
Definition: cdrom.c:177
struct _CDB::_MODE_SENSE10 MODE_SENSE10
UCHAR CdbLength
Definition: srb.h:250
GLuint buffer
Definition: glext.h:5915
ULONG BytesPerSector
Definition: ntdddisk.h:381
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
struct _ERROR_RECOVERY_DATA ERROR_RECOVERY_DATA
VOID NTAPI CdRomIsDeviceMmcDevice(IN PDEVICE_OBJECT Fdo, OUT PBOOLEAN IsMmc)
Definition: mmc.c:424
ULONG TimeOutValue
Definition: srb.h:254
VOID NTAPI CdRomMmcErrorHandler(IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, OUT PNTSTATUS Status, OUT PBOOLEAN Retry)
Definition: cdrom.c:6443
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
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
#define SCSI_CDROM_TIMEOUT
Definition: cdrom.c:170
NTSTATUS NTAPI ClassSetDeviceParameter(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PWSTR SubkeyName OPTIONAL, IN PWSTR ParameterName, IN ULONG ParameterValue)
Definition: utils.c:136
ULONG_PTR HackFlags
Definition: cdrom.h:163
ULONG DelayedRetryInterval
Definition: cdrom.h:209
#define CLEAR_FLAG(Flags, Bit)
Definition: classpnp.h:155
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
#define SCSIOP_MODE_SENSE10
Definition: cdrw_hw.h:946
KSPIN_LOCK DelayedRetrySpinLock
Definition: cdrom.h:211
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI CdRomFindProfileInProfiles(IN PFEATURE_DATA_PROFILE_LIST ProfileHeader, IN FEATURE_PROFILE_TYPE ProfileToFind, OUT PBOOLEAN Exists)
Definition: mmc.c:69
union _CDB * PCDB
PCLASS_DRIVER_EXTENSION NTAPI ClassGetDriverExtension(IN PDRIVER_OBJECT DriverObject)
Definition: class.c:7236
#define CDROM_HACK_FORCE_READ_CD_DETECTION
Definition: cdrom.h:65
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
VOID NTAPI ClassGetDeviceParameter(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PWSTR SubkeyName OPTIONAL, IN PWSTR ParameterName, IN OUT PULONG ParameterValue)
Definition: utils.c:52
struct _CDB::_MODE_SENSE MODE_SENSE
#define TraceLog(x)
Definition: trace.h:14
LARGE_INTEGER StartingOffset
Definition: classpnp.h:595
int64_t LONGLONG
Definition: typedefs.h:67
VOID NTAPI ClassInitializeSrbLookasideList(IN PCOMMON_DEVICE_EXTENSION CommonExtension, IN ULONG NumberElements)
Definition: obsolete.c:941
if(!(yy_init))
Definition: macro.lex.yy.c:714
NTSTATUS NTAPI ClassSendSrbSynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:2648
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
ULONG WriteAllowed
Definition: cdrom.h:123
ULONG SectorsPerTrack
Definition: ntdddisk.h:380
#define XA_PLEXTOR_CDDA
Definition: cdrom.h:300
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:698
PIRP DelayedRetryIrp
Definition: cdrom.h:207
VOID NTAPI CdRomDeAllocateMmcResources(IN PDEVICE_OBJECT Fdo)
Definition: mmc.c:1335
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:697
ULONG LowPart
Definition: typedefs.h:105
ULONG CapabilitiesBufferSize
Definition: cdrom.h:134
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
#define CDROM_TAG_MODE_DATA
Definition: cdrom.h:330
ULONG NTAPI ClassQueryTimeOutRegistryValue(IN PDEVICE_OBJECT DeviceObject)
Definition: class.c:6190
USHORT XAFlags
Definition: cdrom.c:82
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
struct _ERROR_RECOVERY_DATA10 ERROR_RECOVERY_DATA10
#define FILE_DEVICE_DVD
Definition: winioctl.h:156
DEVICE_TYPE NTAPI CdRomGetDeviceType(IN PDEVICE_OBJECT DeviceObject)
Definition: cdrom.c:5493
#define XA_USE_6_BYTE
Definition: cdrom.c:208
#define DEV_SAFE_START_UNIT
Definition: class2.h:35
#define XA_USE_READ_CD
Definition: cdrom.c:210
#define CdromMmcUpdateRequired
Definition: cdrom.h:117
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:157
VOID NTAPI ClassInitializeMediaChangeDetection(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PUCHAR EventPrefix)
Definition: autorun.c:2058
#define XA_USE_10_BYTE
Definition: cdrom.c:209
#define XA_NEC_CDDA
Definition: cdrom.h:301
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define SCSIOP_READ_CD
Definition: cdrw_hw.h:967
#define CDROM_TAG_SENSE_INFO
Definition: cdrom.h:326
NTSTATUS NTAPI CdRomAllocateMmcResources(IN PDEVICE_OBJECT Fdo)
Definition: mmc.c:1369
struct _CDB::_READ_CD READ_CD
PGET_CONFIGURATION_HEADER CapabilitiesBuffer
Definition: cdrom.h:133
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:605
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSTATUS NTAPI ClassReadDriveCapacity(IN PDEVICE_OBJECT Fdo)
Definition: class.c:1729
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
LONGLONG QuadPart
Definition: typedefs.h:113
Definition: ps.c:97

Referenced by DriverEntry().

◆ CdRomIsPlayActive()

BOOLEAN NTAPI CdRomIsPlayActive ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 4712 of file cdrom.c.

4731 {
4733  IO_STATUS_BLOCK ioStatus;
4734  PSUB_Q_CURRENT_POSITION currentBuffer;
4735 
4736  PAGED_CODE();
4737 
4738  //
4739  // if we don't think it is playing audio, don't bother checking.
4740  //
4741 
4742  if (!PLAY_ACTIVE(fdoExtension)) {
4743  return(FALSE);
4744  }
4745 
4747  sizeof(SUB_Q_CURRENT_POSITION),
4749 
4750  if (currentBuffer == NULL) {
4751  return(FALSE);
4752  }
4753 
4754  ((PCDROM_SUB_Q_DATA_FORMAT) currentBuffer)->Format = IOCTL_CDROM_CURRENT_POSITION;
4755  ((PCDROM_SUB_Q_DATA_FORMAT) currentBuffer)->Track = 0;
4756 
4757  //
4758  // Build the synchronous request to be sent to ourself
4759  // to perform the request.
4760  //
4761 
4764  DeviceObject,
4765  currentBuffer,
4766  sizeof(CDROM_SUB_Q_DATA_FORMAT),
4767  sizeof(SUB_Q_CURRENT_POSITION),
4768  FALSE,
4769  &ioStatus);
4770 
4771  if (!NT_SUCCESS(ioStatus.Status)) {
4772  ExFreePool(currentBuffer);
4773  return FALSE;
4774  }
4775 
4776  //
4777  // should update the playactive flag here.
4778  //
4779 
4780  if (currentBuffer->Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS) {
4781  PLAY_ACTIVE(fdoExtension) = TRUE;
4782  } else {
4783  PLAY_ACTIVE(fdoExtension) = FALSE;
4784  }
4785 
4786  ExFreePool(currentBuffer);
4787 
4788  return(PLAY_ACTIVE(fdoExtension));
4789 
4790 }
#define TRUE
Definition: types.h:120
SUB_Q_HEADER Header
Definition: ntddcdrm.h:314
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
#define PAGED_CODE()
Definition: video.h:57
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define AUDIO_STATUS_IN_PROGRESS
Definition: ntddcdrm.h:281
#define CDROM_TAG_PLAY_ACTIVE
Definition: cdrom.h:332
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
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
UCHAR AudioStatus
Definition: ntddcdrm.h:289
struct _CDROM_SUB_Q_DATA_FORMAT * PCDROM_SUB_Q_DATA_FORMAT
#define PLAY_ACTIVE(DeviceExtension)
Definition: cdrom.c:190
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:70
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ CdRomMmcErrorHandler()

VOID NTAPI CdRomMmcErrorHandler ( IN PDEVICE_OBJECT  Fdo,
IN PSCSI_REQUEST_BLOCK  Srb,
OUT PNTSTATUS  Status,
OUT PBOOLEAN  Retry 
)

Definition at line 6443 of file cdrom.c.

6449 {
6450  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
6451  //BOOLEAN queryCapabilities = FALSE;
6452 
6453  if (TEST_FLAG(Srb->SrbStatus, SRB_STATUS_AUTOSENSE_VALID)) {
6454 
6455  PCDROM_DATA cddata = (PCDROM_DATA)commonExtension->DriverData;
6456  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
6457 
6458  //
6459  // the following sense keys could indicate a change in
6460  // capabilities.
6461  //
6462 
6463  //
6464  // we used to expect this to be serialized, and only hit from our
6465  // own routine. we now allow some requests to continue during our
6466  // processing of the capabilities update in order to allow
6467  // IoReadPartitionTable() to succeed.
6468  //
6469 
6470  switch (senseBuffer->SenseKey & 0xf) {
6471 
6472  case SCSI_SENSE_NOT_READY: {
6473  if (senseBuffer->AdditionalSenseCode ==
6475 
6476  if (cddata->Mmc.WriteAllowed) {
6478  "CdromErrorHandler: media removed, writes will be "
6479  "failed until new media detected\n"));
6480  }
6481 
6482  // NOTE - REF #0002
6483  cddata->Mmc.WriteAllowed = FALSE;
6484  } else
6485  if ((senseBuffer->AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY) &&
6486  (senseBuffer->AdditionalSenseCodeQualifier ==
6489  "CdromErrorHandler: media becoming ready, "
6490  "SHOULD notify shell of change time by sending "
6491  "GESN request immediately!\n"));
6492  }
6493  break;
6494  } // end SCSI_SENSE_NOT_READY
6495 
6497  switch (senseBuffer->AdditionalSenseCode) {
6499 
6500  //
6501  // always update if the medium may have changed
6502  //
6503 
6504  // NOTE - REF #0002
6505  cddata->Mmc.WriteAllowed = FALSE;
6509 
6511  "CdromErrorHandler: media change detected, need to "
6512  "update drive capabilities\n"));
6513  break;
6514 
6515  } // end SCSI_ADSENSE_MEDIUM_CHANGED
6516 
6517  case SCSI_ADSENSE_BUS_RESET: {
6518 
6519  // NOTE - REF #0002
6520  cddata->Mmc.WriteAllowed = FALSE;
6524 
6526  "CdromErrorHandler: bus reset detected, need to "
6527  "update drive capabilities\n"));
6528  break;
6529 
6530  } // end SCSI_ADSENSE_BUS_RESET
6531 
6533 
6534  BOOLEAN b = FALSE;
6535 
6536  switch (senseBuffer->AdditionalSenseCodeQualifier) {
6538 
6539  //
6540  // eject notification currently handled by classpnp
6541  //
6542 
6544  "CdromErrorHandler: Eject requested by user\n"));
6545  *Retry = TRUE;
6547  break;
6548  }
6549 
6551  b = TRUE;
6553 
6555  "CdromErrorHandler: Write protect %s requested "
6556  "by user\n",
6557  (b ? "disable" : "enable")));
6558  *Retry = TRUE;
6560  // NOTE - REF #0002
6561  cddata->Mmc.WriteAllowed = FALSE;
6565 
6566  }
6567 
6568  } // end of AdditionalSenseCodeQualifier switch
6569 
6570 
6571  break;
6572 
6573  } // end SCSI_ADSENSE_OPERATOR_REQUEST
6574 
6575  default: {
6577  "CdromErrorHandler: Unit attention %02x/%02x\n",
6578  senseBuffer->AdditionalSenseCode,
6579  senseBuffer->AdditionalSenseCodeQualifier));
6580  break;
6581  }
6582 
6583  } // end of AdditionSenseCode switch
6584  break;
6585 
6586  } // end SCSI_SENSE_UNIT_ATTENTION
6587 
6589  if (senseBuffer->AdditionalSenseCode ==
6591 
6592  if (cddata->Mmc.WriteAllowed) {
6594  "CdromErrorHandler: media was writable, but "
6595  "failed request with WRITE_PROTECT error...\n"));
6596  }
6597  // NOTE - REF #0002
6598  // do not update all the capabilities just because
6599  // we can't write to the disc.
6600  cddata->Mmc.WriteAllowed = FALSE;
6601  }
6602  break;
6603  } // end SCSI_SENSE_ILLEGAL_REQUEST
6604 
6605  } // end of SenseKey switch
6606 
6607  } // end of SRB_STATUS_AUTOSENSE_VALID
6608 }
#define SCSI_ADSENSE_WRITE_PROTECT
Definition: cdrw_hw.h:1268
#define TRUE
Definition: types.h:120
#define SCSI_SENSEQ_MEDIUM_REMOVAL
Definition: scsi.h:644
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
#define SCSI_ADSENSE_OPERATOR_REQUEST
Definition: scsi.h:578
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
switch(r->id)
Definition: btrfs.c:2904
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
ULONG WriteAllowed
Definition: cdrom.h:123
#define SCSI_ADSENSE_BUS_RESET
Definition: cdrw_hw.h:1289
#define CdromMmcUpdateComplete
Definition: cdrom.h:116
Status
Definition: gdiplustypes.h:24
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define CdromMmcUpdateRequired
Definition: cdrom.h:117
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:157
#define SCSI_SENSEQ_WRITE_PROTECT_ENABLE
Definition: scsi.h:645
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
#define SCSI_SENSEQ_WRITE_PROTECT_DISABLE
Definition: scsi.h:646
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288

Referenced by CdRomInitDevice().

◆ CdRomPickDvdRegion()

VOID NTAPI CdRomPickDvdRegion ( IN PDEVICE_OBJECT  Fdo)

Definition at line 5890 of file cdrom.c.

5908 {
5909  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
5910  PCDROM_DATA cddata = (PCDROM_DATA)(commonExtension->DriverData);
5911 
5912  //
5913  // these five pointers all point to dvdReadStructure or part of
5914  // its data, so don't deallocate them more than once!
5915  //
5916 
5917  PDVD_READ_STRUCTURE dvdReadStructure;
5918  PDVD_COPY_PROTECT_KEY copyProtectKey;
5919  PDVD_COPYRIGHT_DESCRIPTOR dvdCopyRight;
5920  PDVD_RPC_KEY rpcKey;
5921  PDVD_SET_RPC_KEY dvdRpcKey;
5922 
5923  IO_STATUS_BLOCK ioStatus;
5924  ULONG bufferLen;
5925  UCHAR mediaRegion;
5926  ULONG pickDvdRegion;
5927  ULONG defaultDvdRegion;
5928  ULONG dvdRegion;
5929  ULONG a, b;
5930 
5931 
5932  PAGED_CODE();
5933 
5934  if ((pickDvdRegion = InterlockedExchange(&cddata->PickDvdRegion, 0)) == 0) {
5935 
5936  //
5937  // it was non-zero, so either another thread will do this, or
5938  // we no longer need to pick a region
5939  //
5940 
5941  return;
5942  }
5943 
5944  //
5945  // short-circuit if license agreement violated
5946  //
5947 
5948  if (cddata->DvdRpc0LicenseFailure) {
5950  "DVD License failure. Refusing to pick a region\n"));
5951  InterlockedExchange(&cddata->PickDvdRegion, 0);
5952  return;
5953  }
5954 
5955 
5956 
5957  a = max(sizeof(DVD_DESCRIPTOR_HEADER) +
5958  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
5959  sizeof(DVD_READ_STRUCTURE)
5960  );
5963  );
5964  bufferLen = max(a, b);
5965 
5966  dvdReadStructure = (PDVD_READ_STRUCTURE)
5968 
5969  if (dvdReadStructure == NULL) {
5970  InterlockedExchange(&cddata->PickDvdRegion, pickDvdRegion);
5971  return;
5972  }
5973 
5974  if (cddata->DvdRpc0Device && cddata->Rpc0RetryRegistryCallback) {
5975 
5977  "CdRomPickDvdRegion (%p): now retrying RPC0 callback\n",
5978  Fdo));
5979 
5980  //
5981  // get the registry settings again
5982  //
5983 
5984  ioStatus.Status = CdRomGetRpc0Settings(Fdo);
5985 
5986  if (ioStatus.Status == STATUS_LICENSE_VIOLATION) {
5987 
5988  //
5989  // if this is the returned error, then
5990  // the routine should have set this!
5991  //
5992 
5993  ASSERT(cddata->DvdRpc0LicenseFailure);
5994  cddata->DvdRpc0LicenseFailure = 1;
5996  "CdRomPickDvdRegion (%p): "
5997  "setting to fail all dvd ioctls due to CSS licensing "
5998  "failure.\n", Fdo));
5999 
6000  pickDvdRegion = 0;
6001  goto getout;
6002 
6003  }
6004 
6005  //
6006  // get the device region, again
6007  //
6008 
6009  copyProtectKey = (PDVD_COPY_PROTECT_KEY)dvdReadStructure;
6010  RtlZeroMemory(copyProtectKey, bufferLen);
6011  copyProtectKey->KeyLength = DVD_RPC_KEY_LENGTH;
6012  copyProtectKey->KeyType = DvdGetRpcKey;
6013 
6014  //
6015  // Build a request for READ_KEY
6016  //
6017 
6020  Fdo,
6021  copyProtectKey,
6024  FALSE,
6025  &ioStatus);
6026 
6027  if (!NT_SUCCESS(ioStatus.Status)) {
6029  "CdRomPickDvdRegion: Unable to get "
6030  "device RPC data (%x)\n", ioStatus.Status));
6031  pickDvdRegion = 0;
6032  goto getout;
6033  }
6034 
6035  //
6036  // now that we have gotten the device's RPC data,
6037  // we have set the device extension to usable data.
6038  // no need to call back into this section of code again
6039  //
6040 
6041  cddata->Rpc0RetryRegistryCallback = 0;
6042 
6043 
6044  rpcKey = (PDVD_RPC_KEY) copyProtectKey->KeyData;
6045 
6046  //
6047  // TypeCode of zero means that no region has been set.
6048  //
6049 
6050  if (rpcKey->TypeCode != 0) {
6052  "CdRomPickDvdRegion (%p): DVD Region already "
6053  "chosen\n", Fdo));
6054  pickDvdRegion = 0;
6055  goto getout;
6056  }
6057 
6059  "CdRomPickDvdRegion (%p): must choose initial DVD "
6060  " Region\n", Fdo));
6061  }
6062 
6063 
6064 
6065  copyProtectKey = (PDVD_COPY_PROTECT_KEY) dvdReadStructure;
6066 
6067  dvdCopyRight = (PDVD_COPYRIGHT_DESCRIPTOR)
6068  ((PDVD_DESCRIPTOR_HEADER) dvdReadStructure)->Data;
6069 
6070  //
6071  // get the media region
6072  //
6073 
6074  RtlZeroMemory (dvdReadStructure, bufferLen);
6075  dvdReadStructure->Format = DvdCopyrightDescriptor;
6076 
6077  //
6078  // Build and send a request for READ_KEY
6079  //
6080 
6082  "CdRomPickDvdRegion (%p): Getting Copyright Descriptor\n",
6083  Fdo));
6084 
6087  Fdo,
6088  dvdReadStructure,
6089  sizeof(DVD_READ_STRUCTURE),
6090  sizeof (DVD_DESCRIPTOR_HEADER) +
6091  sizeof(DVD_COPYRIGHT_DESCRIPTOR),
6092  FALSE,
6093  &ioStatus
6094  );
6096  "CdRomPickDvdRegion (%p): Got Copyright Descriptor %x\n",
6097  Fdo, ioStatus.Status));
6098 
6099  if ((NT_SUCCESS(ioStatus.Status)) &&
6100  (dvdCopyRight->CopyrightProtectionType == 0x01)
6101  ) {
6102 
6103  //
6104  // keep the media region bitmap around
6105  // a 1 means ok to play
6106  //
6107 
6108  if (dvdCopyRight->RegionManagementInformation == 0xff) {
6110  "CdRomPickDvdRegion (%p): RegionManagementInformation "
6111  "is set to dis-allow playback for all regions. This is "
6112  "most likely a poorly authored disc. defaulting to all "
6113  "region disc for purpose of choosing initial region\n",
6114  Fdo));
6115  dvdCopyRight->RegionManagementInformation = 0;
6116  }
6117 
6118 
6119  mediaRegion = ~dvdCopyRight->RegionManagementInformation;
6120 
6121  } else {
6122 
6123  //
6124  // could be media, can't set the device region
6125  //
6126 
6127  if (!cddata->DvdRpc0Device) {
6128 
6129  //
6130  // can't automatically pick a default region on a rpc2 drive
6131  // without media, so just exit
6132  //
6134  "CdRomPickDvdRegion (%p): failed to auto-choose "
6135  "a region due to status %x getting copyright "
6136  "descriptor\n", Fdo, ioStatus.Status));
6137  goto getout;
6138 
6139  } else {
6140 
6141  //
6142  // for an RPC0 drive, we can try to pick a region for
6143  // the drive
6144  //
6145 
6146  mediaRegion = 0x0;
6147  }
6148 
6149  }
6150 
6151  //
6152  // get the device region
6153  //
6154 
6155  RtlZeroMemory (copyProtectKey, bufferLen);
6156  copyProtectKey->KeyLength = DVD_RPC_KEY_LENGTH;
6157  copyProtectKey->KeyType = DvdGetRpcKey;
6158 
6159  //
6160  // Build and send a request for READ_KEY for RPC key
6161  //
6162 
6164  "CdRomPickDvdRegion (%p): Getting RpcKey\n",
6165  Fdo));
6168  Fdo,
6169  copyProtectKey,
6172  FALSE,
6173  &ioStatus
6174  );
6176  "CdRomPickDvdRegion (%p): Got RpcKey %x\n",
6177  Fdo, ioStatus.Status));
6178 
6179  if (!NT_SUCCESS(ioStatus.Status)) {
6180 
6182  "CdRomPickDvdRegion (%p): failed to get RpcKey from "
6183  "a DVD Device\n", Fdo));
6184  goto getout;
6185 
6186  }
6187 
6188  //
6189  // so we now have what we can get for the media region and the
6190  // drive region. we will not set a region if the drive has one
6191  // set already (mask is not all 1's), nor will we set a region
6192  // if there are no more user resets available.
6193  //
6194 
6195  rpcKey = (PDVD_RPC_KEY) copyProtectKey->KeyData;
6196 
6197 
6198  if (rpcKey->RegionMask != 0xff) {
6200  "CdRomPickDvdRegion (%p): not picking a region since "
6201  "it is already chosen\n", Fdo));
6202  goto getout;
6203  }
6204 
6205  if (rpcKey->UserResetsAvailable <= 1) {
6207  "CdRomPickDvdRegion (%p): not picking a region since "
6208  "only one change remains\n", Fdo));
6209  goto getout;
6210  }
6211 
6212  defaultDvdRegion = 0;
6213 
6214  //
6215  // the proppage dvd class installer sets
6216  // this key based upon the system locale
6217  //
6218 
6220  Fdo,
6222  &defaultDvdRegion
6223  );
6224 
6225  if (defaultDvdRegion > DVD_MAX_REGION) {
6226 
6227  //
6228  // the registry has a bogus default
6229  //
6230 
6232  "CdRomPickDvdRegion (%p): registry has a bogus default "
6233  "region value of %x\n", Fdo, defaultDvdRegion));
6234  defaultDvdRegion = 0;
6235 
6236  }
6237 
6238  //
6239  // if defaultDvdRegion == 0, it means no default.
6240  //
6241 
6242  //
6243  // we will select the initial dvd region for the user
6244  //
6245 
6246  if ((defaultDvdRegion != 0) &&
6247  (mediaRegion &
6248  (1 << (defaultDvdRegion - 1))
6249  )
6250  ) {
6251 
6252  //
6253  // first choice:
6254  // the media has region that matches
6255  // the default dvd region.
6256  //
6257 
6258  dvdRegion = (1 << (defaultDvdRegion - 1));
6259 
6261  "CdRomPickDvdRegion (%p): Choice #1: media matches "
6262  "drive's default, chose region %x\n", Fdo, dvdRegion));
6263 
6264 
6265  } else if (mediaRegion) {
6266 
6267  //
6268  // second choice:
6269  // pick the lowest region number
6270  // from the media
6271  //
6272 
6273  UCHAR mask;
6274 
6275  mask = 1;
6276  dvdRegion = 0;
6277  while (mediaRegion && !dvdRegion) {
6278 
6279  //
6280  // pick the lowest bit
6281  //
6282  dvdRegion = mediaRegion & mask;
6283  mask <<= 1;
6284  }
6285 
6287  "CdRomPickDvdRegion (%p): Choice #2: choosing lowest "
6288  "media region %x\n", Fdo, dvdRegion));
6289 
6290  } else if (defaultDvdRegion) {
6291 
6292  //
6293  // third choice:
6294  // default dvd region from the dvd class installer
6295  //
6296 
6297  dvdRegion = (1 << (defaultDvdRegion - 1));
6299  "CdRomPickDvdRegion (%p): Choice #3: using default "
6300  "region for this install %x\n", Fdo, dvdRegion));
6301 
6302  } else {
6303 
6304  //
6305  // unable to pick one for the user -- this should rarely
6306  // happen, since the proppage dvd class installer sets
6307  // the key based upon the system locale
6308  //
6310  "CdRomPickDvdRegion (%p): Choice #4: failed to choose "
6311  "a media region\n", Fdo));
6312  goto getout;
6313 
6314  }
6315 
6316  //
6317  // now that we've chosen a region, set the region by sending the
6318  // appropriate request to the drive
6319  //
6320 
6321  RtlZeroMemory (copyProtectKey, bufferLen);
6322  copyProtectKey->KeyLength = DVD_SET_RPC_KEY_LENGTH;
6323  copyProtectKey->KeyType = DvdSetRpcKey;
6324  dvdRpcKey = (PDVD_SET_RPC_KEY) copyProtectKey->KeyData;
6325  dvdRpcKey->PreferredDriveRegionCode = (UCHAR) ~dvdRegion;
6326 
6327  //
6328  // Build and send request for SEND_KEY
6329  //
6331  "CdRomPickDvdRegion (%p): Sending new Rpc Key to region %x\n",
6332  Fdo, dvdRegion));
6333 
6336  Fdo,
6337  copyProtectKey,
6339  0,
6340  FALSE,
6341  &ioStatus);
6343  "CdRomPickDvdRegion (%p): Sent new Rpc Key %x\n",
6344  Fdo, ioStatus.Status));
6345 
6346  if (!NT_SUCCESS(ioStatus.Status)) {
6347  DebugPrint ((1, "CdRomPickDvdRegion (%p): unable to set dvd initial "
6348  " region code (%p)\n", Fdo, ioStatus.Status));
6349  } else {
6350  DebugPrint ((1, "CdRomPickDvdRegion (%p): Successfully set dvd "
6351  "initial region\n", Fdo));
6352  pickDvdRegion = 0;
6353  }
6354 
6355 getout:
6356  if (dvdReadStructure) {
6357  ExFreePool (dvdReadStructure);
6358  }
6359 
6360  //
6361  // update the new PickDvdRegion value
6362  //
6363 
6364  InterlockedExchange(&cddata->PickDvdRegion, pickDvdRegion);
6365 
6366  return;
6367 }
#define max(a, b)
Definition: svc.c:63
ULONG Rpc0RetryRegistryCallback
Definition: cdrom.h:249
UCHAR PreferredDriveRegionCode
Definition: ntddcdvd.h:193
#define DVD_TAG_DVD_REGION
Definition: cdrom.h:346
ULONG PickDvdRegion
Definition: cdrom.h:218
#define PAGED_CODE()
Definition: video.h:57
struct _DVD_COPYRIGHT_DESCRIPTOR * PDVD_COPYRIGHT_DESCRIPTOR
GLenum GLint GLuint mask
Definition: glext.h:6028
struct _DVD_RPC_KEY * PDVD_RPC_KEY
#define a
Definition: ke_i.h:78
UCHAR UserResetsAvailable
Definition: scsi.h:2923
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
#define DVD_DEFAULT_REGION
Definition: cdrom.h:356
#define b
Definition: ke_i.h:79
#define TraceLog(x)
Definition: trace.h:14
BOOLEAN DvdRpc0Device
Definition: cdrom.h:244
BOOLEAN DvdRpc0LicenseFailure
Definition: cdrom.h:245
NTSTATUS NTAPI CdRomGetRpc0Settings(IN PDEVICE_OBJECT Fdo)
Definition: sec.c:11
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_LICENSE_VIOLATION
Definition: udferr_usr.h:185
#define DVD_SET_RPC_KEY_LENGTH
Definition: cdrw_usr.h:1598
NTSTATUS NTAPI CdRomGetDeviceParameter(IN PDEVICE_OBJECT Fdo, IN PWSTR ParameterName, IN OUT PULONG ParameterValue)
Definition: cdrom.c:5753
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
DVD_KEY_TYPE KeyType
Definition: ntddcdvd.h:139
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR RegionMask
Definition: scsi.h:2926
#define IOCTL_DVD_READ_KEY
Definition: cdrw_usr.h:160
#define InterlockedExchange
Definition: armddk.h:54
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define DVD_MAX_REGION
Definition: cdrom.h:360
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
struct _DVD_COPY_PROTECT_KEY * PDVD_COPY_PROTECT_KEY
struct _DVD_SET_RPC_KEY * PDVD_SET_RPC_KEY
#define IOCTL_DVD_SEND_KEY2
Definition: cdrw_usr.h:165
DVD_STRUCTURE_FORMAT Format
Definition: ntddcdvd.h:81
unsigned int ULONG
Definition: retypes.h:1
#define DVD_RPC_KEY_LENGTH
Definition: cdrw_usr.h:1597
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct DVD_READ_STRUCTURE * PDVD_READ_STRUCTURE
UCHAR TypeCode
Definition: scsi.h:2925
#define IOCTL_DVD_READ_STRUCTURE
Definition: cdrw_usr.h:157

Referenced by CdRomDeviceControlDispatch(), and CdRomStartDevice().

◆ CdRomReadWriteVerification()

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

Definition at line 3293 of file cdrom.c.

3316 {
3319 
3321  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
3322  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
3323 
3324  //PCDROM_DATA cdData = (PCDROM_DATA)(commonExtension->DriverData);
3325 
3326  //SCSI_REQUEST_BLOCK srb;
3327  //PCDB cdb = (PCDB)srb.Cdb;
3328  //NTSTATUS status;
3329 
3330  PAGED_CODE();
3331 
3332  //
3333  // note: we are no longer failing write commands immediately
3334  // they are now failed in StartIo based upon media ability
3335  //
3336 
3337  //
3338  // If the cd is playing music then reject this request.
3339  //
3340 
3341  if (PLAY_ACTIVE(fdoExtension)) {
3342  Irp->IoStatus.Status = STATUS_DEVICE_BUSY;
3343  return STATUS_DEVICE_BUSY;
3344  }
3345 
3346  //
3347  // Verify parameters of this request.
3348  // Check that ending sector is on disc and
3349  // that number of bytes to transfer is a multiple of
3350  // the sector size.
3351  //
3352 
3353  startingOffset.QuadPart = currentIrpStack->Parameters.Read.ByteOffset.QuadPart +
3354  transferByteCount;
3355 
3356  if (!fdoExtension->DiskGeometry.BytesPerSector) {
3357  fdoExtension->DiskGeometry.BytesPerSector = 2048;
3358  }
3359 
3360  if ((startingOffset.QuadPart > commonExtension->PartitionLength.QuadPart) ||
3361  (transferByteCount & (fdoExtension->DiskGeometry.BytesPerSector - 1))) {
3362 
3363  //
3364  // Fail request with status of invalid parameters.
3365  //
3366 
3367  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3368 
3369  return STATUS_INVALID_PARAMETER;
3370  }
3371 
3372 
3373  return STATUS_SUCCESS;
3374 
3375 } // end CdRomReadWriteVerification()
LARGE_INTEGER PartitionLength
Definition: classpnp.h:594
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:704
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
ULONG BytesPerSector
Definition: ntdddisk.h:381
#define PAGED_CODE()
Definition: video.h:57
PVOID DeviceExtension
Definition: env_spec_w32.h:418
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
unsigned int ULONG
Definition: retypes.h:1
#define PLAY_ACTIVE(DeviceExtension)
Definition: cdrom.c:190
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
LONGLONG QuadPart
Definition: typedefs.h:113

Referenced by DriverEntry().

◆ CdRomRemoveDevice()

NTSTATUS NTAPI CdRomRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  Type 
)

Definition at line 5352 of file cdrom.c.

5376 {
5377  PFUNCTIONAL_DEVICE_EXTENSION deviceExtension =
5379 
5380  PCDROM_DATA cdData = deviceExtension->CommonExtension.DriverData;
5381 
5382  PAGED_CODE();
5383 
5384  if((Type == IRP_MN_QUERY_REMOVE_DEVICE) ||
5386  return STATUS_SUCCESS;
5387  }
5388 
5389  if(cdData->DelayedRetryIrp != NULL) {
5390  cdData->DelayedRetryInterval = 1;
5392  }
5393 
5395 
5396  if (deviceExtension->DeviceDescriptor) {
5397  ExFreePool(deviceExtension->DeviceDescriptor);
5398  deviceExtension->DeviceDescriptor = NULL;
5399  }
5400 
5401  if (deviceExtension->AdapterDescriptor) {
5402  ExFreePool(deviceExtension->AdapterDescriptor);
5403  deviceExtension->AdapterDescriptor = NULL;
5404  }
5405 
5406  if (deviceExtension->SenseData) {
5407  ExFreePool(deviceExtension->SenseData);
5408  deviceExtension->SenseData = NULL;
5409  }
5410 
5411  ClassDeleteSrbLookasideList(&deviceExtension->CommonExtension);
5412 
5413  if(cdData->CdromInterfaceString.Buffer != NULL) {
5415  &(cdData->CdromInterfaceString),
5416  FALSE);
5419  }
5420 
5421  if(cdData->VolumeInterfaceString.Buffer != NULL) {
5423  &(cdData->VolumeInterfaceString),
5424  FALSE);
5427  }
5428 
5430 
5431  ASSERT(cdData->DelayedRetryIrp == NULL);
5432 
5433  if(Type == IRP_MN_REMOVE_DEVICE) {
5434 
5436 
5437  //
5438  // unlock locked pages by locking (to get Mm pointer)
5439  // and then unlocking twice.
5440  //
5441 
5442  PVOID locked;
5443 
5445 
5447 
5448  } else if (TEST_FLAG(cdData->HackFlags, CDROM_HACK_HITACHI_GD_2000)) {
5449 
5451 
5452  } else if (TEST_FLAG(cdData->HackFlags, CDROM_HACK_TOSHIBA_XM_3xx )) {
5453 
5455 
5456  } else {
5457 
5458  // this is a problem!
5459  // workaround by locking this twice, once for us and
5460  // once for the non-existant locker from ScanForSpecial
5461  ASSERT(!"hack flags show locked section, but none exists?");
5464 
5465 
5466  }
5467 
5468  MmUnlockPagableImageSection(locked);
5469  MmUnlockPagableImageSection(locked);
5470 
5471  }
5472 
5473  //
5474  // keep the system-wide count accurate, as
5475  // programs use this info to know when they
5476  // have found all the cdroms in a system.
5477  //
5478 
5480  "CDROM.SYS Remove device\n"));
5482  }
5483 
5484  //
5485  // so long, and thanks for all the fish!
5486  //
5487 
5488  return STATUS_SUCCESS;
5489 }
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_REMOVE_DEVICE
#define CDROM_HACK_LOCKED_PAGES
Definition: cdrom.h:67
Type
Definition: Type.h:6
UNICODE_STRING CdromInterfaceString
Definition: cdrom.h:224
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
VOID NTAPI ClassDeleteSrbLookasideList(IN PCOMMON_DEVICE_EXTENSION CommonExtension)
Definition: obsolete.c:899
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
#define PAGED_CODE()
Definition: video.h:57
VOID NTAPI ToshibaProcessError(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
Definition: cdrom.c:5695
#define IRP_MN_QUERY_REMOVE_DEVICE
ULONG_PTR HackFlags
Definition: cdrom.h:163
ULONG DelayedRetryInterval
Definition: cdrom.h:209
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define TraceLog(x)
Definition: trace.h:14
#define MmLockPagableCodeSection(Address)
VOID NTAPI CdRomTickHandler(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: cdrom.c:6132
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:699
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:698
PIRP DelayedRetryIrp
Definition: cdrom.h:207
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define CDROM_HACK_TOSHIBA_XM_3xx
Definition: cdrom.h:61
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI CdRomDeAllocateMmcResources(IN PDEVICE_OBJECT Fdo)
Definition: mmc.c:1335
#define CDROM_HACK_HITACHI_1750
Definition: cdrom.h:58
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
UNICODE_STRING VolumeInterfaceString
Definition: cdrom.h:225
NTSTATUS NTAPI CdRomRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
Definition: cdrom.c:5352
#define CDROM_HACK_HITACHI_GD_2000
Definition: cdrom.h:59
VOID NTAPI HitachiProcessError(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
Definition: cdrom.c:4265
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI HitachiProcessErrorGD2000(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK OriginalSrb, NTSTATUS *Status, BOOLEAN *Retry)
Definition: cdrom.c:4186
VOID NTAPI CdRomDeleteWellKnownName(IN PDEVICE_OBJECT DeviceObject)
Definition: cdrom.c:5732

Referenced by CdRomRemoveDevice(), and DriverEntry().

◆ CdRomRerunRequest()

NTSTATUS NTAPI CdRomRerunRequest ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN OPTIONAL PIRP  Irp,
IN BOOLEAN  ResendIrp 
)

Definition at line 6403 of file cdrom.c.

6408 {
6409  if(ResendIrp) {
6410  return IoCallDriver(FdoExtension->CommonExtension.LowerDeviceObject,
6411  Irp);
6412  } else {
6413  KIRQL oldIrql;
6414 
6415  oldIrql = KeRaiseIrqlToDpcLevel();
6416  CdRomStartIo(FdoExtension->DeviceObject, Irp);
6417  KeLowerIrql(oldIrql);
6419  }
6420 }
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 STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI CdRomStartIo(IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
Definition: cdrom.c:1327
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218

Referenced by CdRomRetryRequest(), and CdRomTickHandler().

◆ CdRomRetryRequest()

NTSTATUS NTAPI CdRomRetryRequest ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PIRP  Irp,
IN ULONG  Delay,
IN BOOLEAN  ResendIrp 
)

Definition at line 6371 of file cdrom.c.

6377 {
6378  PCDROM_DATA cdData;
6379  KIRQL oldIrql;
6380 
6381  if(Delay == 0) {
6382  return CdRomRerunRequest(FdoExtension, Irp, ResendIrp);
6383  }
6384 
6385  cdData = FdoExtension->CommonExtension.DriverData;
6386 
6387  KeAcquireSpinLock(&(cdData->DelayedRetrySpinLock), &oldIrql);
6388 
6389  ASSERT(cdData->DelayedRetryIrp == NULL);
6390  ASSERT(cdData->DelayedRetryInterval == 0);
6391 
6392  cdData->DelayedRetryIrp = Irp;
6393  cdData->DelayedRetryInterval = Delay;
6394  cdData->DelayedRetryResend = ResendIrp;
6395 
6396  KeReleaseSpinLock(&(cdData->DelayedRetrySpinLock), oldIrql);
6397 
6398  return STATUS_PENDING;
6399 }
_In_ PIRP Irp
Definition: csq.h:116
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG DelayedRetryInterval
Definition: cdrom.h:209
KSPIN_LOCK DelayedRetrySpinLock
Definition: cdrom.h:211
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_PENDING
Definition: ntstatus.h:82
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
PIRP DelayedRetryIrp
Definition: cdrom.h:207
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN DelayedRetryResend
Definition: cdrom.h:205
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS NTAPI CdRomRerunRequest(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN OPTIONAL PIRP Irp, IN BOOLEAN ResendIrp)
Definition: cdrom.c:6403

Referenced by CdRomDeviceControlCompletion(), CdRomSetVolumeIntermediateCompletion(), CdRomSwitchModeCompletion(), CdRomUpdateGeometryCompletion(), CdRomUpdateMmcDriveCapabilitiesCompletion(), and CdRomXACompletion().

◆ CdRomSetDeviceParameter()

NTSTATUS NTAPI CdRomSetDeviceParameter ( IN PDEVICE_OBJECT  Fdo,
IN PWSTR  ParameterName,
IN ULONG  ParameterValue 
)

Definition at line 5829 of file cdrom.c.

5853 {
5854  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
5855  NTSTATUS status;
5856  HANDLE deviceParameterHandle;
5857 
5858  PAGED_CODE();
5859 
5860  //
5861  // open the given parameter
5862  //
5863  status = IoOpenDeviceRegistryKey(fdoExtension->LowerPdo,
5865  KEY_READ | KEY_WRITE,
5866  &deviceParameterHandle);
5867 
5868  if(NT_SUCCESS(status)) {
5869 
5872  (PWSTR) deviceParameterHandle,
5873  ParameterName,
5874  REG_DWORD,
5875  &ParameterValue,
5876  sizeof (ParameterValue));
5877 
5878  //
5879  // close what we open
5880  //
5881  ZwClose(deviceParameterHandle);
5882  }
5883 
5884  return status;
5885 
5886 } // CdromSetDeviceParameter
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:55
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define KEY_WRITE
Definition: nt_native.h:1031
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_opt_ PWSTR _In_ PWSTR _Inout_ PULONG ParameterValue
Definition: classpnp.h:1209
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:697
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define PLUGPLAY_REGKEY_DRIVER
Definition: usbd.c:42
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: classpnp.h:1209
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:4658
#define REG_DWORD
Definition: sdbapi.c:596
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ CdRomShutdownFlush()

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

Definition at line 6722 of file cdrom.c.

6726 {
6729  return STATUS_PENDING;
6730 
6731 }
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_PENDING
Definition: ntstatus.h:82
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
IoMarkIrpPending(Irp)

Referenced by DriverEntry().

◆ CdRomShutdownFlushCompletion()

NTSTATUS NTAPI CdRomShutdownFlushCompletion ( IN PDEVICE_OBJECT  Fdo,
IN PIRP  NewIrp,
IN PIRP  OriginalIrp 
)

Definition at line 6756 of file cdrom.c.

6761 {
6762  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
6763  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
6764  PIO_STACK_LOCATION originalIrpStack;
6767 
6768  ASSERT(OriginalIrp);
6769 
6770  originalIrpStack = IoGetCurrentIrpStackLocation(OriginalIrp);
6771 
6772  //
6773  // always use a new irp so we can call
6774  // CdRomCompleteIrpAndStartNextPacketSafely() from this routine.
6775  //
6776 
6777  if (NewIrp != NULL) {
6778  status = NewIrp->IoStatus.Status;
6779  IoFreeIrp(NewIrp);
6780  NewIrp = NULL;
6781  }
6782 
6783  if (!NT_SUCCESS(status)) {
6784  BAIL_OUT(OriginalIrp);
6785  goto SafeExit;
6786  }
6787 
6788  //
6789  // the current irpstack saves the counter which states
6790  // what part of the multi-part shutdown or flush we are in.
6791  //
6792 
6793  iteration = (ULONG_PTR)originalIrpStack->Parameters.Others.Argument1;
6794  iteration++;
6795  originalIrpStack->Parameters.Others.Argument1 = (PVOID)iteration;
6796 
6797  switch (iteration) {
6798  case 2:
6799  if (originalIrpStack->MajorFunction != IRP_MJ_SHUTDOWN) {
6800  //
6801  // then we don't want to send the unlock command
6802  // the incrementing of the state was done above.
6803  // return the completion routine's result.
6804  //
6805  return CdRomShutdownFlushCompletion(Fdo, NULL, OriginalIrp);
6806  }
6807  // else fall through....
6808 
6809  case 1: {
6810 
6811  PIRP newIrp = NULL;
6812  PSCSI_REQUEST_BLOCK newSrb = NULL;
6813  PCDB newCdb = NULL;
6814  PIO_STACK_LOCATION newIrpStack = NULL;
6815  ULONG isRemoved;
6816 
6817  newIrp = IoAllocateIrp((CCHAR)(Fdo->StackSize+1), FALSE);
6818  if (newIrp == NULL) {
6819  BAIL_OUT(OriginalIrp);
6821  goto SafeExit;
6822  }
6824  sizeof(SCSI_REQUEST_BLOCK),
6825  CDROM_TAG_SRB);
6826  if (newSrb == NULL) {
6827  IoFreeIrp(newIrp);
6828  BAIL_OUT(OriginalIrp);
6830  goto SafeExit;
6831  }
6832 
6833  //
6834  // ClassIoComplete will free the SRB, but we need a routine
6835  // that will free the irp. then just call ClassSendAsync,
6836  // and don't care about the return value, since the completion
6837  // routine will be called anyways.
6838  //
6839 
6840  IoSetNextIrpStackLocation(newIrp);
6841  newIrpStack = IoGetCurrentIrpStackLocation(newIrp);
6842  newIrpStack->DeviceObject = Fdo;
6843  IoSetCompletionRoutine(newIrp,
6845  OriginalIrp,
6846  TRUE, TRUE, TRUE);
6847  IoSetNextIrpStackLocation(newIrp);
6848  newIrpStack = IoGetCurrentIrpStackLocation(newIrp);
6849  newIrpStack->DeviceObject = Fdo;
6850 
6851  //
6852  // setup the request
6853  //
6854 
6855  RtlZeroMemory(newSrb, sizeof(SCSI_REQUEST_BLOCK));
6856  newCdb = (PCDB)(newSrb->Cdb);
6857 
6858  newSrb->QueueTag = SP_UNTAGGED;
6861 
6862  //
6863  // tell classpnp not to call StartNextPacket()
6864  //
6865 
6867 
6868  if (iteration == 1) {
6869 
6870  //
6871  // first synchronize the cache
6872  //
6873 
6874  newSrb->TimeOutValue = fdoExtension->TimeOutValue * 4;
6875  newSrb->CdbLength = 10;
6876  newCdb->SYNCHRONIZE_CACHE10.OperationCode = SCSIOP_SYNCHRONIZE_CACHE;
6877 
6878  } else if (iteration == 2) {
6879 
6880  //
6881  // then unlock the medium
6882  //
6883 
6884  ASSERT( originalIrpStack->MajorFunction == IRP_MJ_SHUTDOWN );
6885 
6886  newSrb->TimeOutValue = fdoExtension->TimeOutValue;
6887  newSrb->CdbLength = 6;
6888  newCdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
6889  newCdb->MEDIA_REMOVAL.Prevent = FALSE;
6890 
6891  }
6892 
6893 
6894  isRemoved = ClassAcquireRemoveLock(Fdo, newIrp);
6895  if (isRemoved) {
6896  IoFreeIrp(newIrp);
6897  ExFreePool(newSrb);
6898  ClassReleaseRemoveLock(Fdo, newIrp);
6899  BAIL_OUT(OriginalIrp);
6901  goto SafeExit;
6902  }
6903  ClassSendSrbAsynchronous(Fdo, newSrb, newIrp, NULL, 0, FALSE);
6904  break;
6905  }
6906 
6907  case 3: {
6908 
6909  PSCSI_REQUEST_BLOCK srb;
6910  PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(OriginalIrp);
6911 
6912  //
6913  // forward this request to the device appropriately,
6914  // don't use this completion routine anymore...
6915  //
6916 
6918  sizeof(SCSI_REQUEST_BLOCK),
6919  CDROM_TAG_SRB);
6920  if (srb == NULL) {
6921  BAIL_OUT(OriginalIrp);
6923  goto SafeExit;
6924  }
6925 
6928  srb->TimeOutValue = fdoExtension->TimeOutValue * 4;
6929  srb->QueueTag = SP_UNTAGGED;
6931  srb->SrbFlags = fdoExtension->SrbFlags;
6932  srb->CdbLength = 0;
6933  srb->OriginalRequest = OriginalIrp;
6934 
6935  if (originalIrpStack->MajorFunction == IRP_MJ_SHUTDOWN) {
6937  } else {
6939  }
6940 
6941  //
6942  // Set up IoCompletion routine address.
6943  //
6944 
6945  IoSetCompletionRoutine(OriginalIrp,
6947  srb,
6948  TRUE, TRUE, TRUE);
6949 
6950  //
6951  // Set the retry count to zero.
6952  //
6953 
6954  originalIrpStack->Parameters.Others.Argument4 = (PVOID) 0;
6955 
6956  //
6957  // Get next stack location and set major function code.
6958  //
6959 
6960  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
6961 
6962  //
6963  // Set up SRB for execute scsi request.
6964  // Save SRB address in next stack for port driver.
6965  //
6966 
6967  nextIrpStack->Parameters.Scsi.Srb = srb;
6968 
6969  //
6970  // Call the port driver to process the request.
6971  //
6972 
6973  IoCallDriver(commonExtension->LowerDeviceObject, OriginalIrp);
6974 
6975  break;
6976 
6977  }
6978  default: {
6979  ASSERT(FALSE);
6980  break;
6981  }
6982 
6983  } // end switch
6984 
6986 
6987 SafeExit:
6988 
6989  if (!NT_SUCCESS(status)) {
6990  OriginalIrp->IoStatus.Status = status;
6991  CdRomCompleteIrpAndStartNextPacketSafely(Fdo, OriginalIrp);
6992  }
6993 
6994  //
6995  // always return STATUS_MORE_PROCESSING_REQUIRED, so noone else tries
6996  // to access the new irp that we free'd....
6997  //
6998 
7000 
7001 } // end CdromShutdownFlush()
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
#define TRUE
Definition: types.h:120
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define IRP_MJ_SHUTDOWN
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
struct _CDB::_SYNCHRONIZE_CACHE10 SYNCHRONIZE_CACHE10
static int iteration
Definition: StackOverflow.c:14
UCHAR CdbLength
Definition: srb.h:250
UCHAR QueueAction
Definition: srb.h:249
static VOID CdRomCompleteIrpAndStartNextPacketSafely(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cdrom.h:407
ULONG TimeOutValue
Definition: srb.h:254
#define SRB_FLAGS_DONT_START_NEXT_PACKET
Definition: srb.h:407
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define SP_UNTAGGED
Definition: srb.h:225
#define IRP_MJ_SCSI
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
void * PVOID
Definition: retypes.h:9
UCHAR QueueTag
Definition: srb.h:248
NTSTATUS NTAPI CdRomShutdownFlushCompletion(IN PDEVICE_OBJECT Fdo, IN PIRP NewIrp, IN PIRP OriginalIrp)
Definition: cdrom.c:6756
NTSTATUS NTAPI ClassIoComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: class.c:2432
#define SRB_FUNCTION_FLUSH
Definition: srb.h:315
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:51
UCHAR Function
Definition: srb.h:242
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
USHORT Length
Definition: srb.h:241
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SRB_FUNCTION_SHUTDOWN
Definition: srb.h:314
#define CDROM_TAG_SRB
Definition: cdrom.h:328
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI ClassSendSrbAsynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:4321
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2480
#define BAIL_OUT(Irp)
Definition: cdrom.h:362
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
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
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
Definition: ps.c:97

Referenced by CdRomShutdownFlushCompletion(), and CdRomStartIo().

◆ CdRomStartDevice()

NTSTATUS NTAPI CdRomStartDevice ( IN PDEVICE_OBJECT  Fdo)

Definition at line 1169 of file cdrom.c.

1188 {
1189  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
1190  PCDROM_DATA cddata = (PCDROM_DATA)(commonExtension->DriverData);
1191  PDVD_COPY_PROTECT_KEY copyProtectKey;
1192  PDVD_RPC_KEY rpcKey;
1193  IO_STATUS_BLOCK ioStatus;
1194  ULONG bufferLen;
1195 
1196  // CdRomCreateWellKnownName(Fdo);
1197 
1198  //
1199  // if we have a DVD-ROM
1200  // if we have a rpc0 device
1201  // fake a rpc2 device
1202  // if device does not have a dvd region set
1203  // select a dvd region for the user
1204  //
1205 
1206  cddata->DvdRpc0Device = FALSE;
1207 
1208  //
1209  // since StartIo() will call IoStartNextPacket() on error, allowing
1210  // StartIo() to be non-recursive prevents stack overflow bugchecks in
1211  // severe error cases (such as fault-injection in the verifier).
1212  //
1213  // the only difference is that the thread context may be different
1214  // in StartIo() than in the caller of IoStartNextPacket().
1215  //
1216 
1218 
1219  //
1220  // check to see if we have a DVD device
1221  //
1222 
1223  if (CdRomGetDeviceType(Fdo) != FILE_DEVICE_DVD) {
1224  return STATUS_SUCCESS;
1225  }
1226 
1227  //
1228  // we got a DVD drive.
1229  // now, figure out if we have a RPC0 device
1230  //
1231 
1232  bufferLen = DVD_RPC_KEY_LENGTH;
1233  copyProtectKey =
1235  bufferLen,
1237 
1238  if (copyProtectKey == NULL) {
1240  }
1241 
1242  //
1243  // get the device region
1244  //
1245  RtlZeroMemory (copyProtectKey, bufferLen);
1246  copyProtectKey->KeyLength = DVD_RPC_KEY_LENGTH;
1247  copyProtectKey->KeyType = DvdGetRpcKey;
1248 
1249  //
1250  // Build a request for READ_KEY
1251  //
1254  Fdo,
1255  copyProtectKey,
1258  FALSE,
1259  &ioStatus
1260  );
1261 
1262  if (!NT_SUCCESS(ioStatus.Status)) {
1263 
1264  //
1265  // we have a rpc0 device
1266  //
1267  // NOTE: THIS MODIFIES THE BEHAVIOR OF THE IOCTL
1268  //
1269 
1270  cddata->DvdRpc0Device = TRUE;
1271 
1273  "CdromStartDevice (%p): RPC Phase 1 drive detected\n",
1274  Fdo));
1275 
1276  //
1277  // note: we could force this chosen now, but it's better to reduce
1278  // the number of code paths that could be taken. always delay to
1279  // increase the percentage code coverage.
1280  //
1281 
1283  "CdromStartDevice (%p): Delay DVD Region Selection\n",
1284  Fdo));
1285 
1286  cddata->Rpc0SystemRegion = 0xff;
1288  cddata->PickDvdRegion = 1;
1289  cddata->Rpc0RetryRegistryCallback = 1;
1290  ExFreePool(copyProtectKey);
1291  return STATUS_SUCCESS;
1292 
1293  } else {
1294 
1295  rpcKey = (PDVD_RPC_KEY) copyProtectKey->KeyData;
1296 
1297  //
1298  // TypeCode of zero means that no region has been set.
1299  //
1300 
1301  if (rpcKey->TypeCode == 0) {
1303  "CdromStartDevice (%p): must choose DVD region\n",
1304  Fdo));
1305  cddata->PickDvdRegion = 1;
1306  CdRomPickDvdRegion(Fdo);
1307  }
1308  }
1309 
1310  ExFreePool (copyProtectKey);
1311 
1312  return STATUS_SUCCESS;
1313 }
UCHAR Rpc0SystemRegionResetCount
Definition: cdrom.h:247
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG Rpc0RetryRegistryCallback
Definition: cdrom.h:249
#define DVD_MAX_REGION_RESET_COUNT
Definition: cdrom.h:359
ULONG PickDvdRegion
Definition: cdrom.h:218
VOID NTAPI CdRomPickDvdRegion(IN PDEVICE_OBJECT Fdo)
Definition: cdrom.c:5890
struct _DVD_RPC_KEY * PDVD_RPC_KEY
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
#define TraceLog(x)
Definition: trace.h:14
BOOLEAN DvdRpc0Device
Definition: cdrom.h:244
UCHAR Rpc0SystemRegion
Definition: cdrom.h:246
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable)
Definition: device.c:1798
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
DVD_KEY_TYPE KeyType
Definition: ntddcdvd.h:139
#define IOCTL_DVD_READ_KEY
Definition: cdrw_usr.h:160
#define DVD_TAG_RPC2_CHECK
Definition: cdrom.h:345
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 FILE_DEVICE_DVD
Definition: winioctl.h:156
DEVICE_TYPE NTAPI CdRomGetDeviceType(IN PDEVICE_OBJECT DeviceObject)
Definition: cdrom.c:5493
struct _DVD_COPY_PROTECT_KEY * PDVD_COPY_PROTECT_KEY
unsigned int ULONG
Definition: retypes.h:1
#define DVD_RPC_KEY_LENGTH
Definition: cdrw_usr.h:1597
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UCHAR TypeCode
Definition: scsi.h:2925

Referenced by DriverEntry().

◆ CdRomStartIo()

VOID NTAPI CdRomStartIo ( IN PDEVICE_OBJECT  Fdo,
IN PIRP  Irp 
)

Definition at line 1327 of file cdrom.c.

1331 {
1332 
1333  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
1334  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
1335 
1338  PIO_STACK_LOCATION irpStack;
1339 
1340  PIRP irp2 = NULL;
1341 
1342  ULONG transferPages;
1343  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
1344  //LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
1345  PCDROM_DATA cdData;
1346  PSCSI_REQUEST_BLOCK srb = NULL;
1347  PCDB cdb;
1348  PUCHAR senseBuffer = NULL;
1349  PVOID dataBuffer;
1350  NTSTATUS status;
1351  BOOLEAN use6Byte;
1352 
1353  //
1354  // Mark IRP with status pending.
1355  //
1356 
1358 
1359  cdData = (PCDROM_DATA)(fdoExtension->CommonExtension.DriverData);
1360  use6Byte = TEST_FLAG(cdData->XAFlags, XA_USE_6_BYTE);
1361 
1362  //
1363  // if this test is true, then we will exit the routine within this
1364  // code block, queueing the irp for later completion.
1365  //
1366 
1367  if ((cdData->Mmc.IsMmc) &&
1369  ) {
1370 
1371  USHORT queueDepth;
1373  "CdRomStartIo: [%p] Device needs to update capabilities\n",
1374  Irp));
1375  ASSERT(cdData->Mmc.IsMmc);
1376  ASSERT(cdData->Mmc.CapabilitiesIrp != NULL);
1377  ASSERT(cdData->Mmc.CapabilitiesIrp != Irp);
1378 
1379  //
1380  // NOTE - REF #0002
1381  //
1382  // the state was either UpdateRequired (which means we will
1383  // have to start the work item) or UpdateStarted (which means
1384  // we have already started the work item at least once -- may
1385  // transparently change to UpdateComplete).
1386  //
1387  // if it's update required, we just queue it, change to UpdateStarted,
1388  // start the workitem, and start the next packet.
1389  //
1390  // else, we must queue the item and check the queue depth. if the
1391  // queue depth is equal to 1, that means the worker item from the
1392  // previous attempt has already de-queued the items, so we should
1393  // call this routine again (retry) as an optimization rather than
1394  // re-add it this irp to the queue. since this is tail recursion,
1395  // it won't take much/any stack to do this.
1396  //
1397  // NOTE: This presumes the following items are true:
1398  //
1399  // we only add to the list from CdRomStartIo(), which is serialized.
1400  // we only set to UpdateStarted from CdRomStartIo(), and only if
1401  // the state was UpdateRequired.
1402  // we only set to UpdateRequired from CdRomMmcErrorHandler(), and
1403  // only if the state was UpdateComplete.
1404  // we only set to UpdateComplete from the workitem, and assert the
1405  // state was UpdateStarted.
1406  // we flush the entire queue in one atomic operation in the workitem,
1407  // except in the special case described above when we dequeue
1408  // the request immediately.
1409  //
1410  // order of operations is vitally important: queue, then test the depth
1411  // this will prevent lost irps.
1412  //
1413 
1415  (PSLIST_ENTRY)&(Irp->Tail.Overlay.DriverContext[0]), // ReactOS
1416  &(cdData->Mmc.DelayedLock));
1417 
1418  queueDepth = ExQueryDepthSList(&(cdData->Mmc.DelayedIrps));
1419  if (queueDepth == 1) {
1420 
1421  if (cdData->Mmc.UpdateState == CdromMmcUpdateRequired) {
1422  LONG oldState;
1423 
1424  //
1425  // should free any old partition list info that
1426  // we've previously saved away and then start the WorkItem
1427  //
1428 
1429  oldState = InterlockedExchange(&cdData->Mmc.UpdateState,
1431  ASSERT(oldState == CdromMmcUpdateRequired);
1432 
1436  NULL);
1437 
1438  } else {
1439 
1440  //
1441  // they *just* finished updating, so we should flush the list
1442  // back onto the StartIo queue and start the next packet.
1443  //
1444 
1445  CdRompFlushDelayedList(Fdo, &(cdData->Mmc), STATUS_SUCCESS, FALSE);
1446 
1447  }
1448 
1449  }
1450 
1451  //
1452  // start the next packet so we don't deadlock....
1453  //
1454 
1455  IoStartNextPacket(Fdo, FALSE);
1456  return;
1457 
1458  }
1459 
1460  //
1461  // If the flag is set in the device object
1462  // force a verify for READ, WRITE and RAW_READ requests
1463  // Note that ioctls are passed through....
1464  //
1465 
1466  if (TEST_FLAG(Fdo->Flags, DO_VERIFY_VOLUME) &&
1467  IS_READ_WRITE_REQUEST(currentIrpStack)) {
1468 
1470  "CdRomStartIo: [%p] Volume needs verified\n", Irp));
1471 
1472  if (!(currentIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME)) {
1473 
1474  if (Irp->Tail.Overlay.Thread) {
1476  }
1477 
1478  Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
1479 
1481  "CdRomStartIo: [%p] Calling UpdateCapacity - "
1482  "ioctl event = %p\n",
1483  Irp,
1484  nextIrpStack->Parameters.Others.Argument1
1485  ));
1486 
1487  //
1488  // our device control dispatch routine stores an event in the next
1489  // stack location to signal when startio has completed. We need to
1490  // pass this in so that the update capacity completion routine can
1491  // set it rather than completing the Irp.
1492  //
1493 
1494  status = CdRomUpdateCapacity(fdoExtension,
1495  Irp,
1496  nextIrpStack->Parameters.Others.Argument1
1497  );
1498 
1500  "CdRomStartIo: [%p] UpdateCapacity returned %lx\n",
1501  Irp, status));
1502  return;
1503  }
1504  }
1505 
1506  //
1507  // fail writes if they are not allowed...
1508  //
1509 
1510  if ((currentIrpStack->MajorFunction == IRP_MJ_WRITE) &&
1511  !(cdData->Mmc.WriteAllowed)) {
1512 
1514  "CdRomStartIo: [%p] Device %p failing write request\n",
1515  Irp, Fdo));
1516 
1517  Irp->IoStatus.Information = 0;
1518  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1519  BAIL_OUT(Irp);
1521  return;
1522  }
1523 
1524  if (currentIrpStack->MajorFunction == IRP_MJ_READ ||
1525  currentIrpStack->MajorFunction == IRP_MJ_WRITE ) {
1526 
1527  ULONG maximumTransferLength = fdoExtension->AdapterDescriptor->MaximumTransferLength;
1528 
1529  //
1530  // Add partition byte offset to make starting byte relative to
1531  // beginning of disk.
1532  //
1533 
1534  currentIrpStack->Parameters.Read.ByteOffset.QuadPart +=
1535  (fdoExtension->CommonExtension.StartingOffset.QuadPart);
1536 
1537  //
1538  // Calculate number of pages in this transfer.
1539  //
1540 
1541  transferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
1542  currentIrpStack->Parameters.Read.Length);
1543 
1544  //
1545  // Check if request length is greater than the maximum number of
1546  // bytes that the hardware can transfer.
1547  //
1548 
1549  if (cdData->RawAccess) {
1550 
1551  //
1552  // a writable device must be MMC compliant, which supports
1553  // READ_CD commands.
1554  //
1555 
1556  ASSERT(currentIrpStack->MajorFunction != IRP_MJ_WRITE);
1557 
1558  ASSERT(!TEST_FLAG(cdData->XAFlags, XA_USE_READ_CD));
1559 
1560  //
1561  // Fire off a mode select to switch back to cooked sectors.
1562  //
1563 
1564  irp2 = IoAllocateIrp((CCHAR)(Fdo->StackSize+1), FALSE);
1565 
1566  if (!irp2) {
1567  Irp->IoStatus.Information = 0;
1568  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1569 
1570  BAIL_OUT(Irp);
1572  return;
1573  }
1574 
1576  sizeof(SCSI_REQUEST_BLOCK),
1577  CDROM_TAG_SRB);
1578  if (!srb) {
1579  IoFreeIrp(irp2);
1580  Irp->IoStatus.Information = 0;
1581  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1582 
1583  BAIL_OUT(Irp);
1585  return;
1586  }
1587 
1588  RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
1589 
1590  cdb = (PCDB)srb->Cdb;
1591 
1592  //
1593  // Allocate sense buffer.
1594  //
1595 
1599 
1600  if (!senseBuffer) {
1601  ExFreePool(srb);
1602  IoFreeIrp(irp2);
1603  Irp->IoStatus.Information = 0;
1604  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1605 
1606  BAIL_OUT(Irp);
1608  return;
1609  }
1610 
1611  //
1612  // Set up the irp.
1613  //
1614 
1616  irp2->IoStatus.Status = STATUS_SUCCESS;
1617  irp2->IoStatus.Information = 0;
1618  irp2->Flags = 0;
1619  irp2->UserBuffer = NULL;
1620 
1621  //
1622  // Save the device object and irp in a private stack location.
1623  //
1624 
1625  irpStack = IoGetCurrentIrpStackLocation(irp2);
1626  irpStack->DeviceObject = Fdo;
1627  irpStack->Parameters.Others.Argument2 = (PVOID) Irp;
1628 
1629  //
1630  // The retry count will be in the real Irp, as the retry logic will
1631  // recreate our private irp.
1632  //
1633 
1634  if (!(nextIrpStack->Parameters.Others.Argument1)) {
1635 
1636  //
1637  // Only jam this in if it doesn't exist. The completion routines can
1638  // call StartIo directly in the case of retries and resetting it will
1639  // cause infinite loops.
1640  //
1641 
1642  nextIrpStack->Parameters.Others.Argument1 = (PVOID) MAXIMUM_RETRIES;
1643  }
1644 
1645  //
1646  // Construct the IRP stack for the lower level driver.
1647  //
1648 
1649  irpStack = IoGetNextIrpStackLocation(irp2);
1651  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
1652  irpStack->Parameters.Scsi.Srb = srb;
1653 
1656  srb->SrbStatus = srb->ScsiStatus = 0;
1657  srb->NextSrb = 0;
1658  srb->OriginalRequest = irp2;
1660  srb->SenseInfoBuffer = senseBuffer;
1661 
1662  transferByteCount = (use6Byte) ? sizeof(ERROR_RECOVERY_DATA) : sizeof(ERROR_RECOVERY_DATA10);
1663 
1665  transferByteCount,
1666  CDROM_TAG_RAW);
1667 
1668  if (!dataBuffer) {
1669  ExFreePool(senseBuffer);
1670  ExFreePool(srb);
1671  IoFreeIrp(irp2);
1672  Irp->IoStatus.Information = 0;
1673  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1674 
1675  BAIL_OUT(Irp);
1677  return;
1678 
1679  }
1680 
1681  irp2->MdlAddress = IoAllocateMdl(dataBuffer,
1682  transferByteCount,
1683  FALSE,
1684  FALSE,
1685  (PIRP) NULL);
1686 
1687  if (!irp2->MdlAddress) {
1688  ExFreePool(senseBuffer);
1689  ExFreePool(srb);
1690  ExFreePool(dataBuffer);
1691  IoFreeIrp(irp2);
1692  Irp->IoStatus.Information = 0;
1693  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1694 
1695  BAIL_OUT(Irp);
1697  return;
1698  }
1699 
1700  //
1701  // Prepare the MDL
1702  //
1703 
1704  MmBuildMdlForNonPagedPool(irp2->MdlAddress);
1705 
1706  srb->DataBuffer = dataBuffer;
1707 
1708  //
1709  // Set the new block size in the descriptor.
1710  //
1711 
1712  if (use6Byte) {
1713  cdData->BlockDescriptor.BlockLength[0] = (UCHAR)(COOKED_SECTOR_SIZE >> 16) & 0xFF;
1714  cdData->BlockDescriptor.BlockLength[1] = (UCHAR)(COOKED_SECTOR_SIZE >> 8) & 0xFF;
1715  cdData->BlockDescriptor.BlockLength[2] = (UCHAR)(COOKED_SECTOR_SIZE & 0xFF);
1716  } else {
1717  cdData->BlockDescriptor10.BlockLength[0] = (UCHAR)(COOKED_SECTOR_SIZE >> 16) & 0xFF;
1718  cdData->BlockDescriptor10.BlockLength[1] = (UCHAR)(COOKED_SECTOR_SIZE >> 8) & 0xFF;
1719  cdData->BlockDescriptor10.BlockLength[2] = (UCHAR)(COOKED_SECTOR_SIZE & 0xFF);
1720  }
1721 
1722  //
1723  // Move error page into dataBuffer.
1724  //
1725 
1726  RtlCopyMemory(srb->DataBuffer, &cdData->Header, transferByteCount);
1727 
1728  //
1729  // Build and send a mode select to switch into raw mode.
1730  //
1731 
1732  srb->SrbFlags = fdoExtension->SrbFlags;
1735  srb->DataTransferLength = transferByteCount;
1736  srb->TimeOutValue = fdoExtension->TimeOutValue * 2;
1737 
1738  if (use6Byte) {
1739  srb->CdbLength = 6;
1740  cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
1741  cdb->MODE_SELECT.PFBit = 1;
1742  cdb->MODE_SELECT.ParameterListLength = (UCHAR)transferByteCount;
1743  } else {
1744  srb->CdbLength = 10;
1745  cdb->MODE_SELECT10.OperationCode = SCSIOP_MODE_SELECT10;
1746  cdb->MODE_SELECT10.PFBit = 1;
1747  cdb->MODE_SELECT10.ParameterListLength[0] = (UCHAR)(transferByteCount >> 8);
1748  cdb->MODE_SELECT10.ParameterListLength[1] = (UCHAR)(transferByteCount & 0xFF);
1749  }
1750 
1751  //
1752  // Update completion routine.
1753  //
1754 
1757  srb,
1758  TRUE,
1759  TRUE,
1760  TRUE);
1761 
1762  IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, irp2);
1763  return;
1764  }
1765 
1766 
1767  //
1768  // Request needs to be split. Completion of each portion of the
1769  // request will fire off the next portion. The final request will
1770  // signal Io to send a new request.
1771  //
1772 
1773  transferPages =
1774  fdoExtension->AdapterDescriptor->MaximumPhysicalPages - 1;
1775 
1776  if(maximumTransferLength > (transferPages << PAGE_SHIFT)) {
1777  maximumTransferLength = transferPages << PAGE_SHIFT;
1778  }
1779 
1780  //
1781  // Check that the maximum transfer size is not zero
1782  //
1783 
1784  if(maximumTransferLength == 0) {
1785  maximumTransferLength = PAGE_SIZE;
1786  }
1787 
1788  ClassSplitRequest(Fdo, Irp, maximumTransferLength);
1789  return;
1790 
1791  } else if (currentIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
1792 
1793  //
1794  // Allocate an irp, srb and associated structures.
1795  //
1796 
1797  irp2 = IoAllocateIrp((CCHAR)(Fdo->StackSize+1),
1798  FALSE);
1799 
1800  if (!irp2) {
1801  Irp->IoStatus.Information = 0;
1802  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1803 
1804  BAIL_OUT(Irp);
1806  return;
1807  }
1808 
1810  sizeof(SCSI_REQUEST_BLOCK),
1811  CDROM_TAG_SRB);
1812  if (!srb) {
1813  IoFreeIrp(irp2);
1814  Irp->IoStatus.Information = 0;
1815  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1816 
1817  BAIL_OUT(Irp);
1819  return;
1820  }
1821 
1822  RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
1823 
1824  cdb = (PCDB)srb->Cdb;
1825 
1826  //
1827  // Allocate sense buffer.
1828  //
1829 
1833 
1834  if (!senseBuffer) {
1835  ExFreePool(srb);
1836  IoFreeIrp(irp2);
1837  Irp->IoStatus.Information = 0;
1838  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1839 
1840  BAIL_OUT(Irp);
1842  return;
1843  }
1844 
1845  RtlZeroMemory(senseBuffer, SENSE_BUFFER_SIZE);
1846 
1847  //
1848  // Set up the irp.
1849  //
1850 
1852  irp2->IoStatus.Status = STATUS_SUCCESS;
1853  irp2->IoStatus.Information = 0;
1854  irp2->Flags = 0;
1855  irp2->UserBuffer = NULL;
1856 
1857  //
1858  // Save the device object and irp in a private stack location.
1859  //
1860 
1861  irpStack = IoGetCurrentIrpStackLocation(irp2);
1862  irpStack->DeviceObject = Fdo;
1863  irpStack->Parameters.Others.Argument2 = (PVOID) Irp;
1864 
1865  //
1866  // The retry count will be in the real Irp, as the retry logic will
1867  // recreate our private irp.
1868  //
1869 
1870  if (!(nextIrpStack->Parameters.Others.Argument1)) {
1871 
1872  //
1873  // Only jam this in if it doesn't exist. The completion routines can
1874  // call StartIo directly in the case of retries and resetting it will
1875  // cause infinite loops.
1876  //
1877 
1878  nextIrpStack->Parameters.Others.Argument1 = (PVOID) MAXIMUM_RETRIES;
1879  }
1880 
1881  //
1882  // keep track of the new irp as Argument3
1883  //
1884 
1885  nextIrpStack->Parameters.Others.Argument3 = irp2;
1886 
1887 
1888  //
1889  // Construct the IRP stack for the lower level driver.
1890  //
1891 
1892  irpStack = IoGetNextIrpStackLocation(irp2);
1894  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
1895  irpStack->Parameters.Scsi.Srb = srb;
1896 
1899  srb,
1900  TRUE,
1901  TRUE,
1902  TRUE);
1903  //
1904  // Setup those fields that are generic to all requests.
1905  //
1906 
1909  srb->SrbStatus = srb->ScsiStatus = 0;
1910  srb->NextSrb = 0;
1911  srb->OriginalRequest = irp2;
1913  srb->SenseInfoBuffer = senseBuffer;
1914 
1915  switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode) {
1916 
1917 
1918  case IOCTL_CDROM_RAW_READ: {
1919 
1920  //
1921  // Determine whether the drive is currently in raw or cooked mode,
1922  // and which command to use to read the data.
1923  //
1924 
1925  if (!TEST_FLAG(cdData->XAFlags, XA_USE_READ_CD)) {
1926 
1927  PRAW_READ_INFO rawReadInfo =
1928  (PRAW_READ_INFO)currentIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
1929  ULONG maximumTransferLength;
1930  ULONG transferPages;
1931 
1932  if (cdData->RawAccess) {
1933 
1934  ULONG startingSector;
1935  //UCHAR min, sec, frame;
1936 
1937  //
1938  // Free the recently allocated irp, as we don't need it.
1939  //
1940 
1941  IoFreeIrp(irp2);
1942 
1943  cdb = (PCDB)srb->Cdb;
1945 
1946  //
1947  // Calculate starting offset.
1948  //
1949 
1950  startingSector = (ULONG)(rawReadInfo->DiskOffset.QuadPart >> fdoExtension->SectorShift);
1951  transferByteCount = rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
1952  maximumTransferLength = fdoExtension->AdapterDescriptor->MaximumTransferLength;
1953  transferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
1954  transferByteCount);
1955 
1956  //
1957  // Determine if request is within limits imposed by miniport.
1958  //
1959  if (transferByteCount > maximumTransferLength ||
1960  transferPages > fdoExtension->AdapterDescriptor->MaximumPhysicalPages) {
1961 
1962  //
1963  // The claim is that this won't happen, and is backed up by
1964  // ActiveMovie usage, which does unbuffered XA reads of 0x18000, yet
1965  // we get only 4 sector requests.
1966  //
1967 
1968  ExFreePool(senseBuffer);
1969  ExFreePool(srb);
1970 
1971  Irp->IoStatus.Information = 0;
1972  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1973 
1974  BAIL_OUT(Irp);
1976  return;
1977 
1978  }
1979 
1980  srb->OriginalRequest = Irp;
1981  srb->SrbFlags = fdoExtension->SrbFlags;
1984  srb->DataTransferLength = transferByteCount;
1985  srb->TimeOutValue = fdoExtension->TimeOutValue;
1986  srb->CdbLength = 10;
1987  srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
1988 
1989  if (rawReadInfo->TrackMode == CDDA) {
1990  if (TEST_FLAG(cdData->XAFlags, XA_PLEXTOR_CDDA)) {
1991 
1992  srb->CdbLength = 12;
1993 
1994  cdb->PLXTR_READ_CDDA.LogicalBlockByte3 = (UCHAR) (startingSector & 0xFF);
1995  cdb->PLXTR_READ_CDDA.LogicalBlockByte2 = (UCHAR) ((startingSector >> 8) & 0xFF);
1996  cdb->PLXTR_READ_CDDA.LogicalBlockByte1 = (UCHAR) ((startingSector >> 16) & 0xFF);
1997  cdb->PLXTR_READ_CDDA.LogicalBlockByte0 = (UCHAR) ((startingSector >> 24) & 0xFF);
1998 
1999  cdb->PLXTR_READ_CDDA.TransferBlockByte3 = (UCHAR) (rawReadInfo->SectorCount & 0xFF);
2000  cdb->PLXTR_READ_CDDA.TransferBlockByte2 = (UCHAR) (rawReadInfo->SectorCount >> 8);
2001  cdb->PLXTR_READ_CDDA.TransferBlockByte1 = 0;
2002  cdb->PLXTR_READ_CDDA.TransferBlockByte0 = 0;
2003 
2004  cdb->PLXTR_READ_CDDA.SubCode = 0;
2005  cdb->PLXTR_READ_CDDA.OperationCode = 0xD8;
2006 
2007  } else if (TEST_FLAG(cdData->XAFlags, XA_NEC_CDDA)) {
2008 
2009  cdb->NEC_READ_CDDA.LogicalBlockByte3 = (UCHAR) (startingSector & 0xFF);
2010  cdb->NEC_READ_CDDA.LogicalBlockByte2 = (UCHAR) ((startingSector >> 8) & 0xFF);
2011  cdb->NEC_READ_CDDA.LogicalBlockByte1 = (UCHAR) ((startingSector >> 16) & 0xFF);
2012  cdb->NEC_READ_CDDA.LogicalBlockByte0 = (UCHAR) ((startingSector >> 24) & 0xFF);
2013 
2014  cdb->NEC_READ_CDDA.TransferBlockByte1 = (UCHAR) (rawReadInfo->SectorCount & 0xFF);
2015  cdb->NEC_READ_CDDA.TransferBlockByte0 = (UCHAR) (rawReadInfo->SectorCount >> 8);
2016 
2017  cdb->NEC_READ_CDDA.OperationCode = 0xD4;
2018  }
2019  } else {
2020 
2021  cdb->CDB10.TransferBlocksMsb = (UCHAR) (rawReadInfo->SectorCount >> 8);
2022  cdb->CDB10.TransferBlocksLsb = (UCHAR) (rawReadInfo->SectorCount & 0xFF);
2023 
2024  cdb->CDB10.LogicalBlockByte3 = (UCHAR) (startingSector & 0xFF);
2025  cdb->CDB10.LogicalBlockByte2 = (UCHAR) ((startingSector >> 8) & 0xFF);
2026  cdb->CDB10.LogicalBlockByte1 = (UCHAR) ((startingSector >> 16) & 0xFF);
2027  cdb->CDB10.LogicalBlockByte0 = (UCHAR) ((startingSector >> 24) & 0xFF);
2028 
2029  cdb->CDB10.OperationCode = SCSIOP_READ;
2030  }
2031 
2032  srb->SrbStatus = srb->ScsiStatus = 0;
2033 
2034  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
2035  nextIrpStack->Parameters.Scsi.Srb = srb;
2036 
2037  // HACKHACK - REF #0001
2038 
2039  //
2040  // Set up IoCompletion routine address.
2041  //
2042 
2045  srb,
2046  TRUE,
2047  TRUE,
2048  TRUE);
2049 
2050  IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, Irp);
2051  return;
2052 
2053  } else {
2054 
2055  transferByteCount = (use6Byte) ? sizeof(ERROR_RECOVERY_DATA) : sizeof(ERROR_RECOVERY_DATA10);
2057  transferByteCount,
2058  CDROM_TAG_RAW );
2059  if (!dataBuffer) {
2060  ExFreePool(senseBuffer);
2061  ExFreePool(srb);
2062  IoFreeIrp(irp2);
2063  Irp->IoStatus.Information = 0;
2064  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2065 
2066  BAIL_OUT(Irp);
2068  return;
2069 
2070  }
2071 
2072  irp2->MdlAddress = IoAllocateMdl(dataBuffer,
2073  transferByteCount,
2074  FALSE,
2075  FALSE,
2076  (PIRP) NULL);
2077 
2078  if (!irp2->MdlAddress) {
2079  ExFreePool(senseBuffer);
2080  ExFreePool(srb);
2081  ExFreePool(dataBuffer);
2082  IoFreeIrp(irp2);
2083  Irp->IoStatus.Information = 0;
2084  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2085 
2086  BAIL_OUT(Irp);
2088  return;
2089  }
2090 
2091  //
2092  // Prepare the MDL
2093  //
2094 
2095  MmBuildMdlForNonPagedPool(irp2->MdlAddress);
2096 
2097  srb->DataBuffer = dataBuffer;
2098 
2099  //
2100  // Set the new block size in the descriptor.
2101  // This will set the block read size to RAW_SECTOR_SIZE
2102  // TODO: Set density code, based on operation
2103  //
2104 
2105  if (use6Byte) {
2106  cdData->BlockDescriptor.BlockLength[0] = (UCHAR)(RAW_SECTOR_SIZE >> 16) & 0xFF;
2107  cdData->BlockDescriptor.BlockLength[1] = (UCHAR)(RAW_SECTOR_SIZE >> 8) & 0xFF;
2108  cdData->BlockDescriptor.BlockLength[2] = (UCHAR)(RAW_SECTOR_SIZE & 0xFF);
2109  cdData->BlockDescriptor.DensityCode = 0;
2110  } else {
2111  cdData->BlockDescriptor10.BlockLength[0] = (UCHAR)(RAW_SECTOR_SIZE >> 16) & 0xFF;
2112  cdData->BlockDescriptor10.BlockLength[1] = (UCHAR)(RAW_SECTOR_SIZE >> 8) & 0xFF;
2113  cdData->BlockDescriptor10.BlockLength[2] = (UCHAR)(RAW_SECTOR_SIZE & 0xFF);
2114  cdData->BlockDescriptor10.DensityCode = 0;
2115  }
2116 
2117  //
2118  // Move error page into dataBuffer.
2119  //
2120 
2121  RtlCopyMemory(srb->DataBuffer, &cdData->Header, transferByteCount);
2122 
2123 
2124  //
2125  // Build and send a mode select to switch into raw mode.
2126  //
2127 
2128  srb->SrbFlags = fdoExtension->SrbFlags;
2131  srb->DataTransferLength = transferByteCount;
2132  srb->TimeOutValue = fdoExtension->TimeOutValue * 2;
2133 
2134  if (use6Byte) {