ReactOS  0.4.15-dev-1397-g19779b3
cdrom.c File Reference
#include "ntddk.h"
#include "ntstrsafe.h"
#include "ntddstor.h"
#include "ntddtape.h"
#include "wdfcore.h"
#include "devpkey.h"
#include "cdrom.h"
#include "ioctl.h"
#include "mmc.h"
#include "scratch.h"
Include dependency graph for cdrom.c:

Go to the source code of this file.

Macros

#define DEBUG_MAIN_SOURCE   1
 

Functions

BOOLEAN BootEnvironmentIsWinPE (VOID)
 
NTSTATUS NTAPI DriverEntry (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
 
VOID NTAPI DriverEvtCleanup (_In_ WDFOBJECT Driver)
 
NTSTATUS NTAPI DriverEvtDeviceAdd (_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit)
 
VOID NTAPI DeviceEvtCleanup (_In_ WDFOBJECT Device)
 
VOID NTAPI DeviceEvtSelfManagedIoCleanup (_In_ WDFDEVICE Device)
 
NTSTATUS NTAPI DeviceEvtD0Entry (_In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE PreviousState)
 
NTSTATUS NTAPI DeviceEvtD0Exit (_In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE TargetState)
 
VOID NTAPI DeviceEvtSurpriseRemoval (_In_ WDFDEVICE Device)
 
VOID NTAPI CreateQueueEvtIoDefault (_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request)
 
VOID NTAPI DeviceEvtFileClose (_In_ WDFFILEOBJECT FileObject)
 
 _IRQL_requires_max_ (PASSIVE_LEVEL)
 
 _IRQL_requires_max_ (APC_LEVEL)
 
VOID NormalizeIoctl (_Inout_ PWDF_REQUEST_PARAMETERS requestParameters)
 
VOID NTAPI DeviceEvtIoInCallerContext (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
 
BOOLEAN RequestDispatchProcessDirectly (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
 
BOOLEAN RequestDispatchToSequentialQueue (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
 
BOOLEAN RequestDispatchSyncWithSequentialQueue (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
 
BOOLEAN RequestDispatchSpecialIoctls (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
 
BOOLEAN RequestDispatchUnknownRequests (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
 
VOID RequestProcessInternalDeviceControl (_In_ WDFREQUEST Request, _In_ PCDROM_DEVICE_EXTENSION DeviceExtension)
 
VOID NTAPI SequentialQueueEvtIoReadWrite (_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t Length)
 
VOID NTAPI ReadWriteWorkItemRoutine (_In_ WDFWORKITEM WorkItem)
 
VOID NTAPI SequentialQueueEvtIoDeviceControl (_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode)
 
VOID NTAPI IoctlWorkItemRoutine (_In_ WDFWORKITEM WorkItem)
 
VOID NTAPI SequentialQueueEvtCanceledOnQueue (_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request)
 
NTSTATUS RequestSynchronizeProcessWithSerialQueue (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
 
NTSTATUS RequestIsIoctlBlockedByExclusiveAccess (_In_ WDFREQUEST Request, _Out_ PBOOLEAN IsBlocked)
 
BOOLEAN DeviceIsMmcUpdateRequired (_In_ WDFDEVICE Device)
 
VOID NTAPI RequestEvtCleanup (_In_ WDFOBJECT Request)
 

Macro Definition Documentation

◆ DEBUG_MAIN_SOURCE

#define DEBUG_MAIN_SOURCE   1

Definition at line 26 of file cdrom.c.

Function Documentation

◆ _IRQL_requires_max_() [1/2]

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Definition at line 1389 of file cdrom.c.

1412 {
1414 
1415  PAGED_CODE();
1416 
1417  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
1418  "CleanupProtectedLocks called for WDFDEVICE %p, WDFFILEOBJECT %p, locked %d times.\n",
1419  DeviceExtension->Device, FileObjectContext->FileObject, FileObjectContext->LockCount));
1420 
1421  // Synchronize with ejection and ejection control requests.
1422  WdfWaitLockAcquire(DeviceExtension->EjectSynchronizationLock, NULL);
1423 
1424  // For each secure lock on this handle decrement the secured lock count
1425  // for the FDO. Keep track of the new value.
1426  if (FileObjectContext->LockCount != 0)
1427  {
1428  DeviceExtension->ProtectedLockCount -= FileObjectContext->LockCount;
1430 
1431  // If the new lock count has been dropped to zero then issue a lock
1432  // command to the device.
1433  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
1434  "FDO secured lock count = %d "
1435  "lock count = %d\n",
1436  DeviceExtension->ProtectedLockCount,
1437  DeviceExtension->LockCount));
1438 
1439  if ((DeviceExtension->ProtectedLockCount == 0) && (DeviceExtension->LockCount == 0))
1440  {
1441  SCSI_REQUEST_BLOCK srb = {0};
1442  PCDB cdb = (PCDB) &(srb.Cdb);
1443 
1444  srb.CdbLength = 6;
1445 
1446  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
1447 
1448  // TRUE - prevent media removal.
1449  // FALSE - allow media removal.
1450  cdb->MEDIA_REMOVAL.Prevent = FALSE;
1451 
1452  // Set timeout value.
1453  srb.TimeOutValue = DeviceExtension->TimeOutValue;
1454  status = DeviceSendSrbSynchronously(DeviceExtension->Device,
1455  &srb,
1456  NULL,
1457  0,
1458  FALSE,
1459  NULL);
1460 
1461  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
1462  "Allow media removal (unlock) request to drive returned %!STATUS!\n",
1463  status));
1464  }
1465  }
1466 
1467  WdfWaitLockRelease(DeviceExtension->EjectSynchronizationLock);
1468 
1469  return status;
1470 }
UCHAR Cdb[16]
Definition: srb.h:271
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
ULONG TimeOutValue
Definition: srb.h:254
#define FALSE
Definition: types.h:117
_In_ PFILE_OBJECT_CONTEXT FileObjectContext
Definition: cdrom.h:1212
union _CDB * PCDB
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
WDFFILEOBJECT FileObject
Definition: cdromp.h:364
static SERVICE_STATUS status
Definition: service.c:31
_Must_inspect_result_ FORCEINLINE NTSTATUS WdfWaitLockAcquire(_In_ _Requires_lock_not_held_(_Curr_) WDFWAITLOCK Lock, _In_opt_ PLONGLONG Timeout)
Definition: wdfsync.h:173
#define PAGED_CODE()
Definition: ps.c:97

◆ _IRQL_requires_max_() [2/2]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 1473 of file cdrom.c.

1496 {
1497  PAGED_CODE();
1498 
1499  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_INIT,
1500  "CleanupDisableMcn called for WDFDEVICE %p, WDFFILEOBJECT %p, locked %d times.\n",
1501  DeviceExtension->Device, FileObjectContext->FileObject, FileObjectContext->McnDisableCount));
1502 
1503  // For each secure lock on this handle decrement the secured lock count
1504  // for the FDO. Keep track of the new value.
1505  while (FileObjectContext->McnDisableCount != 0)
1506  {
1507  DeviceEnableMediaChangeDetection(DeviceExtension, FileObjectContext, TRUE);
1508  }
1509 
1510  return STATUS_SUCCESS;
1511 }
#define TRUE
Definition: types.h:120
ULONG McnDisableCount
Definition: cdromp.h:367
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
_In_ PFILE_OBJECT_CONTEXT FileObjectContext
Definition: cdrom.h:1212
#define STATUS_SUCCESS
Definition: shellext.h:65
WDFFILEOBJECT FileObject
Definition: cdromp.h:364
#define PAGED_CODE()

◆ BootEnvironmentIsWinPE()

BOOLEAN BootEnvironmentIsWinPE ( VOID  )

Definition at line 158 of file cdrom.c.

176 {
178  WDFKEY registryKey = NULL;
179 
181 
182  PAGED_CODE();
183 
184  status = WdfRegistryOpenKey(NULL,
185  &registryKeyName,
186  KEY_READ,
188  &registryKey);
189 
190  if (!NT_SUCCESS(status))
191  {
192  return FALSE;
193  }
194 
195  WdfRegistryClose(registryKey);
196  return TRUE;
197 } // end BootEnvironmentIsWinPE()
#define WINPE_REG_KEY_NAME
Definition: cdromp.h:127
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
#define NULL
Definition: types.h:112
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEntry().

◆ CreateQueueEvtIoDefault()

VOID NTAPI CreateQueueEvtIoDefault ( _In_ WDFQUEUE  Queue,
_In_ WDFREQUEST  Request 
)

Definition at line 1266 of file cdrom.c.

1288 {
1289  WDFFILEOBJECT fileObject = WdfRequestGetFileObject(Request);
1290  WDFDEVICE device = WdfIoQueueGetDevice(Queue);
1292  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(device);
1293  PFILE_OBJECT_CONTEXT fileObjectContext = NULL;
1294 
1295  PAGED_CODE();
1296 
1297  if (fileObject == NULL) {
1298 
1299  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_QUEUE,
1300  "Error: received a file create request with file object set to NULL\n"));
1301 
1302  RequestCompletion(deviceExtension, Request, STATUS_INTERNAL_ERROR, 0);
1303  return;
1304  }
1305 
1306  fileObjectContext = FileObjectGetContext(fileObject);
1307 
1308  // Initialize this WDFFILEOBJECT's context
1309  fileObjectContext->DeviceObject = device;
1310  fileObjectContext->FileObject = fileObject;
1311  fileObjectContext->LockCount = 0;
1312  fileObjectContext->McnDisableCount = 0;
1313  fileObjectContext->EnforceStreamingRead = FALSE;
1314  fileObjectContext->EnforceStreamingWrite = FALSE;
1315 
1316  // send down the create synchronously
1317  status = DeviceSendRequestSynchronously(device, Request, FALSE);
1318 
1319  // Need to complete the request in this routine.
1320  RequestCompletion(deviceExtension, Request, status, WdfRequestGetInformation(Request));
1321 
1322  return;
1323 }
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
LONG NTSTATUS
Definition: precomp.h:26
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
ULONG McnDisableCount
Definition: cdromp.h:367
FxDevice * device
BOOLEAN EnforceStreamingRead
Definition: cdromp.h:368
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define FALSE
Definition: types.h:117
Definition: devices.h:37
WDFDEVICE DeviceObject
Definition: cdromp.h:365
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define NULL
Definition: types.h:112
BOOLEAN EnforceStreamingWrite
Definition: cdromp.h:369
#define STATUS_SUCCESS
Definition: shellext.h:65
WDFFILEOBJECT FileObject
Definition: cdromp.h:364
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEvtDeviceAdd().

◆ DeviceEvtCleanup()

VOID NTAPI DeviceEvtCleanup ( _In_ WDFOBJECT  Device)

Definition at line 856 of file cdrom.c.

873 {
874  WDFDEVICE device = (WDFDEVICE)Device;
875  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
876 
877  PAGED_CODE ();
878 
879  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
880  "WDFDEVICE %p cleanup: The device is about to be destroyed.\n",
881  device));
882 
883  deviceExtension = DeviceGetExtension(device);
884 
885  FREE_POOL(deviceExtension->DeviceName.Buffer);
886  RtlInitUnicodeString(&deviceExtension->DeviceName, NULL);
887 
888  if (deviceExtension->DeviceAdditionalData.WellKnownName.Buffer != NULL)
889  {
891  }
892 
895 
896  return;
897 }
UNICODE_STRING WellKnownName
Definition: cdrom.h:357
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
Definition: devices.h:37
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define NULL
Definition: types.h:112
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define PAGED_CODE()
UNICODE_STRING DeviceName
Definition: cdrom.h:502

Referenced by DriverEvtDeviceAdd().

◆ DeviceEvtD0Entry()

NTSTATUS NTAPI DeviceEvtD0Entry ( _In_ WDFDEVICE  Device,
_In_ WDF_POWER_DEVICE_STATE  PreviousState 
)

Definition at line 993 of file cdrom.c.

1014 {
1015  PCDROM_DEVICE_EXTENSION deviceExtension;
1017  PZERO_POWER_ODD_INFO zpoddInfo = NULL;
1018  STORAGE_IDLE_POWERUP_REASON powerupReason = {0};
1019 
1021  deviceExtension = DeviceGetExtension(Device);
1022 
1023  // Make certain not to do anything before properly initialized
1024  if (deviceExtension->IsInitialized)
1025  {
1026  zpoddInfo = deviceExtension->ZeroPowerODDInfo;
1027 
1028  if (zpoddInfo != NULL)
1029  {
1030  if (zpoddInfo->InZeroPowerState != FALSE)
1031  {
1032  // We just woke up from Zero Power state
1033  zpoddInfo->InZeroPowerState = FALSE;
1034  zpoddInfo->RetryFirstCommand = TRUE;
1036 
1037  status = DeviceZPODDGetPowerupReason(deviceExtension, &powerupReason);
1038 
1039  if (NT_SUCCESS(status) &&
1040  (powerupReason.PowerupReason == StoragePowerupDeviceAttention))
1041  {
1042  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_POWER,
1043  "DeviceEvtD0Entry: Device has left zero power state due to eject button pressed\n"
1044  ));
1045 
1046  // This wake-up is caused by user pressing the eject button.
1047  // In case of drawer type, we need to soft eject the tray to emulate the effect.
1048  // Note that the first command to the device after power resumed will
1049  // be terminated with CHECK CONDITION status with sense code 6/29/00,
1050  // but we already have a retry logic to handle this.
1051  if ((zpoddInfo->LoadingMechanism == LOADING_MECHANISM_TRAY) && (zpoddInfo->Load == 0)) // Drawer
1052  {
1053  DeviceSendIoctlAsynchronously(deviceExtension, IOCTL_STORAGE_EJECT_MEDIA, deviceExtension->DeviceObject);
1054  }
1055  }
1056  else
1057  {
1058  // This wake-up is caused by non-cached CDB received or a 3rd-party driver
1059  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_POWER,
1060  "DeviceEvtD0Entry: Device has left zero power state due to IO received\n"
1061  ));
1062 
1063  }
1064  }
1065  }
1066 
1067  DeviceEnableMainTimer(deviceExtension);
1068  }
1069 
1070  return STATUS_SUCCESS;
1071 }
BOOLEAN RetryFirstCommand
Definition: cdromp.h:273
NTSTATUS DeviceZPODDGetPowerupReason(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _Out_ PSTORAGE_IDLE_POWERUP_REASON PowerupReason)
Definition: zpodd.c:608
BOOLEAN IsInitialized
Definition: cdrom.h:464
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
#define BECOMING_READY_RETRY_COUNT
Definition: cdromp.h:261
BOOLEAN InZeroPowerState
Definition: cdromp.h:272
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
STORAGE_POWERUP_REASON_TYPE PowerupReason
Definition: ntddstor.h:1102
#define LOADING_MECHANISM_TRAY
Definition: scsi.h:972
#define FALSE
Definition: types.h:117
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PZERO_POWER_ODD_INFO ZeroPowerODDInfo
Definition: cdrom.h:566
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define NULL
Definition: types.h:112
ULONG BecomingReadyRetryCount
Definition: cdromp.h:277
UCHAR LoadingMechanism
Definition: cdromp.h:266
PDEVICE_OBJECT DeviceObject
Definition: cdrom.h:493
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID DeviceSendIoctlAsynchronously(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT TargetDeviceObject)
Definition: common.c:1030
_In_ WDF_POWER_DEVICE_STATE PreviousState
Definition: wdfdevice.h:829
Definition: ps.c:97

Referenced by DriverEvtDeviceAdd().

◆ DeviceEvtD0Exit()

NTSTATUS NTAPI DeviceEvtD0Exit ( _In_ WDFDEVICE  Device,
_In_ WDF_POWER_DEVICE_STATE  TargetState 
)

Definition at line 1075 of file cdrom.c.

