ReactOS 0.4.16-dev-329-g9223134
ioctl.c File Reference
#include "stddef.h"
#include "string.h"
#include "ntddk.h"
#include "ntddstor.h"
#include "cdrom.h"
#include "ioctl.h"
#include "scratch.h"
#include "mmc.h"
Include dependency graph for ioctl.c:

Go to the source code of this file.

Macros

#define FirstDriveLetter   'C'
 
#define LastDriveLetter   'Z'
 

Functions

 _IRQL_requires_max_ (APC_LEVEL)
 
NTSTATUS RequestHandleGetInquiryData (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleGetMediaTypeEx (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateRawRead (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateReadTocEx (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateReadToc (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateGetLastSession (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateReadQChannel (_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateDvdReadStructure (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateDvdStartSession (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateDvdSendKey (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateGetConfiguration (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateSetSpeed (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsReadMediaKeyBlock (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsStartSession (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsSendCertificate (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsGetCertificate (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsGetChallengeKey (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsSendChallengeKey (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsReadVolumeId (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsReadSerialNumber (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsReadMediaId (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsBindingNonce (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateExclusiveAccess (_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleQueryPropertyRetrieveCachedData (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleQueryPropertyDeviceUniqueId (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
 
NTSTATUS RequestHandleQueryPropertyWriteCache (_In_ WDFDEVICE Device, _In_ WDFREQUEST Request)
 
NTSTATUS RequestValidateDvdReadKey (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateDvdEndSession (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateAacsEndSession (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateEnableStreaming (_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateSendOpcInformation (_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestValidateGetPerformance (_In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleMountQueryUniqueId (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleMountQueryDeviceName (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleMountQuerySuggestedLinkName (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
 _IRQL_requires_max_ (PASSIVE_LEVEL)
 
NTSTATUS RequestHandleGetDeviceNumber (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleGetHotPlugInfo (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestHandleSetHotPlugInfo (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
BOOLEAN RequestIsRealtimeStreaming (_In_ WDFREQUEST Request, _In_ BOOLEAN IsReadRequest)
 
NTSTATUS RequestValidateReadWrite (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
 
NTSTATUS RequestHandleReadWrite (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters)
 
static BOOLEAN ValidPersistentReserveScope (UCHAR Scope)
 
static BOOLEAN ValidPersistentReserveType (UCHAR Type)
 
NTSTATUS RequestValidatePersistentReserve (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 

Macro Definition Documentation

◆ FirstDriveLetter

#define FirstDriveLetter   'C'

Definition at line 40 of file ioctl.c.

◆ LastDriveLetter

#define LastDriveLetter   'Z'

Definition at line 41 of file ioctl.c.

Function Documentation

◆ _IRQL_requires_max_() [1/2]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 54 of file ioctl.c.

148{
150 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
151 PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
152 BOOLEAN syncRequired = requestContext->SyncRequired;
153
154 ULONG sendOptionsFlags = 0;
155 BOOLEAN requestSent = FALSE;
156
157 WdfRequestFormatRequestUsingCurrentType(Request);
158
159 if (syncRequired)
160 {
161 sendOptionsFlags = WDF_REQUEST_SEND_OPTION_SYNCHRONOUS;
162 }
163 else
164 {
165 WdfRequestSetCompletionRoutine(Request, RequestDummyCompletionRoutine, NULL);
166 }
167
168 status = RequestSend(deviceExtension,
169 Request,
170 deviceExtension->IoTarget,
171 sendOptionsFlags,
172 &requestSent);
173
174 if (requestSent)
175 {
176 if (syncRequired)
177 {
178 // the request needs to be completed here.
179 RequestCompletion(deviceExtension, Request, status, WdfRequestGetInformation(Request));
180 }
181 }
182 else
183 {
184 // failed to send the request to IoTarget
185 RequestCompletion(deviceExtension, Request, status, WdfRequestGetInformation(Request));
186 }
187
188 return status;
189}
unsigned char BOOLEAN
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
EVT_WDF_REQUEST_COMPLETION_ROUTINE RequestDummyCompletionRoutine
Definition: cdrom.h:1608
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
WDFIOTARGET IoTarget
Definition: cdrom.h:476
BOOLEAN SyncRequired
Definition: cdrom.h:643
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
@ WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
Definition: wdfrequest.h:109

◆ _IRQL_requires_max_() [2/2]

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Definition at line 4831 of file ioctl.c.

4862{
4864 VOID* outputBuffer = NULL;
4865
4866 PAGED_CODE ();
4867
4868 *DataLength = 0;
4869
4870 status = WdfRequestRetrieveOutputBuffer(Request,
4871 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
4872 &outputBuffer,
4873 NULL);
4874
4875 // Issue ReadCapacity to update device extension
4876 // with information for current media.
4877 if (NT_SUCCESS(status))
4878 {
4879 status = MediaReadCapacity(DeviceExtension->Device);
4880 }
4881
4882 if (NT_SUCCESS(status))
4883 {
4884 switch(RequestParameters.Parameters.DeviceIoControl.IoControlCode)
4885 {
4887 {
4888 PGET_LENGTH_INFORMATION lengthInfo = (PGET_LENGTH_INFORMATION)outputBuffer;
4889
4890 lengthInfo->Length = DeviceExtension->PartitionLength;
4892 break;
4893 }
4896 {
4897 PDISK_GEOMETRY geometry = (PDISK_GEOMETRY)outputBuffer;
4898
4899 *geometry = DeviceExtension->DiskGeometry;
4900 *DataLength = sizeof(DISK_GEOMETRY);
4901 break;
4902 }
4905 {
4906 PDISK_GEOMETRY_EX geometryEx = (PDISK_GEOMETRY_EX)outputBuffer;
4907
4908 geometryEx->DiskSize = DeviceExtension->PartitionLength;
4909 geometryEx->Geometry = DeviceExtension->DiskGeometry;
4911 break;
4912 }
4914 {
4915 PSTORAGE_READ_CAPACITY readCapacity = (PSTORAGE_READ_CAPACITY)outputBuffer;
4916
4917 readCapacity->Version = sizeof(STORAGE_READ_CAPACITY);
4918 readCapacity->Size = sizeof(STORAGE_READ_CAPACITY);
4919
4920 readCapacity->BlockLength = DeviceExtension->DiskGeometry.BytesPerSector;
4921 if (readCapacity->BlockLength > 0)
4922 {
4923 readCapacity->NumberOfBlocks.QuadPart = DeviceExtension->PartitionLength.QuadPart/readCapacity->BlockLength;
4924 }
4925 else
4926 {
4927 readCapacity->NumberOfBlocks.QuadPart = 0;
4928 }
4929
4930 readCapacity->DiskLength = DeviceExtension->PartitionLength;
4931
4933 break;
4934 }
4935 default:
4936 {
4938 break;
4939 }
4940 } // end of switch()
4941 }
4942
4943 return status;
4944}
#define PAGED_CODE()
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:138
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
struct _GET_LENGTH_INFORMATION * PGET_LENGTH_INFORMATION
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX
Definition: ntddcdrm.h:76
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:73
struct _DISK_GEOMETRY DISK_GEOMETRY
struct _DISK_GEOMETRY * PDISK_GEOMETRY
STORAGE_READ_CAPACITY
Definition: ntddstor.h:861
#define IOCTL_STORAGE_READ_CAPACITY
Definition: ntddstor.h:175
* PSTORAGE_READ_CAPACITY
Definition: ntddstor.h:861
struct _DISK_GEOMETRY_EX * PDISK_GEOMETRY_EX
#define STATUS_SUCCESS
Definition: shellext.h:65
DISK_GEOMETRY Geometry
Definition: winioctl.h:330
LARGE_INTEGER DiskSize
Definition: winioctl.h:331
LARGE_INTEGER Length
Definition: imports.h:232
union _WDF_REQUEST_PARAMETERS::@3883 Parameters
struct _WDF_REQUEST_PARAMETERS::@3883::@3887 DeviceIoControl
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NT_ASSERT
Definition: rtlfuncs.h:3327

◆ RequestHandleGetDeviceNumber()

NTSTATUS RequestHandleGetDeviceNumber ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 5280 of file ioctl.c.

5304{
5306
5307 *DataLength = 0;
5308
5309 if(RequestParameters.Parameters.DeviceIoControl.OutputBufferLength >=
5310 sizeof(STORAGE_DEVICE_NUMBER))
5311 {
5312 PSTORAGE_DEVICE_NUMBER deviceNumber = NULL;
5313 status = WdfRequestRetrieveOutputBuffer(Request,
5314 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
5315 &deviceNumber,
5316 NULL);
5317 if (NT_SUCCESS(status))
5318 {
5319 deviceNumber->DeviceType = DeviceExtension->DeviceObject->DeviceType;
5320 deviceNumber->DeviceNumber = DeviceExtension->DeviceNumber;
5321 deviceNumber->PartitionNumber = (ULONG)-1; // legacy reason, return (-1) for this IOCTL.
5322
5325 }
5326 }
5327 else
5328 {
5331 }
5332
5333 return status;
5334}
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
DEVICE_TYPE DeviceType
Definition: ntddstor.h:324

Referenced by RequestDispatchProcessDirectly().

◆ RequestHandleGetHotPlugInfo()

NTSTATUS RequestHandleGetHotPlugInfo ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 5337 of file ioctl.c.

5361{
5363
5364 *DataLength = 0;
5365
5366 if(RequestParameters.Parameters.DeviceIoControl.OutputBufferLength >=
5367 sizeof(STORAGE_HOTPLUG_INFO))
5368 {
5370 status = WdfRequestRetrieveOutputBuffer(Request,
5371 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
5372 &info,
5373 NULL);
5374 if (NT_SUCCESS(status))
5375 {
5376 *info = DeviceExtension->PrivateFdoData->HotplugInfo;
5377
5380 }
5381 }
5382 else
5383 {
5386 }
5387
5388 return status;
5389}
struct _STORAGE_HOTPLUG_INFO STORAGE_HOTPLUG_INFO

Referenced by RequestDispatchProcessDirectly().

◆ RequestHandleGetInquiryData()

NTSTATUS RequestHandleGetInquiryData ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 270 of file ioctl.c.

293{
295 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
296
297 *DataLength = 0;
298
299 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength == 0)
300 {
302 }
303 else
304 {
305 PVOID outputBuffer = NULL;
306
308 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength);
309
310 status = WdfRequestRetrieveOutputBuffer(Request,
312 &outputBuffer,
313 NULL);
314
315 if (NT_SUCCESS(status) &&
316 (outputBuffer != NULL))
317 {
318 // Always copy as much data as possible
319 RtlCopyMemory(outputBuffer,
320 cdData->CachedInquiryData,
321 *DataLength);
322 }
323
324 // and finally decide between two possible status values
326 {
328 }
329 }
330
331 return status;
332}
#define min(a, b)
Definition: monoChain.cc:55
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
ULONG CachedInquiryDataByteCount
Definition: cdrom.h:392
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by RequestDispatchProcessDirectly().

◆ RequestHandleGetMediaTypeEx()

NTSTATUS RequestHandleGetMediaTypeEx ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_Out_ size_t DataLength 
)

Definition at line 336 of file ioctl.c.

358{
360 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
361
362 PGET_MEDIA_TYPES mediaTypes = NULL;
363 PDEVICE_MEDIA_INFO mediaInfo = NULL; //&mediaTypes->MediaInfo[0];
364 ULONG sizeNeeded = 0;
365 PZERO_POWER_ODD_INFO zpoddInfo = DeviceExtension->ZeroPowerODDInfo;
366
367 *DataLength = 0;
368
369 // Must run below dispatch level.
371 {
374 }
375
376 sizeNeeded = sizeof(GET_MEDIA_TYPES);
377
378 // IsMmc is static...
379 if (cdData->Mmc.IsMmc)
380 {
381 sizeNeeded += sizeof(DEVICE_MEDIA_INFO) * 1; // return two media types
382 }
383
384 status = WdfRequestRetrieveOutputBuffer(Request,
385 sizeNeeded,
386 (PVOID*)&mediaTypes,
387 NULL);
388
389 if (NT_SUCCESS(status) &&
390 (mediaTypes != NULL))
391 {
392 mediaInfo = &mediaTypes->MediaInfo[0];
393
394 RtlZeroMemory(mediaTypes, sizeNeeded);
395
396 // ISSUE-2000/5/11-henrygab - need to update GET_MEDIA_TYPES_EX
397
398 mediaTypes->DeviceType = cdData->DriveDeviceType;
399
400 mediaTypes->MediaInfoCount = 1;
401 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = CD_ROM;
402 mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
403 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_ONLY;
404 mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = DeviceExtension->DiskGeometry.Cylinders.QuadPart;
405 mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = DeviceExtension->DiskGeometry.TracksPerCylinder;
406 mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = DeviceExtension->DiskGeometry.SectorsPerTrack;
407 mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = DeviceExtension->DiskGeometry.BytesPerSector;
408
409 if (cdData->Mmc.IsMmc)
410 {
411 // also report a removable disk
412 mediaTypes->MediaInfoCount += 1;
413
414 mediaInfo++;
415 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = RemovableMedia;
416 mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
417 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_WRITE;
418 mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = DeviceExtension->DiskGeometry.Cylinders.QuadPart;
419 mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = DeviceExtension->DiskGeometry.TracksPerCylinder;
420 mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = DeviceExtension->DiskGeometry.SectorsPerTrack;
421 mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = DeviceExtension->DiskGeometry.BytesPerSector;
422 mediaInfo--;
423
424 }
425
426 // Status will either be success, if media is present, or no media.
427 // It would be optimal to base from density code and medium type, but not all devices
428 // have values for these fields.
429
430 // Send a TUR to determine if media is present, only if the device is not in ZPODD mode.
431 if ((!EXCLUSIVE_MODE(cdData) ||
432 EXCLUSIVE_OWNER(cdData, WdfRequestGetFileObject(Request))) &&
433 ((zpoddInfo == NULL) ||
434 (zpoddInfo->InZeroPowerState == FALSE)))
435 {
437 PCDB cdb = (PCDB)srb.Cdb;
438
439 RtlZeroMemory(&srb,sizeof(SCSI_REQUEST_BLOCK));
440
441 srb.CdbLength = 6;
442 cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
443
445
446 status = DeviceSendSrbSynchronously(DeviceExtension->Device,
447 &srb,
448 NULL,
449 0,
450 FALSE,
451 Request);
452
453 if (NT_SUCCESS(status))
454 {
455 // set the disk's media as current if we can write to it.
456 if (cdData->Mmc.IsMmc && cdData->Mmc.WriteAllowed)
457 {
458 mediaInfo++;
459 SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics,
461 mediaInfo--;
462 }
463 else
464 {
465 SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics,
467 }
468 }
469 else
470 {
471 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
472 "RequestHandleGetMediaTypeEx: GET_MEDIA_TYPES status of TUR - %lx\n", status));
473 }
474 }
475
476 // per legacy cdrom behavior, always return success
478 }
479
480 *DataLength = sizeNeeded;
481
482 return status;
483}
#define CDROM_TEST_UNIT_READY_TIMEOUT
Definition: cdrom.h:128
#define EXCLUSIVE_OWNER(_CdData, _FileObject)
Definition: cdrom.h:789
#define EXCLUSIVE_MODE(_CdData)
Definition: cdrom.h:788
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
union _CDB * PCDB
@ CD_ROM
Definition: cdrw_usr.h:240
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define MEDIA_CURRENTLY_MOUNTED
Definition: minitape.h:36
#define MEDIA_READ_WRITE
Definition: minitape.h:34
#define MEDIA_READ_ONLY
Definition: minitape.h:33
@ RemovableMedia
Definition: ntdddisk.h:382
struct _DEVICE_MEDIA_INFO DEVICE_MEDIA_INFO
struct _GET_MEDIA_TYPES GET_MEDIA_TYPES
#define STATUS_INVALID_LEVEL
Definition: ntstatus.h:564
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:341
DEVICE_TYPE DriveDeviceType
Definition: cdrom.h:388
BOOLEAN WriteAllowed
Definition: cdrom.h:250
union _DEVICE_MEDIA_INFO::@3165 DeviceSpecific
struct _DEVICE_MEDIA_INFO::@3165::@3167 RemovableDiskInfo
ULONG DeviceType
Definition: ntddstor.h:494
DEVICE_MEDIA_INFO MediaInfo[1]
Definition: ntddstor.h:496
ULONG MediaInfoCount
Definition: ntddstor.h:495
ULONG TimeOutValue
Definition: srb.h:262
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
BOOLEAN InZeroPowerState
Definition: cdromp.h:272
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
Definition: cdrw_hw.h:28
struct _CDB::_CDB6GENERIC CDB6GENERIC

Referenced by RequestDispatchProcessDirectly().

◆ RequestHandleMountQueryDeviceName()

NTSTATUS RequestHandleMountQueryDeviceName ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 4015 of file ioctl.c.

4039{
4042
4043 *DataLength = 0;
4044
4045 NT_ASSERT(DeviceExtension->DeviceName.Buffer);
4046
4047 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME))
4048 {
4050 *DataLength = sizeof(MOUNTDEV_NAME);
4051 }
4052
4053 if (NT_SUCCESS(status))
4054 {
4055 status = WdfRequestRetrieveOutputBuffer(Request,
4056 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
4057 &name,
4058 NULL);
4059 }
4060
4061 if (NT_SUCCESS(status))
4062 {
4064 name->NameLength = DeviceExtension->DeviceName.Length;
4065
4066 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
4067 (sizeof(USHORT) + DeviceExtension->DeviceName.Length))
4068 {
4070 *DataLength = sizeof(MOUNTDEV_NAME);
4071 }
4072 }
4073
4074 if (NT_SUCCESS(status))
4075 {
4076 RtlCopyMemory(name->Name,
4077 DeviceExtension->DeviceName.Buffer,
4078 name->NameLength);
4079
4081 *DataLength = sizeof(USHORT) + name->NameLength;
4082 }
4083
4084 return status;
4085}
struct _MOUNTDEV_NAME MOUNTDEV_NAME
unsigned short USHORT
Definition: pedump.c:61
Definition: name.c:39

Referenced by RequestDispatchProcessDirectly().

◆ RequestHandleMountQuerySuggestedLinkName()

NTSTATUS RequestHandleMountQuerySuggestedLinkName ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 4088 of file ioctl.c.

4112{
4114
4115 PMOUNTDEV_SUGGESTED_LINK_NAME suggestedName = NULL;
4116
4117 WCHAR driveLetterNameBuffer[10] = {0};
4118 RTL_QUERY_REGISTRY_TABLE queryTable[2] = {0};
4119 PWSTR valueName = NULL;
4120 UNICODE_STRING driveLetterName = {0};
4121
4122 *DataLength = 0;
4123
4124 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
4126 {
4129 }
4130
4131 if (NT_SUCCESS(status))
4132 {
4133 valueName = ExAllocatePoolWithTag(PagedPool,
4134 DeviceExtension->DeviceName.Length + sizeof(WCHAR),
4136 if (valueName == NULL)
4137 {
4139 }
4140 }
4141
4142 if (NT_SUCCESS(status))
4143 {
4144 RtlCopyMemory(valueName,
4145 DeviceExtension->DeviceName.Buffer,
4146 DeviceExtension->DeviceName.Length);
4147 valueName[DeviceExtension->DeviceName.Length/sizeof(WCHAR)] = 0;
4148
4149 driveLetterName.Buffer = driveLetterNameBuffer;
4150 driveLetterName.MaximumLength = sizeof(driveLetterNameBuffer);
4151 driveLetterName.Length = 0;
4152
4154 queryTable[0].Name = valueName;
4155 queryTable[0].EntryContext = &driveLetterName;
4157
4159 L"\\Registry\\Machine\\System\\DISK", // why hard coded?
4160 queryTable, NULL, NULL);
4161 }
4162
4163 if (NT_SUCCESS(status))
4164 {
4165 if ((driveLetterName.Length == 4) &&
4166 (driveLetterName.Buffer[0] == '%') &&
4167 (driveLetterName.Buffer[1] == ':'))
4168 {
4169 driveLetterName.Buffer[0] = 0xFF;
4170 }
4171 else if ((driveLetterName.Length != 4) ||
4172 (driveLetterName.Buffer[0] < FirstDriveLetter) ||
4173 (driveLetterName.Buffer[0] > LastDriveLetter) ||
4174 (driveLetterName.Buffer[1] != ':'))
4175 {
4177 }
4178 }
4179
4180 if (NT_SUCCESS(status))
4181 {
4182 status = WdfRequestRetrieveOutputBuffer(Request,
4183 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
4184 &suggestedName,
4185 NULL);
4186 }
4187
4188 if (NT_SUCCESS(status))
4189 {
4190 RtlZeroMemory(suggestedName, RequestParameters.Parameters.DeviceIoControl.OutputBufferLength);
4191 suggestedName->UseOnlyIfThereAreNoOtherLinks = TRUE;
4192 suggestedName->NameLength = 28;
4193
4195
4196 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < *DataLength)
4197 {
4200 }
4201 }
4202
4203 if (NT_SUCCESS(status))
4204 {
4206 L"\\Registry\\Machine\\System\\DISK",
4207 valueName);
4208
4209 RtlCopyMemory(suggestedName->Name, L"\\DosDevices\\", 24);
4210 suggestedName->Name[12] = driveLetterName.Buffer[0];
4211 suggestedName->Name[13] = ':';
4212 }
4213
4214 FREE_POOL(valueName);
4215
4216 return status;
4217}
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define CDROM_TAG_STRINGS
Definition: cdrom.h:743
#define TRUE
Definition: types.h:120
#define LastDriveLetter
Definition: ioctl.c:41
#define FirstDriveLetter
Definition: ioctl.c:40
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define REG_SZ
Definition: layer.c:22
struct _MOUNTDEV_SUGGESTED_LINK_NAME MOUNTDEV_SUGGESTED_LINK_NAME
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_NONE
Definition: nt_native.h:1492
#define L(x)
Definition: ntvdm.h:50
#define STATUS_NOT_FOUND
Definition: shellext.h:72
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define RTL_QUERY_REGISTRY_TYPECHECK
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by RequestDispatchProcessDirectly().

◆ RequestHandleMountQueryUniqueId()

NTSTATUS RequestHandleMountQueryUniqueId ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 3939 of file ioctl.c.

3963{
3965 PMOUNTDEV_UNIQUE_ID uniqueId = NULL;
3966
3967 *DataLength = 0;
3968
3969 if (!DeviceExtension->MountedDeviceInterfaceName.Buffer)
3970 {
3972 }
3973 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID))
3974 {
3975 *DataLength = sizeof(MOUNTDEV_UNIQUE_ID);
3977 }
3978
3979 if (NT_SUCCESS(status))
3980 {
3981 status = WdfRequestRetrieveOutputBuffer(Request,
3982 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
3983 &uniqueId,
3984 NULL);
3985 }
3986
3987 if (NT_SUCCESS(status))
3988 {
3989 RtlZeroMemory(uniqueId, RequestParameters.Parameters.DeviceIoControl.OutputBufferLength);
3990
3991 uniqueId->UniqueIdLength = DeviceExtension->MountedDeviceInterfaceName.Length;
3992
3993 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
3994 (sizeof(USHORT) + DeviceExtension->MountedDeviceInterfaceName.Length))
3995 {
3996 *DataLength = sizeof(MOUNTDEV_UNIQUE_ID);
3998 }
3999 }
4000
4001 if (NT_SUCCESS(status))
4002 {
4003 RtlCopyMemory(uniqueId->UniqueId,
4004 DeviceExtension->MountedDeviceInterfaceName.Buffer,
4005 uniqueId->UniqueIdLength);
4006
4007 *DataLength = sizeof(USHORT) + uniqueId->UniqueIdLength;
4009 }
4010
4011 return status;
4012}
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
USHORT UniqueIdLength
Definition: imports.h:136
UCHAR UniqueId[1]
Definition: imports.h:137
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by RequestDispatchProcessDirectly().

◆ RequestHandleQueryPropertyDeviceUniqueId()

NTSTATUS RequestHandleQueryPropertyDeviceUniqueId ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request 
)

Definition at line 2799 of file ioctl.c.

2821{
2823 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
2824 PSTORAGE_PROPERTY_QUERY inputBuffer = NULL;
2825 PSTORAGE_DESCRIPTOR_HEADER descHeader = NULL;
2826 size_t outLength = 0;
2827 WDF_REQUEST_PARAMETERS requestParameters;
2828
2829 // Get the Request parameters
2830 WDF_REQUEST_PARAMETERS_INIT(&requestParameters);
2831 WdfRequestGetParameters(Request, &requestParameters);
2832
2833 status = WdfRequestRetrieveInputBuffer(Request,
2834 requestParameters.Parameters.DeviceIoControl.InputBufferLength,
2835 &inputBuffer,
2836 NULL);
2837
2838 if (NT_SUCCESS(status))
2839 {
2840 BOOLEAN overflow = FALSE;
2841 BOOLEAN infoFound = FALSE;
2842
2843 // Must run at less then dispatch.
2845 {
2847 outLength = 0;
2849 }
2850 else if (inputBuffer->QueryType == PropertyExistsQuery)
2851 {
2852 outLength = 0;
2854 }
2855 else if (inputBuffer->QueryType != PropertyStandardQuery)
2856 {
2857 outLength = 0;
2859 }
2860 else
2861 {
2862 // Check AdditionalParameters validity.
2863 if (inputBuffer->AdditionalParameters[0] == DUID_INCLUDE_SOFTWARE_IDS)
2864 {
2865 // Do nothing
2866 }
2867 else if (inputBuffer->AdditionalParameters[0] == DUID_HARDWARE_IDS_ONLY)
2868 {
2869 // Do nothing
2870 }
2871 else
2872 {
2873 outLength = 0;
2875 }
2876
2877 if (NT_SUCCESS(status) &&
2878 (outLength < sizeof(STORAGE_DESCRIPTOR_HEADER)))
2879 {
2880 outLength = 0;
2882 }
2883 }
2884
2885 // From this point forward the status depends on the overflow
2886 // and infoFound flags.
2887 if (NT_SUCCESS(status))
2888 {
2889 outLength = requestParameters.Parameters.DeviceIoControl.OutputBufferLength;
2890 status = WdfRequestRetrieveOutputBuffer(Request,
2891 requestParameters.Parameters.DeviceIoControl.OutputBufferLength,
2892 &descHeader,
2893 NULL);
2894 }
2895
2896 if (NT_SUCCESS(status))
2897 {
2898 RtlZeroMemory(descHeader, outLength);
2899
2900 descHeader->Version = DUID_VERSION_1;
2901 descHeader->Size = sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER);
2902
2903 // Try to build device unique id from StorageDeviceIdProperty.
2904 status = RequestDuidGetDeviceIdProperty(deviceExtension,
2905 Request,
2906 requestParameters,
2907 &outLength);
2908
2910 {
2911 overflow = TRUE;
2912 }
2913
2914 if (NT_SUCCESS(status))
2915 {
2916 infoFound = TRUE;
2917 }
2918
2919 // Try to build device unique id from StorageDeviceProperty.
2920 status = RequestDuidGetDeviceProperty(deviceExtension,
2921 Request,
2922 requestParameters,
2923 &outLength);
2924
2926 {
2927 overflow = TRUE;
2928 }
2929
2930 if (NT_SUCCESS(status))
2931 {
2932 infoFound = TRUE;
2933 }
2934
2935 // Return overflow, success, or a generic error.
2936 if (overflow)
2937 {
2938 // If output buffer is STORAGE_DESCRIPTOR_HEADER, then return
2939 // success to the user. Otherwise, send an error so the user
2940 // knows a larger buffer is required.
2941 if (outLength == sizeof(STORAGE_DESCRIPTOR_HEADER))
2942 {
2944 }
2945 else
2946 {
2947 outLength = (ULONG)WdfRequestGetInformation(Request);
2949 }
2950
2951 }
2952 else if (infoFound)
2953 {
2955
2956 // Exercise the compare routine. This should always succeed.
2959
2960 }
2961 else
2962 {
2964 }
2965 }
2966 }
2967
2968 RequestCompletion(deviceExtension, Request, status, outLength);
2969
2970 return status;
2971}
NTSTATUS RequestDuidGetDeviceIdProperty(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: common.c:2797
NTSTATUS RequestDuidGetDeviceProperty(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
Definition: common.c:2888
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
* PSTORAGE_DESCRIPTOR_HEADER
Definition: ntddstor.h:560
STORAGE_DESCRIPTOR_HEADER
Definition: ntddstor.h:560
@ PropertyExistsQuery
Definition: ntddstor.h:506
@ PropertyStandardQuery
Definition: ntddstor.h:505
FORCEINLINE DUID_MATCH_STATUS CompareStorageDuids(_In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid1, _In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid2)
Definition: storduid.h:56
struct _STORAGE_DEVICE_UNIQUE_IDENTIFIER STORAGE_DEVICE_UNIQUE_IDENTIFIER
#define DUID_INCLUDE_SOFTWARE_IDS
Definition: storduid.h:23
#define DUID_VERSION_1
Definition: storduid.h:20
@ DuidExactMatch
Definition: storduid.h:6
#define DUID_HARDWARE_IDS_ONLY
Definition: storduid.h:22
STORAGE_QUERY_TYPE QueryType
Definition: ntddstor.h:553
UCHAR AdditionalParameters[1]
Definition: ntddstor.h:554
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211

Referenced by RequestDispatchSpecialIoctls().

◆ RequestHandleQueryPropertyRetrieveCachedData()

NTSTATUS RequestHandleQueryPropertyRetrieveCachedData ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 2628 of file ioctl.c.

2652{
2654 PSTORAGE_PROPERTY_QUERY inputBuffer = NULL;
2655
2656 *DataLength = 0;
2657
2658 status = WdfRequestRetrieveInputBuffer(Request,
2660 &inputBuffer,
2661 NULL);
2662
2663 if (NT_SUCCESS(status))
2664 {
2665 if (inputBuffer->PropertyId == StorageDeviceProperty)
2666 {
2667 // check output buffer length
2668 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength == 0)
2669 {
2670 // According to MSDN, an output buffer of size 0 can be used to determine if a property exists
2671 // so this must be a success case with no data transferred
2672 *DataLength = 0;
2674 }
2675 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DESCRIPTOR_HEADER))
2676 {
2677 // Buffer too small
2678 *DataLength = DeviceExtension->DeviceDescriptor->Size;
2680 }
2681 else
2682 {
2683 PSTORAGE_DEVICE_DESCRIPTOR outputDescriptor = NULL;
2684 CHAR* localDescriptorBuffer = (CHAR*)DeviceExtension->DeviceDescriptor;
2685
2686 status = WdfRequestRetrieveOutputBuffer(Request,
2687 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
2688 &outputDescriptor,
2689 NULL);
2690
2691 if (NT_SUCCESS(status))
2692 {
2693 // transfer as much data out as the buffer will allow
2695 DeviceExtension->DeviceDescriptor->Size);
2696
2697 RtlCopyMemory(outputDescriptor,
2698 DeviceExtension->DeviceDescriptor,
2699 *DataLength);
2700
2701 // walk through and update offset variables to reflect data that didn't make it into the output buffer
2703 (DeviceExtension->DeviceDescriptor->VendorIdOffset != 0) &&
2704 (DeviceExtension->DeviceDescriptor->VendorIdOffset != 0xFFFFFFFF))
2705 {
2706 // set VendorIdOffset appropriately
2707 if (*DataLength <
2708 (DeviceExtension->DeviceDescriptor->VendorIdOffset + strlen(localDescriptorBuffer + DeviceExtension->DeviceDescriptor->VendorIdOffset)))
2709 {
2710 outputDescriptor->VendorIdOffset = 0;
2711 }
2712 }
2713
2715 (DeviceExtension->DeviceDescriptor->ProductIdOffset != 0) &&
2716 (DeviceExtension->DeviceDescriptor->ProductIdOffset != 0xFFFFFFFF))
2717 {
2718 // set ProductIdOffset appropriately
2719 if (*DataLength <
2720 (DeviceExtension->DeviceDescriptor->ProductIdOffset + strlen(localDescriptorBuffer + DeviceExtension->DeviceDescriptor->ProductIdOffset)))
2721 {
2722 outputDescriptor->ProductIdOffset = 0;
2723 }
2724 }
2725
2726 if ((*DataLength >= RTL_SIZEOF_THROUGH_FIELD(STORAGE_DEVICE_DESCRIPTOR, ProductRevisionOffset)) &&
2727 (DeviceExtension->DeviceDescriptor->ProductRevisionOffset != 0) &&
2728 (DeviceExtension->DeviceDescriptor->ProductRevisionOffset != 0xFFFFFFFF))
2729 {
2730 // set ProductRevisionOffset appropriately
2731 if (*DataLength <
2732 (DeviceExtension->DeviceDescriptor->ProductRevisionOffset + strlen(localDescriptorBuffer + DeviceExtension->DeviceDescriptor->ProductRevisionOffset)))
2733 {
2734 outputDescriptor->ProductRevisionOffset = 0;
2735 }
2736 }
2737
2738 if ((*DataLength >= RTL_SIZEOF_THROUGH_FIELD(STORAGE_DEVICE_DESCRIPTOR, SerialNumberOffset)) &&
2739 (DeviceExtension->DeviceDescriptor->SerialNumberOffset != 0) &&
2740 (DeviceExtension->DeviceDescriptor->SerialNumberOffset != 0xFFFFFFFF))
2741 {
2742 // set SerialNumberOffset appropriately
2743 if (*DataLength <
2744 (DeviceExtension->DeviceDescriptor->SerialNumberOffset + strlen(localDescriptorBuffer + DeviceExtension->DeviceDescriptor->SerialNumberOffset)))
2745 {
2746 // NOTE: setting this to 0 since that is what most port drivers do
2747 // [this could cause issues with SCSI port devices whose clients expect -1 in this field]
2748 outputDescriptor->SerialNumberOffset = 0;
2749 }
2750 }
2752 }
2753 }
2754 } //end of StorageDeviceProperty
2755 else if (inputBuffer->PropertyId == StorageAdapterProperty)
2756 {
2757 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength == 0)
2758 {
2759 // According to MSDN, an output buffer of size 0 can be used to determine if a property exists
2760 // so this must be a success case with no data transferred
2761 *DataLength = 0;
2763 }
2764 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DESCRIPTOR_HEADER))
2765 {
2766 // Buffer too small
2767 *DataLength = DeviceExtension->AdapterDescriptor->Size;
2769 }
2770 else
2771 {
2772 PSTORAGE_ADAPTER_DESCRIPTOR outputDescriptor = NULL;
2773
2774 status = WdfRequestRetrieveOutputBuffer(Request,
2775 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
2776 &outputDescriptor,
2777 NULL);
2778 if (NT_SUCCESS(status))
2779 {
2780 // copy as much data out as the buffer will allow
2782 DeviceExtension->AdapterDescriptor->Size);
2783
2784 RtlCopyMemory(outputDescriptor,
2785 DeviceExtension->AdapterDescriptor,
2786 *DataLength);
2787
2788 // set status
2790 }
2791 }
2792 }
2793 }
2794
2795 return status;
2796}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:680
* PSTORAGE_DEVICE_DESCRIPTOR
Definition: ntddstor.h:576
@ StorageAdapterProperty
Definition: ntddstor.h:513
@ StorageDeviceProperty
Definition: ntddstor.h:512
STORAGE_DEVICE_DESCRIPTOR
Definition: ntddstor.h:576
* PSTORAGE_ADAPTER_DESCRIPTOR
Definition: ntddstor.h:599
STORAGE_PROPERTY_ID PropertyId
Definition: ntddstor.h:552
char CHAR
Definition: xmlstorage.h:175

Referenced by RequestDispatchSpecialIoctls().

◆ RequestHandleQueryPropertyWriteCache()

NTSTATUS RequestHandleQueryPropertyWriteCache ( _In_ WDFDEVICE  Device,
_In_ WDFREQUEST  Request 
)

Definition at line 2974 of file ioctl.c.

2994{
2996 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
2999 PMODE_PARAMETER_HEADER modeData = NULL;
3000 PMODE_CACHING_PAGE pageData = NULL;
3001 size_t length = 0;
3002 ULONG information = 0;
3004 WDF_REQUEST_PARAMETERS requestParameters;
3005
3006 // Get the Request parameters
3007 WDF_REQUEST_PARAMETERS_INIT(&requestParameters);
3008 WdfRequestGetParameters(Request, &requestParameters);
3009
3010 status = WdfRequestRetrieveInputBuffer(Request,
3011 requestParameters.Parameters.DeviceIoControl.InputBufferLength,
3012 &query,
3013 NULL);
3014
3015 if (NT_SUCCESS(status))
3016 {
3017
3018 // Must run at less then dispatch.
3020 {
3023 }
3024 else if (query->QueryType == PropertyExistsQuery)
3025 {
3026 information = 0;
3028 }
3029 else if (query->QueryType != PropertyStandardQuery)
3030 {
3032 }
3033 }
3034
3035 if (NT_SUCCESS(status))
3036 {
3037 length = requestParameters.Parameters.DeviceIoControl.OutputBufferLength;
3038
3039 if (length < sizeof(STORAGE_DESCRIPTOR_HEADER))
3040 {
3042 }
3043 }
3044
3045 if (NT_SUCCESS(status))
3046 {
3047 status = WdfRequestRetrieveOutputBuffer(Request,
3048 requestParameters.Parameters.DeviceIoControl.OutputBufferLength,
3049 &writeCache,
3050 NULL);
3051 }
3052
3053 if (NT_SUCCESS(status))
3054 {
3055 RtlZeroMemory(writeCache, length);
3056
3057 // Set version and required size.
3058 writeCache->Version = sizeof(STORAGE_WRITE_CACHE_PROPERTY);
3059 writeCache->Size = sizeof(STORAGE_WRITE_CACHE_PROPERTY);
3060
3062 {
3063 // caller only wants header information, bail out.
3066
3067 RequestCompletion(deviceExtension, Request, status, information);
3068 return status;
3069 }
3070 }
3071
3072 if (NT_SUCCESS(status))
3073 {
3074 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
3075 sizeof(SCSI_REQUEST_BLOCK) +
3076 (sizeof(ULONG_PTR) * 2),
3078
3079 if (srb == NULL)
3080 {
3082 }
3083 }
3084
3085 if (NT_SUCCESS(status))
3086 {
3087 RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
3088
3089 // Set known values
3090 writeCache->NVCacheEnabled = FALSE;
3091 writeCache->UserDefinedPowerProtection = TEST_FLAG(deviceExtension->DeviceFlags, DEV_POWER_PROTECTED);
3092
3093 // Check for flush cache support by sending a sync cache command
3094 // to the device.
3095
3096 // Set timeout value and mark the request as not being a tagged request.
3098 srb->TimeOutValue = TimeOutValueGetCapValue(deviceExtension->TimeOutValue, 4);
3099 srb->QueueTag = SP_UNTAGGED;
3101 srb->SrbFlags = deviceExtension->SrbFlags;
3102
3104 srb->CdbLength = 10;
3105
3106 srb->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
3107
3108 status = DeviceSendSrbSynchronously(Device,
3109 srb,
3110 NULL,
3111 0,
3112 TRUE, //flush drive cache
3113 Request);
3114
3115 if (NT_SUCCESS(status))
3116 {
3117 writeCache->FlushCacheSupported = TRUE;
3118 }
3119 else
3120 {
3121 // Device does not support sync cache
3122 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
3123 "RequestHandleQueryPropertyWriteCache: Synchronize cache failed with status 0x%X\n", status));
3124 writeCache->FlushCacheSupported = FALSE;
3125
3126 // Reset the status if there was any failure
3128 }
3129
3130 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
3133
3134 if (modeData == NULL)
3135 {
3136 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
3137 "RequestHandleQueryPropertyWriteCache: Unable to allocate mode data buffer\n"));
3139 }
3140 }
3141
3142 if (NT_SUCCESS(status))
3143 {
3145
3146 length = DeviceRetrieveModeSenseUsingScratch(deviceExtension,
3147 (PCHAR)modeData,
3151
3152 if (length < sizeof(MODE_PARAMETER_HEADER))
3153 {
3154 // Retry the request in case of a check condition.
3155 length = DeviceRetrieveModeSenseUsingScratch(deviceExtension,
3156 (PCHAR)modeData,
3160
3161 if (length < sizeof(MODE_PARAMETER_HEADER))
3162 {
3163 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "RequestHandleQueryPropertyWriteCache: Mode Sense failed\n"));
3165 }
3166 }
3167 }
3168
3169 if (NT_SUCCESS(status))
3170 {
3171 // If the length is greater than length indicated by the mode data reset
3172 // the data to the mode data.
3173 if (length > (ULONG) (modeData->ModeDataLength + 1))
3174 {
3175 length = modeData->ModeDataLength + 1;
3176 }
3177
3178 // Look for caching page in the returned mode page data.
3179 pageData = ModeSenseFindSpecificPage((PCHAR)modeData,
3180 length,
3182 TRUE);
3183
3184 // Check if valid caching page exists.
3185 if (pageData == NULL)
3186 {
3187 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "RequestHandleQueryPropertyWriteCache: Unable to find caching mode page.\n"));
3188
3189 // Set write cache value as unknown.
3190 writeCache->WriteCacheEnabled = WriteCacheEnableUnknown;
3191 writeCache->WriteCacheType = WriteCacheTypeUnknown;
3192 }
3193 else
3194 {
3195 writeCache->WriteCacheEnabled = pageData->WriteCacheEnable
3198
3199 writeCache->WriteCacheType = pageData->WriteCacheEnable
3202 }
3203
3204 // Check write through support.
3206 {
3207 writeCache->WriteThroughSupported = WriteThroughSupported;
3208 }
3209 else
3210 {
3211 writeCache->WriteThroughSupported = WriteThroughNotSupported;
3212 }
3213
3214 // Get the changeable caching mode page and check write cache is changeable.
3216
3217 length = DeviceRetrieveModeSenseUsingScratch(deviceExtension,
3218 (PCHAR) modeData,
3222
3223 if (length < sizeof(MODE_PARAMETER_HEADER))
3224 {
3225 // Retry the request in case of a check condition.
3226 length = DeviceRetrieveModeSenseUsingScratch(deviceExtension,
3227 (PCHAR) modeData,
3231
3232 if (length < sizeof(MODE_PARAMETER_HEADER))
3233 {
3234 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "RequestHandleQueryPropertyWriteCache: Mode Sense failed\n"));
3235
3236 // If the device fails to return changeable pages, then
3237 // set the write cache changeable value to unknown.
3238 writeCache->WriteCacheChangeable = WriteCacheChangeUnknown;
3240 }
3241 }
3242 }
3243
3244 if (NT_SUCCESS(status))
3245 {
3246 // If the length is greater than length indicated by the mode data reset
3247 // the data to the mode data.
3248 if (length > (ULONG) (modeData->ModeDataLength + 1))
3249 {
3250 length = modeData->ModeDataLength + 1;
3251 }
3252
3253 // Look for caching page in the returned mode page data.
3254 pageData = ModeSenseFindSpecificPage((PCHAR)modeData,
3255 length,
3257 TRUE);
3258 // Check if valid caching page exists.
3259 if (pageData == NULL)
3260 {
3261 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "RequestHandleQueryPropertyWriteCache: Unable to find caching mode page.\n"));
3262
3263 // Set write cache changeable value to unknown.
3264 writeCache->WriteCacheChangeable = WriteCacheChangeUnknown;
3265 }
3266 else
3267 {
3268 writeCache->WriteCacheChangeable = pageData->WriteCacheEnable
3271 }
3272
3274
3275 }
3276
3277 FREE_POOL(srb);
3278 FREE_POOL(modeData);
3279
3280 RequestCompletion(deviceExtension, Request, status, information);
3281
3282 return status;
3283}
#define DEV_POWER_PROTECTED
Definition: cdrom.h:143
#define CDROM_TAG_MODE_DATA
Definition: cdrom.h:737
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define CDROM_TAG_SRB
Definition: cdrom.h:742
FORCEINLINE ULONG TimeOutValueGetCapValue(_In_ ULONG TimeOutValue, _In_ ULONG Times)
Definition: cdrom.h:1569
#define MODE_PAGE_DATA_SIZE
Definition: cdromp.h:376
#define MODE_DSP_FUA_SUPPORTED
Definition: cdrw_hw.h:2522
#define MODE_SENSE_CHANGEABLE_VALUES
Definition: cdrw_hw.h:860
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
#define MODE_SENSE_CURRENT_VALUES
Definition: cdrw_hw.h:859
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
static PDB_INFORMATION information
Definition: db.cpp:178
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:282
#define SP_UNTAGGED
Definition: srb.h:233
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:423
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
@ WriteThroughSupported
Definition: ntddstor.h:885
@ WriteThroughNotSupported
Definition: ntddstor.h:884
* PSTORAGE_WRITE_CACHE_PROPERTY
Definition: ntddstor.h:898
@ WriteCacheChangeUnknown
Definition: ntddstor.h:877
@ WriteCacheChangeable
Definition: ntddstor.h:879
@ WriteCacheNotChangeable
Definition: ntddstor.h:878
@ WriteCacheTypeWriteBack
Definition: ntddstor.h:866
@ WriteCacheTypeUnknown
Definition: ntddstor.h:864
@ WriteCacheEnableUnknown
Definition: ntddstor.h:871
@ WriteCacheDisabled
Definition: ntddstor.h:872
@ WriteCacheEnabled
Definition: ntddstor.h:873
STORAGE_WRITE_CACHE_PROPERTY
Definition: ntddstor.h:898
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
UCHAR WriteCacheEnable
Definition: cdrw_hw.h:2779
UCHAR DeviceSpecificParameter
Definition: cdrw_hw.h:2507
UCHAR QueueTag
Definition: srb.h:256
UCHAR QueueAction
Definition: srb.h:257
UCHAR Function
Definition: srb.h:250
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
uint32_t ULONG_PTR
Definition: typedefs.h:65
char * PCHAR
Definition: typedefs.h:51
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179

Referenced by RequestDispatchSpecialIoctls().

◆ RequestHandleReadWrite()

NTSTATUS RequestHandleReadWrite ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters 
)

Definition at line 6353 of file ioctl.c.

6375{
6377 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
6378
6379 size_t transferByteCount = 0;
6380 PIRP irp = NULL;
6381 PIO_STACK_LOCATION currentStack = NULL;
6382
6384
6385
6386 irp = WdfRequestWdmGetIrp(Request);
6387 currentStack = IoGetCurrentIrpStackLocation(irp);
6388 dataBuffer = MmGetMdlVirtualAddress(irp->MdlAddress);
6389
6390 if (NT_SUCCESS(status))
6391 {
6393 {
6394 transferByteCount = RequestParameters.Parameters.Read.Length;
6395 }
6396 else
6397 {
6398 transferByteCount = RequestParameters.Parameters.Write.Length;
6399 }
6400
6401 if (transferByteCount == 0)
6402 {
6403 // Several parts of the code turn 0 into 0xffffffff,
6404 // so don't process a zero-length request any further.
6406 RequestCompletion(DeviceExtension, Request, status, 0);
6407 return status;
6408 }
6409
6410 // Add partition byte offset to make starting byte relative to
6411 // beginning of disk.
6412 currentStack->Parameters.Read.ByteOffset.QuadPart += (DeviceExtension->StartingOffset.QuadPart);
6413
6414 //not very necessary as the starting offset for CD/DVD device is always 0.
6416 {
6417 RequestParameters.Parameters.Read.DeviceOffset = currentStack->Parameters.Read.ByteOffset.QuadPart;
6418 }
6419 else
6420 {
6421 RequestParameters.Parameters.Write.DeviceOffset = currentStack->Parameters.Write.ByteOffset.QuadPart;
6422 }
6423 }
6424
6425 if (NT_SUCCESS(status))
6426 {
6427 ULONG entireXferLen = currentStack->Parameters.Read.Length;
6428 ULONG maxLength = 0;
6429 ULONG packetsCount = 0;
6430
6431 PCDROM_SCRATCH_READ_WRITE_CONTEXT readWriteContext;
6432 PCDROM_REQUEST_CONTEXT requestContext;
6433 PCDROM_REQUEST_CONTEXT originalRequestContext;
6434
6435 // get the count of packets we need to send.
6436 if ((((ULONG_PTR)dataBuffer) & (PAGE_SIZE-1)) == 0)
6437 {
6439 }
6440 else
6441 {
6443 }
6444
6445 packetsCount = entireXferLen / maxLength;
6446
6447 if (entireXferLen % maxLength != 0)
6448 {
6449 packetsCount++;
6450 }
6451
6452 originalRequestContext = RequestGetContext(Request);
6453
6454
6455 ScratchBuffer_BeginUse(DeviceExtension);
6456
6457 readWriteContext = &DeviceExtension->ScratchContext.ScratchReadWriteContext;
6458 requestContext = RequestGetContext(DeviceExtension->ScratchContext.ScratchRequest);
6459
6460 readWriteContext->PacketsCount = packetsCount;
6461 readWriteContext->EntireXferLen = entireXferLen;
6462 readWriteContext->MaxLength = maxLength;
6463 readWriteContext->StartingOffset = currentStack->Parameters.Read.ByteOffset;
6464 readWriteContext->DataBuffer = dataBuffer;
6465 readWriteContext->TransferedBytes = 0;
6466 readWriteContext->IsRead = (RequestParameters.Type == WdfRequestTypeRead);
6467
6468 requestContext->OriginalRequest = Request;
6469 requestContext->DeviceExtension = DeviceExtension;
6470
6471 //
6472 // Setup the READ/WRITE fields in the original request which is what
6473 // we use to properly synchronize cancellation logic between the
6474 // cancel callback and the timer routine.
6475 //
6476
6477 originalRequestContext->ReadWriteIsCompleted = FALSE;
6478 originalRequestContext->ReadWriteRetryInitialized = FALSE;
6479 originalRequestContext->DeviceExtension = DeviceExtension;
6480
6482
6483 // We do not call ScratchBuffer_EndUse here, because we're not releasing the scratch SRB.
6484 // It will be released in the completion routine.
6485 }
6486
6487 return status;
6488}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PVOID dataBuffer
FxIrp * irp
GLsizei maxLength
Definition: glext.h:6877
NTSTATUS ScratchBuffer_PerformNextReadWrite(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FirstTry)
Definition: scratch.c:429
#define ScratchBuffer_BeginUse(context)
Definition: scratch.h:87
ULONG MaxPageAlignedTransferBytes
Definition: cdrom.h:360
ULONG MaxUnalignedTransferBytes
Definition: cdrom.h:361
WDFREQUEST OriginalRequest
Definition: cdrom.h:633
PCDROM_DEVICE_EXTENSION DeviceExtension
Definition: cdrom.h:631
BOOLEAN ReadWriteIsCompleted
Definition: cdrom.h:665
BOOLEAN ReadWriteRetryInitialized
Definition: cdrom.h:666
LARGE_INTEGER StartingOffset
Definition: cdrom.h:285
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@3980::@3985 Write
struct _IO_STACK_LOCATION::@3980::@3984 Read
WDF_REQUEST_TYPE Type
Definition: wdfrequest.h:142
struct _WDF_REQUEST_PARAMETERS::@3883::@3885 Read
struct _WDF_REQUEST_PARAMETERS::@3883::@3886 Write
unsigned char * PUCHAR
Definition: typedefs.h:53
@ WdfRequestTypeRead
Definition: wdfdevice.h:506
#define MmGetMdlVirtualAddress(_Mdl)

Referenced by ReadWriteWorkItemRoutine(), and SequentialQueueEvtIoReadWrite().

◆ RequestHandleSetHotPlugInfo()

NTSTATUS RequestHandleSetHotPlugInfo ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 5392 of file ioctl.c.

5416{
5419
5420 *DataLength = 0;
5421
5422 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
5423 sizeof(STORAGE_HOTPLUG_INFO))
5424 {
5425 // Indicate unsuccessful status and no data transferred.
5427 }
5428
5429 if (NT_SUCCESS(status))
5430 {
5431 status = WdfRequestRetrieveInputBuffer(Request,
5433 &info,
5434 NULL);
5435 }
5436
5437 if (NT_SUCCESS(status))
5438 {
5439 if (info->Size != DeviceExtension->PrivateFdoData->HotplugInfo.Size)
5440 {
5442 }
5443
5444 if (info->MediaRemovable != DeviceExtension->PrivateFdoData->HotplugInfo.MediaRemovable)
5445 {
5447 }
5448
5449 if (info->MediaHotplug != DeviceExtension->PrivateFdoData->HotplugInfo.MediaHotplug)
5450 {
5452 }
5453
5454 if (info->WriteCacheEnableOverride != DeviceExtension->PrivateFdoData->HotplugInfo.WriteCacheEnableOverride)
5455 {
5457 }
5458 }
5459
5460 if (NT_SUCCESS(status))
5461 {
5462 DeviceExtension->PrivateFdoData->HotplugInfo.DeviceHotplug = info->DeviceHotplug;
5463
5464 // Store the user-defined override in the registry
5465 DeviceSetParameter(DeviceExtension,
5469 }
5470
5471 return status;
5472}
#define CLASSP_REG_REMOVAL_POLICY_VALUE_NAME
Definition: cdromp.h:126
#define CLASSP_REG_SUBKEY_NAME
Definition: cdromp.h:120
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:479
@ RemovalPolicyExpectSurpriseRemoval
Definition: iotypes.h:842
@ RemovalPolicyExpectOrderlyRemoval
Definition: iotypes.h:841

Referenced by RequestDispatchProcessDirectly().

◆ RequestIsRealtimeStreaming()

BOOLEAN RequestIsRealtimeStreaming ( _In_ WDFREQUEST  Request,
_In_ BOOLEAN  IsReadRequest 
)

Definition at line 6050 of file ioctl.c.

6072{
6073 BOOLEAN useStreaming = FALSE;
6074
6075 if (!useStreaming) {
6076 //
6077 // Check if we're required to use Streaming via I/O Stack Location flags
6078 //
6079 UCHAR currentStackLocationFlags = 0;
6080 currentStackLocationFlags = RequestGetCurrentStackLocationFlags(Request);
6081
6082 useStreaming = TEST_FLAG(currentStackLocationFlags, SL_REALTIME_STREAM);
6083 }
6084
6085 if (!useStreaming) {
6086 //
6087 // Check if we were previously requested to enforce Streaming for
6088 // the file handle through which this request was sent.
6089 //
6090
6091 WDFFILEOBJECT fileObject;
6092 PFILE_OBJECT_CONTEXT fileObjectContext;
6093
6094 fileObject = WdfRequestGetFileObject(Request);
6095
6096 if (fileObject != NULL) {
6097 fileObjectContext = FileObjectGetContext(fileObject);
6098 NT_ASSERT(fileObjectContext != NULL);
6099
6100 if (IsReadRequest && fileObjectContext->EnforceStreamingRead)
6101 {
6102 useStreaming = TRUE;
6103 }
6104
6105 if (!IsReadRequest && fileObjectContext->EnforceStreamingWrite)
6106 {
6107 useStreaming = TRUE;
6108 }
6109 }
6110 }
6111
6112 return useStreaming;
6113}
FORCEINLINE UCHAR RequestGetCurrentStackLocationFlags(_In_ WDFREQUEST Request)
Definition: cdrom.h:1554
BOOLEAN EnforceStreamingRead
Definition: cdromp.h:368
BOOLEAN EnforceStreamingWrite
Definition: cdromp.h:369
#define SL_REALTIME_STREAM
Definition: iotypes.h:1827
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by RequestValidateReadWrite(), and ScratchBuffer_SetupReadWriteSrb().

◆ RequestValidateAacsBindingNonce()

NTSTATUS RequestValidateAacsBindingNonce ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 2162 of file ioctl.c.

2187{
2189 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
2190 PAACS_READ_BINDING_NONCE inputBuffer = NULL;
2191
2192 *DataLength = 0;
2193
2194 if (!cdData->Mmc.IsAACS)
2195 {
2197 }
2198 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(AACS_READ_BINDING_NONCE))
2199 {
2201 }
2202 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(AACS_BINDING_NONCE))
2203 {
2204 *DataLength = sizeof(AACS_BINDING_NONCE);
2206 }
2207 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > sizeof(AACS_BINDING_NONCE))
2208 {
2210 }
2211
2212 if (NT_SUCCESS(status))
2213 {
2214 status = WdfRequestRetrieveInputBuffer(Request,
2216 &inputBuffer,
2217 NULL);
2218 }
2219
2220 if (NT_SUCCESS(status))
2221 {
2222 if (inputBuffer->SessionId > MAX_COPY_PROTECT_AGID)
2223 {
2225 }
2226 else if (inputBuffer->NumberOfSectors > 255)
2227 {
2229 }
2230 else if (inputBuffer->StartLba > MAXULONG)
2231 {
2233 }
2234 }
2235
2236 return status;
2237}
#define MAX_COPY_PROTECT_AGID
Definition: cdrom.h:712
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
struct _AACS_BINDING_NONCE AACS_BINDING_NONCE
DVD_SESSION_ID SessionId
Definition: ntddcdvd.h:322
BOOLEAN IsAACS
Definition: cdrom.h:248
#define MAXULONG
Definition: typedefs.h:251
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsEndSession()

NTSTATUS RequestValidateAacsEndSession ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 3462 of file ioctl.c.

3486{
3488 PDVD_SESSION_ID sessionId = NULL;
3489 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
3490
3491 *DataLength = 0;
3492
3493 status = WdfRequestRetrieveInputBuffer(Request,
3495 &sessionId,
3496 NULL);
3497
3498 if (NT_SUCCESS(status))
3499 {
3500 if (!cdData->Mmc.IsAACS)
3501 {
3503 }
3504 else if(RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(DVD_SESSION_ID))
3505 {
3507 }
3508 }
3509
3510 return status;
3511}
ULONG DVD_SESSION_ID
Definition: cdrw_usr.h:1544
ULONG * PDVD_SESSION_ID
Definition: cdrw_usr.h:1544

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsGetCertificate()

NTSTATUS RequestValidateAacsGetCertificate ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1757 of file ioctl.c.

1781{
1783 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1784 PDVD_SESSION_ID sessionId = NULL;
1785
1786 *DataLength = 0;
1787
1788 if (!cdData->Mmc.IsAACS)
1789 {
1791 }
1792 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(DVD_SESSION_ID))
1793 {
1795 }
1796 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(AACS_CERTIFICATE))
1797 {
1798 *DataLength = sizeof(AACS_CERTIFICATE);
1800 }
1801 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > sizeof(AACS_CERTIFICATE))
1802 {
1804 }
1805
1806 if (NT_SUCCESS(status))
1807 {
1808 status = WdfRequestRetrieveInputBuffer(Request,
1810 &sessionId,
1811 NULL);
1812 }
1813
1814 if (NT_SUCCESS(status))
1815 {
1816 if (*sessionId > MAX_COPY_PROTECT_AGID)
1817 {
1819 }
1820 }
1821
1822 return status;
1823}
struct _AACS_CERTIFICATE AACS_CERTIFICATE

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsGetChallengeKey()

NTSTATUS RequestValidateAacsGetChallengeKey ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1826 of file ioctl.c.

1850{
1852 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1853 PDVD_SESSION_ID sessionId = NULL;
1854
1855 *DataLength = 0;
1856
1857 if (!cdData->Mmc.IsAACS)
1858 {
1860 }
1861 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(DVD_SESSION_ID))
1862 {
1864 }
1865 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(AACS_CHALLENGE_KEY))
1866 {
1867 *DataLength = sizeof(AACS_CHALLENGE_KEY);
1869 }
1870 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > sizeof(AACS_CHALLENGE_KEY))
1871 {
1873 }
1874
1875 if (NT_SUCCESS(status))
1876 {
1877 status = WdfRequestRetrieveInputBuffer(Request,
1879 &sessionId,
1880 NULL);
1881 }
1882
1883 if (NT_SUCCESS(status))
1884 {
1885 if (*sessionId > MAX_COPY_PROTECT_AGID)
1886 {
1888 }
1889 }
1890
1891 return status;
1892}
struct _AACS_CHALLENGE_KEY AACS_CHALLENGE_KEY

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsReadMediaId()

