ReactOS  0.4.15-dev-1207-g698a8e6
cdrom.c File Reference
#include "precomp.h"
#include <ntddk.h>
#include <scsi.h>
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <include/class2.h>
#include <stdio.h>
#include <debug.h>
Include dependency graph for cdrom.c:

Go to the source code of this file.

Classes

struct  _XA_CONTEXT
 
struct  _ERROR_RECOVERY_DATA
 
struct  _ERROR_RECOVERY_DATA10
 
struct  _CDROM_DATA
 

Macros

#define CDB12GENERIC_LENGTH   12
 
#define DEVICE_EXTENSION_SIZE   sizeof(DEVICE_EXTENSION) + sizeof(CDROM_DATA)
 
#define SCSI_CDROM_TIMEOUT   10
 
#define SCSI_CHANGER_BONUS_TIMEOUT   10
 
#define HITACHI_MODE_DATA_SIZE   12
 
#define MODE_DATA_SIZE   64
 
#define RAW_SECTOR_SIZE   2352
 
#define COOKED_SECTOR_SIZE   2048
 
#define MEDIA_CHANGE_DEFAULT_TIME   4
 
#define CDROM_SRB_LIST_SIZE   4
 
#define PLAY_ACTIVE(DeviceExtension)   (((PCDROM_DATA)(DeviceExtension + 1))->PlayActive)
 
#define MSF_TO_LBA(Minutes, Seconds, Frames)   (ULONG)((60 * 75 * (Minutes)) + (75 * (Seconds)) + ((Frames) - 150))
 
#define LBA_TO_MSF(Lba, Minutes, Seconds, Frames)
 
#define DEC_TO_BCD(x)   (((x / 10) << 4) + (x % 10))
 
#define XA_USE_6_BYTE   0x01
 
#define XA_USE_10_BYTE   0x02
 
#define XA_USE_READ_CD   0x04
 
#define XA_NOT_SUPPORTED   0x08
 
#define PLEXTOR_CDDA   0x10
 
#define NEC_CDDA   0x20
 
#define ANY_SECTOR   0
 
#define CD_DA_SECTOR   1
 
#define YELLOW_MODE1_SECTOR   2
 
#define YELLOW_MODE2_SECTOR   3
 
#define FORM2_MODE1_SECTOR   4
 
#define FORM2_MODE2_SECTOR   5
 
#define ITEMS_TO_QUERY   2 /* always 1 greater than what is searched */
 

Typedefs

typedef struct _XA_CONTEXT XA_CONTEXT
 
typedef struct _XA_CONTEXTPXA_CONTEXT
 
typedef struct _ERROR_RECOVERY_DATA ERROR_RECOVERY_DATA
 
typedef struct _ERROR_RECOVERY_DATAPERROR_RECOVERY_DATA
 
typedef struct _ERROR_RECOVERY_DATA10 ERROR_RECOVERY_DATA10
 
typedef struct _ERROR_RECOVERY_DATA10PERROR_RECOVERY_DATA10
 
typedef struct _CDROM_DATA CDROM_DATA
 
typedef struct _CDROM_DATAPCDROM_DATA
 

Functions

NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
BOOLEAN NTAPI ScsiCdRomFindDevices (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath, IN PCLASS_INIT_DATA InitializationData, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG PortNumber)
 