1097 {
1099  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
1100  PZERO_POWER_ODD_INFO zpoddInfo = NULL;
1101 
1102  PAGED_CODE ();
1103 
1104  deviceExtension = DeviceGetExtension(Device);
1105  zpoddInfo = deviceExtension->ZeroPowerODDInfo;
1106 
1107  // we only process the situation that the device is going into D3.
1108  if ((TargetState != WdfPowerDeviceD3) &&
1110  {
1111  return STATUS_SUCCESS;
1112  }
1113 
1114  // Stop the main timer
1115  DeviceDisableMainTimer(deviceExtension);
1116 
1117  // note: do not stop CreateQueue as the create request can be handled by port driver even the device is in D3 status.
1118 
1119  // If initialization was not finished or the device was removed, we cannot interact
1120  // with it device, so we have to exit
1121  if ((!deviceExtension->IsInitialized) || deviceExtension->SurpriseRemoved)
1122  {
1123  return STATUS_SUCCESS;
1124  }
1125 
1126 
1127 #ifdef DBG
1128  #if (WINVER >= 0x0601)
1129  // this API is introduced in Windows7
1130  {
1131  ULONG secondsRemaining = 0;
1132  BOOLEAN watchdogTimeSupported = FALSE;
1133 
1134  watchdogTimeSupported = PoQueryWatchdogTime(deviceExtension->LowerPdo, &secondsRemaining);
1135  UNREFERENCED_PARAMETER(watchdogTimeSupported);
1136  }
1137  #endif
1138 #endif
1139 
1140  deviceExtension->PowerDownInProgress = TRUE;
1141 
1142  status = PowerContextBeginUse(deviceExtension);
1143 
1144  deviceExtension->PowerContext.Options.PowerDown = TRUE;
1145 
1146  // Step 1. LOCK QUEUE
1147  if (NT_SUCCESS(status) &&
1149  {
1150  status = DeviceSendPowerDownProcessRequest(deviceExtension, NULL, NULL);
1151 
1152  if (NT_SUCCESS(status))
1153  {
1154  deviceExtension->PowerContext.Options.LockQueue = TRUE;
1155  }
1156 
1157  // Ignore failure.
1159  }
1160 
1161  deviceExtension->PowerContext.PowerChangeState.PowerDown++;
1162 
1163  // Step 2. QUIESCE QUEUE
1164  if (NT_SUCCESS(status) &&
1166  {
1167  status = DeviceSendPowerDownProcessRequest(deviceExtension, NULL, NULL);
1169  // We don't care about the status.
1171  }
1172 
1173  deviceExtension->PowerContext.PowerChangeState.PowerDown++;
1174 
1175  // Step 3. SYNC CACHE command should be sent to drive if the media is currently writable.
1176  if (NT_SUCCESS(status) &&
1177  deviceExtension->DeviceAdditionalData.Mmc.WriteAllowed)
1178  {
1179  status = DeviceSendPowerDownProcessRequest(deviceExtension, NULL, NULL);
1182  }
1183 
1184  deviceExtension->PowerContext.PowerChangeState.PowerDown++;
1185 
1186  // Step 4. STOP UNIT
1187  if (NT_SUCCESS(status) &&
1189  {
1190  status = DeviceSendPowerDownProcessRequest(deviceExtension, NULL, NULL);
1193  }
1194 
1196  {
1197  // We're done with the power context.
1198  PowerContextEndUse(deviceExtension);
1199  }
1200 
1201  // Bumping the media change count will force the file system to verify the volume when we resume
1202  SET_FLAG(deviceExtension->DeviceObject->Flags, DO_VERIFY_VOLUME);
1203  InterlockedIncrement((PLONG)&deviceExtension->MediaChangeCount);
1204 
1205  // If this power down is caused by Zero Power ODD, we should mark the device as in ZPODD mode.
1206  if (zpoddInfo != NULL)
1207  {
1208  zpoddInfo->InZeroPowerState = TRUE;
1209 
1210  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_POWER,
1211  "Device has entered zero power state\n"
1212  ));
1213  }
1214 
1215  deviceExtension->PowerDownInProgress = FALSE;
1216 
1217  return STATUS_SUCCESS;
1218 }
BOOLEAN IsInitialized
Definition: cdrom.h:464
BOOLEAN WriteAllowed
Definition: cdrom.h:250
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define CDROM_SPECIAL_DISABLE_SPIN_DOWN
Definition: cdrom.h:149
BOOLEAN InZeroPowerState
Definition: cdromp.h:272
PDEVICE_OBJECT LowerPdo
Definition: cdrom.h:496
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
BOOLEAN SurpriseRemoved
Definition: cdrom.h:470
ULONG ScanForSpecialFlags
Definition: cdrom.h:512
union _CDROM_POWER_CONTEXT::@1027 PowerChangeState
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PZERO_POWER_ODD_INFO ZeroPowerODDInfo
Definition: cdrom.h:566
BOOLEAN PowerDownInProgress
Definition: cdrom.h:587
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDF_POWER_DEVICE_STATE TargetState
Definition: wdfdevice.h:859
#define InterlockedIncrement
Definition: armddk.h:53
CDROM_POWER_DOWN_STATE PowerDown
Definition: cdrom.h:438
#define NULL
Definition: types.h:112
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:341
CDROM_POWER_OPTIONS Options
Definition: cdrom.h:442
unsigned int ULONG
Definition: retypes.h:1
PDEVICE_OBJECT DeviceObject
Definition: cdrom.h:493
#define STATUS_SUCCESS
Definition: shellext.h:65
signed int * PLONG
Definition: retypes.h:5
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
CDROM_POWER_CONTEXT PowerContext
Definition: cdrom.h:586
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEvtDeviceAdd().

◆ DeviceEvtFileClose()

VOID NTAPI DeviceEvtFileClose ( _In_ WDFFILEOBJECT  FileObject)

Definition at line 1327 of file cdrom.c.

1346 {
1348 
1349  PAGED_CODE();
1350 
1351  if (FileObject != NULL)
1352  {
1353  WDFDEVICE device = WdfFileObjectGetDevice(FileObject);
1354  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(device);
1355  PCDROM_DATA cdData = &(deviceExtension->DeviceAdditionalData);
1356  PFILE_OBJECT_CONTEXT fileObjectContext = FileObjectGetContext(FileObject);
1357 
1358  // cleanup locked media tray
1359  status = DeviceCleanupProtectedLocks(deviceExtension, fileObjectContext);
1360  if (!NT_SUCCESS(status))
1361  {
1362  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
1363  "Failed to cleanup protected locks for WDFDEVICE %p, %!STATUS!\n", device, status));
1364  }
1365 
1366  // cleanup disabled MCN
1367  status = DeviceCleanupDisableMcn(deviceExtension, fileObjectContext);
1368  if (!NT_SUCCESS(status))
1369  {
1370  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
1371  "Failed to disable MCN for WDFDEVICE %p, %!STATUS!\n", device, status));
1372  }
1373 
1374  // cleanup exclusive access
1375  if (EXCLUSIVE_MODE(cdData) && EXCLUSIVE_OWNER(cdData, FileObject))
1376  {
1377  status = DeviceUnlockExclusive(deviceExtension, FileObject, FALSE);
1378  if (!NT_SUCCESS(status))
1379  {
1380  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
1381  "Failed to release exclusive lock for WDFDEVICE %p, %!STATUS!\n", device, status));
1382  }
1383  }
1384  }
1385 
1386  return;
1387 }
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
LONG NTSTATUS
Definition: precomp.h:26
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define FALSE
Definition: types.h:117
Definition: devices.h:37
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCLUSIVE_MODE(_CdData)
Definition: cdrom.h:788
#define EXCLUSIVE_OWNER(_CdData, _FileObject)
Definition: cdrom.h:789
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEvtDeviceAdd().

◆ DeviceEvtIoInCallerContext()

VOID NTAPI DeviceEvtIoInCallerContext ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request 
)

Definition at line 1554 of file cdrom.c.

1575 {
1577  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
1578  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
1579  WDF_REQUEST_PARAMETERS requestParameters;
1580 
1581  requestContext->DeviceExtension = deviceExtension;
1582 
1583  // set the received time
1585 
1586  // get the request parameters
1587  WDF_REQUEST_PARAMETERS_INIT(&requestParameters);
1588  WdfRequestGetParameters(Request, &requestParameters);
1589 
1590  if (requestParameters.Type == WdfRequestTypeDeviceControl)
1591  {
1593  PCDROM_DATA cdData = &(deviceExtension->DeviceAdditionalData);
1595 
1596  if (requestParameters.Parameters.DeviceIoControl.IoControlCode != IOCTL_MCN_SYNC_FAKE_IOCTL)
1597  {
1598  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
1599  "Receiving IOCTL: %lx\n",
1600  requestParameters.Parameters.DeviceIoControl.IoControlCode));
1601  }
1602  else
1603  {
1604  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_IOCTL,
1605  "Receiving IOCTL: %lx\n",
1606  requestParameters.Parameters.DeviceIoControl.IoControlCode));
1607  }
1608 
1609  // If the device is in exclusive mode, check whether the request is from
1610  // the handle that locked the device.
1611  if (EXCLUSIVE_MODE(cdData) && !EXCLUSIVE_OWNER(cdData, WdfRequestGetFileObject(Request)))
1612  {
1613  BOOLEAN isBlocked = FALSE;
1614 
1616  UNREFERENCED_PARAMETER(status); //defensive coding, avoid PREFAST warning.
1617 
1618  if (isBlocked)
1619  {
1620  if ((requestParameters.Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_EVENT_NOTIFICATION) &&
1621  (info != NULL) && (info->AsynchronousNotificationSupported != FALSE))
1622  {
1623  // If AN is supported and we receive a signal but we can't send down GESN
1624  // due to exclusive lock, we should save it and fire a GESN when it's unlocked.
1625  // We just need true/false here and don't need count because we will keep sending
1626  // GESN until we deplete all events.
1627  info->ANSignalPendingDueToExclusiveLock = TRUE;
1628  }
1629 
1630  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
1631  "Access Denied! Device in exclusive mode.Failing Ioctl %lx\n",
1632  requestParameters.Parameters.DeviceIoControl.IoControlCode));
1633  RequestCompletion(deviceExtension, Request, STATUS_ACCESS_DENIED, 0);
1634 
1635  return;
1636  }
1637  }
1638 
1639  NormalizeIoctl(&requestParameters);
1640 
1641  // 1. All requests that don't need to access device can be processed immediately
1642  if (!processed)
1643  {
1644  processed = RequestDispatchProcessDirectly(Device, Request, requestParameters);
1645  }
1646 
1647  // 2. Requests that should be put in sequential queue.
1648  if (!processed)
1649  {
1651  }
1652 
1653  // 3. Requests that need to be processed sequentially and in caller's context.
1654  if (!processed)
1655  {
1657  }
1658 
1659  // 4. Special requests that needs different process in different cases.
1660  if (!processed)
1661  {
1662  processed = RequestDispatchSpecialIoctls(Device, Request, requestParameters);
1663  }
1664 
1665  // 5. This is default behavior for unknown IOCTLs. To pass it to lower level.
1666  if (!processed)
1667  {
1668  processed = RequestDispatchUnknownRequests(Device, Request, requestParameters);
1669  }
1670 
1671  // All requests should be processed already.
1673  UNREFERENCED_PARAMETER(processed); //defensive coding, avoid PREFAST warning.
1674  }
1675  else if (requestParameters.Type == WdfRequestTypeDeviceControlInternal)
1676  {
1677  RequestProcessInternalDeviceControl(Request, deviceExtension);
1678  }
1679  else
1680  {
1681  // Requests other than IOCTLs will be forwarded to default queue.
1682  status = WdfDeviceEnqueueRequest(Device, Request);
1683  if (!NT_SUCCESS(status))
1684  {
1685  RequestCompletion(deviceExtension, Request, status, WdfRequestGetInformation(Request));
1686  }
1687  }
1688 
1689  return;
1690 }
VOID RequestProcessInternalDeviceControl(_In_ WDFREQUEST Request, _In_ PCDROM_DEVICE_EXTENSION DeviceExtension)
Definition: cdrom.c:3154
BOOLEAN RequestDispatchSpecialIoctls(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:2849
VOID RequestSetReceivedTime(_In_ WDFREQUEST Request)
Definition: common.c:64
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
NTSTATUS RequestIsIoctlBlockedByExclusiveAccess(_In_ WDFREQUEST Request, _Out_ PBOOLEAN IsBlocked)
Definition: cdrom.c:4058
LONG NTSTATUS
Definition: precomp.h:26
WDF_REQUEST_TYPE Type
Definition: wdfrequest.h:142
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
BOOLEAN RequestDispatchToSequentialQueue(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:1855
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
BOOLEAN RequestDispatchSyncWithSequentialQueue(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:2717
BOOLEAN RequestDispatchProcessDirectly(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:1694
unsigned char BOOLEAN
BOOLEAN RequestDispatchUnknownRequests(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:3093
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCLUSIVE_MODE(_CdData)
Definition: cdrom.h:788
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define EXCLUSIVE_OWNER(_CdData, _FileObject)
Definition: cdrom.h:789
PCDROM_DEVICE_EXTENSION DeviceExtension
Definition: cdrom.h:631
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define IOCTL_STORAGE_EVENT_NOTIFICATION
Definition: ntddstor.h:226
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define NULL
Definition: types.h:112
#define IOCTL_MCN_SYNC_FAKE_IOCTL
Definition: cdrom.h:181
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211
VOID NormalizeIoctl(_Inout_ PWDF_REQUEST_PARAMETERS requestParameters)
Definition: cdrom.c:1514
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
static int processed(const type_t *type)
Definition: typegen.c:2236
PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo
Definition: cdrom.h:563
#define STATUS_SUCCESS
Definition: shellext.h:65
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by DriverEvtDeviceAdd().

◆ DeviceEvtSelfManagedIoCleanup()

VOID NTAPI DeviceEvtSelfManagedIoCleanup ( _In_ WDFDEVICE  Device)

Definition at line 902 of file cdrom.c.

921 {
923  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
924 
925  PAGED_CODE ();
926 
927  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP,
928  "DeviceEvtSelfManagedIoCleanup: WDFDEVICE %p is being stopped.\n",
929  Device));
930 
931  // extract the device and driver extensions
932  deviceExtension = DeviceGetExtension(Device);
933 
934  // Purge unprocessed requests, stop the IO queues.
935  // Incoming request will be completed with STATUS_INVALID_DEVICE_STATE status.
936  WdfIoQueuePurge(deviceExtension->SerialIOQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);
937  WdfIoQueuePurge(deviceExtension->CreateQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);
938 
939  // Close the IoTarget so that we are sure there are no outstanding I/Os in the stack.
940  if (deviceExtension->IoTarget)
941  {
942  WdfIoTargetClose(deviceExtension->IoTarget);
943  }
944 
945  // Release the device
946  if (!deviceExtension->SurpriseRemoved)
947  {
948  status = DeviceClaimRelease(deviceExtension, TRUE); //status is mainly for debugging. we don't really care.
949  UNREFERENCED_PARAMETER(status); //defensive coding, avoid PREFAST warning.
950  }
951 
952  // Be sure to flush the DPCs as the READ/WRITE timer routine may still be running
953  // during device removal. This call may take a while to complete.
955 
956  // Release all the memory that we have allocated.
957 
958  DeviceDeallocateMmcResources(Device);
959  ScratchBuffer_Deallocate(deviceExtension);
960  RtlZeroMemory(&(deviceExtension->DeviceAdditionalData.Mmc), sizeof(CDROM_MMC_EXTENSION));
961 
962  FREE_POOL(deviceExtension->DeviceDescriptor);
963  FREE_POOL(deviceExtension->AdapterDescriptor);
964  FREE_POOL(deviceExtension->PowerDescriptor);
965  FREE_POOL(deviceExtension->SenseData);
966 
967  if (deviceExtension->DeviceAdditionalData.CachedInquiryData != NULL)
968  {
969  FREE_POOL(deviceExtension->DeviceAdditionalData.CachedInquiryData);
971  }
972 
973  FREE_POOL(deviceExtension->PrivateFdoData);
974 
975  DeviceReleaseMcnResources(deviceExtension);
976 
977  DeviceReleaseZPODDResources(deviceExtension);
978 
979  // Keep the system-wide CDROM count accurate, as programs use this info to
980  // know when they have found all the cdroms in a system.
982 
983  deviceExtension->PartitionLength.QuadPart = 0;
984 
985  // All WDF objects related to Device will be automatically released
986  // when the root object is deleted. No need to release them manually.
987 
988  return;
989 }
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
PCDROM_PRIVATE_FDO_DATA PrivateFdoData
Definition: cdrom.h:605
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
WDFIOTARGET IoTarget
Definition: cdrom.h:476
LONG NTSTATUS
Definition: precomp.h:26
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
BOOLEAN SurpriseRemoved
Definition: cdrom.h:470
WDFQUEUE CreateQueue
Definition: cdrom.h:483
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define WDF_NO_CONTEXT
Definition: wdftypes.h:108
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: cdrom.h:539
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: cdrom.h:542
ULONG CachedInquiryDataByteCount
Definition: cdrom.h:392
PDEVICE_POWER_DESCRIPTOR PowerDescriptor
Definition: cdrom.h:545
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
LARGE_INTEGER PartitionLength
Definition: cdrom.h:530
WDFQUEUE SerialIOQueue
Definition: cdrom.h:479
PSENSE_DATA SenseData
Definition: cdrom.h:548
#define WDF_NO_EVENT_CALLBACK
Definition: wdftypes.h:106
#define NULL
Definition: types.h:112
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:341
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static SERVICE_STATUS status
Definition: service.c:31
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:918
LONGLONG QuadPart
Definition: typedefs.h:114
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEvtDeviceAdd().

◆ DeviceEvtSurpriseRemoval()

VOID NTAPI DeviceEvtSurpriseRemoval ( _In_ WDFDEVICE  Device)

Definition at line 1223 of file cdrom.c.

1242 {
1243  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
1244 
1245  PAGED_CODE();
1246 
1247  deviceExtension = DeviceGetExtension(Device);
1248 
1249  deviceExtension->SurpriseRemoved = TRUE;
1250 
1251  // Stop the main timer
1252  DeviceDisableMainTimer(deviceExtension);
1253 
1254  // legacy behavior to set partition length to be 0.
1255  deviceExtension->PartitionLength.QuadPart = 0;
1256 
1257  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
1258  "Surprisely remove a WDFDEVICE %p\n", Device));
1259 
1260  return;
1261 }
#define TRUE
Definition: types.h:120
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
BOOLEAN SurpriseRemoved
Definition: cdrom.h:470
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
LARGE_INTEGER PartitionLength
Definition: cdrom.h:530
#define NULL
Definition: types.h:112
LONGLONG QuadPart
Definition: typedefs.h:114
#define PAGED_CODE()

Referenced by DriverEvtDeviceAdd().

◆ DeviceIsMmcUpdateRequired()

BOOLEAN DeviceIsMmcUpdateRequired ( _In_ WDFDEVICE  Device)

Definition at line 4180 of file cdrom.c.

4197 {
4198  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
4199  PCDROM_DATA cdData = &(deviceExtension->DeviceAdditionalData);
4200 
4201  if ((cdData->Mmc.IsMmc) &&
4202  (cdData->Mmc.UpdateState == CdromMmcUpdateRequired))
4203  {
4204  return TRUE;
4205  }
4206  else
4207  {
4208  // no update required: just proceed
4209  return FALSE;
4210  }
4211 }
#define TRUE
Definition: types.h:120
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define CdromMmcUpdateRequired
Definition: cdrom.h:242
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:341

Referenced by IoctlWorkItemRoutine(), ReadWriteWorkItemRoutine(), and SequentialQueueEvtIoReadWrite().

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( _In_ PDRIVER_OBJECT  DriverObject,
_In_ PUNICODE_STRING  RegistryPath 
)

Definition at line 75 of file cdrom.c.

99 {
102  WDF_OBJECT_ATTRIBUTES attributes;
103  WDFDRIVER driverObject = NULL;
104 
105  PAGED_CODE();
106 
107  // Initialize WPP Tracing
109 
110  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
111  "CDROM.SYS DriverObject %p loading\n",
112  DriverObject));
113 
114  // Register DeviceAdd and DriverEvtCleanup callback.
115  // WPP_CLEANUP will be called in DriverEvtCleanup
118 
120 
121  status = WdfDriverCreate(DriverObject,
122  RegistryPath,
123  &attributes,
124  &config,
125  &driverObject);
126 
127  if (!NT_SUCCESS(status))
128  {
129  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_INIT,
130  "WdfDriverCreate failed. %x\n",
131  status));
132 
133  // Cleanup tracing here because DriverUnload will not be called
134  // as we have failed to create WDFDRIVER object itself.
136 
137  }
138  else
139  {
140  PCDROM_DRIVER_EXTENSION driverExtension = DriverGetExtension(driverObject);
141 
142  // Copy the registry path into the driver extension so we can use it later
143  driverExtension->Version = 0x01;
144  driverExtension->DriverObject = DriverObject;
145 
146  if (BootEnvironmentIsWinPE()) {
147 
148  SET_FLAG(driverExtension->Flags, CDROM_FLAG_WINPE_MODE);
149  }
150 
151  }
152 
153  return status;
154 }
struct config_s config
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
VOID NTAPI DriverEvtCleanup(_In_ WDFOBJECT Driver)
Definition: cdrom.c:202
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
FORCEINLINE VOID WDF_DRIVER_CONFIG_INIT(_Out_ PWDF_DRIVER_CONFIG Config, _In_opt_ PFN_WDF_DRIVER_DEVICE_ADD EvtDriverDeviceAdd)
Definition: wdfdriver.h:148
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
BOOLEAN BootEnvironmentIsWinPE(VOID)
Definition: cdrom.c:158
#define WPP_CLEANUP(a)
Definition: kdebugprint.h:57
#define WPP_INIT_TRACING(a, b)
Definition: kdebugprint.h:56
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI DriverEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit)
Definition: cdrom.c:238
PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback
Definition: wdfobject.h:109
PDRIVER_OBJECT DriverObject
Definition: cdrom.h:232
#define NULL
Definition: types.h:112
static SERVICE_STATUS status
Definition: service.c:31
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define CDROM_FLAG_WINPE_MODE
Definition: cdrom.h:237
#define PAGED_CODE()
Definition: ps.c:97