NTSTATUS RequestValidateAacsReadMediaId ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 2093 of file ioctl.c.

2117{
2119 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
2120 PDVD_SESSION_ID sessionId = NULL;
2121
2122 *DataLength = 0;
2123
2124 if (!cdData->Mmc.IsAACS)
2125 {
2127 }
2128 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(DVD_SESSION_ID))
2129 {
2131 }
2132 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(AACS_MEDIA_ID))
2133 {
2134 *DataLength = sizeof(AACS_MEDIA_ID);
2136 }
2137 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > sizeof(AACS_MEDIA_ID))
2138 {
2140 }
2141
2142 if (NT_SUCCESS(status))
2143 {
2144 status = WdfRequestRetrieveInputBuffer(Request,
2146 &sessionId,
2147 NULL);
2148 }
2149
2150 if (NT_SUCCESS(status))
2151 {
2152 if (*sessionId > MAX_COPY_PROTECT_AGID)
2153 {
2155 }
2156 }
2157
2158 return status;
2159}
struct _AACS_MEDIA_ID AACS_MEDIA_ID

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsReadMediaKeyBlock()

NTSTATUS RequestValidateAacsReadMediaKeyBlock ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1584 of file ioctl.c.

1608{
1610 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1611 PAACS_LAYER_NUMBER layerNumber = NULL;
1612
1613 *DataLength = 0;
1614
1615 if (!cdData->Mmc.IsAACS)
1616 {
1618 }
1619 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(AACS_LAYER_NUMBER))
1620 {
1622 }
1623 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < 8)
1624 {
1625 // This is a variable-length structure, but we're pretty sure
1626 // it can never be less than eight bytes...
1627 *DataLength = 8;
1629 }
1630
1631 if (NT_SUCCESS(status))
1632 {
1633 status = WdfRequestRetrieveInputBuffer(Request,
1635 &layerNumber,
1636 NULL);
1637 }
1638
1639 if (NT_SUCCESS(status))
1640 {
1641 if (*layerNumber > 255)
1642 {
1644 }
1645 }
1646
1647 return status;
1648}
* PAACS_LAYER_NUMBER
Definition: ntddcdvd.h:255

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsReadSerialNumber()

