ReactOS 0.4.15-dev-8614-gbc76250
class.c File Reference
#include "classp.h"
#include "debug.h"
#include <process.h>
#include <devpkey.h>
#include <ntiologc.h>
Include dependency graph for class.c:

Go to the source code of this file.

Macros

#define CLASS_INIT_GUID   1
 
#define DEBUG_MAIN_SOURCE   1
 
#define FirstDriveLetter   'C'
 
#define LastDriveLetter   'Z'
 

Functions

NTSTATUS DllUnload (VOID)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
 _IRQL_requires_max_ (PASSIVE_LEVEL)
 
VOID NTAPI ClassUnload (IN PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI ClassAddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
 
NTSTATUS NTAPI ClassDispatchPnp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS ClassPnpStartDevice (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ClassReadWrite (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID InterpretCapacityData (PDEVICE_OBJECT Fdo, PREAD_CAPACITY_DATA_EX ReadCapacityData)
 
_Must_inspect_result_ NTSTATUS NTAPI ClassReadDriveCapacity (_In_ PDEVICE_OBJECT Fdo)
 
VOID NTAPI ClassSendStartUnit (_In_ PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI ClassAsynchronousCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
NTSTATUS ServiceTransferRequest (PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc)
 
NTSTATUS NTAPI ClassIoComplete (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ClassSendSrbSynchronous (_In_ PDEVICE_OBJECT Fdo, _Inout_ PSCSI_REQUEST_BLOCK _Srb, _In_reads_bytes_opt_(BufferLength) PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
 
BOOLEAN NTAPI ClassInterpretSenseInfo (_In_ PDEVICE_OBJECT Fdo, _In_ PSCSI_REQUEST_BLOCK _Srb, _In_ UCHAR MajorFunctionCode, _In_ ULONG IoDeviceCode, _In_ ULONG RetryCount, _Out_ NTSTATUS *Status, _Out_opt_ _Deref_out_range_(0, 100) ULONG *RetryInterval)
 
ULONG NTAPI ClassModeSense (_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode)
 
ULONG NTAPI ClassModeSenseEx (_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ UCHAR PageControl)
 
ULONG ClasspModeSense (_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ UCHAR PageControl)
 
PVOID NTAPI ClassFindModePage (_In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ BOOLEAN Use6Byte)
 
NTSTATUS NTAPI ClassModeSelect (_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, _In_ ULONG Length, _In_ BOOLEAN SavePages)
 
NTSTATUS ClasspModeSelect (_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, _In_ ULONG Length, _In_ BOOLEAN SavePages)
 
 _Success_ (return==STATUS_PENDING)
 
NTSTATUS NTAPI ClassDeviceControlDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI ClassDeviceControl (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
 
NTSTATUS NTAPI ClassShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS ClasspIsPortable (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _Out_ PBOOLEAN IsPortable)
 
NTSTATUS NTAPI ClassInternalIoControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ClassCheckVerifyComplete (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ClassSignalCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS ClassPnpQueryFdoRelations (IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
 
NTSTATUS ClassRetrieveDeviceRelations (IN PDEVICE_OBJECT Fdo, IN DEVICE_RELATION_TYPE RelationType, OUT PDEVICE_RELATIONS *DeviceRelations)
 
NTSTATUS ClassGetPdoId (IN PDEVICE_OBJECT Pdo, IN BUS_QUERY_ID_TYPE IdType, IN PUNICODE_STRING IdString)
 
NTSTATUS ClassQueryPnpCapabilities (IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_CAPABILITIES Capabilities)
 
__drv_aliasesMem _IRQL_requires_max_ (DISPATCH_LEVEL)
 
VOID NTAPI ClasspStartIo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ClasspSendSynchronousCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
VOID ClasspRegisterMountedDeviceInterface (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI ClassSendDeviceIoControlSynchronous (_In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT TargetDeviceObject, _Inout_updates_opt_(_Inexpressible_(max(InputBufferLength, OutputBufferLength))) PVOID Buffer, _In_ ULONG InputBufferLength, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl, _Out_ PIO_STATUS_BLOCK IoStatus)
 
NTSTATUS NTAPI ClassForwardIrpSynchronous (_In_ PCOMMON_DEVICE_EXTENSION CommonExtension, _In_ PIRP Irp)
 
NTSTATUS NTAPI ClassSendIrpSynchronous (_In_ PDEVICE_OBJECT TargetDeviceObject, _In_ PIRP Irp)
 
PVPB NTAPI ClassGetVpb (_In_ PDEVICE_OBJECT DeviceObject)
 
NTSTATUS ClasspAllocateReleaseRequest (IN PDEVICE_OBJECT Fdo)
 
VOID ClasspFreeReleaseRequest (IN PDEVICE_OBJECT Fdo)
 
VOID NTAPI ClassReleaseQueue (_In_ PDEVICE_OBJECT Fdo)
 
NTSTATUS ClasspAllocateReleaseQueueIrp (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
NTSTATUS ClasspAllocatePowerProcessIrp (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID ClasspReleaseQueue (IN PDEVICE_OBJECT Fdo, IN PIRP ReleaseQueueIrp OPTIONAL)
 
NTSTATUS NTAPI ClassReleaseQueueCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
VOID NTAPI ClassReleaseChildLock (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID ClassAddChild (_In_ PFUNCTIONAL_DEVICE_EXTENSION Parent, _In_ PPHYSICAL_DEVICE_EXTENSION Child, _In_ BOOLEAN AcquireLock)
 
PPHYSICAL_DEVICE_EXTENSION ClassRemoveChild (IN PFUNCTIONAL_DEVICE_EXTENSION Parent, IN PPHYSICAL_DEVICE_EXTENSION Child, IN BOOLEAN AcquireLock)
 
VOID NTAPI ClasspRetryRequestDpc (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID Arg1, IN PVOID Arg2)
 
VOID ClassRetryRequest (IN PDEVICE_OBJECT SelfDeviceObject, IN PIRP Irp, _In_ _In_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) IN LONGLONG TimeDelta100ns)
 
VOID ClasspRetryDpcTimer (IN PCLASS_PRIVATE_FDO_DATA FdoData)
 
NTSTATUS ClasspInitializeHotplugInfo (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClasspScanForClassHacks (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG_PTR Data)
 
VOID ClasspScanForSpecialInRegistry (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClasspUpdateDiskProperties (IN PDEVICE_OBJECT Fdo, IN PVOID Context)
 
BOOLEAN InterpretSenseInfoWithoutHistory (_In_ PDEVICE_OBJECT Fdo, _In_opt_ PIRP OriginalRequest, _In_ PSCSI_REQUEST_BLOCK Srb, UCHAR MajorFunctionCode, ULONG IoDeviceCode, ULONG PreviousRetryCount, _Out_ NTSTATUS *Status, _Out_opt_ _Deref_out_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) LONGLONG *RetryIn100nsUnits)
 
VOID ClasspGetInquiryVpdSupportInfo (_Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
NTSTATUS ClasspGetLBProvisioningInfo (_Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
 _IRQL_requires_ (PASSIVE_LEVEL) ==NDIS_MEMORY_NONCACHED
 
_IRQL_requires_same_ NTSTATUS ClasspGetBlockDeviceTokenLimitsInfo (_Inout_ PDEVICE_OBJECT DeviceObject)
 
 _IRQL_requires_max_ (APC_LEVEL)
 
VOID ClasspCompleteOffloadRequest (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ NTSTATUS CompletionStatus)
 
VOID ClasspPopulateTokenTransferPacketDone (_In_ PVOID Context)
 
VOID ClasspCompleteOffloadRead (_In_ POFFLOAD_READ_CONTEXT OffloadReadContext, _In_ NTSTATUS CompletionStatus)
 
VOID ClasspCleanupOffloadReadContext (_In_ __drv_freesMem(mem) POFFLOAD_READ_CONTEXT OffloadReadContext)
 
_IRQL_requires_same_ VOID ClasspReceivePopulateTokenInformation (_In_ POFFLOAD_READ_CONTEXT OffloadReadContext)
 
VOID ClasspReceivePopulateTokenInformationTransferPacketDone (_In_ PVOID Context)
 
VOID ClasspContinueOffloadWrite (_In_ __drv_aliasesMem POFFLOAD_WRITE_CONTEXT OffloadWriteContext)
 
VOID ClasspAdvanceOffloadWritePosition (_In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext, _In_ ULONGLONG SectorsToAdvance)
 
VOID ClasspWriteUsingTokenTransferPacketDone (_In_ PVOID Context)
 
VOID ClasspReceiveWriteUsingTokenInformationDone (_In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext, _In_ NTSTATUS CompletionCausingStatus)
 
VOID ClasspCompleteOffloadWrite (_In_ __drv_freesMem(Mem) POFFLOAD_WRITE_CONTEXT OffloadWriteContext, _In_ NTSTATUS CompletionCausingStatus)
 
VOID ClasspCleanupOffloadWriteContext (_In_ __drv_freesMem(mem) POFFLOAD_WRITE_CONTEXT OffloadWriteContext)
 
_IRQL_requires_same_ VOID ClasspReceiveWriteUsingTokenInformation (_In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext)
 
VOID ClasspReceiveWriteUsingTokenInformationTransferPacketDone (_In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext)
 
NTSTATUS ClasspRefreshFunctionSupportInfo (_Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN ForceQuery)
 
NTSTATUS ClasspBlockLimitsDataSnapshot (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN ForceQuery, _Out_ PCLASS_VPD_B0_DATA BlockLimitsData, _Out_ PULONG GenerationCount)
 

Variables

IO_COMPLETION_ROUTINE ClassCheckVerifyComplete
 
ULONG ClassPnpAllowUnload = TRUE
 
ULONG ClassMaxInterleavePerCriticalIo = CLASS_MAX_INTERLEAVE_PER_CRITICAL_IO
 
CONST LARGE_INTEGER Magic10000 = {{0xe219652c, 0xd1b71758}}
 
GUID StoragePredictFailureDPSGuid = WDI_STORAGE_PREDICT_FAILURE_DPS_GUID
 
BOOLEAN UseQPCTime = FALSE
 
BOOLEAN InitSecurityCookie = FALSE
 
ULONG MaxTokenOperationListIdentifier = MAX_TOKEN_LIST_IDENTIFIERS
 
volatile ULONG TokenOperationListIdentifier = (ULONG)-1
 
LIST_ENTRY IdlePowerFDOList = {0}
 
KGUARDED_MUTEX IdlePowerFDOListMutex
 
PVOID PowerSettingNotificationHandle
 
PVOID ScreenStateNotificationHandle
 
ULONG DiskIdleTimeoutInMS = 0xFFFFFFFF
 

Macro Definition Documentation

◆ CLASS_INIT_GUID

#define CLASS_INIT_GUID   1

Definition at line 24 of file class.c.

◆ DEBUG_MAIN_SOURCE

#define DEBUG_MAIN_SOURCE   1

Definition at line 25 of file class.c.

◆ FirstDriveLetter

#define FirstDriveLetter   'C'

Definition at line 92 of file class.c.

◆ LastDriveLetter

#define LastDriveLetter   'Z'

Definition at line 93 of file class.c.

Function Documentation

◆ _IRQL_requires_()

_IRQL_requires_ ( PASSIVE_LEVEL  ) ==NDIS_MEMORY_NONCACHED

Definition at line 13147 of file class.c.

13175{
13177
13178 PAGED_CODE();
13179
13180 TracePrint((TRACE_LEVEL_VERBOSE,
13181 TRACE_FLAG_PNP,
13182 "ClassDetermineTokenOperationCommandSupport (%p): Entering function.\n",
13183 DeviceObject));
13184
13185 //
13186 // Send down Inquiry for VPD_THIRD_PARTY_COPY_PAGE and cache away the device parameters
13187 // from WINDOWS_BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR.
13188 //
13190
13191 if (NT_SUCCESS(status)) {
13192
13193 ULONG maxListIdentifier = MaxTokenOperationListIdentifier;
13194
13195 //
13196 // Query the maximum list identifier to use for TokenOperation commands.
13197 //
13198 if (NT_SUCCESS(ClasspGetMaximumTokenListIdentifier(DeviceObject, REG_DISK_CLASS_CONTROL, &maxListIdentifier))) {
13199 if (maxListIdentifier >= MIN_TOKEN_LIST_IDENTIFIERS) {
13200
13201 NT_ASSERT(maxListIdentifier <= MAX_TOKEN_LIST_IDENTIFIERS);
13202 MaxTokenOperationListIdentifier = maxListIdentifier;
13203 }
13204 }
13205
13206 }
13207
13208 TracePrint((TRACE_LEVEL_VERBOSE,
13209 TRACE_FLAG_PNP,
13210 "ClassDetermineTokenOperationCommandSupport (%p): Exiting function with status %x.\n",
13212 status));
13213
13214 return status;
13215}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define REG_DISK_CLASS_CONTROL
Definition: classp.h:218
#define MAX_TOKEN_LIST_IDENTIFIERS
Definition: classp.h:215
#define MIN_TOKEN_LIST_IDENTIFIERS
Definition: classp.h:214
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG MaxTokenOperationListIdentifier
Definition: class.c:107
_IRQL_requires_same_ NTSTATUS ClasspGetBlockDeviceTokenLimitsInfo(_Inout_ PDEVICE_OBJECT DeviceObject)
Definition: class.c:13220
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ _IRQL_requires_max_() [1/3]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 13463 of file class.c.

13495{
13496 PIO_STACK_LOCATION irpStack;
13499 PDEVICE_DSM_OFFLOAD_READ_PARAMETERS offloadReadParameters;
13500 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
13501
13503
13504 //
13505 // This function must be called at less than dispatch level.
13506 // Fail if IRQL >= DISPATCH_LEVEL.
13507 //
13508 PAGED_CODE();
13509
13510 TracePrint((TRACE_LEVEL_VERBOSE,
13511 TRACE_FLAG_IOCTL,
13512 "ClassDeviceProcessOffloadRead (%p): Entering function. Irp %p\n",
13514 Irp));
13515
13516
13517 irpStack = IoGetCurrentIrpStackLocation (Irp);
13518
13519 //
13520 // Validations
13521 //
13522 status = ClasspValidateOffloadSupported(DeviceObject, Irp);
13523 if (!NT_SUCCESS(status)) {
13524 goto __ClassDeviceProcessOffloadRead_CompleteAndExit;
13525 }
13526
13528
13530 TracePrint((TRACE_LEVEL_ERROR,
13531 TRACE_FLAG_IOCTL,
13532 "ClassDeviceProcessOffloadRead (%p): Called at raised IRQL.\n",
13533 DeviceObject));
13534
13536 goto __ClassDeviceProcessOffloadRead_CompleteAndExit;
13537 }
13538
13539 //
13540 // Ensure that this DSM IOCTL was generated in kernel
13541 //
13542 if (Irp->RequestorMode != KernelMode) {
13543
13544 TracePrint((TRACE_LEVEL_ERROR,
13545 TRACE_FLAG_IOCTL,
13546 "ClassDeviceProcessOffloadRead (%p): Called from user mode.\n",
13547 DeviceObject));
13548
13550 goto __ClassDeviceProcessOffloadRead_CompleteAndExit;
13551 }
13552
13553 status = ClasspValidateOffloadInputParameters(DeviceObject, Irp);
13554 if (!NT_SUCCESS(status)) {
13555 goto __ClassDeviceProcessOffloadRead_CompleteAndExit;
13556 }
13557
13558 dsmAttributes = Irp->AssociatedIrp.SystemBuffer;
13559
13560 //
13561 // Validate that we were passed in correct sized parameter block.
13562 //
13563 if (dsmAttributes->ParameterBlockLength < sizeof(DEVICE_DSM_OFFLOAD_READ_PARAMETERS)) {
13564
13565 TracePrint((TRACE_LEVEL_ERROR,
13566 TRACE_FLAG_IOCTL,
13567 "ClassDeviceProcessOffloadRead (%p): Parameter block size (%u) too small. Required %u.\n",
13569 dsmAttributes->ParameterBlockLength,
13571
13573 goto __ClassDeviceProcessOffloadRead_CompleteAndExit;
13574 }
13575
13576 offloadReadParameters = Add2Ptr(dsmAttributes, dsmAttributes->ParameterBlockOffset);
13577
13578 fdoExtension = DeviceObject->DeviceExtension;
13579
13580 //
13581 // If the request TTL is greater than the max supported by this storage, the target will
13582 // end up failing this command, so might as well do the check up front.
13583 //
13584 if ((fdoExtension->FunctionSupportInfo->BlockDeviceRODLimitsData.MaximumInactivityTimer > 0) &&
13585 (offloadReadParameters->TimeToLive > fdoExtension->FunctionSupportInfo->BlockDeviceRODLimitsData.MaximumInactivityTimer)) {
13586
13587 TracePrint((TRACE_LEVEL_ERROR,
13588 TRACE_FLAG_IOCTL,
13589 "ClassDeviceProcessOffloadRead (%p): Requested TTL (%u) greater than max supported (%u).\n",
13591 offloadReadParameters->TimeToLive,
13592 fdoExtension->FunctionSupportInfo->BlockDeviceRODLimitsData.MaximumInactivityTimer));
13593
13595 goto __ClassDeviceProcessOffloadRead_CompleteAndExit;
13596 }
13597
13598 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_OFFLOAD_READ_OUTPUT)) {
13599
13600 TracePrint((TRACE_LEVEL_ERROR,
13601 TRACE_FLAG_IOCTL,
13602 "ClassDeviceProcessOffloadRead (%p): Output buffer size (%u) too small.\n",
13604 irpStack->Parameters.DeviceIoControl.OutputBufferLength));
13605
13607 goto __ClassDeviceProcessOffloadRead_CompleteAndExit;
13608 }
13609
13610
13611
13612 status = ClasspServicePopulateTokenTransferRequest(DeviceObject, Irp);
13613
13614 if (status == STATUS_PENDING) {
13615 goto __ClassDeviceProcessOffloadRead_Exit;
13616 }
13617
13618__ClassDeviceProcessOffloadRead_CompleteAndExit:
13620__ClassDeviceProcessOffloadRead_Exit:
13621 TracePrint((TRACE_LEVEL_VERBOSE,
13622 TRACE_FLAG_IOCTL,
13623 "ClassDeviceProcessOffloadRead (%p): Exiting function Irp %p with status %x.\n",
13625 Irp,
13626 status));
13627
13628 return status;
13629}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
_In_ PIRP Irp
Definition: csq.h:116
VOID ClasspCompleteOffloadRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ NTSTATUS CompletionStatus)
Definition: class.c:13632
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define Add2Ptr(PTR, INC)
#define KernelMode
Definition: asm.h:34
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_INVALID_LEVEL
Definition: ntstatus.h:564
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
struct _IO_STACK_LOCATION::@1575::@1576 DeviceIoControl
union _IO_STACK_LOCATION::@1575 Parameters
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

◆ _IRQL_requires_max_() [2/3]

__drv_aliasesMem _IRQL_requires_max_ ( DISPATCH_LEVEL  )

Definition at line 10631 of file class.c.

10637{
10638#ifdef _MSC_VER
10639#pragma warning(suppress:4054) // okay to type cast function pointer as data pointer for this use case
10640#endif
10642} // end ClassGetDriverExtension()
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:94
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1904
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213

◆ _IRQL_requires_max_() [3/3]

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Definition at line 207 of file class.c.

216{
219
220 PCLASS_DRIVER_EXTENSION driverExtension;
221
223
224
225
226 PAGED_CODE();
227
228 //
229 // Initialize the security cookie if needed.
230 //
231#ifndef __REACTOS__
232 if (InitSecurityCookie == FALSE) {
235 }
236#endif
237
238
239 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_INIT, "\n\nSCSI Class Driver\n"));
240
242
243 //
244 // Validate the length of this structure. This is effectively a
245 // version check.
246 //
247
248 if (InitializationData->InitializationDataSize != sizeof(CLASS_INIT_DATA)) {
249
250 //
251 // This DebugPrint is to help third-party driver writers
252 //
253
254 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_INIT, "ClassInitialize: Class driver wrong version\n"));
256 }
257
258 //
259 // Check that each required entry is not NULL. Note that Shutdown, Flush and Error
260 // are not required entry points.
261 //
262
263 if ((!InitializationData->FdoData.ClassDeviceControl) ||
264 (!((InitializationData->FdoData.ClassReadWriteVerification) ||
265 (InitializationData->ClassStartIo))) ||
266 (!InitializationData->ClassAddDevice) ||
267 (!InitializationData->FdoData.ClassStartDevice)) {
268
269 //
270 // This DebugPrint is to help third-party driver writers
271 //
272
273 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_INIT,
274 "ClassInitialize: Class device-specific driver missing required "
275 "FDO entry\n"));
276
278 }
279
280 if ((InitializationData->ClassEnumerateDevice) &&
281 ((!InitializationData->PdoData.ClassDeviceControl) ||
282 (!InitializationData->PdoData.ClassStartDevice) ||
283 (!((InitializationData->PdoData.ClassReadWriteVerification) ||
284 (InitializationData->ClassStartIo))))) {
285
286 //
287 // This DebugPrint is to help third-party driver writers
288 //
289
290 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_INIT, "ClassInitialize: Class device-specific missing "
291 "required PDO entry\n"));
292
294 }
295
296 if((InitializationData->FdoData.ClassStopDevice == NULL) ||
297 ((InitializationData->ClassEnumerateDevice != NULL) &&
298 (InitializationData->PdoData.ClassStopDevice == NULL))) {
299
300 //
301 // This DebugPrint is to help third-party driver writers
302 //
303
304 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_INIT, "ClassInitialize: Class device-specific missing "
305 "required PDO entry\n"));
308 }
309
310 //
311 // Setup the default power handlers if the class driver didn't provide
312 // any.
313 //
314
315 if(InitializationData->FdoData.ClassPowerDevice == NULL) {
316 InitializationData->FdoData.ClassPowerDevice = ClassMinimalPowerHandler;
317 }
318
319 if((InitializationData->ClassEnumerateDevice != NULL) &&
320 (InitializationData->PdoData.ClassPowerDevice == NULL)) {
321 InitializationData->PdoData.ClassPowerDevice = ClassMinimalPowerHandler;
322 }
323
324 //
325 // warn that unload is not supported
326 //
327 // ISSUE-2000/02/03-peterwie
328 // We should think about making this a fatal error.
329 //
330
331 if(InitializationData->ClassUnload == NULL) {
332
333 //
334 // This DebugPrint is to help third-party driver writers
335 //
336
337 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT, "ClassInitialize: driver does not support unload %wZ\n",
338 RegistryPath));
339 }
340
341 //
342 // Create an extension for the driver object
343 //
344#ifdef _MSC_VER
345#pragma warning(suppress:4054) // okay to type cast function pointer as data pointer for this use case
346#endif
348
349 if(NT_SUCCESS(status)) {
350
351 //
352 // Copy the registry path into the driver extension so we can use it later
353 //
354
355 driverExtension->RegistryPath.Length = RegistryPath->Length;
356 driverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;
357
358 driverExtension->RegistryPath.Buffer =
360 RegistryPath->MaximumLength,
361 '1CcS');
362
363 if(driverExtension->RegistryPath.Buffer == NULL) {
364
366 return status;
367 }
368
370 &(driverExtension->RegistryPath),
372
373 //
374 // Copy the initialization data into the driver extension so we can reuse
375 // it during our add device routine
376 //
377
379 &(driverExtension->InitData),
381 sizeof(CLASS_INIT_DATA));
382
383 driverExtension->DeviceCount = 0;
384
385 ClassInitializeDispatchTables(driverExtension);
386
387 } else if (status == STATUS_OBJECT_NAME_COLLISION) {
388
389 //
390 // The extension already exists - get a pointer to it
391 //
392#ifdef _MSC_VER
393#pragma warning(suppress:4054) // okay to type cast function pointer as data pointer for this use case
394#endif
396
397 NT_ASSERT(driverExtension != NULL);
398
399 } else {
400
401 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_INIT, "ClassInitialize: Class driver extension could not be "
402 "allocated %lx\n", status));
403 return status;
404 }
405
406
407 //
408 // Update driver object with entry points.
409 //
410
411#ifdef _MSC_VER
412#pragma prefast(push)
413#pragma prefast(disable:28175, "Accessing DRIVER_OBJECT fileds is OK here since this function " \
414 "is supposed to be invoked from DriverEntry only")
415#endif
427
428 if (InitializationData->ClassStartIo) {
429 DriverObject->DriverStartIo = ClasspStartIo;
430 }
431
432 if ((InitializationData->ClassUnload) && (ClassPnpAllowUnload == TRUE)) {
433 DriverObject->DriverUnload = ClassUnload;
434 } else {
435 DriverObject->DriverUnload = NULL;
436 }
437
438 DriverObject->DriverExtension->AddDevice = ClassAddDevice;
439#ifdef _MSC_VER
440#pragma prefast(pop)
441#endif
442
443
444 //
445 // Register for event tracing
446 //
447 if (driverExtension->EtwHandle == 0) {
449 NULL,
450 NULL,
451 &driverExtension->EtwHandle);
452 if (!NT_SUCCESS(status)) {
453 driverExtension->EtwHandle = 0;
454 }
456 }
457
458
459 //
460 // Ensure these are only initialized once.
461 //
462 if (IdlePowerFDOList.Flink == NULL) {
465 }
466
468 return status;
469} // end ClassInitialize()
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSTATUS NTAPI ClassMinimalPowerHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: power.c:1890
DRIVER_STARTIO ClasspStartIo
Definition: classp.h:1454
DRIVER_UNLOAD ClassUnload
Definition: classp.h:1356
VOID ClassInitializeDispatchTables(PCLASS_DRIVER_EXTENSION DriverExtension)
Definition: dispatch.c:38
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:722
_In_ PVOID Argument2
Definition: classpnp.h:721
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define WPP_INIT_TRACING(a, b)
Definition: kdebugprint.h:56
ULONG ClassPnpAllowUnload
Definition: class.c:87
BOOLEAN InitSecurityCookie
Definition: class.c:102
KGUARDED_MUTEX IdlePowerFDOListMutex
Definition: class.c:114
GUID StoragePredictFailureDPSGuid
Definition: class.c:90
LIST_ENTRY IdlePowerFDOList
Definition: class.c:113
#define ClasspInitializeDebugGlobals()
Definition: debug.h:123
NTSTATUS NTAPI ClassGlobalDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: dispatch.c:73
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
static DRIVER_ADD_DEVICE ClassAddDevice
Definition: kbdclass.c:24
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1826
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
void __cdecl __security_init_cookie(void)
Definition: gs_support.c:55
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
CLASS_INIT_DATA InitData
Definition: classpnp.h:577
UNICODE_STRING RegistryPath
Definition: kbdclass.h:25
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696
#define IRP_MJ_SCSI
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_POWER