◆ DriverEvtCleanup()

VOID NTAPI DriverEvtCleanup ( _In_ WDFOBJECT  Driver)

Definition at line 202 of file cdrom.c.

219 {
220  WDFDRIVER driver = (WDFDRIVER)Driver;
221 
222  PAGED_CODE ();
223 
224  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
225  "CDROM.SYS DriverObject %p cleanup. Will be unloaded soon\n",
226  driver));
227 
228  // Stop WPP Tracing
229  WPP_CLEANUP( WdfDriverWdmGetDriverObject(driver) );
230 
231 
232  return;
233 }
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
struct @1657::@1658 driver
#define WPP_CLEANUP(a)
Definition: kdebugprint.h:57
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
#define PAGED_CODE()

Referenced by DriverEntry().

◆ DriverEvtDeviceAdd()

NTSTATUS NTAPI DriverEvtDeviceAdd ( _In_ WDFDRIVER  Driver,
_Inout_ PWDFDEVICE_INIT  DeviceInit 
)

Definition at line 238 of file cdrom.c.

261 {
263  PCDROM_DRIVER_EXTENSION driverExtension = NULL;
264  WDFDEVICE device = NULL;
265  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
266  BOOLEAN deviceClaimed = FALSE;
267 
268  WDF_OBJECT_ATTRIBUTES attributes;
269  WDF_FILEOBJECT_CONFIG fileObjectConfig;
270  WDF_IO_TARGET_OPEN_PARAMS ioTargetOpenParams;
271  WDF_IO_QUEUE_CONFIG queueConfig;
272  WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
273  WDF_REMOVE_LOCK_OPTIONS removeLockOptions;
274  PWCHAR wideDeviceName = NULL;
275  UNICODE_STRING unicodeDeviceName;
276  PDEVICE_OBJECT lowerPdo = NULL;
277  ULONG deviceNumber = 0;
278  ULONG devicePropertySessionId = INVALID_SESSION;
279  ULONG devicePropertySize = 0;
280  DEVPROPTYPE devicePropertyType = DEVPROP_TYPE_EMPTY;
281 
282  PAGED_CODE();
283 
284  driverExtension = DriverGetExtension(Driver);
285 
286  // 0. Initialize the objects that we're going to use
287  RtlInitUnicodeString(&unicodeDeviceName, NULL);
288 
289  // 1. Register PnP&Power callbacks for any we are interested in.
290  // If a callback isn't set, Framework will take the default action by itself.
291  {
292  // Zero out the PnpPowerCallbacks structure.
293  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
294 
295  // Use this callback to init resources that are used by the device and only needs to be called once.
297 
298  // Use this callback to prepare device for coming back from a lower power mode to D0.
299  pnpPowerCallbacks.EvtDeviceD0Entry = DeviceEvtD0Entry;
300 
301  // Use this callback to prepare device for entering into a lower power mode.
302  pnpPowerCallbacks.EvtDeviceD0Exit = DeviceEvtD0Exit;
303 
304  // Use this callback to free any resources used by device and will be called when the device is
305  // powered down.
307 
309 
310  // Register the PnP and power callbacks.
311  WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
312  }
313 
314  // 2. Register the EvtIoInCallerContext to deal with IOCTLs that need to stay in original context.
315  WdfDeviceInitSetIoInCallerContextCallback(DeviceInit,
317 
318  // 3. Register PreprocessCallback for IRP_MJ_POWER, IRP_MJ_FLUSH_BUFFERS and IRP_MJ_SHUTDOWN
319  {
320  UCHAR minorFunctions[1];
321 
322  minorFunctions[0] = IRP_MN_SET_POWER;
323 
324  status = WdfDeviceInitAssignWdmIrpPreprocessCallback(DeviceInit,
326  IRP_MJ_POWER,
327  minorFunctions,
328  RTL_NUMBER_OF(minorFunctions));
329  if (!NT_SUCCESS(status))
330  {
331  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
332  "DriverEvtDeviceAdd: Assign IrpPreprocessCallback for IRP_MJ_POWER failed, "
333  "status: 0x%X\n", status));
334 
335  goto Exit;
336  }
337 
338  status = WdfDeviceInitAssignWdmIrpPreprocessCallback(DeviceInit,
341  NULL,
342  0);
343  if (!NT_SUCCESS(status))
344  {
345  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
346  "DriverEvtDeviceAdd: Assign IrpPreprocessCallback for IRP_MJ_FLUSH_BUFFERS failed, "
347  "status: 0x%X\n", status));
348 
349  goto Exit;
350  }
351 
352  status = WdfDeviceInitAssignWdmIrpPreprocessCallback(DeviceInit,
355  NULL,
356  0);
357  if (!NT_SUCCESS(status))
358  {
359  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
360  "DriverEvtDeviceAdd: Assign IrpPreprocessCallback for IRP_MJ_SHUTDOWN failed, "
361  "status: 0x%X\n", status));
362 
363  goto Exit;
364  }
365  }
366 
367  // 4. Set attributes to create Request Context area.
368  {
369  //Reuse this structure.
373 
374  WdfDeviceInitSetRequestAttributes(DeviceInit,
375  &attributes);
376  }
377 
378  // 5. Register FileObject related callbacks
379  {
380  // Add FILE_OBJECT_EXTENSION as the context to the file object.
382 
383  // Set Entry points for Create and Close..
384 
385  // The framework doesn't sync the file create requests with pnp/power
386  // state. Re-direct all the file create requests to a dedicated
387  // queue, which will be purged manually during removal.
388  WDF_FILEOBJECT_CONFIG_INIT(&fileObjectConfig,
389  NULL, //CreateQueueEvtIoDefault,
391  WDF_NO_EVENT_CALLBACK); // No callback for Cleanup
392 
394 
395  // Since we are registering file events and fowarding create request
396  // ourself, we must also set AutoForwardCleanupClose so that cleanup
397  // and close can also get forwarded.
398  fileObjectConfig.AutoForwardCleanupClose = WdfTrue;
401 
402  // Indicate that file object is optional.
403  fileObjectConfig.FileObjectClass |= WdfFileObjectCanBeOptional;
404 
405  WdfDeviceInitSetFileObjectConfig(DeviceInit,
406  &fileObjectConfig,
407  &attributes);
408  }
409 
410  // 6. Initialize device-wide attributes
411  {
412  // Declare ourselves as NOT owning power policy.
413  // The power policy owner in storage stack is port driver.
414  WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, FALSE);
415 
416  // Set other DeviceInit attributes.
417  WdfDeviceInitSetExclusive(DeviceInit, FALSE);
418  WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_CD_ROM);
419  WdfDeviceInitSetCharacteristics(DeviceInit, FILE_REMOVABLE_MEDIA, FALSE);
420  WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);
421  WdfDeviceInitSetPowerPageable(DeviceInit);
422 
423  // We require the framework to acquire a remove lock before delivering all IRP types
424  WDF_REMOVE_LOCK_OPTIONS_INIT(&removeLockOptions,
426 
427  WdfDeviceInitSetRemoveLockOptions(DeviceInit, &removeLockOptions);
428 
429  // save the PDO for later reference
430  lowerPdo = WdfFdoInitWdmGetPhysicalDevice(DeviceInit);
431 
434 
435  // We have a parallel queue, so WdfSynchronizationScopeNone is our only choice.
438 
439  // Provide a cleanup callback which will release memory allocated with ExAllocatePool*
441  }
442 
443  // 7. Now, the device can be created.
444  {
445  wideDeviceName = ExAllocatePoolWithTag(NonPagedPoolNx,
446  64 * sizeof(WCHAR),
448 
449  if (wideDeviceName == NULL)
450  {
452  goto Exit;
453  }
454 
455  // Find the lowest device number currently available.
456  do {
457  status = RtlStringCchPrintfW((NTSTRSAFE_PWSTR)wideDeviceName,
458  64,
459  L"\\Device\\CdRom%d",
460  deviceNumber);
461 
462  if (!NT_SUCCESS(status)) {
463  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
464  "DriverEvtDeviceAdd: Format device name failed with error: 0x%X\n", status));
465 
466  goto Exit;
467  }
468 
469  RtlInitUnicodeString(&unicodeDeviceName, wideDeviceName);
470 
471  status = WdfDeviceInitAssignName(DeviceInit, &unicodeDeviceName);
472  if (!NT_SUCCESS(status))
473  {
474  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
475  "DriverEvtDeviceAdd: WdfDeviceInitAssignName() failed with error: 0x%X\n", status));
476 
477  goto Exit;
478  }
479 
480  status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
481 
482  deviceNumber++;
483 
485 
486  // When this loop exits the count is inflated by one - fix that.
487  deviceNumber--;
488 
489  if (!NT_SUCCESS(status))
490  {
491  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
492  "DriverEvtDeviceAdd: Can not create a new device, status: 0x%X\n",
493  status));
494 
495  goto Exit;
496  }
497  }
498 
499  // 8. Fill up basic Device Extension settings and create a remote I/O target for the next-lower driver.
500  // The reason why we do not use the local I/O target is because we want to be able to close the
501  // I/O target on surprise removal.
502  {
503  deviceExtension = DeviceGetExtension(device);
504 
505  deviceExtension->Version = 0x01;
506  deviceExtension->Size = sizeof(CDROM_DEVICE_EXTENSION);
507 
508  deviceExtension->DeviceObject = WdfDeviceWdmGetDeviceObject(device);
509  deviceExtension->Device = device;
510  deviceExtension->DriverExtension = driverExtension;
511 
512  deviceExtension->LowerPdo = lowerPdo;
513 
514  deviceExtension->DeviceType = FILE_DEVICE_CD_ROM; //Always a FILE_DEVICE_CD_ROM for all device it manages.
515  deviceExtension->DeviceName = unicodeDeviceName;
516 
517  deviceExtension->DeviceNumber = deviceNumber;
518  }
519  {
520  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
521  attributes.ParentObject = deviceExtension->Device;
522 
523  status = WdfIoTargetCreate(deviceExtension->Device,
524  &attributes,
525  &deviceExtension->IoTarget);
526 
527  if (!NT_SUCCESS(status))
528  {
529  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
530  "DriverEvtDeviceAdd: Can not create a remote I/O target object, status: 0x%X\n",
531  status));
532  goto Exit;
533  }
534 
536  WdfDeviceWdmGetAttachedDevice(deviceExtension->Device));
537 
538  status = WdfIoTargetOpen(deviceExtension->IoTarget,
539  &ioTargetOpenParams);
540  if (!NT_SUCCESS(status))
541  {
542  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
543  "DriverEvtDeviceAdd: Can not open a remote I/O target for the next-lower device, status: 0x%X\n",
544  status));
545 
546  WdfObjectDelete(deviceExtension->IoTarget);
547  deviceExtension->IoTarget = NULL;
548 
549  goto Exit;
550  }
551  }
552 
553  // 9. Claim the device, so that port driver will only accept the commands from CDROM.SYS for this device.
554  // NOTE: The I/O should be issued after the device is started. But we would like to claim
555  // the device as soon as possible, so this legacy behavior is kept.
556  status = DeviceClaimRelease(deviceExtension, FALSE);
557 
558  if (!NT_SUCCESS(status))
559  {
560  // Someone already had this device - we're in trouble
561  goto Exit;
562  }
563  else
564  {
565  deviceClaimed = TRUE;
566  }
567 
568  //
569  // CDROM Queueing Structure
570  //
571  // a. EvtIoInCallerContext (prior to queueing):
572  // This event will be used ONLY to forward down IOCTLs that come in at PASSIVE LEVEL
573  // and need to be forwarded down the stack in the original context.
574  //
575  // b. Main input queue: serial queue for main dispatching
576  // This queue will be used to do all dispatching of requests to serialize
577  // access to the device. Any request that was previously completed in
578  // the Dispatch routines will be completed here. Anything requiring device
579  // I/O will be sent through the serial I/O queue.
580  //
581  // 10. Set up IO queues after device being created.
582  //
583  {
586 
587  queueConfig.PowerManaged = WdfFalse;
588 
589 #pragma prefast(push)
590 #pragma prefast(disable: 28155, "a joint handler for read/write cannot be EVT_WDF_IO_QUEUE_IO_READ and EVT_WDF_IO_QUEUE_IO_WRITE simultaneously")
591 #pragma prefast(disable: 28023, "a joint handler for read/write cannot be EVT_WDF_IO_QUEUE_IO_READ and EVT_WDF_IO_QUEUE_IO_WRITE simultaneously")
594 #pragma prefast(pop)
595 
598 
599  status = WdfIoQueueCreate(device,
600  &queueConfig,
602  &(deviceExtension->SerialIOQueue));
603  if (!NT_SUCCESS(status))
604  {
605  goto Exit;
606  }
607 
608  // this queue is dedicated for file create requests.
610 
611  queueConfig.PowerManaged = WdfFalse;
613 
614  //Reuse this structure.
617 
620 
621  status = WdfIoQueueCreate(device,
622  &queueConfig,
623  &attributes,
624  &(deviceExtension->CreateQueue));
625 
626  if (!NT_SUCCESS(status))
627  {
628  goto Exit;
629  }
630 
631  // Configure the device to use driver created queue for dispatching create.
632  status = WdfDeviceConfigureRequestDispatching(device,
633  deviceExtension->CreateQueue,
635 
636  if (!NT_SUCCESS(status))
637  {
638  goto Exit;
639  }
640  }
641 
642  // 11. Set the alignment requirements for the device based on the host adapter requirements.
643  //
644  // NOTE: this should have been set when device is attached on device stack,
645  // by keeping this legacy code, we could avoid issue that this value was not correctly set at that time.
646  if (deviceExtension->LowerPdo->AlignmentRequirement > deviceExtension->DeviceObject->AlignmentRequirement)
647  {
648  WdfDeviceSetAlignmentRequirement(deviceExtension->Device,
649  deviceExtension->LowerPdo->AlignmentRequirement);
650  }
651 
652  // 12. Initialization of miscellaneous internal properties
653 
654  // CDROMs are not partitionable so starting offset is 0.
655  deviceExtension->StartingOffset.LowPart = 0;
656  deviceExtension->StartingOffset.HighPart = 0;
657 
658  // Set the default geometry for the cdrom to match what NT 4 used.
659  // these values will be used to compute the cylinder count rather
660  // than using it's NT 5.0 defaults.
661  deviceExtension->DiskGeometry.MediaType = RemovableMedia;
662  deviceExtension->DiskGeometry.TracksPerCylinder = 0x40;
663  deviceExtension->DiskGeometry.SectorsPerTrack = 0x20;
664 
666 
667  // Clear the SrbFlags and disable synchronous transfers
668  deviceExtension->SrbFlags = SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
669 
670  // Set timeout value in seconds.
671  deviceExtension->TimeOutValue = DeviceGetTimeOutValueFromRegistry();
672  if ((deviceExtension->TimeOutValue > 30 * 60) || // longer than 30 minutes
673  (deviceExtension->TimeOutValue == 0))
674  {
675  deviceExtension->TimeOutValue = SCSI_CDROM_TIMEOUT;
676  }
677 
678  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT,
679  "DriverEvtDeviceAdd: device timeout is set to %x seconds",
680  deviceExtension->TimeOutValue
681  ));
682 
683 #if (NTDDI_VERSION >= NTDDI_WIN8)
684  deviceExtension->IsVolumeOnlinePending = TRUE;
685 
687 
688  queueConfig.PowerManaged = WdfFalse;
689 
690  status = WdfIoQueueCreate(device,
691  &queueConfig,
693  &deviceExtension->ManualVolumeReadyQueue);
694 
695  if (!NT_SUCCESS(status))
696  {
697  goto Exit;
698  }
699 #endif
700 
701  // 13. Initialize the stuff related to media locking
702  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
703  attributes.ParentObject = deviceExtension->Device;
704  status = WdfWaitLockCreate(&attributes,
705  &deviceExtension->EjectSynchronizationLock);
706 
707  deviceExtension->LockCount = 0;
708 
709  // 14. Initialize context structures needed for asynchronous release queue and power requests
710 
711  if (NT_SUCCESS(status))
712  {
713  status = DeviceInitReleaseQueueContext(deviceExtension);
714  }
715 
716  if (NT_SUCCESS(status))
717  {
718  status = DeviceInitPowerContext(deviceExtension);
719  }
720 
721  // 15. Create external access points other than device name.
722  if (NT_SUCCESS(status))
723  {
724  status = DeviceCreateWellKnownName(deviceExtension);
725  }
726 
727  // 16. Query session id from the PDO.
728  if (NT_SUCCESS(status))
729  {
730  status = IoGetDevicePropertyData(deviceExtension->LowerPdo,
731  &DEVPKEY_Device_SessionId,
732  0,
733  0,
734  sizeof(devicePropertySessionId),
735  &devicePropertySessionId,
736  &devicePropertySize,
737  &devicePropertyType);
738 
739  if (!NT_SUCCESS(status))
740  {
741  // The device is global.
742  devicePropertySessionId = INVALID_SESSION;
744  }
745  }
746 
747  // 17. Register interfaces for this device.
748  if (NT_SUCCESS(status))
749  {
750  status = DeviceRegisterInterface(deviceExtension, CdRomDeviceInterface);
751  }
752 
753  if (NT_SUCCESS(status))
754  {
755  // If this is a per-session DO, don't register for mount interface so that
756  // mountmgr will not automatically assign a drive letter.
757  if (devicePropertySessionId == INVALID_SESSION)
758  {
759  status = DeviceRegisterInterface(deviceExtension, MountedDeviceInterface);
760  }
761  }
762 
763  // 18. Initialize the shutdown/flush lock
764  if (NT_SUCCESS(status))
765  {
766  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
767  attributes.ParentObject = deviceExtension->Device;
768 
769  status = WdfWaitLockCreate(&attributes, &deviceExtension->ShutdownFlushWaitLock);
770  if (!NT_SUCCESS(status))
771  {
772  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
773  "DriverEvtDeviceAdd: Cannot create shutdown/flush waitlock, status: 0x%X\n",
774  status));
775  }
776  }
777 
778  // 19. Initialize the work item that is used to initiate asynchronous reads/writes
779  if (NT_SUCCESS(status))
780  {
781  WDF_WORKITEM_CONFIG workItemConfig;
782  WDF_OBJECT_ATTRIBUTES workItemAttributes;
783 
784  WDF_WORKITEM_CONFIG_INIT(&workItemConfig,
786  );
787 
788  WDF_OBJECT_ATTRIBUTES_INIT(&workItemAttributes);
789  workItemAttributes.ParentObject = deviceExtension->Device;
790 
791  status = WdfWorkItemCreate(&workItemConfig,
792  &workItemAttributes,
793  &deviceExtension->ReadWriteWorkItem
794  );
795 
796  if (!NT_SUCCESS(status))
797  {
798  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_INIT,
799  "DriverEvtDeviceAdd: Cannot create read/write work item, status: 0x%X\n",
800  status));
801  }
802  }
803 
804  // 20. Initialize the work item that is used to process most IOCTLs at PASSIVE_LEVEL.
805  if (NT_SUCCESS(status))
806  {
807  WDF_WORKITEM_CONFIG workItemConfig;
808  WDF_OBJECT_ATTRIBUTES workItemAttributes;
809 
810  WDF_WORKITEM_CONFIG_INIT(&workItemConfig,
812  );
813 
814  WDF_OBJECT_ATTRIBUTES_INIT(&workItemAttributes);
815  workItemAttributes.ParentObject = deviceExtension->Device;
816 
817  status = WdfWorkItemCreate(&workItemConfig,
818  &workItemAttributes,
819  &deviceExtension->IoctlWorkItem
820  );
821 
822  if (!NT_SUCCESS(status))
823  {
824  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_INIT,
825  "DriverEvtDeviceAdd: Cannot create ioctl work item, status: 0x%X\n",
826  status));
827  }
828  }
829 
830 
831 Exit:
832 
833  if (!NT_SUCCESS(status))
834  {
835  FREE_POOL(wideDeviceName);
836 
837  if (deviceExtension != NULL)
838  {
839  RtlInitUnicodeString(&deviceExtension->DeviceName, NULL);
840  }
841 
842  // Release the device with the port driver, if it was claimed
843  if ((deviceExtension != NULL) && deviceClaimed)
844  {
845  DeviceClaimRelease(deviceExtension, TRUE);
846  }
847  deviceClaimed = FALSE;
848  }
849 
850  return status;
851 }
PFN_WDF_IO_QUEUE_IO_READ EvtIoRead
Definition: wdfio.h:401
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
WDF_TRI_STATE AutoForwardCleanupClose
Definition: wdfdevice.h:612
PCDROM_DRIVER_EXTENSION DriverExtension
Definition: cdrom.h:490
PFN_WDF_DEVICE_SURPRISE_REMOVAL EvtDeviceSurpriseRemoval
Definition: wdfdevice.h:1175
VOID NTAPI SequentialQueueEvtIoDeviceControl(_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode)
Definition: cdrom.c:3408
#define INVALID_SESSION
Definition: cdromp.h:381
VOID NTAPI DeviceEvtSurpriseRemoval(_In_ WDFDEVICE Device)
Definition: cdrom.c:1223
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
FORCEINLINE VOID WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE(_Out_ PWDF_IO_TARGET_OPEN_PARAMS Params, _In_ PDEVICE_OBJECT DeviceObject)
Definition: wdfiotarget.h:287
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85
struct _CDROM_DEVICE_EXTENSION CDROM_DEVICE_EXTENSION
Definition: cdrom.h:216
#define IRP_MJ_FLUSH_BUFFERS
VOID NTAPI DeviceEvtCleanup(_In_ WDFOBJECT Device)
Definition: cdrom.c:856
#define IRP_MJ_SHUTDOWN
#define TRUE
Definition: types.h:120
WDFWORKITEM ReadWriteWorkItem
Definition: cdrom.h:608
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
WDFQUEUE ManualVolumeReadyQueue
Definition: cdrom.h:591
WDFIOTARGET IoTarget
Definition: cdrom.h:476
LONG NTSTATUS
Definition: precomp.h:26
#define WRITE_RETRY_DELAY_DVD_1x
Definition: cdrom.h:118
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:443
VOID NTAPI SequentialQueueEvtCanceledOnQueue(_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request)
Definition: cdrom.c:3848
ULONG TracksPerCylinder
Definition: ntdddisk.h:440
uint16_t * PWCHAR
Definition: typedefs.h:56
PDEVICE_OBJECT LowerPdo
Definition: cdrom.h:496
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
ULONG DEVPROPTYPE
Definition: devpropdef.h:24
WDFQUEUE CreateQueue
Definition: cdrom.h:483
PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT EvtDeviceSelfManagedIoInit
Definition: wdfdevice.h:1172
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
DEVICE_TYPE DeviceType
Definition: cdrom.h:499
FxDevice * device
WDF_EXECUTION_LEVEL ExecutionLevel
Definition: wdfobject.h:120
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
#define SCSI_CDROM_TIMEOUT
Definition: cdrom.c:170
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
Definition: devices.h:37
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
VOID NTAPI DeviceEvtIoInCallerContext(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
Definition: cdrom.c:1554
unsigned char BOOLEAN
VOID NTAPI DeviceEvtFileClose(_In_ WDFFILEOBJECT FileObject)
Definition: cdrom.c:1327
VOID NTAPI RequestEvtCleanup(_In_ WDFOBJECT Request)
Definition: cdrom.c:4215
VOID NTAPI IoctlWorkItemRoutine(_In_ WDFWORKITEM WorkItem)
Definition: cdrom.c:3503
FORCEINLINE VOID WDF_FILEOBJECT_CONFIG_INIT(_Out_ PWDF_FILEOBJECT_CONFIG FileEventCallbacks, _In_opt_ PFN_WDF_DEVICE_FILE_CREATE EvtDeviceFileCreate, _In_opt_ PFN_WDF_FILE_CLOSE EvtFileClose, _In_opt_ PFN_WDF_FILE_CLEANUP EvtFileCleanup)
Definition: wdfdevice.h:625
#define DEVPROP_TYPE_EMPTY
Definition: devpropdef.h:29
LARGE_INTEGER StartingOffset
Definition: cdrom.h:533
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static void Exit(void)
Definition: sock.c:1331
PFN_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP EvtDeviceSelfManagedIoCleanup
Definition: wdfdevice.h:1170
NTSTATUS NTAPI DeviceEvtD0Entry(_In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE PreviousState)
Definition: cdrom.c:993
ULONG SectorsPerTrack
Definition: ntdddisk.h:441
VOID NTAPI ReadWriteWorkItemRoutine(_In_ WDFWORKITEM WorkItem)
Definition: cdrom.c:3345
EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT DeviceEvtSelfManagedIoInit
Definition: cdrom.h:874
BOOLEAN IsVolumeOnlinePending
Definition: cdrom.h:590
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
MEDIA_TYPE MediaType
Definition: ntdddisk.h:439
#define CDROM_TAG_STRINGS
Definition: cdrom.h:743
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
_Null_terminated_ wchar_t * NTSTRSAFE_PWSTR
Definition: ntstrsafe.h:58
#define IRP_MJ_POWER
FORCEINLINE VOID WDF_PNPPOWER_EVENT_CALLBACKS_INIT(_Out_ PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks)
Definition: wdfdevice.h:1214
static const WCHAR L[]
Definition: oid.c:1250
VOID NTAPI CreateQueueEvtIoDefault(_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request)
Definition: cdrom.c:1266
PFN_WDF_DEVICE_D0_ENTRY EvtDeviceD0Entry
Definition: wdfdevice.h:1164
ULONG LowPart
Definition: typedefs.h:106
#define IRP_MN_SET_POWER
EVT_WDFDEVICE_WDM_IRP_PREPROCESS RequestProcessSetPower
Definition: cdrom.h:910
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
EVT_WDFDEVICE_WDM_IRP_PREPROCESS RequestProcessShutdownFlush
Definition: cdrom.h:908
WDFDEVICE Device
Definition: cdrom.h:473
WDFWAITLOCK ShutdownFlushWaitLock
Definition: cdrom.h:595
WDFWAITLOCK EjectSynchronizationLock
Definition: cdrom.h:559
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback
Definition: wdfobject.h:109
PFN_WDF_IO_QUEUE_IO_DEVICE_CONTROL EvtIoDeviceControl
Definition: wdfio.h:405
WDFQUEUE SerialIOQueue
Definition: cdrom.h:479
DISK_GEOMETRY DiskGeometry
Definition: cdrom.h:524
PFN_WDF_IO_QUEUE_IO_DEFAULT EvtIoDefault
Definition: wdfio.h:399
WDF_TRI_STATE PowerManaged
Definition: wdfio.h:393
PFN_WDF_IO_QUEUE_IO_WRITE EvtIoWrite
Definition: wdfio.h:403
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
WDFOBJECT ParentObject
Definition: wdfobject.h:130
#define WDF_NO_EVENT_CALLBACK
Definition: wdftypes.h:106
#define NULL
Definition: types.h:112
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
PFN_WDF_DEVICE_D0_EXIT EvtDeviceD0Exit
Definition: wdfdevice.h:1166
LONGLONG ReadWriteRetryDelay100nsUnits
Definition: cdrom.h:384
WDF_FILEOBJECT_CLASS FileObjectClass
Definition: wdfdevice.h:619
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:426
PDEVICE_OBJECT DeviceObject
Definition: cdrom.h:493
WDF_SYNCHRONIZATION_SCOPE SynchronizationScope
Definition: wdfobject.h:125
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
#define STATUS_SUCCESS
Definition: shellext.h:65
FORCEINLINE VOID WDF_REMOVE_LOCK_OPTIONS_INIT(_Out_ PWDF_REMOVE_LOCK_OPTIONS RemoveLockOptions, _In_ ULONG Flags)
Definition: wdfdevice.h:1661
PFN_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: wdfio.h:413
VOID NTAPI SequentialQueueEvtIoReadWrite(_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t Length)
Definition: cdrom.c:3215
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI DeviceEvtD0Exit(_In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE TargetState)
Definition: cdrom.c:1075
VOID NTAPI DeviceEvtSelfManagedIoCleanup(_In_ WDFDEVICE Device)
Definition: cdrom.c:902
#define PAGED_CODE()
WDFWORKITEM IoctlWorkItem
Definition: cdrom.h:613
UNICODE_STRING DeviceName
Definition: cdrom.h:502
Definition: ps.c:97

Referenced by DriverEntry().

◆ IoctlWorkItemRoutine()

VOID NTAPI IoctlWorkItemRoutine ( _In_ WDFWORKITEM  WorkItem)

Definition at line 3503 of file cdrom.c.

3523 {
3524  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
3525 
3526  PAGED_CODE ();
3527 
3528  deviceExtension = WdfObjectGetTypedContext(WdfWorkItemGetParentObject(WorkItem), CDROM_DEVICE_EXTENSION);
3529 
3530  if (DeviceIsMmcUpdateRequired(deviceExtension->Device))
3531  {
3532  // Issue command to update the drive capabilities.
3533  // The failure of MMC update is not considered critical,
3534  // so that we'll continue to process I/O even MMC update fails.
3535  DeviceUpdateMmcCapabilities(deviceExtension->Device);
3536  }
3537 
3538  RequestProcessSerializedIoctl(deviceExtension, deviceExtension->IoctlWorkItemContext.OriginalRequest);
3539 }
WDFREQUEST OriginalRequest
Definition: cdrom.h:328
CDROM_IOCTL_CONTEXT IoctlWorkItemContext
Definition: cdrom.h:614
WDFDEVICE Device
Definition: cdrom.h:473
#define WdfObjectGetTypedContext(handle, type)
Definition: wdfobject.h:404
#define NULL
Definition: types.h:112
BOOLEAN DeviceIsMmcUpdateRequired(_In_ WDFDEVICE Device)
Definition: cdrom.c:4180
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
#define PAGED_CODE()

Referenced by DriverEvtDeviceAdd().

◆ NormalizeIoctl()

VOID NormalizeIoctl ( _Inout_ PWDF_REQUEST_PARAMETERS  requestParameters)

Definition at line 1514 of file cdrom.c.

1517 {
1518  ULONG ioctlCode;
1519  ULONG baseCode;
1520  ULONG functionCode;
1521 
1522  // if this is a class driver ioctl then we need to change the base code
1523  // to IOCTL_STORAGE_BASE so that the switch statement can handle it.
1524  //
1525  // WARNING - currently the scsi class ioctl function codes are between
1526  // 0x200 & 0x300. this routine depends on that fact
1527  ioctlCode = requestParameters->Parameters.DeviceIoControl.IoControlCode;
1528  baseCode = DEVICE_TYPE_FROM_CTL_CODE(ioctlCode);
1529  functionCode = (ioctlCode & (~0xffffc003)) >> 2;
1530 
1531  if ((baseCode == IOCTL_SCSI_BASE) ||
1532  (baseCode == IOCTL_DISK_BASE) ||
1533  (baseCode == IOCTL_TAPE_BASE) ||
1534  (baseCode == IOCTL_DVD_BASE) ||
1535  (baseCode == IOCTL_CDROM_BASE))
1536  //IOCTL_STORAGE_BASE does not need to be converted.
1537  {
1538  if((functionCode >= 0x200) && (functionCode <= 0x300))
1539  {
1540  ioctlCode = (ioctlCode & 0x0000ffff) | CTL_CODE(IOCTL_STORAGE_BASE, 0, 0, 0);
1541 
1542  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_IOCTL,
1543  "IOCTL code recalibrate, New ioctl code is %lx\n",
1544  ioctlCode));
1545 
1546  // Set the code into request parameters, then "requestParameters" needs to be used for dispatch functions.
1547  requestParameters->Parameters.DeviceIoControl.IoControlCode = ioctlCode;
1548  }
1549  }
1550 }
#define IOCTL_DISK_BASE
Definition: ntdddisk.h:44
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
#define IOCTL_TAPE_BASE
Definition: ntddtape.h:35
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define CTL_CODE(DeviceType, Function, Method, Access)
Definition: nt_native.h:586
#define IOCTL_DVD_BASE
Definition: ntddcdvd.h:32
#define IOCTL_SCSI_BASE
Definition: scsi_port.h:37
#define DEVICE_TYPE_FROM_CTL_CODE(c)
Definition: winioctl.h:176
unsigned int ULONG
Definition: retypes.h:1
#define IOCTL_STORAGE_BASE
Definition: ntddstor.h:96