NTSTATUS RequestValidateAacsReadSerialNumber ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 2024 of file ioctl.c.

2048{
2050 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
2051 PDVD_SESSION_ID sessionId = NULL;
2052
2053 *DataLength = 0;
2054
2055 if (!cdData->Mmc.IsAACS)
2056 {
2058 }
2059 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(DVD_SESSION_ID))
2060 {
2062 }
2063 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(AACS_SERIAL_NUMBER))
2064 {
2065 *DataLength = sizeof(AACS_SERIAL_NUMBER);
2067 }
2068 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > sizeof(AACS_SERIAL_NUMBER))
2069 {
2071 }
2072
2073 if (NT_SUCCESS(status))
2074 {
2075 status = WdfRequestRetrieveInputBuffer(Request,
2077 &sessionId,
2078 NULL);
2079 }
2080
2081 if (NT_SUCCESS(status))
2082 {
2083 if (*sessionId > MAX_COPY_PROTECT_AGID)
2084 {
2086 }
2087 }
2088
2089 return status;
2090}
struct _AACS_SERIAL_NUMBER AACS_SERIAL_NUMBER

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsReadVolumeId()

NTSTATUS RequestValidateAacsReadVolumeId ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1955 of file ioctl.c.

1979{
1981 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1982 PDVD_SESSION_ID sessionId = NULL;
1983
1984 *DataLength = 0;
1985
1986 if (!cdData->Mmc.IsAACS)
1987 {
1989 }
1990 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(DVD_SESSION_ID))
1991 {
1993 }
1994 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(AACS_VOLUME_ID))
1995 {
1996 *DataLength = sizeof(AACS_VOLUME_ID);
1998 }
1999 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > sizeof(AACS_VOLUME_ID))
2000 {
2002 }
2003
2004 if (NT_SUCCESS(status))
2005 {
2006 status = WdfRequestRetrieveInputBuffer(Request,
2008 &sessionId,
2009 NULL);
2010 }
2011
2012 if (NT_SUCCESS(status))
2013 {
2014 if (*sessionId > MAX_COPY_PROTECT_AGID)
2015 {
2017 }
2018 }
2019
2020 return status;
2021}
struct _AACS_VOLUME_ID AACS_VOLUME_ID

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsSendCertificate()