NTSTATUS NTAPI ScsiCdRomOpenClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiCdRomReadVerification (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiCdRomSwitchMode (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN PIRP OriginalRequest)
 
NTSTATUS NTAPI CdRomDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI CdRomDeviceControlCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomSetVolumeIntermediateCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomSwitchModeCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomXACompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI CdRomClassIoctlCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
VOID NTAPI ScsiCdRomStartIo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI CdRomTickHandler (IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
 
BOOLEAN NTAPI CdRomCheckRegistryForMediaChangeValue (IN PUNICODE_STRING RegistryPath, IN ULONG DeviceNumber)
 
NTSTATUS NTAPI CdRomUpdateCapacity (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP IrpToComplete, IN OPTIONAL PKEVENT IoctlEvent)
 
NTSTATUS NTAPI CreateCdRomDeviceObject (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG PortNumber, IN PULONG DeviceCount, PIO_SCSI_CAPABILITIES PortCapabilities, IN PSCSI_INQUIRY_DATA LunInfo, IN PCLASS_INIT_DATA InitializationData, IN PUNICODE_STRING RegistryPath)
 
VOID NTAPI ScanForSpecial (PDEVICE_OBJECT DeviceObject, PINQUIRYDATA InquiryData, PIO_SCSI_CAPABILITIES PortCapabilities)
 
BOOLEAN NTAPI CdRomIsPlayActive (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI HitachProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
VOID NTAPI ToshibaProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
BOOLEAN NTAPI IsThisAnAtapiChanger (IN PDEVICE_OBJECT DeviceObject, OUT PULONG DiscsPresent)
 
BOOLEAN NTAPI IsThisASanyo (IN PDEVICE_OBJECT DeviceObject, IN UCHAR PathId, IN UCHAR TargetId)
 
BOOLEAN NTAPI IsThisAMultiLunDevice (IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT PortDeviceObject)
 
VOID NTAPI CdRomCreateNamedEvent (IN PDEVICE_EXTENSION DeviceExtension, IN ULONG DeviceNumber)
 
VOID NTAPI ReportToMountMgr (IN PDEVICE_OBJECT CdDeviceObject)
 
NTSTATUS NTAPI CreateCdRomDeviceObject (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG PortNumber, IN PULONG DeviceCount, IN PIO_SCSI_CAPABILITIES PortCapabilities, IN PSCSI_INQUIRY_DATA LunInfo, IN PCLASS_INIT_DATA InitializationData, IN PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI ToshibaProcessErrorCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
NTSTATUS NTAPI CdRomMediaChangeCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
NTSTATUS NTAPI CdRomUpdateGeometryCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 

Variables

IO_COMPLETION_ROUTINE CdRomDeviceControlCompletion
 
IO_COMPLETION_ROUTINE CdRomSetVolumeIntermediateCompletion
 
IO_COMPLETION_ROUTINE CdRomSwitchModeCompletion
 
IO_COMPLETION_ROUTINE CdRomXACompletion
 
IO_COMPLETION_ROUTINE CdRomClassIoctlCompletion
 
IO_COMPLETION_ROUTINE ToshibaProcessErrorCompletion
 
ULONG NoLoad = 0
 
IO_COMPLETION_ROUTINE CdRomMediaChangeCompletion
 
IO_COMPLETION_ROUTINE CdRomUpdateGeometryCompletion
 

Macro Definition Documentation

◆ ANY_SECTOR

#define ANY_SECTOR   0

Definition at line 220 of file cdrom.c.

◆ CD_DA_SECTOR

#define CD_DA_SECTOR   1

Definition at line 221 of file cdrom.c.

◆ CDB12GENERIC_LENGTH

#define CDB12GENERIC_LENGTH   12

Definition at line 21 of file cdrom.c.

◆ CDROM_SRB_LIST_SIZE

#define CDROM_SRB_LIST_SIZE   4

Definition at line 177 of file cdrom.c.

◆ COOKED_SECTOR_SIZE

#define COOKED_SECTOR_SIZE   2048

Definition at line 175 of file cdrom.c.

◆ DEC_TO_BCD

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

Definition at line 202 of file cdrom.c.

◆ DEVICE_EXTENSION_SIZE

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

Definition at line 169 of file cdrom.c.

◆ FORM2_MODE1_SECTOR

#define FORM2_MODE1_SECTOR   4

Definition at line 224 of file cdrom.c.

◆ FORM2_MODE2_SECTOR

#define FORM2_MODE2_SECTOR   5

Definition at line 225 of file cdrom.c.

◆ HITACHI_MODE_DATA_SIZE

#define HITACHI_MODE_DATA_SIZE   12

Definition at line 172 of file cdrom.c.

◆ ITEMS_TO_QUERY

#define ITEMS_TO_QUERY   2 /* always 1 greater than what is searched */

◆ LBA_TO_MSF

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

Definition at line 195 of file cdrom.c.

◆ MEDIA_CHANGE_DEFAULT_TIME

#define MEDIA_CHANGE_DEFAULT_TIME   4

Definition at line 176 of file cdrom.c.

◆ MODE_DATA_SIZE

#define MODE_DATA_SIZE   64

Definition at line 173 of file cdrom.c.

◆ MSF_TO_LBA

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

Definition at line 192 of file cdrom.c.

◆ NEC_CDDA

#define NEC_CDDA   0x20

Definition at line 214 of file cdrom.c.

◆ PLAY_ACTIVE

#define PLAY_ACTIVE (   DeviceExtension)    (((PCDROM_DATA)(DeviceExtension + 1))->PlayActive)

Definition at line 190 of file cdrom.c.

◆ PLEXTOR_CDDA

#define PLEXTOR_CDDA   0x10

Definition at line 213 of file cdrom.c.

◆ RAW_SECTOR_SIZE

#define RAW_SECTOR_SIZE   2352

Definition at line 174 of file cdrom.c.

◆ SCSI_CDROM_TIMEOUT

#define SCSI_CDROM_TIMEOUT   10

Definition at line 170 of file cdrom.c.

◆ SCSI_CHANGER_BONUS_TIMEOUT

#define SCSI_CHANGER_BONUS_TIMEOUT   10

Definition at line 171 of file cdrom.c.

◆ XA_NOT_SUPPORTED

#define XA_NOT_SUPPORTED   0x08

Definition at line 211 of file cdrom.c.

◆ XA_USE_10_BYTE

#define XA_USE_10_BYTE   0x02

Definition at line 209 of file cdrom.c.

◆ XA_USE_6_BYTE

#define XA_USE_6_BYTE   0x01

Definition at line 208 of file cdrom.c.

◆ XA_USE_READ_CD

#define XA_USE_READ_CD   0x04

Definition at line 210 of file cdrom.c.

◆ YELLOW_MODE1_SECTOR

#define YELLOW_MODE1_SECTOR   2

Definition at line 222 of file cdrom.c.

◆ YELLOW_MODE2_SECTOR

#define YELLOW_MODE2_SECTOR   3

Definition at line 223 of file cdrom.c.

Typedef Documentation

◆ CDROM_DATA

◆ ERROR_RECOVERY_DATA

◆ ERROR_RECOVERY_DATA10

◆ PCDROM_DATA

◆ PERROR_RECOVERY_DATA

◆ PERROR_RECOVERY_DATA10

◆ PXA_CONTEXT

◆ XA_CONTEXT

Function Documentation

◆ CdRomCheckRegistryForMediaChangeValue()

BOOLEAN NTAPI CdRomCheckRegistryForMediaChangeValue ( IN PUNICODE_STRING  RegistryPath,
IN ULONG  DeviceNumber 
)

Definition at line 6386 of file cdrom.c.

6420 {
6421 #define ITEMS_TO_QUERY 2 /* always 1 greater than what is searched */
6422  PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
6423  NTSTATUS status;
6424  LONG zero = 0;
6425 
6426  LONG tmp = 0;
6427  LONG doRun = 0;
6428 
6429  CHAR buf[32];
6430  ANSI_STRING paramNum;
6431 
6432  UNICODE_STRING paramStr;
6433 
6434  UNICODE_STRING paramSuffix;
6435  UNICODE_STRING paramPath;
6436  UNICODE_STRING paramDevPath;
6437 
6438  //
6439  // First append \Parameters to the passed in registry path
6440  //
6441 
6442  RtlInitUnicodeString(&paramStr, L"\\Parameters");
6443 
6444  RtlInitUnicodeString(&paramPath, NULL);
6445 
6446  paramPath.MaximumLength = RegistryPath->Length +
6447  paramStr.Length +
6448  sizeof(WCHAR);
6449 
6450  paramPath.Buffer = ExAllocatePool(PagedPool, paramPath.MaximumLength);
6451 
6452  if(!paramPath.Buffer) {
6453 
6454  DebugPrint((1,"CdRomCheckRegAP: couldn't allocate paramPath\n"));
6455 
6456  return FALSE;
6457  }
6458 
6459  RtlZeroMemory(paramPath.Buffer, paramPath.MaximumLength);
6460  RtlAppendUnicodeToString(&paramPath, RegistryPath->Buffer);
6461  RtlAppendUnicodeToString(&paramPath, paramStr.Buffer);
6462 
6463  DebugPrint((2, "CdRomCheckRegAP: paramPath [%d] = %ws\n",
6464  paramPath.Length,
6465  paramPath.Buffer));
6466 
6467  //
6468  // build a counted ANSI string that contains
6469  // the suffix for the path
6470  //
6471 
6472  sprintf(buf, "\\Device%lu", DeviceNumber);
6473  RtlInitAnsiString(&paramNum, buf);
6474 
6475  //
6476  // Next convert this into a unicode string
6477  //
6478 
6479  status = RtlAnsiStringToUnicodeString(&paramSuffix, &paramNum, TRUE);
6480 
6481  if(!NT_SUCCESS(status)) {
6482  DebugPrint((1,"CdRomCheckRegAP: couldn't convert paramNum to paramSuffix\n"));
6483  ExFreePool(paramPath.Buffer);
6484  return FALSE;
6485  }
6486 
6487  RtlInitUnicodeString(&paramDevPath, NULL);
6488 
6489  //
6490  // now build the device specific path
6491  //
6492 
6493  paramDevPath.MaximumLength = paramPath.Length +
6494  paramSuffix.Length +
6495  sizeof(WCHAR);
6496  paramDevPath.Buffer = ExAllocatePool(PagedPool, paramDevPath.MaximumLength);
6497 
6498  if(!paramDevPath.Buffer) {
6499  RtlFreeUnicodeString(&paramSuffix);
6500  ExFreePool(paramPath.Buffer);
6501  return FALSE;
6502  }
6503 
6504  RtlZeroMemory(paramDevPath.Buffer, paramDevPath.MaximumLength);
6505  RtlAppendUnicodeToString(&paramDevPath, paramPath.Buffer);
6506  RtlAppendUnicodeToString(&paramDevPath, paramSuffix.Buffer);
6507 
6508  DebugPrint((2, "CdRomCheckRegAP: paramDevPath [%d] = %ws\n",
6509  paramPath.Length,
6510  paramPath.Buffer));
6511 
6512  parameters = ExAllocatePool(NonPagedPool,
6514 
6515  if (parameters) {
6516 
6517  //
6518  // Check for the Autorun value.
6519  //
6520 
6521  RtlZeroMemory(parameters,
6523 
6524  parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
6525  parameters[0].Name = L"Autorun";
6526  parameters[0].EntryContext = &doRun;
6527  parameters[0].DefaultType = REG_DWORD;
6528  parameters[0].DefaultData = &zero;
6529  parameters[0].DefaultLength = sizeof(ULONG);
6530 
6532  RegistryPath->Buffer,
6533  parameters,
6534  NULL,
6535  NULL);
6536 
6537  DebugPrint((2, "CdRomCheckRegAP: cdrom/Autorun flag = %d\n", doRun));
6538 
6539  RtlZeroMemory(parameters,
6541 
6542  parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
6543  parameters[0].Name = L"Autorun";
6544  parameters[0].EntryContext = &tmp;
6545  parameters[0].DefaultType = REG_DWORD;
6546  parameters[0].DefaultData = &doRun;
6547  parameters[0].DefaultLength = sizeof(ULONG);
6548 
6550  paramPath.Buffer,
6551  parameters,
6552  NULL,
6553  NULL);
6554 
6555  DebugPrint((2, "CdRomCheckRegAP: cdrom/parameters/autorun flag = %d\n", tmp));
6556 
6557  RtlZeroMemory(parameters,
6559 
6560  parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
6561  parameters[0].Name = L"Autorun";
6562  parameters[0].EntryContext = &doRun;
6563  parameters[0].DefaultType = REG_DWORD;
6564  parameters[0].DefaultData = &tmp;
6565  parameters[0].DefaultLength = sizeof(ULONG);
6566 
6568  paramDevPath.Buffer,
6569  parameters,
6570  NULL,
6571  NULL);
6572 
6573  DebugPrint((1, "CdRomCheckRegAP: cdrom/parameters/device%d/autorun flag = %d\n", DeviceNumber, doRun));
6574 
6575  ExFreePool(parameters);
6576 
6577  }
6578 
6579  ExFreePool(paramPath.Buffer);
6580  ExFreePool(paramDevPath.Buffer);
6581  RtlFreeUnicodeString(&paramSuffix);
6582 
6583  DebugPrint((1, "CdRomCheckRegAP: Autoplay for device %d is %s\n",
6584  DeviceNumber,
6585  (doRun ? "on" : "off")));
6586 
6587  if(doRun) {
6588  return TRUE;
6589  }
6590 
6591  return FALSE;
6592 }
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
USHORT MaximumLength
Definition: env_spec_w32.h:370
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define ITEMS_TO_QUERY
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
static double zero
Definition: j0_y0.c:96
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
#define REG_DWORD
Definition: sdbapi.c:596
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
Definition: ps.c:97

Referenced by CreateCdRomDeviceObject().

◆ CdRomClassIoctlCompletion()

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

Definition at line 7322 of file cdrom.c.

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

◆ CdRomCreateNamedEvent()

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

Definition at line 674 of file cdrom.c.

696 {
697  UNICODE_STRING unicodeString;
698  OBJECT_ATTRIBUTES objectAttributes;
699  CCHAR eventNameBuffer[MAXIMUM_FILENAME_LENGTH];
700  STRING eventNameString;
701  HANDLE handle;
703 
704 
705  sprintf(eventNameBuffer,"\\Device\\MediaChangeEvent%ld",
706  DeviceNumber);
707 
708  RtlInitString(&eventNameString,
709  eventNameBuffer);
710 
711  status = RtlAnsiStringToUnicodeString(&unicodeString,
712  &eventNameString,
713  TRUE);
714 
715  if (!NT_SUCCESS(status)) {
716  return;
717  }
718 
719  InitializeObjectAttributes(&objectAttributes,
720  &unicodeString,
722  NULL,
723  NULL);
724 
725  DeviceExtension->MediaChangeEvent = IoCreateSynchronizationEvent(&unicodeString,
726  &handle);
727  DeviceExtension->MediaChangeEventHandle = handle;
728 
729  KeClearEvent(DeviceExtension->MediaChangeEvent);
730 
731  RtlFreeUnicodeString(&unicodeString);
732 }
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_OPENIF
Definition: winternl.h:229
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define sprintf(buf, format,...)
Definition: sprintf.c:55
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:51
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
std::wstring STRING
Definition: fontsub.cpp:33
#define OBJ_PERMANENT
Definition: winternl.h:226
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
PKEVENT NTAPI IoCreateSynchronizationEvent(IN PUNICODE_STRING EventName, IN PHANDLE EventHandle)
Definition: ioevent.c:82
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by CreateCdRomDeviceObject().

◆ CdRomDeviceControl()

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

Definition at line 4686 of file cdrom.c.

4709 {
4711  PIO_STACK_LOCATION nextStack;
4712  PKEVENT deviceControlEvent;
4713  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4714  PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension+1);
4715  SCSI_REQUEST_BLOCK srb;
4716  NTSTATUS status;
4717  KIRQL irql;
4718 
4719  ULONG ioctlCode;
4720  ULONG baseCode;
4721  ULONG functionCode;
4722 
4723 RetryControl:
4724 
4725  //
4726  // Zero the SRB on stack.
4727  //
4728 
4729  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
4730 
4731  Irp->IoStatus.Information = 0;
4732 
4733  //
4734  // if this is a class driver ioctl then we need to change the base code
4735  // to IOCTL_CDROM_BASE so that the switch statement can handle it.
4736  //
4737  // WARNING - currently the scsi class ioctl function codes are between
4738  // 0x200 & 0x300. this routine depends on that fact
4739  //
4740 
4741  ioctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
4742  baseCode = ioctlCode >> 16;
4743  functionCode = (ioctlCode & (~0xffffc003)) >> 2;
4744 
4745  DebugPrint((1, "CdRomDeviceControl: Ioctl Code = %#08lx, Base Code = %#lx,"
4746  " Function Code = %#lx\n",
4747  ioctlCode,
4748  baseCode,
4749  functionCode
4750  ));
4751 
4752  if((functionCode >= 0x200) && (functionCode <= 0x300)) {
4753 
4754  ioctlCode = (ioctlCode & 0x0000ffff) | CTL_CODE(IOCTL_CDROM_BASE, 0, 0, 0);
4755 
4756  DebugPrint((1, "CdRomDeviceControl: Class Code - new ioctl code is %#08lx\n",
4757  ioctlCode));
4758 
4759  irpStack->Parameters.DeviceIoControl.IoControlCode = ioctlCode;
4760 
4761  }
4762 
4763  switch (ioctlCode) {
4764 
4765  case IOCTL_CDROM_RAW_READ: {
4766 
4767  LARGE_INTEGER startingOffset;
4768  ULONG transferBytes;
4769  PRAW_READ_INFO rawReadInfo = (PRAW_READ_INFO)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
4770  PUCHAR userData = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
4771 
4772  //
4773  // Ensure that XA reads are supported.
4774  //
4775 
4776  if (cdData->XAFlags & XA_NOT_SUPPORTED) {
4777 
4778  DebugPrint((1,
4779  "CdRomDeviceControl: XA Reads not supported. Flags (%x)\n",
4780  cdData->XAFlags));
4781 
4783  break;
4784  }
4785 
4786  //
4787  // Check that ending sector is on disc and buffers are there and of
4788  // correct size.
4789  //
4790 
4791  if (rawReadInfo == NULL) {
4792 
4793  //
4794  // Called from user space. Validate the buffers.
4795  //
4796 
4797  rawReadInfo = (PRAW_READ_INFO)userData;
4798  irpStack->Parameters.DeviceIoControl.Type3InputBuffer = (PVOID)userData;
4799 
4800  if (rawReadInfo == NULL) {
4801 
4802  DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA Read (No extent info\n"));
4803 
4804  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
4805 
4807  return STATUS_INVALID_PARAMETER;
4808  }
4809 
4810  if (irpStack->Parameters.DeviceIoControl.InputBufferLength != sizeof(RAW_READ_INFO)) {
4811 
4812  DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA Read (Invalid info buffer\n"));
4813 
4814  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
4815 
4817  return STATUS_INVALID_PARAMETER;
4818  }
4819  }
4820 
4821  startingOffset.QuadPart = rawReadInfo->DiskOffset.QuadPart;
4822  transferBytes = rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
4823 
4824  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < transferBytes) {
4825 
4826  DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA Read (Bad buffer size)\n"));
4827 
4828  //
4829  // Fail request with status of invalid parameters.
4830  //
4831 
4832  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
4833 
4835  return STATUS_INVALID_PARAMETER;
4836  }
4837 
4838  if ((startingOffset.QuadPart + transferBytes) > deviceExtension->PartitionLength.QuadPart) {
4839 
4840  DebugPrint((1,"CdRomDeviceControl: Invalid I/O parameters for XA Read (Request Out of Bounds)\n"));
4841 
4842  //
4843  // Fail request with status of invalid parameters.
4844  //
4845 
4847  break;
4848  }
4849 
4852 
4853  return STATUS_PENDING;
4854  }
4855 
4858 
4859  DebugPrint((2,"CdRomDeviceControl: Get drive geometry\n"));
4860 
4861  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4862  sizeof( DISK_GEOMETRY ) ) {
4863 
4865  break;
4866  }
4867 
4870 
4871  return STATUS_PENDING;
4872  }
4873 
4876 
4877  DebugPrint((2,"CdRomDeviceControl: Get drive geometry ex\n"));
4878 
4879  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4880  sizeof( DISK_GEOMETRY_EX ) ) {
4881 
4883  break;
4884  }
4885 
4888 
4889  return STATUS_PENDING;
4890  }
4891 
4893 
4894  DebugPrint((2,"CdRomDeviceControl: Get length info\n"));
4895 
4896  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4897  sizeof( GET_LENGTH_INFORMATION ) ) {
4898 
4900  break;
4901  }
4902 
4905 
4906  return STATUS_PENDING;
4907  }
4908 
4910  case IOCTL_CDROM_READ_TOC: {
4911 
4912  //
4913  // If the cd is playing music then reject this request.
4914  //
4915 
4917  Irp->IoStatus.Status = STATUS_DEVICE_BUSY;
4919  return STATUS_DEVICE_BUSY;
4920  }
4921 
4924 
4925  return STATUS_PENDING;
4926  }
4927 
4929 
4930  //
4931  // Play Audio MSF
4932  //
4933 
4934  DebugPrint((2,"CdRomDeviceControl: Play audio MSF\n"));
4935 
4936  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
4937  sizeof(CDROM_PLAY_AUDIO_MSF)) {
4938 
4939  //
4940  // Indicate unsuccessful status.
4941  //
4942 
4944  break;
4945  }
4946 
4949 
4950  return STATUS_PENDING;
4951  }
4952 
4954 
4955 
4956  //
4957  // Seek Audio MSF
4958  //
4959 
4960  DebugPrint((2,"CdRomDeviceControl: Seek audio MSF\n"));
4961 
4962  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
4963  sizeof(CDROM_SEEK_AUDIO_MSF)) {
4964 
4965  //
4966  // Indicate unsuccessful status.
4967  //
4968 
4970  break;
4971  } else {
4974 
4975  return STATUS_PENDING;
4976 
4977  }
4978  }
4979 
4980  case IOCTL_CDROM_PAUSE_AUDIO: {
4981 
4982  //
4983  // Pause audio
4984  //
4985 
4986  DebugPrint((2, "CdRomDeviceControl: Pause audio\n"));
4987 
4990 
4991  return STATUS_PENDING;
4992 
4993  break;
4994  }
4995 
4996  case IOCTL_CDROM_RESUME_AUDIO: {
4997 
4998  //
4999  // Resume audio
5000  //
5001 
5002  DebugPrint((2, "CdRomDeviceControl: Resume audio\n"));
5003 
5006 
5007  return STATUS_PENDING;
5008  }
5009 
5011 
5012  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
5013  sizeof(CDROM_SUB_Q_DATA_FORMAT)) {
5014 
5016  Irp->IoStatus.Information = 0;
5017  break;
5018  }
5019 
5022 
5023  return STATUS_PENDING;
5024  }
5025 
5026  case IOCTL_CDROM_GET_CONTROL: {
5027 
5028  DebugPrint((2, "CdRomDeviceControl: Get audio control\n"));
5029 
5030  //
5031  // Verify user buffer is large enough for the data.
5032  //
5033 
5034  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
5035  sizeof(CDROM_AUDIO_CONTROL)) {
5036 
5037  //
5038  // Indicate unsuccessful status and no data transferred.
5039  //
5040 
5042  Irp->IoStatus.Information = 0;
5043  break;
5044 
5045  } else {
5046 
5049 
5050  return STATUS_PENDING;
5051  }
5052  }
5053 
5054  case IOCTL_CDROM_GET_VOLUME: {
5055 
5056  DebugPrint((2, "CdRomDeviceControl: Get volume control\n"));
5057 
5058  //
5059  // Verify user buffer is large enough for data.
5060  //
5061 
5062  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
5063  sizeof(VOLUME_CONTROL)) {
5064 
5065  //
5066  // Indicate unsuccessful status and no data transferred.
5067  //
5068 
5070  Irp->IoStatus.Information = 0;
5071  break;
5072 
5073  } else {
5076 
5077  return STATUS_PENDING;
5078  }
5079  }
5080 
5081  case IOCTL_CDROM_SET_VOLUME: {
5082 
5083  DebugPrint((2, "CdRomDeviceControl: Set volume control\n"));
5084 
5085  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
5086  sizeof(VOLUME_CONTROL)) {
5087 
5088  //
5089  // Indicate unsuccessful status.
5090  //
5091 
5093  break;
5094  } else {
5095 
5098 
5099  return STATUS_PENDING;
5100  }
5101  }
5102 
5103  case IOCTL_CDROM_STOP_AUDIO: {
5104 
5105  //
5106  // Stop play.
5107  //
5108 
5109  DebugPrint((2, "CdRomDeviceControl: Stop audio\n"));
5110 
5113 
5114  return STATUS_PENDING;
5115  }
5116 
5117  case IOCTL_CDROM_CHECK_VERIFY: {
5118  DebugPrint((1, "CdRomDeviceControl: [%lx] Check Verify\n", Irp));
5120 
5121  if((irpStack->Parameters.DeviceIoControl.OutputBufferLength) &&
5122  (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))) {
5123 
5124  DebugPrint((1, "CdRomDeviceControl: Check Verify: media count "
5125  "buffer too small\n"));
5126 
5128  break;
5129  }
5130 
5132 
5133  return STATUS_PENDING;
5134  }
5135 
5136  default: {
5137 
5138  //
5139  // allocate an event and stuff it into our stack location.
5140  //
5141 
5142  deviceControlEvent = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
5143 
5144  if(!deviceControlEvent) {
5145 
5147 
5148  } else {
5149 
5150  PIO_STACK_LOCATION currentStack;
5151 
5152  KeInitializeEvent(deviceControlEvent, NotificationEvent, FALSE);
5153 
5154  currentStack = IoGetCurrentIrpStackLocation(Irp);
5155  nextStack = IoGetNextIrpStackLocation(Irp);
5156 
5157  //
5158  // Copy the stack down a notch
5159  //
5160 
5161  *nextStack = *currentStack;
5162 
5164  Irp,
5166  deviceControlEvent,
5167  TRUE,
5168  TRUE,
5169  TRUE
5170  );
5171 
5173 
5174  Irp->IoStatus.Status = STATUS_SUCCESS;
5175  Irp->IoStatus.Information = 0;
5176 
5177  //
5178  // Override volume verifies on this stack location so that we
5179  // will be forced through the synchronization. Once this location
5180  // goes away we get the old value back
5181  //
5182 
5183  nextStack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
5184 
5186 
5188 
5189  //
5190  // Wait for CdRomClassIoctlCompletion to set the event. This
5191  // ensures serialization remains intact for these unhandled device
5192  // controls.
5193  //
5194 
5196  deviceControlEvent,
5197  Suspended,
5198  KernelMode,
5199  FALSE,
5200  NULL);
5201 
5202  ExFreePool(deviceControlEvent);
5203 
5204  DebugPrint((2, "CdRomDeviceControl: irp %#08lx synchronized\n", Irp));
5205 
5206  //
5207  // If an error occured then propagate that back up - we are no longer
5208  // guaranteed synchronization and the upper layers will have to
5209  // retry.
5210  //
5211  // If no error occured, call down to the class driver directly
5212  // then start up the next request.
5213  //
5214 
5215  if(Irp->IoStatus.Status == STATUS_SUCCESS) {
5216 
5218 
5220 
5222 
5223  KeLowerIrql(irql);
5224  }
5225  }
5226 
5227  return status;
5228  }
5229 
5230  } // end switch()
5231 
5232  if (status == STATUS_VERIFY_REQUIRED) {
5233 
5234  //
5235  // If the status is verified required and this request
5236  // should bypass verify required then retry the request.
5237  //
5238 
5239  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME) {
5240 
5242  goto RetryControl;
5243 
5244  }
5245  }
5246 
5248 
5250 
5251  }
5252 
5253  //
5254  // Update IRP with completion status.
5255  //
5256 
5257  Irp->IoStatus.Status = status;
5258 
5259  //
5260  // Complete the request.
5261  //
5262 
5264  DebugPrint((2, "CdRomDeviceControl: Status is %lx\n", status));
5265  return status;
5266 
5267 } // end ScsiCdRomDeviceControl()
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define IOCTL_CDROM_GET_CONTROL
Definition: ntddcdrm.h:61
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define XA_NOT_SUPPORTED
Definition: cdrom.c:211
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define RAW_SECTOR_SIZE
Definition: cdrom.c:174
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:103
unsigned char * PUCHAR
Definition: retypes.h:3
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:64
ULONG SectorCount
Definition: ntddcdrm.h:395
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX
Definition: ntddcdrm.h:76
#define IOCTL_CDROM_RAW_READ
Definition: ntddcdrm.h:67
struct __RAW_READ_INFO * PRAW_READ_INFO
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IOCTL_CDROM_SET_VOLUME
Definition: ntddcdrm.h:55
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
IO_COMPLETION_ROUTINE CdRomClassIoctlCompletion
Definition: cdrom.c:317
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:40
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:37
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:52
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
void * PVOID
Definition: retypes.h:9
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define CTL_CODE(DeviceType, Function, Method, Access)
Definition: nt_native.h:586
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:73
#define IOCTL_CDROM_GET_VOLUME
Definition: ntddcdrm.h:49
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define IOCTL_CDROM_PAUSE_AUDIO
Definition: ntddcdrm.h:43
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define IOCTL_CDROM_RESUME_AUDIO
Definition: ntddcdrm.h:46
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
USHORT XAFlags
Definition: cdrom.c:82
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
BOOLEAN NTAPI CdRomIsPlayActive(IN PDEVICE_OBJECT DeviceObject)
Definition: cdrom.c:5869
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
KIRQL irql
Definition: wave.h:1
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSTATUS NTAPI ScsiClassDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class2.c:3603
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
LARGE_INTEGER DiskOffset
Definition: ntddcdrm.h:394
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:58
static SERVICE_STATUS status
Definition: service.c:31
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
LONGLONG QuadPart
Definition: typedefs.h:114
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