Referenced by DeviceEvtIoInCallerContext().

◆ ReadWriteWorkItemRoutine()

VOID NTAPI ReadWriteWorkItemRoutine ( _In_ WDFWORKITEM  WorkItem)

Definition at line 3345 of file cdrom.c.

3365 {
3366  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
3367  WDFREQUEST readWriteRequest = NULL;
3368  WDF_REQUEST_PARAMETERS readWriteRequestParameters;
3370 
3371  PAGED_CODE ();
3372 
3373  deviceExtension = WdfObjectGetTypedContext(WdfWorkItemGetParentObject(WorkItem), CDROM_DEVICE_EXTENSION);
3374  readWriteRequest = deviceExtension->ReadWriteWorkItemContext.OriginalRequest;
3375  deviceExtension->ReadWriteWorkItemContext.OriginalRequest = NULL;
3376 
3377  WDF_REQUEST_PARAMETERS_INIT(&readWriteRequestParameters);
3378  WdfRequestGetParameters(readWriteRequest, &readWriteRequestParameters);
3379 
3380  if (DeviceIsMmcUpdateRequired(deviceExtension->Device))
3381  {
3382  // Issue command to update the drive capabilities.
3383  // The failure of MMC update is not considered critical, so we'll
3384  // continue to process the request even if MMC update fails.
3385  (VOID) DeviceUpdateMmcCapabilities(deviceExtension->Device);
3386  }
3387 
3388  // Now verify and process the request
3389  if (NT_SUCCESS(status))
3390  {
3391  status = RequestValidateReadWrite(deviceExtension, readWriteRequest, readWriteRequestParameters);
3392  }
3393  if (NT_SUCCESS(status))
3394  {
3395  status = RequestHandleReadWrite(deviceExtension, readWriteRequest, readWriteRequestParameters);
3396  }
3397 
3398  // Complete the request immediately on failure
3399  if (!NT_SUCCESS(status))
3400  {
3401  RequestCompletion(deviceExtension, readWriteRequest, status, 0);
3402  }
3403 }
LONG NTSTATUS
Definition: precomp.h:26
CDROM_READ_WRITE_CONTEXT ReadWriteWorkItemContext
Definition: cdrom.h:609
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
WDFREQUEST OriginalRequest
Definition: cdrom.h:335
NTSTATUS RequestValidateReadWrite(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: ioctl.c:6117
NTSTATUS RequestHandleReadWrite(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: ioctl.c:6353
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define VOID
Definition: acefi.h:82
WDFDEVICE Device
Definition: cdrom.h:473
#define WdfObjectGetTypedContext(handle, type)
Definition: wdfobject.h:404
#define NULL
Definition: types.h:112
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211
BOOLEAN DeviceIsMmcUpdateRequired(_In_ WDFDEVICE Device)
Definition: cdrom.c:4180
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEvtDeviceAdd().

◆ RequestDispatchProcessDirectly()

BOOLEAN RequestDispatchProcessDirectly ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters 
)

Definition at line 1694 of file cdrom.c.

1717 {
1720  size_t dataLength = 0;
1721 
1722  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
1723  ULONG ioctlCode = RequestParameters.Parameters.DeviceIoControl.IoControlCode;
1724 
1725  switch (ioctlCode)
1726  {
1727 
1729  {
1731 
1732  processed = TRUE;
1733  break; // complete the irp
1734  }
1735 
1737  {
1738  status = RequestHandleGetMediaTypeEx(deviceExtension, Request, &dataLength);
1739 
1740  processed = TRUE;
1741  break; // complete the irp
1742  }
1743 
1745  {
1747 
1748  processed = TRUE;
1749  break; // complete the irp
1750  }
1751 
1753  {
1755 
1756  processed = TRUE;
1757  break; // complete the irp
1758  }
1759 
1761  {
1763 
1764  processed = TRUE;
1765  break; // complete the irp
1766  }
1767 
1769  {
1771 
1772  processed = TRUE;
1773  break; // complete the irp
1774  }
1775 
1777  {
1779 
1780  processed = TRUE;
1781  break; // complete the irp
1782  }
1783 
1785  {
1787 
1788  processed = TRUE;
1789  break; // complete the irp
1790  }
1791 
1793  {
1794  status = RequestHandleEventNotification(deviceExtension, Request, &RequestParameters, &dataLength);
1795 
1796  processed = TRUE;
1797  break; // complete the irp
1798  }
1799 
1800 #if (NTDDI_VERSION >= NTDDI_WIN8)
1801  case IOCTL_VOLUME_ONLINE:
1802  {
1803  //
1804  // Mount manager and volume manager will
1805  // follow this online with a post online
1806  // but other callers may not. In those
1807  // cases, we process this request right
1808  // away. We approximate that these other
1809  // callers are from user mode
1810  //
1811 
1812  if (WdfRequestGetRequestorMode(Request) == KernelMode)
1813  {
1814  processed = TRUE;
1815  }
1816  break;
1817  }
1818 #endif
1819 
1820  default:
1821  {
1822  processed = FALSE;
1823  break;
1824  }
1825 
1826  } //end of switch (ioctlCode)
1827 
1828  if (processed)
1829  {
1830  UCHAR currentStackLocationFlags = 0;
1831  currentStackLocationFlags = RequestGetCurrentStackLocationFlags(Request);
1832 
1833  if ((status == STATUS_VERIFY_REQUIRED) &&
1834  (currentStackLocationFlags & SL_OVERRIDE_VERIFY_VOLUME))
1835  {
1836  // If the status is verified required and this request
1837  // should bypass verify required then retry the request.
1839  UNREFERENCED_PARAMETER(status); // disables prefast warning; defensive coding...
1840 
1842  }
1843  else
1844  {
1845  // Complete the request after processing it.
1846  RequestCompletion(deviceExtension, Request, status, dataLength);
1847  }
1848  }
1849 
1850  return processed;
1851 }
#define IOCTL_STORAGE_SET_HOTPLUG_INFO
Definition: ntddstor.h:157
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
NTSTATUS RequestHandleMountQueryDeviceName(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:4015
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
NTSTATUS RequestHandleGetMediaTypeEx(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _Out_ size_t *DataLength)
Definition: ioctl.c:336
#define FALSE
Definition: types.h:117
NTSTATUS RequestHandleMountQueryUniqueId(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:3939
BOOLEAN RequestDispatchProcessDirectly(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:1694
unsigned char BOOLEAN
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
ULONG dataLength
Definition: scsi.h:3751
unsigned char UCHAR
Definition: xmlstorage.h:181
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
NTSTATUS RequestHandleSetHotPlugInfo(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:5392
#define IOCTL_STORAGE_EVENT_NOTIFICATION
Definition: ntddstor.h:226
#define IOCTL_CDROM_GET_INQUIRY_DATA
Definition: ntddcdrm.h:91
__inline UCHAR RequestGetCurrentStackLocationFlags(_In_ WDFREQUEST Request)
Definition: cdrom.h:1554
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:137
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
NTSTATUS RequestHandleGetDeviceNumber(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:5280
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
static int processed(const type_t *type)
Definition: typegen.c:2236
NTSTATUS RequestHandleGetInquiryData(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:270
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS RequestHandleGetHotPlugInfo(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:5337
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS RequestHandleMountQuerySuggestedLinkName(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:4088
Definition: ps.c:97

Referenced by DeviceEvtIoInCallerContext(), and RequestDispatchProcessDirectly().

◆ RequestDispatchSpecialIoctls()

BOOLEAN RequestDispatchSpecialIoctls ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters 
)

Definition at line 2849 of file cdrom.c.

2872 {
2875  size_t dataLength = 0;
2876  BOOLEAN requestCompleted = FALSE;
2877 
2878  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
2879  PCDROM_DATA cdData = &(deviceExtension->DeviceAdditionalData);
2880  ULONG ioctlCode = RequestParameters.Parameters.DeviceIoControl.IoControlCode;
2881 
2882  switch (ioctlCode)
2883  {
2888  {
2889  // SPTI is considered special case as we need to set the MinorFunction before pass to low level.
2890 
2891 #if defined (_WIN64)
2892  if (WdfRequestIsFrom32BitProcess(Request))
2893  {
2894  if ((ioctlCode == IOCTL_SCSI_PASS_THROUGH) || (ioctlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT))
2895  {
2896  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH32))
2897  {
2899  }
2900  }
2901  else
2902  {
2903  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH32_EX))
2904  {
2906  }
2907  }
2908  }
2909  else
2910 #endif
2911  {
2912  if ((ioctlCode == IOCTL_SCSI_PASS_THROUGH) || (ioctlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT))
2913  {
2914  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH))
2915  {
2917  }
2918  }
2919  else
2920  {
2921  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH_EX))
2922  {
2924  }
2925  }
2926  }
2927 
2928  if (!NT_SUCCESS(status))
2929  {
2930  // validation failed.
2931  RequestCompletion(deviceExtension, Request, status, dataLength);
2932  }
2933  else
2934  {
2935  // keep the request in serialized manner and stay in user's context.
2936  status = RequestSetContextFields(Request, RequestHandleScsiPassThrough);
2937 
2938  if (NT_SUCCESS(status))
2939  {
2941  }
2942  else
2943  {
2944  RequestCompletion(deviceExtension, Request, status, 0);
2945  }
2946  }
2947 
2948  requestCompleted = TRUE;
2949  processed = TRUE;
2950  break;
2951  }
2952 
2954  {
2955  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(STORAGE_PROPERTY_QUERY))
2956  {
2958  }
2959  else
2960  {
2961  PSTORAGE_PROPERTY_QUERY inputBuffer = NULL;
2962 
2963  status = WdfRequestRetrieveInputBuffer(Request,
2964  RequestParameters.Parameters.DeviceIoControl.InputBufferLength,
2965  &inputBuffer,
2966  NULL);
2967 
2968  if (NT_SUCCESS(status))
2969  {
2970  if (!EXCLUSIVE_MODE(cdData) || // not locked
2971  EXCLUSIVE_OWNER(cdData, WdfRequestGetFileObject(Request)) || // request is from lock owner
2972  (inputBuffer->QueryType == PropertyExistsQuery)) // request not access device
2973  {
2974  if (inputBuffer->PropertyId == StorageDeviceUniqueIdProperty)
2975  {
2976  // previously handled in classpnp
2977  // keep the request in serialized manner and stay in user's context.
2979 
2980  if (NT_SUCCESS(status))
2981  {
2983  // remeber that the request has been completed.
2984  requestCompleted = TRUE;
2985  }
2986  }
2987  else if (inputBuffer->PropertyId == StorageDeviceWriteCacheProperty)
2988  {
2989  // previously handled in classpnp
2990  // keep the request in serialized manner and stay in user's context.
2992 
2993  if (NT_SUCCESS(status))
2994  {
2996  // remeber that the request has been completed.
2997  requestCompleted = TRUE;
2998  }
2999  }
3000  else
3001  {
3002  // Pass to port driver for handling
3004 
3005  // remeber that the request has been completed.
3006  requestCompleted = TRUE;
3007  }
3008  }
3009  else
3010  {
3011  // If cached data exists, return cached data. Otherwise, fail the request.
3012  if ((inputBuffer->QueryType == PropertyStandardQuery) &&
3013  ((inputBuffer->PropertyId == StorageDeviceProperty) || (inputBuffer->PropertyId == StorageAdapterProperty)) )
3014  {
3016  }
3017  else
3018  {
3020  }
3021  }
3022  }
3023  }
3024 
3025  processed = TRUE;
3026  break;
3027  }
3028 
3029  // this IOCTL is a fake one, used for MCN process sync-ed with serial queue.
3031  {
3032  PIRP irp = WdfRequestWdmGetIrp(Request);
3033 
3034  if ((deviceExtension->MediaChangeDetectionInfo != NULL) &&
3035  (irp == deviceExtension->MediaChangeDetectionInfo->MediaChangeSyncIrp) &&
3036  (WdfRequestGetRequestorMode(Request) == KernelMode) &&
3040  {
3041  // This is the requset we use to sync Media Change Detection with sequential queue.
3042  status = WdfDeviceEnqueueRequest(Device, Request);
3043 
3044  if (!NT_SUCCESS(status))
3045  {
3046  RequestCompletion(deviceExtension, Request, status, dataLength);
3047  }
3048 
3049  requestCompleted = TRUE;
3050  processed = TRUE;
3051  }
3052  else
3053  {
3054  // process as an unknown request.
3055  processed = FALSE;
3056  }
3057  break;
3058  }
3059 
3060  default:
3061  {
3062  processed = FALSE;
3063  break;
3064  }
3065  } //end of switch (ioctlCode)
3066 
3067  if (processed && !requestCompleted)
3068  {
3069  UCHAR currentStackLocationFlags = 0;
3070  currentStackLocationFlags = RequestGetCurrentStackLocationFlags(Request);
3071 
3072  if ((status == STATUS_VERIFY_REQUIRED) &&
3073  (currentStackLocationFlags & SL_OVERRIDE_VERIFY_VOLUME))
3074  {
3075  // If the status is verified required and this request
3076  // should bypass verify required then retry the request.
3078  UNREFERENCED_PARAMETER(status); // disables prefast warning; defensive coding...
3079 
3081  }
3082  else
3083  {
3084  RequestCompletion(deviceExtension, Request, status, dataLength);
3085  }
3086  }
3087 
3088  return processed;
3089 }
BOOLEAN RequestDispatchSpecialIoctls(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:2849
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define IOCTL_SCSI_PASS_THROUGH_DIRECT_EX
Definition: ntddscsi.h:38
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
struct _WDF_REQUEST_PARAMETERS::@3696::@3701 Others
LONG NTSTATUS
Definition: precomp.h:26
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
NTSTATUS RequestSetContextFields(_In_ WDFREQUEST Request, _In_ PSYNC_HANDLER Handler)
Definition: common.c:2748
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define IOCTL_SCSI_PASS_THROUGH_EX
Definition: ntddscsi.h:37
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define FALSE
Definition: types.h:117
NTSTATUS RequestSynchronizeProcessWithSerialQueue(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
Definition: cdrom.c:3893
unsigned char BOOLEAN
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
BOOLEAN RequestDispatchUnknownRequests(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:3093
VOID RequestSetupMcnSyncIrp(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension)
Definition: autorun.c:2749
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
NTSTATUS RequestHandleQueryPropertyDeviceUniqueId(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
Definition: ioctl.c:2799
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG dataLength
Definition: scsi.h:3751
#define EXCLUSIVE_MODE(_CdData)
Definition: cdrom.h:788
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
NTSTATUS RequestHandleQueryPropertyRetrieveCachedData(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:2628
unsigned char UCHAR
Definition: xmlstorage.h:181
#define EXCLUSIVE_OWNER(_CdData, _FileObject)
Definition: cdrom.h:789
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
__inline UCHAR RequestGetCurrentStackLocationFlags(_In_ WDFREQUEST Request)
Definition: cdrom.h:1554
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:137
STORAGE_QUERY_TYPE QueryType
Definition: ntddstor.h:553
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
#define NULL
Definition: types.h:112
#define IOCTL_MCN_SYNC_FAKE_IOCTL
Definition: cdrom.h:181
STORAGE_PROPERTY_ID PropertyId
Definition: ntddstor.h:552
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
static int processed(const type_t *type)
Definition: typegen.c:2236
unsigned int ULONG
Definition: retypes.h:1
PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo
Definition: cdrom.h:563
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS RequestHandleQueryPropertyWriteCache(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
Definition: ioctl.c:2974
FxIrp * irp
Definition: ps.c:97

Referenced by DeviceEvtIoInCallerContext(), and RequestDispatchSpecialIoctls().

◆ RequestDispatchSyncWithSequentialQueue()

BOOLEAN RequestDispatchSyncWithSequentialQueue ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters 
)

Definition at line 2717 of file cdrom.c.

2740 {
2743  size_t dataLength = 0;
2744 
2745  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
2746  ULONG ioctlCode = RequestParameters.Parameters.DeviceIoControl.IoControlCode;
2747 
2748  switch (ioctlCode)
2749  {
2750 
2752  {
2753  //1. Validate
2755 
2756  //2. keep the request in serialized manner and stay in user's context.
2757  if (NT_SUCCESS(status))
2758  {
2759  PCDROM_EXCLUSIVE_ACCESS exclusiveAccess = NULL;
2760 
2761  status = WdfRequestRetrieveInputBuffer(Request,
2762  RequestParameters.Parameters.DeviceIoControl.InputBufferLength,
2763  &exclusiveAccess,
2764  NULL);
2765 
2766  if (NT_SUCCESS(status))
2767  {
2768  // do not need to check "status" as it passed validation and cannot fail in WdfRequestRetrieveInputBuffer()
2769  switch (exclusiveAccess->RequestType)
2770  {
2771 
2773  {
2774  status = RequestSetContextFields(Request, RequestHandleExclusiveAccessQueryLockState);
2775  break;
2776  }
2777 
2779  {
2780  status = RequestSetContextFields(Request, RequestHandleExclusiveAccessLockDevice);
2781  break;
2782  }
2783 
2785  {
2786  status = RequestSetContextFields(Request, RequestHandleExclusiveAccessUnlockDevice);
2787  break;
2788  }
2789  default:
2790  {
2791  // already valicated in RequestValidateExclusiveAccess()
2792  NT_ASSERT(FALSE);
2793  break;
2794  }
2795  }
2796  }
2797 
2798  if (NT_SUCCESS(status))
2799  {
2800  // now, put the special synchronization information into the context
2802 
2803  // "status" is used for debugging in above statement, reset to success to avoid further work in this function.
2805  }
2806  }
2807 
2808  processed = TRUE;
2809  break; // complete the irp
2810  }
2811 
2812  default:
2813  {
2814  processed = FALSE;
2815  break;
2816  }
2817  } //end of switch (ioctlCode)
2818 
2819  // Following process is only valid if the request is not really processed. (failed in validation)
2820  if (processed && !NT_SUCCESS(status))
2821  {
2822  UCHAR currentStackLocationFlags = 0;
2823  currentStackLocationFlags = RequestGetCurrentStackLocationFlags(Request);
2824 
2825  if ((status == STATUS_VERIFY_REQUIRED) &&
2826  (currentStackLocationFlags & SL_OVERRIDE_VERIFY_VOLUME))
2827  {
2828  //
2829  // If the status is verified required and this request
2830  // should bypass verify required then retry the request.
2831  //
2833  UNREFERENCED_PARAMETER(status); // disables prefast warning; defensive coding...
2834 
2836  }
2837  else
2838  {
2839  // Validation failed / forward failed, complete the request.
2840  RequestCompletion(deviceExtension, Request, status, dataLength);
2841  }
2842  }
2843 
2844  return processed;
2845 }
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
NTSTATUS RequestSetContextFields(_In_ WDFREQUEST Request, _In_ PSYNC_HANDLER Handler)
Definition: common.c:2748
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define FALSE
Definition: types.h:117
BOOLEAN RequestDispatchSyncWithSequentialQueue(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:2717
NTSTATUS RequestSynchronizeProcessWithSerialQueue(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
Definition: cdrom.c:3893
unsigned char BOOLEAN
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG dataLength
Definition: scsi.h:3751
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IOCTL_CDROM_EXCLUSIVE_ACCESS
Definition: ntddcdrm.h:85
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
__inline UCHAR RequestGetCurrentStackLocationFlags(_In_ WDFREQUEST Request)
Definition: cdrom.h:1554
EXCLUSIVE_ACCESS_REQUEST_TYPE RequestType
Definition: ntddcdrm.h:419
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:137
#define NULL
Definition: types.h:112
NTSTATUS RequestValidateExclusiveAccess(_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:2240
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
static int processed(const type_t *type)
Definition: typegen.c:2236
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by DeviceEvtIoInCallerContext(), and RequestDispatchSyncWithSequentialQueue().

◆ RequestDispatchToSequentialQueue()

BOOLEAN RequestDispatchToSequentialQueue ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters 
)

Definition at line 1855 of file cdrom.c.

1878 {
1881  size_t dataLength = 0;
1882  BOOLEAN inZeroPowerState = FALSE;
1883 
1884  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
1885  ULONG ioctlCode = RequestParameters.Parameters.DeviceIoControl.IoControlCode;
1886  PZERO_POWER_ODD_INFO zpoddInfo = deviceExtension->ZeroPowerODDInfo;
1887 
1888  if ((zpoddInfo != NULL) &&
1889  (zpoddInfo->InZeroPowerState != FALSE))
1890  {
1891  inZeroPowerState = TRUE;
1892  }
1893 
1894  switch (ioctlCode)
1895  {
1896 
1897  case IOCTL_CDROM_RAW_READ:
1898  {
1900 
1901  processed = TRUE;
1902  break;
1903  }
1904 
1907  {
1908  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
1909  "RequestDispatchToSequentialQueue: Get drive geometryEx\n"));
1910  if ( RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1912  {
1915  }
1916  else if (inZeroPowerState != FALSE)
1917  {
1919  }
1920  else
1921  {
1923  }
1924 
1925  processed = TRUE;
1926  break;
1927  }
1928 
1931  {
1932  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
1933  "RequestDispatchToSequentialQueue: Get drive geometry\n"));
1934  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1935  sizeof(DISK_GEOMETRY))
1936  {
1938  dataLength = sizeof(DISK_GEOMETRY);
1939  }
1940  else if (inZeroPowerState != FALSE)
1941  {
1943  }
1944  else
1945  {
1947  }
1948 
1949  processed = TRUE;
1950  break;
1951  }
1952 
1954  {
1956 
1957  if (inZeroPowerState != FALSE)
1958  {
1960  }
1961 
1962  processed = TRUE;
1963  break;
1964  }
1965 
1966  case IOCTL_CDROM_READ_TOC:
1967  {
1969 
1970  if (inZeroPowerState != FALSE)
1971  {
1973  }
1974 
1975  processed = TRUE;
1976  break;
1977  }
1978 
1980  {
1982 
1983  processed = TRUE;
1984  break;
1985  }
1986 
1988  {
1989  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
1990  "RequestDispatchToSequentialQueue: Play audio MSF\n"));
1991 
1992  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
1993  sizeof(CDROM_PLAY_AUDIO_MSF))
1994  {
1996  }
1997  else
1998  {
2000  }
2001 
2002  processed = TRUE;
2003  break;
2004  }
2005 
2007  {
2008  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2009  "RequestDispatchToSequentialQueue: Seek audio MSF\n"));
2010 
2011  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
2012  sizeof(CDROM_SEEK_AUDIO_MSF))
2013  {
2015  }
2016  else
2017  {
2019  }
2020 
2021  processed = TRUE;
2022  break;
2023  }
2024 
2026  {
2027  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2028  "RequestDispatchToSequentialQueue: Pause audio\n"));
2029 
2031  processed = TRUE;
2032  break;
2033  }
2034 
2036  {
2037  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2038  "RequestDispatchToSequentialQueue: Resume audio\n"));
2039 
2041  processed = TRUE;
2042  break;
2043  }
2044 
2046  {
2048 
2049  processed = TRUE;
2050  break;
2051  }
2052 
2054  {
2055  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2056  "RequestDispatchToSequentialQueue: Get volume control\n"));
2057 
2058  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
2059  sizeof(VOLUME_CONTROL))
2060  {
2062  dataLength = sizeof(VOLUME_CONTROL);
2063  }
2064  else
2065  {
2067  }
2068 
2069  processed = TRUE;
2070  break;
2071  }
2072 
2074  {
2075  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2076  "RequestDispatchToSequentialQueue: Set volume control\n"));
2077 
2078  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
2079  sizeof(VOLUME_CONTROL))
2080  {
2082  }
2083  else
2084  {
2086  }
2087 
2088  processed = TRUE;
2089  break;
2090  }
2091 
2093  {
2094  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2095  "RequestDispatchToSequentialQueue: Stop audio\n"));
2096 
2098  processed = TRUE;
2099  break;
2100  }
2101 
2104  {
2105  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2106  "RequestDispatchToSequentialQueue: [%p] Check Verify\n", Request));
2107 
2108  // Following check will let the condition "OutputBufferLength == 0" pass.
2109  // Since it's legacy behavior in classpnp, we need to keep it.
2110  if ((RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > 0) &&
2111  (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)))
2112  {
2114  dataLength = sizeof(ULONG);
2115  }
2116  else if (inZeroPowerState != FALSE)
2117  {
2119  }
2120  else
2121  {
2123  }
2124 
2125  processed = TRUE;
2126  break;
2127  }
2128 
2129  case IOCTL_DVD_GET_REGION:
2130  {
2131  // validation will be done when process it.
2133  processed = TRUE;
2134  break;
2135  }
2136 
2138  {
2139  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2140  "RequestDispatchToSequentialQueue: [%p] IOCTL_DVD_READ_STRUCTURE\n", Request));
2141 
2143 
2144  processed = TRUE;
2145  break;
2146  }
2147 
2148  case IOCTL_DVD_READ_KEY:
2149  {
2150  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2151  "RequestDispatchToSequentialQueue: [%p] IOCTL_DVD_READ_KEY\n", Request));
2152 
2154 
2155  processed = TRUE;
2156  break;
2157  }
2158 
2160  {
2161  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2162  "RequestDispatchToSequentialQueue: [%p] IOCTL_DVD_START_SESSION\n", Request));
2163 
2165 
2166  processed = TRUE;
2167  break;
2168  }
2169 
2170  case IOCTL_DVD_SEND_KEY:
2171  case IOCTL_DVD_SEND_KEY2:
2172  {
2173  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2174  "RequestDispatchToSequentialQueue: [%p] IOCTL_DVD_SEND_KEY\n", Request));
2175 
2177 
2178  processed = TRUE;
2179  break;
2180  }
2181 
2183  {
2184  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2185  "RequestDispatchToSequentialQueue: [%p] SetReadAhead\n", Request));
2186 
2187  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
2188  sizeof(STORAGE_SET_READ_AHEAD))
2189  {
2191  }
2192  else
2193  {
2195  }
2196 
2197  processed = TRUE;
2198  break;
2199  }
2200 
2202  {
2204 
2205  processed = TRUE;
2206  break;
2207  }
2208 
2210  {
2211  ULONG requiredSize = 0;
2212 
2213  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2214  "RequestDispatchToSequentialQueue: Get drive layout\n"));
2215 
2216  requiredSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[1]);
2217 
2218  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
2219  requiredSize)
2220  {
2222  dataLength = requiredSize;
2223  }
2224  else
2225  {
2227  }
2228 
2229  processed = TRUE;
2230  break;
2231  }
2232 
2234  {
2235  ULONG requiredSize = 0;
2236 
2237  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2238  "RequestDispatchToSequentialQueue: Get drive layoutEx\n"));
2239 
2240  requiredSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[1]);
2241 
2242  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
2243  requiredSize)
2244  {
2246  dataLength = requiredSize;
2247  }
2248  else
2249  {
2251  }
2252 
2253  processed = TRUE;
2254  break;
2255  }
2256 
2258  {
2259  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2260  "RequestDispatchToSequentialQueue: Get Partition Info\n"));
2261 
2262  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
2263  sizeof(PARTITION_INFORMATION))
2264  {
2267  }
2268  else
2269  {
2271  }
2272 
2273  processed = TRUE;
2274  break;
2275  }
2276 
2278  {
2279  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2280  "RequestDispatchToSequentialQueue: Get Partition InfoEx\n"));
2281 
2282  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
2283  sizeof(PARTITION_INFORMATION_EX))
2284  {
2287  }
2288  else
2289  {
2291  }
2292 
2293  processed = TRUE;
2294  break;
2295  }
2296 
2297  case IOCTL_DISK_VERIFY:
2298  {
2299  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2300  "RequestDispatchToSequentialQueue: IOCTL_DISK_VERIFY to device %p through request %p\n",
2301  Device,
2302  Request));
2303 
2304  if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
2305  sizeof(VERIFY_INFORMATION))
2306  {
2308  }
2309  else
2310  {
2312  }
2313 
2314  processed = TRUE;
2315  break;
2316  }
2317 
2319  {
2320  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2321  "RequestDispatchToSequentialQueue: Disk Get Length InfoEx\n"));
2322 
2323  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
2324  sizeof(GET_LENGTH_INFORMATION))
2325  {
2328  }
2329  else if (inZeroPowerState != FALSE)
2330  {
2332  }
2333  else
2334  {
2336  }
2337 
2338  processed = TRUE;
2339  break;
2340  }
2341 
2343  {
2344  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2345  "RequestDispatchToSequentialQueue: [%p] IOCTL_CDROM_GET_CONFIGURATION\n", Request));
2346 
2348 
2349  processed = TRUE;
2350  break;
2351  }
2352 
2353  case IOCTL_CDROM_SET_SPEED:
2354  {
2355  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2356  "RequestDispatchToSequentialQueue: [%p] IOCTL_CDROM_SET_SPEED\n", Request));
2357 
2359 
2360  processed = TRUE;
2361  break;
2362  }
2363 
2364  case IOCTL_DVD_END_SESSION:
2365  {
2366  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2367  "RequestDispatchToSequentialQueue: [%p] IOCTL_DVD_END_SESSION\n", Request));
2368 
2370 
2371  processed = TRUE;
2372  break;
2373  }
2374 
2376  {
2377  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2378  "RequestDispatchToSequentialQueue: [%p] IOCTL_AACS_END_SESSION\n", Request));
2379 
2381 
2382  processed = TRUE;
2383  break;
2384  }
2385 
2387  {
2388  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2389  "AACS: Querying full MKB with bufferSize of %x bytes\n",
2390  (int)RequestParameters.Parameters.DeviceIoControl.OutputBufferLength
2391  ));
2392 
2394 
2395  processed = TRUE;
2396  break;
2397  }
2398 
2400  {
2401  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2402  "AACS: Requesting AGID\n"
2403  ));
2404 
2406 
2407  processed = TRUE;
2408  break;
2409  }
2410 
2412  {
2413  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2414  "AACS: Sending host certificate to drive\n"
2415  ));
2416 
2418 
2419  processed = TRUE;
2420  break;
2421  }
2422 
2424  {
2425  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2426  "AACS: Querying drive certificate\n"
2427  ));
2428 
2430 
2431  processed = TRUE;
2432  break;
2433  }
2434 
2436  {
2437  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2438  "AACS: Querying drive challenge key\n"
2439  ));
2440 
2442 
2443  processed = TRUE;
2444  break;
2445  }
2446 
2448  {
2449  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2450  "AACS: Sending drive challenge key\n"
2451  ));
2452 
2454 
2455  processed = TRUE;
2456  break;
2457  }
2458 
2460  {
2461  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2462  "AACS: Reading volume ID\n"
2463  ));
2464 
2466 
2467  processed = TRUE;
2468  break;
2469  }
2470 
2472  {
2473  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2474  "AACS: Reading Serial Number\n"
2475  ));
2476 
2478 
2479  processed = TRUE;
2480  break;
2481  }
2482 
2484  {
2485  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2486  "AACS: Reading media ID\n"
2487  ));
2488 
2490 
2491  processed = TRUE;
2492  break;
2493  }
2494 
2497  {
2498  if (ioctlCode == IOCTL_AACS_GENERATE_BINDING_NONCE)
2499  {
2500  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2501  "AACS: Generating new binding nonce\n"
2502  ));
2503  }
2504  else
2505  {
2506  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
2507  "AACS: Reading existing binding nonce\n"
2508  ));
2509  }
2510 
2512 
2513  processed = TRUE;
2514  break;
2515  }
2516 
2518  {
2519  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2520  "RequestDispatchToSequentialQueue: [%p] IOCTL_CDROM_ENABLE_STREAMING\n", Request));
2521 
2523 
2524  processed = TRUE;
2525  break;
2526  }
2527 
2529  {
2530  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2531  "RequestDispatchToSequentialQueue: [%p] IOCTL_CDROM_SEND_OPC_INFORMATION\n", Request));
2532 
2534 
2535  processed = TRUE;
2536  break;
2537  }
2538 
2540  {
2541  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2542  "RequestDispatchToSequentialQueue: [%p] IOCTL_CDROM_GET_PERFORMANCE\n", Request));
2543 
2545 
2546  processed = TRUE;
2547  break;
2548  }
2549 
2552  {
2553  if(RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
2554  sizeof(PREVENT_MEDIA_REMOVAL))
2555  {
2557  }
2558  else
2559  {
2561  }
2562 
2563  processed = TRUE;
2564  break; // complete the irp
2565  }
2566 
2568  {
2569  if(RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
2570  sizeof(PREVENT_MEDIA_REMOVAL))
2571  {
2573  }
2574  else
2575  {
2577  }
2578 
2579  processed = TRUE;
2580  break; // complete the irp
2581  }
2582 
2583  case IOCTL_STORAGE_RESERVE:
2584  case IOCTL_STORAGE_RELEASE:
2585  {
2586  // there is no validate check currently.
2588  processed = TRUE;
2589  break;
2590  }
2591 
2594  {
2596 
2597  processed = TRUE;
2598  break;
2599  }
2600 
2604  {
2606 
2607  processed = TRUE;
2608  break; // complete the irp
2609  }
2610 
2612  {
2613  // process it.
2615 
2617 
2618  processed = TRUE;
2619  break; // complete the irp
2620  }
2621 
2623  {
2624  if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_READ_CAPACITY))
2625  {
2628  }
2629  else if (inZeroPowerState != FALSE)
2630  {
2632  }
2633  else
2634  {
2636  }
2637 
2638  processed = TRUE;
2639  break; // complete the irp
2640  }
2641 
2643  {
2644  // for disk.sys only in original classpnp
2646 
2647  processed = TRUE;
2648  break; // complete the irp
2649  }
2650 
2651 #if (NTDDI_VERSION >= NTDDI_WIN8)
2653  {
2654  // this request doesn't access device at all, so seemingly it can be processed
2655  // directly; however, in case volume online is not received, we will need to
2656  // park these requests in a queue, and the only way a request can be queued is
2657  // if the request came out of another queue.
2659 
2660  processed = TRUE;
2661  break;
2662  }
2663 
2664  case IOCTL_VOLUME_ONLINE:
2666  {
2668 
2669  processed = TRUE;
2670  break;
2671  }
2672 #endif
2673 
2674  default:
2675  {
2676  processed = FALSE;
2677  break;
2678  }
2679  } //end of switch (ioctlCode)
2680 
2681  if (processed)
2682  {
2683  UCHAR currentStackLocationFlags = 0;
2684  currentStackLocationFlags = RequestGetCurrentStackLocationFlags(Request);
2685 
2686  if ((status == STATUS_VERIFY_REQUIRED) &&
2687  (currentStackLocationFlags & SL_OVERRIDE_VERIFY_VOLUME))
2688  {
2689  // If the status is verified required and this request
2690  // should bypass verify required then retry the request.
2692  UNREFERENCED_PARAMETER(status); // disables prefast warning; defensive coding...
2693 
2695  }
2696  else
2697  {
2698  if (NT_SUCCESS(status))
2699  {
2700  // Forward the request to serialized queue.
2701  status = WdfDeviceEnqueueRequest(Device, Request);
2702  }
2703 
2704  if (!NT_SUCCESS(status))
2705  {
2706  // Validation failed / forward failed, complete the request.
2707  RequestCompletion(deviceExtension, Request, status, dataLength);
2708  }
2709  }
2710  }
2711 
2712  return processed;
2713 }
NTSTATUS RequestValidateAacsReadSerialNumber(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:2024
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define IOCTL_STORAGE_MCN_CONTROL
Definition: ntddstor.h:128
#define IOCTL_STORAGE_SET_READ_AHEAD
Definition: cdrw_usr.h:186
return STATUS_NOT_SUPPORTED
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
NTSTATUS RequestValidateAacsGetCertificate(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1757
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:104
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS RequestValidateReadToc(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:984
#define IOCTL_AACS_GET_CERTIFICATE
Definition: ntddcdvd.h:73
#define IOCTL_CDROM_GET_CONFIGURATION
Definition: ntddcdrm.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_STORAGE_PERSISTENT_RESERVE_OUT
Definition: ntddstor.h:172
NTSTATUS RequestValidateDvdReadKey(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:3286
#define IOCTL_AACS_START_SESSION
Definition: ntddcdvd.h:64
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:64
BOOLEAN RequestDispatchToSequentialQueue(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
Definition: cdrom.c:1855
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
#define IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT
Definition: ntddstor.h:196
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
BOOLEAN InZeroPowerState
Definition: cdromp.h:272
#define IOCTL_AACS_GENERATE_BINDING_NONCE
Definition: ntddcdvd.h:94
NTSTATUS RequestValidateGetLastSession(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1029
PDEVICE_OBJECT LowerPdo
Definition: cdrom.h:496
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
struct _PARTITION_INFORMATION PARTITION_INFORMATION
#define IOCTL_AACS_READ_MEDIA_ID
Definition: ntddcdvd.h:88
#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
#define IOCTL_CDROM_SET_VOLUME
Definition: ntddcdrm.h:55
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define IOCTL_STORAGE_FIND_NEW_DEVICES
Definition: ntddstor.h:122
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define FALSE
Definition: types.h:117
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
NTSTATUS RequestValidateReadQChannel(_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1072
NTSTATUS RequestValidateAacsSendCertificate(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1697
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:40
NTSTATUS RequestValidateAacsGetChallengeKey(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1826
#define IOCTL_STORAGE_EJECTION_CONTROL
Definition: ntddstor.h:125
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
NTSTATUS RequestValidateDvdStartSession(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1225
NTSTATUS RequestValidatePersistentReserve(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:6715
#define IOCTL_STORAGE_RELEASE
Definition: ntddstor.h:119
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
NTSTATUS RequestValidateAacsReadVolumeId(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1955
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:37
STORAGE_READ_CAPACITY
Definition: ntddstor.h:861
unsigned char BOOLEAN
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:52
#define IOCTL_DVD_END_SESSION
Definition: cdrw_usr.h:162
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
NTSTATUS RequestValidateEnableStreaming(_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:3515
NTSTATUS RequestValidateGetConfiguration(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1364
#define IOCTL_CDROM_ENABLE_STREAMING
Definition: ntddcdrm.h:94
NTSTATUS RequestValidateDvdSendKey(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1274
NTSTATUS RequestValidateAacsStartSession(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1651
#define IOCTL_STORAGE_RESERVE
Definition: ntddstor.h:116
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define IOCTL_AACS_GET_CHALLENGE_KEY
Definition: ntddcdvd.h:76
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98
NTSTATUS RequestValidateAacsSendChallengeKey(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1895
#define IOCTL_VOLUME_POST_ONLINE
Definition: volume.c:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IOCTL_STORAGE_PERSISTENT_RESERVE_IN
Definition: ntddstor.h:169
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:73
PZERO_POWER_ODD_INFO ZeroPowerODDInfo
Definition: cdrom.h:566
#define IOCTL_CDROM_GET_VOLUME
Definition: ntddcdrm.h:49
NTSTATUS RequestValidateSendOpcInformation(_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:3576
ULONG dataLength
Definition: scsi.h:3751
#define IOCTL_DVD_SEND_KEY
Definition: cdrw_usr.h:161
#define IOCTL_STORAGE_LOAD_MEDIA2
Definition: ntddk_ex.h:210
#define IOCTL_DISK_ARE_VOLUMES_READY
Definition: ntdddisk.h:46
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
#define IOCTL_AACS_READ_SERIAL_NUMBER
Definition: ntddcdvd.h:85
#define IOCTL_STORAGE_CHECK_VERIFY2
Definition: ntddk_ex.h:212
#define IOCTL_DVD_READ_KEY
Definition: cdrw_usr.h:160
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define IOCTL_CDROM_PAUSE_AUDIO
Definition: ntddcdrm.h:43
#define IOCTL_DVD_GET_REGION
Definition: cdrw_usr.h:164
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define IOCTL_AACS_END_SESSION
Definition: ntddcdvd.h:67
NTSTATUS RequestValidateGetPerformance(_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:3634
__inline UCHAR RequestGetCurrentStackLocationFlags(_In_ WDFREQUEST Request)
Definition: cdrom.h:1554
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define IOCTL_CDROM_RESUME_AUDIO
Definition: ntddcdrm.h:46
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:137
NTSTATUS RequestValidateSetSpeed(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1501
struct _DISK_GEOMETRY DISK_GEOMETRY
#define IOCTL_AACS_SEND_CERTIFICATE
Definition: ntddcdvd.h:70
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2486
#define IOCTL_AACS_READ_MEDIA_KEY_BLOCK
Definition: ntddcdvd.h:61
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
NTSTATUS RequestValidateAacsReadMediaKeyBlock(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1584
#define IOCTL_CDROM_READ_TOC_EX
Definition: ntddcdrm.h:79
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:110
#define NULL
Definition: types.h:112
NTSTATUS RequestValidateAacsBindingNonce(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:2162
NTSTATUS RequestValidateAacsEndSession(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:3462
#define IOCTL_DVD_SEND_KEY2
Definition: cdrw_usr.h:165
#define IOCTL_CDROM_GET_PERFORMANCE
Definition: ntddcdrm.h:100
#define IOCTL_AACS_READ_BINDING_NONCE
Definition: ntddcdvd.h:91
#define IOCTL_AACS_READ_VOLUME_ID
Definition: ntddcdvd.h:82
#define IOCTL_CDROM_SEND_OPC_INFORMATION
Definition: ntddcdrm.h:97
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
static int processed(const type_t *type)
Definition: typegen.c:2236
NTSTATUS RequestValidateDvdEndSession(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:3408
NTSTATUS RequestValidateReadTocEx(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:887
unsigned int ULONG
Definition: retypes.h:1
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
#define IOCTL_AACS_SEND_CHALLENGE_KEY
Definition: ntddcdvd.h:79
#define STATUS_SUCCESS
Definition: shellext.h:65
#define IOCTL_DVD_START_SESSION
Definition: cdrw_usr.h:159
#define IOCTL_CDROM_SET_SPEED
Definition: ntddcdrm.h:88
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:58
NTSTATUS RequestValidateDvdReadStructure(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:1151
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
NTSTATUS RequestValidateRawRead(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:650
struct _VOLUME_CONTROL VOLUME_CONTROL
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
#define IOCTL_STORAGE_READ_CAPACITY
Definition: ntddstor.h:175
NTSTATUS RequestValidateAacsReadMediaId(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: ioctl.c:2093
#define IOCTL_DVD_READ_STRUCTURE
Definition: cdrw_usr.h:157
Definition: ps.c:97

Referenced by DeviceEvtIoInCallerContext(), and RequestDispatchToSequentialQueue().

◆ RequestDispatchUnknownRequests()

BOOLEAN RequestDispatchUnknownRequests ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters 
)

Definition at line 3093 of file cdrom.c.

3118 {
3120  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
3121 
3123 
3124  if ((KeGetCurrentIrql() != PASSIVE_LEVEL) ||
3125  (baseCode == FILE_DEVICE_ACPI))
3126  {
3127  // 1. When IRQL is higher than PASSIVE_LEVEL,
3128  // 2. ataport sends IOCTL_ACPI_ASYNC_EVAL_METHOD before queue starts,
3129  // send request directly to lower driver.
3131  }
3132  else
3133  {
3134  // keep the request in serialized manner and stay in user's context.
3136 
3137  if (NT_SUCCESS(status))
3138  {
3140  }
3141  else
3142  {
3143  RequestCompletion(deviceExtension, Request, status, 0);
3144  }
3145  }
3146 
3147  UNREFERENCED_PARAMETER(status); //defensive coding, avoid PREFAST warning.
3148 
3149  // All unknown IOCTLs are processed in this function.
3150  return TRUE; //processed
3151 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
NTSTATUS RequestHandleUnknownIoctl(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
NTSTATUS RequestSetContextFields(_In_ WDFREQUEST Request, _In_ PSYNC_HANDLER Handler)
Definition: common.c:2748
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
NTSTATUS RequestSynchronizeProcessWithSerialQueue(_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
Definition: cdrom.c:3893
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:137
#define DEVICE_TYPE_FROM_CTL_CODE(c)
Definition: winioctl.h:176
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
#define FILE_DEVICE_ACPI
Definition: winioctl.h:155
unsigned int ULONG
Definition: retypes.h:1
Definition: ps.c:97

Referenced by DeviceEvtIoInCallerContext(), and RequestDispatchSpecialIoctls().

◆ RequestEvtCleanup()

VOID NTAPI RequestEvtCleanup ( _In_ WDFOBJECT  Request)

Definition at line 4215 of file cdrom.c.

4232 {
4233  WDFREQUEST request = (WDFREQUEST)Request;
4234  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(request);
4235 
4236  if (requestContext->SyncRequired)
4237  {
4238  // the event should have been signaled, just check that
4239  NT_ASSERT(KeReadStateEvent(requestContext->SyncEvent) != 0);
4240  }
4241 }
BOOLEAN SyncRequired
Definition: cdrom.h:643
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
Definition: tftpd.h:85
LONG NTAPI KeReadStateEvent(IN PKEVENT Event)
Definition: eventobj.c:120
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by DriverEvtDeviceAdd().

◆ RequestIsIoctlBlockedByExclusiveAccess()

NTSTATUS RequestIsIoctlBlockedByExclusiveAccess ( _In_ WDFREQUEST  Request,
_Out_ PBOOLEAN  IsBlocked 
)

Definition at line 4058 of file cdrom.c.

4079 {
4081  ULONG ioctlCode = 0;
4082  ULONG baseCode = 0;
4083  WDF_REQUEST_PARAMETERS requestParameters;
4084 
4085  // Get the Request parameters
4086  WDF_REQUEST_PARAMETERS_INIT(&requestParameters);
4087  WdfRequestGetParameters(Request, &requestParameters);
4088 
4089  // check and initialize parameter
4090  if (IsBlocked == NULL)
4091  {
4092  //This is an internal function and this parameter must be supplied.
4093  NT_ASSERT(FALSE);
4094 
4095  return STATUS_INVALID_PARAMETER;
4096  }
4097  else
4098  {
4099  *IsBlocked = FALSE;
4100  }
4101 
4102  // check if this is an IOCTL
4103  if ((requestParameters.Type == WdfRequestTypeDeviceControl) ||
4104  (requestParameters.Type == WdfRequestTypeDeviceControlInternal))
4105  {
4106  //
4107  // Allow minimum set of commands that are required for the disk manager
4108  // to show the CD device, while in exclusive mode.
4109  // Note: These commands should not generate any requests to the device,
4110  // and thus must be handled directly in StartIO during exclusive
4111  // access (except for the exclusive owner, of course).
4112  //
4113  ioctlCode = requestParameters.Parameters.DeviceIoControl.IoControlCode;
4114  baseCode = DEVICE_TYPE_FROM_CTL_CODE(ioctlCode);
4115 
4116  if (ioctlCode == IOCTL_SCSI_GET_ADDRESS ||
4117  ioctlCode == IOCTL_STORAGE_GET_HOTPLUG_INFO ||
4118  ioctlCode == IOCTL_STORAGE_GET_DEVICE_NUMBER ||
4119  ioctlCode == IOCTL_STORAGE_GET_MEDIA_TYPES_EX ||
4120  ioctlCode == IOCTL_CDROM_EXCLUSIVE_ACCESS ||
4121  ioctlCode == IOCTL_CDROM_GET_INQUIRY_DATA
4122  )
4123  {
4124  *IsBlocked = FALSE;
4125  }
4126 
4127  //
4128  // Handle IOCTL_STORAGE_QUERY_PROPERTY special because:
4129  // (1) PropertyExistsQuery should not generate device i/o
4130  // (2) Queries for StorageDeviceProperty and StorageAdapterDescriptor
4131  // will return cache'd data
4132  else if (ioctlCode == IOCTL_STORAGE_QUERY_PROPERTY)
4133  {
4135  status = WdfRequestRetrieveInputBuffer(Request,
4136  requestParameters.Parameters.DeviceIoControl.InputBufferLength,
4137  (PVOID*)&query,
4138  NULL);
4139 
4140  if (NT_SUCCESS(status))
4141  {
4142  if (query != NULL)
4143  {
4144  if (query->QueryType == PropertyExistsQuery)
4145  {
4146  *IsBlocked = FALSE;
4147  }
4148  else if ((query->QueryType == PropertyStandardQuery) &&
4149  ((query->PropertyId == StorageDeviceProperty) ||
4150  (query->PropertyId == StorageAdapterProperty)))
4151  {
4152  *IsBlocked = FALSE;
4153  }
4154  }
4155  }
4156  }
4157 
4158  // Return TRUE for unknown IOCTLs with STORAGE bases
4159  else if (baseCode == IOCTL_SCSI_BASE ||
4160  baseCode == IOCTL_DISK_BASE ||
4161  baseCode == IOCTL_CDROM_BASE ||
4162  baseCode == IOCTL_STORAGE_BASE ||
4163  baseCode == IOCTL_DVD_BASE )
4164  {
4165  *IsBlocked = TRUE;
4166  }
4167  }
4168  else
4169  {
4170  // this should only be called with an IOCTL
4171  NT_ASSERT(FALSE);
4172 
4174  }
4175 
4176  return status;
4177 }
#define IOCTL_DISK_BASE
Definition: ntdddisk.h:44
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
WDF_REQUEST_TYPE Type
Definition: wdfrequest.h:142
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define FALSE
Definition: types.h:117
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
#define IOCTL_DVD_BASE
Definition: ntddcdvd.h:32
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IOCTL_CDROM_EXCLUSIVE_ACCESS
Definition: ntddcdrm.h:85
#define IOCTL_CDROM_GET_INQUIRY_DATA
Definition: ntddcdrm.h:91
#define IOCTL_SCSI_BASE
Definition: scsi_port.h:37
#define NULL
Definition: types.h:112
#define DEVICE_TYPE_FROM_CTL_CODE(c)
Definition: winioctl.h:176
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
#define IOCTL_STORAGE_BASE
Definition: ntddstor.h:96
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by DeviceEvtIoInCallerContext(), RequestSynchronizeProcessWithSerialQueue(), and SequentialQueueEvtIoDeviceControl().

◆ RequestProcessInternalDeviceControl()

VOID RequestProcessInternalDeviceControl ( _In_ WDFREQUEST  Request,
_In_ PCDROM_DEVICE_EXTENSION  DeviceExtension 
)

Definition at line 3154 of file cdrom.c.

3173 {
3175  PIRP irp = NULL;
3176  PIO_STACK_LOCATION irpStack = NULL;
3177  PIO_STACK_LOCATION nextStack = NULL;
3178  BOOLEAN requestSent = FALSE;
3179 
3180  irp = WdfRequestWdmGetIrp(Request);
3181  irpStack = IoGetCurrentIrpStackLocation(irp);
3182  nextStack = IoGetNextIrpStackLocation(irp);
3183 
3184  // Set the parameters in the next stack location.
3185  nextStack->Parameters.Scsi.Srb = irpStack->Parameters.Scsi.Srb;
3186  nextStack->MajorFunction = IRP_MJ_SCSI;
3187  nextStack->MinorFunction = IRP_MN_SCSI_CLASS;
3188 
3189  WdfRequestSetCompletionRoutine(Request, RequestDummyCompletionRoutine, NULL);
3190 
3191  status = RequestSend(DeviceExtension,
3192  Request,
3193  DeviceExtension->IoTarget,
3194  0,
3195  &requestSent);
3196 
3197  // send the request straight down (asynchronously)
3198  if (!requestSent)
3199  {
3200  // fail the request
3201  RequestCompletion(DeviceExtension, Request, status, WdfRequestGetInformation(Request));
3202  }
3203 
3204  return;
3205 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS RequestSend(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDFIOTARGET IoTarget, _In_ ULONG Flags, _Out_opt_ PBOOLEAN RequestSent)
Definition: common.c:3793
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
EVT_WDF_REQUEST_COMPLETION_ROUTINE RequestDummyCompletionRoutine
Definition: cdrom.h:1608
#define IRP_MJ_SCSI
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
#define IRP_MN_SCSI_CLASS
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
FxIrp * irp
Definition: ps.c:97

Referenced by DeviceEvtIoInCallerContext().

◆ RequestSynchronizeProcessWithSerialQueue()

NTSTATUS RequestSynchronizeProcessWithSerialQueue ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request 
)

Definition at line 3893 of file cdrom.c.

3916 {
3918  PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
3919  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
3920  PKEVENT bufferToFree = requestContext->SyncEvent;
3921 
3922  if (KeGetCurrentIrql() >= DISPATCH_LEVEL) {
3923  // cannot block at or above DISPATCH_LEVEL
3924  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
3925  "RequestSynchronousProcessWithSerialQueue called at DISPATCH_LEVEL or above"));
3926  NT_ASSERT(FALSE);
3927  RequestCompletion(deviceExtension, Request, STATUS_INVALID_LEVEL, 0);
3928  return STATUS_INVALID_LEVEL;
3929  }
3930 
3931  // init the synchronization event
3933 
3934  // do we still need to do something like this?
3935  // SET_FLAG(nextStack->Flags, SL_OVERRIDE_VERIFY_VOLUME);
3936 
3937  // NOTE: this mechanism relies on that KMDF will not complete request by itself.
3938  // Doing that will cause the syncEvent not fired thus this thread will stuck.
3939  // This should not really happen: our EvtCanceledOnQueue callbacks should be
3940  // called even if queues are purged for some reason. The only case when these
3941  // callbacks are not called is when a request is owned by the driver (i.e. has
3942  // already been passed to one of the registered handlers). In this case, it is
3943  // our responsibility to cancel such requests properly.
3944  status = WdfDeviceEnqueueRequest(Device, Request);
3945 
3946  if (!NT_SUCCESS(status))
3947  {
3948  // Failed to forward request! Pretend the sync event already occured, otherwise we'll hit
3949  // an assert in RequestEvtCleanup.
3950  KeSetEvent(requestContext->SyncEvent, IO_CD_ROM_INCREMENT, FALSE);
3951  RequestCompletion(deviceExtension, Request, status, WdfRequestGetInformation(Request));
3952  }
3953  else
3954  {
3955  NTSTATUS waitStatus = STATUS_UNSUCCESSFUL;
3956  PCDROM_DATA cdData = &(deviceExtension->DeviceAdditionalData);
3957  BOOLEAN fCallSyncCallback = FALSE;
3958  PIRP irp = WdfRequestWdmGetIrp(Request);
3959 
3960  // ok, now wait on the event
3961  while (waitStatus != STATUS_SUCCESS)
3962  {
3963  waitStatus = KeWaitForSingleObject(requestContext->SyncEvent, Executive, KernelMode, TRUE, NULL);
3964  if (waitStatus == STATUS_SUCCESS) // must check equality -- STATUS_ALERTED is success code
3965  {
3966  // do nothing
3967  }
3968  else if (waitStatus != STATUS_ALERTED)
3969  {
3970  // do nothing
3971  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_IOCTL,
3972  "Request %p on device object %p had a non-alert, non-success result from wait (%!HRESULT!)\n",
3973  Request, Device, waitStatus));
3974  NT_ASSERT(FALSE);
3975  }
3977  {
3978  // the thread was alerted and is terminating, so cancel the irp
3979  // this will cause EvtIoCanceledOnQueue to be called, which will signal the event,
3980  // so we will get out of the while loop and eventually complete the request.
3981  if (IoCancelIrp(irp))
3982  {
3983  // cancellation routine was called
3984  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
3985  "Sychronize Ioctl: request %p cancelled from device %p\n",
3986  Request, Device));
3987  }
3988  else
3989  {
3990  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
3991  "Sychronize Ioctl: request %p could not be cancelled from device %p\n",
3992  Request, Device));
3993  }
3994  }
3995  else
3996  {
3997  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
3998  "SPURIOUS ALERT waiting for Request %p on device %p (%!STATUS!)\n",
3999  Request, Device, status));
4000  }
4001  } // end of wait loop on the event
4002 
4003  // because we've waited an unknown amount of time, should check
4004  // the cancelled flag to immediately fail the irp as appropriate
4005  if (WdfRequestIsCanceled(Request))
4006  {
4007  // the request was cancelled, thus we should always stop
4008  // processing here if possible.
4010  RequestCompletion(deviceExtension, Request, status, 0);
4011  }
4012  else if (EXCLUSIVE_MODE(cdData) && !EXCLUSIVE_OWNER(cdData, WdfRequestGetFileObject(Request)))
4013  {
4014  WDF_REQUEST_PARAMETERS requestParameters;
4015  BOOLEAN isBlocked = FALSE;
4016 
4017  // get the request parameters
4018  WDF_REQUEST_PARAMETERS_INIT(&requestParameters);
4019  WdfRequestGetParameters(Request, &requestParameters);
4020 
4022  if (isBlocked)
4023  {
4024  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
4025  "Access Denied! Device in exclusive mode.Failing Ioctl %lx\n",
4026  requestParameters.Parameters.DeviceIoControl.IoControlCode));
4027  RequestCompletion(deviceExtension, Request, STATUS_ACCESS_DENIED, 0);
4028  }
4029  else
4030  {
4031  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
4032  "Ioctl %lx not blocked by cdrom being in exclusive mode\n",
4033  requestParameters.Parameters.DeviceIoControl.IoControlCode));
4034  fCallSyncCallback = TRUE;
4035  }
4036  }
4037  else
4038  {
4039  fCallSyncCallback = TRUE;
4040  }
4041 
4042  if (fCallSyncCallback)
4043  {
4044  // Synchronization completed successfully. Call the requested routine
4045  status = requestContext->SyncCallback(Device, Request);
4046  }
4047  }
4048 
4049  // The next SequentialQueue evt routine will not be triggered until the current request is completed.
4050 
4051  // clean up the request context setting.
4052  FREE_POOL(bufferToFree);
4053 
4054  return status;
4055 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define TRUE
Definition: types.h:120
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
NTSTATUS RequestIsIoctlBlockedByExclusiveAccess(_In_ WDFREQUEST Request, _Out_ PBOOLEAN IsBlocked)
Definition: cdrom.c:4058
LONG NTSTATUS
Definition: precomp.h:26
struct _WDF_REQUEST_PARAMETERS::@3696::@3700 DeviceIoControl
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_ALERTED
Definition: ntstatus.h:80
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
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
PSYNC_HANDLER SyncCallback
Definition: cdrom.h:645
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
unsigned char BOOLEAN
#define STATUS_INVALID_LEVEL
Definition: ntstatus.h:564
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define EXCLUSIVE_MODE(_CdData)
Definition: cdrom.h:788
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define EXCLUSIVE_OWNER(_CdData, _FileObject)
Definition: cdrom.h:789
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define IO_CD_ROM_INCREMENT
Definition: iotypes.h:582
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NULL
Definition: types.h:112
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
union _WDF_REQUEST_PARAMETERS::@3696 Parameters
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
static SERVICE_STATUS status
Definition: service.c:31
FxIrp * irp
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by RequestDispatchSpecialIoctls(), RequestDispatchSyncWithSequentialQueue(), and RequestDispatchUnknownRequests().

◆ SequentialQueueEvtCanceledOnQueue()

VOID NTAPI SequentialQueueEvtCanceledOnQueue ( _In_ WDFQUEUE  Queue,
_In_ WDFREQUEST  Request 
)

Definition at line 3848 of file cdrom.c.

3870 {
3871  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
3872 
3873  if (requestContext->SyncRequired)
3874  {
3875  KeSetEvent(requestContext->SyncEvent, IO_CD_ROM_INCREMENT, FALSE);
3876  }
3877  else
3878  {
3879  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
3880  WDFDEVICE device = WdfIoQueueGetDevice(Queue);
3881 
3882  deviceExtension = DeviceGetExtension(device);
3883 
3884  RequestCompletion(deviceExtension, Request, STATUS_CANCELLED, 0);
3885 
3886  }
3887 
3888  return;
3889 }
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
BOOLEAN SyncRequired
Definition: cdrom.h:643
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define FALSE
Definition: types.h:117
Definition: devices.h:37
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define IO_CD_ROM_INCREMENT
Definition: iotypes.h:582
#define NULL
Definition: types.h:112

Referenced by DriverEvtDeviceAdd().

◆ SequentialQueueEvtIoDeviceControl()

VOID NTAPI SequentialQueueEvtIoDeviceControl ( _In_ WDFQUEUE  Queue,
_In_ WDFREQUEST  Request,