NTSTATUS RequestValidateAacsSendCertificate ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1697 of file ioctl.c.

1721{
1723 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1724 PAACS_SEND_CERTIFICATE inputBuffer = NULL;
1725
1726 *DataLength = 0;
1727
1728 if (!cdData->Mmc.IsAACS)
1729 {
1731 }
1732 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(AACS_SEND_CERTIFICATE))
1733 {
1735 }
1736
1737 if (NT_SUCCESS(status))
1738 {
1739 status = WdfRequestRetrieveInputBuffer(Request,
1741 &inputBuffer,
1742 NULL);
1743 }
1744
1745 if (NT_SUCCESS(status))
1746 {
1747 if (inputBuffer->SessionId > MAX_COPY_PROTECT_AGID)
1748 {
1750 }
1751 }
1752
1753 return status;
1754}
DVD_SESSION_ID SessionId
Definition: ntddcdvd.h:300

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsSendChallengeKey()

NTSTATUS RequestValidateAacsSendChallengeKey ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1895 of file ioctl.c.

1919{
1921 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1922 PAACS_SEND_CHALLENGE_KEY inputBuffer = NULL;
1923
1924 *DataLength = 0;
1925
1926 if (!cdData->Mmc.IsAACS)
1927 {
1929 }
1930 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != sizeof(AACS_SEND_CHALLENGE_KEY))
1931 {
1933 }
1934
1935 if (NT_SUCCESS(status))
1936 {
1937 status = WdfRequestRetrieveInputBuffer(Request,
1939 &inputBuffer,
1940 NULL);
1941 }
1942
1943 if (NT_SUCCESS(status))
1944 {
1945 if (inputBuffer->SessionId > MAX_COPY_PROTECT_AGID)
1946 {
1948 }
1949 }
1950
1951 return status;
1952}
DVD_SESSION_ID SessionId
Definition: ntddcdvd.h:307

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateAacsStartSession()