Referenced by DriverEntry().

◆ CdRomDeviceControlCompletion()

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

Definition at line 2996 of file cdrom.c.

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

◆ CdRomIsPlayActive()

BOOLEAN NTAPI CdRomIsPlayActive ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 5869 of file cdrom.c.

5888 {
5889  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
5890  PIRP irp;
5891  IO_STATUS_BLOCK ioStatus;
5892  KEVENT event;
5893  NTSTATUS status;
5894  PSUB_Q_CURRENT_POSITION currentBuffer;
5895 
5896  if (!PLAY_ACTIVE(deviceExtension)) {
5897  return(FALSE);
5898  }
5899 
5901 
5902  if (currentBuffer == NULL) {
5903  return(FALSE);
5904  }
5905 
5906  ((PCDROM_SUB_Q_DATA_FORMAT) currentBuffer)->Format = IOCTL_CDROM_CURRENT_POSITION;
5907  ((PCDROM_SUB_Q_DATA_FORMAT) currentBuffer)->Track = 0;
5908 
5909  //
5910  // Create notification event object to be used to signal the
5911  // request completion.
5912  //
5913 
5915 
5916  //
5917  // Build the synchronous request to be sent to the port driver
5918  // to perform the request.
5919  //
5920 
5922  deviceExtension->DeviceObject,
5923  currentBuffer,
5924  sizeof(CDROM_SUB_Q_DATA_FORMAT),
5925  currentBuffer,
5926  sizeof(SUB_Q_CURRENT_POSITION),
5927  FALSE,
5928  &event,
5929  &ioStatus);
5930 
5931  if (irp == NULL) {
5932  ExFreePool(currentBuffer);
5933  return FALSE;
5934  }
5935 
5936  //
5937  // Pass request to port driver and wait for request to complete.
5938  //
5939 
5940  status = IoCallDriver(deviceExtension->DeviceObject, irp);
5941 
5942  if (status == STATUS_PENDING) {
5944  status = ioStatus.Status;
5945  }
5946 
5947  if (!NT_SUCCESS(status)) {
5948  ExFreePool(currentBuffer);
5949  return FALSE;
5950  }
5951 
5952  ExFreePool(currentBuffer);
5953 
5954  return(PLAY_ACTIVE(deviceExtension));
5955 
5956 }
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _cl_event * event
Definition: glext.h:7739
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
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:58
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by CdRomDeviceControl().

