ReactOS  0.4.14-dev-384-g5b37caa
class.c File Reference
#include "classp.h"
#include <stddef.h>
#include <initguid.h>
#include <mountdev.h>
Include dependency graph for class.c:

Go to the source code of this file.

Macros

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

Functions

NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
ULONG NTAPI ClassInitialize (IN PVOID Argument1, IN PVOID Argument2, IN PCLASS_INIT_DATA InitializationData)
 
ULONG NTAPI ClassInitializeEx (IN PDRIVER_OBJECT DriverObject, IN LPGUID Guid, IN PVOID Data)
 
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 NTAPI ClassPnpStartDevice (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ClassReadWrite (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ClassReadDriveCapacity (IN PDEVICE_OBJECT Fdo)
 
VOID NTAPI ClassSendStartUnit (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI ClassAsynchronousCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
VOID NTAPI ServiceTransferRequest (PDEVICE_OBJECT Fdo, PIRP Irp)
 
NTSTATUS NTAPI ClassIoComplete (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ClassSendSrbSynchronous (PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, 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 OPTIONAL ULONG *RetryInterval)
 
ULONG NTAPI ClassModeSense (IN PDEVICE_OBJECT Fdo, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
 
PVOID NTAPI ClassFindModePage (IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
 
NTSTATUS NTAPI ClassSendSrbAsynchronous (PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
 
NTSTATUS NTAPI ClassDeviceControlDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI ClassDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI ClassShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ClassCreateDeviceObject (IN PDRIVER_OBJECT DriverObject, IN PCCHAR ObjectNameBuffer, IN PDEVICE_OBJECT LowerDevice, IN BOOLEAN IsFdo, IN OUT PDEVICE_OBJECT *DeviceObject)
 
NTSTATUS NTAPI ClassClaimDevice (IN PDEVICE_OBJECT LowerDeviceObject, IN BOOLEAN Release)
 
NTSTATUS NTAPI ClassInternalIoControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
ULONG NTAPI ClassQueryTimeOutRegistryValue (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ClassCheckVerifyComplete (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ClassGetDescriptor (IN PDEVICE_OBJECT DeviceObject, IN PSTORAGE_PROPERTY_ID PropertyId, OUT PSTORAGE_DESCRIPTOR_HEADER *Descriptor)
 
NTSTATUS NTAPI ClassSignalCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ClassPnpQueryFdoRelations (IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
 
VOID NTAPI ClassMarkChildrenMissing (IN PFUNCTIONAL_DEVICE_EXTENSION Fdo)
 
BOOLEAN NTAPI ClassMarkChildMissing (IN PPHYSICAL_DEVICE_EXTENSION Child, IN BOOLEAN AcquireChildLock)
 
NTSTATUS NTAPI ClassRetrieveDeviceRelations (IN PDEVICE_OBJECT Fdo, IN DEVICE_RELATION_TYPE RelationType, OUT PDEVICE_RELATIONS *DeviceRelations)
 
NTSTATUS NTAPI ClassGetPdoId (IN PDEVICE_OBJECT Pdo, IN BUS_QUERY_ID_TYPE IdType, IN PUNICODE_STRING IdString)
 
NTSTATUS NTAPI ClassQueryPnpCapabilities (IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_CAPABILITIES Capabilities)
 
VOID NTAPI ClassInvalidateBusRelations (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI ClassRemoveDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR RemoveType)
 
PCLASS_DRIVER_EXTENSION NTAPI ClassGetDriverExtension (IN PDRIVER_OBJECT DriverObject)
 
VOID NTAPI ClasspStartIo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI ClassUpdateInformationInRegistry (IN PDEVICE_OBJECT Fdo, IN PCHAR DeviceName, IN ULONG DeviceNumber, IN PINQUIRYDATA InquiryData, IN ULONG InquiryDataLength)
 
NTSTATUS NTAPI ClasspSendSynchronousCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
VOID NTAPI ClasspRegisterMountedDeviceInterface (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI ClassSendDeviceIoControlSynchronous (IN ULONG IoControlCode, IN PDEVICE_OBJECT TargetDeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG InputBufferLength, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, OUT PIO_STATUS_BLOCK IoStatus)
 
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 NTAPI ClasspAllocateReleaseRequest (IN PDEVICE_OBJECT Fdo)
 
VOID NTAPI ClasspFreeReleaseRequest (IN PDEVICE_OBJECT Fdo)
 
VOID NTAPI ClassReleaseQueue (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI ClasspAllocateReleaseQueueIrp (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClasspReleaseQueue (IN PDEVICE_OBJECT Fdo, IN PIRP ReleaseQueueIrp OPTIONAL)
 
NTSTATUS NTAPI ClassReleaseQueueCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
VOID NTAPI ClassAcquireChildLock (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClassReleaseChildLock (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClassAddChild (IN PFUNCTIONAL_DEVICE_EXTENSION Parent, IN PPHYSICAL_DEVICE_EXTENSION Child, IN BOOLEAN AcquireLock)
 
PPHYSICAL_DEVICE_EXTENSION NTAPI ClassRemoveChild (IN PFUNCTIONAL_DEVICE_EXTENSION Parent, IN PPHYSICAL_DEVICE_EXTENSION Child, IN BOOLEAN AcquireLock)
 
VOID NTAPI ClasspRetryRequestDpc (IN PKDPC Dpc, IN PVOID Context, IN PVOID Arg1, IN PVOID Arg2)
 
VOID NTAPI ClassRetryRequest (IN PDEVICE_OBJECT SelfDeviceObject, IN PIRP Irp, IN LARGE_INTEGER TimeDelta100ns)
 
VOID NTAPI ClasspRetryDpcTimer (IN PCLASS_PRIVATE_FDO_DATA FdoData)
 
NTSTATUS NTAPI ClasspInitializeHotplugInfo (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClasspScanForClassHacks (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG_PTR Data)
 
VOID NTAPI ClasspScanForSpecialInRegistry (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 

Variables

ULONG ClassPnpAllowUnload = TRUE
 

Macro Definition Documentation

◆ FirstDriveLetter

#define FirstDriveLetter   'C'

Definition at line 65 of file class.c.

◆ LastDriveLetter

#define LastDriveLetter   'Z'

Definition at line 66 of file class.c.

Function Documentation

◆ ClassAcquireChildLock()

VOID NTAPI ClassAcquireChildLock ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 8483 of file class.c.

8486 {
8487  PAGED_CODE();
8488 
8489  if(FdoExtension->ChildLockOwner != KeGetCurrentThread()) {
8490  KeWaitForSingleObject(&FdoExtension->ChildLock,
8492  FALSE, NULL);
8493 
8494  ASSERT(FdoExtension->ChildLockOwner == NULL);
8495  ASSERT(FdoExtension->ChildLockAcquisitionCount == 0);
8496 
8497  FdoExtension->ChildLockOwner = KeGetCurrentThread();
8498  } else {
8499  ASSERT(FdoExtension->ChildLockAcquisitionCount != 0);
8500  }
8501 
8502  FdoExtension->ChildLockAcquisitionCount++;
8503  return;
8504 }
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define KeGetCurrentThread
Definition: hal.h:44

Referenced by ClassAddChild(), ClassMarkChildrenMissing(), ClassRemoveChild(), ClassRemoveDevice(), ClassRetrieveDeviceRelations(), DiskDeviceControl(), DiskUpdatePartitions(), and DiskUpdateRemovablePartitions().

◆ ClassAddChild()

VOID NTAPI ClassAddChild ( IN PFUNCTIONAL_DEVICE_EXTENSION  Parent,
IN PPHYSICAL_DEVICE_EXTENSION  Child,
IN BOOLEAN  AcquireLock 
)

Definition at line 8566 of file class.c.

8571 {
8572  if(AcquireLock) {
8574  }
8575 
8576  #if DBG
8577  //
8578  // Make sure this child's not already in the list.
8579  //
8580  {
8581  PPHYSICAL_DEVICE_EXTENSION testChild;
8582 
8583  for (testChild = Parent->CommonExtension.ChildList;
8584  testChild != NULL;
8585  testChild = testChild->CommonExtension.ChildList) {
8586 
8587  ASSERT(testChild != Child);
8588  }
8589  }
8590  #endif
8591 
8592  Child->CommonExtension.ChildList = Parent->CommonExtension.ChildList;
8593  Parent->CommonExtension.ChildList = Child;
8594 
8595  if(AcquireLock) {
8597  }
8598  return;
8599 } // end ClassAddChild()
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:628
VOID NTAPI ClassAcquireChildLock(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: class.c:8483
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:728
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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 ACPI_HANDLE Child
Definition: acpixf.h:728
VOID NTAPI ClassReleaseChildLock(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: class.c:8526

Referenced by ClassCreateDeviceObject().

◆ ClassAddDevice()

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

Definition at line 491 of file class.c.

495 {
496  PCLASS_DRIVER_EXTENSION driverExtension =
499 
501 
502  PAGED_CODE();
503 
504  DbgPrint("got a device\n");
505  status = driverExtension->InitData.ClassAddDevice(DriverObject,
507  return status;
508 } // end ClassAddDevice()
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:91
#define DbgPrint
Definition: loader.c:25
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
#define PAGED_CODE()
Definition: video.h:57
PCLASS_ADD_DEVICE ClassAddDevice
Definition: classpnp.h:523
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
CLASS_INIT_DATA InitData
Definition: classpnp.h:556
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by ClassInitialize().

◆ ClassAsynchronousCompletion()

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

Definition at line 2168 of file class.c.

2173 {
2175  PSCSI_REQUEST_BLOCK srb;
2176 
2177  if(DeviceObject == NULL) {
2178 
2179  DeviceObject = context->DeviceObject;
2180  }
2181 
2182  srb = &context->Srb;
2183 
2184  //
2185  // If this is an execute srb, then check the return status and make sure.
2186  // the queue is not frozen.
2187  //
2188 
2189  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
2190 
2191  //
2192  // Check for a frozen queue.
2193  //
2194 
2195  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2196 
2197  //
2198  // Unfreeze the queue getting the device object from the context.
2199  //
2200 
2201  ClassReleaseQueue(context->DeviceObject);
2202  }
2203  }
2204 
2205  { // free port-allocated sense buffer if we can detect
2206 
2208 
2210  if (PORT_ALLOCATED_SENSE(fdoExtension, srb)) {
2211  FREE_PORT_ALLOCATED_SENSE_BUFFER(fdoExtension, srb);
2212  }
2213 
2214  } else {
2215 
2217 
2218  }
2219  }
2220 
2221 
2222  //
2223  // Free the context and the Irp.
2224  //
2225 
2226  if (Irp->MdlAddress != NULL) {
2227  MmUnlockPages(Irp->MdlAddress);
2228  IoFreeMdl(Irp->MdlAddress);
2229 
2230  Irp->MdlAddress = NULL;
2231  }
2232 
2234 
2236  IoFreeIrp(Irp);
2237 
2238  //
2239  // Indicate the I/O system should stop processing the Irp completion.
2240  //
2241 
2243 
2244 } // end ClassAsynchronousCompletion()
VOID NTAPI ClassReleaseQueue(IN PDEVICE_OBJECT Fdo)
Definition: class.c:8160
ULONG SrbFlags
Definition: srb.h:252
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:6587
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:398
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
UCHAR SrbStatus
Definition: srb.h:243
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
static __inline BOOLEAN PORT_ALLOCATED_SENSE(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: classpnp.h:1244
UCHAR Function
Definition: srb.h:242
static __inline VOID FREE_PORT_ALLOCATED_SENSE_BUFFER(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: classpnp.h:1255
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
struct tagContext Context
Definition: acpixf.h:1030
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212

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

◆ ClassCheckVerifyComplete()

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

Definition at line 6298 of file class.c.

6303 {
6305  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
6306 
6307  PIRP originalIrp;
6308 
6309  ASSERT_FDO(Fdo);
6310 
6311  originalIrp = irpStack->Parameters.Others.Argument1;
6312 
6313  //
6314  // Copy the media change count and status
6315  //
6316 
6317  *((PULONG) (originalIrp->AssociatedIrp.SystemBuffer)) =
6318  fdoExtension->MediaChangeCount;
6319 
6320  DebugPrint((2, "ClassCheckVerifyComplete - Media change count for"
6321  "device %d is %lx - saved as %lx\n",
6322  fdoExtension->DeviceNumber,
6323  fdoExtension->MediaChangeCount,
6324  *((PULONG) originalIrp->AssociatedIrp.SystemBuffer)));
6325 
6326  originalIrp->IoStatus.Status = Irp->IoStatus.Status;
6327  originalIrp->IoStatus.Information = sizeof(ULONG);
6328 
6329  ClassReleaseRemoveLock(Fdo, originalIrp);
6330  ClassCompleteRequest(Fdo, originalIrp, IO_DISK_INCREMENT);
6331 
6332  IoFreeIrp(Irp);
6333 
6335 
6336 } // end ClassCheckVerifyComplete()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define ASSERT_FDO(x)
Definition: pci.h:35
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
unsigned int ULONG
Definition: retypes.h:1
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212

Referenced by ClassDeviceControl().

◆ ClassClaimDevice()

NTSTATUS NTAPI ClassClaimDevice ( IN PDEVICE_OBJECT  LowerDeviceObject,
IN BOOLEAN  Release 
)

Definition at line 5985 of file class.c.

5989 {
5990  IO_STATUS_BLOCK ioStatus;
5991  PIRP irp;
5992  PIO_STACK_LOCATION irpStack;
5993  KEVENT event;
5994  NTSTATUS status;
5995  SCSI_REQUEST_BLOCK srb;
5996 
5997  PAGED_CODE();
5998 
5999  //
6000  // Clear the SRB fields.
6001  //
6002 
6003  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
6004 
6005  //
6006  // Write length to SRB.
6007  //
6008 
6009  srb.Length = sizeof(SCSI_REQUEST_BLOCK);
6010 
6013 
6014  //
6015  // Set the event object to the unsignaled state.
6016  // It will be used to signal request completion
6017  //
6018 
6020 
6021  //
6022  // Build synchronous request with no transfer.
6023  //
6024 
6027  NULL,
6028  0,
6029  NULL,
6030  0,
6031  TRUE,
6032  &event,
6033  &ioStatus);
6034 
6035  if (irp == NULL) {
6036  DebugPrint((1, "ClassClaimDevice: Can't allocate Irp\n"));
6038  }
6039 
6040  irpStack = IoGetNextIrpStackLocation(irp);
6041 
6042  //
6043  // Save SRB address in next stack for port driver.
6044  //
6045 
6046  irpStack->Parameters.Scsi.Srb = &srb;
6047 
6048  //
6049  // Set up IRP Address.
6050  //
6051 
6052  srb.OriginalRequest = irp;
6053 
6054  //
6055  // Call the port driver with the request and wait for it to complete.
6056  //
6057 
6059  if (status == STATUS_PENDING) {
6060 
6062  status = ioStatus.Status;
6063  }
6064 
6065  //
6066  // If this is a release request, then just decrement the reference count
6067  // and return. The status does not matter.
6068  //
6069 
6070  if (Release) {
6071 
6072  // ObDereferenceObject(LowerDeviceObject);
6073  return STATUS_SUCCESS;
6074  }
6075 
6076  if (!NT_SUCCESS(status)) {
6077  return status;
6078  }
6079 
6080  ASSERT(srb.DataBuffer != NULL);
6082 
6083  return status;
6084 } // end ClassClaimDevice()
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
_In_ BOOLEAN Release
Definition: classpnp.h:929
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:398
PVOID DataBuffer
Definition: srb.h:255
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_FUNCTION_CLAIM_DEVICE
Definition: srb.h:308
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
#define SRB_FUNCTION_RELEASE_DEVICE
Definition: srb.h:313
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_z_ PCCHAR _In_ PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:789
struct _cl_event * event
Definition: glext.h:7739
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by CdRomCreateDeviceObject(), CreateFlopDeviceObject(), and DiskCreateFdo().

◆ ClassCreateDeviceObject()

NTSTATUS NTAPI ClassCreateDeviceObject ( IN PDRIVER_OBJECT  DriverObject,
IN PCCHAR  ObjectNameBuffer,
IN PDEVICE_OBJECT  LowerDevice,
IN BOOLEAN  IsFdo,
IN OUT PDEVICE_OBJECT DeviceObject 
)

Definition at line 5687 of file class.c.

5694 {
5695  BOOLEAN isPartitionable;
5696  STRING ntNameString;
5697  UNICODE_STRING ntUnicodeString;
5698  NTSTATUS status;
5699  PDEVICE_OBJECT deviceObject = NULL;
5700 
5701  ULONG characteristics;
5702 
5704  driverExtension = IoGetDriverObjectExtension(DriverObject,
5706 
5707  PCLASS_DEV_INFO devInfo;
5708 
5709  PAGED_CODE();
5710 
5711  *DeviceObject = NULL;
5712  RtlInitUnicodeString(&ntUnicodeString, NULL);
5713 
5714  DebugPrint((2, "ClassCreateFdo: Create device object\n"));
5715 
5716  ASSERT(LowerDevice);
5717 
5718  //
5719  // Make sure that if we're making PDO's we have an enumeration routine
5720  //
5721 
5722  isPartitionable = (driverExtension->InitData.ClassEnumerateDevice != NULL);
5723 
5724  ASSERT(IsFdo || isPartitionable);
5725 
5726  //
5727  // Grab the correct dev-info structure out of the init data
5728  //
5729 
5730  if(IsFdo) {
5731  devInfo = &(driverExtension->InitData.FdoData);
5732  } else {
5733  devInfo = &(driverExtension->InitData.PdoData);
5734  }
5735 
5736  characteristics = devInfo->DeviceCharacteristics;
5737 
5739  DebugPrint((2, "ClassCreateFdo: Name is %s\n", ObjectNameBuffer));
5740 
5741  RtlInitString(&ntNameString, ObjectNameBuffer);
5742 
5743  status = RtlAnsiStringToUnicodeString(&ntUnicodeString, &ntNameString, TRUE);
5744 
5745  if (!NT_SUCCESS(status)) {
5746 
5747  DebugPrint((1,
5748  "ClassCreateFdo: Cannot convert string %s\n",
5749  ObjectNameBuffer));
5750 
5751  ntUnicodeString.Buffer = NULL;
5752  return status;
5753  }
5754  } else {
5755  DebugPrint((2, "ClassCreateFdo: Object will be unnamed\n"));
5756 
5757  if(IsFdo == FALSE) {
5758 
5759  //
5760  // PDO's have to have some sort of name.
5761  //
5762 
5763  SET_FLAG(characteristics, FILE_AUTOGENERATED_DEVICE_NAME);
5764  }
5765 
5766  RtlInitUnicodeString(&ntUnicodeString, NULL);
5767  }
5768 
5770  devInfo->DeviceExtensionSize,
5771  &ntUnicodeString,
5772  devInfo->DeviceType,
5773  devInfo->DeviceCharacteristics,
5774  FALSE,
5775  &deviceObject);
5776 
5777  if (!NT_SUCCESS(status)) {
5778 
5779  DebugPrint((1, "ClassCreateFdo: Can not create device object %lx\n",
5780  status));
5781  ASSERT(deviceObject == NULL);
5782 
5783  //
5784  // buffer is not used any longer here.
5785  //
5786 
5787  if (ntUnicodeString.Buffer != NULL) {
5788  DebugPrint((1, "ClassCreateFdo: Freeing unicode name buffer\n"));
5789  ExFreePool(ntUnicodeString.Buffer);
5790  RtlInitUnicodeString(&ntUnicodeString, NULL);
5791  }
5792 
5793  } else {
5794 
5795  PCOMMON_DEVICE_EXTENSION commonExtension = deviceObject->DeviceExtension;
5796 
5797  RtlZeroMemory(
5798  deviceObject->DeviceExtension,
5799  devInfo->DeviceExtensionSize);
5800 
5801  //
5802  // Setup version code
5803  //
5804 
5805  commonExtension->Version = 0x03;
5806 
5807  //
5808  // Setup the remove lock and event
5809  //
5810 
5811  commonExtension->IsRemoved = NO_REMOVE;
5812  commonExtension->RemoveLock = 0;
5813  KeInitializeEvent(&commonExtension->RemoveEvent,
5815  FALSE);
5816 
5817  #if DBG
5818  KeInitializeSpinLock(&commonExtension->RemoveTrackingSpinlock);
5819  commonExtension->RemoveTrackingList = NULL;
5820  #else
5821  commonExtension->RemoveTrackingSpinlock = (ULONG_PTR) -1;
5822  commonExtension->RemoveTrackingList = (PVOID) -1;
5823  #endif
5824 
5825  //
5826  // Acquire the lock once. This reference will be released when the
5827  // remove IRP has been received.
5828  //
5829 
5830  ClassAcquireRemoveLock(deviceObject, (PIRP) deviceObject);
5831 
5832  //
5833  // Store a pointer to the driver extension so we don't have to do
5834  // lookups to get it.
5835  //
5836 
5837  commonExtension->DriverExtension = driverExtension;
5838 
5839  //
5840  // Fill in entry points
5841  //
5842 
5843  commonExtension->DevInfo = devInfo;
5844 
5845  //
5846  // Initialize some of the common values in the structure
5847  //
5848 
5849  commonExtension->DeviceObject = deviceObject;
5850 
5851  commonExtension->LowerDeviceObject = NULL;
5852 
5853  if(IsFdo) {
5854 
5855  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PVOID) commonExtension;
5856 
5857  commonExtension->PartitionZeroExtension = deviceObject->DeviceExtension;
5858 
5859  //
5860  // Set the initial device object flags.
5861  //
5862 
5863  SET_FLAG(deviceObject->Flags, DO_POWER_PAGABLE);
5864 
5865  //
5866  // Clear the PDO list
5867  //
5868 
5869  commonExtension->ChildList = NULL;
5870 
5871  commonExtension->DriverData =
5872  ((PFUNCTIONAL_DEVICE_EXTENSION) deviceObject->DeviceExtension + 1);
5873 
5874  if(isPartitionable) {
5875 
5876  commonExtension->PartitionNumber = 0;
5877  } else {
5878  commonExtension->PartitionNumber = (ULONG) (-1L);
5879  }
5880 
5881  fdoExtension->DevicePowerState = PowerDeviceD0;
5882 
5885  TRUE);
5886 
5887  KeInitializeEvent(&fdoExtension->ChildLock,
5889  TRUE);
5890 
5891  status = ClasspAllocateReleaseRequest(deviceObject);
5892 
5893  if(!NT_SUCCESS(status)) {
5894  IoDeleteDevice(deviceObject);
5895  *DeviceObject = NULL;
5896 
5897  if (ntUnicodeString.Buffer != NULL) {
5898  DebugPrint((1, "ClassCreateFdo: Freeing unicode name buffer\n"));
5899  ExFreePool(ntUnicodeString.Buffer);
5900  RtlInitUnicodeString(&ntUnicodeString, NULL);
5901  }
5902 
5903  return status;
5904  }
5905 
5906  } else {
5907 
5908  PPHYSICAL_DEVICE_EXTENSION pdoExtension =
5909  deviceObject->DeviceExtension;
5910 
5911  PFUNCTIONAL_DEVICE_EXTENSION p0Extension =
5912  LowerDevice->DeviceExtension;
5913 
5914  SET_FLAG(deviceObject->Flags, DO_POWER_PAGABLE);
5915 
5916  commonExtension->PartitionZeroExtension = p0Extension;
5917 
5918  //
5919  // Stick this onto the PDO list
5920  //
5921 
5922  ClassAddChild(p0Extension, pdoExtension, TRUE);
5923 
5924  commonExtension->DriverData = (PVOID) (pdoExtension + 1);
5925 
5926  //
5927  // Get the top of stack for the lower device - this allows
5928  // filters to get stuck in between the partitions and the
5929  // physical disk.
5930  //
5931 
5932  commonExtension->LowerDeviceObject =
5933  IoGetAttachedDeviceReference(LowerDevice);
5934 
5935  //
5936  // Pnp will keep a reference to the lower device object long
5937  // after this partition has been deleted. Dereference now so
5938  // we don't have to deal with it later.
5939  //
5940 
5941  ObDereferenceObject(commonExtension->LowerDeviceObject);
5942  }
5943 
5945 
5946  commonExtension->IsFdo = IsFdo;
5947 
5948  commonExtension->DeviceName = ntUnicodeString;
5949 
5950  commonExtension->PreviousState = 0xff;
5951 
5952  InitializeDictionary(&(commonExtension->FileObjectDictionary));
5953 
5954  commonExtension->CurrentState = IRP_MN_STOP_DEVICE;
5955  }
5956 
5957  *DeviceObject = deviceObject;
5958 
5959  return status;
5960 } // end ClassCreateDeviceObject()
#define DO_POWER_PAGABLE
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:91
#define TRUE
Definition: types.h:120
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
CLASS_DEV_INFO FdoData
Definition: classpnp.h:521
_In_z_ PCCHAR _In_ PDEVICE_OBJECT _In_ BOOLEAN IsFdo
Definition: classpnp.h:789
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:575
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
ULONG DeviceCharacteristics
Definition: classpnp.h:504
#define PAGED_CODE()
Definition: video.h:57
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
_In_z_ PCCHAR ObjectNameBuffer
Definition: classpnp.h:789
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
void * PVOID
Definition: retypes.h:9
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
UNICODE_STRING DeviceName
Definition: classpnp.h:591
PDEVICE_OBJECT DeviceObject
Definition: pci.h:42
#define IRP_MN_STOP_DEVICE
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARGUMENT_PRESENT(ArgumentPointer)
struct _PHYSICAL_DEVICE_EXTENSION * ChildList
Definition: classpnp.h:592
VOID NTAPI ClassAddChild(IN PFUNCTIONAL_DEVICE_EXTENSION Parent, IN PPHYSICAL_DEVICE_EXTENSION Child, IN BOOLEAN AcquireLock)
Definition: class.c:8566
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
std::wstring STRING
Definition: fontsub.cpp:33
#define NO_REMOVE
Definition: classpnp.h:93
static const WCHAR L[]
Definition: oid.c:1250
PCLASS_ENUM_DEVICE ClassEnumerateDevice
Definition: classpnp.h:524
PCLASS_DRIVER_EXTENSION DriverExtension
Definition: classpnp.h:576
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI InitializeDictionary(IN PDICTIONARY Dictionary)
Definition: dictlib.c:39
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PCLASS_DEV_INFO DevInfo
Definition: classpnp.h:596
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
CLASS_DEV_INFO PdoData
Definition: classpnp.h:522
DEVICE_TYPE DeviceType
Definition: classpnp.h:502
CLASS_INIT_DATA InitData
Definition: classpnp.h:556
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
DICTIONARY FileObjectDictionary
Definition: classpnp.h:607
KSPIN_LOCK RemoveTrackingSpinlock
Definition: classpnp.h:579
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ClasspAllocateReleaseRequest(IN PDEVICE_OBJECT Fdo)
Definition: class.c:8062
ULONG DeviceExtensionSize
Definition: classpnp.h:501
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
DEVICE_POWER_STATE DevicePowerState
Definition: classpnp.h:700
Definition: ps.c:97

Referenced by CdRomCreateDeviceObject(), CreateFlopDeviceObject(), DiskCreateFdo(), and DiskCreatePdo().

◆ ClassDeviceControl()

NTSTATUS NTAPI ClassDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 4590 of file class.c.

4594 {
4596 
4598  PIO_STACK_LOCATION nextStack = NULL;
4599 
4600  ULONG controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
4601 
4602  PSCSI_REQUEST_BLOCK srb = NULL;
4603  PCDB cdb = NULL;
4604 
4605  NTSTATUS status;
4606  ULONG modifiedIoControlCode;
4607 
4608  //
4609  // If this is a pass through I/O control, set the minor function code
4610  // and device address and pass it to the port driver.
4611  //
4612 
4613  if ((controlCode == IOCTL_SCSI_PASS_THROUGH) ||
4614  (controlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT)) {
4615 
4616  //PSCSI_PASS_THROUGH scsiPass;
4617 
4618  //
4619  // Validate the user buffer.
4620  //
4621  #if defined (_WIN64)
4622 
4623  if (IoIs32bitProcess(Irp)) {
4624 
4625  if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH32)){
4626 
4627  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
4628 
4631 
4633  goto SetStatusAndReturn;
4634  }
4635  }
4636  else
4637  #endif
4638  {
4639  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
4640  sizeof(SCSI_PASS_THROUGH)) {
4641 
4642  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
4643 
4646 
4648  goto SetStatusAndReturn;
4649  }
4650  }
4651 
4653 
4654  nextStack = IoGetNextIrpStackLocation(Irp);
4655  nextStack->MinorFunction = 1;
4656 
4658 
4659  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
4660  goto SetStatusAndReturn;
4661  }
4662 
4663  Irp->IoStatus.Information = 0;
4664 
4665  switch (controlCode) {
4666 
4668 
4669  PMOUNTDEV_UNIQUE_ID uniqueId;
4670 
4671  if (!commonExtension->MountedDeviceInterfaceName.Buffer) {
4673  break;
4674  }
4675 
4676  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4677  sizeof(MOUNTDEV_UNIQUE_ID)) {
4678 
4680  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
4681  break;
4682  }
4683 
4684  uniqueId = Irp->AssociatedIrp.SystemBuffer;
4685  uniqueId->UniqueIdLength =
4686  commonExtension->MountedDeviceInterfaceName.Length;
4687 
4688  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4689  sizeof(USHORT) + uniqueId->UniqueIdLength) {
4690 
4692  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
4693  break;
4694  }
4695 
4696  RtlCopyMemory(uniqueId->UniqueId,
4697  commonExtension->MountedDeviceInterfaceName.Buffer,
4698  uniqueId->UniqueIdLength);
4699 
4701  Irp->IoStatus.Information = sizeof(USHORT) +
4702  uniqueId->UniqueIdLength;
4703  break;
4704  }
4705 
4707 
4709 
4710  ASSERT(commonExtension->DeviceName.Buffer);
4711 
4712  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4713  sizeof(MOUNTDEV_NAME)) {
4714 
4716  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
4717  break;
4718  }
4719 
4720  name = Irp->AssociatedIrp.SystemBuffer;
4721  name->NameLength = commonExtension->DeviceName.Length;
4722 
4723  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4724  sizeof(USHORT) + name->NameLength) {
4725 
4727  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
4728  break;
4729  }
4730 
4731  RtlCopyMemory(name->Name, commonExtension->DeviceName.Buffer,
4732  name->NameLength);
4733 
4735  Irp->IoStatus.Information = sizeof(USHORT) + name->NameLength;
4736  break;
4737  }
4738 
4740 
4741  PMOUNTDEV_SUGGESTED_LINK_NAME suggestedName;
4742  WCHAR driveLetterNameBuffer[10];
4743  RTL_QUERY_REGISTRY_TABLE queryTable[2];
4744  PWSTR valueName;
4745  UNICODE_STRING driveLetterName;
4746 
4747  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4748  sizeof(MOUNTDEV_SUGGESTED_LINK_NAME)) {
4749 
4751  Irp->IoStatus.Information = sizeof(MOUNTDEV_SUGGESTED_LINK_NAME);
4752  break;
4753  }
4754 
4755  valueName = ExAllocatePoolWithTag(
4756  PagedPool,
4757  commonExtension->DeviceName.Length + sizeof(WCHAR),
4758  '8CcS');
4759 
4760  if (!valueName) {
4762  break;
4763  }
4764 
4765  RtlCopyMemory(valueName, commonExtension->DeviceName.Buffer,
4766  commonExtension->DeviceName.Length);
4767  valueName[commonExtension->DeviceName.Length/sizeof(WCHAR)] = 0;
4768 
4769  driveLetterName.Buffer = driveLetterNameBuffer;
4770  driveLetterName.MaximumLength = 20;
4771  driveLetterName.Length = 0;
4772 
4773  RtlZeroMemory(queryTable, 2*sizeof(RTL_QUERY_REGISTRY_TABLE));
4774  queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED |
4776  queryTable[0].Name = valueName;
4777  queryTable[0].EntryContext = &driveLetterName;
4778 
4780  L"\\Registry\\Machine\\System\\DISK",
4781  queryTable, NULL, NULL);
4782 
4783  if (!NT_SUCCESS(status)) {
4784  ExFreePool(valueName);
4785  break;
4786  }
4787 
4788  if (driveLetterName.Length == 4 &&
4789  driveLetterName.Buffer[0] == '%' &&
4790  driveLetterName.Buffer[1] == ':') {
4791 
4792  driveLetterName.Buffer[0] = 0xFF;
4793 
4794  } else if (driveLetterName.Length != 4 ||
4795  driveLetterName.Buffer[0] < FirstDriveLetter ||
4796  driveLetterName.Buffer[0] > LastDriveLetter ||
4797  driveLetterName.Buffer[1] != ':') {
4798 
4800  ExFreePool(valueName);
4801  break;
4802  }
4803 
4804  suggestedName = Irp->AssociatedIrp.SystemBuffer;
4805  suggestedName->UseOnlyIfThereAreNoOtherLinks = TRUE;
4806  suggestedName->NameLength = 28;
4807 
4808  Irp->IoStatus.Information =
4810 
4811  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4812  Irp->IoStatus.Information) {
4813 
4814  Irp->IoStatus.Information =
4817  ExFreePool(valueName);
4818  break;
4819  }
4820 
4822  L"\\Registry\\Machine\\System\\DISK",
4823  valueName);
4824 
4825  ExFreePool(valueName);
4826 
4827  RtlCopyMemory(suggestedName->Name, L"\\DosDevices\\", 24);
4828  suggestedName->Name[12] = driveLetterName.Buffer[0];
4829  suggestedName->Name[13] = ':';
4830 
4831  //
4832  // NT_SUCCESS(status) based on RtlQueryRegistryValues
4833  //
4835 
4836  break;
4837  }
4838 
4839  default:
4841  break;
4842  }
4843 
4844  if (status != STATUS_PENDING) {
4846  Irp->IoStatus.Status = status;
4848  return status;
4849  }
4850 
4851  if (commonExtension->IsFdo){
4852 
4853  PULONG_PTR function;
4854 
4856  sizeof(SCSI_REQUEST_BLOCK) +
4857  (sizeof(ULONG_PTR) * 2),
4858  '9CcS');
4859 
4860  if (srb == NULL) {
4861 
4862  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
4866  goto SetStatusAndReturn;
4867  }
4868 
4869  RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
4870 
4871  cdb = (PCDB)srb->Cdb;
4872 
4873  //
4874  // Save the function code and the device object in the memory after
4875  // the SRB.
4876  //
4877 
4878  function = (PULONG_PTR) ((PSCSI_REQUEST_BLOCK) (srb + 1));
4879  *function = (ULONG_PTR) DeviceObject;
4880  function++;
4881  *function = (ULONG_PTR) controlCode;
4882 
4883  } else {
4884  srb = NULL;
4885  }
4886 
4887  //
4888  // Change the device type to storage for the switch statement, but only
4889  // if from a legacy device type
4890  //
4891 
4892  if (((controlCode & 0xffff0000) == (IOCTL_DISK_BASE << 16)) ||
4893  ((controlCode & 0xffff0000) == (IOCTL_TAPE_BASE << 16)) ||
4894  ((controlCode & 0xffff0000) == (IOCTL_CDROM_BASE << 16))
4895  ) {
4896 
4897  modifiedIoControlCode = (controlCode & ~0xffff0000);
4898  modifiedIoControlCode |= (IOCTL_STORAGE_BASE << 16);
4899 
4900  } else {
4901 
4902  modifiedIoControlCode = controlCode;
4903 
4904  }
4905 
4906  DBGTRACE(ClassDebugTrace, ("> ioctl %xh (%s)", modifiedIoControlCode, DBGGETIOCTLSTR(modifiedIoControlCode)));
4907 
4908  switch (modifiedIoControlCode) {
4909 
4911 
4912  if (srb) {
4913  ExFreePool(srb);
4914  srb = NULL;
4915  }
4916 
4917  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4918  sizeof(STORAGE_HOTPLUG_INFO)) {
4919 
4920  //
4921  // Indicate unsuccessful status and no data transferred.
4922  //
4923 
4924  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
4925  Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
4926 
4930 
4931  } else if(!commonExtension->IsFdo) {
4932 
4933  //
4934  // Just forward this down and return
4935  //
4936 
4938 
4940  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
4941 
4942  } else {
4943 
4944  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
4946 
4947  fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
4948  info = Irp->AssociatedIrp.SystemBuffer;
4949 
4950  *info = fdoExtension->PrivateFdoData->HotplugInfo;
4951  Irp->IoStatus.Status = STATUS_SUCCESS;
4952  Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
4956 
4957  }
4958  break;
4959  }
4960 
4962 
4963  if (srb)
4964  {
4965  ExFreePool(srb);
4966  srb = NULL;
4967  }
4968 
4969  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
4970  sizeof(STORAGE_HOTPLUG_INFO)) {
4971 
4972  //
4973  // Indicate unsuccessful status and no data transferred.
4974  //
4975 
4976  Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
4977 
4981  goto SetStatusAndReturn;
4982 
4983  }
4984 
4985  if(!commonExtension->IsFdo) {
4986 
4987  //
4988  // Just forward this down and return
4989  //
4990 
4992 
4994  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
4995 
4996  } else {
4997 
4998  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
4999  PSTORAGE_HOTPLUG_INFO info = Irp->AssociatedIrp.SystemBuffer;
5000 
5002 
5003  if (info->Size != fdoExtension->PrivateFdoData->HotplugInfo.Size)
5004  {
5006  }
5007 
5008  if (info->MediaRemovable != fdoExtension->PrivateFdoData->HotplugInfo.MediaRemovable)
5009  {
5011  }
5012 
5013  if (info->MediaHotplug != fdoExtension->PrivateFdoData->HotplugInfo.MediaHotplug)
5014  {
5016  }
5017 
5018  if (info->WriteCacheEnableOverride != fdoExtension->PrivateFdoData->HotplugInfo.WriteCacheEnableOverride)
5019  {
5021  }
5022 
5023  if (NT_SUCCESS(status))
5024  {
5025  fdoExtension->PrivateFdoData->HotplugInfo.DeviceHotplug = info->DeviceHotplug;
5026 
5027  //
5028  // Store the user-defined override in the registry
5029  //
5030 
5031  ClassSetDeviceParameter(fdoExtension,
5035  }
5036 
5037  Irp->IoStatus.Status = status;
5038 
5041  }
5042 
5043  break;
5044  }
5045 
5048 
5049  PIRP irp2 = NULL;
5050  PIO_STACK_LOCATION newStack;
5051 
5052  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
5053 
5054  DebugPrint((1,"DeviceIoControl: Check verify\n"));
5055 
5056  //
5057  // If a buffer for a media change count was provided, make sure it's
5058  // big enough to hold the result
5059  //
5060 
5061  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
5062 
5063  //
5064  // If the buffer is too small to hold the media change count
5065  // then return an error to the caller
5066  //
5067 
5068  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
5069  sizeof(ULONG)) {
5070 
5071  DebugPrint((3,"DeviceIoControl: media count "
5072  "buffer too small\n"));
5073 
5074  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
5075  Irp->IoStatus.Information = sizeof(ULONG);
5076 
5077  if(srb != NULL) {
5078  ExFreePool(srb);
5079  }
5080 
5083 
5085  goto SetStatusAndReturn;
5086 
5087  }
5088  }
5089 
5090  if(!commonExtension->IsFdo) {
5091 
5092  //
5093  // If this is a PDO then we should just forward the request down
5094  //
5095  ASSERT(!srb);
5096 
5098 
5100 
5101  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
5102 
5103  goto SetStatusAndReturn;
5104 
5105  } else {
5106 
5107  fdoExtension = DeviceObject->DeviceExtension;
5108 
5109  }
5110 
5111  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
5112 
5113  //
5114  // The caller has provided a valid buffer. Allocate an additional
5115  // irp and stick the CheckVerify completion routine on it. We will
5116  // then send this down to the port driver instead of the irp the
5117  // caller sent in
5118  //
5119 
5120  DebugPrint((2,"DeviceIoControl: Check verify wants "
5121  "media count\n"));
5122 
5123  //
5124  // Allocate a new irp to send the TestUnitReady to the port driver
5125  //
5126 
5127  irp2 = IoAllocateIrp((CCHAR) (DeviceObject->StackSize + 3), FALSE);
5128 
5129  if(irp2 == NULL) {
5130  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
5131  Irp->IoStatus.Information = 0;
5132  ASSERT(srb);
5133  ExFreePool(srb);
5137  goto SetStatusAndReturn;
5138 
5139  break;
5140  }
5141 
5142  //
5143  // Make sure to acquire the lock for the new irp.
5144  //
5145 
5147 
5148  irp2->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
5150 
5151  //
5152  // Set the top stack location and shove the master Irp into the
5153  // top location
5154  //
5155 
5156  newStack = IoGetCurrentIrpStackLocation(irp2);
5157  newStack->Parameters.Others.Argument1 = Irp;
5158  newStack->DeviceObject = DeviceObject;
5159 
5160  //
5161  // Stick the check verify completion routine onto the stack
5162  // and prepare the irp for the port driver
5163  //
5164 
5167  NULL,
5168  TRUE,
5169  TRUE,
5170  TRUE);
5171 
5173  newStack = IoGetCurrentIrpStackLocation(irp2);
5174  newStack->DeviceObject = DeviceObject;
5175  newStack->MajorFunction = irpStack->MajorFunction;
5176  newStack->MinorFunction = irpStack->MinorFunction;
5177 
5178  //
5179  // Mark the master irp as pending - whether the lower level
5180  // driver completes it immediately or not this should allow it
5181  // to go all the way back up.
5182  //
5183 
5185 
5186  Irp = irp2;
5187 
5188  }
5189 
5190  //
5191  // Test Unit Ready
5192  //
5193 
5194  srb->CdbLength = 6;
5195  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
5196 
5197  //
5198  // Set timeout value.
5199  //
5200 
5201  srb->TimeOutValue = fdoExtension->TimeOutValue;
5202 
5203  //
5204  // If this was a CV2 then mark the request as low-priority so we don't
5205  // spin up the drive just to satisfy it.
5206  //
5207 
5208  if(controlCode == IOCTL_STORAGE_CHECK_VERIFY2) {
5210  }
5211 
5212  //
5213  // Since this routine will always hand the request to the
5214  // port driver if there isn't a data transfer to be done
5215  // we don't have to worry about completing the request here
5216  // on an error
5217  //
5218 
5219  //
5220  // This routine uses a completion routine so we don't want to release
5221  // the remove lock until then.
5222  //
5223 
5225  srb,
5226  Irp,
5227  NULL,
5228  0,
5229  FALSE);
5230 
5231  break;
5232  }
5233 
5236 
5237  PPREVENT_MEDIA_REMOVAL mediaRemoval = Irp->AssociatedIrp.SystemBuffer;
5238 
5239  DebugPrint((3, "DiskIoControl: ejection control\n"));
5240 
5241  if(srb) {
5242  ExFreePool(srb);
5243  }
5244 
5245  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
5246  sizeof(PREVENT_MEDIA_REMOVAL)) {
5247 
5248  //
5249  // Indicate unsuccessful status and no data transferred.
5250  //
5251 
5252  Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
5253 
5257  goto SetStatusAndReturn;
5258  }
5259 
5260  if(!commonExtension->IsFdo) {
5261 
5262  //
5263  // Just forward this down and return
5264  //
5265 
5267 
5269  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
5270  }
5271  else {
5272 
5273  // i don't believe this assertion is valid. this is a request
5274  // from user-mode, so they could request this for any device
5275  // they want? also, we handle it properly.
5276  // ASSERT(TEST_FLAG(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA));
5278  DeviceObject,
5279  Irp,
5280  ((modifiedIoControlCode ==
5282  SimpleMediaLock),
5283  mediaRemoval->PreventMediaRemoval);
5284 
5285  Irp->IoStatus.Status = status;
5288  }
5289 
5290  break;
5291  }
5292 
5294 
5295  DebugPrint((3, "DiskIoControl: MCN control\n"));
5296 
5297  if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
5298  sizeof(PREVENT_MEDIA_REMOVAL)) {
5299 
5300  //
5301  // Indicate unsuccessful status and no data transferred.
5302  //
5303 
5304  Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
5305  Irp->IoStatus.Information = 0;
5306 
5307  if(srb) {
5308  ExFreePool(srb);
5309  }
5310 
5314  goto SetStatusAndReturn;
5315  }
5316 
5317  if(!commonExtension->IsFdo) {
5318 
5319  //
5320  // Just forward this down and return
5321  //
5322 
5323  if(srb) {
5324  ExFreePool(srb);
5325  }
5326 
5328 
5330  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
5331 
5332  } else {
5333 
5334  //
5335  // Call to the FDO - handle the ejection control.
5336  //
5337 
5339  Irp,
5340  srb);
5341  }
5342  goto SetStatusAndReturn;
5343  }
5344 
5345  case IOCTL_STORAGE_RESERVE:
5346  case IOCTL_STORAGE_RELEASE: {
5347 
5348  //
5349  // Reserve logical unit.
5350  //
5351 
5352  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
5353 
5354  if(!commonExtension->IsFdo) {
5355 
5357 
5359  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
5360  goto SetStatusAndReturn;
5361  } else {
5362  fdoExtension = DeviceObject->DeviceExtension;
5363  }
5364 
5365  srb->CdbLength = 6;
5366 
5367  if(modifiedIoControlCode == IOCTL_STORAGE_RESERVE) {
5368  cdb->CDB6GENERIC.OperationCode = SCSIOP_RESERVE_UNIT;
5369  } else {
5370  cdb->CDB6GENERIC.OperationCode = SCSIOP_RELEASE_UNIT;
5371  }
5372 
5373  //
5374  // Set timeout value.
5375  //
5376 
5377  srb->TimeOutValue = fdoExtension->TimeOutValue;
5378 
5380  srb,
5381  Irp,
5382  NULL,
5383  0,
5384  FALSE);
5385 
5386  break;
5387  }
5388 
5392 
5393  //
5394  // Eject media.
5395  //
5396 
5397  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
5398 
5399  if(!commonExtension->IsFdo) {
5400 
5402 
5404 
5405  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
5406  goto SetStatusAndReturn;
5407  } else {
5408  fdoExtension = DeviceObject->DeviceExtension;
5409  }
5410 
5411  if(commonExtension->PagingPathCount != 0) {
5412 
5413  DebugPrint((1, "ClassDeviceControl: call to eject paging device - "
5414  "failure\n"));
5415 
5417  Irp->IoStatus.Status = status;
5418 
5419  Irp->IoStatus.Information = 0;
5420 
5421  if(srb) {
5422  ExFreePool(srb);
5423  }
5424 
5427  goto SetStatusAndReturn;
5428  }
5429 
5430  //
5431  // Synchronize with ejection control and ejection cleanup code as
5432  // well as other eject/load requests.
5433  //
5434 
5437  UserRequest,
5438  UserMode,
5439  FALSE,
5440  NULL);
5441 
5442  if(fdoExtension->ProtectedLockCount != 0) {
5443 
5444  DebugPrint((1, "ClassDeviceControl: call to eject protected locked "
5445  "device - failure\n"));
5446 
5448  Irp->IoStatus.Status = status;
5449  Irp->IoStatus.Information = 0;
5450 
5451  if(srb) {
5452  ExFreePool(srb);
5453  }
5454 
5457 
5458  KeSetEvent(&fdoExtension->EjectSynchronizationEvent,
5460  FALSE);
5462 
5463  goto SetStatusAndReturn;
5464  }
5465 
5466  srb->CdbLength = 6;
5467 
5468  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
5469  cdb->START_STOP.LoadEject = 1;
5470 
5471  if(modifiedIoControlCode == IOCTL_STORAGE_EJECT_MEDIA) {
5472  cdb->START_STOP.Start = 0;
5473  } else {
5474  cdb->START_STOP.Start = 1;
5475  }
5476 
5477  //
5478  // Set timeout value.
5479  //
5480 
5481  srb->TimeOutValue = fdoExtension->TimeOutValue;
5483  srb,
5484  Irp,
5485  NULL,
5486  0,
5487  FALSE);
5488 
5491 
5492  break;
5493  }
5494 
5496 
5497  if(srb) {
5498  ExFreePool(srb);
5499  }
5500 
5501  if(commonExtension->IsFdo) {
5502 
5504  ((PFUNCTIONAL_DEVICE_EXTENSION) commonExtension)->LowerPdo,
5505  BusRelations);
5506 
5508  Irp->IoStatus.Status = status;
5509 
5512  }
5513  else {
5514 
5516 
5518  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
5519  }
5520  break;
5521  }
5522 
5524 
5525  if(srb) {
5526  ExFreePool(srb);
5527  }
5528 
5529  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength >=
5530  sizeof(STORAGE_DEVICE_NUMBER)) {
5531 
5532  PSTORAGE_DEVICE_NUMBER deviceNumber =
5533  Irp->AssociatedIrp.SystemBuffer;
5534  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
5535  commonExtension->PartitionZeroExtension;
5536 
5537  deviceNumber->DeviceType = fdoExtension->CommonExtension.DeviceObject->DeviceType;
5538  deviceNumber->DeviceNumber = fdoExtension->DeviceNumber;
5539  deviceNumber->PartitionNumber = commonExtension->PartitionNumber;
5540 
5542  Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
5543 
5544  } else {
5546  Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
5547  }
5548 
5549  Irp->IoStatus.Status = status;
5552 
5553  break;
5554  }
5555 
5556  default: {
5557 
5558  DebugPrint((4, "IoDeviceControl: Unsupported device IOCTL %x for %p\n",
5559  controlCode, DeviceObject));
5560 
5561  //
5562  // Pass the device control to the next driver.
5563  //
5564 
5565  if(srb) {
5566  ExFreePool(srb);
5567  }
5568 
5569  //
5570  // Copy the Irp stack parameters to the next stack location.
5571  //
5572 
5574 
5576  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
5577  break;
5578  }
5579 
5580  } // end switch( ...
5581 
5582 SetStatusAndReturn:
5583 
5584  DBGTRACE(ClassDebugTrace, ("< ioctl %xh (%s): status %xh.", modifiedIoControlCode, DBGGETIOCTLSTR(modifiedIoControlCode), status));
5585 
5586  return status;
5587 } // end ClassDeviceControl()
DEVICE_TYPE DeviceType
Definition: ntddstor.h:232
#define IOCTL_STORAGE_MCN_CONTROL
Definition: ntddstor.h:117
#define SCSIOP_RESERVE_UNIT
Definition: cdrw_hw.h:892
#define IOCTL_DISK_BASE
Definition: ntdddisk.h:44
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CLASSP_REG_REMOVAL_POLICY_VALUE_NAME
Definition: classp.h:47
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
ULONG SrbFlags
Definition: srb.h:252
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
NTSTATUS NTAPI ClasspMcnControl(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb)
Definition: autorun.c:2890
#define IOCTL_STORAGE_SET_HOTPLUG_INFO
Definition: ntddstor.h:146
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
UCHAR Cdb[16]
Definition: srb.h:271
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:93
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define SCSIOP_RELEASE_UNIT
Definition: cdrw_hw.h:893
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:54
NTSTATUS NTAPI ClasspEjectionControl(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN MEDIA_LOCK_TYPE LockType, IN BOOLEAN Lock)
Definition: create.c:449
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:575
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
#define IOCTL_TAPE_BASE
Definition: ntddtape.h:35
USHORT UniqueIdLength
Definition: imports.h:138
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define DBGGETIOCTLSTR(_ioctl)
Definition: debug.h:139
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
UCHAR CdbLength
Definition: srb.h:250
ULONG TimeOutValue
Definition: srb.h:254
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
struct _test_info info[]
Definition: SetCursorPos.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IOCTL_STORAGE_FIND_NEW_DEVICES
Definition: ntddstor.h:111
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
PDEVICE_OBJECT DeviceObject
Definition: kstypes.h:153
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:463
#define SRB_CLASS_FLAGS_LOW_PRIORITY
Definition: classpnp.h:19
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
#define IOCTL_STORAGE_EJECTION_CONTROL
Definition: ntddstor.h:114
#define IOCTL_STORAGE_RELEASE
Definition: ntddstor.h:108
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:96
struct _MOUNTDEV_NAME MOUNTDEV_NAME
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:132
struct _CDB::_START_STOP START_STOP
#define IOCTL_STORAGE_RESERVE
Definition: ntddstor.h:105
UNICODE_STRING DeviceName
Definition: classpnp.h:591
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:465
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
const char name[9]
Definition: class.c:929
#define STATUS_NOT_FOUND
Definition: shellext.h:72
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
char CCHAR
Definition: typedefs.h:50
NTSTATUS NTAPI ClassSetDeviceParameter(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PWSTR SubkeyName OPTIONAL, IN PWSTR ParameterName, IN ULONG ParameterValue)
Definition: utils.c:136
UNICODE_STRING MountedDeviceInterfaceName
Definition: classpnp.h:604
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
#define IOCTL_STORAGE_LOAD_MEDIA2
Definition: ntddk_ex.h:210
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define CLASSP_REG_SUBKEY_NAME
Definition: classp.h:41
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:251
static const WCHAR L[]
Definition: oid.c:1250
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define IOCTL_STORAGE_CHECK_VERIFY2
Definition: ntddk_ex.h:212
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define STATUS_FILES_OPEN
Definition: ntstatus.h:485
NTSTATUS NTAPI ClassCheckVerifyComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: class.c:6298
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
#define FirstDriveLetter
Definition: class.c:65
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5111
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
struct _MOUNTDEV_SUGGESTED_LINK_NAME MOUNTDEV_SUGGESTED_LINK_NAME
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
unsigned short USHORT
Definition: pedump.c:61
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:99
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
Definition: name.c:36
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
static SERVICE_STATUS status
Definition: service.c:31
#define IOCTL_STORAGE_BASE
Definition: ntddstor.h:85
NTSTATUS NTAPI ClassSendSrbAsynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:4321
UCHAR UniqueId[1]
Definition: imports.h:139
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct _STORAGE_HOTPLUG_INFO STORAGE_HOTPLUG_INFO
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
#define LastDriveLetter
Definition: class.c:66
Definition: ps.c:97