NTSTATUS RequestValidateAacsStartSession ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1651 of file ioctl.c.

1673{
1675 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1676
1677 *DataLength = 0;
1678
1679 if (!cdData->Mmc.IsAACS)
1680 {
1682 }
1683 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(DVD_SESSION_ID))
1684 {
1685 *DataLength = sizeof(DVD_SESSION_ID);
1687 }
1688 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > sizeof(DVD_SESSION_ID))
1689 {
1691 }
1692
1693 return status;
1694}

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateDvdEndSession()

NTSTATUS RequestValidateDvdEndSession ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 3408 of file ioctl.c.

3432{
3434 PDVD_SESSION_ID sessionId = NULL;
3435
3436 UNREFERENCED_PARAMETER(DeviceExtension);
3437
3438 *DataLength = 0;
3439
3440 status = WdfRequestRetrieveInputBuffer(Request,
3442 &sessionId,
3443 NULL);
3444
3445 if (NT_SUCCESS(status))
3446 {
3447 if(RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
3448 sizeof(DVD_SESSION_ID))
3449 {
3450 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
3451 "DvdDeviceControl: EndSession - input buffer too "
3452 "small\n"));
3454 }
3455 }
3456
3457 return status;
3458}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateDvdReadKey()

NTSTATUS RequestValidateDvdReadKey ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 3286 of file ioctl.c.

3310{
3312 PDVD_COPY_PROTECT_KEY keyParameters = NULL;
3313 ULONG keyLength = 0;
3314
3315 *DataLength = 0;
3316
3317 status = WdfRequestRetrieveInputBuffer(Request,
3319 &keyParameters,
3320 NULL);
3321
3322 if (NT_SUCCESS(status))
3323 {
3325 {
3326 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
3327 "DvdDeviceControl: EstablishDriveKey - challenge "
3328 "key buffer too small\n"));
3330 }
3331 }
3332
3333 if (NT_SUCCESS(status))
3334 {
3335 switch(keyParameters->KeyType)
3336 {
3337
3338 case DvdChallengeKey:
3339 {
3341 keyLength = DVD_CHALLENGE_KEY_LENGTH;
3342 break;
3343 }
3344 case DvdBusKey1:
3345 case DvdBusKey2:
3346 {
3348 keyLength = DVD_BUS_KEY_LENGTH;
3349 break;
3350 }
3351 case DvdTitleKey:
3352 {
3354 keyLength = DVD_TITLE_KEY_LENGTH;
3355 break;
3356 }
3357 case DvdAsf:
3358 {
3360 keyLength = DVD_ASF_LENGTH;
3361 break;
3362 }
3363 case DvdDiskKey:
3364 {
3366 keyLength = DVD_DISK_KEY_LENGTH;
3367 break;
3368 }
3369 case DvdGetRpcKey:
3370 {
3372 keyLength = DVD_RPC_KEY_LENGTH;
3373 break;
3374 }
3375 default:
3376 {
3377 keyLength = sizeof(DVD_COPY_PROTECT_KEY);
3378 break;
3379 }
3380 }
3381
3382 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < keyLength)
3383 {
3384
3385 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
3386 "DvdDeviceControl: EstablishDriveKey - output "
3387 "buffer too small\n"));
3389 *DataLength = keyLength;
3390 }
3391 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength &
3392 DeviceExtension->AdapterDescriptor->AlignmentMask)
3393 {
3395 }
3396 else if (DeviceExtension->DeviceAdditionalData.DriveDeviceType != FILE_DEVICE_DVD)
3397 {
3398 // reject the request if it's not a DVD device.
3400 }
3401 }
3402
3403 return status;
3404}
#define DVD_TITLE_KEY_LENGTH
Definition: cdrw_usr.h:1595
#define DVD_BUS_KEY_LENGTH
Definition: cdrw_usr.h:1594
#define DVD_CHALLENGE_KEY_LENGTH
Definition: cdrw_usr.h:1593
#define DVD_DISK_KEY_LENGTH
Definition: cdrw_usr.h:1596
#define DVD_ASF_LENGTH
Definition: cdrw_usr.h:1599
#define DVD_RPC_KEY_LENGTH
Definition: cdrw_usr.h:1597
#define C_ASSERT(e)
Definition: intsafe.h:73
@ DvdAsf
Definition: ntddcdvd.h:168
@ DvdDiskKey
Definition: ntddcdvd.h:171
@ DvdTitleKey
Definition: ntddcdvd.h:167
@ DvdBusKey1
Definition: ntddcdvd.h:165
@ DvdBusKey2
Definition: ntddcdvd.h:166
@ DvdChallengeKey
Definition: ntddcdvd.h:164
@ DvdGetRpcKey
Definition: ntddcdvd.h:170
struct _DVD_COPY_PROTECT_KEY DVD_COPY_PROTECT_KEY
#define FILE_DEVICE_DVD
Definition: winioctl.h:96
DVD_KEY_TYPE KeyType
Definition: ntddcdvd.h:178

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateDvdReadStructure()

NTSTATUS RequestValidateDvdReadStructure ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1151 of file ioctl.c.

1173{
1175
1176 *DataLength = 0;
1177
1178 if (NT_SUCCESS(status))
1179 {
1180 if(RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
1181 sizeof(DVD_READ_STRUCTURE))
1182 {
1183 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
1184 "RequestValidateDvdReadStructure - input buffer "
1185 "length too small (was %d should be %d)\n",
1186 (int)RequestParameters.Parameters.DeviceIoControl.InputBufferLength,
1187 sizeof(DVD_READ_STRUCTURE)));
1189 }
1190 else if(RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1192 {
1193
1194 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
1195 "RequestValidateDvdReadStructure - output buffer "
1196 "cannot hold header information\n"));
1199 }
1200 else if(RequestParameters.Parameters.DeviceIoControl.OutputBufferLength >
1201 MAXUSHORT)
1202 {
1203 // key length must fit in two bytes
1204 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
1205 "RequestValidateDvdReadStructure - output buffer "
1206 "too large\n"));
1208 }
1209 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength &
1210 DeviceExtension->AdapterDescriptor->AlignmentMask)
1211 {
1213 }
1214 else if (DeviceExtension->DeviceAdditionalData.DriveDeviceType != FILE_DEVICE_DVD)
1215 {
1216 // reject the request if it's not a DVD device.
1218 }
1219 }
1220
1221 return status;
1222}
struct _READ_DVD_STRUCTURES_HEADER READ_DVD_STRUCTURES_HEADER
#define MAXUSHORT
Definition: typedefs.h:83

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateDvdSendKey()

NTSTATUS RequestValidateDvdSendKey ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1274 of file ioctl.c.