◆ CdRomMediaChangeCompletion()

NTSTATUS NTAPI CdRomMediaChangeCompletion ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

Definition at line 5961 of file cdrom.c.

5988 {
5992  PDEVICE_EXTENSION deviceExtension;
5993  PDEVICE_EXTENSION physicalExtension;
5994  PSENSE_DATA senseBuffer;
5995  PCDROM_DATA cddata;
5996 
5997  ASSERT(Irp);
5998  ASSERT(cdStack);
5999  DeviceObject = cdStack->DeviceObject;
6001 
6002  deviceExtension = DeviceObject->DeviceExtension;
6003  physicalExtension = deviceExtension->PhysicalDevice->DeviceExtension;
6004  cddata = (PCDROM_DATA)(deviceExtension + 1);
6005 
6006  ASSERT(cddata->MediaChangeIrp == NULL);
6007 
6008  //
6009  // If the sense data field is valid, look for a media change.
6010  // otherwise this iteration of the polling will just assume nothing
6011  // changed.
6012  //
6013 
6014  DebugPrint((3, "CdRomMediaChangeHandler: Completing Autorun Irp 0x%lx "
6015  "for device %d\n",
6016  Irp, deviceExtension->DeviceNumber));
6017 
6019  if (srb->SenseInfoBufferLength >= FIELD_OFFSET(SENSE_DATA, CommandSpecificInformation)) {
6020 
6021  //
6022  // See if this is a media change.
6023  //
6024 
6025  senseBuffer = srb->SenseInfoBuffer;
6026  if ((senseBuffer->SenseKey & 0x0f) == SCSI_SENSE_UNIT_ATTENTION) {
6027  if (senseBuffer->AdditionalSenseCode == SCSI_ADSENSE_MEDIUM_CHANGED) {
6028 
6029  DebugPrint((1, "CdRomMediaChangeCompletion: New media inserted "
6030  "into CdRom%d [irp = 0x%lx]\n",
6031  deviceExtension->DeviceNumber, Irp));
6032 
6033  //
6034  // Media change event occurred - signal the named event.
6035  //
6036 
6037  KeSetEvent(deviceExtension->MediaChangeEvent,
6038  (KPRIORITY) 0,
6039  FALSE);
6040 
6041  deviceExtension->MediaChangeNoMedia = FALSE;
6042 
6043  }
6044 
6045  if (DeviceObject->Vpb->Flags & VPB_MOUNTED) {
6046 
6047  //
6048  // Must remember the media changed and force the
6049  // file system to verify on next access
6050  //
6051 
6052  DeviceObject->Flags |= DO_VERIFY_VOLUME;
6053  }
6054 
6055  physicalExtension->MediaChangeCount++;
6056 
6057  } else if(((senseBuffer->SenseKey & 0x0f) == SCSI_SENSE_NOT_READY)&&
6059  (!deviceExtension->MediaChangeNoMedia)){
6060 
6061  //
6062  // If there was no media in the device then signal the waiters if
6063  // we haven't already done so before.
6064  //
6065 
6066  DebugPrint((1, "CdRomMediaChangeCompletion: No media in device"
6067  "CdRom%d [irp = 0x%lx]\n",
6068  deviceExtension->DeviceNumber, Irp));
6069 
6070  KeSetEvent(deviceExtension->MediaChangeEvent,
6071  (KPRIORITY) 0,
6072  FALSE);
6073 
6074  deviceExtension->MediaChangeNoMedia = TRUE;
6075 
6076  }
6077  }
6078  } else if((srb->SrbStatus == SRB_STATUS_SUCCESS)&&
6079  (deviceExtension->MediaChangeNoMedia)) {
6080  //
6081  // We didn't have any media before and now the requests are succeeding
6082  // we probably missed the Media change somehow. Signal the change
6083  // anyway
6084  //
6085 
6086  DebugPrint((1, "CdRomMediaChangeCompletion: Request completed normally"
6087  "for CdRom%d which was marked w/NoMedia [irp = 0x%lx]\n",
6088  deviceExtension->DeviceNumber, Irp));
6089 
6090  KeSetEvent(deviceExtension->MediaChangeEvent,
6091  (KPRIORITY) 0,
6092  FALSE);
6093 
6094  deviceExtension->MediaChangeNoMedia = FALSE;
6095 
6096  }
6097 
6098  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
6099  ScsiClassReleaseQueue(deviceExtension->DeviceObject);
6100  }
6101 
6102  //
6103  // Remember the IRP and SRB for use the next time.
6104  //
6105 
6106  irpNextStack->Parameters.Scsi.Srb = srb;
6107  cddata->MediaChangeIrp = Irp;
6108 
6109  if (deviceExtension->ClassError) {
6110 
6111  NTSTATUS status;
6112  BOOLEAN retry;
6113 
6114  //
6115  // Throw away the status and retry values. Just give the error routine a chance
6116  // to do what it needs to.
6117  //
6118 
6119  deviceExtension->ClassError(DeviceObject,
6120  srb,
6121  &status,
6122  &retry);
6123  }
6124 
6126 
6128 }
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
VOID ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
UCHAR SrbStatus
Definition: srb.h:243
LONG KPRIORITY
Definition: compat.h:662
#define FALSE
Definition: types.h:117
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
UCHAR SenseInfoBufferLength
Definition: srb.h:251
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
PVOID SenseInfoBuffer
Definition: srb.h:256
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
#define VPB_MOUNTED
Definition: iotypes.h:1787
static SERVICE_STATUS status
Definition: service.c:31
PIRP MediaChangeIrp
Definition: cdrom.c:156
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

◆ CdRomSetVolumeIntermediateCompletion()

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

Definition at line 3834 of file cdrom.c.