◆ _Success_()

_Success_ ( return  = STATUS_PENDING)

Definition at line 7019 of file class.c.

7030{
7031
7032 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
7033 PIO_STACK_LOCATION irpStack;
7035
7036 ULONG savedFlags;
7037
7039 //
7040 // Write length to SRB.
7041 //
7042
7043 Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
7044
7045 //
7046 // Set SCSI bus address.
7047 //
7048
7050 }
7051
7052 //
7053 // This is a violation of the SCSI spec but it is required for
7054 // some targets.
7055 //
7056
7057 // Srb->Cdb[1] |= deviceExtension->Lun << 5;
7058
7059 //
7060 // Indicate auto request sense by specifying buffer and size.
7061 //
7062
7063 SrbSetSenseInfoBuffer(Srb, fdoExtension->SenseData);
7065
7067
7068 //
7069 // Set the transfer length.
7070 //
7072
7073 //
7074 // Save the class driver specific flags away.
7075 //
7076
7078
7079 //
7080 // Allow the caller to specify that they do not wish
7081 // IoStartNextPacket() to be called in the completion routine.
7082 //
7083
7085
7086 //
7087 // If caller wants to this request to be tagged, save this fact.
7088 //
7089
7094
7098 }
7099 }
7100
7101 if (BufferAddress != NULL) {
7102
7103 //
7104 // Build Mdl if necessary.
7105 //
7106
7107 if (Irp->MdlAddress == NULL) {
7108
7109 PMDL mdl;
7110
7113 FALSE,
7114 FALSE,
7115 Irp);
7116
7117 if ((mdl == NULL) || (Irp->MdlAddress == NULL)) {
7118
7119 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
7120
7121 //
7122 // ClassIoComplete() would have free'd the srb
7123 //
7124
7125 if (PORT_ALLOCATED_SENSE_EX(fdoExtension, Srb)) {
7127 }
7131
7133 }
7134
7136
7137 MmBuildMdlForNonPagedPool(Irp->MdlAddress);
7138
7139 } else {
7140
7141 //
7142 // Make sure the buffer requested matches the MDL.
7143 //
7144
7146 }
7147
7148 //
7149 // Set read flag.
7150 //
7151
7153
7154 } else {
7155
7156 //
7157 // Clear flags.
7158 //
7159
7161 }
7162
7163 //
7164 // Restore saved flags.
7165 //
7166
7167 SrbSetSrbFlags(Srb, savedFlags);
7168
7169 //
7170 // Disable synchronous transfer for these requests.
7171 //
7172
7174
7175 //
7176 // Zero out status.
7177 //
7178
7180 Srb->SrbStatus = 0;
7181
7183
7184 //
7185 // Save a few parameters in the current stack location.
7186 //
7187
7189
7190 //
7191 // Save retry count in current Irp stack.
7192 //
7193
7194 irpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
7195
7196 //
7197 // Set up IoCompletion routine address.
7198 //
7199
7201
7202 //
7203 // Get next stack location and
7204 // set major function code.
7205 //
7206
7207 irpStack = IoGetNextIrpStackLocation(Irp);
7208
7209 irpStack->MajorFunction = IRP_MJ_SCSI;
7210
7211 //
7212 // Save SRB address in next stack for port driver.
7213 //
7214
7215 irpStack->Parameters.Scsi.Srb = (PSCSI_REQUEST_BLOCK)Srb;
7216
7217 //
7218 // Set up Irp Address.
7219 //
7220
7222
7223 //
7224 // Call the port driver to process the request.
7225 //
7226
7228
7230
7231 return STATUS_PENDING;
7232
7233} // end ClassSendSrbAsynchronous()
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:990
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:992
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
FORCEINLINE BOOLEAN PORT_ALLOCATED_SENSE_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2547
VOID ClassFreeOrReuseSrb(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN __drv_freesMem(mem) PSCSI_REQUEST_BLOCK Srb)
Definition: obsolete.c:882
FORCEINLINE VOID FREE_PORT_ALLOCATED_SENSE_BUFFER_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2560
#define SRB_CLASS_FLAGS_FREE_MDL
Definition: classpnp.h:22
FORCEINLINE UCHAR GET_FDO_EXTENSON_SENSE_DATA_LENGTH(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: classpnp.h:1437
NTSTATUS NTAPI ClassIoComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: class.c:3768
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_FLAGS_CLASS_DRIVER_RESERVED
Definition: srb.h:418
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_FLAGS_DONT_START_NEXT_PACKET
Definition: srb.h:415
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:402
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:423
#define SRB_ORDERED_QUEUE_TAG_REQUEST
Definition: srb.h:425
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:395
#define SRB_HEAD_OF_QUEUE_TAG_REQUEST
Definition: srb.h:424
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:404
MDL * mdl
#define IoAllocateMdl
Definition: fxmdl.h:88
IoMarkIrpPending(Irp)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
#define IoCallDriver
Definition: irp.c:1225
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:108
struct SRB_ALIGN _STORAGE_REQUEST_BLOCK_HEADER * PSTORAGE_REQUEST_BLOCK_HEADER
FORCEINLINE VOID SrbSetSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:964
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
FORCEINLINE VOID SrbSetNextSrb(_In_ PVOID Srb, _In_opt_ PVOID NextSrb)
Definition: srbhelper.h:909
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
FORCEINLINE VOID SrbSetScsiStatus(_In_ PVOID Srb, _In_ UCHAR ScsiStatus)
Definition: srbhelper.h:1056
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
FORCEINLINE ULONG SrbGetSrbFlags(_In_ PVOID Srb)
Definition: srbhelper.h:927
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
FORCEINLINE ULONG SrbGetRequestAttribute(_In_ PVOID Srb)
Definition: srbhelper.h:1111
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:598
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
struct _IO_STACK_LOCATION::@3984::@4006 Scsi
struct _IO_STACK_LOCATION::@3984::@4023 Others
UCHAR Function
Definition: srb.h:250
USHORT Length
Definition: srb.h:249
UCHAR SrbStatus
Definition: srb.h:251
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define MmGetMdlVirtualAddress(_Mdl)

◆ ClassAddChild()

VOID ClassAddChild ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  Parent,
_In_ PPHYSICAL_DEVICE_EXTENSION  Child,
_In_ BOOLEAN  AcquireLock 
)