1298{
1301
1302 *DataLength = 0;
1303
1304 status = WdfRequestRetrieveInputBuffer(Request,
1306 &key,
1307 NULL);
1308
1309 if (NT_SUCCESS(status))
1310 {
1311 if((RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(DVD_COPY_PROTECT_KEY)) ||
1312 (RequestParameters.Parameters.DeviceIoControl.InputBufferLength != key->KeyLength))
1313 {
1314
1315 //
1316 // Key is too small to have a header or the key length doesn't
1317 // match the input buffer length. Key must be invalid
1318 //
1319
1320 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
1321 "RequestValidateDvdSendKey: [%p] IOCTL_DVD_SEND_KEY - "
1322 "key is too small or does not match KeyLength\n",
1323 Request));
1325 }
1326 }
1327
1328 if (NT_SUCCESS(status))
1329 {
1330 // allow only certain key type (non-destructive) to go through
1331 // IOCTL_DVD_SEND_KEY (which only requires READ access to the device)
1333 {
1334 if ((key->KeyType != DvdChallengeKey) &&
1335 (key->KeyType != DvdBusKey2) &&
1336 (key->KeyType != DvdInvalidateAGID))
1337 {
1339 }
1340 }
1341 else if ((key->KeyType != DvdChallengeKey) &&
1342 (key->KeyType != DvdBusKey1) &&
1343 (key->KeyType != DvdBusKey2) &&
1344 (key->KeyType != DvdTitleKey) &&
1345 (key->KeyType != DvdAsf) &&
1346 (key->KeyType != DvdSetRpcKey) &&
1347 (key->KeyType != DvdGetRpcKey) &&
1348 (key->KeyType != DvdDiskKey) &&
1349 (key->KeyType != DvdInvalidateAGID))
1350 {
1352 }
1353 else if (DeviceExtension->DeviceAdditionalData.DriveDeviceType != FILE_DEVICE_DVD)
1354 {
1355 // reject the request if it's not a DVD device.
1357 }
1358 }
1359
1360 return status;
1361}
#define IOCTL_DVD_SEND_KEY
Definition: cdrw_usr.h:161
@ DvdInvalidateAGID
Definition: ntddcdvd.h:172
@ DvdSetRpcKey
Definition: ntddcdvd.h:169
Definition: copy.c:22

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateDvdStartSession()

NTSTATUS RequestValidateDvdStartSession ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1225 of file ioctl.c.

1247{
1249
1250 *DataLength = 0;
1251
1252 if (NT_SUCCESS(status))
1253 {
1254 if(RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1255 sizeof(DVD_SESSION_ID))
1256 {
1257 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
1258 "RequestValidateDvdStartSession: DVD_START_SESSION - output "
1259 "buffer too small\n"));
1261 *DataLength = sizeof(DVD_SESSION_ID);
1262 }
1263 else if (DeviceExtension->DeviceAdditionalData.DriveDeviceType != FILE_DEVICE_DVD)
1264 {
1265 // reject the request if it's not a DVD device.
1267 }
1268 }
1269
1270 return status;
1271}

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateEnableStreaming()

NTSTATUS RequestValidateEnableStreaming ( _In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 3515 of file ioctl.c.

3537{
3539
3540 PCDROM_STREAMING_CONTROL inputBuffer = NULL;
3541
3542 *DataLength = 0;
3543
3544 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
3546 {
3548 }
3549
3550 if (NT_SUCCESS(status))
3551 {
3552 // Get the request type using CDROM_STREAMING_CONTROL structure
3553 status = WdfRequestRetrieveInputBuffer(Request,
3555 &inputBuffer,
3556 NULL);
3557 }
3558
3559 if (NT_SUCCESS(status))
3560 {
3561 if (inputBuffer->RequestType != CdromStreamingDisable &&
3565 {
3566 // Unknown request type
3568 }
3569 }
3570
3571 return status;
3572}
@ CdromStreamingDisable
Definition: ntddcdrm.h:479
@ CdromStreamingEnableForWriteOnly
Definition: ntddcdrm.h:481
@ CdromStreamingEnableForReadOnly
Definition: ntddcdrm.h:480
@ CdromStreamingEnableForReadWrite
Definition: ntddcdrm.h:482
STREAMING_CONTROL_REQUEST_TYPE RequestType
Definition: ntddcdrm.h:486

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateExclusiveAccess()

NTSTATUS RequestValidateExclusiveAccess ( _In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 2240 of file ioctl.c.

2262{
2264 PCDROM_EXCLUSIVE_ACCESS exclusiveAccess = NULL;
2265
2266 *DataLength = 0;
2267
2269 {
2270 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "RequestValidateExclusiveAccess: IOCTL must be called at passive level.\n"));
2272 }
2273 else if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(CDROM_EXCLUSIVE_ACCESS))
2274 {
2275
2276 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "RequestValidateExclusiveAccess: Input buffer too small\n"));
2278 }
2279
2280 if (NT_SUCCESS(status))
2281 {
2282 status = WdfRequestRetrieveInputBuffer(Request,
2284 &exclusiveAccess,
2285 NULL);
2286 }
2287
2288 if (NT_SUCCESS(status))
2289 {
2290 switch (exclusiveAccess->RequestType)
2291 {
2293 {
2294 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
2296 {
2297 //
2298 // Output buffer too small.
2299 //
2300 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "RequestValidateExclusiveAccess: Output buffer too small\n"));
2303 }
2304 break;
2305 }
2306
2308 {
2309 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
2310 sizeof(CDROM_EXCLUSIVE_LOCK))
2311 {
2312 //
2313 // Input buffer too small
2314 //
2315 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "RequestValidateExclusiveAccess: Input buffer too small\n"));
2317 }
2318 break;
2319 }
2321 {
2322 //
2323 // Nothing to check
2324 //
2325 break;
2326 }
2327
2328 default:
2329 {
2330 //
2331 // Unknown request type.
2332 //
2333 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "RequestValidateExclusiveAccess: Invalid request type\n"));
2335 }
2336 }
2337 }
2338
2339 return status;
2340}
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
struct _CDROM_EXCLUSIVE_LOCK_STATE CDROM_EXCLUSIVE_LOCK_STATE
@ ExclusiveAccessQueryState
Definition: ntddcdrm.h:412
@ ExclusiveAccessLockDevice
Definition: ntddcdrm.h:413
@ ExclusiveAccessUnlockDevice
Definition: ntddcdrm.h:414
EXCLUSIVE_ACCESS_REQUEST_TYPE RequestType
Definition: ntddcdrm.h:419

Referenced by RequestDispatchSyncWithSequentialQueue().

◆ RequestValidateGetConfiguration()

NTSTATUS RequestValidateGetConfiguration ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1364 of file ioctl.c.

1388{
1390
1391 *DataLength = 0;
1392
1393 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1395 {
1398 }
1399 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength > 0xffff)
1400 {
1401 // output buffer is too large
1403 }
1404 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength &
1405 DeviceExtension->AdapterDescriptor->AlignmentMask)
1406 {
1407 // buffer is not proper size multiple
1409 }
1410
1411 if (NT_SUCCESS(status))
1412 {
1413
1414#if BUILD_WOW64_ENABLED && defined(_WIN64)
1415
1416 if (WdfRequestIsFrom32BitProcess(Request))
1417 {
1418 PGET_CONFIGURATION_IOCTL_INPUT32 inputBuffer = NULL;
1419
1420 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
1421 sizeof(GET_CONFIGURATION_IOCTL_INPUT32))
1422 {
1424 }
1425
1426 //
1427 // also verify the arguments are reasonable.
1428 //
1429 if (NT_SUCCESS(status))
1430 {
1431 status = WdfRequestRetrieveInputBuffer(Request,
1433 &inputBuffer,
1434 NULL);
1435 }
1436
1437 if (NT_SUCCESS(status))
1438 {
1439 if (inputBuffer->Feature > 0xffff)
1440 {
1442 }
1443 else if ((inputBuffer->RequestType != SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE) &&
1444 (inputBuffer->RequestType != SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT) &&
1445 (inputBuffer->RequestType != SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL))
1446 {
1448 }
1449 else if (inputBuffer->Reserved[0] || inputBuffer->Reserved[1])
1450 {
1452 }
1453 }
1454 }
1455 else
1456
1457#endif
1458
1459 {
1461
1462 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
1464 {
1466 }
1467
1468 // also verify the arguments are reasonable.
1469 if (NT_SUCCESS(status))
1470 {
1471 status = WdfRequestRetrieveInputBuffer(Request,
1473 &inputBuffer,
1474 NULL);
1475 }
1476
1477 if (NT_SUCCESS(status))
1478 {
1479 if (inputBuffer->Feature > 0xffff)
1480 {
1482 }
1483 else if ((inputBuffer->RequestType != SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE) &&
1486 {
1488 }
1489 else if (inputBuffer->Reserved[0] || inputBuffer->Reserved[1])
1490 {
1492 }
1493 }
1494 }
1495 }
1496
1497 return status;
1498}
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE
Definition: ntddmmc.h:17
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL
Definition: ntddmmc.h:15
#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT
Definition: ntddmmc.h:16
struct _GET_CONFIGURATION_HEADER GET_CONFIGURATION_HEADER

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateGetLastSession()

NTSTATUS RequestValidateGetLastSession ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1029 of file ioctl.c.

1051{
1053
1054 *DataLength = 0;
1055
1056 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1057 sizeof(CDROM_TOC_SESSION_DATA))
1058 {
1061 }
1062 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength &
1063 DeviceExtension->AdapterDescriptor->AlignmentMask)
1064 {
1066 }
1067
1068 return status;
1069}
struct _CDROM_TOC_SESSION_DATA CDROM_TOC_SESSION_DATA

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateGetPerformance()

NTSTATUS RequestValidateGetPerformance ( _In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 3634 of file ioctl.c.

3656{
3658 PCDROM_WRITE_SPEED_REQUEST writeSpeedRequest = NULL;
3659 PCDROM_PERFORMANCE_REQUEST performanceRequest = NULL;
3660
3661 *DataLength = 0;
3662
3663 // CDROM_WRITE_SPEED_REQUEST is the smallest performance request that we support.
3664 // We use it to retrieve request type and then check input length more carefully
3665 // on a per request type basis.
3666 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
3668 {
3670 }
3671
3672 if (NT_SUCCESS(status))
3673 {
3674 status = WdfRequestRetrieveInputBuffer(Request,
3676 (PVOID*)&writeSpeedRequest,
3677 NULL);
3678 }
3679
3680 if (NT_SUCCESS(status))
3681 {
3682 if (writeSpeedRequest->RequestType == CdromPerformanceRequest)
3683 {
3684 // CDROM_PERFORMANCE_REQUEST is bigger than CDROM_WRITE_SPEED_REQUEST,
3685 // so we perform more checks and retrieve more bytes through WDF.
3686 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
3688 {
3690 }
3691 if (NT_SUCCESS(status))
3692 {
3693 status = WdfRequestRetrieveInputBuffer(Request,
3695 &performanceRequest,
3696 NULL);
3697 }
3698
3699 if (!NT_SUCCESS(status))
3700 {
3701 // just pass the status code from above
3702 }
3703 // validate all enum-type fields of CDROM_PERFORMANCE_REQUEST
3704 else if (performanceRequest->PerformanceType != CdromReadPerformance &&
3705 performanceRequest->PerformanceType != CdromWritePerformance)
3706 {
3708 }
3709 else if (performanceRequest->Exceptions != CdromNominalPerformance &&
3710 performanceRequest->Exceptions != CdromEntirePerformanceList &&
3711 performanceRequest->Exceptions != CdromPerformanceExceptionsOnly)
3712 {
3714 }
3715 else if (performanceRequest->Tolerance != Cdrom10Nominal20Exceptions)
3716 {
3718 }
3719 }
3720 else if (writeSpeedRequest->RequestType == CdromWriteSpeedRequest)
3721 {
3722 // No additional checks here: all remaining fields are ignored
3723 // if RequestType == CdromWriteSpeedRequest.
3724 }
3725 else
3726 {
3728 }
3729 }
3730
3731 // finally, check output buffer length
3732 if (NT_SUCCESS(status))
3733 {
3734 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
3736 {
3739 }
3740 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength >
3741 ((USHORT)-1))
3742 {
3744 }
3745 }
3746
3747 return status;
3748}
@ CdromNominalPerformance
Definition: ntddcdrm.h:521
@ CdromEntirePerformanceList
Definition: ntddcdrm.h:522
@ CdromPerformanceExceptionsOnly
Definition: ntddcdrm.h:523
struct _CDROM_PERFORMANCE_HEADER CDROM_PERFORMANCE_HEADER
@ Cdrom10Nominal20Exceptions
Definition: ntddcdrm.h:528
@ CdromReadPerformance
Definition: ntddcdrm.h:515
@ CdromWritePerformance
Definition: ntddcdrm.h:516
@ CdromPerformanceRequest
Definition: ntddcdrm.h:509
@ CdromWriteSpeedRequest
Definition: ntddcdrm.h:510
CDROM_PERFORMANCE_TYPE PerformanceType
Definition: ntddcdrm.h:534
CDROM_PERFORMANCE_EXCEPTION_TYPE Exceptions
Definition: ntddcdrm.h:535
CDROM_PERFORMANCE_TOLERANCE_TYPE Tolerance
Definition: ntddcdrm.h:536
CDROM_PERFORMANCE_REQUEST_TYPE RequestType
Definition: ntddcdrm.h:542

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidatePersistentReserve()

NTSTATUS RequestValidatePersistentReserve ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 6715 of file ioctl.c.