◆ ClassDeviceControlDispatch()

NTSTATUS NTAPI ClassDeviceControlDispatch ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 4532 of file class.c.

4536 {
4537 
4539  ULONG isRemoved;
4540 
4541  isRemoved = ClassAcquireRemoveLock(DeviceObject, Irp);
4542 
4543  if(isRemoved) {
4544 
4546 
4547  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
4550  }
4551 
4552  //
4553  // Call the class specific driver DeviceControl routine.
4554  // If it doesn't handle it, it will call back into ClassDeviceControl.
4555  //
4556 
4557  ASSERT(commonExtension->DevInfo->ClassDeviceControl);
4558 
4559  return commonExtension->DevInfo->ClassDeviceControl(DeviceObject,Irp);
4560 } // end ClassDeviceControlDispatch()
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
_In_ PIRP Irp
Definition: csq.h:116
PCLASS_DEVICE_CONTROL ClassDeviceControl
Definition: classpnp.h:507
PVOID DeviceExtension
Definition: env_spec_w32.h:418
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
PCLASS_DEV_INFO DevInfo
Definition: classpnp.h:596
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212

Referenced by ClassInitialize().

◆ ClassDispatchPnp()

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

Definition at line 532 of file class.c.

536 {
538  BOOLEAN isFdo = commonExtension->IsFdo;
539 
540  PCLASS_DRIVER_EXTENSION driverExtension;
541  PCLASS_INIT_DATA initData;
542  PCLASS_DEV_INFO devInfo;
543 
545 
546  NTSTATUS status = Irp->IoStatus.Status;
547  BOOLEAN completeRequest = TRUE;
548  BOOLEAN lockReleased = FALSE;
549 
550  PAGED_CODE();
551 
552  //
553  // Extract all the useful information out of the driver object
554  // extension
555  //
556 
557  driverExtension = IoGetDriverObjectExtension(DeviceObject->DriverObject,
559  if (driverExtension){
560 
561  initData = &(driverExtension->InitData);
562 
563  if(isFdo) {
564  devInfo = &(initData->FdoData);
565  } else {
566  devInfo = &(initData->PdoData);
567  }
568 
570 
571  DebugPrint((2, "ClassDispatchPnp (%p,%p): minor code %#x for %s %p\n",
572  DeviceObject, Irp,
573  irpStack->MinorFunction,
574  isFdo ? "fdo" : "pdo",
575  DeviceObject));
576  DebugPrint((2, "ClassDispatchPnp (%p,%p): previous %#x, current %#x\n",
577  DeviceObject, Irp,
578  commonExtension->PreviousState,
579  commonExtension->CurrentState));
580 
581  switch(irpStack->MinorFunction) {
582 
583  case IRP_MN_START_DEVICE: {
584 
585  //
586  // if this is sent to the FDO we should forward it down the
587  // attachment chain before we start the FDO.
588  //
589 
590  if (isFdo) {
591  status = ClassForwardIrpSynchronous(commonExtension, Irp);
592  }
593  else {
595  }
596 
597  if (NT_SUCCESS(status)){
598  status = Irp->IoStatus.Status = ClassPnpStartDevice(DeviceObject);
599  }
600 
601  break;
602  }
603 
604 
606 
608  irpStack->Parameters.QueryDeviceRelations.Type;
609 
610  PDEVICE_RELATIONS deviceRelations = NULL;
611 
612  if(!isFdo) {
613 
614  if(type == TargetDeviceRelation) {
615 
616  //
617  // Device relations has one entry built in to it's size.
618  //
619 
621 
622  deviceRelations = ExAllocatePoolWithTag(PagedPool,
623  sizeof(DEVICE_RELATIONS),
624  '2CcS');
625 
626  if(deviceRelations != NULL) {
627 
628  RtlZeroMemory(deviceRelations,
629  sizeof(DEVICE_RELATIONS));
630 
631  Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
632 
633  deviceRelations->Count = 1;
634  deviceRelations->Objects[0] = DeviceObject;
635  ObReferenceObject(deviceRelations->Objects[0]);
636 
638  }
639 
640  } else {
641  //
642  // PDO's just complete enumeration requests without altering
643  // the status.
644  //
645 
646  status = Irp->IoStatus.Status;
647  }
648 
649  break;
650 
651  } else if (type == BusRelations) {
652 
653  ASSERT(commonExtension->IsInitialized);
654 
655  //
656  // Make sure we support enumeration
657  //
658 
659  if(initData->ClassEnumerateDevice == NULL) {
660 
661  //
662  // Just send the request down to the lower driver. Perhaps
663  // It can enumerate children.
664  //
665 
666  } else {
667 
668  //
669  // Re-enumerate the device
670  //
671 
673 
674  if(!NT_SUCCESS(status)) {
675  completeRequest = TRUE;
676  break;
677  }
678  }
679  }
680 
683  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
684  completeRequest = FALSE;
685 
686  break;
687  }
688 
689  case IRP_MN_QUERY_ID: {
690 
691  BUS_QUERY_ID_TYPE idType = irpStack->Parameters.QueryId.IdType;
692  UNICODE_STRING unicodeString;
693 
694  if(isFdo) {
695 
696  //
697  // FDO's should just forward the query down to the lower
698  // device objects
699  //
700 
703 
704  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
705  completeRequest = FALSE;
706  break;
707  }
708 
709  //
710  // PDO's need to give an answer - this is easy for now
711  //
712 
713  RtlInitUnicodeString(&unicodeString, NULL);
714 
716  idType,
717  &unicodeString);
718 
720  //
721  // The driver doesn't implement this ID (whatever it is).
722  // Use the status out of the IRP so that we don't mangle a
723  // response from someone else.
724  //
725 
726  status = Irp->IoStatus.Status;
727  } else if(NT_SUCCESS(status)) {
728  Irp->IoStatus.Information = (ULONG_PTR) unicodeString.Buffer;
729  } else {
730  Irp->IoStatus.Information = (ULONG_PTR) NULL;
731  }
732 
733  break;
734  }
735 
738 
739  DebugPrint((2, "ClassDispatchPnp (%p,%p): Processing QUERY_%s irp\n",
740  DeviceObject, Irp,
741  ((irpStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) ?
742  "STOP" : "REMOVE")));
743 
744  //
745  // If this device is in use for some reason (paging, etc...)
746  // then we need to fail the request.
747  //
748 
749  if(commonExtension->PagingPathCount != 0) {
750 
751  DebugPrint((1, "ClassDispatchPnp (%p,%p): device is in paging "
752  "path and cannot be removed\n",
753  DeviceObject, Irp));
755  break;
756  }
757 
758  //
759  // Check with the class driver to see if the query operation
760  // can succeed.
761  //
762 
763  if(irpStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) {
765  irpStack->MinorFunction);
766  } else {
768  irpStack->MinorFunction);
769  }
770 
771  if(NT_SUCCESS(status)) {
772 
773  //
774  // ASSERT that we never get two queries in a row, as
775  // this will severely mess up the state machine
776  //
777  ASSERT(commonExtension->CurrentState != irpStack->MinorFunction);
778  commonExtension->PreviousState = commonExtension->CurrentState;
779  commonExtension->CurrentState = irpStack->MinorFunction;
780 
781  if(isFdo) {
782  DebugPrint((2, "ClassDispatchPnp (%p,%p): Forwarding QUERY_"
783  "%s irp\n", DeviceObject, Irp,
784  ((irpStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) ?
785  "STOP" : "REMOVE")));
786  status = ClassForwardIrpSynchronous(commonExtension, Irp);
787  }
788  }
789  DebugPrint((2, "ClassDispatchPnp (%p,%p): Final status == %x\n",
790  DeviceObject, Irp, status));
791 
792  break;
793  }
794 
797 
798  //
799  // Check with the class driver to see if the query or cancel
800  // operation can succeed.
801  //
802 
803  if(irpStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) {
805  irpStack->MinorFunction);
806  NT_ASSERTMSGW(L"ClassDispatchPnp !! CANCEL_STOP_DEVICE should "
807  L"never be failed\n", NT_SUCCESS(status));
808  } else {
810  irpStack->MinorFunction);
811  NT_ASSERTMSGW(L"ClassDispatchPnp !! CANCEL_REMOVE_DEVICE should "
812  L"never be failed\n", NT_SUCCESS(status));
813  }
814 
815  Irp->IoStatus.Status = status;
816 
817  //
818  // We got a CANCEL - roll back to the previous state only
819  // if the current state is the respective QUERY state.
820  //
821 
822  if(((irpStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) &&
823  (commonExtension->CurrentState == IRP_MN_QUERY_STOP_DEVICE)
824  ) ||
825  ((irpStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE) &&
826  (commonExtension->CurrentState == IRP_MN_QUERY_REMOVE_DEVICE)
827  )
828  ) {
829 
830  commonExtension->CurrentState =
831  commonExtension->PreviousState;
832  commonExtension->PreviousState = 0xff;
833 
834  }
835 
836  if(isFdo) {
839  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
840  completeRequest = FALSE;
841  } else {
843  }
844 
845  break;
846  }
847 
848  case IRP_MN_STOP_DEVICE: {
849 
850  //
851  // These all mean nothing to the class driver currently. The
852  // port driver will handle all queueing when necessary.
853  //
854 
855  DebugPrint((2, "ClassDispatchPnp (%p,%p): got stop request for %s\n",
856  DeviceObject, Irp,
857  (isFdo ? "fdo" : "pdo")
858  ));
859 
860  ASSERT(commonExtension->PagingPathCount == 0);
861 
862  //
863  // ISSUE-2000/02/03-peterwie
864  // if we stop the timer here then it means no class driver can
865  // do i/o in its ClassStopDevice routine. This is because the
866  // retry (among other things) is tied into the tick handler
867  // and disabling retries could cause the class driver to deadlock.
868  // Currently no class driver we're aware of issues i/o in its
869  // Stop routine but this is a case we may want to defend ourself
870  // against.
871  //
872 
873  if (DeviceObject->Timer) {
875  }
876 
878 
879  NT_ASSERTMSGW(L"ClassDispatchPnp !! STOP_DEVICE should "
880  L"never be failed\n", NT_SUCCESS(status));
881 
882  if(isFdo) {
883  status = ClassForwardIrpSynchronous(commonExtension, Irp);
884  }
885 
886  if(NT_SUCCESS(status)) {
887  commonExtension->CurrentState = irpStack->MinorFunction;
888  commonExtension->PreviousState = 0xff;
889  }
890 
891  break;
892  }
893 
896 
897  UCHAR removeType = irpStack->MinorFunction;
898 
899  if (commonExtension->PagingPathCount != 0) {
900  DBGTRACE(ClassDebugWarning, ("ClassDispatchPnp (%p,%p): paging device is getting removed!", DeviceObject, Irp));
901  }
902 
903  //
904  // Release the lock for this IRP before calling in.
905  //
907  lockReleased = TRUE;
908 
909  /*
910  * If a timer was started on the device, stop it.
911  */
912  if (DeviceObject->Timer) {
914  }
915 
916  /*
917  * "Fire-and-forget" the remove irp to the lower stack.
918  * Don't touch the irp (or the irp stack!) after this.
919  */
920  if (isFdo) {
922  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
924  completeRequest = FALSE;
925  }
926  else {
928  }
929 
930  /*
931  * Do our own cleanup and call the class driver's remove
932  * cleanup routine.
933  * For IRP_MN_REMOVE_DEVICE, this also deletes our device object,
934  * so don't touch the extension after this.
935  */
936  commonExtension->PreviousState = commonExtension->CurrentState;
937  commonExtension->CurrentState = removeType;
938  ClassRemoveDevice(DeviceObject, removeType);
939 
940  break;
941  }
942 
944 
945  switch(irpStack->Parameters.UsageNotification.Type) {
946 
947  case DeviceUsageTypePaging: {
948 
949  BOOLEAN setPagable;
950 
951  if((irpStack->Parameters.UsageNotification.InPath) &&
952  (commonExtension->CurrentState != IRP_MN_START_DEVICE)) {
953 
954  //
955  // Device isn't started. Don't allow adding a
956  // paging file, but allow a removal of one.
957  //
958 
960  break;
961  }
962 
963  ASSERT(commonExtension->IsInitialized);
964 
965  //
966  // need to synchronize this now...
967  //
968 
970  status = KeWaitForSingleObject(&commonExtension->PathCountEvent,
972  FALSE, NULL);
975 
976  //
977  // If the volume is removable we should try to lock it in
978  // place or unlock it once per paging path count
979  //
980 
981  if (commonExtension->IsFdo){
983  DeviceObject,
984  Irp,
986  (BOOLEAN)irpStack->Parameters.UsageNotification.InPath);
987  }
988 
989  if (!NT_SUCCESS(status)){
990  KeSetEvent(&commonExtension->PathCountEvent, IO_NO_INCREMENT, FALSE);
992  break;
993  }
994 
995  //
996  // if removing last paging device, need to set DO_POWER_PAGABLE
997  // bit here, and possible re-set it below on failure.
998  //
999 
1000  setPagable = FALSE;
1001 
1002  if (!irpStack->Parameters.UsageNotification.InPath &&
1003  commonExtension->PagingPathCount == 1
1004  ) {
1005 
1006  //
1007  // removing last paging file
1008  // must have DO_POWER_PAGABLE bits set, but only
1009  // if noone set the DO_POWER_INRUSH bit
1010  //
1011 
1012 
1014  DebugPrint((2, "ClassDispatchPnp (%p,%p): Last "
1015  "paging file removed, but "
1016  "DO_POWER_INRUSH was set, so NOT "
1017  "setting DO_POWER_PAGABLE\n",
1018  DeviceObject, Irp));
1019  } else {
1020  DebugPrint((2, "ClassDispatchPnp (%p,%p): Last "
1021  "paging file removed, "
1022  "setting DO_POWER_PAGABLE\n",
1023  DeviceObject, Irp));
1025  setPagable = TRUE;
1026  }
1027 
1028  }
1029 
1030  //
1031  // forward the irp before finishing handling the
1032  // special cases
1033  //
1034 
1035  status = ClassForwardIrpSynchronous(commonExtension, Irp);
1036 
1037  //
1038  // now deal with the failure and success cases.
1039  // note that we are not allowed to fail the irp
1040  // once it is sent to the lower drivers.
1041  //
1042 
1043  if (NT_SUCCESS(status)) {
1044 
1046  (PLONG)&commonExtension->PagingPathCount,
1047  irpStack->Parameters.UsageNotification.InPath);
1048 
1049  if (irpStack->Parameters.UsageNotification.InPath) {
1050  if (commonExtension->PagingPathCount == 1) {
1051  DebugPrint((2, "ClassDispatchPnp (%p,%p): "
1052  "Clearing PAGABLE bit\n",
1053  DeviceObject, Irp));
1055  }
1056  }
1057 
1058  } else {
1059 
1060  //
1061  // cleanup the changes done above
1062  //
1063 
1064  if (setPagable != FALSE) {
1065  DebugPrint((2, "ClassDispatchPnp (%p,%p): Unsetting "
1066  "PAGABLE bit due to irp failure\n",
1067  DeviceObject, Irp));
1069  setPagable = FALSE;
1070  }
1071 
1072  //
1073  // relock or unlock the media if needed.
1074  //
1075 
1076  if (commonExtension->IsFdo) {
1077 
1079  DeviceObject,
1080  Irp,
1082  (BOOLEAN)!irpStack->Parameters.UsageNotification.InPath);
1083  }
1084  }
1085 
1086  //
1087  // set the event so the next one can occur.
1088  //
1089 
1090  KeSetEvent(&commonExtension->PathCountEvent,
1093  break;
1094  }
1095 
1097 
1099  (PLONG)&commonExtension->HibernationPathCount,
1100  irpStack->Parameters.UsageNotification.InPath
1101  );
1102  status = ClassForwardIrpSynchronous(commonExtension, Irp);
1103  if (!NT_SUCCESS(status)) {
1105  (PLONG)&commonExtension->HibernationPathCount,
1106  !irpStack->Parameters.UsageNotification.InPath
1107  );
1108  }
1109 
1110  break;
1111  }
1112 
1113  case DeviceUsageTypeDumpFile: {
1115  (PLONG)&commonExtension->DumpPathCount,
1116  irpStack->Parameters.UsageNotification.InPath
1117  );
1118  status = ClassForwardIrpSynchronous(commonExtension, Irp);
1119  if (!NT_SUCCESS(status)) {
1121  (PLONG)&commonExtension->DumpPathCount,
1122  !irpStack->Parameters.UsageNotification.InPath
1123  );
1124  }
1125 
1126  break;
1127  }
1128 
1129  default: {
1131  break;
1132  }
1133  }
1134  break;
1135  }
1136 
1138 
1139  DebugPrint((2, "ClassDispatchPnp (%p,%p): QueryCapabilities\n",
1140  DeviceObject, Irp));
1141 
1142  if(!isFdo) {
1143 
1145  DeviceObject,
1146  irpStack->Parameters.DeviceCapabilities.Capabilities
1147  );
1148 
1149  break;
1150 
1151  } else {
1152 
1153  PDEVICE_CAPABILITIES deviceCapabilities;
1154  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
1155  PCLASS_PRIVATE_FDO_DATA fdoData;
1156 
1157  fdoExtension = DeviceObject->DeviceExtension;
1158  fdoData = fdoExtension->PrivateFdoData;
1159  deviceCapabilities =
1160  irpStack->Parameters.DeviceCapabilities.Capabilities;
1161 
1162  //
1163  // forward the irp before handling the special cases
1164  //
1165 
1166  status = ClassForwardIrpSynchronous(commonExtension, Irp);
1167  if (!NT_SUCCESS(status)) {
1168  break;
1169  }
1170 
1171  //
1172  // we generally want to remove the device from the hotplug
1173  // applet, which requires the SR-OK bit to be set.
1174  // only when the user specifies that they are capable of
1175  // safely removing things do we want to clear this bit
1176  // (saved in WriteCacheEnableOverride)
1177  //
1178  // setting of this bit is done either above, or by the
1179  // lower driver.
1180  //
1181  // note: may not be started, so check we have FDO data first.
1182  //
1183 
1184  if (fdoData &&
1186  if (deviceCapabilities->SurpriseRemovalOK) {
1187  DebugPrint((1, "Classpnp: Clearing SR-OK bit in "
1188  "device capabilities due to hotplug "
1189  "device or media\n"));
1190  }
1191  deviceCapabilities->SurpriseRemovalOK = FALSE;
1192  }
1193  break;
1194 
1195  } // end QUERY_CAPABILITIES for FDOs
1196 
1197  ASSERT(FALSE);
1198  break;
1199 
1200 
1201  } // end QUERY_CAPABILITIES
1202 
1203  default: {
1204 
1205  if (isFdo){
1207 
1209  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1210 
1211  completeRequest = FALSE;
1212  }
1213 
1214  break;
1215  }
1216  }
1217  }
1218  else {
1219  ASSERT(driverExtension);
1221  }
1222 
1223  if (completeRequest){
1224  Irp->IoStatus.Status = status;
1225 
1226  if (!lockReleased){
1228  }
1229 
1231 
1232  DBGTRACE(ClassDebugTrace, ("ClassDispatchPnp (%p,%p): leaving with previous %#x, current %#x.", DeviceObject, Irp, commonExtension->PreviousState, commonExtension->CurrentState));
1233  }
1234  else {
1235  /*
1236  * The irp is already completed so don't touch it.
1237  * This may be a remove so don't touch the device extension.
1238  */
1239  DBGTRACE(ClassDebugTrace, ("ClassDispatchPnp (%p,%p): leaving.", DeviceObject, Irp));
1240  }
1241 
1242  return status;
1243 } // end ClassDispatchPnp()
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define DO_POWER_PAGABLE
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:91
#define TRUE
Definition: types.h:120
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI ClassRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN UCHAR RemoveType)
Definition: class.c:6971
#define IRP_MN_QUERY_ID
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
CLASS_DEV_INFO FdoData
Definition: classpnp.h:521
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define DO_POWER_INRUSH
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2055
NTSTATUS NTAPI ClasspEjectionControl(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN MEDIA_LOCK_TYPE LockType, IN BOOLEAN Lock)
Definition: create.c:449
LONG NTSTATUS
Definition: precomp.h:26
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
STORAGE_HOTPLUG_INFO HotplugInfo
Definition: classp.h:403
#define PAGED_CODE()
Definition: video.h:57
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
NTSTATUS NTAPI ClassQueryPnpCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_CAPABILITIES Capabilities)
Definition: class.c:6863
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
#define IRP_MN_QUERY_REMOVE_DEVICE
VOID NTAPI IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:166
#define CLEAR_FLAG(Flags, Bit)
Definition: classpnp.h:155
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
BOOLEAN WriteCacheEnableOverride
Definition: imports.h:249
#define IRP_MN_STOP_DEVICE
#define IoAdjustPagingPathCount(_Count, _Increment)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MN_START_DEVICE
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
PCLASS_ENUM_DEVICE ClassEnumerateDevice
Definition: classpnp.h:524
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
PCLASS_STOP_DEVICE ClassStopDevice
Definition: classpnp.h:513
NTSTATUS NTAPI ClassPnpQueryFdoRelations(IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
Definition: class.c:6551
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
* PDEVICE_CAPABILITIES
Definition: iotypes.h:928
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PCLASS_REMOVE_DEVICE ClassRemoveDevice
Definition: classpnp.h:514
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
NTSTATUS NTAPI ClassGetPdoId(IN PDEVICE_OBJECT Pdo, IN BUS_QUERY_ID_TYPE IdType, IN PUNICODE_STRING IdString)
Definition: class.c:6824
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
CLASS_DEV_INFO PdoData
Definition: classpnp.h:522
#define ObReferenceObject
Definition: obfuncs.h:204
CLASS_INIT_DATA InitData
Definition: classpnp.h:556
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
#define IRP_MN_CANCEL_STOP_DEVICE
#define IRP_MN_DEVICE_USAGE_NOTIFICATION
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
signed int * PLONG
Definition: retypes.h:5
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ClassForwardIrpSynchronous(IN PCOMMON_DEVICE_EXTENSION CommonExtension, IN PIRP Irp)
Definition: class.c:7918
#define IRP_MN_QUERY_CAPABILITIES
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
NTSTATUS NTAPI ClassPnpStartDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: class.c:1265
#define NT_ASSERTMSGW
Definition: rtlfuncs.h:3314
Definition: ps.c:97

Referenced by ClassInitialize().

◆ ClassFindModePage()

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

Definition at line 4209 of file class.c.

4215 {
4216  PCHAR limit;
4217  ULONG parameterHeaderLength;
4218  PVOID result = NULL;
4219 
4220  limit = ModeSenseBuffer + Length;
4221  parameterHeaderLength = (Use6Byte) ? sizeof(MODE_PARAMETER_HEADER) : sizeof(MODE_PARAMETER_HEADER10);
4222 
4223  if (Length >= parameterHeaderLength) {
4224 
4225  PMODE_PARAMETER_HEADER10 modeParam10;
4226  ULONG blockDescriptorLength;
4227 
4228  /*
4229  * Skip the mode select header and block descriptors.
4230  */
4231  if (Use6Byte){
4232  blockDescriptorLength = ((PMODE_PARAMETER_HEADER) ModeSenseBuffer)->BlockDescriptorLength;
4233  }
4234  else {
4235  modeParam10 = (PMODE_PARAMETER_HEADER10) ModeSenseBuffer;
4236  blockDescriptorLength = modeParam10->BlockDescriptorLength[1];
4237  }
4238 
4239  ModeSenseBuffer += parameterHeaderLength + blockDescriptorLength;
4240 
4241  //
4242  // ModeSenseBuffer now points at pages. Walk the pages looking for the
4243  // requested page until the limit is reached.
4244  //
4245 
4246  while (ModeSenseBuffer +
4248 
4249  if (((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageCode == PageMode) {
4250 
4251  /*
4252  * found the mode page. make sure it's safe to touch it all
4253  * before returning the pointer to caller
4254  */
4255 
4256  if (ModeSenseBuffer + ((PMODE_DISCONNECT_PAGE)ModeSenseBuffer)->PageLength > limit) {
4257  /*
4258  * Return NULL since the page is not safe to access in full
4259  */
4260  result = NULL;
4261  }
4262  else {
4263  result = ModeSenseBuffer;
4264  }
4265  break;
4266  }
4267 
4268  //
4269  // Advance to the next page which is 4-byte-aligned offset after this page.
4270  //
4271  ModeSenseBuffer +=
4272  ((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageLength +
4274 
4275  }
4276  }
4277 
4278  return result;
4279 } // end ClassFindModePage()
signed char * PCHAR
Definition: retypes.h:7
struct _MODE_DISCONNECT_PAGE * PMODE_DISCONNECT_PAGE
GLint limit
Definition: glext.h:10326
UCHAR BlockDescriptorLength[2]
Definition: cdrw_hw.h:2516
smooth NULL
Definition: ftsmooth.c:416
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
struct _MODE_PARAMETER_HEADER10 * PMODE_PARAMETER_HEADER10
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:679
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
unsigned int ULONG
Definition: retypes.h:1
GLuint64EXT * result
Definition: glext.h:11304

Referenced by CdRomDeviceControlCompletion(), CdRomSetVolumeIntermediateCompletion(), DetermineDriveType(), DiskGetCacheInformation(), DiskGetInfoExceptionInformation(), DiskInfoExceptionComplete(), DiskSetCacheInformation(), and FormatMedia().

◆ ClassForwardIrpSynchronous()

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

Definition at line 7918 of file class.c.

7922 {
7924  return ClassSendIrpSynchronous(CommonExtension->LowerDeviceObject, Irp);
7925 } // end ClassForwardIrpSynchronous()
_In_ PIRP Irp
Definition: csq.h:116
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
NTSTATUS NTAPI ClassSendIrpSynchronous(IN PDEVICE_OBJECT TargetDeviceObject, IN PIRP Irp)
Definition: class.c:7948

Referenced by ClassDispatchPnp().

◆ ClassGetDescriptor()

NTSTATUS NTAPI ClassGetDescriptor ( IN PDEVICE_OBJECT  DeviceObject,
IN PSTORAGE_PROPERTY_ID  PropertyId,
OUT PSTORAGE_DESCRIPTOR_HEADER Descriptor 
)

Definition at line 6364 of file class.c.

6369 {
6371  IO_STATUS_BLOCK ioStatus;
6372 
6373  PSTORAGE_DESCRIPTOR_HEADER descriptor = NULL;
6374  ULONG length;
6375 
6376  //UCHAR pass = 0;
6377 
6378  PAGED_CODE();
6379 
6380  //
6381  // Set the passed-in descriptor pointer to NULL as default
6382  //
6383 
6384  *Descriptor = NULL;
6385 
6386 
6388  query.PropertyId = *PropertyId;
6389  query.QueryType = PropertyStandardQuery;
6390 
6391  //
6392  // On the first pass we just want to get the first few
6393  // bytes of the descriptor so we can read it's size
6394  //
6395 
6396  descriptor = (PVOID)&query;
6397 
6398  ASSERT(sizeof(STORAGE_PROPERTY_QUERY) >= (sizeof(ULONG)*2));
6399 
6402  DeviceObject,
6403  &query,
6404  sizeof(STORAGE_PROPERTY_QUERY),
6405  sizeof(ULONG) * 2,
6406  FALSE,
6407  &ioStatus
6408  );
6409 
6410  if(!NT_SUCCESS(ioStatus.Status)) {
6411 
6412  DebugPrint((1, "ClassGetDescriptor: error %lx trying to "
6413  "query properties #1\n", ioStatus.Status));
6414  return ioStatus.Status;
6415  }
6416 
6417  if (descriptor->Size == 0) {
6418 
6419  //
6420  // This DebugPrint is to help third-party driver writers
6421  //
6422 
6423  DebugPrint((0, "ClassGetDescriptor: size returned was zero?! (status "
6424  "%x\n", ioStatus.Status));
6425  return STATUS_UNSUCCESSFUL;
6426 
6427  }
6428 
6429  //
6430  // This time we know how much data there is so we can
6431  // allocate a buffer of the correct size
6432  //
6433 
6434  length = descriptor->Size;
6435 
6436  descriptor = ExAllocatePoolWithTag(NonPagedPool, length, '4BcS');
6437 
6438  if(descriptor == NULL) {
6439 
6440  DebugPrint((1, "ClassGetDescriptor: unable to memory for descriptor "
6441  "(%d bytes)\n", length));
6443  }
6444 
6445  //
6446  // setup the query again, as it was overwritten above
6447  //
6448 
6450  query.PropertyId = *PropertyId;
6451  query.QueryType = PropertyStandardQuery;
6452 
6453  //
6454  // copy the input to the new outputbuffer
6455  //
6456 
6457  RtlCopyMemory(descriptor,
6458  &query,
6459  sizeof(STORAGE_PROPERTY_QUERY)
6460  );
6461 
6464  DeviceObject,
6465  descriptor,
6466  sizeof(STORAGE_PROPERTY_QUERY),
6467  length,
6468  FALSE,
6469  &ioStatus
6470  );
6471 
6472  if(!NT_SUCCESS(ioStatus.Status)) {
6473 
6474  DebugPrint((1, "ClassGetDescriptor: error %lx trying to "
6475  "query properties #1\n", ioStatus.Status));
6476  ExFreePool(descriptor);
6477  return ioStatus.Status;
6478  }
6479 
6480  //
6481  // return the memory we've allocated to the caller
6482  //
6483 
6484  *Descriptor = descriptor;
6485  return ioStatus.Status;
6486 } // end ClassGetDescriptor()
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
* PSTORAGE_DESCRIPTOR_HEADER
Definition: ntddstor.h:441
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PSTORAGE_PROPERTY_ID PropertyId
Definition: classpnp.h:966
VOID NTAPI ClassSendDeviceIoControlSynchronous(IN ULONG IoControlCode, IN PDEVICE_OBJECT TargetDeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG InputBufferLength, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, OUT PIO_STATUS_BLOCK IoStatus)
Definition: class.c:7660
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:167
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
GLenum query
Definition: glext.h:7781
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966

Referenced by ClassPnpStartDevice().

◆ ClassGetDriverExtension()

PCLASS_DRIVER_EXTENSION NTAPI ClassGetDriverExtension ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 7236 of file class.c.

7239 {
7241 } // end ClassGetDriverExtension()
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:91
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842

Referenced by CdRomInitDevice(), ClassInitializeMediaChangeDetection(), and ClassQueryPnpCapabilities().

◆ ClassGetPdoId()

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

Definition at line 6824 of file class.c.

6829 {
6831  driverExtension = IoGetDriverObjectExtension(Pdo->DriverObject,
6833 
6834  ASSERT_PDO(Pdo);
6835  ASSERT(driverExtension->InitData.ClassQueryId);
6836 
6837  PAGED_CODE();
6838 
6839  return driverExtension->InitData.ClassQueryId( Pdo, IdType, IdString);
6840 } // end ClassGetPdoId()
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:91
_In_ PDEVICE_OBJECT Pdo
Definition: classpnp.h:301
PCLASS_QUERY_ID ClassQueryId
Definition: classpnp.h:525
_In_ BUS_QUERY_ID_TYPE _In_ PUNICODE_STRING IdString
Definition: classpnp.h:357
#define PAGED_CODE()
Definition: video.h:57
#define ASSERT_PDO(x)
Definition: pci.h:36
_In_ BUS_QUERY_ID_TYPE IdType
Definition: classpnp.h:357
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
CLASS_INIT_DATA InitData
Definition: classpnp.h:556

Referenced by ClassDispatchPnp().

◆ ClassGetVpb()

PVPB NTAPI ClassGetVpb ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 8048 of file class.c.

8051 {
8052  return DeviceObject->Vpb;
8053 } // end ClassGetVpb()
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560

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

◆ ClassInitialize()

ULONG NTAPI ClassInitialize ( IN PVOID  Argument1,
IN PVOID  Argument2,
IN PCLASS_INIT_DATA  InitializationData 
)

Definition at line 120 of file class.c.

125 {
128 
129  PCLASS_DRIVER_EXTENSION driverExtension;
130 
132 
133  PAGED_CODE();
134 
135  DebugPrint((3,"\n\nSCSI Class Driver\n"));
136 
138 
139  //
140  // Validate the length of this structure. This is effectively a
141  // version check.
142  //
143 
144  if (InitializationData->InitializationDataSize != sizeof(CLASS_INIT_DATA)) {
145 
146  //
147  // This DebugPrint is to help third-party driver writers
148  //
149 
150  DebugPrint((0,"ClassInitialize: Class driver wrong version\n"));
152  }
153 
154  //
155  // Check that each required entry is not NULL. Note that Shutdown, Flush and Error
156  // are not required entry points.
157  //
158 
159  if ((!InitializationData->FdoData.ClassDeviceControl) ||
160  (!((InitializationData->FdoData.ClassReadWriteVerification) ||
161  (InitializationData->ClassStartIo))) ||
162  (!InitializationData->ClassAddDevice) ||
163  (!InitializationData->FdoData.ClassStartDevice)) {
164 
165  //
166  // This DebugPrint is to help third-party driver writers
167  //
168 
169  DebugPrint((0,
170  "ClassInitialize: Class device-specific driver missing required "
171  "FDO entry\n"));
172 
174  }
175 
176  if ((InitializationData->ClassEnumerateDevice) &&
177  ((!InitializationData->PdoData.ClassDeviceControl) ||
178  (!InitializationData->PdoData.ClassStartDevice) ||
179  (!((InitializationData->PdoData.ClassReadWriteVerification) ||
180  (InitializationData->ClassStartIo))))) {
181 
182  //
183  // This DebugPrint is to help third-party driver writers
184  //
185 
186  DebugPrint((0, "ClassInitialize: Class device-specific missing "
187  "required PDO entry\n"));
188 
190  }
191 
192  if((InitializationData->FdoData.ClassStopDevice == NULL) ||
193  ((InitializationData->ClassEnumerateDevice != NULL) &&
194  (InitializationData->PdoData.ClassStopDevice == NULL))) {
195 
196  //
197  // This DebugPrint is to help third-party driver writers
198  //
199 
200  DebugPrint((0, "ClassInitialize: Class device-specific missing "
201  "required PDO entry\n"));
202  ASSERT(FALSE);
204  }
205 
206  //
207  // Setup the default power handlers if the class driver didn't provide
208  // any.
209  //
210 
211  if(InitializationData->FdoData.ClassPowerDevice == NULL) {
212  InitializationData->FdoData.ClassPowerDevice = ClassMinimalPowerHandler;
213  }
214 
215  if((InitializationData->ClassEnumerateDevice != NULL) &&
216  (InitializationData->PdoData.ClassPowerDevice == NULL)) {
217  InitializationData->PdoData.ClassPowerDevice = ClassMinimalPowerHandler;
218  }
219 
220  //
221  // warn that unload is not supported
222  //
223  // ISSUE-2000/02/03-peterwie
224  // We should think about making this a fatal error.
225  //
226 
227  if(InitializationData->ClassUnload == NULL) {
228 
229  //
230  // This DebugPrint is to help third-party driver writers
231  //
232 
233  DebugPrint((0, "ClassInitialize: driver does not support unload %wZ\n",
234  RegistryPath));
235  }
236 
237  //
238  // Create an extension for the driver object
239  //
240 
243  sizeof(CLASS_DRIVER_EXTENSION),
244  (PVOID *)&driverExtension);
245 
246  if(NT_SUCCESS(status)) {
247 
248  //
249  // Copy the registry path into the driver extension so we can use it later
250  //
251 
252  driverExtension->RegistryPath.Length = RegistryPath->Length;
254 
255  driverExtension->RegistryPath.Buffer =
258  '1CcS');
259 
260  if(driverExtension->RegistryPath.Buffer == NULL) {
261 
263  return status;
264  }
265 
267  &(driverExtension->RegistryPath),
268  RegistryPath);
269 
270  //
271  // Copy the initialization data into the driver extension so we can reuse
272  // it during our add device routine
273  //
274 
276  &(driverExtension->InitData),
278  sizeof(CLASS_INIT_DATA));
279 
280  driverExtension->DeviceCount = 0;
281 
282  } else if (status == STATUS_OBJECT_NAME_COLLISION) {
283 
284  //
285  // The extension already exists - get a pointer to it
286  //
287 
288  driverExtension = IoGetDriverObjectExtension(DriverObject,
290 
291  ASSERT(driverExtension != NULL);
292 
293  } else {
294 
295  DebugPrint((1, "ClassInitialize: Class driver extension could not be "
296  "allocated %lx\n", status));
297  return status;
298  }
299 
300  //
301  // Update driver object with entry points.
302  //
303 
315 
316  if (InitializationData->ClassStartIo) {
318  }
319 
320  if ((InitializationData->ClassUnload) && (ClassPnpAllowUnload != FALSE)) {
322  } else {
324  }
325 
327 
328  DbgPrint("Driver is ready to go\n");
330  return status;
331 } // end ClassInitialize()
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:311
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:91
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:694
#define IRP_MJ_FLUSH_BUFFERS
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1764
NTSTATUS NTAPI ClassDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class.c:532
#define DbgPrint
Definition: loader.c:25
DRIVER_DISPATCH ClassCreateClose
Definition: classp.h:505
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
DRIVER_DISPATCH ClassSystemControl
Definition: classp.h:548
NTSTATUS NTAPI ClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class.c:5613
UNICODE_STRING RegistryPath
Definition: kbdclass.h:25
#define PAGED_CODE()
Definition: video.h:57
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define IRP_MJ_SCSI
ULONG ClassPnpAllowUnload
Definition: class.c:62
NTSTATUS NTAPI ClassAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: class.c:491
NTSTATUS NTAPI ClassReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class.c:1574
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2174
#define ClasspInitializeDebugGlobals()
Definition: debug.h:133
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
_In_ PVOID Argument2
Definition: classpnp.h:680
DRIVER_DISPATCH ClassDispatchPower
Definition: classp.h:729
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI ClassInternalIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class.c:6117
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID NTAPI ClasspStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class.c:7262
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:680
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
#define IRP_MJ_SYSTEM_CONTROL
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
VOID NTAPI ClassUnload(IN PDRIVER_OBJECT DriverObject)
Definition: class.c:426
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
#define IRP_MJ_READ
Definition: rdpdr.c:46
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
CLASS_INIT_DATA InitData
Definition: classpnp.h:556
unsigned int ULONG
Definition: retypes.h:1
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
NTSTATUS NTAPI ClassMinimalPowerHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: power.c:1302
PDRIVER_STARTIO DriverStartIo
Definition: iotypes.h:2179
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ClassDeviceControlDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class.c:4532
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: ps.c:97

Referenced by DriverEntry().

◆ ClassInitializeEx()

ULONG NTAPI ClassInitializeEx ( IN PDRIVER_OBJECT  DriverObject,
IN LPGUID  Guid,
IN PVOID  Data 
)

Definition at line 367 of file class.c.

372 {
373  PCLASS_DRIVER_EXTENSION driverExtension;
374 
376 
377  PAGED_CODE();
378 
379  driverExtension = IoGetDriverObjectExtension( DriverObject,
381  );
383  {
385 
386  //
387  // Indicate the device supports PCLASS_QUERY_REGINFO_EX
388  // callback instead of PCLASS_QUERY_REGINFO callback.
389  //
391 
392  if (List->Size == sizeof(CLASS_QUERY_WMI_REGINFO_EX_LIST))
393  {
394  driverExtension->ClassFdoQueryWmiRegInfoEx = List->ClassFdoQueryWmiRegInfoEx;
395  driverExtension->ClassPdoQueryWmiRegInfoEx = List->ClassPdoQueryWmiRegInfoEx;
397  } else {
399  }
400  } else {
402  }
403 
404  return(status);
405 
406 } // end ClassInitializeEx()
#define CLASS_DRIVER_EXTENSION_KEY
Definition: classpnp.h:91
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
static GUID * Guid
Definition: apphelp.c:93
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx
Definition: classpnp.h:559
LIST_ENTRY List
Definition: psmgr.c:57
PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx
Definition: classpnp.h:560
struct _CLASS_QUERY_WMI_REGINFO_EX_LIST * PCLASS_QUERY_WMI_REGINFO_EX_LIST
GUID ClassGuidQueryRegInfoEx
Definition: data.c:43
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by DriverEntry().

◆ ClassInternalIoControl()

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

Definition at line 6117 of file class.c.

6121 {
6123 
6126 
6127  ULONG isRemoved;
6128 
6129  PSCSI_REQUEST_BLOCK srb;
6130 
6131  isRemoved = ClassAcquireRemoveLock(DeviceObject, Irp);
6132 
6133  if(isRemoved) {
6134 
6135  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
6136 
6138 
6140 
6142  }
6143 
6144  //
6145  // Get a pointer to the SRB.
6146  //
6147 
6148  srb = irpStack->Parameters.Scsi.Srb;
6149 
6150  //
6151  // Set the parameters in the next stack location.
6152  //
6153 
6154  if(commonExtension->IsFdo) {
6155  nextStack->Parameters.Scsi.Srb = srb;
6156  nextStack->MajorFunction = IRP_MJ_SCSI;
6157  nextStack->MinorFunction = IRP_MN_SCSI_CLASS;
6158 
6159  } else {
6160 
6162  }
6163 
6165 
6166  return IoCallDriver(commonExtension->LowerDeviceObject, Irp);
6167 } // end ClassInternalIoControl()
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
_In_ PIRP Irp
Definition: csq.h:116
#define IRP_MJ_SCSI
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
PVOID DeviceExtension
Definition: env_spec_w32.h:418
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define IRP_MN_SCSI_CLASS
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212

Referenced by ClassInitialize().

◆ 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 OPTIONAL ULONG RetryInterval 
)