Definition at line 12058 of file class.c.

12063{
12064 if(AcquireLock) {
12065 ClassAcquireChildLock(Parent);
12066 }
12067
12068 #if DBG
12069 //
12070 // Make sure this child's not already in the list.
12071 //
12072 {
12074
12075 for (testChild = Parent->CommonExtension.ChildList;
12076 testChild != NULL;
12077 testChild = testChild->CommonExtension.ChildList) {
12078
12079 NT_ASSERT(testChild != Child);
12080 }
12081 }
12082 #endif
12083
12084 Child->CommonExtension.ChildList = Parent->CommonExtension.ChildList;
12085 Parent->CommonExtension.ChildList = Child;
12086
12087 if(AcquireLock) {
12089 }
12090 return;
12091} // end ClassAddChild()
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
VOID NTAPI ClassReleaseChildLock(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: class.c:12019
pPkgPnp m_DeviceInterfaceLock AcquireLock(pFxDriverGlobals)
struct _PHYSICAL_DEVICE_EXTENSION * ChildList
Definition: classpnp.h:616
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:652
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536

◆ ClassAddDevice()

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

Definition at line 851 of file class.c.

855{
856#ifdef _MSC_VER
857#pragma warning(suppress:4054) // okay to type cast function pointer as data pointer for this use case
858#endif
860
862
863 PAGED_CODE();
864
865
866 status = driverExtension->InitData.ClassAddDevice(DriverObject,
868
869 return status;
870} // end ClassAddDevice()
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
PCLASS_ADD_DEVICE ClassAddDevice
Definition: classpnp.h:540

◆ ClassAsynchronousCompletion()

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

Definition at line 3246 of file class.c.

3251{
3254 ULONG srbFunction;
3255 ULONG srbFlags;
3256
3257 if (context == NULL) {
3259 }
3260
3261 if (DeviceObject == NULL) {
3262
3263 DeviceObject = context->DeviceObject;
3264 }
3265
3266 srb = &context->Srb.Srb;
3267
3269 srbFunction = ((PSTORAGE_REQUEST_BLOCK)srb)->SrbFunction;
3270 srbFlags = ((PSTORAGE_REQUEST_BLOCK)srb)->SrbFlags;
3271 } else {
3272 srbFunction = srb->Function;
3273 srbFlags = srb->SrbFlags;
3274 }
3275
3276 //
3277 // If this is an execute srb, then check the return status and make sure.
3278 // the queue is not frozen.
3279 //
3280
3281 if (srbFunction == SRB_FUNCTION_EXECUTE_SCSI) {
3282
3283 //
3284 // Check for a frozen queue.
3285 //
3286
3288
3289 //
3290 // Unfreeze the queue getting the device object from the context.
3291 //
3292
3293 ClassReleaseQueue(context->DeviceObject);
3294 }
3295 }
3296
3297 { // free port-allocated sense buffer if we can detect
3298
3299 if (((PCOMMON_DEVICE_EXTENSION)(DeviceObject->DeviceExtension))->IsFdo) {
3300
3301 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3302 if (PORT_ALLOCATED_SENSE(fdoExtension, srb)) {
3303 FREE_PORT_ALLOCATED_SENSE_BUFFER(fdoExtension, srb);
3304 }
3305
3306 } else {
3307
3309
3310 }
3311 }
3312
3313
3314 //
3315 // Free the context and the Irp.
3316 //
3317
3318 if (Irp->MdlAddress != NULL) {
3319 MmUnlockPages(Irp->MdlAddress);
3320 IoFreeMdl(Irp->MdlAddress);
3321
3322 Irp->MdlAddress = NULL;
3323 }
3324
3326
3328
3329 IoFreeIrp(Irp);
3330
3331 //
3332 // Indicate the I/O system should stop processing the Irp completion.
3333 //
3334
3336
3337} // end ClassAsynchronousCompletion()
FORCEINLINE BOOLEAN PORT_ALLOCATED_SENSE(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:826
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
FORCEINLINE VOID FREE_PORT_ALLOCATED_SENSE_BUFFER(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:839
VOID NTAPI ClassReleaseQueue(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:11589
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:406
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:386
#define IoFreeMdl
Definition: fxmdl.h:89
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:661
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
ULONG SrbFlags
Definition: srb.h:260
Definition: http.c:7252

Referenced by ClassSendStartUnit(), ResetBus(), and ScsiFlopProcessError().

◆ ClassCheckVerifyComplete()

NTSTATUS NTAPI ClassCheckVerifyComplete ( IN PDEVICE_OBJECT  Fdo,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 9578 of file class.c.

9583{
9585 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
9586
9587 PIRP originalIrp;
9588
9590
9591 ASSERT_FDO(Fdo);
9592
9593 originalIrp = irpStack->Parameters.Others.Argument1;
9594
9595 //
9596 // Copy the media change count and status
9597 //
9598
9599 *((PULONG) (originalIrp->AssociatedIrp.SystemBuffer)) =
9600 fdoExtension->MediaChangeCount;
9601
9602 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "ClassCheckVerifyComplete - Media change count for"
9603 "device %d is %lx - saved as %lx\n",
9604 fdoExtension->DeviceNumber,
9605 fdoExtension->MediaChangeCount,
9606 *((PULONG) originalIrp->AssociatedIrp.SystemBuffer)));
9607
9608 originalIrp->IoStatus.Status = Irp->IoStatus.Status;
9609 originalIrp->IoStatus.Information = sizeof(ULONG);
9610
9611 ClassReleaseRemoveLock(Fdo, originalIrp);
9613
9614 IoFreeIrp(Irp);
9615
9617
9618} // end ClassCheckVerifyComplete()
#define ASSERT_FDO(x)
Definition: pci.h:37
union _IRP::@1577 AssociatedIrp
PVOID SystemBuffer
IO_STATUS_BLOCK IoStatus
uint32_t * PULONG
Definition: typedefs.h:59
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

◆ ClassDeviceControl()

NTSTATUS NTAPI ClassDeviceControl ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PIRP  Irp 
)

Definition at line 7317 of file class.c.

7321{
7322 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
7323
7325 PIO_STACK_LOCATION nextStack = NULL;
7326
7327 ULONG controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
7328
7330 PCDB cdb = NULL;
7331
7333 ULONG modifiedIoControlCode = 0;
7334 GUID activityId = {0};
7335
7336
7337 //
7338 // If this is a pass through I/O control, set the minor function code
7339 // and device address and pass it to the port driver.
7340 //
7341
7342 if ( (controlCode == IOCTL_SCSI_PASS_THROUGH) ||
7343 (controlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) ||
7344 (controlCode == IOCTL_SCSI_PASS_THROUGH_EX) ||
7345 (controlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT_EX) ) {
7346
7347
7348
7349 //
7350 // Validiate the user buffer for SCSI pass through.
7351 // For pass through EX: as the handler will validate the size anyway,
7352 // do not apply the similar check and leave the work to the handler.
7353 //
7354 if ( (controlCode == IOCTL_SCSI_PASS_THROUGH) ||
7355 (controlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) ) {
7356
7357 #if BUILD_WOW64_ENABLED && defined(_WIN64)
7358
7359 if (IoIs32bitProcess(Irp)) {
7360
7361 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH32)){
7362
7363 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
7364
7367
7369 goto SetStatusAndReturn;
7370 }
7371 }
7372 else
7373
7374 #endif
7375
7376 {
7377 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
7378 sizeof(SCSI_PASS_THROUGH)) {
7379
7380 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
7381
7384
7386 goto SetStatusAndReturn;
7387 }
7388 }
7389 }
7390
7391
7393
7394 nextStack = IoGetNextIrpStackLocation(Irp);
7395 nextStack->MinorFunction = 1;
7396
7398
7399 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7400 goto SetStatusAndReturn;
7401
7402 }
7403
7404 Irp->IoStatus.Information = 0;
7405
7406
7407 switch (controlCode) {
7408
7410
7411 PMOUNTDEV_UNIQUE_ID uniqueId;
7412
7413 if (!commonExtension->MountedDeviceInterfaceName.Buffer) {
7415 break;
7416 }
7417
7418 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7419 sizeof(MOUNTDEV_UNIQUE_ID)) {
7420
7422 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
7423 break;
7424 }
7425
7426 uniqueId = Irp->AssociatedIrp.SystemBuffer;
7427 RtlZeroMemory(uniqueId, sizeof(MOUNTDEV_UNIQUE_ID));
7428 uniqueId->UniqueIdLength =
7429 commonExtension->MountedDeviceInterfaceName.Length;
7430
7431 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7432 sizeof(USHORT) + uniqueId->UniqueIdLength) {
7433
7435 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
7436 break;
7437 }
7438
7439 RtlCopyMemory(uniqueId->UniqueId,
7440 commonExtension->MountedDeviceInterfaceName.Buffer,
7441 uniqueId->UniqueIdLength);
7442
7444 Irp->IoStatus.Information = sizeof(USHORT) +
7445 uniqueId->UniqueIdLength;
7446 break;
7447 }
7448
7450
7452
7453 NT_ASSERT(commonExtension->DeviceName.Buffer);
7454
7455 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7456 sizeof(MOUNTDEV_NAME)) {
7457
7459 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
7460 break;
7461 }
7462
7463 name = Irp->AssociatedIrp.SystemBuffer;
7465 name->NameLength = commonExtension->DeviceName.Length;
7466
7467 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7468 sizeof(USHORT) + name->NameLength) {
7469
7471 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
7472 break;
7473 }
7474
7475 RtlCopyMemory(name->Name, commonExtension->DeviceName.Buffer,
7476 name->NameLength);
7477
7479 Irp->IoStatus.Information = sizeof(USHORT) + name->NameLength;
7480 break;
7481 }
7482
7484
7485 PMOUNTDEV_SUGGESTED_LINK_NAME suggestedName;
7486 WCHAR driveLetterNameBuffer[10] = {0};
7487 RTL_QUERY_REGISTRY_TABLE queryTable[2] = {0};
7488 PWSTR valueName;
7489 UNICODE_STRING driveLetterName;
7490
7491 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7493
7495 Irp->IoStatus.Information = sizeof(MOUNTDEV_SUGGESTED_LINK_NAME);
7496 break;
7497 }
7498
7499 valueName = ExAllocatePoolWithTag(
7500 PagedPool,
7501 commonExtension->DeviceName.Length + sizeof(WCHAR),
7502 '8CcS');
7503
7504 if (!valueName) {
7506 break;
7507 }
7508
7509 RtlCopyMemory(valueName, commonExtension->DeviceName.Buffer,
7510 commonExtension->DeviceName.Length);
7511 valueName[commonExtension->DeviceName.Length/sizeof(WCHAR)] = 0;
7512
7513 driveLetterName.Buffer = driveLetterNameBuffer;
7514 driveLetterName.MaximumLength = sizeof(driveLetterNameBuffer);
7515 driveLetterName.Length = 0;
7516
7517 queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED |
7520 queryTable[0].Name = valueName;
7521 queryTable[0].EntryContext = &driveLetterName;
7523
7525 L"\\Registry\\Machine\\System\\DISK",
7526 queryTable, NULL, NULL);
7527
7528 if (!NT_SUCCESS(status)) {
7529 FREE_POOL(valueName);
7530 break;
7531 }
7532
7533 if (driveLetterName.Length == 4 &&
7534 driveLetterName.Buffer[0] == '%' &&
7535 driveLetterName.Buffer[1] == ':') {
7536
7537 driveLetterName.Buffer[0] = 0xFF;
7538
7539 } else if (driveLetterName.Length != 4 ||
7540 driveLetterName.Buffer[0] < FirstDriveLetter ||
7541 driveLetterName.Buffer[0] > LastDriveLetter ||
7542 driveLetterName.Buffer[1] != ':') {
7543
7545 FREE_POOL(valueName);
7546 break;
7547 }
7548
7549 suggestedName = Irp->AssociatedIrp.SystemBuffer;
7550 RtlZeroMemory(suggestedName, sizeof(MOUNTDEV_SUGGESTED_LINK_NAME));
7551 suggestedName->UseOnlyIfThereAreNoOtherLinks = TRUE;
7552 suggestedName->NameLength = 28;
7553
7554 Irp->IoStatus.Information =
7556
7557 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7558 Irp->IoStatus.Information) {
7559
7560 Irp->IoStatus.Information =
7563 FREE_POOL(valueName);
7564 break;
7565 }
7566
7568 L"\\Registry\\Machine\\System\\DISK",
7569 valueName);
7570
7571 FREE_POOL(valueName);
7572
7573 RtlCopyMemory(suggestedName->Name, L"\\DosDevices\\", 24);
7574 suggestedName->Name[12] = driveLetterName.Buffer[0];
7575 suggestedName->Name[13] = ':';
7576
7577 //
7578 // NT_SUCCESS(status) based on RtlQueryRegistryValues
7579 //
7581
7582 break;
7583 }
7584
7585 default:
7587 break;
7588 }
7589
7590 if (status != STATUS_PENDING) {
7592 Irp->IoStatus.Status = status;
7593
7594
7596 return status;
7597 }
7598
7599 if (commonExtension->IsFdo){
7600
7601 PULONG_PTR function;
7602 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
7603 size_t sizeNeeded;
7604
7605 //
7606 // Allocate a SCSI SRB for handling various IOCTLs.
7607 // NOTE - there is a case where an IOCTL is sent to classpnp before AdapterDescriptor
7608 // is initialized. In this case, default to legacy SRB.
7609 //
7610 if ((fdoExtension->AdapterDescriptor != NULL) &&
7611 (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK)) {
7613 } else {
7614 sizeNeeded = sizeof(SCSI_REQUEST_BLOCK);
7615 }
7616
7617 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
7618 sizeNeeded +
7619 (sizeof(ULONG_PTR) * 2),
7620 '9CcS');
7621
7622 if (srb == NULL) {
7623
7624 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
7628 goto SetStatusAndReturn;
7629 }
7630
7631 if ((fdoExtension->AdapterDescriptor != NULL) &&
7632 (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK)) {
7636 1,
7638 if (NT_SUCCESS(status)) {
7640 function = (PULONG_PTR)((PCHAR)srb + sizeNeeded);
7641 } else {
7642 //
7643 // Should not occur.
7644 //
7646 goto SetStatusAndReturn;
7647 }
7648 } else {
7649 RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
7650 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
7651 srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
7652 function = (PULONG_PTR) ((PSCSI_REQUEST_BLOCK) (srb + 1));
7653 }
7654
7655 //
7656 // Save the function code and the device object in the memory after
7657 // the SRB.
7658 //
7659
7660 *function = (ULONG_PTR) DeviceObject;
7661 function++;
7662 *function = (ULONG_PTR) controlCode;
7663
7664 } else {
7665 srb = NULL;
7666 }
7667
7668 //
7669 // Change the device type to storage for the switch statement, but only
7670 // if from a legacy device type
7671 //
7672
7673 if (((controlCode & 0xffff0000) == (IOCTL_DISK_BASE << 16)) ||
7674 ((controlCode & 0xffff0000) == (IOCTL_TAPE_BASE << 16)) ||
7675 ((controlCode & 0xffff0000) == (IOCTL_CDROM_BASE << 16))
7676 ) {
7677
7678 modifiedIoControlCode = (controlCode & ~0xffff0000);
7679 modifiedIoControlCode |= (IOCTL_STORAGE_BASE << 16);
7680
7681 } else {
7682
7683 modifiedIoControlCode = controlCode;
7684
7685 }
7686
7687 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "> ioctl %xh (%s)", modifiedIoControlCode, DBGGETIOCTLSTR(modifiedIoControlCode)));
7688
7689
7690 switch (modifiedIoControlCode) {
7691
7693
7694 FREE_POOL(srb);
7695
7696 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7697 sizeof(STORAGE_HOTPLUG_INFO)) {
7698
7699 //
7700 // Indicate unsuccessful status and no data transferred.
7701 //
7702
7703 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
7704 Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
7705
7709
7710 } else if (!commonExtension->IsFdo) {
7711
7712
7713 //
7714 // Just forward this down and return
7715 //
7716
7718
7720 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7721
7722 } else {
7723
7724 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
7726
7727 fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
7728 info = Irp->AssociatedIrp.SystemBuffer;
7729
7730 *info = fdoExtension->PrivateFdoData->HotplugInfo;
7731 Irp->IoStatus.Status = STATUS_SUCCESS;
7732 Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
7736 }
7737 break;
7738 }
7739
7741
7742 FREE_POOL(srb);
7743
7744 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
7745 sizeof(STORAGE_HOTPLUG_INFO)) {
7746
7747 //
7748 // Indicate unsuccessful status and no data transferred.
7749 //
7750
7751 Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
7752
7756 goto SetStatusAndReturn;
7757
7758 }
7759
7760 if (!commonExtension->IsFdo) {
7761
7762
7763 //
7764 // Just forward this down and return
7765 //
7766
7768
7770 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7771
7772 } else {
7773
7774 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
7775 PSTORAGE_HOTPLUG_INFO info = Irp->AssociatedIrp.SystemBuffer;
7776
7778
7779 if (info->Size != fdoExtension->PrivateFdoData->HotplugInfo.Size)
7780 {
7782 }
7783
7784 if (info->MediaRemovable != fdoExtension->PrivateFdoData->HotplugInfo.MediaRemovable)
7785 {
7787 }
7788
7789 if (info->MediaHotplug != fdoExtension->PrivateFdoData->HotplugInfo.MediaHotplug)
7790 {
7792 }
7793
7794 if (NT_SUCCESS(status))
7795 {
7796 if (info->WriteCacheEnableOverride != fdoExtension->PrivateFdoData->HotplugInfo.WriteCacheEnableOverride)
7797 {
7798 fdoExtension->PrivateFdoData->HotplugInfo.WriteCacheEnableOverride = info->WriteCacheEnableOverride;
7799
7800 //
7801 // Store the user-defined override in the registry
7802 //
7803
7804 ClassSetDeviceParameter(fdoExtension,
7807 info->WriteCacheEnableOverride);
7808 }
7809
7810 fdoExtension->PrivateFdoData->HotplugInfo.DeviceHotplug = info->DeviceHotplug;
7811
7812 //
7813 // Store the user-defined override in the registry
7814 //
7815
7816 ClassSetDeviceParameter(fdoExtension,
7820 }
7821
7822 Irp->IoStatus.Status = status;
7823
7826 }
7827
7828 break;
7829 }
7830
7833
7834 PIRP irp2 = NULL;
7835 PIO_STACK_LOCATION newStack;
7836
7837 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
7838
7839 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DeviceIoControl: Check verify\n"));
7840
7841 //
7842 // If a buffer for a media change count was provided, make sure it's
7843 // big enough to hold the result
7844 //
7845
7846 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
7847
7848 //
7849 // If the buffer is too small to hold the media change count
7850 // then return an error to the caller
7851 //
7852
7853 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7854 sizeof(ULONG)) {
7855
7856 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "DeviceIoControl: media count "
7857 "buffer too small\n"));
7858
7859 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
7860 Irp->IoStatus.Information = sizeof(ULONG);
7861
7862 FREE_POOL(srb);
7863
7866
7868 goto SetStatusAndReturn;
7869 }
7870 }
7871
7872 if (!commonExtension->IsFdo) {
7873
7874
7875 //
7876 // If this is a PDO then we should just forward the request down
7877 //
7878 NT_ASSERT(!srb);
7879
7881
7883
7884 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7885
7886 goto SetStatusAndReturn;
7887
7888 } else {
7889
7890 fdoExtension = DeviceObject->DeviceExtension;
7891
7892 }
7893
7894 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
7895
7896 //
7897 // The caller has provided a valid buffer. Allocate an additional
7898 // irp and stick the CheckVerify completion routine on it. We will
7899 // then send this down to the port driver instead of the irp the
7900 // caller sent in
7901 //
7902
7903 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DeviceIoControl: Check verify wants "
7904 "media count\n"));
7905
7906 //
7907 // Allocate a new irp to send the TestUnitReady to the port driver
7908 //
7909
7910 irp2 = IoAllocateIrp((CCHAR) (DeviceObject->StackSize + 3), FALSE);
7911
7912 if (irp2 == NULL) {
7913 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
7914 Irp->IoStatus.Information = 0;
7915 FREE_POOL(srb);
7919 goto SetStatusAndReturn;
7920
7921 break;
7922 }
7923
7924 //
7925 // Make sure to acquire the lock for the new irp.
7926 //
7927
7929
7930 irp2->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
7932
7933 //
7934 // Set the top stack location and shove the master Irp into the
7935 // top location
7936 //
7937
7938 newStack = IoGetCurrentIrpStackLocation(irp2);
7939 newStack->Parameters.Others.Argument1 = Irp;
7940 newStack->DeviceObject = DeviceObject;
7941
7942 //
7943 // Stick the check verify completion routine onto the stack
7944 // and prepare the irp for the port driver
7945 //
7946
7949 NULL,
7950 TRUE,
7951 TRUE,
7952 TRUE);
7953
7955 newStack = IoGetCurrentIrpStackLocation(irp2);
7956 newStack->DeviceObject = DeviceObject;
7957 newStack->MajorFunction = irpStack->MajorFunction;
7958 newStack->MinorFunction = irpStack->MinorFunction;
7959 newStack->Flags = irpStack->Flags;
7960
7961
7962 //
7963 // Mark the master irp as pending - whether the lower level
7964 // driver completes it immediately or not this should allow it
7965 // to go all the way back up.
7966 //
7967
7969
7970 Irp = irp2;
7971
7972 }
7973
7974 //
7975 // Test Unit Ready
7976 //
7977
7978 SrbSetCdbLength(srb, 6);
7979 cdb = SrbGetCdb(srb);
7980 cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
7981
7982 //
7983 // Set timeout value.
7984 //
7985
7986 SrbSetTimeOutValue(srb, fdoExtension->TimeOutValue);
7987
7988 //
7989 // If this was a CV2 then mark the request as low-priority so we don't
7990 // spin up the drive just to satisfy it.
7991 //
7992
7993 if (controlCode == IOCTL_STORAGE_CHECK_VERIFY2) {
7995 }
7996
7997 //
7998 // Since this routine will always hand the request to the
7999 // port driver if there isn't a data transfer to be done
8000 // we don't have to worry about completing the request here
8001 // on an error
8002 //
8003
8004 //
8005 // This routine uses a completion routine so we don't want to release
8006 // the remove lock until then.
8007 //
8008
8010 srb,
8011 Irp,
8012 NULL,
8013 0,
8014 FALSE);
8015
8016 break;
8017 }
8018
8021
8022 PPREVENT_MEDIA_REMOVAL mediaRemoval = Irp->AssociatedIrp.SystemBuffer;
8023
8024 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoControl: ejection control\n"));
8025
8026 FREE_POOL(srb);
8027
8028 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
8029 sizeof(PREVENT_MEDIA_REMOVAL)) {
8030
8031 //
8032 // Indicate unsuccessful status and no data transferred.
8033 //
8034
8035 Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
8036
8040 goto SetStatusAndReturn;
8041 }
8042
8043 if (!commonExtension->IsFdo) {
8044
8045
8046 //
8047 // Just forward this down and return
8048 //
8049
8051
8053 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8054 }
8055 else {
8056
8057 // i don't believe this assertion is valid. this is a request
8058 // from user-mode, so they could request this for any device
8059 // they want? also, we handle it properly.
8060 // NT_ASSERT(TEST_FLAG(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA));
8063 Irp,
8064 ((modifiedIoControlCode ==
8067 mediaRemoval->PreventMediaRemoval);
8068
8069 Irp->IoStatus.Status = status;
8072 }
8073
8074 break;
8075 }
8076
8078
8079 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoControl: MCN control\n"));
8080
8081 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
8082 sizeof(PREVENT_MEDIA_REMOVAL)) {
8083
8084 //
8085 // Indicate unsuccessful status and no data transferred.
8086 //
8087
8088 Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
8089 Irp->IoStatus.Information = 0;
8090
8091 FREE_POOL(srb);
8092
8096 goto SetStatusAndReturn;
8097 }
8098
8099 if (!commonExtension->IsFdo) {
8100
8101
8102 //
8103 // Just forward this down and return
8104 //
8105
8106 FREE_POOL(srb);
8107
8109
8111 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8112
8113 } else {
8114
8115 //
8116 // Call to the FDO - handle the ejection control.
8117 //
8118
8119 status = ClasspMcnControl(DeviceObject->DeviceExtension,
8120 Irp,
8121 srb);
8122 }
8123 goto SetStatusAndReturn;
8124 }
8125
8127 case IOCTL_STORAGE_RELEASE: {
8128
8129 //
8130 // Reserve logical unit.
8131 //
8132
8133 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
8134
8135 if (!commonExtension->IsFdo) {
8136
8137
8139
8141 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8142 goto SetStatusAndReturn;
8143
8144 } else {
8145 fdoExtension = DeviceObject->DeviceExtension;
8146 }
8147
8148 if (TEST_FLAG(fdoExtension->PrivateFdoData->HackFlags, FDO_HACK_NO_RESERVE6))
8149 {
8150 SrbSetCdbLength(srb, 10);
8151 cdb = SrbGetCdb(srb);
8152 cdb->CDB10.OperationCode = (modifiedIoControlCode == IOCTL_STORAGE_RESERVE) ? SCSIOP_RESERVE_UNIT10 : SCSIOP_RELEASE_UNIT10;
8153 }
8154 else
8155 {
8156 SrbSetCdbLength(srb, 6);
8157 cdb = SrbGetCdb(srb);
8158 cdb->CDB6GENERIC.OperationCode = (modifiedIoControlCode == IOCTL_STORAGE_RESERVE) ? SCSIOP_RESERVE_UNIT : SCSIOP_RELEASE_UNIT;
8159 }
8160
8161 //
8162 // Set timeout value.
8163 //
8164
8165 SrbSetTimeOutValue(srb, fdoExtension->TimeOutValue);
8166
8167 //
8168 // Send reserves as tagged requests.
8169 //
8170
8171 if ( IOCTL_STORAGE_RESERVE == modifiedIoControlCode ) {
8174 }
8175
8177 srb,
8178 Irp,
8179 NULL,
8180 0,
8181 FALSE);
8182
8183 break;
8184 }
8185
8188
8189 if (!commonExtension->IsFdo) {
8190
8192
8194 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8195 goto SetStatusAndReturn;
8196 }
8197
8198 //
8199 // Process Persistent Reserve
8200 //
8201
8203
8204 break;
8205
8206 }
8207
8211
8212 //
8213 // Eject media.
8214 //
8215
8216 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
8217
8218 if (!commonExtension->IsFdo) {
8219
8220
8222
8224
8225 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8226 goto SetStatusAndReturn;
8227 } else {
8228 fdoExtension = DeviceObject->DeviceExtension;
8229 }
8230
8231 if (commonExtension->PagingPathCount != 0) {
8232
8233 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "ClassDeviceControl: call to eject paging device - "
8234 "failure\n"));
8235
8237 Irp->IoStatus.Status = status;
8238
8239 Irp->IoStatus.Information = 0;
8240
8241 FREE_POOL(srb);
8242
8245 goto SetStatusAndReturn;
8246 }
8247
8248 //
8249 // Synchronize with ejection control and ejection cleanup code as
8250 // well as other eject/load requests.
8251 //
8252
8256 KernelMode,
8257 FALSE,
8258 NULL);
8259
8260 if (fdoExtension->ProtectedLockCount != 0) {
8261
8262 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "ClassDeviceControl: call to eject protected locked "
8263 "device - failure\n"));
8264
8266 Irp->IoStatus.Status = status;
8267 Irp->IoStatus.Information = 0;
8268
8269 FREE_POOL(srb);
8270
8273
8276 FALSE);
8278
8279 goto SetStatusAndReturn;
8280 }
8281
8282 SrbSetCdbLength(srb, 6);
8283 cdb = SrbGetCdb(srb);
8284
8285 cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
8286 cdb->START_STOP.LoadEject = 1;
8287
8288 if (modifiedIoControlCode == IOCTL_STORAGE_EJECT_MEDIA) {
8289 cdb->START_STOP.Start = 0;
8290 } else {
8291 cdb->START_STOP.Start = 1;
8292 }
8293
8294 //
8295 // Set timeout value.
8296 //
8297
8298 SrbSetTimeOutValue(srb, fdoExtension->TimeOutValue);
8300 srb,
8301 Irp,
8302 NULL,
8303 0,
8304 FALSE);
8305
8308
8309 break;
8310 }
8311
8313
8314 FREE_POOL(srb);
8315
8316 if (commonExtension->IsFdo) {
8317
8319 ((PFUNCTIONAL_DEVICE_EXTENSION) commonExtension)->LowerPdo,
8320 BusRelations);
8321
8323 Irp->IoStatus.Status = status;
8324
8327 }
8328 else {
8329
8330
8332
8334 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8335 }
8336 break;
8337 }
8338
8340
8341 FREE_POOL(srb);
8342
8343 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >=
8344 sizeof(STORAGE_DEVICE_NUMBER)) {
8345
8346 PSTORAGE_DEVICE_NUMBER deviceNumber =
8347 Irp->AssociatedIrp.SystemBuffer;
8348 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
8349 commonExtension->PartitionZeroExtension;
8350
8351 deviceNumber->DeviceType = fdoExtension->CommonExtension.DeviceObject->DeviceType;
8352 deviceNumber->DeviceNumber = fdoExtension->DeviceNumber;
8353 deviceNumber->PartitionNumber = commonExtension->PartitionNumber;
8354
8356 Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
8357
8358 } else {
8360 Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
8361 }
8362
8363 Irp->IoStatus.Status = status;
8366
8367 break;
8368 }
8369
8370
8372
8373 FREE_POOL(srb);
8374
8375 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
8376 sizeof(STORAGE_READ_CAPACITY)) {
8377
8378 //
8379 // Indicate unsuccessful status and no data transferred.
8380 //
8381
8382 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
8383 Irp->IoStatus.Information = sizeof(STORAGE_READ_CAPACITY);
8384
8388 break;
8389 }
8390
8391 if (!commonExtension->IsFdo) {
8392
8393
8394 //
8395 // Just forward this down and return
8396 //
8397
8399
8401 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8402 }
8403 else {
8404
8405 PFUNCTIONAL_DEVICE_EXTENSION fdoExt = DeviceObject->DeviceExtension;
8406 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
8407 PSTORAGE_READ_CAPACITY readCapacity = Irp->AssociatedIrp.SystemBuffer;
8408 LARGE_INTEGER diskLength;
8409
8411 if (NT_SUCCESS(status) && fdoData->IsCachedDriveCapDataValid) {
8412
8413 readCapacity->Version = sizeof(STORAGE_READ_CAPACITY);
8414 readCapacity->Size = sizeof(STORAGE_READ_CAPACITY);
8415
8416 REVERSE_BYTES(&readCapacity->BlockLength,
8418 REVERSE_BYTES_QUAD(&readCapacity->NumberOfBlocks,
8420 readCapacity->NumberOfBlocks.QuadPart++;
8421
8422 readCapacity->DiskLength = fdoExt->CommonExtension.PartitionLength;
8423
8424 //
8425 // Make sure the lengths are equal.
8426 // Remove this after testing.
8427 //
8428 diskLength.QuadPart = readCapacity->NumberOfBlocks.QuadPart *
8429 readCapacity->BlockLength;
8430
8431 Irp->IoStatus.Status = STATUS_SUCCESS;
8432 Irp->IoStatus.Information = sizeof(STORAGE_READ_CAPACITY);
8433
8434 } else {
8435 //
8436 // Read capacity request failed.
8437 //
8438 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "ClassDeviceControl: ClassReadDriveCapacity failed: 0x%X IsCachedDriveCapDataValid: %d\n",
8440 Irp->IoStatus.Status = status;
8441 Irp->IoStatus.Information = 0;
8442 }
8445 }
8446
8447 break;
8448 }
8449
8451
8452 PSTORAGE_PROPERTY_QUERY query = Irp->AssociatedIrp.SystemBuffer;
8453
8454 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(STORAGE_PROPERTY_QUERY)) {
8455
8457 Irp->IoStatus.Status = status;
8460 FREE_POOL(srb);
8461 break;
8462 }
8463
8464 if (!commonExtension->IsFdo) {
8465
8466
8468
8470 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8471 FREE_POOL(srb);
8472 break;
8473 }
8474
8475 //
8476 // Determine PropertyId type and either call appropriate routine
8477 // or pass request to lower drivers.
8478 //
8479
8480 switch ( query->PropertyId ) {
8481
8483
8485 break;
8486 }
8487
8489
8491 break;
8492 }
8493
8494 // these propertyId has been implemented in some port driver and filter drivers.
8495 // to keep the backwards compatibility, classpnp will send the request down if it's supported by lower layer.
8496 // otherwise, classpnp sends SCSI command and then interprets the result.
8498
8500 break;
8501 }
8502
8504
8506 break;
8507 }
8508
8510
8512 break;
8513 }
8514
8516
8518 break;
8519 }
8520
8522
8523 status = ClasspDeviceCopyOffloadProperty(DeviceObject, Irp, srb);
8524 break;
8525 }
8526
8528
8530 break;
8531 }
8532
8533 default: {
8534
8535 //
8536 // Copy the Irp stack parameters to the next stack location.
8537 //
8538
8540
8542 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8543 break;
8544 }
8545 } // end switch
8546
8547 FREE_POOL(srb);
8548 break;
8549 }
8550
8552
8553 FREE_POOL(srb);
8554
8555 if (!commonExtension->IsFdo) {
8556
8557
8559
8561 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8562 break;
8563 }
8564
8565 //
8566 // Process priority hit request
8567 //
8568
8570 break;
8571 }
8572
8574
8575 PDEVICE_MANAGE_DATA_SET_ATTRIBUTES dsmAttributes = Irp->AssociatedIrp.SystemBuffer;
8576
8577 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) {
8578
8580 Irp->IoStatus.Status = status;
8583 FREE_POOL(srb);
8584 break;
8585 }
8586
8587 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
8588 (sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + dsmAttributes->ParameterBlockLength + dsmAttributes->DataSetRangesLength)) {
8589
8591 Irp->IoStatus.Status = status;
8594 FREE_POOL(srb);
8595 break;
8596 }
8597
8598 if (!commonExtension->IsFdo) {
8599
8600
8602
8604 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8605 FREE_POOL(srb);
8606 break;
8607 }
8608
8609 switch(dsmAttributes->Action) {
8610
8611 // only process Trim action in class layer if possible.
8612 case DeviceDsmAction_Trim: {
8613 status = ClasspDeviceTrimProcess(DeviceObject, Irp, &activityId, srb);
8614 break;
8615 }
8616
8618 status = ClassDeviceProcessOffloadRead(DeviceObject, Irp, srb);
8619 break;
8620 }
8621
8623 status = ClassDeviceProcessOffloadWrite(DeviceObject, Irp, srb);
8624 break;
8625 }
8626
8629 break;
8630 }
8631
8632
8633 default: {
8634
8635
8636 //
8637 // Copy the Irp stack parameters to the next stack location.
8638 //
8639
8641
8643 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8644 break;
8645 }
8646 } // end switch
8647
8648 FREE_POOL(srb);
8649 break;
8650 }
8651
8653
8654 if (commonExtension->IsFdo) {
8655
8657
8658 } else {
8659
8661
8663 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8664 }
8665
8666 FREE_POOL(srb);
8667
8668 break;
8669 }
8670
8672
8673 FREE_POOL(srb);
8674
8676 break;
8677 }
8678
8679#if (NTDDI_VERSION >= NTDDI_WINTRHESHOLD)
8681 FREE_POOL(srb);
8682
8684 break;
8685 }
8686
8688 if (!commonExtension->IsFdo) {
8689
8691
8693 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8694 goto SetStatusAndReturn;
8695 }
8696
8698 break;
8699 }
8700
8702 if (!commonExtension->IsFdo) {
8703
8705
8707 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8708 goto SetStatusAndReturn;
8709 }
8710
8712 break;
8713 }
8714#endif
8715
8716
8717 default: {
8718
8719 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "IoDeviceControl: Unsupported device IOCTL %x for %p\n",
8720 controlCode, DeviceObject));
8721
8722
8723 //
8724 // Pass the device control to the next driver.
8725 //
8726
8727 FREE_POOL(srb);
8728
8729 //
8730 // Copy the Irp stack parameters to the next stack location.
8731 //
8732
8734
8736 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8737 break;
8738 }
8739
8740 } // end switch( ...
8741
8742SetStatusAndReturn:
8743
8744 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "< ioctl %xh (%s): status %xh.", modifiedIoControlCode, DBGGETIOCTLSTR(modifiedIoControlCode), status));
8745
8746 return status;
8747} // end ClassDeviceControl()
#define VOID
Definition: acefi.h:82
#define SRB_CLASS_FLAGS_LOW_PRIORITY
Definition: cdrom.h:162
#define FDO_HACK_NO_RESERVE6
Definition: cdromp.h:135
#define CLASSP_REG_WRITE_CACHE_VALUE_NAME
Definition: cdromp.h:124
@ SimpleMediaLock
Definition: cdromp.h:289
@ SecureMediaLock
Definition: cdromp.h:290
#define CLASSP_REG_REMOVAL_POLICY_VALUE_NAME
Definition: cdromp.h:126
#define CLASSP_REG_SUBKEY_NAME
Definition: cdromp.h:120
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define SCSIOP_RELEASE_UNIT
Definition: cdrw_hw.h:893
#define SCSIOP_RESERVE_UNIT
Definition: cdrw_hw.h:892
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
NTSTATUS InitializeStorageRequestBlock(_Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, _In_ USHORT AddressType, _In_ ULONG ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:206
NTSTATUS ClasspDeviceLBProvisioningProperty(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:2894
NTSTATUS ClasspWriteCacheProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:1199
NTSTATUS ClasspDeviceTrimProcess(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PGUID ActivityId, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:3476
_IRQL_requires_same_ NTSTATUS ClasspStorageEventNotification(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: utils.c:7826
NTSTATUS ClassDeviceHwFirmwareDownloadProcess(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:8541
NTSTATUS ClasspDeviceGetLBAStatus(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:3861
NTSTATUS ClasspPersistentReserve(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:6211
NTSTATUS ClasspDuidQueryProperty(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: utils.c:997
NTSTATUS ClasspAccessAlignmentProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:1700
NTSTATUS ClassDeviceHwFirmwareGetInfoProcess(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: utils.c:8366
NTSTATUS ClasspPriorityHint(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: utils.c:6480
NTSTATUS ClasspDeviceSeekPenaltyProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:2172
NTSTATUS ClasspDeviceTrimProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:2730
NTSTATUS ClasspEjectionControl(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN MEDIA_LOCK_TYPE LockType, IN BOOLEAN Lock)
Definition: create.c:474
NTSTATUS ClassDeviceGetLBProvisioningResources(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:5087
NTSTATUS ClassDeviceHwFirmwareActivateProcess(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:8902
NTSTATUS ClasspDeviceMediaTypeProperty(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:1917
NTSTATUS ClasspMcnControl(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb)
Definition: autorun.c:3276
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
SCSIPORT_API NTSTATUS NTAPI ClassSendSrbAsynchronous(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PSCSI_REQUEST_BLOCK Srb, _In_ PIRP Irp, _In_reads_bytes_opt_(BufferLength) __drv_aliasesMem PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
IO_COMPLETION_ROUTINE ClassCheckVerifyComplete
Definition: class.c:84
#define LastDriveLetter
Definition: class.c:93
_Must_inspect_result_ NTSTATUS NTAPI ClassReadDriveCapacity(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:2742
#define FirstDriveLetter
Definition: class.c:92
#define DBGGETIOCTLSTR(_ioctl)
Definition: debug.h:25
#define ULONG_PTR
Definition: config.h:101
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define IOCTL_STORAGE_CHECK_VERIFY2
Definition: ntddk_ex.h:212
#define IOCTL_STORAGE_LOAD_MEDIA2
Definition: ntddk_ex.h:210
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define REG_SZ
Definition: layer.c:22
struct _MOUNTDEV_NAME MOUNTDEV_NAME
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
struct _STORAGE_HOTPLUG_INFO STORAGE_HOTPLUG_INFO
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:91
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:97
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:78
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
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 IOCTL_DISK_BASE
Definition: ntdddisk.h:44
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
#define IOCTL_STORAGE_RELEASE
Definition: ntddstor.h:119
#define DeviceDsmAction_OffloadRead
Definition: ntddstor.h:278
STORAGE_READ_CAPACITY
Definition: ntddstor.h:861
#define IOCTL_STORAGE_EVENT_NOTIFICATION
Definition: ntddstor.h:226
#define DeviceDsmAction_Allocation
Definition: ntddstor.h:280
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
#define IOCTL_STORAGE_SET_HOTPLUG_INFO
Definition: ntddstor.h:157
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define IOCTL_STORAGE_FIRMWARE_ACTIVATE
Definition: ntddstor.h:211
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98
#define IOCTL_STORAGE_READ_CAPACITY
Definition: ntddstor.h:175
#define IOCTL_STORAGE_FIRMWARE_DOWNLOAD
Definition: ntddstor.h:208
#define DeviceDsmAction_OffloadWrite
Definition: ntddstor.h:279
#define IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
Definition: ntddstor.h:181
#define IOCTL_STORAGE_PERSISTENT_RESERVE_IN
Definition: ntddstor.h:169
#define IOCTL_STORAGE_PERSISTENT_RESERVE_OUT
Definition: ntddstor.h:172
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:110
#define IOCTL_STORAGE_RESERVE
Definition: ntddstor.h:116
@ StorageDeviceUniqueIdProperty
Definition: ntddstor.h:515
@ StorageDeviceMediumProductType
Definition: ntddstor.h:527
@ StorageDeviceSeekPenaltyProperty
Definition: ntddstor.h:519
@ StorageDeviceLBProvisioningProperty
Definition: ntddstor.h:523
@ StorageDeviceWriteCacheProperty
Definition: ntddstor.h:516
@ StorageDeviceTrimProperty
Definition: ntddstor.h:520
@ StorageDeviceCopyOffloadProperty
Definition: ntddstor.h:525
@ StorageAccessAlignmentProperty
Definition: ntddstor.h:518
#define IOCTL_STORAGE_FIRMWARE_GET_INFO
Definition: ntddstor.h:205
#define IOCTL_STORAGE_GET_LB_PROVISIONING_MAP_RESOURCES
Definition: ntddstor.h:184
#define IOCTL_STORAGE_FIND_NEW_DEVICES
Definition: ntddstor.h:122
#define IOCTL_STORAGE_BASE
Definition: ntddstor.h:96
#define IOCTL_STORAGE_MCN_CONTROL
Definition: ntddstor.h:128
#define IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT
Definition: ntddstor.h:196
#define DeviceDsmAction_Trim
Definition: ntddstor.h:276
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
#define IOCTL_STORAGE_EJECTION_CONTROL
Definition: ntddstor.h:125
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:104
* PSTORAGE_READ_CAPACITY
Definition: ntddstor.h:861
#define IOCTL_TAPE_BASE
Definition: ntddtape.h:35
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#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_FILES_OPEN
Definition: ntstatus.h:499
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
#define SCSIOP_RELEASE_UNIT10
Definition: scsi.h:322
#define SCSIOP_RESERVE_UNIT10
Definition: scsi.h:320
#define REVERSE_BYTES_QUAD(Destination, Source)
Definition: scsi.h:3452
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:664
#define STORAGE_ADDRESS_TYPE_BTL8
Definition: srb.h:666
@ SrbExDataTypeScsiCdb16
Definition: srb.h:459
#define IOCTL_SCSI_PASS_THROUGH_DIRECT_EX
Definition: ntddscsi.h:38
#define IOCTL_SCSI_PASS_THROUGH_EX
Definition: ntddscsi.h:37
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
BOOLEAN IsCachedDriveCapDataValid
Definition: classp.h:803
READ_CAPACITY_DATA_EX LastKnownDriveCapacityData
Definition: classp.h:802
PDEVICE_OBJECT DeviceObject
Definition: pci.h:46
UNICODE_STRING DeviceName
Definition: classpnp.h:615
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
UNICODE_STRING MountedDeviceInterfaceName
Definition: classpnp.h:628
LARGE_INTEGER PartitionLength
Definition: classpnp.h:618
DEVICE_DATA_MANAGEMENT_SET_ACTION Action
Definition: ntddstor.h:773
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
USHORT UniqueIdLength
Definition: imports.h:136
UCHAR UniqueId[1]
Definition: imports.h:137
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:343
LARGE_INTEGER LogicalBlockAddress
Definition: scsi.h:2749
DEVICE_TYPE DeviceType
Definition: ntddstor.h:324
Definition: name.c:39
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
char CCHAR
Definition: typedefs.h:51
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
Definition: cdrw_hw.h:28
struct _CDB::_CDB10 CDB10
struct _CDB::_CDB6GENERIC CDB6GENERIC
struct _CDB::_START_STOP START_STOP
LONGLONG QuadPart
Definition: typedefs.h:114
#define SrbGetCdb(srb)
Definition: usbstor.h:18
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2680
@ BusRelations
Definition: iotypes.h:2152
@ RemovalPolicyExpectSurpriseRemoval
Definition: iotypes.h:842
@ RemovalPolicyExpectOrderlyRemoval
Definition: iotypes.h:841
@ UserRequest
Definition: ketypes.h:421
#define RTL_QUERY_REGISTRY_TYPECHECK
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ ClassDeviceControlDispatch()

NTSTATUS NTAPI ClassDeviceControlDispatch ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 7258 of file class.c.

7262{
7263
7264 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
7265 ULONG isRemoved;
7266
7268 _Analysis_assume_(isRemoved);
7269 if(isRemoved) {
7270
7272
7273 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
7276 }
7277
7278 //
7279 // Call the class specific driver DeviceControl routine.
7280 // If it doesn't handle it, it will call back into ClassDeviceControl.
7281 //
7282
7283 NT_ASSERT(commonExtension->DevInfo->ClassDeviceControl);
7284
7285 return commonExtension->DevInfo->ClassDeviceControl(DeviceObject,Irp);
7286} // end ClassDeviceControlDispatch()
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
PCLASS_DEVICE_CONTROL ClassDeviceControl
Definition: classpnp.h:524
PCLASS_DEV_INFO DevInfo
Definition: classpnp.h:620

Referenced by ClassInitializeDispatchTables().

◆ ClassDispatchPnp()

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

Definition at line 894 of file class.c.

898{
899 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
900 BOOLEAN isFdo = commonExtension->IsFdo;
901
902 PCLASS_DRIVER_EXTENSION driverExtension;
903 PCLASS_INIT_DATA initData;
904 PCLASS_DEV_INFO devInfo;
905
907
908 NTSTATUS status = Irp->IoStatus.Status;
909 BOOLEAN completeRequest = TRUE;
910 BOOLEAN lockReleased = FALSE;
911
912
913 PAGED_CODE();
914
915 //
916 // Extract all the useful information out of the driver object
917 // extension
918 //
919
920#ifdef _MSC_VER
921#pragma warning(suppress:4054) // okay to type cast function pointer as data pointer for this use case
922#endif
924
925 if (driverExtension){
926
927 initData = &(driverExtension->InitData);
928
929 if(isFdo) {
930 devInfo = &(initData->FdoData);
931 } else {
932 devInfo = &(initData->PdoData);
933 }
934
936
937 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): minor code %#x for %s %p\n",
939 irpStack->MinorFunction,
940 isFdo ? "fdo" : "pdo",
941 DeviceObject));
942 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): previous %#x, current %#x\n",
944 commonExtension->PreviousState,
945 commonExtension->CurrentState));
946
947
948 switch(irpStack->MinorFunction) {
949
950 case IRP_MN_START_DEVICE: {
951
952 //
953 // if this is sent to the FDO we should forward it down the
954 // attachment chain before we start the FDO.
955 //
956
957 if (isFdo) {
958 status = ClassForwardIrpSynchronous(commonExtension, Irp);
959 }
960 else {
962 }
963
964 if (NT_SUCCESS(status)){
965 status = Irp->IoStatus.Status = ClassPnpStartDevice(DeviceObject);
966 }
967
968 break;
969 }
970
971
973
975 irpStack->Parameters.QueryDeviceRelations.Type;
976
977 PDEVICE_RELATIONS deviceRelations = NULL;
978
979
980 if(!isFdo) {
981
983
984 //
985 // Device relations has one entry built in to it's size.
986 //
987
989
990 deviceRelations = ExAllocatePoolWithTag(PagedPool,
991 sizeof(DEVICE_RELATIONS),
992 '2CcS');
993
994 if(deviceRelations != NULL) {
995
996 RtlZeroMemory(deviceRelations,
997 sizeof(DEVICE_RELATIONS));
998
999 Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
1000
1001 deviceRelations->Count = 1;
1002 deviceRelations->Objects[0] = DeviceObject;
1003 ObReferenceObject(deviceRelations->Objects[0]);
1004
1006 }
1007
1008 } else {
1009 //
1010 // PDO's just complete enumeration requests without altering
1011 // the status.
1012 //
1013
1014 status = Irp->IoStatus.Status;
1015 }
1016
1017 break;
1018
1019 } else if (type == BusRelations) {
1020
1021 NT_ASSERT(commonExtension->IsInitialized);
1022
1023 //
1024 // Make sure we support enumeration
1025 //
1026
1027 if(initData->ClassEnumerateDevice == NULL) {
1028
1029 //
1030 // Just send the request down to the lower driver. Perhaps
1031 // It can enumerate children.
1032 //
1033
1034 } else {
1035
1036 //
1037 // Re-enumerate the device
1038 //
1039
1041
1042 if(!NT_SUCCESS(status)) {
1043 completeRequest = TRUE;
1044 break;
1045 }
1046 }
1047 }
1048
1049
1052 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1053 completeRequest = FALSE;
1054
1055 break;
1056 }
1057
1058 case IRP_MN_QUERY_ID: {
1059
1060 BUS_QUERY_ID_TYPE idType = irpStack->Parameters.QueryId.IdType;
1061 UNICODE_STRING unicodeString;
1062
1063
1064 if(isFdo) {
1065
1066
1067 //
1068 // FDO's should just forward the query down to the lower
1069 // device objects
1070 //
1071
1074
1075 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1076 completeRequest = FALSE;
1077 break;
1078 }
1079
1080 //
1081 // PDO's need to give an answer - this is easy for now
1082 //
1083
1084 RtlInitUnicodeString(&unicodeString, NULL);
1085
1087 idType,
1088 &unicodeString);
1089
1091 //
1092 // The driver doesn't implement this ID (whatever it is).
1093 // Use the status out of the IRP so that we don't mangle a
1094 // response from someone else.
1095 //
1096
1097 status = Irp->IoStatus.Status;
1098 } else if(NT_SUCCESS(status)) {
1099 Irp->IoStatus.Information = (ULONG_PTR) unicodeString.Buffer;
1100 } else {
1101 Irp->IoStatus.Information = (ULONG_PTR) NULL;
1102 }
1103
1104 break;
1105 }
1106
1109
1110
1111 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Processing QUERY_%s irp\n",
1113 ((irpStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) ?
1114 "STOP" : "REMOVE")));
1115
1116 //
1117 // If this device is in use for some reason (paging, etc...)
1118 // then we need to fail the request.
1119 //
1120
1121 if(commonExtension->PagingPathCount != 0) {
1122
1123 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): device is in paging "
1124 "path and cannot be removed\n",
1125 DeviceObject, Irp));
1127 break;
1128 }
1129
1130
1131 //
1132 // Check with the class driver to see if the query operation
1133 // can succeed.
1134 //
1135
1136 if(irpStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) {
1138 irpStack->MinorFunction);
1139 } else {
1141 irpStack->MinorFunction);
1142 }
1143
1144 if(NT_SUCCESS(status)) {
1145
1146 //
1147 // ASSERT that we never get two queries in a row, as
1148 // this will severly mess up the state machine
1149 //
1150 NT_ASSERT(commonExtension->CurrentState != irpStack->MinorFunction);
1151 commonExtension->PreviousState = commonExtension->CurrentState;
1152 commonExtension->CurrentState = irpStack->MinorFunction;
1153
1154 if(isFdo) {
1155 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Forwarding QUERY_"
1156 "%s irp\n", DeviceObject, Irp,
1157 ((irpStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) ?
1158 "STOP" : "REMOVE")));
1159 status = ClassForwardIrpSynchronous(commonExtension, Irp);
1160 }
1161 }
1162
1163
1164 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Final status == %x\n",
1166
1167 break;
1168 }
1169
1172
1173
1174 //
1175 // Check with the class driver to see if the query or cancel
1176 // operation can succeed.
1177 //
1178
1179 if(irpStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) {
1181 irpStack->MinorFunction);
1182 NT_ASSERTMSG("ClassDispatchPnp !! CANCEL_STOP_DEVICE should never be failed\n", NT_SUCCESS(status));
1183 } else {
1185 irpStack->MinorFunction);
1186 NT_ASSERTMSG("ClassDispatchPnp !! CANCEL_REMOVE_DEVICE should never be failed\n", NT_SUCCESS(status));
1187 }
1188
1189 Irp->IoStatus.Status = status;
1190
1191 //
1192 // We got a CANCEL - roll back to the previous state only
1193 // if the current state is the respective QUERY state.
1194 //
1195
1196 if(((irpStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) &&
1197 (commonExtension->CurrentState == IRP_MN_QUERY_STOP_DEVICE)
1198 ) ||
1200 (commonExtension->CurrentState == IRP_MN_QUERY_REMOVE_DEVICE)
1201 )
1202 ) {
1203
1204 commonExtension->CurrentState =
1205 commonExtension->PreviousState;
1206 commonExtension->PreviousState = 0xff;
1207
1208 }
1209
1210
1211 if(isFdo) {
1212
1213
1216 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1217 completeRequest = FALSE;
1218 } else {
1220 }
1221
1222 break;
1223 }
1224
1225 case IRP_MN_STOP_DEVICE: {
1226
1227
1228 //
1229 // These all mean nothing to the class driver currently. The
1230 // port driver will handle all queueing when necessary.
1231 //
1232
1233 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): got stop request for %s\n",
1235 (isFdo ? "fdo" : "pdo")
1236 ));
1237
1238 NT_ASSERT(commonExtension->PagingPathCount == 0);
1239
1240 //
1241 // ISSUE-2000/02/03-peterwie
1242 // if we stop the timer here then it means no class driver can
1243 // do i/o in its ClassStopDevice routine. This is because the
1244 // retry (among other things) is tied into the tick handler
1245 // and disabling retries could cause the class driver to deadlock.
1246 // Currently no class driver we're aware of issues i/o in its
1247 // Stop routine but this is a case we may want to defend ourself
1248 // against.
1249 //
1250
1252
1253
1255
1256 NT_ASSERTMSG("ClassDispatchPnp !! STOP_DEVICE should never be failed\n", NT_SUCCESS(status));
1257
1258 if(isFdo) {
1259 status = ClassForwardIrpSynchronous(commonExtension, Irp);
1260 }
1261
1262 if(NT_SUCCESS(status)) {
1263 commonExtension->CurrentState = irpStack->MinorFunction;
1264 commonExtension->PreviousState = 0xff;
1265 }
1266
1267
1268 break;
1269 }
1270
1273 UCHAR removeType = irpStack->MinorFunction;
1274
1275 //
1276 // Log a sytem event when non-removable disks are surprise-removed.
1277 //
1278 if (isFdo &&
1279 (removeType == IRP_MN_SURPRISE_REMOVAL)) {
1280
1281 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1282 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
1283 BOOLEAN logSurpriseRemove = TRUE;
1284 STORAGE_BUS_TYPE busType = fdoExtension->DeviceDescriptor->BusType;
1285
1286 //
1287 // Don't log an event for VHDs
1288 //
1289 if (busType == BusTypeFileBackedVirtual) {
1290 logSurpriseRemove = FALSE;
1291
1292 } else if (fdoData->HotplugInfo.MediaRemovable) {
1293 logSurpriseRemove = FALSE;
1294
1295 } else if (fdoData->HotplugInfo.DeviceHotplug && ( busType == BusTypeUsb || busType == BusType1394)) {
1296
1297 /*
1298 This device is reported as DeviceHotplug but since the busType is Usb or 1394, don't log an event
1299 Note that some storage arrays may report DeviceHotplug and we would like to log an event in those cases
1300 */
1301
1302 logSurpriseRemove = FALSE;
1303 }
1304
1305 if (logSurpriseRemove) {
1306
1308 }
1309
1310 }
1311
1312 if (commonExtension->PagingPathCount != 0) {
1313 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): paging device is getting removed!", DeviceObject, Irp));
1314 }
1315
1316 //
1317 // Release the lock for this IRP before calling in.
1318 //
1320 lockReleased = TRUE;
1321
1322 /*
1323 * Set IsRemoved before propagating the REMOVE down the stack.
1324 * This keeps class-initiated I/O (e.g. the MCN irp) from getting sent
1325 * after we propagate the remove.
1326 */
1327 commonExtension->IsRemoved = REMOVE_PENDING;
1328
1329 /*
1330 * If a timer was started on the device, stop it.
1331 */
1333
1334 /*
1335 * "Fire-and-forget" the remove irp to the lower stack.
1336 * Don't touch the irp (or the irp stack!) after this.
1337 */
1338 if (isFdo) {
1339
1340
1342 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1344 completeRequest = FALSE;
1345 }
1346 else {
1348 }
1349
1350 /*
1351 * Do our own cleanup and call the class driver's remove
1352 * cleanup routine.
1353 * For IRP_MN_REMOVE_DEVICE, this also deletes our device object,
1354 * so don't touch the extension after this.
1355 */
1356 commonExtension->PreviousState = commonExtension->CurrentState;
1357 commonExtension->CurrentState = removeType;
1358 ClassRemoveDevice(DeviceObject, removeType);
1359
1360 break;
1361 }
1362
1364
1366 BOOLEAN setPagable;
1367
1368
1369 switch(type) {
1370
1371 case DeviceUsageTypePaging: {
1372
1373 if ((irpStack->Parameters.UsageNotification.InPath) &&
1374 (commonExtension->CurrentState != IRP_MN_START_DEVICE)) {
1375
1376 //
1377 // Device isn't started. Don't allow adding a
1378 // paging file, but allow a removal of one.
1379 //
1380
1382 break;
1383 }
1384
1385 NT_ASSERT(commonExtension->IsInitialized);
1386
1387 /*
1388 * Ensure that this user thread is not suspended while we are holding the PathCountEvent.
1389 */
1391
1392 (VOID)KeWaitForSingleObject(&commonExtension->PathCountEvent,
1394 FALSE, NULL);
1396
1397 //
1398 // If the volume is removable we should try to lock it in
1399 // place or unlock it once per paging path count
1400 //
1401
1402 if (commonExtension->IsFdo){
1405 Irp,
1407 (BOOLEAN)irpStack->Parameters.UsageNotification.InPath);
1408 }
1409
1410 if (!NT_SUCCESS(status)){
1411 KeSetEvent(&commonExtension->PathCountEvent, IO_NO_INCREMENT, FALSE);
1413 break;
1414 }
1415
1416 //
1417 // if removing last paging device, need to set DO_POWER_PAGABLE
1418 // bit here, and possible re-set it below on failure.
1419 //
1420
1421 setPagable = FALSE;
1422
1423 if ((!irpStack->Parameters.UsageNotification.InPath) &&
1424 (commonExtension->PagingPathCount == 1)) {
1425
1426 //
1427 // removing last paging file
1428 // must have DO_POWER_PAGABLE bits set, but only
1429 // if none set the DO_POWER_INRUSH bit and no other special files
1430 //
1431
1432 if (TEST_FLAG(DeviceObject->Flags, DO_POWER_INRUSH)) {
1433 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Last "
1434 "paging file removed, but "
1435 "DO_POWER_INRUSH was set, so NOT "
1436 "setting DO_POWER_PAGABLE\n",
1437 DeviceObject, Irp));
1438 } else if ((commonExtension->HibernationPathCount == 0) &&
1439 (commonExtension->DumpPathCount == 0)) {
1440 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Last "
1441 "paging file removed, "
1442 "setting DO_POWER_PAGABLE\n",
1443 DeviceObject, Irp));
1445 setPagable = TRUE;
1446 }
1447
1448 }
1449
1450 //
1451 // forward the irp before finishing handling the
1452 // special cases
1453 //
1454
1455 status = ClassForwardIrpSynchronous(commonExtension, Irp);
1456
1457 //
1458 // now deal with the failure and success cases.
1459 // note that we are not allowed to fail the irp
1460 // once it is sent to the lower drivers.
1461 //
1462
1463 if (NT_SUCCESS(status)) {
1464
1466 (volatile LONG *)&commonExtension->PagingPathCount,
1467 irpStack->Parameters.UsageNotification.InPath);
1468
1469 if (irpStack->Parameters.UsageNotification.InPath) {
1470 if (commonExtension->PagingPathCount == 1) {
1471 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): "
1472 "Clearing PAGABLE bit\n",
1473 DeviceObject, Irp));
1475
1476
1477 }
1478
1479 }
1480
1481 } else {
1482
1483 //
1484 // cleanup the changes done above
1485 //
1486
1487 if (setPagable == TRUE) {
1488 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Unsetting "
1489 "PAGABLE bit due to irp failure\n",
1490 DeviceObject, Irp));
1492 setPagable = FALSE;
1493 }
1494
1495 //
1496 // relock or unlock the media if needed.
1497 //
1498
1499 if (commonExtension->IsFdo) {
1500
1503 Irp,
1505 (BOOLEAN)!irpStack->Parameters.UsageNotification.InPath);
1506 }
1507 }
1508
1509 //
1510 // set the event so the next one can occur.
1511 //
1512
1513 KeSetEvent(&commonExtension->PathCountEvent,
1516 break;
1517 }
1518
1520
1521 //
1522 // if removing last hiber device, need to set DO_POWER_PAGABLE
1523 // bit here, and possible re-set it below on failure.
1524 //
1525
1526 setPagable = FALSE;
1527
1528 if ((!irpStack->Parameters.UsageNotification.InPath) &&
1529 (commonExtension->HibernationPathCount == 1)) {
1530
1531 //
1532 // removing last hiber file
1533 // must have DO_POWER_PAGABLE bits set, but only
1534 // if none set the DO_POWER_INRUSH bit and no other special files
1535 //
1536
1537 if (TEST_FLAG(DeviceObject->Flags, DO_POWER_INRUSH)) {
1538 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Last "
1539 "hiber file removed, but "
1540 "DO_POWER_INRUSH was set, so NOT "
1541 "setting DO_POWER_PAGABLE\n",
1542 DeviceObject, Irp));
1543 } else if ((commonExtension->PagingPathCount == 0) &&
1544 (commonExtension->DumpPathCount == 0)) {
1545 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Last "
1546 "hiber file removed, "
1547 "setting DO_POWER_PAGABLE\n",
1548 DeviceObject, Irp));
1550 setPagable = TRUE;
1551 }
1552
1553 }
1554
1555 status = ClassForwardIrpSynchronous(commonExtension, Irp);
1556 if (!NT_SUCCESS(status)) {
1557
1558 if (setPagable == TRUE) {
1559 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Unsetting "
1560 "PAGABLE bit due to irp failure\n",
1561 DeviceObject, Irp));
1563 setPagable = FALSE;
1564 }
1565
1566 } else {
1567
1569 (volatile LONG *)&commonExtension->HibernationPathCount,
1570 irpStack->Parameters.UsageNotification.InPath
1571 );
1572
1573 if ((irpStack->Parameters.UsageNotification.InPath) &&
1574 (commonExtension->HibernationPathCount == 1)) {
1575 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): "
1576 "Clearing PAGABLE bit\n",
1577 DeviceObject, Irp));
1579 }
1580 }
1581
1582 break;
1583 }
1584
1586
1587 //
1588 // if removing last dump device, need to set DO_POWER_PAGABLE
1589 // bit here, and possible re-set it below on failure.
1590 //
1591
1592 setPagable = FALSE;
1593
1594 if ((!irpStack->Parameters.UsageNotification.InPath) &&
1595 (commonExtension->DumpPathCount == 1)) {
1596
1597 //
1598 // removing last dump file
1599 // must have DO_POWER_PAGABLE bits set, but only
1600 // if none set the DO_POWER_INRUSH bit and no other special files
1601 //
1602
1603 if (TEST_FLAG(DeviceObject->Flags, DO_POWER_INRUSH)) {
1604 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Last "
1605 "dump file removed, but "
1606 "DO_POWER_INRUSH was set, so NOT "
1607 "setting DO_POWER_PAGABLE\n",
1608 DeviceObject, Irp));
1609 } else if ((commonExtension->PagingPathCount == 0) &&
1610 (commonExtension->HibernationPathCount == 0)) {
1611 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Last "
1612 "dump file removed, "
1613 "setting DO_POWER_PAGABLE\n",
1614 DeviceObject, Irp));
1616 setPagable = TRUE;
1617 }
1618
1619 }
1620
1621 status = ClassForwardIrpSynchronous(commonExtension, Irp);
1622 if (!NT_SUCCESS(status)) {
1623
1624 if (setPagable == TRUE) {
1625 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): Unsetting "
1626 "PAGABLE bit due to irp failure\n",
1627 DeviceObject, Irp));
1629 setPagable = FALSE;
1630 }
1631
1632 } else {
1633
1635 (volatile LONG *)&commonExtension->DumpPathCount,
1636 irpStack->Parameters.UsageNotification.InPath
1637 );
1638
1639 if ((irpStack->Parameters.UsageNotification.InPath) &&
1640 (commonExtension->DumpPathCount == 1)) {
1641 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): "
1642 "Clearing PAGABLE bit\n",
1643 DeviceObject, Irp));
1645 }
1646 }
1647
1648 break;
1649 }
1650
1651 case DeviceUsageTypeBoot: {
1652
1653 if (isFdo) {
1655
1656 fdoData = ((PFUNCTIONAL_DEVICE_EXTENSION)(DeviceObject->DeviceExtension))->PrivateFdoData;
1657
1658
1659 //
1660 // If boot disk has removal policy as RemovalPolicyExpectSurpriseRemoval (e.g. disk is hotplug-able),
1661 // change the removal policy to RemovalPolicyExpectOrderlyRemoval.
1662 // This will cause the write cache of disk to be enabled on subsequent start Fdo (next boot).
1663 //
1664 if ((fdoData != NULL) &&
1665 fdoData->HotplugInfo.DeviceHotplug) {
1666
1667 fdoData->HotplugInfo.DeviceHotplug = FALSE;
1668 fdoData->HotplugInfo.MediaRemovable = FALSE;
1669
1670 ClassSetDeviceParameter((PFUNCTIONAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension,
1674 }
1675 }
1676
1677 status = ClassForwardIrpSynchronous(commonExtension, Irp);
1678 break;
1679 }
1680
1681 default: {
1683 break;
1684 }
1685 }
1686 break;
1687 }
1688
1690
1691 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): QueryCapabilities\n",
1692 DeviceObject, Irp));
1693
1694 if(!isFdo) {
1695
1698 irpStack->Parameters.DeviceCapabilities.Capabilities
1699 );
1700
1701 break;
1702
1703 } else {
1704
1705 PDEVICE_CAPABILITIES deviceCapabilities;
1706 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
1708
1709 fdoExtension = DeviceObject->DeviceExtension;
1710 fdoData = fdoExtension->PrivateFdoData;
1711 deviceCapabilities =
1712 irpStack->Parameters.DeviceCapabilities.Capabilities;
1713
1714 //
1715 // forward the irp before handling the special cases
1716 //
1717
1718 status = ClassForwardIrpSynchronous(commonExtension, Irp);
1719 if (!NT_SUCCESS(status)) {
1720 break;
1721 }
1722
1723 //
1724 // we generally want to remove the device from the hotplug
1725 // applet, which requires the SR-OK bit to be set.
1726 // only when the user specifies that they are capable of
1727 // safely removing things do we want to clear this bit
1728 // (saved in WriteCacheEnableOverride)
1729 //
1730 // setting of this bit is done either above, or by the
1731 // lower driver.
1732 //
1733 // note: may not be started, so check we have FDO data first.
1734 //
1735
1736 if (fdoData &&
1738 if (deviceCapabilities->SurpriseRemovalOK) {
1739 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "Classpnp: Clearing SR-OK bit in "
1740 "device capabilities due to hotplug "
1741 "device or media\n"));
1742 }
1743 deviceCapabilities->SurpriseRemovalOK = FALSE;
1744 }
1745 break;
1746
1747 } // end QUERY_CAPABILITIES for FDOs
1748
1749 break;
1750
1751
1752 } // end QUERY_CAPABILITIES
1753
1754 default: {
1755
1756 if (isFdo){
1757
1758
1760
1762 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1763
1764 completeRequest = FALSE;
1765 }
1766
1767 break;
1768 }
1769 }
1770 }
1771 else {
1772 NT_ASSERT(driverExtension);
1774 }
1775
1776 if (completeRequest){
1777 Irp->IoStatus.Status = status;
1778
1779 if (!lockReleased){
1781 }
1782
1784
1785 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): leaving with previous %#x, current %#x.", DeviceObject, Irp, commonExtension->PreviousState, commonExtension->CurrentState));
1786 }
1787 else {
1788 /*
1789 * The irp is already completed so don't touch it.
1790 * This may be a remove so don't touch the device extension.
1791 */
1792 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "ClassDispatchPnp (%p,%p): leaving.", DeviceObject, Irp));
1793 }
1794
1795 return status;
1796} // end ClassDispatchPnp()
unsigned char BOOLEAN
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
@ InternalMediaLock
Definition: cdromp.h:291
NTSTATUS ClasspLogSystemEventWithDeviceNumber(_In_ PDEVICE_OBJECT DeviceObject, _In_ NTSTATUS IoErrorCode)
Definition: utils.c:5354
VOID ClasspDisableTimer(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:3956
#define REMOVE_PENDING
Definition: classpnp.h:97
NTSTATUS ClassPnpStartDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: class.c:1819
NTSTATUS ClassGetPdoId(IN PDEVICE_OBJECT Pdo, IN BUS_QUERY_ID_TYPE IdType, IN PUNICODE_STRING IdString)
Definition: class.c:10151
NTSTATUS ClassQueryPnpCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_CAPABILITIES Capabilities)
Definition: class.c:10192
NTSTATUS ClassPnpQueryFdoRelations(IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
Definition: class.c:9843
NTSTATUS NTAPI ClassForwardIrpSynchronous(_In_ PCOMMON_DEVICE_EXTENSION CommonExtension, _In_ PIRP Irp)
Definition: class.c:11343
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
@ BusTypeFileBackedVirtual
Definition: ntddstor.h:453
@ BusTypeUsb
Definition: ntddstor.h:445
@ BusType1394
Definition: ntddstor.h:442
enum _STORAGE_BUS_TYPE STORAGE_BUS_TYPE
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IO_WARNING_DISK_SURPRISE_REMOVED
Definition: ntiologc.h:118
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
long LONG
Definition: pedump.c:60
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
PCLASS_REMOVE_DEVICE ClassRemoveDevice
Definition: classpnp.h:531
PCLASS_STOP_DEVICE ClassStopDevice
Definition: classpnp.h:530
CLASS_DEV_INFO FdoData
Definition: classpnp.h:538
CLASS_DEV_INFO PdoData
Definition: classpnp.h:539
PCLASS_ENUM_DEVICE ClassEnumerateDevice
Definition: classpnp.h:541
STORAGE_HOTPLUG_INFO HotplugInfo
Definition: classp.h:739
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:876
struct _IO_STACK_LOCATION::@3984::@4015 QueryId
struct _IO_STACK_LOCATION::@3984::@4009 QueryDeviceRelations
struct _IO_STACK_LOCATION::@3984::@4011 DeviceCapabilities
struct _IO_STACK_LOCATION::@3984::@4017 UsageNotification
BOOLEAN WriteCacheEnableOverride
Definition: imports.h:249
BOOLEAN MediaRemovable
Definition: imports.h:246
BOOLEAN DeviceHotplug
Definition: imports.h:248
#define IoAdjustPagingPathCount(_Count, _Increment)
#define IRP_MN_CANCEL_STOP_DEVICE
@ TargetDeviceRelation
Definition: iotypes.h:2156
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
#define IRP_MN_START_DEVICE
#define IRP_MN_DEVICE_USAGE_NOTIFICATION
#define IRP_MN_QUERY_ID
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define DO_POWER_PAGABLE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_QUERY_CAPABILITIES
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
#define DO_POWER_INRUSH
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
enum _DEVICE_USAGE_NOTIFICATION_TYPE DEVICE_USAGE_NOTIFICATION_TYPE
@ DeviceUsageTypeHibernation
Definition: iotypes.h:1171
@ DeviceUsageTypeBoot
Definition: iotypes.h:1173
@ DeviceUsageTypeDumpFile
Definition: iotypes.h:1172
@ DeviceUsageTypePaging
Definition: iotypes.h:1170
#define IRP_MN_QUERY_REMOVE_DEVICE
@ Executive
Definition: ketypes.h:415
#define ObReferenceObject
Definition: obfuncs.h:204
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by ClassInitializeDispatchTables().

◆ ClassFindModePage()

PVOID NTAPI ClassFindModePage ( _In_reads_bytes_(Length) PCHAR  ModeSenseBuffer,
_In_ ULONG  Length,
_In_ UCHAR  PageMode,
_In_ BOOLEAN  Use6Byte 
)

Definition at line 6798 of file class.c.

6804{
6805 PUCHAR limit;
6806 ULONG parameterHeaderLength;
6807 PVOID result = NULL;
6808
6809 limit = (PUCHAR)ModeSenseBuffer + Length;
6810 parameterHeaderLength = (Use6Byte) ? sizeof(MODE_PARAMETER_HEADER) : sizeof(MODE_PARAMETER_HEADER10);
6811
6812 if (Length >= parameterHeaderLength) {
6813
6814 PMODE_PARAMETER_HEADER10 modeParam10;
6815 ULONG blockDescriptorLength;
6816
6817 /*
6818 * Skip the mode select header and block descriptors.
6819 */
6820 if (Use6Byte){
6821 blockDescriptorLength = ((PMODE_PARAMETER_HEADER) ModeSenseBuffer)->BlockDescriptorLength;
6822 }
6823 else {
6824 modeParam10 = (PMODE_PARAMETER_HEADER10) ModeSenseBuffer;
6825 blockDescriptorLength = modeParam10->BlockDescriptorLength[1];
6826 }
6827
6828 ModeSenseBuffer += parameterHeaderLength + blockDescriptorLength;
6829
6830 //
6831 // ModeSenseBuffer now points at pages. Walk the pages looking for the
6832 // requested page until the limit is reached.
6833 //
6834
6835 while (ModeSenseBuffer +
6837
6838 if (((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageCode == PageMode) {
6839
6840 /*
6841 * found the mode page. make sure it's safe to touch it all
6842 * before returning the pointer to caller
6843 */
6844
6845 if (ModeSenseBuffer + ((PMODE_DISCONNECT_PAGE)ModeSenseBuffer)->PageLength > (PCHAR)limit) {
6846 /*
6847 * Return NULL since the page is not safe to access in full
6848 */
6849 result = NULL;
6850 }
6851 else {
6852 result = ModeSenseBuffer;
6853 }
6854 break;
6855 }
6856
6857 //
6858 // Advance to the next page which is 4-byte-aligned offset after this page.
6859 //
6860 ModeSenseBuffer +=
6861 ((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageLength +
6863
6864 }
6865 }
6866
6867 return result;
6868} // end ClassFindModePage()
_In_ size_t _In_ UCHAR _In_ BOOLEAN Use6Byte
Definition: cdrom.h:1328
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1326
_In_ ULONG _In_ UCHAR PageCode
Definition: cdrom.h:1317
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
struct _MODE_PARAMETER_HEADER10 * PMODE_PARAMETER_HEADER10
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
GLint limit
Definition: glext.h:10326
GLuint64EXT * result
Definition: glext.h:11304
#define PCHAR
Definition: match.c:90
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
struct _MODE_DISCONNECT_PAGE * PMODE_DISCONNECT_PAGE
UCHAR BlockDescriptorLength[2]
Definition: cdrw_hw.h:2516
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by ClasspWriteCacheProperty(), ClasspZeroQERR(), DetermineDriveType(), DiskGetCacheInformation(), DiskGetInfoExceptionInformation(), DiskGetModePage(), DiskInfoExceptionComplete(), DiskSetCacheInformation(), and FormatMedia().

◆ ClassForwardIrpSynchronous()

NTSTATUS NTAPI ClassForwardIrpSynchronous ( _In_ PCOMMON_DEVICE_EXTENSION  CommonExtension,
_In_ PIRP  Irp 
)

Definition at line 11343 of file class.c.

11347{
11349 return ClassSendIrpSynchronous(CommonExtension->LowerDeviceObject, Irp);
11350} // end ClassForwardIrpSynchronous()
NTSTATUS NTAPI ClassSendIrpSynchronous(_In_ PDEVICE_OBJECT TargetDeviceObject, _In_ PIRP Irp)
Definition: class.c:11373

Referenced by ClassDispatchPnp(), ClasspAccessAlignmentProperty(), ClasspDeviceSeekPenaltyProperty(), ClasspDeviceTrimProcess(), ClasspDeviceTrimProperty(), and ClasspPriorityHint().

◆ ClassGetPdoId()

NTSTATUS ClassGetPdoId ( IN PDEVICE_OBJECT  Pdo,
IN BUS_QUERY_ID_TYPE  IdType,
IN PUNICODE_STRING  IdString 
)

Definition at line 10151 of file class.c.

10156{
10157#ifdef _MSC_VER
10158#pragma warning(suppress:4054) // okay to type cast function pointer as data pointer for this use case
10159#endif
10161
10162 _Analysis_assume_(driverExtension != NULL);
10163
10164 ASSERT_PDO(Pdo);
10165 NT_ASSERT(driverExtension->InitData.ClassQueryId);
10166
10167 PAGED_CODE();
10168
10169 return driverExtension->InitData.ClassQueryId( Pdo, IdType, IdString);
10170} // end ClassGetPdoId()
_In_ BUS_QUERY_ID_TYPE IdType
Definition: classpnp.h:374
_In_ BUS_QUERY_ID_TYPE _In_ PUNICODE_STRING IdString
Definition: classpnp.h:375
#define ASSERT_PDO(x)
Definition: pci.h:38
PCLASS_QUERY_ID ClassQueryId
Definition: classpnp.h:542
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_ WDFDRIVER _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT Pdo
Definition: wdfminiport.h:72

Referenced by ClassDispatchPnp().

◆ ClassGetVpb()

PVPB NTAPI ClassGetVpb ( _In_ PDEVICE_OBJECT  DeviceObject)

Definition at line 11473 of file class.c.

11476{
11477#ifdef _MSC_VER
11478#pragma prefast(suppress:28175)
11479#endif
11480 return DeviceObject->Vpb;
11481} // end ClassGetVpb()

Referenced by ClassInterpretSenseInfo(), ClassMinimalPowerHandler(), and ClasspInterpretGesnData().

◆ ClassInternalIoControl()

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

Definition at line 9394 of file class.c.

9398{
9399 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
9400
9403
9404 ULONG isRemoved;
9405
9407
9409 _Analysis_assume_(isRemoved);
9410 if(isRemoved) {
9411
9412 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
9413
9415
9417
9419 }
9420
9421 //
9422 // Get a pointer to the SRB.
9423 //
9424
9425 srb = irpStack->Parameters.Scsi.Srb;
9426
9427 //
9428 // Set the parameters in the next stack location.
9429 //
9430
9431 if(commonExtension->IsFdo) {
9432 nextStack->Parameters.Scsi.Srb = srb;
9433 nextStack->MajorFunction = IRP_MJ_SCSI;
9434 nextStack->MinorFunction = IRP_MN_SCSI_CLASS;
9435
9436 } else {
9437
9439 }
9440
9442
9443 return IoCallDriver(commonExtension->LowerDeviceObject, Irp);
9444} // end ClassInternalIoControl()
#define IRP_MN_SCSI_CLASS

Referenced by ClassInitializeDispatchTables().

◆ ClassInterpretSenseInfo()

BOOLEAN NTAPI ClassInterpretSenseInfo ( _In_ PDEVICE_OBJECT  Fdo,
_In_ PSCSI_REQUEST_BLOCK  _Srb,
_In_ UCHAR  MajorFunctionCode,
_In_ ULONG  IoDeviceCode,
_In_ ULONG  RetryCount,
_Out_ NTSTATUS Status,
_Out_opt_ _Deref_out_range_(0, 100) ULONG RetryInterval 
)

Definition at line 4452 of file class.c.

4461{
4462 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
4463 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
4465 PVOID senseBuffer = SrbGetSenseInfoBuffer(Srb);
4466 BOOLEAN retry = TRUE;
4467 BOOLEAN logError = FALSE;
4468 BOOLEAN unhandledError = FALSE;
4469 BOOLEAN incrementErrorCount = FALSE;
4470
4471 //
4472 // NOTE: This flag must be used only for read/write requests that
4473 // fail with a unexpected retryable error.
4474 //
4475 BOOLEAN logRetryableError = TRUE;
4476
4477 //
4478 // Indicates if we should log this error in our internal log.
4479 //
4480 BOOLEAN logErrorInternal = TRUE;
4481
4482 ULONGLONG badSector = 0;
4483 ULONG uniqueId = 0;
4484
4485 NTSTATUS logStatus;
4486
4487 ULONGLONG readSector;
4488 ULONG index;
4489
4490 ULONG retryInterval = 0;
4491 KIRQL oldIrql;
4492 PCDB cdb = SrbGetCdb(Srb);
4493 UCHAR cdbOpcode = 0;
4494 ULONG cdbLength = SrbGetCdbLength(Srb);
4495
4496#if DBG
4497 BOOLEAN isReservationConflict = FALSE;
4498#endif
4499
4500 if (cdb) {
4501 cdbOpcode = cdb->CDB6GENERIC.OperationCode;
4502 }
4503
4505 logStatus = -1;
4506
4508
4509 //
4510 // Log anything remotely incorrect about paging i/o
4511 //
4512
4513 logError = TRUE;
4514 uniqueId = 301;
4515 logStatus = IO_WARNING_PAGING_FAILURE;
4516 }
4517
4518 //
4519 // Check that request sense buffer is valid.
4520 //
4521
4522 NT_ASSERT(fdoExtension->CommonExtension.IsFdo);
4523
4524
4525 //
4526 // must handle the SRB_STATUS_INTERNAL_ERROR case first,
4527 // as it has all the flags set.
4528 //
4529
4531
4532 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
4533 "ClassInterpretSenseInfo: Internal Error code is %x\n",
4535
4536 retry = FALSE;
4538
4540
4541 //
4542 // Need to reserve STATUS_DEVICE_BUSY to convey reservation conflict
4543 // for read/write requests as there are upper level components that
4544 // have built-in assumptions that STATUS_DEVICE_BUSY implies reservation
4545 // conflict.
4546 //
4548 retry = FALSE;
4549 logError = FALSE;
4550#if DBG
4551 isReservationConflict = TRUE;
4552#endif
4553
4554 } else {
4555
4557
4558 if ((Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) && senseBuffer) {
4559
4560 UCHAR errorCode = 0;
4561 UCHAR senseKey = 0;
4562 UCHAR addlSenseCode = 0;
4563 UCHAR addlSenseCodeQual = 0;
4564 BOOLEAN isIncorrectLengthValid = FALSE;
4565 BOOLEAN incorrectLength = FALSE;
4566 BOOLEAN isInformationValid = FALSE;
4568
4569
4570 validSense = ScsiGetSenseKeyAndCodes(senseBuffer,
4573 &senseKey,
4574 &addlSenseCode,
4575 &addlSenseCodeQual);
4576
4577 if (!validSense && !IsSenseDataFormatValueValid(senseBuffer)) {
4578
4580
4581 validSense = ScsiGetFixedSenseKeyAndCodes(senseBuffer,
4583 &senseKey,
4584 &addlSenseCode,
4585 &addlSenseCodeQual);
4586 }
4587
4588 if (!validSense) {
4589 goto __ClassInterpretSenseInfo_ProcessingInvalidSenseBuffer;
4590 }
4591
4592 errorCode = ScsiGetSenseErrorCode(senseBuffer);
4593
4594 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Error code is %x\n", errorCode));
4595 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Sense key is %x\n", senseKey));
4596 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Additional sense code is %x\n", addlSenseCode));
4597 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Additional sense code qualifier is %x\n", addlSenseCodeQual));
4598
4599 if (IsDescriptorSenseDataFormat(senseBuffer)) {
4600
4601 //
4602 // Sense data in Descriptor format
4603 //
4604
4605 PVOID startBuffer = NULL;
4606 UCHAR startBufferLength = 0;
4607
4608
4609 if (ScsiGetSenseDescriptor(senseBuffer,
4611 &startBuffer,
4612 &startBufferLength)) {
4613 UCHAR outType;
4615 UCHAR outBufferLength = 0;
4616 BOOLEAN foundBlockCommandType = FALSE;
4617 BOOLEAN foundInformationType = FALSE;
4619
4622
4623 while ((!foundBlockCommandType || !foundInformationType) &&
4624 ScsiGetNextSenseDescriptorByType(startBuffer,
4625 startBufferLength,
4626 typeList,
4627 ARRAYSIZE(typeList),
4628 &outType,
4629 &outBuffer,
4630 &outBufferLength)) {
4631
4633
4634 if (outBufferLength < descriptorLength) {
4635
4636 // Descriptor data is truncated.
4637 // Complete searching descriptors. Exit the loop now.
4638 break;
4639 }
4640
4642
4643 //
4644 // Block Command type
4645 //
4646
4647 if (!foundBlockCommandType) {
4648
4649 foundBlockCommandType = TRUE;
4650
4651 if (ScsiValidateBlockCommandSenseDescriptor(outBuffer, outBufferLength)) {
4652 incorrectLength = ((PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND)outBuffer)->IncorrectLength;
4653 isIncorrectLengthValid = TRUE;
4654 }
4655 } else {
4656
4657 //
4658 // A Block Command descriptor is already found earlier.
4659 //
4660 // T10 SPC specification only allows one descriptor for Block Command Descriptor type.
4661 // Assert here to catch devices that violate this rule. Ignore this descriptor.
4662 //
4664 }
4665
4666 } else if (outType == SCSI_SENSE_DESCRIPTOR_TYPE_INFORMATION) {
4667
4668 //
4669 // Information type
4670 //
4671
4672 if (!foundInformationType) {
4673
4674 foundInformationType = TRUE;
4675
4676 if (ScsiValidateInformationSenseDescriptor(outBuffer, outBufferLength)) {
4678 isInformationValid = TRUE;
4679 }
4680 } else {
4681
4682 //
4683 // A Information descriptor is already found earlier.
4684 //
4685 // T10 SPC specification only allows one descriptor for Information Descriptor type.
4686 // Assert here to catch devices that violate this rule. Ignore this descriptor.
4687 //
4689 }
4690
4691 } else {
4692
4693 //
4694 // ScsiGetNextDescriptorByType should only return a type that is specified by us.
4695 //
4697 break;
4698 }
4699
4700 //
4701 // Advance to start address of next descriptor
4702 //
4703 startBuffer = (PUCHAR)outBuffer + descriptorLength;
4704 startBufferLength = outBufferLength - descriptorLength;
4705 }
4706 }
4707 } else {
4708
4709 //
4710 // Sense data in Fixed format
4711 //
4712
4713 incorrectLength = ((PFIXED_SENSE_DATA)(senseBuffer))->IncorrectLength;
4715 isInformationValid = TRUE;
4716 isIncorrectLengthValid = TRUE;
4717 }
4718
4719
4720 switch (senseKey) {
4721
4722 case SCSI_SENSE_NO_SENSE: {
4723
4724 //
4725 // Check other indicators.
4726 //
4727
4728 if (isIncorrectLengthValid && incorrectLength) {
4729
4730 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4731 "Incorrect length detected.\n"));
4733 retry = FALSE;
4734
4735 } else {
4736
4737 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4738 "No specific sense key\n"));
4740 retry = TRUE;
4741 }
4742
4743 break;
4744 } // end SCSI_SENSE_NO_SENSE
4745
4747
4748 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4749 "Recovered error\n"));
4751 retry = FALSE;
4752 logError = TRUE;
4753 uniqueId = 258;
4754
4755 switch(addlSenseCode) {
4758 logStatus = IO_ERR_SEEK_ERROR;
4759 break;
4760 }
4761
4764 logStatus = IO_RECOVERED_VIA_ECC;
4765 break;
4766 }
4767
4769
4770 UCHAR wmiEventData[sizeof(ULONG)+sizeof(UCHAR)] = {0};
4771
4772 *((PULONG)wmiEventData) = sizeof(UCHAR);
4773 wmiEventData[sizeof(ULONG)] = addlSenseCodeQual;
4774
4775 //
4776 // Don't log another eventlog if we have already logged once
4777 // NOTE: this should have been interlocked, but the structure
4778 // was publicly defined to use a BOOLEAN (char). Since
4779 // media only reports these errors once per X minutes,
4780 // the potential race condition is nearly non-existant.
4781 // the worst case is duplicate log entries, so ignore.
4782 //
4783
4784 logError = FALSE;
4785 if (fdoExtension->FailurePredicted == 0) {
4786 logError = TRUE;
4787 }
4788 fdoExtension->FailureReason = addlSenseCodeQual;
4789 logStatus = IO_WRN_FAILURE_PREDICTED;
4790
4791 ClassNotifyFailurePredicted(fdoExtension,
4792 (PUCHAR)wmiEventData,
4793 sizeof(wmiEventData),
4794 FALSE, // do not log error
4795 4, // unique error value
4798 SrbGetLun(Srb));
4799
4800 fdoExtension->FailurePredicted = TRUE;
4801 break;
4802 }
4803
4804 default: {
4805 logStatus = IO_ERR_CONTROLLER_ERROR;
4806 break;
4807 }
4808
4809 } // end switch(addlSenseCode)
4810
4811 if (isIncorrectLengthValid && incorrectLength) {
4812
4813 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4814 "Incorrect length detected.\n"));
4816 }
4817
4818
4819 break;
4820 } // end SCSI_SENSE_RECOVERED_ERROR
4821
4822 case SCSI_SENSE_NOT_READY: {
4823
4824 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4825 "Device not ready\n"));
4827
4828 switch (addlSenseCode) {
4829
4831
4832 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4833 "Lun not ready\n"));
4834
4835 retryInterval = NOT_READY_RETRY_INTERVAL;
4836
4837 switch (addlSenseCodeQual) {
4838
4840 DEVICE_EVENT_BECOMING_READY notReady = {0};
4841
4842 logRetryableError = FALSE;
4843 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4844 "In process of becoming ready\n"));
4845
4846 notReady.Version = 1;
4847 notReady.Reason = 1;
4848 notReady.Estimated100msToReady = retryInterval * 10;
4849 ClassSendNotification(fdoExtension,
4850 &GUID_IO_DEVICE_BECOMING_READY,
4852 &notReady);
4853 break;
4854 }
4855
4857 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4858 "Manual intervention required\n"));
4860 retry = FALSE;
4861 break;
4862 }
4863
4865 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4866 "Format in progress\n"));
4867 retry = FALSE;
4868 break;
4869 }
4870
4872 DEVICE_EVENT_BECOMING_READY notReady = {0};
4873
4874 logRetryableError = FALSE;
4875 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4876 "Operation In Progress\n"));
4877
4878 notReady.Version = 1;
4879 notReady.Reason = 2;
4880 notReady.Estimated100msToReady = retryInterval * 10;
4881 ClassSendNotification(fdoExtension,
4882 &GUID_IO_DEVICE_BECOMING_READY,
4884 &notReady);
4885
4886 break;
4887 }
4888
4890 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4891 "Long write in progress\n"));
4892 //
4893 // This has been seen as a transcient failure on some cdrom
4894 // drives. The cdrom class driver is going to override this
4895 // setting but has no way of dropping the retry interval
4896 //
4897 retry = FALSE;
4898 retryInterval = 1;
4899 break;
4900 }
4901
4903 logRetryableError = FALSE;
4904 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4905 "The device (%p) is busy allocating space.\n",
4906 Fdo));
4907
4908 //
4909 // This indicates that a thinly-provisioned device has hit
4910 // a temporary resource exhaustion and is busy allocating
4911 // more space. We need to retry the request as the device
4912 // will eventually be able to service it.
4913 //
4915 retry = TRUE;
4916
4917 break;
4918 }
4919
4921
4922 if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
4924
4925 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
4926 "ClassInterpretSenseInfo: "
4927 "not ready, cause unknown\n"));
4928 /*
4929 Many non-WHQL certified drives (mostly CD-RW) return
4930 this when they have no media instead of the obvious
4931 choice of:
4932
4933 SCSI_SENSE_NOT_READY/SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
4934
4935 These drives should not pass WHQL certification due
4936 to this discrepency.
4937
4938 */
4939 retry = FALSE;
4940 break;
4941
4942 } else {
4943
4944 //
4945 // Treat this as init command required and fall through.
4946 //
4947 }
4948 }
4949
4951 default: {
4952 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4953 "Initializing command required\n"));
4954 retryInterval = 0; // go back to default
4955 logRetryableError = FALSE;
4956
4957 //
4958 // This sense code/additional sense code
4959 // combination may indicate that the device
4960 // needs to be started. Send an start unit if this
4961 // is a disk device.
4962 //
4963 if (TEST_FLAG(fdoExtension->DeviceFlags, DEV_SAFE_START_UNIT) &&
4965
4967 }
4968 break;
4969 }
4970
4971 } // end switch (addlSenseCodeQual)
4972 break;
4973 }
4974
4976 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4977 "No Media in device.\n"));
4979 retry = FALSE;
4980
4981 //
4982 // signal MCN that there isn't any media in the device
4983 //
4984 if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
4985 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4986 "No Media in a non-removable device %p\n",
4987 Fdo));
4988 }
4989
4990 if (addlSenseCodeQual == 0xCC){
4991 /*
4992 * The IMAPI filter returns this ASCQ value when it is burning CD-R media.
4993 * We want to indicate that the media is not present to most applications;
4994 * but RSM has to know that the media is still in the drive (i.e. the drive is not free).
4995 */
4996 ClassSetMediaChangeState(fdoExtension, MediaUnavailable, FALSE);
4997 }
4998 else {
4999 ClassSetMediaChangeState(fdoExtension, MediaNotPresent, FALSE);
5000 }
5001
5002 break;
5003 }
5004 } // end switch (addlSenseCode)
5005
5006 break;
5007 } // end SCSI_SENSE_NOT_READY
5008
5010 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5011 "Medium Error (bad block)\n"));
5013
5014 retry = FALSE;
5015 logError = TRUE;
5016 uniqueId = 256;
5017 logStatus = IO_ERR_BAD_BLOCK;
5018
5019 //
5020 // Check if this error is due to unknown format
5021 //
5022 if (addlSenseCode == SCSI_ADSENSE_INVALID_MEDIA) {
5023
5024 switch (addlSenseCodeQual) {
5025
5027
5029
5030 //
5031 // Log error only if this is a paging request
5032 //
5034 logError = FALSE;
5035 }
5036 break;
5037 }
5038
5040
5042 logError = FALSE;
5043 break;
5044
5045 }
5046 default: {
5047 break;
5048 }
5049 } // end switch addlSenseCodeQual
5050
5051 } // end SCSI_ADSENSE_INVALID_MEDIA
5052