3839 {
3840  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3842  PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension + 1);
3843  BOOLEAN use6Byte = cdData->XAFlags & XA_USE_6_BYTE;
3844  PIO_STACK_LOCATION realIrpStack;
3845  PIO_STACK_LOCATION realIrpNextStack;
3847  PIRP realIrp = NULL;
3848  NTSTATUS status;
3849  BOOLEAN retry;
3850 
3851  //
3852  // Extract the 'real' irp from the irpstack.
3853  //
3854 
3855  realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
3856  realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
3857  realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
3858 
3859  //
3860  // Check SRB status for success of completing request.
3861  //
3862 
3863  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
3864 
3865  DebugPrint((2,
3866  "CdRomSetVolumeIntermediateCompletion: Irp %lx, Srb %lx Real Irp\n",
3867  Irp,
3868  srb,
3869  realIrp));
3870 
3871  //
3872  // Release the queue if it is frozen.
3873  //
3874 
3875  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
3877  }
3878 
3879 
3881  srb,
3882  irpStack->MajorFunction,
3883  irpStack->Parameters.DeviceIoControl.IoControlCode,
3884  MAXIMUM_RETRIES - ((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
3885  &status);
3886 
3887  if (status == STATUS_DATA_OVERRUN) {
3889  retry = FALSE;
3890  }
3891 
3892  //
3893  // If the status is verified required and the this request
3894  // should bypass verify required then retry the request.
3895  //
3896 
3897  if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
3899 
3901  retry = TRUE;
3902  }
3903 
3904  if (retry && (realIrpNextStack->Parameters.Others.Argument1 = (PVOID)((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1-1))) {
3905 
3906  if (((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
3907 
3908  //
3909  // Retry request.
3910  //
3911 
3912  DebugPrint((1, "Retry request %lx - Calling StartIo\n", Irp));
3913 
3914 
3916  ExFreePool(srb->DataBuffer);
3917  ExFreePool(srb);
3918  if (Irp->MdlAddress) {
3919  IoFreeMdl(Irp->MdlAddress);
3920  }
3921 
3922  IoFreeIrp(Irp);
3923 
3924  //
3925  // Call StartIo directly since IoStartNextPacket hasn't been called,
3926  // the serialisation is still intact.
3927  //
3928  ScsiCdRomStartIo(DeviceObject, realIrp);
3930 
3931  }
3932 
3933  //
3934  // Exhausted retries. Fall through and complete the request with the appropriate status.
3935  //
3936 
3937  }
3938  } else {
3939 
3940  //
3941  // Set status for successful request.
3942  //
3943 
3945  }
3946 
3947  if (NT_SUCCESS(status)) {
3948 
3949  PAUDIO_OUTPUT audioInput = NULL;
3950  PAUDIO_OUTPUT audioOutput;
3951  PVOLUME_CONTROL volumeControl = realIrp->AssociatedIrp.SystemBuffer;
3952  ULONG i,bytesTransferred,headerLength;
3953  PVOID dataBuffer;
3954  PCDB cdb;
3955 
3956  audioInput = ScsiClassFindModePage((PCHAR)srb->DataBuffer,
3957  srb->DataTransferLength,
3959  use6Byte);
3960 
3961  //
3962  // Check to make sure the mode sense data is valid before we go on
3963  //
3964 
3965  if(audioInput == NULL) {
3966 
3967  DebugPrint((1, "Mode Sense Page %d not found\n",
3969 
3970  realIrp->IoStatus.Information = 0;
3974  ExFreePool(srb);
3975  IoFreeMdl(Irp->MdlAddress);
3976  IoFreeIrp(Irp);
3978  }
3979 
3980  if (use6Byte) {
3981  headerLength = sizeof(MODE_PARAMETER_HEADER);
3982  } else {
3983  headerLength = sizeof(MODE_PARAMETER_HEADER10);
3984  }
3985 
3986  bytesTransferred = sizeof(AUDIO_OUTPUT) + headerLength;
3987 
3988  //
3989  // Allocate a new buffer for the mode select.
3990  //
3991 
3992  dataBuffer = ExAllocatePool(NonPagedPoolCacheAligned, bytesTransferred);
3993 
3994  if (!dataBuffer) {
3995  realIrp->IoStatus.Information = 0;
3999  ExFreePool(srb);
4000  IoFreeMdl(Irp->MdlAddress);
4001  IoFreeIrp(Irp);
4003  }
4004 
4005  RtlZeroMemory(dataBuffer, bytesTransferred);
4006 
4007  //
4008  // Rebuild the data buffer to include the user requested values.
4009  //
4010 
4011  audioOutput = (PAUDIO_OUTPUT) ((PCHAR) dataBuffer + headerLength);
4012 
4013  for (i=0; i<4; i++) {
4014  audioOutput->PortOutput[i].Volume =
4015  volumeControl->PortVolume[i];
4016  audioOutput->PortOutput[i].ChannelSelection =
4017  audioInput->PortOutput[i].ChannelSelection;
4018  }
4019 
4020  audioOutput->CodePage = CDROM_AUDIO_CONTROL_PAGE;
4021  audioOutput->ParameterLength = sizeof(AUDIO_OUTPUT) - 2;
4022  audioOutput->Immediate = MODE_SELECT_IMMEDIATE;
4023 
4024  //
4025  // Free the old data buffer, mdl.
4026  //
4027 
4028  ExFreePool(srb->DataBuffer);
4029  IoFreeMdl(Irp->MdlAddress);
4030 
4031  //
4032  // rebuild the srb.
4033  //
4034 
4035  cdb = (PCDB)srb->Cdb;
4037 
4038  srb->SrbStatus = srb->ScsiStatus = 0;
4039  srb->SrbFlags = deviceExtension->SrbFlags;
4041  srb->DataTransferLength = bytesTransferred;
4042 
4043  if (use6Byte) {
4044 
4045  cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
4046  cdb->MODE_SELECT.ParameterListLength = (UCHAR) bytesTransferred;
4047  cdb->MODE_SELECT.PFBit = 1;
4048  srb->CdbLength = 6;
4049  } else {
4050 
4051  cdb->MODE_SELECT10.OperationCode = SCSIOP_MODE_SELECT10;
4052  cdb->MODE_SELECT10.ParameterListLength[0] = (UCHAR) (bytesTransferred >> 8);
4053  cdb->MODE_SELECT10.ParameterListLength[1] = (UCHAR) (bytesTransferred & 0xFF);
4054  cdb->MODE_SELECT10.PFBit = 1;
4055  srb->CdbLength = 10;
4056  }
4057 
4058  //
4059  // Prepare the MDL
4060  //
4061 
4062  Irp->MdlAddress = IoAllocateMdl(dataBuffer,
4063  bytesTransferred,
4064  FALSE,
4065  FALSE,
4066  (PIRP) NULL);
4067 
4068  if (!Irp->MdlAddress) {
4069  realIrp->IoStatus.Information = 0;
4073  ExFreePool(srb);
4074  ExFreePool(dataBuffer);
4075  IoFreeIrp(Irp);
4077 
4078  }
4079 
4080  MmBuildMdlForNonPagedPool(Irp->MdlAddress);
4081  srb->DataBuffer = dataBuffer;
4082 
4083  irpStack = IoGetNextIrpStackLocation(Irp);
4085  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
4086  irpStack->Parameters.Scsi.Srb = srb;
4087 
4088  //
4089  // reset the irp completion.
4090  //
4091 
4094  srb,
4095  TRUE,
4096  TRUE,
4097  TRUE);
4098  //
4099  // Call the port driver.
4100  //
4101 
4102  IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4103 
4105  }
4106 
4107  //
4108  // Deallocate srb and sense buffer.
4109  //
4110 
4111  if (srb) {
4112  if (srb->DataBuffer) {
4113  ExFreePool(srb->DataBuffer);
4114  }
4115  if (srb->SenseInfoBuffer) {
4117  }
4118  ExFreePool(srb);
4119  }
4120 
4121  if (Irp->PendingReturned) {
4123  }
4124 
4125  if (realIrp->PendingReturned) {
4126  IoMarkIrpPending(realIrp);
4127  }
4128 
4129  if (Irp->MdlAddress) {
4130  IoFreeMdl(Irp->MdlAddress);
4131  }
4132 
4133  IoFreeIrp(Irp);
4134 
4135  //
4136  // Set status in completing IRP.
4137  //
4138 
4139  realIrp->IoStatus.Status = status;
4140 
4141  //
4142  // Set the hard error if necessary.
4143  //
4144 
4146 
4147  //
4148  // Store DeviceObject for filesystem, and clear
4149  // in IoStatus.Information field.
4150  //
4151 
4153  realIrp->IoStatus.Information = 0;
4154  }
4155 
4157 
4159 
4161 }
#define CDB12GENERIC_LENGTH
Definition: cdrom.c:21
signed char * PCHAR
Definition: retypes.h:7
struct _CDB::_MODE_SELECT10 MODE_SELECT10
#define MODE_SELECT_IMMEDIATE
Definition: scsi.h:992
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG SrbFlags
Definition: srb.h:252
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
UCHAR Cdb[16]
Definition: srb.h:271
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
ULONG DataTransferLength
Definition: srb.h:253
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define CDROM_AUDIO_CONTROL_PAGE
Definition: scsi.h:991
UCHAR CdbLength
Definition: srb.h:250
VOID ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
IO_COMPLETION_ROUTINE CdRomDeviceControlCompletion
Definition: cdrom.c:281
IO_STATUS_BLOCK IoStatus
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
VOID NTAPI ScsiCdRomStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cdrom.c:1495
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _AUDIO_OUTPUT AUDIO_OUTPUT
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
PVOID NTAPI ScsiClassFindModePage(IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
Definition: class2.c:3296
UCHAR ScsiStatus
Definition: srb.h:244
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
UCHAR ChannelSelection
Definition: scsi.h:3188
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
struct _CDB::_MODE_SELECT MODE_SELECT
UCHAR ParameterLength
Definition: scsi.h:3194
PORT_OUTPUT PortOutput[4]
Definition: scsi.h:3199
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _AUDIO_OUTPUT * PAUDIO_OUTPUT
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
struct _IRP * PIRP
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR CodePage
Definition: scsi.h:3193
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
UCHAR Volume
Definition: scsi.h:3189
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
UCHAR PortVolume[4]
Definition: ntddcdrm.h:375
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
USHORT XAFlags
Definition: cdrom.c:82
#define XA_USE_6_BYTE
Definition: cdrom.c:208
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PVOID SenseInfoBuffer
Definition: srb.h:256
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
#define SCSIOP_MODE_SELECT10
Definition: cdrw_hw.h:943
static SERVICE_STATUS status
Definition: service.c:31
UCHAR Immediate
Definition: scsi.h:3195
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

◆ CdRomSwitchModeCompletion()

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

Definition at line 4166 of file cdrom.c.

4171 {
4172  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4174  PCDROM_DATA cdData = (PCDROM_DATA)(deviceExtension + 1);
4175  PIO_STACK_LOCATION realIrpStack;
4176  PIO_STACK_LOCATION realIrpNextStack;
4178  PIRP realIrp = NULL;
4179  NTSTATUS status;
4180  BOOLEAN retry;
4181 
4182  //
4183  // Extract the 'real' irp from the irpstack.
4184  //
4185 
4186  realIrp = (PIRP) irpStack->Parameters.Others.Argument2;
4187  realIrpStack = IoGetCurrentIrpStackLocation(realIrp);
4188  realIrpNextStack = IoGetNextIrpStackLocation(realIrp);
4189 
4190  //
4191  // Check SRB status for success of completing request.
4192  //
4193 
4194  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
4195 
4196  DebugPrint((2,
4197  "CdRomSetVolumeIntermediateCompletion: Irp %lx, Srb %lx Real Irp\n",
4198  Irp,
4199  srb,
4200  realIrp));
4201 
4202  //
4203  // Release the queue if it is frozen.
4204  //
4205 
4206  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
4208  }
4209 
4210 
4212  srb,
4213  irpStack->MajorFunction,
4214  irpStack->Parameters.DeviceIoControl.IoControlCode,
4215  MAXIMUM_RETRIES - ((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1),
4216  &status);
4217 
4218  //
4219  // If the status is verified required and the this request
4220  // should bypass verify required then retry the request.
4221  //
4222 
4223  if (realIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
4225 
4227  retry = TRUE;
4228  }
4229 
4230  if (retry && (realIrpNextStack->Parameters.Others.Argument1 = (PVOID)((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1-1))) {
4231 
4232  if (((ULONG_PTR)realIrpNextStack->Parameters.Others.Argument1)) {
4233 
4234  //
4235  // Retry request.
4236  //
4237 
4238  DebugPrint((1, "Retry request %lx - Calling StartIo\n", Irp));
4239 
4240 
4242  ExFreePool(srb->DataBuffer);
4243  ExFreePool(srb);
4244  if (Irp->MdlAddress) {
4245  IoFreeMdl(Irp->MdlAddress);
4246  }
4247 
4248  IoFreeIrp(Irp);
4249 
4250  //
4251  // Call StartIo directly since IoStartNextPacket hasn't been called,
4252  // the serialisation is still intact.
4253  //
4254 
4255  ScsiCdRomStartIo(DeviceObject, realIrp);
4257 
4258  }
4259 
4260  //
4261  // Exhausted retries. Fall through and complete the request with the appropriate status.
4262  //
4263  }
4264  } else {
4265 
4266  //
4267  // Set status for successful request.
4268  //
4269 
4271  }
4272 
4273  if (NT_SUCCESS(status)) {
4274 
4275  ULONG sectorSize, startingSector, transferByteCount;
4276  PCDB cdb;
4277 
4278  //
4279  // Update device ext. to show which mode we are currently using.
4280  //
4281 
4282  sectorSize = cdData->u1.BlockDescriptor.BlockLength[0] << 16;
4283  sectorSize |= (cdData->u1.BlockDescriptor.BlockLength[1] << 8);
4284  sectorSize |= (cdData->u1.BlockDescriptor.BlockLength[2]);
4285 
4286  cdData->RawAccess = (sectorSize == RAW_SECTOR_SIZE) ? TRUE : FALSE;
4287 
4288  //
4289  // Free the old data buffer, mdl.
4290  //
4291 
4292  ExFreePool(srb->DataBuffer);
4293  IoFreeMdl(Irp->MdlAddress);
4294  IoFreeIrp(Irp);
4295 
4296  //
4297  // rebuild the srb.
4298  //
4299 
4300  cdb = (PCDB)srb->Cdb;
4302 
4303 
4304  if (cdData->RawAccess) {
4305 
4306  PRAW_READ_INFO rawReadInfo =
4307  (PRAW_READ_INFO)realIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
4308 
4309  ULONG maximumTransferLength;
4310  ULONG transferPages;
4311 
4312  //
4313  // Calculate starting offset.
4314  //
4315 
4316  startingSector = (ULONG)(rawReadInfo->DiskOffset.QuadPart >> deviceExtension->SectorShift);
4317  transferByteCount = rawReadInfo->SectorCount * RAW_SECTOR_SIZE;
4318  maximumTransferLength = deviceExtension->PortCapabilities->MaximumTransferLength;
4319  transferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(realIrp->MdlAddress),
4320  transferByteCount);
4321 
4322  //
4323  // Determine if request is within limits imposed by miniport.
4324  // If the request is larger than the miniport's capabilities, split it.
4325  //
4326 
4327  if (transferByteCount > maximumTransferLength ||
4328  transferPages > deviceExtension->PortCapabilities->MaximumPhysicalPages) {
4329 
4330  realIrp->IoStatus.Information = 0;
4333 
4335  ExFreePool(srb);
4336 
4338 
4340  }
4341 
4342  srb->OriginalRequest = realIrp;
4343  srb->SrbFlags = deviceExtension->SrbFlags;
4345  srb->DataTransferLength = transferByteCount;
4346  srb->TimeOutValue = deviceExtension->TimeOutValue;
4347  srb->CdbLength = 10;
4348  srb->DataBuffer = MmGetMdlVirtualAddress(realIrp->MdlAddress);
4349 
4350  if (rawReadInfo->TrackMode == CDDA) {
4351  if (cdData->XAFlags & PLEXTOR_CDDA) {
4352 
4353  srb->CdbLength = 12;
4354 
4355  cdb->PLXTR_READ_CDDA.LogicalUnitNumber = deviceExtension->Lun;
4356  cdb->PLXTR_READ_CDDA.LogicalBlockByte3 = (UCHAR) (startingSector & 0xFF);
4357  cdb->PLXTR_READ_CDDA.LogicalBlockByte2 = (UCHAR) ((startingSector >> 8) & 0xFF);
4358  cdb->PLXTR_READ_CDDA.LogicalBlockByte1 = (UCHAR) ((startingSector >> 16) & 0xFF);
4359  cdb->PLXTR_READ_CDDA.LogicalBlockByte0 = (UCHAR) ((startingSector >> 24) & 0xFF);
4360 
4361  cdb->PLXTR_READ_CDDA.TransferBlockByte3 = (UCHAR) (rawReadInfo->SectorCount & 0xFF);
4362  cdb->PLXTR_READ_CDDA.TransferBlockByte2 = (UCHAR) (rawReadInfo->SectorCount >> 8);
4363  cdb->PLXTR_READ_CDDA.TransferBlockByte1 = 0;
4364  cdb->PLXTR_READ_CDDA.TransferBlockByte0 = 0;
4365 
4366  cdb->PLXTR_READ_CDDA.SubCode = 0;
4367  cdb->PLXTR_READ_CDDA.OperationCode = 0xD8;
4368 
4369  } else if (cdData->XAFlags & NEC_CDDA) {
4370 
4371  cdb->NEC_READ_CDDA.LogicalBlockByte3 = (UCHAR) (startingSector & 0xFF);
4372  cdb->NEC_READ_CDDA.LogicalBlockByte2 = (UCHAR) ((startingSector >> 8) & 0xFF);
4373  cdb->NEC_READ_CDDA.LogicalBlockByte1 = (UCHAR) ((startingSector >> 16) & 0xFF);
4374  cdb->NEC_READ_CDDA.LogicalBlockByte0 = (UCHAR) ((startingSector >> 24) & 0xFF);
4375 
4376  cdb->NEC_READ_CDDA.TransferBlockByte1 = (UCHAR) (rawReadInfo->SectorCount & 0xFF);
4377  cdb->NEC_READ_CDDA.TransferBlockByte0 = (UCHAR) (rawReadInfo->SectorCount >> 8);
4378 
4379  cdb->NEC_READ_CDDA.OperationCode = 0xD4;
4380  }
4381  } else {
4382  cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
4383 
4384  cdb->CDB10.TransferBlocksMsb = (UCHAR) (rawReadInfo->SectorCount >> 8);
4385  cdb->CDB10.TransferBlocksLsb = (UCHAR) (rawReadInfo->SectorCount & 0xFF);
4386 
4387  cdb->CDB10.LogicalBlockByte3 = (UCHAR) (startingSector & 0xFF);
4388  cdb->CDB10.LogicalBlockByte2 = (UCHAR) ((startingSector >> 8) & 0xFF);
4389  cdb->CDB10.LogicalBlockByte1 = (UCHAR) ((startingSector >> 16) & 0xFF);
4390  cdb->CDB10.LogicalBlockByte0 = (UCHAR) ((startingSector >> 24) & 0xFF);
4391 
4392  cdb->CDB10.OperationCode = SCSIOP_READ;
4393  }
4394 
4395  srb->SrbStatus = srb->ScsiStatus = 0;
4396 
4397 
4398  irpStack = IoGetNextIrpStackLocation(realIrp);
4399  irpStack->MajorFunction = IRP_MJ_SCSI;
4400  irpStack->Parameters.Scsi.Srb = srb;
4401 
4402  if (!(irpStack->Parameters.Others.Argument1)) {
4403 
4404  //
4405  // Only jam this in if it doesn't exist. The completion routines can
4406  // call StartIo directly in the case of retries and resetting it will
4407  // cause infinite loops.
4408  //
4409 
4410  irpStack->Parameters.Others.Argument1 = (PVOID) MAXIMUM_RETRIES;
4411  }
4412 
4413  //
4414  // Set up IoCompletion routine address.
4415  //
4416 
4417  IoSetCompletionRoutine(realIrp,
4419  srb,
4420  TRUE,
4421  TRUE,
4422  TRUE);
4423  } else {
4424 
4425  ULONG maximumTransferLength = deviceExtension->PortCapabilities->MaximumTransferLength;
4426  ULONG transferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(realIrp->MdlAddress),
4427  realIrpStack->Parameters.Read.Length);
4428  //
4429  // Back to cooked sectors. Build and send a normal read.
4430  // The real work for setting offsets and checking for splitrequests was
4431  // done in startio
4432  //
4433 
4434  if ((realIrpStack->Parameters.Read.Length > maximumTransferLength) ||
4435  (transferPages > deviceExtension->PortCapabilities->MaximumPhysicalPages)) {
4436 
4437  //
4438  // Request needs to be split. Completion of each portion of the request will
4439  // fire off the next portion. The final request will signal Io to send a new request.
4440  //
4441 
4442  ScsiClassSplitRequest(DeviceObject, realIrp, maximumTransferLength);
4444 
4445  } else {
4446 
4447  //
4448  // Build SRB and CDB for this IRP.
4449  //
4450 
4452 
4453  }
4454  }
4455 
4456  //
4457  // Call the port driver.
4458  //
4459 
4460  IoCallDriver(deviceExtension->PortDeviceObject, realIrp);
4461 
4463  }
4464 
4465  //
4466  // Update device Extension flags to indicate that XA isn't supported.
4467  //
4468 
4469  cdData->XAFlags |= XA_NOT_SUPPORTED;
4470 
4471  //
4472  // Deallocate srb and sense buffer.
4473  //
4474 
4475  if (srb) {
4476  if (srb->DataBuffer) {
4477  ExFreePool(srb->DataBuffer);
4478  }
4479  if (srb->SenseInfoBuffer) {
4481  }
4482  ExFreePool(srb);
4483  }
4484 
4485  if (Irp->PendingReturned) {
4487  }
4488 
4489  if (realIrp->PendingReturned) {
4490  IoMarkIrpPending(realIrp);
4491  }
4492 
4493  if (Irp->MdlAddress) {
4494  IoFreeMdl(Irp->MdlAddress);
4495  }
4496 
4497  IoFreeIrp(Irp);
4498 
4499  //
4500  // Set status in completing IRP.
4501  //
4502 
4503  realIrp->IoStatus.Status = status;
4504 
4505  //
4506  // Set the hard error if necessary.
4507  //
4508 
4510 
4511  //
4512  // Store DeviceObject for filesystem, and clear
4513  // in IoStatus.Information field.
4514  //
4515 
4517  realIrp->IoStatus.Information = 0;
4518  }
4519 
4521 
4523 
4525 }
#define CDB12GENERIC_LENGTH
Definition: cdrom.c:21
#define XA_NOT_SUPPORTED
Definition: cdrom.c:211
ULONG SrbFlags
Definition: srb.h:252
#define RAW_SECTOR_SIZE
Definition: cdrom.c:174
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
struct _CDB::_NEC_READ_CDDA NEC_READ_CDDA
#define NEC_CDDA
Definition: cdrom.c:214
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PVOID DataBuffer
Definition: srb.h:255
ULONG DataTransferLength
Definition: srb.h:253
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
ULONG SectorCount
Definition: ntddcdrm.h:395
struct _CDB::_PLXTR_READ_CDDA PLXTR_READ_CDDA
UCHAR CdbLength
Definition: srb.h:250
VOID NTAPI ScsiClassSplitRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG MaximumBytes)
Definition: class2.c:1298
VOID ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
IO_STATUS_BLOCK IoStatus
struct _CDB::_CDB10 CDB10
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
ERROR_RECOVERY_DATA u1
Definition: cdrom.c:90
VOID NTAPI ScsiCdRomStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cdrom.c:1495
struct __RAW_READ_INFO * PRAW_READ_INFO
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IRP_MJ_SCSI
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
UCHAR ScsiStatus
Definition: srb.h:244
#define SCSIOP_READ
Definition: cdrw_hw.h:905
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
void * PVOID
Definition: retypes.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
TRACK_MODE_TYPE TrackMode
Definition: ntddcdrm.h:396
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
struct _IRP * PIRP
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
UCHAR BlockLength[3]
Definition: cdrw_hw.h:2531
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
Definition: ntddcdrm.h:381
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
USHORT XAFlags
Definition: cdrom.c:82
#define PLEXTOR_CDDA
Definition: cdrom.c:213
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PVOID SenseInfoBuffer
Definition: srb.h:256
VOID NTAPI ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class2.c:2970
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
LARGE_INTEGER DiskOffset
Definition: ntddcdrm.h:394
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
MODE_PARAMETER_BLOCK BlockDescriptor
Definition: cdrom.c:47
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
BOOLEAN RawAccess
Definition: cdrom.c:75
IO_COMPLETION_ROUTINE CdRomXACompletion
Definition: cdrom.c:308
LONGLONG QuadPart
Definition: typedefs.h:114
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