6740{
6742 ULONG ioctlCode = RequestParameters.Parameters.DeviceIoControl.IoControlCode;
6743
6744 PPERSISTENT_RESERVE_COMMAND reserveCommand = NULL;
6745
6746 *DataLength = 0;
6747
6748 status = WdfRequestRetrieveInputBuffer(Request,
6750 (PVOID*)&reserveCommand,
6751 NULL);
6752 if (NT_SUCCESS(status))
6753 {
6754 if ((RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(PERSISTENT_RESERVE_COMMAND)) ||
6755 (reserveCommand->Size < sizeof(PERSISTENT_RESERVE_COMMAND)))
6756 {
6757 *DataLength = 0;
6759 }
6760 else if ((ULONG_PTR)reserveCommand & DeviceExtension->AdapterDescriptor->AlignmentMask)
6761 {
6762 // Check buffer alignment. Only an issue if another kernel mode component
6763 // (not the I/O manager) allocates the buffer.
6764 *DataLength = 0;
6766 }
6767 }
6768
6769 if (NT_SUCCESS(status))
6770 {
6771 if (ioctlCode == IOCTL_STORAGE_PERSISTENT_RESERVE_IN)
6772 {
6773 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < reserveCommand->PR_IN.AllocationLength)
6774 {
6775 *DataLength = 0;
6777 }
6778 else
6779 {
6780 switch (reserveCommand->PR_IN.ServiceAction)
6781 {
6783 if (reserveCommand->PR_IN.AllocationLength < sizeof(PRI_REGISTRATION_LIST))
6784 {
6785 *DataLength = 0;
6787 }
6788 break;
6789
6791 if (reserveCommand->PR_IN.AllocationLength < sizeof(PRI_RESERVATION_LIST))
6792 {
6793 *DataLength = 0;
6795 }
6796 break;
6797
6798 default:
6799 *DataLength = 0;
6801 break;
6802 }
6803 }
6804 }
6805 else // case of IOCTL_STORAGE_PERSISTENT_RESERVE_OUT
6806 {
6807 // Verify ServiceAction, Scope, and Type
6808 switch (reserveCommand->PR_OUT.ServiceAction)
6809 {
6813 // Scope and type ignored.
6814 break;
6815
6820 if (!ValidPersistentReserveScope(reserveCommand->PR_OUT.Scope) ||
6821 !ValidPersistentReserveType(reserveCommand->PR_OUT.Type))
6822 {
6823 *DataLength = 0;
6825 }
6826 break;
6827
6828 default:
6829 *DataLength = 0;
6831 break;
6832 }
6833
6834 // Check input buffer for PR Out.
6835 // Caller must include the PR parameter list.
6836 if (NT_SUCCESS(status))
6837 {
6838 if ((RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
6839 (sizeof(PERSISTENT_RESERVE_COMMAND) + sizeof(PRO_PARAMETER_LIST))) ||
6840 (reserveCommand->Size < RequestParameters.Parameters.DeviceIoControl.InputBufferLength))
6841 {
6842 *DataLength = 0;
6844 }
6845 }
6846 } // end of validation for IOCTL_STORAGE_PERSISTENT_RESERVE_OUT
6847 }
6848
6849 return status;
6850} // end RequestValidatePersistentReserve()
static BOOLEAN ValidPersistentReserveScope(UCHAR Scope)
Definition: ioctl.c:6680
static BOOLEAN ValidPersistentReserveType(UCHAR Type)
Definition: ioctl.c:6697
#define IOCTL_STORAGE_PERSISTENT_RESERVE_IN
Definition: ntddstor.h:169
#define RESERVATION_ACTION_REGISTER
Definition: scsi.h:579
#define RESERVATION_ACTION_RESERVE
Definition: scsi.h:580
#define RESERVATION_ACTION_RELEASE
Definition: scsi.h:581
#define RESERVATION_ACTION_REGISTER_IGNORE_EXISTING
Definition: scsi.h:585
#define RESERVATION_ACTION_READ_KEYS
Definition: scsi.h:576
#define RESERVATION_ACTION_PREEMPT_ABORT
Definition: scsi.h:584
#define RESERVATION_ACTION_CLEAR
Definition: scsi.h:582
#define RESERVATION_ACTION_PREEMPT
Definition: scsi.h:583
#define RESERVATION_ACTION_READ_RESERVATIONS
Definition: scsi.h:577
struct _PERSISTENT_RESERVE_COMMAND::@3171::@3173 PR_OUT
struct _PERSISTENT_RESERVE_COMMAND::@3171::@3172 PR_IN
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateRawRead()

NTSTATUS RequestValidateRawRead ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 650 of file ioctl.c.

674{
676 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
677
678 PVOID inputBuffer = NULL;
679 PIRP irp = NULL;
680 PIO_STACK_LOCATION currentStack = NULL;
681
682 LARGE_INTEGER startingOffset = {0};
683 ULONGLONG transferBytes = 0;
684 ULONGLONG endOffset;
685 ULONGLONG mdlBytes;
686 RAW_READ_INFO rawReadInfo = {0};
687
688 *DataLength = 0;
689
690 irp = WdfRequestWdmGetIrp(Request);
691 currentStack = IoGetCurrentIrpStackLocation(irp);
692
693 status = WdfRequestRetrieveInputBuffer(Request,
695 &inputBuffer,
696 NULL);
697
698 // Check that ending sector is on disc and buffers are there and of
699 // correct size.
700 if (NT_SUCCESS(status) &&
701 (RequestParameters.Parameters.DeviceIoControl.Type3InputBuffer == NULL))
702 {
703 // This is a call from user space. This is the only time that we need to validate parameters.
704 // Validate the input and get the input buffer into Type3InputBuffer
705 // so the rest of the code will be uniform.
706 if (inputBuffer != NULL)
707 {
708 currentStack->Parameters.DeviceIoControl.Type3InputBuffer = inputBuffer;
709 RequestParameters.Parameters.DeviceIoControl.Type3InputBuffer = inputBuffer;
710
711 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(RAW_READ_INFO))
712 {
713 *DataLength = sizeof(RAW_READ_INFO);
715 }
716 }
717 else
718 {
720 }
721 }
722
723 if (NT_SUCCESS(status))
724 {
725 // Since this ioctl is METHOD_OUT_DIRECT, we need to copy away the input buffer before interpreting it.
726 // This prevents a malicious app from messing with the input buffer while we are interpreting it.
727 rawReadInfo = *(PRAW_READ_INFO)RequestParameters.Parameters.DeviceIoControl.Type3InputBuffer;
728
729 startingOffset.QuadPart = rawReadInfo.DiskOffset.QuadPart;
730
731 if ((rawReadInfo.TrackMode == CDDA) ||
732 (rawReadInfo.TrackMode == YellowMode2) ||
733 (rawReadInfo.TrackMode == XAForm2) )
734 {
735 transferBytes = (ULONGLONG)rawReadInfo.SectorCount * RAW_SECTOR_SIZE;
736 }
737 else if (rawReadInfo.TrackMode == RawWithSubCode)
738 {
739 transferBytes = (ULONGLONG)rawReadInfo.SectorCount * CD_RAW_SECTOR_WITH_SUBCODE_SIZE;
740 }
741 else if (rawReadInfo.TrackMode == RawWithC2)
742 {
743 transferBytes = (ULONGLONG)rawReadInfo.SectorCount * CD_RAW_SECTOR_WITH_C2_SIZE;
744 }
745 else if (rawReadInfo.TrackMode == RawWithC2AndSubCode)
746 {
747 transferBytes = (ULONGLONG)rawReadInfo.SectorCount * CD_RAW_SECTOR_WITH_C2_AND_SUBCODE_SIZE;
748 }
749 else
750 {
751 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
752 "RequestValidateRawRead: Invalid TrackMode type %x for XA read\n",
753 rawReadInfo.TrackMode
754 ));
755 }
756
757 endOffset = (ULONGLONG)rawReadInfo.SectorCount * COOKED_SECTOR_SIZE;
758 endOffset += startingOffset.QuadPart;
759
760 // check for overflows....
761 if (rawReadInfo.SectorCount == 0)
762 {
763 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
764 "RequestValidateRawRead: Invalid I/O parameters for XA "
765 "Read (zero sectors requested)\n"));
767 }
768 else if (transferBytes < (ULONGLONG)(rawReadInfo.SectorCount))
769 {
770 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
771 "RequestValidateRawRead: Invalid I/O parameters for XA "
772 "Read (TransferBytes Overflow)\n"));
774 }
775 else if (endOffset < (ULONGLONG)startingOffset.QuadPart)
776 {
777 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
778 "RequestValidateRawRead: Invalid I/O parameters for XA "
779 "Read (EndingOffset Overflow)\n"));
781 }
782 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < transferBytes)
783 {
784 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
785 "RequestValidateRawRead: Invalid I/O parameters for XA "
786 "Read (Bad buffer size)\n"));
788 }
789 else if (endOffset > (ULONGLONG)DeviceExtension->PartitionLength.QuadPart)
790 {
791 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
792 "RequestValidateRawRead: Invalid I/O parameters for XA "
793 "Read (Request Out of Bounds)\n"));
795 }
796 }
797
798 if (NT_SUCCESS(status))
799 {
800 // cannot validate the MdlAddress, since it is not included in any
801 // other location per the DDK and file system calls.
802
803 // validate the mdl describes at least the number of bytes
804 // requested from us.
805 mdlBytes = (ULONGLONG)MmGetMdlByteCount(irp->MdlAddress);
806 if (mdlBytes < transferBytes)
807 {
808 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
809 "RequestValidateRawRead: Invalid MDL %s, Irp %p\n",
810 "size (5)", irp));
812 }
813 }
814
815 if (NT_SUCCESS(status))
816 {
817 // check the buffer for alignment
818 // This is important for x86 as some busses (ie ATAPI)
819 // require word-aligned buffers.
820 if ( ((ULONG_PTR)MmGetMdlVirtualAddress(irp->MdlAddress)) &
821 DeviceExtension->AdapterDescriptor->AlignmentMask )
822 {
823 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
824 "RequestValidateRawRead: Invalid I/O parameters for "
825 "XA Read (Buffer %p not aligned with mask %x\n",
827 DeviceExtension->AdapterDescriptor->AlignmentMask));
829 }
830 }
831
832 if (NT_SUCCESS(status))
833 {
834 // Validate the request is not too large for the adapter
835 BOOLEAN bufferIsPageAligned = FALSE;
836 ULONG maxLength = 0;
837
838 // if buffer is not page-aligned, then subtract one as the
839 // transfer could cross a page boundary.
840 if ((((ULONG_PTR)MmGetMdlVirtualAddress(irp->MdlAddress)) & (PAGE_SIZE-1)) == 0)
841 {
842 bufferIsPageAligned = TRUE;
843 }
844
845 if (bufferIsPageAligned)
846 {
848 }
849 else
850 {
852 }
853
854 if (transferBytes > maxLength)
855 {
856 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
857 "RequestValidateRawRead: The XA Read (type %x) would require %I64x bytes, "
858 "but the adapter can only handle %x bytes (for a%saligned buffer)\n",
859 rawReadInfo.TrackMode,
860 transferBytes,
861 maxLength,
862 (bufferIsPageAligned ? " " : "n un")
863 ));
865 }
866 }
867
868 if (NT_SUCCESS(status))
869 {
870 //
871 // HACKHACK - REF #0001
872 // The retry count will be in this irp's IRP_MN function,
873 // as the new irp was freed, and we therefore cannot use
874 // this irp's next stack location for this function.
875 // This may be a good location to store this info for
876 // when we remove RAW_READ (mode switching), as we will
877 // no longer have the nextIrpStackLocation to play with
878 // when that occurs
879 //
880 currentStack->MinorFunction = MAXIMUM_RETRIES; // HACKHACK - REF #0001
881 }
882
883 return status;
884}
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define COOKED_SECTOR_SIZE
Definition: cdrom.h:694
#define RAW_SECTOR_SIZE
Definition: mcicda.c:50
if(dx< 0)
Definition: linetemp.h:194
#define CD_RAW_SECTOR_WITH_C2_AND_SUBCODE_SIZE
Definition: ntddcdrm.h:391
@ XAForm2
Definition: ntddcdrm.h:380
@ CDDA
Definition: ntddcdrm.h:381
@ RawWithC2AndSubCode
Definition: ntddcdrm.h:382
@ YellowMode2
Definition: ntddcdrm.h:379
@ RawWithSubCode
Definition: ntddcdrm.h:384
@ RawWithC2
Definition: ntddcdrm.h:383
struct __RAW_READ_INFO RAW_READ_INFO
#define CD_RAW_SECTOR_WITH_C2_SIZE
Definition: ntddcdrm.h:389
#define CD_RAW_SECTOR_WITH_SUBCODE_SIZE
Definition: ntddcdrm.h:390
struct __RAW_READ_INFO * PRAW_READ_INFO
struct _IO_STACK_LOCATION::@1581::@1582 DeviceIoControl
TRACK_MODE_TYPE TrackMode
Definition: ntddcdrm.h:396
ULONG SectorCount
Definition: ntddcdrm.h:395
LARGE_INTEGER DiskOffset
Definition: ntddcdrm.h:394
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
#define MmGetMdlByteCount(_Mdl)

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateReadQChannel()

NTSTATUS RequestValidateReadQChannel ( _In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1072 of file ioctl.c.

1094{
1096 PCDROM_SUB_Q_DATA_FORMAT inputBuffer = NULL;
1097 ULONG transferByteCount = 0;
1098
1099 *DataLength = 0;
1100
1101 if(RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
1103 {
1105 }
1106
1107 if (NT_SUCCESS(status))
1108 {
1109 status = WdfRequestRetrieveInputBuffer(Request,
1111 &inputBuffer,
1112 NULL);
1113 }
1114
1115 if (NT_SUCCESS(status))
1116 {
1117 // check for all valid types of request
1118 if (inputBuffer->Format == IOCTL_CDROM_CURRENT_POSITION)
1119 {
1120 transferByteCount = sizeof(SUB_Q_CURRENT_POSITION);
1121 }
1122 else if (inputBuffer->Format == IOCTL_CDROM_MEDIA_CATALOG)
1123 {
1124 transferByteCount = sizeof(SUB_Q_MEDIA_CATALOG_NUMBER);
1125 }
1126 else if (inputBuffer->Format == IOCTL_CDROM_TRACK_ISRC)
1127 {
1128 transferByteCount = sizeof(SUB_Q_TRACK_ISRC);
1129 }
1130 else
1131 {
1132 // Format not valid
1134 }
1135 }
1136
1137 if (NT_SUCCESS(status))
1138 {
1139 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1140 transferByteCount)
1141 {
1143 *DataLength = transferByteCount;
1144 }
1145 }
1146
1147 return status;
1148}
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
#define IOCTL_CDROM_MEDIA_CATALOG
Definition: cdrw_usr.h:1355
#define IOCTL_CDROM_TRACK_ISRC
Definition: cdrw_usr.h:1356
struct _SUB_Q_MEDIA_CATALOG_NUMBER SUB_Q_MEDIA_CATALOG_NUMBER
struct _SUB_Q_CURRENT_POSITION SUB_Q_CURRENT_POSITION
struct _SUB_Q_TRACK_ISRC SUB_Q_TRACK_ISRC

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateReadToc()

NTSTATUS RequestValidateReadToc ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 984 of file ioctl.c.

1006{
1008
1009 *DataLength = 0;
1010
1011 if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
1012 sizeof(CDROM_TOC))
1013 {
1014 // they didn't request the entire TOC -- use _EX version
1015 // for partial transfers and such.
1017 *DataLength = sizeof(CDROM_TOC);
1018 }
1019 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength &
1020 DeviceExtension->AdapterDescriptor->AlignmentMask)
1021 {
1023 }
1024
1025 return status;
1026}
struct _CDROM_TOC CDROM_TOC

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateReadTocEx()

NTSTATUS RequestValidateReadTocEx ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 887 of file ioctl.c.