Definition at line 2994 of file class.c.

3003 {
3004  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
3005  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
3006 
3007  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
3008 
3009  BOOLEAN retry = TRUE;
3010  BOOLEAN logError = FALSE;
3011  BOOLEAN unhandledError = FALSE;
3012  BOOLEAN incrementErrorCount = FALSE;
3013 
3014  ULONG badSector = 0;
3015  ULONG uniqueId = 0;
3016 
3017  NTSTATUS logStatus;
3018 
3019  ULONG readSector;
3020  ULONG index;
3021 
3022  ULONG retryInterval = 0;
3023  KIRQL oldIrql;
3024 
3025 
3026  logStatus = -1;
3027 
3028  if(TEST_FLAG(Srb->SrbFlags, SRB_CLASS_FLAGS_PAGING)) {
3029 
3030  //
3031  // Log anything remotely incorrect about paging i/o
3032  //
3033 
3034  logError = TRUE;
3035  uniqueId = 301;
3036  logStatus = IO_WARNING_PAGING_FAILURE;
3037  }
3038 
3039  //
3040  // Check that request sense buffer is valid.
3041  //
3042 
3043  ASSERT(fdoExtension->CommonExtension.IsFdo);
3044 
3045 
3046  //
3047  // must handle the SRB_STATUS_INTERNAL_ERROR case first,
3048  // as it has all the flags set.
3049  //
3050 
3051  if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_INTERNAL_ERROR) {
3052 
3054  "ClassInterpretSenseInfo: Internal Error code is %x\n",
3055  Srb->InternalStatus));
3056 
3057  retry = FALSE;
3058  *Status = Srb->InternalStatus;
3059 
3060  } else if ((Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) &&
3061  (Srb->SenseInfoBufferLength >=
3062  offsetof(SENSE_DATA, CommandSpecificInformation))) {
3063 
3064  //
3065  // Zero the additional sense code and additional sense code qualifier
3066  // if they were not returned by the device.
3067  //
3068 
3069  readSector = senseBuffer->AdditionalSenseLength +
3070  offsetof(SENSE_DATA, AdditionalSenseLength);
3071 
3072  if (readSector > Srb->SenseInfoBufferLength) {
3073  readSector = Srb->SenseInfoBufferLength;
3074  }
3075 
3076  if (readSector <= offsetof(SENSE_DATA, AdditionalSenseCode)) {
3077  senseBuffer->AdditionalSenseCode = 0;
3078  }
3079 
3080  if (readSector <= offsetof(SENSE_DATA, AdditionalSenseCodeQualifier)) {
3081  senseBuffer->AdditionalSenseCodeQualifier = 0;
3082  }
3083 
3085  "ClassInterpretSenseInfo: Error code is %x\n",
3086  senseBuffer->ErrorCode));
3088  "ClassInterpretSenseInfo: Sense key is %x\n",
3089  senseBuffer->SenseKey));
3091  "ClassInterpretSenseInfo: Additional sense code is %x\n",
3092  senseBuffer->AdditionalSenseCode));
3094  "ClassInterpretSenseInfo: Additional sense code qualifier "
3095  "is %x\n",
3096  senseBuffer->AdditionalSenseCodeQualifier));
3097 
3098 
3099  switch (senseBuffer->SenseKey & 0xf) {
3100 
3101  case SCSI_SENSE_NOT_READY: {
3102 
3103  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3104  "Device not ready\n"));
3106 
3107  switch (senseBuffer->AdditionalSenseCode) {
3108 
3110 
3111  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3112  "Lun not ready\n"));
3113 
3114  switch (senseBuffer->AdditionalSenseCodeQualifier) {
3115 
3117  DEVICE_EVENT_BECOMING_READY notReady;
3118 
3119  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3120  "Operation In Progress\n"));
3121  retryInterval = NOT_READY_RETRY_INTERVAL;
3122 
3123  RtlZeroMemory(&notReady, sizeof(DEVICE_EVENT_BECOMING_READY));
3124  notReady.Version = 1;
3125  notReady.Reason = 2;
3126  notReady.Estimated100msToReady = retryInterval * 10;
3127  ClasspSendNotification(fdoExtension,
3128  &GUID_IO_DEVICE_BECOMING_READY,
3130  &notReady);
3131 
3132  break;
3133  }
3134 
3136  DEVICE_EVENT_BECOMING_READY notReady;
3137 
3138  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3139  "In process of becoming ready\n"));
3140  retryInterval = NOT_READY_RETRY_INTERVAL;
3141 
3142  RtlZeroMemory(&notReady, sizeof(DEVICE_EVENT_BECOMING_READY));
3143  notReady.Version = 1;
3144  notReady.Reason = 1;
3145  notReady.Estimated100msToReady = retryInterval * 10;
3146  ClasspSendNotification(fdoExtension,
3147  &GUID_IO_DEVICE_BECOMING_READY,
3149  &notReady);
3150  break;
3151  }
3152 
3154  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3155  "Long write in progress\n"));
3156  retry = FALSE;
3157  break;
3158  }
3159 
3161  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3162  "Manual intervention required\n"));
3164  retry = FALSE;
3165  break;
3166  }
3167 
3169  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3170  "Format in progress\n"));
3171  retry = FALSE;
3172  break;
3173  }
3174 
3176 
3177  if(!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
3179 
3181  "ClassInterpretSenseInfo: "
3182  "not ready, cause unknown\n"));
3183  /*
3184  Many non-WHQL certified drives (mostly CD-RW) return
3185  this when they have no media instead of the obvious
3186  choice of:
3187 
3188  SCSI_SENSE_NOT_READY/SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
3189 
3190  These drives should not pass WHQL certification due
3191  to this discrepancy.
3192 
3193  */
3194  retry = FALSE;
3195  break;
3196 
3197  } else {
3198 
3199  //
3200  // Treat this as init command required and fall through.
3201  //
3202  }
3203  }
3204 
3206  default: {
3207  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3208  "Initializing command required\n"));
3209 
3210  //
3211  // This sense code/additional sense code
3212  // combination may indicate that the device
3213  // needs to be started. Send an start unit if this
3214  // is a disk device.
3215  //
3216 
3217  if(TEST_FLAG(fdoExtension->DeviceFlags,
3219  !TEST_FLAG(Srb->SrbFlags,
3221  ClassSendStartUnit(Fdo);
3222  }
3223  break;
3224  }
3225 
3226 
3227  } // end switch (senseBuffer->AdditionalSenseCodeQualifier)
3228  break;
3229  }
3230 
3232  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3233  "No Media in device.\n"));
3235  retry = FALSE;
3236 
3237  //
3238  // signal MCN that there isn't any media in the device
3239  //
3240  if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
3241  DebugPrint((ClassDebugError, "ClassInterpretSenseInfo: "
3242  "No Media in a non-removable device %p\n",
3243  Fdo));
3244  }
3246 
3247  break;
3248  }
3249  } // end switch (senseBuffer->AdditionalSenseCode)
3250 
3251  break;
3252  } // end SCSI_SENSE_NOT_READY
3253 
3254  case SCSI_SENSE_DATA_PROTECT: {
3255  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3256  "Media write protected\n"));
3258  retry = FALSE;
3259  break;
3260  } // end SCSI_SENSE_DATA_PROTECT
3261 
3262  case SCSI_SENSE_MEDIUM_ERROR: {
3263  DebugPrint((ClassDebugSenseInfo,"ClassInterpretSenseInfo: "
3264  "Medium Error (bad block)\n"));
3266 
3267  retry = FALSE;
3268  logError = TRUE;
3269  uniqueId = 256;
3270  logStatus = IO_ERR_BAD_BLOCK;
3271 
3272  //
3273  // Check if this error is due to unknown format
3274  //
3275  if (senseBuffer->AdditionalSenseCode == SCSI_ADSENSE_INVALID_MEDIA){
3276 
3277  switch (senseBuffer->AdditionalSenseCodeQualifier) {
3278 
3280 
3282 
3283  //
3284  // Log error only if this is a paging request
3285  //
3286  if(!TEST_FLAG(Srb->SrbFlags, SRB_CLASS_FLAGS_PAGING)) {
3287  logError = FALSE;
3288  }
3289  break;
3290  }
3291 
3293 
3295  logError = FALSE;
3296  break;
3297 
3298  }
3299  default: {
3300  break;
3301  }
3302  } // end switch AdditionalSenseCodeQualifier
3303 
3304  } // end SCSI_ADSENSE_INVALID_MEDIA
3305 
3306  break;
3307 
3308  } // end SCSI_SENSE_MEDIUM_ERROR
3309 
3311  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3312  "Hardware error\n"));
3314  logError = TRUE;
3315  uniqueId = 257;
3316  logStatus = IO_ERR_CONTROLLER_ERROR;
3317  break;
3318  } // end SCSI_SENSE_HARDWARE_ERROR
3319 
3321 
3322  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3323  "Illegal SCSI request\n"));
3325  retry = FALSE;
3326 
3327  switch (senseBuffer->AdditionalSenseCode) {
3328 
3330  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3331  "Illegal command\n"));
3332  break;
3333  }
3334 
3336  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3337  "Illegal block address\n"));
3339  break;
3340  }
3341 
3342  case SCSI_ADSENSE_INVALID_LUN: {
3343  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3344  "Invalid LUN\n"));
3346  break;
3347  }
3348 
3349  case SCSI_ADSENSE_MUSIC_AREA: {
3350  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3351  "Music area\n"));
3352  break;
3353  }
3354 
3355  case SCSI_ADSENSE_DATA_AREA: {
3356  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3357  "Data area\n"));
3358  break;
3359  }
3360 
3362  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3363  "Volume overflow\n"));
3364  break;
3365  }
3366 
3368  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3369  "Copy protection failure\n"));
3370 
3372 
3373  switch (senseBuffer->AdditionalSenseCodeQualifier) {
3376  "ClassInterpretSenseInfo: "
3377  "Authentication failure\n"));
3379  break;
3382  "ClassInterpretSenseInfo: "
3383  "Key not present\n"));
3385  break;
3388  "ClassInterpretSenseInfo: "
3389  "Key not established\n"));
3391  break;
3394  "ClassInterpretSenseInfo: "
3395  "Read of scrambled sector w/o "
3396  "authentication\n"));
3398  break;
3401  "ClassInterpretSenseInfo: "
3402  "Media region does not logical unit "
3403  "region\n"));
3405  break;
3408  "ClassInterpretSenseInfo: "
3409  "Region set error -- region may "
3410  "be permanent\n"));
3412  break;
3413  } // end switch of ASCQ for COPY_PROTECTION_FAILURE
3414 
3415  break;
3416  }
3417 
3418 
3419  case SCSI_ADSENSE_INVALID_CDB: {
3420  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3421  "Invalid CDB\n"));
3422 
3423  //
3424  // Note: the retry interval is not typically used.
3425  // it is set here only because a ClassErrorHandler
3426  // cannot set the retryInterval, and the error may
3427  // require a few commands to be sent to clear whatever
3428  // caused this condition (i.e. disk clears the write
3429  // cache, requiring at least two commands)
3430  //
3431  // hopefully, this shortcoming can be changed for
3432  // blackcomb.
3433  //
3434 
3435  retryInterval = 3;
3436  break;
3437  }
3438 
3439  } // end switch (senseBuffer->AdditionalSenseCode)
3440 
3441  break;
3442  } // end SCSI_SENSE_ILLEGAL_REQUEST
3443 
3445 
3446  //PVPB vpb;
3447  ULONG count;
3448 
3449  //
3450  // A media change may have occured so increment the change
3451  // count for the physical device
3452  //
3453 
3454  count = InterlockedIncrement((PLONG)&fdoExtension->MediaChangeCount);
3455  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3456  "Media change count for device %d incremented to %#lx\n",
3457  fdoExtension->DeviceNumber, count));
3458 
3459 
3460  switch (senseBuffer->AdditionalSenseCode) {
3462  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3463  "Media changed\n"));
3464 
3465  if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
3466  DebugPrint((ClassDebugError, "ClassInterpretSenseInfo: "
3467  "Media Changed on non-removable device %p\n",
3468  Fdo));
3469  }
3471  break;
3472  }
3473 
3474  case SCSI_ADSENSE_BUS_RESET: {
3475  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3476  "Bus reset\n"));
3477  break;
3478  }
3479 
3481  switch (senseBuffer->AdditionalSenseCodeQualifier) {
3482 
3484  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3485  "Ejection request received!\n"));
3486  ClassSendEjectionNotification(fdoExtension);
3487  break;
3488  }
3489 
3491  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3492  "Operator selected write permit?! "
3493  "(unsupported!)\n"));
3494  break;
3495  }
3496 
3498  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3499  "Operator selected write protect?! "
3500  "(unsupported!)\n"));
3501  break;
3502  }
3503 
3504  }
3505  break;
3506  }
3507 
3508  default: {
3509  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3510  "Unit attention\n"));
3511  break;
3512  }
3513 
3514  } // end switch (senseBuffer->AdditionalSenseCode)
3515 
3516  if (TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA))
3517  {
3518  //
3519  // TODO : Is the media lockable?
3520  //
3521 
3522  if ((ClassGetVpb(Fdo) != NULL) && (ClassGetVpb(Fdo)->Flags & VPB_MOUNTED))
3523  {
3524  //
3525  // Set bit to indicate that media may have changed
3526  // and volume needs verification.
3527  //
3528 
3529  SET_FLAG(Fdo->Flags, DO_VERIFY_VOLUME);
3530 
3532  retry = FALSE;
3533  }
3534  }
3535  else
3536  {
3538  }
3539 
3540  break;
3541 
3542  } // end SCSI_SENSE_UNIT_ATTENTION
3543 
3545  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3546  "Command aborted\n"));
3548  retryInterval = 1;
3549  break;
3550  } // end SCSI_SENSE_ABORTED_COMMAND
3551 
3552  case SCSI_SENSE_BLANK_CHECK: {
3553  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3554  "Media blank check\n"));
3555  retry = FALSE;
3557  break;
3558  } // end SCSI_SENSE_BLANK_CHECK
3559 
3561 
3562  DebugPrint((ClassDebugSenseInfo, "ClassInterpretSenseInfo: "
3563  "Recovered error\n"));
3565  retry = FALSE;
3566  logError = TRUE;
3567  uniqueId = 258;
3568 
3569  switch(senseBuffer->AdditionalSenseCode) {
3571  case SCSI_ADSENSE_TRACK_ERROR: {
3572  logStatus = IO_ERR_SEEK_ERROR;
3573  break;
3574  }
3575 
3578  logStatus = IO_RECOVERED_VIA_ECC;
3579  break;
3580  }
3581 
3583  UCHAR wmiEventData[5];
3584 
3585  *((PULONG)wmiEventData) = sizeof(UCHAR);