◆ CdRomTickHandler()

VOID NTAPI CdRomTickHandler ( IN PDEVICE_OBJECT  DeviceObject,
IN PVOID  Context 
)

Definition at line 6132 of file cdrom.c.

6157 {
6158  PIRP irp;
6159  PIRP heldIrpList;
6160  PIRP nextIrp;
6161  PLIST_ENTRY listEntry;
6162  PCDROM_DATA cddata;
6163  PIO_STACK_LOCATION irpStack;
6164  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
6165 
6166  cddata = (PCDROM_DATA)(deviceExtension + 1);
6167 
6168  if (cddata->MediaChange) {
6169  if (cddata->MediaChangeIrp != NULL) {
6170 
6171  //
6172  // Media change support is active and the IRP is waiting.
6173  // Decrement the timer.
6174  // There is no MP protection on the timer counter. This
6175  // code is the only code that will manipulate the timer
6176  // and only one instance of it should be running at any
6177  // given time.
6178  //
6179 
6180  cddata->MediaChangeCountDown--;
6181 
6182 #if DBG
6183  cddata->MediaChangeIrpTimeInUse = 0;
6184  cddata->MediaChangeIrpLost = FALSE;
6185 #endif
6186 
6187  if (!cddata->MediaChangeCountDown) {
6188  PSCSI_REQUEST_BLOCK srb;
6189  PIO_STACK_LOCATION irpNextStack;
6190  PCDB cdb;
6191 
6192  //
6193  // Reset the timer.
6194  //
6195 
6197 
6198  //
6199  // Prepare the IRP for the test unit ready
6200  //
6201 
6202  irp = cddata->MediaChangeIrp;
6203  cddata->MediaChangeIrp = NULL;
6204 
6206  irp->IoStatus.Information = 0;
6207  irp->Flags = 0;
6208  irp->UserBuffer = NULL;
6209 
6210  //
6211  // If the irp is sent down when the volume needs to be
6212  // verified, CdRomUpdateGeometryCompletion won't complete
6213  // it since it's not associated with a thread. Marking
6214  // it to override the verify causes it always be sent
6215  // to the port driver
6216  //
6217 
6218  irpStack = IoGetCurrentIrpStackLocation(irp);
6219  irpStack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
6220 
6221  irpNextStack = IoGetNextIrpStackLocation(irp);
6223  irpNextStack->Parameters.DeviceIoControl.IoControlCode =
6225 
6226  //
6227  // Prepare the SRB for execution.
6228  //
6229 
6230  srb = irpNextStack->Parameters.Scsi.Srb;
6231  srb->SrbStatus = srb->ScsiStatus = 0;
6232  srb->NextSrb = 0;
6234  srb->PathId = deviceExtension->PathId;
6235  srb->TargetId = deviceExtension->TargetId;
6236  srb->Lun = deviceExtension->Lun;
6240  srb->DataTransferLength = 0;
6241  srb->OriginalRequest = irp;
6242 
6245 
6246  cdb = (PCDB) &srb->Cdb[0];
6247  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
6248  cdb->CDB6GENERIC.LogicalUnitNumber = srb->Lun;
6249 
6250  //
6251  // Setup the IRP to perform a test unit ready.
6252  //
6253 
6256  srb,
6257  TRUE,
6258  TRUE,
6259  TRUE);
6260 
6261  //
6262  // Issue the request.
6263  //
6264 
6266  }
6267  } else {
6268 
6269 #if DBG
6270  if(cddata->MediaChangeIrpLost == FALSE) {
6271  if(cddata->MediaChangeIrpTimeInUse++ >
6273 
6274  DebugPrint((0, "CdRom%d: AutoPlay has lost it's irp and "
6275  "doesn't know where to find it. Leave it "
6276  "alone and it'll come home dragging it's "
6277  "stack behind it.\n",
6278  deviceExtension->DeviceNumber));
6279  cddata->MediaChangeIrpLost = TRUE;
6280  }
6281  }
6282 
6283 #endif
6284  }
6285  }
6286 
6287  //
6288  // Process all generic timer IRPS in the timer list. As IRPs are pulled
6289  // off of the TimerIrpList they must be remembered in the first loop
6290  // if they are not sent to the lower driver. After all items have
6291  // been pulled off the list, it is possible to put the held IRPs back
6292  // into the TimerIrpList.
6293  //
6294 
6295  heldIrpList = NULL;
6296  if (IsListEmpty(&cddata->TimerIrpList)) {
6297  listEntry = NULL;
6298  } else {
6299  listEntry = ExInterlockedRemoveHeadList(&cddata->TimerIrpList,
6300  &cddata->TimerIrpSpinLock);
6301  }
6302  while (listEntry) {
6303 
6304  //
6305  // There is something in the timer list. Pick up the IRP and
6306  // see if it is ready to be submitted.
6307  //
6308 
6309  irp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
6310  irpStack = IoGetCurrentIrpStackLocation(irp);
6311 
6312  if (irpStack->Parameters.Others.Argument3) {
6313  ULONG_PTR count;
6314 
6315  //
6316  // Decrement the countdown timer and put the IRP back in the list.
6317  //
6318 
6319  count = (ULONG_PTR) irpStack->Parameters.Others.Argument3;
6320  count--;
6321  irpStack->Parameters.Others.Argument3 = (PVOID) count;
6322 
6323  ASSERT(irp->AssociatedIrp.MasterIrp == NULL);
6324  if (heldIrpList) {
6325  irp->AssociatedIrp.MasterIrp = (PVOID) heldIrpList;
6326  }
6327  heldIrpList = irp;
6328 
6329  } else {
6330 
6331  //
6332  // Submit this IRP to the lower driver. This IRP does not
6333  // need to be remembered here. It will be handled again when
6334  // it completes.
6335  //
6336 
6337  DebugPrint((1, "CdRomTickHandler: Reissuing request %lx (thread = %lx)\n", irp, irp->Tail.Overlay.Thread));
6338 
6339  //
6340  // feed this to the appropriate port driver
6341  //
6342 
6343  IoCallDriver (deviceExtension->PortDeviceObject, irp);
6344 
6345  }
6346 
6347  //
6348  // Pick up the next IRP from the timer list.
6349  //
6350 
6351  listEntry = ExInterlockedRemoveHeadList(&cddata->TimerIrpList,
6352  &cddata->TimerIrpSpinLock);
6353  }
6354 
6355  //
6356  // Move all held IRPs back onto the timer list.
6357  //
6358 
6359  while (heldIrpList) {
6360 
6361  //
6362  // Save the single list pointer before queueing this IRP.
6363  //
6364 
6365  nextIrp = (PIRP) heldIrpList->AssociatedIrp.MasterIrp;
6366  heldIrpList->AssociatedIrp.MasterIrp = NULL;
6367 
6368  //
6369  // Return the held IRP to the timer list.
6370  //
6371 
6373  &heldIrpList->Tail.Overlay.ListEntry,
6374  &cddata->TimerIrpSpinLock);
6375 
6376  //
6377  // Continue processing the held IRPs
6378  //
6379 
6380  heldIrpList = nextIrp;
6381  }
6382 }
UCHAR MediaChangeCountDown
Definition: cdrom.c:128
IO_COMPLETION_ROUTINE CdRomMediaChangeCompletion
Definition: cdrom.c:5958
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
#define TRUE
Definition: types.h:120
GLuint GLuint GLsizei count
Definition: gl.h:1545
ULONG DataTransferLength
Definition: srb.h:253
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
Definition: cdrw_hw.h:28
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
IO_STATUS_BLOCK IoStatus
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:257
UCHAR SrbStatus
Definition: srb.h:243
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
UCHAR ScsiStatus
Definition: srb.h:244
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
struct _CDROM_DATA * PCDROM_DATA
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
void * PVOID
Definition: retypes.h:9
UCHAR TargetId
Definition: srb.h:246
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOLEAN MediaChange
Definition: cdrom.c:120
#define MEDIA_CHANGE_TIMEOUT_TIME
Definition: cdrom.h:135
UCHAR Function
Definition: srb.h:242
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
USHORT Length
Definition: srb.h:241
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
struct _IRP * PIRP
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
LIST_ENTRY TimerIrpList
Definition: cdrom.c:164
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
Definition: typedefs.h:119
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
UCHAR SenseInfoBufferLength
Definition: srb.h:251
UCHAR PathId
Definition: srb.h:245
#define MEDIA_CHANGE_DEFAULT_TIME
Definition: cdrom.c:176
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
KSPIN_LOCK TimerIrpSpinLock
Definition: cdrom.c:165
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PVOID SenseInfoBuffer
Definition: srb.h:256
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
PIRP MediaChangeIrp
Definition: cdrom.c:156