911{
913
914 PCDROM_READ_TOC_EX inputBuffer = NULL;
915
916 *DataLength = 0;
917
918 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
919 sizeof(CDROM_READ_TOC_EX))
920 {
922 }
923 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength <
925 {
928 }
929 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength >
930 ((USHORT)-1))
931 {
933 }
934 else if (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength &
935 DeviceExtension->AdapterDescriptor->AlignmentMask)
936 {
938 }
939
940 if (NT_SUCCESS(status))
941 {
942 status = WdfRequestRetrieveInputBuffer(Request,
944 &inputBuffer,
945 NULL);
946 }
947
948 if (NT_SUCCESS(status))
949 {
950 if ((inputBuffer->Reserved1 != 0) ||
951 (inputBuffer->Reserved2 != 0) ||
952 (inputBuffer->Reserved3 != 0))
953 {
955 }
956 // NOTE: when adding new formats, ensure that first two bytes
957 // specify the amount of additional data available.
958 else if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_TOC ) ||
959 (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_FULL_TOC) ||
960 (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_CDTEXT ))
961 {
962 // SessionTrack field is used
963 }
964 else if ((inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_SESSION) ||
965 (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_PMA) ||
966 (inputBuffer->Format == CDROM_READ_TOC_EX_FORMAT_ATIP))
967 {
968 // SessionTrack field is reserved
969 if (inputBuffer->SessionTrack != 0)
970 {
972 }
973 }
974 else
975 {
977 }
978 }
979
980 return status;
981}
#define CDROM_READ_TOC_EX_FORMAT_SESSION
Definition: ntddcdrm.h:163
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC
Definition: ntddcdrm.h:164
#define CDROM_READ_TOC_EX_FORMAT_PMA
Definition: ntddcdrm.h:165
#define CDROM_READ_TOC_EX_FORMAT_TOC
Definition: ntddcdrm.h:162
#define CDROM_READ_TOC_EX_FORMAT_ATIP
Definition: ntddcdrm.h:166
#define MINIMUM_CDROM_READ_TOC_EX_SIZE
Definition: ntddcdrm.h:133
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT
Definition: ntddcdrm.h:167

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateReadWrite()

NTSTATUS RequestValidateReadWrite ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters 
)

Definition at line 6117 of file ioctl.c.

6139{
6141 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
6142
6143 BOOLEAN isValid = TRUE;
6144 LONGLONG startingOffset = 0;
6145 size_t transferByteCount = 0;
6146 PIRP irp = NULL;
6147 PIO_STACK_LOCATION currentStack = NULL;
6148
6149 irp = WdfRequestWdmGetIrp(Request);
6150 currentStack = IoGetCurrentIrpStackLocation(irp);
6151
6152 if (TEST_FLAG(DeviceExtension->DeviceObject->Flags, DO_VERIFY_VOLUME) &&
6153 (currentStack->MinorFunction != CDROM_VOLUME_VERIFY_CHECKED) &&
6154 !TEST_FLAG(currentStack->Flags, SL_OVERRIDE_VERIFY_VOLUME))
6155 {
6156 // DO_VERIFY_VOLUME is set for the device object,
6157 // but this request is not itself a verify request.
6158 // So fail this request.
6159
6160 //set the status for volume verification.
6162 }
6163
6164 if (NT_SUCCESS(status))
6165 {
6166 if (PLAY_ACTIVE(DeviceExtension))
6167 {
6169 }
6170 }
6171
6172 if (NT_SUCCESS(status))
6173 {
6174 // If the device is in exclusive mode, check whether the request is from
6175 // the handle that locked the device.
6176 if (EXCLUSIVE_MODE(cdData) && !EXCLUSIVE_OWNER(cdData, WdfRequestGetFileObject(Request)))
6177 {
6178 // This request is not from the owner. We can't let the operation go.
6179 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "RequestValidateReadWrite: Access Denied! Device in exclusive mode.\n"));
6180
6182 }
6183 }
6184
6185 // Validate the request alignment.
6186 if (NT_SUCCESS(status))
6187 {
6189 {
6190 startingOffset = RequestParameters.Parameters.Read.DeviceOffset;
6191 transferByteCount = RequestParameters.Parameters.Read.Length;
6192 }
6193 else
6194 {
6195 startingOffset = RequestParameters.Parameters.Write.DeviceOffset;
6196 transferByteCount = RequestParameters.Parameters.Write.Length;
6197 }
6198
6199 if (!DeviceExtension->DiskGeometry.BytesPerSector)
6200 {
6201 DeviceExtension->DiskGeometry.BytesPerSector = 2048;
6202 }
6203
6204 if (!DeviceExtension->SectorShift)
6205 {
6206 DeviceExtension->SectorShift = 11;
6207 }
6208
6209 // Perform some basic validation up front
6210 if (TEST_FLAG(startingOffset, DeviceExtension->DiskGeometry.BytesPerSector - 1) ||
6211 TEST_FLAG(transferByteCount, DeviceExtension->DiskGeometry.BytesPerSector - 1))
6212 {
6214 }
6215 }
6216
6217 // validate the request against the current mmc schema
6218 if (NT_SUCCESS(status))
6219 {
6221
6222 // We validate read requests according to the RandomWritable schema, except in the
6223 // case of IncrementalStreamingWritable, wherein the drive is responsible for all
6224 // of the verification
6226 {
6227 if (!cdData->Mmc.WriteAllowed)
6228 {
6229 // standard legacy validation of read irps
6230 // if writing is not allowed on the media
6232 }
6234 {
6235 // standard legacy validation of read irps
6236 // if not using streaming writes on writable media
6238 }
6239 }
6240
6241 // Fail write requests to read-only media
6243 !(cdData->Mmc.WriteAllowed))
6244 {
6245 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "RequestValidateReadWrite: Write request to read-only media\n"));
6246 isValid = FALSE;
6247 }
6248
6249 if (isValid)
6250 {
6251 switch (schema)
6252 {
6255 // Ensure that the request is within bounds for ROM drives.
6256 // Writer drives do not need to have bounds as outbounds request should not damage the drive.
6257 if(!cdData->Mmc.IsWriter)
6258 {
6259 if ((startingOffset >= DeviceExtension->PartitionLength.QuadPart) ||
6260 startingOffset < 0)
6261 {
6262 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "RequestValidateReadWrite: Request is out of bounds\n"));
6263 isValid = FALSE;
6264
6265 }
6266 else
6267 {
6268 ULONGLONG bytesRemaining = DeviceExtension->PartitionLength.QuadPart - startingOffset;
6269
6270 if ((ULONGLONG)transferByteCount > bytesRemaining)
6271 {
6272 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "RequestValidateReadWrite: Request is out of bounds\n"));
6273 isValid = FALSE;
6274 }
6275 }
6276 }
6277 break;
6278
6280 // Ensure that the number of blocks is a multiple of the blocking size
6281 if (((transferByteCount >> DeviceExtension->SectorShift) % cdData->Mmc.Blocking) != 0)
6282 {
6283 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW,
6284 "RequestValidateReadWrite: Number of blocks is not a multiple of the blocking size (%x)\n",
6285 cdData->Mmc.Blocking));
6286
6287 isValid = FALSE;
6288 }
6289 // Fall through
6291 // Ensure that the request begins on a blocking boundary
6292 if ((Int64ShrlMod32(startingOffset, DeviceExtension->SectorShift) % cdData->Mmc.Blocking) != 0)
6293 {
6294 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW,
6295 "RequestValidateReadWrite: Starting block is not a multiple of the blocking size (%x)\n",
6296 cdData->Mmc.Blocking));
6297
6298 isValid = FALSE;
6299 }
6300 break;
6301
6303 // Let the drive handle the verification
6304 break;
6305
6306 default:
6307 // Unknown schema. Fail the request
6308 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW,
6309 "RequestValidateReadWrite: Unknown validation schema (%x)\n",
6310 schema));
6311
6312 isValid = FALSE;
6313 break;
6314 } //end of switch (schema)
6315 } // end of if (isValid)
6316
6317 if (!isValid)
6318 {
6320 }
6321 } // end of mmc schema validation
6322
6323 // validate that the Real-Time Streaming requests meet device capabilties
6324 if (NT_SUCCESS(status))
6325 {
6326 // We do not check for FDO_HACK_NO_STREAMING in DeviceExtension->PrivateFdoData->HackFlags here,
6327 // because we're going to hide device failures related to streaming reads/writes from the sender
6328 // of the request. FDO_HACK_NO_STREAMING is going to be taken into account later during actual
6329 // processing of the request.
6331 {
6333 {
6334 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW,
6335 "RequestValidateReadWrite: Streaming reads are not supported.\n"));
6336
6338 }
6340 {
6341 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW,
6342 "RequestValidateReadWrite: Streaming writes are not supported.\n"));
6343
6345 }
6346 }
6347 }
6348
6349 return status;
6350}
#define PLAY_ACTIVE(x)
Definition: cdrom.h:698
#define CDROM_VOLUME_VERIFY_CHECKED
Definition: cdromp.h:171
BOOLEAN RequestIsRealtimeStreaming(_In_ WDFREQUEST Request, _In_ BOOLEAN IsReadRequest)
Definition: ioctl.c:6050
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
const WCHAR * schema
#define Int64ShrlMod32(a, b)
enum _FEATURE_NUMBER FEATURE_NUMBER
@ FeatureRestrictedOverwrite
Definition: ntddmmc.h:90
@ FeatureIncrementalStreamingWritable
Definition: ntddmmc.h:85
@ FeatureRandomWritable
Definition: ntddmmc.h:84
@ FeatureDefectManagement
Definition: ntddmmc.h:88
@ FeatureRigidRestrictedOverwrite
Definition: ntddmmc.h:96
FEATURE_NUMBER ValidationSchema
Definition: cdrom.h:260
BOOLEAN StreamingReadSupported
Definition: cdrom.h:253
BOOLEAN StreamingWriteSupported
Definition: cdrom.h:254
BOOLEAN IsWriter
Definition: cdrom.h:249
int64_t LONGLONG
Definition: typedefs.h:68
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
@ WdfRequestTypeWrite
Definition: wdfdevice.h:507
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823

Referenced by ReadWriteWorkItemRoutine(), and SequentialQueueEvtIoReadWrite().

◆ RequestValidateSendOpcInformation()

NTSTATUS RequestValidateSendOpcInformation ( _In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 3576 of file ioctl.c.

3598{
3600
3601 PCDROM_SIMPLE_OPC_INFO inputBuffer = NULL;
3602
3603 *DataLength = 0;
3604
3605 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength <
3606 sizeof(CDROM_SIMPLE_OPC_INFO))
3607 {
3609 }
3610
3611 if (NT_SUCCESS(status))
3612 {
3613 // Get the request type using CDROM_SIMPLE_OPC_INFO structure
3614 status = WdfRequestRetrieveInputBuffer(Request,
3615 sizeof(CDROM_SIMPLE_OPC_INFO),
3616 &inputBuffer,
3617 NULL);
3618 }
3619
3620 if (NT_SUCCESS(status))
3621 {
3622 if (inputBuffer->RequestType != SimpleOpcInfo)
3623 {
3624 // Unknown request type
3626 }
3627 }
3628
3629 return status;
3630}
@ SimpleOpcInfo
Definition: ntddcdrm.h:494
CDROM_OPC_INFO_TYPE RequestType
Definition: ntddcdrm.h:499

Referenced by RequestDispatchToSequentialQueue().

◆ RequestValidateSetSpeed()

NTSTATUS RequestValidateSetSpeed ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 1501 of file ioctl.c.

1525{
1527 PCDROM_DATA cdData = &(DeviceExtension->DeviceAdditionalData);
1528 PCDROM_SET_SPEED inputBuffer = NULL;
1529 ULONG requiredLength = 0;
1530
1531 *DataLength = 0;
1532
1533 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(CDROM_SET_SPEED))
1534 {
1536 }
1537
1538 if (NT_SUCCESS(status))
1539 {
1540 // Get the request type using CDROM_SET_SPEED structure
1541 status = WdfRequestRetrieveInputBuffer(Request,
1542 sizeof(CDROM_SET_SPEED),
1543 &inputBuffer,
1544 NULL);
1545
1546 }
1547
1548 if (NT_SUCCESS(status))
1549 {
1550 if (inputBuffer->RequestType > CdromSetStreaming)
1551 {
1552 // Unknown request type.
1554 }
1555 else if (inputBuffer->RequestType == CdromSetSpeed)
1556 {
1557 requiredLength = sizeof(CDROM_SET_SPEED);
1558 }
1559 else
1560 {
1561 // Don't send SET STREAMING command if this is not a MMC compliant device
1562 if (cdData->Mmc.IsMmc == FALSE)
1563 {
1565 }
1566
1567 requiredLength = sizeof(CDROM_SET_STREAMING);
1568 }
1569 }
1570
1571 if (NT_SUCCESS(status))
1572 {
1573 if (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < requiredLength)
1574 {
1575 // Input buffer too small
1577 }
1578 }
1579
1580 return status;
1581}
struct _CDROM_SET_STREAMING CDROM_SET_STREAMING
@ CdromSetSpeed
Definition: ntddcdrm.h:440
@ CdromSetStreaming
Definition: ntddcdrm.h:441
struct _CDROM_SET_SPEED CDROM_SET_SPEED
CDROM_SPEED_REQUEST RequestType
Definition: ntddcdrm.h:452

Referenced by RequestDispatchToSequentialQueue().

◆ ValidPersistentReserveScope()

static BOOLEAN ValidPersistentReserveScope ( UCHAR  Scope)
static

Definition at line 6680 of file ioctl.c.

6682{
6683 switch (Scope) {
6686
6687 return TRUE;
6688
6689 default:
6690
6691 return FALSE;
6692 }
6693}
#define RESERVATION_SCOPE_ELEMENT
Definition: scsi.h:588
#define RESERVATION_SCOPE_LU
Definition: scsi.h:587

Referenced by RequestValidatePersistentReserve().

◆ ValidPersistentReserveType()

static BOOLEAN ValidPersistentReserveType ( UCHAR  Type)
static

Definition at line 6697 of file ioctl.c.

6699{
6700 switch (Type) {
6705
6706 return TRUE;
6707
6708 default:
6709
6710 return FALSE;
6711 }
6712}
Type
Definition: Type.h:7
#define RESERVATION_TYPE_WRITE_EXCLUSIVE
Definition: scsi.h:590
#define RESERVATION_TYPE_EXCLUSIVE_REGISTRANTS
Definition: scsi.h:593
#define RESERVATION_TYPE_EXCLUSIVE
Definition: scsi.h:591
#define RESERVATION_TYPE_WRITE_EXCLUSIVE_REGISTRANTS
Definition: scsi.h:592

Referenced by RequestValidatePersistentReserve().