Referenced by CreateCdRomDeviceObject().

◆ CdRomUpdateCapacity()

NTSTATUS NTAPI CdRomUpdateCapacity ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  IrpToComplete,
IN OPTIONAL PKEVENT  IoctlEvent 
)

Definition at line 7151 of file cdrom.c.

7177 {
7178  PCDB cdb;
7179  PIRP irp;
7180  PSCSI_REQUEST_BLOCK srb;
7181  PREAD_CAPACITY_DATA capacityBuffer;
7182  PIO_STACK_LOCATION irpStack;
7183  PUCHAR senseBuffer;
7184 
7185  irp = IoAllocateIrp((CCHAR)(DeviceExtension->DeviceObject->StackSize+1),
7186  FALSE);
7187 
7188  if (irp) {
7189 
7191  if (srb) {
7192  capacityBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
7193  sizeof(READ_CAPACITY_DATA));
7194 
7195  if (capacityBuffer) {
7196 
7197 
7199 
7200  if (senseBuffer) {
7201 
7202  irp->MdlAddress = IoAllocateMdl(capacityBuffer,
7203  sizeof(READ_CAPACITY_DATA),
7204  FALSE,
7205  FALSE,
7206  (PIRP) NULL);
7207 
7208  if (irp->MdlAddress) {
7209 
7210  //
7211  // Have all resources. Set up the IRP to send for the capacity.
7212  //
7213 
7216  irp->IoStatus.Information = 0;
7217  irp->Flags = 0;
7218  irp->UserBuffer = NULL;
7219 
7220  //
7221  // Save the device object and retry count in a private stack location.
7222  //
7223 
7224  irpStack = IoGetCurrentIrpStackLocation(irp);
7225  irpStack->DeviceObject = DeviceExtension->DeviceObject;
7226  irpStack->Parameters.Others.Argument1 = (PVOID) MAXIMUM_RETRIES;
7227  irpStack->Parameters.Others.Argument2 = (PVOID) IrpToComplete;
7228 
7229  //
7230  // Construct the IRP stack for the lower level driver.
7231  //
7232 
7233  irpStack = IoGetNextIrpStackLocation(irp);
7235  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
7236  irpStack->Parameters.Scsi.Srb = srb;
7239  srb,
7240  TRUE,
7241  TRUE,
7242  TRUE);
7243  //
7244  // Prepare the MDL
7245  //
7246 
7247  MmBuildMdlForNonPagedPool(irp->MdlAddress);
7248 
7249 
7250  //
7251  // Set up the SRB for read capacity.
7252  //
7253 
7254  RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
7255  RtlZeroMemory(senseBuffer, SENSE_BUFFER_SIZE);
7256  srb->CdbLength = 10;
7257  srb->TimeOutValue = DeviceExtension->TimeOutValue;
7258  srb->SrbStatus = srb->ScsiStatus = 0;
7259  srb->NextSrb = 0;
7261  srb->PathId = DeviceExtension->PathId;
7262  srb->TargetId = DeviceExtension->TargetId;
7263  srb->Lun = DeviceExtension->Lun;
7266  srb->DataBuffer = capacityBuffer;
7267  srb->DataTransferLength = sizeof(READ_CAPACITY_DATA);
7268  srb->OriginalRequest = irp;
7269  srb->SenseInfoBuffer = senseBuffer;
7271 
7272  //
7273  // Set up the CDB
7274  //
7275 
7276  cdb = (PCDB) &srb->Cdb[0];
7277  cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
7278  cdb->CDB10.LogicalUnitNumber = DeviceExtension->Lun;
7279 
7280  //
7281  // Set the return value in the IRP that will be completed
7282  // upon completion of the read capacity.
7283  //
7284 
7285  IrpToComplete->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
7286  IoMarkIrpPending(IrpToComplete);
7287 
7288  IoCallDriver(DeviceExtension->PortDeviceObject, irp);
7289 
7290  //
7291  // status is not checked because the completion routine for this
7292  // IRP will always get called and it will free the resources.
7293  //
7294 
7295  return STATUS_PENDING;
7296 
7297  } else {
7298  ExFreePool(senseBuffer);
7299  ExFreePool(capacityBuffer);
7300  ExFreePool(srb);
7301  IoFreeIrp(irp);
7302  }
7303  } else {
7304  ExFreePool(capacityBuffer);
7305  ExFreePool(srb);
7306  IoFreeIrp(irp);
7307  }
7308  } else {
7309  ExFreePool(srb);
7310  IoFreeIrp(irp);
7311  }
7312  } else {
7313  IoFreeIrp(irp);
7314  }
7315  }
7316 
7318 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG DataTransferLength
Definition: srb.h:253
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
Definition: cdrw_hw.h:28
IO_COMPLETION_ROUTINE CdRomUpdateGeometryCompletion
Definition: cdrom.c:6896
UCHAR CdbLength
Definition: srb.h:250
IO_STATUS_BLOCK IoStatus
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:257
struct _CDB::_CDB10 CDB10
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define FALSE
Definition: types.h:117
UCHAR ScsiStatus
Definition: srb.h:244
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
void * PVOID
Definition: retypes.h:9
UCHAR TargetId
Definition: srb.h:246
#define STATUS_PENDING
Definition: ntstatus.h:82
char CCHAR
Definition: typedefs.h:51
UCHAR Function
Definition: srb.h:242
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
USHORT Length
Definition: srb.h:241
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
struct _READ_CAPACITY_DATA READ_CAPACITY_DATA
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
UCHAR SenseInfoBufferLength
Definition: srb.h:251
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
PVOID SenseInfoBuffer
Definition: srb.h:256
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by CdRomDeviceControlCompletion(), and ScsiCdRomStartIo().

◆ CdRomUpdateGeometryCompletion()

NTSTATUS NTAPI CdRomUpdateGeometryCompletion ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

Definition at line 6899 of file cdrom.c.

6926 {
6928  PREAD_CAPACITY_DATA readCapacityBuffer;
6929  PDEVICE_EXTENSION deviceExtension;
6930  PIO_STACK_LOCATION irpStack;
6931  NTSTATUS status;
6932  BOOLEAN retry;
6933  ULONG_PTR retryCount;
6934  ULONG lastSector;
6935  PIRP originalIrp;
6936  PCDROM_DATA cddata;
6937 
6938  //
6939  // Get items saved in the private IRP stack location.
6940  //
6941 
6942  irpStack = IoGetCurrentIrpStackLocation(Irp);
6943  retryCount = (ULONG_PTR) irpStack->Parameters.Others.Argument1;
6944  originalIrp = (PIRP) irpStack->Parameters.Others.Argument2;
6945 
6946  if (!DeviceObject) {
6947  DeviceObject = irpStack->DeviceObject;
6948  }
6950 
6951  deviceExtension = DeviceObject->DeviceExtension;
6952  cddata = (PCDROM_DATA) (deviceExtension + 1);
6953  readCapacityBuffer = srb->DataBuffer;
6954 
6955  if ((NT_SUCCESS(Irp->IoStatus.Status)) && (SRB_STATUS(srb->SrbStatus) == SRB_STATUS_SUCCESS)) {
6956  PFOUR_BYTE from;
6957  PFOUR_BYTE to;
6958 
6959  DebugPrint((2, "CdRomUpdateCapacityCompletion: [%lx] successful completion of buddy-irp %lx\n", originalIrp, Irp));
6960  //
6961  // Copy sector size from read capacity buffer to device extension
6962  // in reverse byte order.
6963  //
6964 
6965  from = (PFOUR_BYTE) &readCapacityBuffer->BytesPerBlock;
6966  to = (PFOUR_BYTE) &deviceExtension->DiskGeometry->Geometry.BytesPerSector;
6967  to->Byte0 = from->Byte3;
6968  to->Byte1 = from->Byte2;
6969  to->Byte2 = from->Byte1;
6970  to->Byte3 = from->Byte0;
6971 
6972  //
6973  // Using the new BytesPerBlock, calculate and store the SectorShift.
6974  //
6975 
6976  WHICH_BIT(deviceExtension->DiskGeometry->Geometry.BytesPerSector, deviceExtension->SectorShift);
6977 
6978  //
6979  // Copy last sector in reverse byte order.
6980  //
6981 
6982  from = (PFOUR_BYTE) &readCapacityBuffer->LogicalBlockAddress;
6983  to = (PFOUR_BYTE) &lastSector;
6984  to->Byte0 = from->Byte3;
6985  to->Byte1 = from->Byte2;
6986  to->Byte2 = from->Byte1;
6987  to->Byte3 = from->Byte0;
6988  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
6989 
6990  //
6991  // Calculate number of cylinders.
6992  //
6993 
6994  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(32 * 64));
6995  deviceExtension->PartitionLength.QuadPart =
6996  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
6997  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
6998 
6999  //
7000  // Assume sectors per track are 32;
7001  //
7002 
7003  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = 32;
7004 
7005  //
7006  // Assume tracks per cylinder (number of heads) is 64.
7007  //
7008 
7009  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = 64;
7010 
7011  } else {
7012 
7013  DebugPrint((1, "CdRomUpdateCapacityCompletion: [%lx] unsuccessful completion of buddy-irp %lx (status - %lx)\n", originalIrp, Irp, Irp->IoStatus.Status));
7014 
7015  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
7017  }
7018 
7020  srb,
7021  IRP_MJ_SCSI,
7022  0,
7023  retryCount,
7024  &status);
7025  if (retry) {
7026  retryCount--;
7027  if (retryCount) {
7028  PCDB cdb;
7029 
7030  DebugPrint((1, "CdRomUpdateCapacityCompletion: [%lx] Retrying request %lx .. thread is %lx\n", originalIrp, Irp, Irp->Tail.Overlay.Thread));
7031  //
7032  // set up a one shot timer to get this process started over
7033  //
7034 
7035  irpStack->Parameters.Others.Argument1 = (PVOID) retryCount;
7036  irpStack->Parameters.Others.Argument2 = (PVOID) originalIrp;
7037  irpStack->Parameters.Others.Argument3 = (PVOID) 2;
7038 
7039  //
7040  // Setup the IRP to be submitted again in the timer routine.
7041  //
7042 
7043  irpStack = IoGetNextIrpStackLocation(Irp);
7045  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
7046  irpStack->Parameters.Scsi.Srb = srb;
7049  srb,
7050  TRUE,
7051  TRUE,
7052  TRUE);
7053 
7054  //
7055  // Set up the SRB for read capacity.
7056  //
7057 
7058  srb->CdbLength = 10;
7059  srb->TimeOutValue = deviceExtension->TimeOutValue;
7060  srb->SrbStatus = srb->ScsiStatus = 0;
7061  srb->NextSrb = 0;
7063  srb->PathId = deviceExtension->PathId;
7064  srb->TargetId = deviceExtension->TargetId;
7065  srb->Lun = deviceExtension->Lun;
7068  srb->DataTransferLength = sizeof(READ_CAPACITY_DATA);
7069 
7070  //
7071  // Set up the CDB
7072  //
7073 
7074  cdb = (PCDB) &srb->Cdb[0];
7075  cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
7076  cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
7077 
7078  //
7079  // Requests queued onto this list will be sent to the
7080  // lower level driver during CdRomTickHandler
7081  //
7082 
7084  &Irp->Tail.Overlay.ListEntry,
7085  &cddata->TimerIrpSpinLock);
7086 
7088  } else {
7089 
7090  //
7091  // This has been bounced for a number of times. Error the
7092  // original request.
7093  //
7094 
7096  RtlZeroMemory(deviceExtension->DiskGeometry, sizeof(DISK_GEOMETRY_EX));
7097  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 2048;
7098  deviceExtension->SectorShift = 11;
7099  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(0x7fffffff);
7100  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
7101  }
7102  } else {
7103 
7104  //
7105  // Set up reasonable defaults
7106  //
7107 
7108  RtlZeroMemory(deviceExtension->DiskGeometry, sizeof(DISK_GEOMETRY_EX));
7109  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 2048;
7110  deviceExtension->SectorShift = 11;
7111  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(0x7fffffff);
7112  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
7113  }
7114  }
7115 
7116  //
7117  // Free resources held.
7118  //
7119 
7121  ExFreePool(srb->DataBuffer);
7122  ExFreePool(srb);
7123  if (Irp->MdlAddress) {
7124  IoFreeMdl(Irp->MdlAddress);
7125  }
7126  IoFreeIrp(Irp);
7127  if (originalIrp->Tail.Overlay.Thread) {
7128 
7129  DebugPrint((2, "CdRomUpdateCapacityCompletion: [%lx] completing original IRP\n", originalIrp));
7130  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
7131 
7132  } else {
7133  DebugPrint((1, "CdRomUpdateCapacityCompletion: [%lx] original irp has "
7134  "no thread\n",
7135  originalIrp
7136  ));
7137  }
7138 
7139  //
7140  // It's now safe to either start the next request or let the waiting ioctl
7141  // request continue along it's merry way
7142  //
7143 
7145 
7147 }
UCHAR Byte0
Definition: tools.h:16
struct _FOUR_BYTE * PFOUR_BYTE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG SrbFlags
Definition: srb.h:252
UCHAR Cdb[16]
Definition: srb.h:271
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
ULONG DataTransferLength
Definition: srb.h:253
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
IO_COMPLETION_ROUTINE CdRomUpdateGeometryCompletion
Definition: cdrom.c:6896
UCHAR CdbLength
Definition: srb.h:250
ULONG LogicalBlockAddress
Definition: cdrw_hw.h:1471
VOID ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
IO_STATUS_BLOCK IoStatus
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:257
struct _CDB::_CDB10 CDB10
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define WHICH_BIT(Data, Bit)
Definition: tools.h:80
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IRP_MJ_SCSI
UCHAR Byte3
Definition: tools.h:19
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
UCHAR ScsiStatus
Definition: srb.h:244
unsigned char BOOLEAN
struct _CDROM_DATA * PCDROM_DATA
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
void * PVOID
Definition: retypes.h:9
UCHAR TargetId
Definition: srb.h:246
int64_t LONGLONG
Definition: typedefs.h:68
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UCHAR Function
Definition: srb.h:242
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
USHORT Length
Definition: srb.h:241
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _READ_CAPACITY_DATA READ_CAPACITY_DATA
LIST_ENTRY TimerIrpList
Definition: cdrom.c:164
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
UCHAR Byte1
Definition: tools.h:17
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
KSPIN_LOCK TimerIrpSpinLock
Definition: cdrom.c:165
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
PVOID SenseInfoBuffer
Definition: srb.h:256
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:262
#define ULONG_PTR
Definition: config.h:101
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
UCHAR Byte2
Definition: tools.h:18
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
CardRegion * from
Definition: spigame.cpp:19
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

◆ CdRomXACompletion()

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

Definition at line 4529 of file cdrom.c.

4560 {
4564  NTSTATUS status;
4565  BOOLEAN retry;
4566 
4567  //
4568  // Check SRB status for success of completing request.
4569  //
4570 
4571  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
4572 
4573  DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
4574 
4575  //
4576  // Release the queue if it is frozen.
4577  //
4578 
4579  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
4581  }
4582 
4584  DeviceObject,
4585  srb,
4586  irpStack->MajorFunction,
4587  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
4588  MAXIMUM_RETRIES - ((ULONG_PTR)irpNextStack->Parameters.Others.Argument1),
4589  &status);
4590 
4591  //
4592  // If the status is verified required and the this request
4593  // should bypass verify required then retry the request.
4594  //
4595 
4596  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
4598 
4600  retry = TRUE;
4601  }
4602 
4603  if (retry && (irpNextStack->Parameters.Others.Argument1 = (PVOID)((ULONG_PTR)irpNextStack->Parameters.Others.Argument1-1))) {
4604 
4605  if (((ULONG_PTR)irpNextStack->Parameters.Others.Argument1)) {
4606 
4607  //
4608  // Retry request.
4609  //
4610 
4611  DebugPrint((1, "CdRomXACompletion: Retry request %lx - Calling StartIo\n", Irp));
4612 
4613 
4615  ExFreePool(srb->DataBuffer);
4616  ExFreePool(srb);
4617 
4618  //
4619  // Call StartIo directly since IoStartNextPacket hasn't been called,
4620  // the serialisation is still intact.
4621  //
4622 
4625 
4626  }
4627 
4628  //
4629  // Exhausted retries. Fall through and complete the request with the appropriate status.
4630  //
4631  }
4632  } else {
4633 
4634  //
4635  // Set status for successful request.
4636  //
4637 
4639 
4640  } // end if (SRB_STATUS(srb->SrbStatus) ...
4641 
4642  //
4643  // Return SRB to nonpaged pool.
4644  //
4645 
4646  ExFreePool(srb);
4647 
4648  //
4649  // Set status in completing IRP.
4650  //
4651 
4652  Irp->IoStatus.Status = status;
4653 
4654  //
4655  // Set the hard error if necessary.
4656  //
4657 
4659 
4660  //
4661  // Store DeviceObject for filesystem, and clear
4662  // in IoStatus.Information field.
4663  //
4664 
4666  Irp->IoStatus.Information = 0;
4667  }
4668 
4669  //
4670  // If pending has be returned for this irp then mark the current stack as
4671  // pending.
4672  //
4673 
4674  if (Irp->PendingReturned) {
4676  }
4677 
4678  //IoCompleteRequest(Irp, IO_DISK_INCREMENT);
4679