ReactOS  0.4.15-dev-1386-g5cb9f87
class2.h File Reference
#include <ntddscsi.h>
#include <srb.h>
Include dependency graph for class2.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _CLASS_INIT_DATA
 
struct  _DEVICE_EXTENSION
 
struct  _COMPLETION_CONTEXT
 

Macros

#define MAXIMUM_RETRIES   15
 
#define RETRY_WAIT   2000000 /* 200 ms in units of 100 ns */
 
#define DEV_WRITE_CACHE   0x00000001
 
#define DEV_USE_SCSI1   0x00000002
 
#define DEV_SAFE_START_UNIT   0x00000004
 
#define DEV_NO_12BYTE_CDB   0x00000008
 

Typedefs

typedef IN PSCSI_REQUEST_BLOCK Srb
 
typedef IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUSStatus
 
typedef IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEANRetry
 
typedef BOOLEAN(NTAPIPCLASS_DEVICE_CALLBACK) (IN PINQUIRYDATA)
 
typedef NTSTATUS(NTAPIPCLASS_READ_WRITE) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
typedef BOOLEAN(NTAPIPCLASS_FIND_DEVICES) (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath, IN struct _CLASS_INIT_DATA *InitializationData, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG PortNumber)
 
typedef NTSTATUS(NTAPIPCLASS_DEVICE_CONTROL) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
typedef NTSTATUS(NTAPIPCLASS_SHUTDOWN_FLUSH) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
typedef NTSTATUS(NTAPIPCLASS_CREATE_CLOSE) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
typedef struct _CLASS_INIT_DATA CLASS_INIT_DATA
 
typedef struct _CLASS_INIT_DATAPCLASS_INIT_DATA
 
typedef struct _DEVICE_EXTENSION DEVICE_EXTENSION
 
typedef struct _DEVICE_EXTENSIONPDEVICE_EXTENSION
 
typedef struct _COMPLETION_CONTEXT COMPLETION_CONTEXT
 
typedef struct _COMPLETION_CONTEXTPCOMPLETION_CONTEXT
 

Functions

typedef VOID (NTAPI *PCLASS_ERROR)(IN PDEVICE_OBJECT DeviceObject
 
NTSTATUS NTAPI ScsiClassAsynchronousCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
VOID NTAPI ScsiClassBuildRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiClassClaimDevice (IN PDEVICE_OBJECT PortDeviceObject, IN PSCSI_INQUIRY_DATA LunInfo, IN BOOLEAN Release, OUT PDEVICE_OBJECT *NewPortDeviceObject OPTIONAL)
 
NTSTATUS NTAPI ScsiClassCreateDeviceObject (IN PDRIVER_OBJECT DriverObject, IN PCCHAR ObjectNameBuffer, IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN OUT PDEVICE_OBJECT *DeviceObject, IN PCLASS_INIT_DATA InitializationData)
 
NTSTATUS NTAPI ScsiClassDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
PVOID NTAPI ScsiClassFindModePage (IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
 
ULONG NTAPI ScsiClassFindUnclaimedDevices (IN PCLASS_INIT_DATA InitializationData, OUT PSCSI_ADAPTER_BUS_INFO AdapterInformation)
 
NTSTATUS NTAPI ScsiClassGetCapabilities (IN PDEVICE_OBJECT PortDeviceObject, OUT PIO_SCSI_CAPABILITIES *PortCapabilities)
 
NTSTATUS NTAPI ScsiClassGetInquiryData (IN PDEVICE_OBJECT PortDeviceObject, OUT PSCSI_ADAPTER_BUS_INFO *ConfigInfo)
 
ULONG NTAPI ScsiClassInitialize (IN PVOID Argument1, IN PVOID Argument2, IN PCLASS_INIT_DATA InitializationData)
 
VOID NTAPI ScsiClassInitializeSrbLookasideList (IN PDEVICE_EXTENSION DeviceExtension, IN ULONG NumberElements)
 
NTSTATUS NTAPI ScsiClassInternalIoControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
BOOLEAN NTAPI ScsiClassInterpretSenseInfo (IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
 
NTSTATUS NTAPI ScsiClassIoComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ScsiClassIoCompleteAssociated (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
ULONG NTAPI ScsiClassModeSense (IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
 
ULONG NTAPI ScsiClassQueryTimeOutRegistryValue (IN PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI ScsiClassReadDriveCapacity (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI ScsiClassReleaseQueue (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ScsiClassSendSrbAsynchronous (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
 
NTSTATUS NTAPI ScsiClassSendSrbSynchronous (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
 
VOID NTAPI ScsiClassSplitRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG MaximumBytes)
 
NTSTATUS NTAPI ScsiClassCheckVerifyComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 

Variables

IO_COMPLETION_ROUTINE ScsiClassAsynchronousCompletion
 

Macro Definition Documentation

◆ DEV_NO_12BYTE_CDB

#define DEV_NO_12BYTE_CDB   0x00000008

Definition at line 42 of file class2.h.

◆ DEV_SAFE_START_UNIT

#define DEV_SAFE_START_UNIT   0x00000004

Definition at line 35 of file class2.h.

◆ DEV_USE_SCSI1

#define DEV_USE_SCSI1   0x00000002

Definition at line 28 of file class2.h.

◆ DEV_WRITE_CACHE

#define DEV_WRITE_CACHE   0x00000001

Definition at line 21 of file class2.h.

◆ MAXIMUM_RETRIES

#define MAXIMUM_RETRIES   15

Definition at line 14 of file class2.h.

◆ RETRY_WAIT

#define RETRY_WAIT   2000000 /* 200 ms in units of 100 ns */

Definition at line 15 of file class2.h.

Typedef Documentation

◆ CLASS_INIT_DATA

◆ COMPLETION_CONTEXT

◆ DEVICE_EXTENSION

◆ PCLASS_CREATE_CLOSE

typedef NTSTATUS(NTAPI * PCLASS_CREATE_CLOSE) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

Definition at line 76 of file class2.h.

◆ PCLASS_DEVICE_CALLBACK

typedef BOOLEAN(NTAPI * PCLASS_DEVICE_CALLBACK) (IN PINQUIRYDATA)

Definition at line 54 of file class2.h.

◆ PCLASS_DEVICE_CONTROL

typedef NTSTATUS(NTAPI * PCLASS_DEVICE_CONTROL) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

Definition at line 68 of file class2.h.

◆ PCLASS_FIND_DEVICES

Definition at line 61 of file class2.h.

◆ PCLASS_INIT_DATA

◆ PCLASS_READ_WRITE

typedef NTSTATUS(NTAPI * PCLASS_READ_WRITE) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

Definition at line 57 of file class2.h.

◆ PCLASS_SHUTDOWN_FLUSH

typedef NTSTATUS(NTAPI * PCLASS_SHUTDOWN_FLUSH) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

Definition at line 72 of file class2.h.

◆ PCOMPLETION_CONTEXT

◆ PDEVICE_EXTENSION

◆ Retry

Definition at line 49 of file class2.h.

◆ Srb

Definition at line 49 of file class2.h.

◆ Status

Definition at line 49 of file class2.h.

Function Documentation

◆ ScsiClassAsynchronousCompletion()

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

◆ ScsiClassBuildRequest()

VOID NTAPI ScsiClassBuildRequest ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

◆ ScsiClassCheckVerifyComplete()

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

Definition at line 4910 of file class2.c.

4939 {
4941  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4942  PDEVICE_EXTENSION physicalExtension =
4943  deviceExtension->PhysicalDevice->DeviceExtension;
4944  PIRP originalIrp;
4945 
4946  ASSERT(*(PULONG)deviceExtension != '2slc');
4947  ASSERT(*(PULONG)physicalExtension != '2slc');
4948 
4949  originalIrp = irpStack->Parameters.Others.Argument1;
4950 
4951  //
4952  // Copy the media change count and status
4953  //
4954 
4955  *((PULONG) (originalIrp->AssociatedIrp.SystemBuffer)) =
4956  physicalExtension->MediaChangeCount;
4957 
4958  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change count for"
4959  "device %d is %d\n",
4960  physicalExtension->DeviceNumber,
4961  physicalExtension->MediaChangeCount));
4962 
4963  originalIrp->IoStatus.Status = Irp->IoStatus.Status;
4964  originalIrp->IoStatus.Information = sizeof(ULONG);
4965 
4966  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
4967 
4968  IoFreeIrp(Irp);
4969 
4971 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
IO_STATUS_BLOCK IoStatus
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#define ASSERT(a)
Definition: mode.c:45
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
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:3107

Referenced by ScsiClassDeviceControl().

◆ ScsiClassClaimDevice()

NTSTATUS NTAPI ScsiClassClaimDevice ( IN PDEVICE_OBJECT  PortDeviceObject,
IN PSCSI_INQUIRY_DATA  LunInfo,
IN BOOLEAN  Release,
OUT PDEVICE_OBJECT *NewPortDeviceObject  OPTIONAL 
)

Definition at line 4489 of file class2.c.

4520 {
4521  IO_STATUS_BLOCK ioStatus;
4522  PIRP irp;
4523  PIO_STACK_LOCATION irpStack;
4524  KEVENT event;
4525  NTSTATUS status;
4526  SCSI_REQUEST_BLOCK srb;
4527 
4528  PAGED_CODE();
4529 
4530  if (NewPortDeviceObject != NULL) {
4531  *NewPortDeviceObject = NULL;
4532  }
4533 
4534  //
4535  // Clear the SRB fields.
4536  //
4537 
4538  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
4539 
4540  //
4541  // Write length to SRB.
4542  //
4543 
4545 
4546  //
4547  // Set SCSI bus address.
4548  //
4549 
4550  srb.PathId = LunInfo->PathId;
4551  srb.TargetId = LunInfo->TargetId;
4552  srb.Lun = LunInfo->Lun;
4553 
4556 
4557  //
4558  // Set the event object to the unsignaled state.
4559  // It will be used to signal request completion.
4560  //
4561 
4563 
4564  //
4565  // Build synchronous request with no transfer.
4566  //
4567 
4569  PortDeviceObject,
4570  NULL,
4571  0,
4572  NULL,
4573  0,
4574  TRUE,
4575  &event,
4576  &ioStatus);
4577 
4578  if (irp == NULL) {
4579 
4580  DebugPrint((1, "ScsiClassClaimDevice: Can't allocate Irp\n"));
4582  }
4583 
4584  irpStack = IoGetNextIrpStackLocation(irp);
4585 
4586  //
4587  // Save SRB address in next stack for port driver.
4588  //
4589 
4590  irpStack->Parameters.Scsi.Srb = &srb;
4591 
4592  //
4593  // Set up IRP Address.
4594  //
4595 
4596  srb.OriginalRequest = irp;
4597 
4598  //
4599  // Call the port driver with the request and wait for it to complete.
4600  //
4601 
4602  status = IoCallDriver(PortDeviceObject, irp);
4603  if (status == STATUS_PENDING) {
4604 
4606  status = ioStatus.Status;
4607  }
4608 
4609  //
4610  // If this is a release request, then just decrement the reference count
4611  // and return. The status does not matter.
4612  //
4613 
4614  if (Release) {
4615 
4616  //ObDereferenceObject(PortDeviceObject);
4617  return STATUS_SUCCESS;
4618  }
4619 
4620  if (!NT_SUCCESS(status)) {
4621  return status;
4622  }
4623 
4624  ASSERT(srb.DataBuffer != NULL);
4625 
4626  //
4627  // Reference the new port driver object so that it will not go away while
4628  // it is being used.
4629  //
4630 
4632  0,
4633  NULL,
4634  KernelMode );
4635 
4636  if (!NT_SUCCESS(status)) {
4637 
4638  return status;
4639  }
4641 
4642  //
4643  // Return the new port device object pointer.
4644  //
4645 
4646  if (NewPortDeviceObject != NULL) {
4647  *NewPortDeviceObject = srb.DataBuffer;
4648  }
4649 
4650  return status;
4651 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID OriginalRequest
Definition: srb.h:258
#define TRUE
Definition: types.h:120
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 FALSE
Definition: types.h:117
#define SRB_FUNCTION_RELEASE_DEVICE
Definition: srb.h:313
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
UCHAR TargetId
Definition: srb.h:246
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
UCHAR Function
Definition: srb.h:242
#define ObDereferenceObject
Definition: obfuncs.h:203
USHORT Length
Definition: srb.h:241
struct _cl_event * event
Definition: glext.h:7739
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
_In_ BOOLEAN Release
Definition: cdrom.h:920
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
#define NULL
Definition: types.h:112
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:262
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
static SERVICE_STATUS status
Definition: service.c:31
FxIrp * irp
#define PAGED_CODE()
Definition: ps.c:97

◆ ScsiClassCreateDeviceObject()

NTSTATUS NTAPI ScsiClassCreateDeviceObject ( IN PDRIVER_OBJECT  DriverObject,
IN PCCHAR  ObjectNameBuffer,
IN PDEVICE_OBJECT PhysicalDeviceObject  OPTIONAL,
IN OUT PDEVICE_OBJECT DeviceObject,
IN PCLASS_INIT_DATA  InitializationData 
)

◆ ScsiClassDeviceControl()

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

◆ ScsiClassFindModePage()

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

Definition at line 3296 of file class2.c.

3325 {
3326  PUCHAR limit;
3327  ULONG parameterHeaderLength;
3328 
3329  limit = (PUCHAR)ModeSenseBuffer + Length;
3330  parameterHeaderLength = (Use6Byte) ? sizeof(MODE_PARAMETER_HEADER) : sizeof(MODE_PARAMETER_HEADER10);
3331 
3332 
3333  //
3334  // Skip the mode select header and block descriptors.
3335  //
3336 
3337  if (Length < parameterHeaderLength) {
3338  return(NULL);
3339  }
3340 
3341 
3342 
3343  ModeSenseBuffer += parameterHeaderLength + ((Use6Byte) ? ((PMODE_PARAMETER_HEADER) ModeSenseBuffer)->BlockDescriptorLength :
3344  ((PMODE_PARAMETER_HEADER10) ModeSenseBuffer)->BlockDescriptorLength[1]);
3345 
3346  //
3347  // ModeSenseBuffer now points at pages. Walk the pages looking for the
3348  // requested page until the limit is reached.
3349  //
3350 
3351 
3352  while ((PUCHAR)ModeSenseBuffer < limit) {
3353 
3354  if (((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageCode == PageMode) {
3355  return(ModeSenseBuffer);
3356  }
3357 
3358  //
3359  // Advance to the next page.
3360  //
3361 
3362  ModeSenseBuffer += ((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageLength + 2;
3363  }
3364 
3365  return(NULL);
3366 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1325
struct _MODE_DISCONNECT_PAGE * PMODE_DISCONNECT_PAGE
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ size_t _In_ UCHAR _In_ BOOLEAN Use6Byte
Definition: cdrom.h:1325
GLint limit
Definition: glext.h:10326
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
_In_ ULONG _In_ UCHAR PageCode
Definition: cdrom.h:1316
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

Referenced by CdRomDeviceControlCompletion(), CdRomSetVolumeIntermediateCompletion(), DisableWriteCache(), and IsFloppyDevice().

◆ ScsiClassFindUnclaimedDevices()

ULONG NTAPI ScsiClassFindUnclaimedDevices ( IN PCLASS_INIT_DATA  InitializationData,
OUT PSCSI_ADAPTER_BUS_INFO  AdapterInformation 
)

◆ ScsiClassGetCapabilities()

NTSTATUS NTAPI ScsiClassGetCapabilities ( IN PDEVICE_OBJECT  PortDeviceObject,
OUT PIO_SCSI_CAPABILITIES PortCapabilities 
)

Definition at line 531 of file class2.c.

560 {
561  PIRP irp;
562  IO_STATUS_BLOCK ioStatus;
563  KEVENT event;
565 
566  PAGED_CODE();
567 
568  //
569  // Create notification event object to be used to signal the
570  // request completion.
571  //
572 
574 
575  //
576  // Build the synchronous request to be sent to the port driver
577  // to perform the request.
578  //
579 
581  PortDeviceObject,
582  NULL,
583  0,
584  PortCapabilities,
585  sizeof(PVOID),
586  FALSE,
587  &event,
588  &ioStatus);
589 
590  if (irp == NULL) {
592  }
593 
594  //
595  // Pass request to port driver and wait for request to complete.
596  //
597 
598  status = IoCallDriver(PortDeviceObject, irp);
599 
600  if (status == STATUS_PENDING) {
602  return(ioStatus.Status);
603  }
604 
605  return status;
606 
607 } // end ScsiClassGetCapabilities()
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _cl_event * event
Definition: glext.h:7739
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NULL
Definition: types.h:112
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 IOCTL_SCSI_GET_CAPABILITIES
Definition: scsi_port.h:50
static SERVICE_STATUS status
Definition: service.c:31
FxIrp * irp
#define PAGED_CODE()
Definition: ps.c:97

◆ ScsiClassGetInquiryData()

NTSTATUS NTAPI ScsiClassGetInquiryData ( IN PDEVICE_OBJECT  PortDeviceObject,
OUT PSCSI_ADAPTER_BUS_INFO ConfigInfo 
)

Definition at line 612 of file class2.c.

643 {
644  PIRP irp;
645  IO_STATUS_BLOCK ioStatus;
646  KEVENT event;
649 
650  PAGED_CODE();
651 
653  *ConfigInfo = buffer;
654 
655  if (buffer == NULL) {
657  }
658 
659  //
660  // Create notification event object to be used to signal the inquiry
661  // request completion.
662  //
663 
665 
666  //
667  // Build the synchronous request to be sent to the port driver
668  // to perform the inquiries.
669  //
670 
672  PortDeviceObject,
673  NULL,
674  0,
675  buffer,
677  FALSE,
678  &event,
679  &ioStatus);
680 
681  if (irp == NULL) {
683  }
684 
685  //
686  // Pass request to port driver and wait for request to complete.
687  //
688 
689  status = IoCallDriver(PortDeviceObject, irp);
690 
691  if (status == STATUS_PENDING) {
693  status = ioStatus.Status;
694  }
695 
696  if (!NT_SUCCESS(status)) {
697 
698  //
699  // Free the buffer on an error.
700  //
701 
703  *ConfigInfo = NULL;
704 
705  }
706 
707  return status;
708 
709 } // end ScsiClassGetInquiryData()
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
GLuint buffer
Definition: glext.h:5915
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
#define INQUIRY_DATA_SIZE
Definition: class2.c:29
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _cl_event * event
Definition: glext.h:7739
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define IOCTL_SCSI_GET_INQUIRY_DATA
Definition: scsi_port.h:49
#define NULL
Definition: types.h:112
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
static SERVICE_STATUS status
Definition: service.c:31
FxIrp * irp
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PAGED_CODE()
Definition: ps.c:97

◆ ScsiClassInitialize()

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

Definition at line 160 of file class2.c.

185 {
186 
187 
189  ULONG portNumber = 0;
190  PDEVICE_OBJECT portDeviceObject;
192  STRING deviceNameString;
193  UNICODE_STRING unicodeDeviceName;
194  PFILE_OBJECT fileObject;
195  CCHAR deviceNameBuffer[256];
196  BOOLEAN deviceFound = FALSE;
197 
198  DebugPrint((3,"\n\nSCSI Class Driver\n"));
199 
200  //
201  // Validate the length of this structure. This is effectively a
202  // version check.
203  //
204 
205  if (InitializationData->InitializationDataSize > sizeof(CLASS_INIT_DATA)) {
206 
207  DebugPrint((0,"ScsiClassInitialize: Class driver wrong version\n"));
209  }
210 
211  //
212  // Check that each required entry is not NULL. Note that Shutdown, Flush and Error
213  // are not required entry points.
214  //
215 
216  if ((!InitializationData->ClassFindDevices) ||
217  (!InitializationData->ClassDeviceControl) ||
218  (!((InitializationData->ClassReadWriteVerification) ||
219  (InitializationData->ClassStartIo)))) {
220 
221  DebugPrint((0,
222  "ScsiClassInitialize: Class device-specific driver missing required entry\n"));
223 
225  }
226 
227  //
228  // Update driver object with entry points.
229  //
230 
233  DriverObject->MajorFunction[IRP_MJ_READ] = ScsiClassReadWrite;
234  DriverObject->MajorFunction[IRP_MJ_WRITE] = ScsiClassReadWrite;
235  DriverObject->MajorFunction[IRP_MJ_PNP] = ScsiClassPlugPlay;
240 
241  if (InitializationData->ClassStartIo) {
242  DriverObject->DriverStartIo = InitializationData->ClassStartIo;
243  }
244 
245  //
246  // Open port driver controller device objects by name.
247  //
248 
249  do {
250 
251  sprintf(deviceNameBuffer, "\\Device\\ScsiPort%lu", portNumber);
252 
253  DebugPrint((2, "ScsiClassInitialize: Open Port %s\n", deviceNameBuffer));
254 
255  RtlInitString(&deviceNameString, deviceNameBuffer);
256 
257  status = RtlAnsiStringToUnicodeString(&unicodeDeviceName,
258  &deviceNameString,
259  TRUE);
260 
261  if (!NT_SUCCESS(status)){
262  break;
263  }
264 
265  status = IoGetDeviceObjectPointer(&unicodeDeviceName,
267  &fileObject,
268  &portDeviceObject);
269 
270  if (NT_SUCCESS(status)) {
271 
272  //
273  // Call the device-specific driver's FindDevice routine.
274  //
275 
277  portDeviceObject, portNumber)) {
278 
279  deviceFound = TRUE;
280  }
281  }
282 
283  //
284  // Check next SCSI adapter.
285  //
286 
287  portNumber++;
288 
289  } while(NT_SUCCESS(status));
290 
291  return deviceFound ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;
292 }
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
NTSTATUS NTAPI ScsiClassDeviceControlDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class2.c:3559
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696
#define IRP_MJ_FLUSH_BUFFERS
NTSTATUS NTAPI ScsiClassInternalIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:4656
#define IRP_MJ_SHUTDOWN
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI ScsiClassCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:297
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
NTSTATUS NTAPI ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:347
NTSTATUS NTAPI ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:4264
#define IRP_MJ_SCSI
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_In_ PVOID Argument2
Definition: classpnp.h:721
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
char CCHAR
Definition: typedefs.h:51
* PFILE_OBJECT
Definition: iotypes.h:1978
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
std::wstring STRING
Definition: fontsub.cpp:33
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:721
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS NTAPI ScsiClassPlugPlay(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:136
unsigned int ULONG
Definition: retypes.h:1
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: ps.c:97

Referenced by DriverEntry().

◆ ScsiClassInitializeSrbLookasideList()

VOID NTAPI ScsiClassInitializeSrbLookasideList ( IN PDEVICE_EXTENSION  DeviceExtension,
IN ULONG  NumberElements 
)

Definition at line 4779 of file class2.c.

4803 {
4804  ExInitializeNPagedLookasideList(&DeviceExtension->SrbLookasideListHead,
4805  NULL,
4806  NULL,
4809  'HscS',
4811 
4812 }
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
unsigned short USHORT
Definition: pedump.c:61
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
#define NULL
Definition: types.h:112
_In_ ULONG NumberElements
Definition: classpnp.h:1137

Referenced by CreateCdRomDeviceObject(), CreateDiskDeviceObject(), CreatePartitionDeviceObjects(), and UpdateDeviceObjects().

◆ ScsiClassInternalIoControl()

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

Definition at line 4656 of file class2.c.

4685 {
4687  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4688  PSCSI_REQUEST_BLOCK srb;
4689 
4690  ASSERT(*(PULONG)deviceExtension != '2slc');
4691 
4692  //
4693  // Get a pointer to the SRB.
4694  //
4695 
4696  srb = irpStack->Parameters.Scsi.Srb;
4697 
4698  //
4699  // Set SCSI bus address.
4700  //
4701 
4702  srb->PathId = deviceExtension->PathId;
4703  srb->TargetId = deviceExtension->TargetId;
4704  srb->Lun = deviceExtension->Lun;
4705 
4706  //
4707  // NOTICE: The SCSI-II specification indicates that this field should be
4708  // zero; however, some target controllers ignore the logical unit number
4709  // in the IDENTIFY message and only look at the logical unit number field
4710  // in the CDB.
4711  //
4712 
4713  srb->Cdb[1] |= deviceExtension->Lun << 5;
4714 
4715  //
4716  // Set the parameters in the next stack location.
4717  //
4718 
4719  irpStack = IoGetNextIrpStackLocation(Irp);
4720 
4721  irpStack->Parameters.Scsi.Srb = srb;
4722  irpStack->MajorFunction = IRP_MJ_SCSI;
4723  irpStack->MinorFunction = IRP_MN_SCSI_CLASS;
4724 
4726  return IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4727 }
UCHAR Cdb[16]
Definition: srb.h:271
#define TRUE
Definition: types.h:120
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
NTSTATUS NTAPI ClassIoCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4731
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
UCHAR TargetId
Definition: srb.h:246
#define ASSERT(a)
Definition: mode.c:45
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
UCHAR PathId
Definition: srb.h:245
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_SCSI_CLASS
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107

◆ ScsiClassInterpretSenseInfo()

BOOLEAN NTAPI ScsiClassInterpretSenseInfo ( IN PDEVICE_OBJECT  DeviceObject,
IN PSCSI_REQUEST_BLOCK  Srb,
IN UCHAR  MajorFunctionCode,
IN ULONG  IoDeviceCode,
IN ULONG  RetryCount,
OUT NTSTATUS Status 
)

Definition at line 2148 of file class2.c.

2184 {
2185  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2186  PDEVICE_EXTENSION physicalExtension = deviceExtension->PhysicalDevice->DeviceExtension;
2187  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
2188  BOOLEAN retry = TRUE;
2189  BOOLEAN logError = FALSE;
2190  ULONG badSector = 0;
2191  ULONG uniqueId = 0;
2192  NTSTATUS logStatus;
2193  ULONG readSector;
2194  ULONG index;
2195  PIO_ERROR_LOG_PACKET errorLogEntry;
2196 #if DBG
2197  ULONG i;
2198 #endif
2199 
2200  ASSERT(*(PULONG)deviceExtension != '2slc');
2201 
2202  //
2203  // Check that request sense buffer is valid.
2204  //
2205 
2206 #if DBG
2207  DebugPrint((3, "Opcode %x\nParameters: ",Srb->Cdb[0]));
2208  for (i = 1; i < 12; i++) {
2209  DebugPrint((3,"%x ",Srb->Cdb[i]));
2210  }
2211  DebugPrint((3,"\n"));
2212 #endif
2213 
2214  if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID &&
2215  Srb->SenseInfoBufferLength >= FIELD_OFFSET(SENSE_DATA, CommandSpecificInformation)) {
2216 
2217  DebugPrint((1,"ScsiClassInterpretSenseInfo: Error code is %x\n",
2218  senseBuffer->ErrorCode));
2219  DebugPrint((1,"ScsiClassInterpretSenseInfo: Sense key is %x\n",
2220  senseBuffer->SenseKey));
2221  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code is %x\n",
2222  senseBuffer->AdditionalSenseCode));
2223  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code qualifier is %x\n",
2224  senseBuffer->AdditionalSenseCodeQualifier));
2225 
2226  //
2227  // Zero the additional sense code and additional sense code qualifier
2228  // if they were not returned by the device.
2229  //
2230 
2231  readSector = senseBuffer->AdditionalSenseLength +
2232  FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
2233 
2234  if (readSector > Srb->SenseInfoBufferLength) {
2235  readSector = Srb->SenseInfoBufferLength;
2236  }
2237 
2238  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCode)) {
2239  senseBuffer->AdditionalSenseCode = 0;
2240  }
2241 
2243  senseBuffer->AdditionalSenseCodeQualifier = 0;
2244  }
2245 
2246  switch (senseBuffer->SenseKey & 0xf) {
2247 
2248  case SCSI_SENSE_NOT_READY:
2249 
2250  DebugPrint((1,"ScsiClassInterpretSenseInfo: Device not ready\n"));
2252 
2253  switch (senseBuffer->AdditionalSenseCode) {
2254 
2256 
2257  DebugPrint((1,"ScsiClassInterpretSenseInfo: Lun not ready\n"));
2258 
2259  switch (senseBuffer->AdditionalSenseCodeQualifier) {
2260 
2262 
2263  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2264  " In process of becoming ready\n"));
2265  break;
2266 
2268 
2269  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2270  " Manual intervention required\n"));
2272  retry = FALSE;
2273  break;
2274 
2276 
2277  DebugPrint((1, "ScsiClassInterpretSenseInfo: Format in progress\n"));
2278  retry = FALSE;
2279  break;
2280 
2282 
2283  default:
2284 
2285  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2286  " Initializing command required\n"));
2287 
2288  //
2289  // This sense code/additional sense code
2290  // combination may indicate that the device
2291  // needs to be started. Send an start unit if this
2292  // is a disk device.
2293  //
2294 
2295  if (deviceExtension->DeviceFlags & DEV_SAFE_START_UNIT) {
2297  }
2298 
2299  break;
2300 
2301  } // end switch (senseBuffer->AdditionalSenseCodeQualifier)
2302 
2303  break;
2304 
2306 
2307  DebugPrint((1,
2308  "ScsiClassInterpretSenseInfo:"
2309  " No Media in device.\n"));
2311  retry = FALSE;
2312 
2313  //
2314  // signal autorun that there isn't any media in the device
2315  //
2316 
2317  if((deviceExtension->MediaChangeEvent != NULL)&&
2318  (!deviceExtension->MediaChangeNoMedia)) {
2319  KeSetEvent(deviceExtension->MediaChangeEvent,
2320  (KPRIORITY) 0,
2321  FALSE);
2322  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2323  "Detected No Media In Device "
2324  "[irp = 0x%lx]\n", Srb->OriginalRequest));
2325  deviceExtension->MediaChangeNoMedia = TRUE;
2326  }
2327 
2328  break;
2329  } // end switch (senseBuffer->AdditionalSenseCode)
2330 
2331  break;
2332 
2334 
2335  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media write protected\n"));
2337  retry = FALSE;
2338  break;
2339 
2341 
2342  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bad media\n"));
2344 
2345  retry = FALSE;
2346  logError = TRUE;
2347  uniqueId = 256;
2348  logStatus = 0;//IO_ERR_BAD_BLOCK;
2349  break;
2350 
2352 
2353  DebugPrint((1,"ScsiClassInterpretSenseInfo: Hardware error\n"));
2355 
2356  logError = TRUE;
2357  uniqueId = 257;
2358  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2359 
2360  break;
2361 
2363 
2364  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal SCSI request\n"));
2366 
2367  switch (senseBuffer->AdditionalSenseCode) {
2368 
2370  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal command\n"));
2371  retry = FALSE;
2372  break;
2373 
2375  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal block address\n"));
2377  retry = FALSE;
2378  break;
2379 
2381  DebugPrint((1,"ScsiClassInterpretSenseInfo: Invalid LUN\n"));
2383  retry = FALSE;
2384  break;
2385 
2387  DebugPrint((1,"ScsiClassInterpretSenseInfo: Music area\n"));
2388  retry = FALSE;
2389  break;
2390 
2392  DebugPrint((1,"ScsiClassInterpretSenseInfo: Data area\n"));
2393  retry = FALSE;
2394  break;
2395 
2397  DebugPrint((1, "ScsiClassInterpretSenseInfo: Volume overflow\n"));
2398  retry = FALSE;
2399  break;
2400 
2402  DebugPrint((1, "ScsiClassInterpretSenseInfo: Invalid CDB\n"));
2403 
2404  //
2405  // Check if write cache enabled.
2406  //
2407 
2408  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
2409 
2410  //
2411  // Assume FUA is not supported.
2412  //
2413 
2414  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
2415  retry = TRUE;
2416 
2417  } else {
2418  retry = FALSE;
2419  }
2420 
2421  break;
2422 
2423  } // end switch (senseBuffer->AdditionalSenseCode)
2424 
2425  break;
2426 
2428 
2429  switch (senseBuffer->AdditionalSenseCode) {
2431  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media changed\n"));
2432 
2433  if(deviceExtension->MediaChangeEvent != NULL) {
2434 
2435  KeSetEvent(deviceExtension->MediaChangeEvent,
2436  (KPRIORITY) 0,
2437  FALSE);
2438  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2439  "New Media Found - Setting MediaChanged event"
2440  " [irp = 0x%lx]\n", Srb->OriginalRequest));
2441  deviceExtension->MediaChangeNoMedia = FALSE;
2442 
2443  }
2444  break;
2445 
2447  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bus reset\n"));
2448  break;
2449 
2450  default:
2451  DebugPrint((1,"ScsiClassInterpretSenseInfo: Unit attention\n"));
2452  break;
2453 
2454  } // end switch (senseBuffer->AdditionalSenseCode)
2455 
2456  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
2457  DeviceObject->Vpb->Flags & VPB_MOUNTED) {
2458 
2459  //
2460  // Set bit to indicate that media may have changed
2461  // and volume needs verification.
2462  //
2463 
2464  DeviceObject->Flags |= DO_VERIFY_VOLUME;
2465 
2467  retry = FALSE;
2468 
2469  } else {
2470 
2472 
2473  }
2474 
2475  //
2476  // A media change may have occured so increment the change
2477  // count for the physical device
2478  //
2479 
2480  physicalExtension->MediaChangeCount++;
2481 
2482  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change "
2483  "count for device %d is %d\n",
2484  physicalExtension->DeviceNumber,
2485  physicalExtension->MediaChangeCount));
2486 
2487  break;
2488 
2490 
2491  DebugPrint((1,"ScsiClassInterpretSenseInfo: Command aborted\n"));
2493  break;
2494 
2496 
2497  DebugPrint((1,"ScsiClassInterpretSenseInfo: Recovered error\n"));
2499  retry = FALSE;
2500  logError = TRUE;
2501  uniqueId = 258;
2502 
2503  switch(senseBuffer->AdditionalSenseCode) {
2506  logStatus = 0;//IO_ERR_SEEK_ERROR;
2507  break;
2508 
2511  logStatus = 0;//IO_RECOVERED_VIA_ECC;
2512  break;
2513 
2514  default:
2515  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2516  break;
2517 
2518  } // end switch(senseBuffer->AdditionalSenseCode)
2519 
2520  if (senseBuffer->IncorrectLength) {
2521 
2522  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2524  }
2525 
2526  break;
2527 
2528  case SCSI_SENSE_NO_SENSE:
2529 
2530  //
2531  // Check other indicators.
2532  //
2533 
2534  if (senseBuffer->IncorrectLength) {
2535 
2536  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2538  retry = FALSE;
2539 
2540  } else {
2541 
2542  DebugPrint((1, "ScsiClassInterpretSenseInfo: No specific sense key\n"));
2544  retry = TRUE;
2545  }
2546 
2547  break;
2548 
2549  default:
2550 
2551  DebugPrint((1, "ScsiClassInterpretSenseInfo: Unrecognized sense code\n"));
2553  break;
2554 
2555  } // end switch (senseBuffer->SenseKey & 0xf)
2556 
2557  //
2558  // Try to determine the bad sector from the inquiry data.
2559  //
2560 
2561  if ((((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_READ ||
2562  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_VERIFY ||
2563  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_WRITE)) {
2564 
2565  for (index = 0; index < 4; index++) {
2566  badSector = (badSector << 8) | senseBuffer->Information[index];
2567  }
2568 
2569  readSector = 0;
2570  for (index = 0; index < 4; index++) {
2571  readSector = (readSector << 8) | Srb->Cdb[index+2];
2572  }
2573 
2574  index = (((PCDB)Srb->Cdb)->CDB10.TransferBlocksMsb << 8) |
2575  ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb;
2576 
2577  //
2578  // Make sure the bad sector is within the read sectors.
2579  //
2580 
2581  if (!(badSector >= readSector && badSector < readSector + index)) {
2582  badSector = readSector;
2583  }
2584  }
2585 
2586  } else {
2587 
2588  //
2589  // Request sense buffer not valid. No sense information
2590  // to pinpoint the error. Return general request fail.
2591  //
2592 
2593  DebugPrint((1,"ScsiClassInterpretSenseInfo: Request sense info not valid. SrbStatus %2x\n",
2594  SRB_STATUS(Srb->SrbStatus)));
2595  retry = TRUE;
2596 
2597  switch (SRB_STATUS(Srb->SrbStatus)) {
2600  case SRB_STATUS_NO_DEVICE:
2601  case SRB_STATUS_NO_HBA:
2604  retry = FALSE;
2605  break;
2606 
2608  case SRB_STATUS_ABORTED:
2609  case SRB_STATUS_TIMEOUT:
2610 
2611  //
2612  // Update the error count for the device.
2613  //
2614 
2615  deviceExtension->ErrorCount++;
2617  break;
2618 
2620  logError = TRUE;
2621  logStatus = 0;//IO_ERR_NOT_READY;
2622  uniqueId = 260;
2624  retry = FALSE;
2625  break;
2626 
2629  retry = FALSE;
2630  break;
2631 
2633 
2634  //
2635  // Update the error count for the device.
2636  //
2637 
2638  deviceExtension->ErrorCount++;
2640 
2641  //
2642  // If there was phase sequence error then limit the number of
2643  // retries.
2644  //
2645 
2646  if (RetryCount > 1 ) {
2647  retry = FALSE;
2648  }
2649 
2650  break;
2651 
2653 
2654  //
2655  // If the status needs verification bit is set. Then set
2656  // the status to need verification and no retry; otherwise,
2657  // just retry the request.
2658  //
2659 
2660  if (DeviceObject->Flags & DO_VERIFY_VOLUME ) {
2661 
2663  retry = FALSE;
2664  } else {
2666  }
2667 
2668  break;
2669 
2671 
2672  //
2673  // An invalid request was attempted.
2674  //
2675 
2677  retry = FALSE;
2678  break;
2679 
2682 
2683  //
2684  // Update the error count for the device.
2685  //
2686 
2687  deviceExtension->ErrorCount++;
2688 
2689  //
2690  // Fall through to below.
2691  //
2692 
2693  case SRB_STATUS_BUS_RESET:
2695  break;
2696 
2697  case SRB_STATUS_ERROR:
2698 
2700  if (Srb->ScsiStatus == 0) {
2701 
2702  //
2703  // This is some strange return code. Update the error
2704  // count for the device.
2705  //
2706 
2707  deviceExtension->ErrorCount++;
2708 
2709  } if (Srb->ScsiStatus == SCSISTAT_BUSY) {
2710 
2712 
2713  } if (Srb->ScsiStatus == SCSISTAT_RESERVATION_CONFLICT) {
2714 
2716  retry = FALSE;
2717 
2718  }
2719 
2720  break;
2721 
2722  default:
2723  logError = TRUE;
2724  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2725  uniqueId = 259;
2727  break;
2728 
2729  }
2730 
2731  //
2732  // If the error count has exceeded the error limit, then disable
2733  // any tagged queuing, multiple requests per lu queueing
2734  // and synchronous data transfers.
2735  //
2736 
2737  if (deviceExtension->ErrorCount == 4) {
2738 
2739  //
2740  // Clearing the no queue freeze flag prevents the port driver
2741  // from sending multiple requests per logical unit.
2742  //
2743 
2744  deviceExtension->SrbFlags &= ~(SRB_FLAGS_QUEUE_ACTION_ENABLE |
2746 
2747  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2748  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling tagged queuing and synchronous data tranfers.\n"));
2749 
2750  } else if (deviceExtension->ErrorCount == 8) {
2751 
2752  //
2753  // If a second threshold is reached, disable disconnects.
2754  //
2755 
2756  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
2757  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling disconnects.\n"));
2758  }
2759  }
2760 
2761  //
2762  // If there is a class specific error handler call it.
2763  //
2764 
2765  if (deviceExtension->ClassError != NULL) {
2766 
2767  deviceExtension->ClassError(DeviceObject,
2768  Srb,
2769  Status,
2770  &retry);
2771  }
2772 
2773  //
2774  // Log an error if necessary.
2775  //
2776 
2777  if (logError) {
2778 
2780  DeviceObject,
2781  sizeof(IO_ERROR_LOG_PACKET) + 5 * sizeof(ULONG));
2782 
2783  if (errorLogEntry == NULL) {
2784 
2785  //
2786  // Return if no packet could be allocated.
2787  //
2788 
2789  return retry;
2790 
2791  }
2792 
2793  if (retry && RetryCount < MAXIMUM_RETRIES) {
2794  errorLogEntry->FinalStatus = STATUS_SUCCESS;
2795  } else {
2796  errorLogEntry->FinalStatus = *Status;
2797  }
2798 
2799  //
2800  // Calculate the device offset if there is a geometry.
2801  //
2802 
2803  if (deviceExtension->DiskGeometry != NULL) {
2804 
2805  errorLogEntry->DeviceOffset.QuadPart = (LONGLONG) badSector;
2806  errorLogEntry->DeviceOffset = RtlExtendedIntegerMultiply(
2807  errorLogEntry->DeviceOffset,
2808  deviceExtension->DiskGeometry->Geometry.BytesPerSector);
2809  }
2810 
2811  errorLogEntry->ErrorCode = logStatus;
2812  errorLogEntry->SequenceNumber = 0;
2813  errorLogEntry->MajorFunctionCode = MajorFunctionCode;
2814  errorLogEntry->IoControlCode = IoDeviceCode;
2815  errorLogEntry->RetryCount = (UCHAR) RetryCount;
2816  errorLogEntry->UniqueErrorValue = uniqueId;
2817  errorLogEntry->DumpDataSize = 6 * sizeof(ULONG);
2818  errorLogEntry->DumpData[0] = Srb->PathId;
2819  errorLogEntry->DumpData[1] = Srb->TargetId;
2820  errorLogEntry->DumpData[2] = Srb->Lun;
2821  errorLogEntry->DumpData[3] = 0;
2822  errorLogEntry->DumpData[4] = Srb->SrbStatus << 8 | Srb->ScsiStatus;
2823 
2824  if (senseBuffer != NULL) {
2825  errorLogEntry->DumpData[5] = senseBuffer->SenseKey << 16 |
2826  senseBuffer->AdditionalSenseCode << 8 |
2827  senseBuffer->AdditionalSenseCodeQualifier;
2828 
2829  }
2830 
2831  //
2832  // Write the error log packet.
2833  //
2834 
2835  IoWriteErrorLogEntry(errorLogEntry);
2836  }
2837 
2838  return retry;
2839 
2840 } // end ScsiClassInterpretSenseInfo()
#define SRB_STATUS_INVALID_REQUEST
Definition: srb.h:338
#define SRB_STATUS_BUS_RESET
Definition: srb.h:345
#define SCSI_SENSEQ_FORMAT_IN_PROGRESS
Definition: cdrw_hw.h:1316
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define SCSISTAT_BUSY
Definition: cdrw_hw.h:1081
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
NTSTATUS FinalStatus
Definition: iotypes.h:1989
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define TRUE
Definition: types.h:120
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_STATUS_REQUEST_FLUSHED
Definition: srb.h:353
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define SCSI_ADSENSE_MUSIC_AREA
Definition: cdrw_hw.h:1282
#define SCSI_ADSENSE_DATA_AREA
Definition: cdrw_hw.h:1283
#define SRB_STATUS_COMMAND_TIMEOUT
Definition: srb.h:343
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:340
#define SRB_STATUS_PHASE_SEQUENCE_FAILURE
Definition: srb.h:351
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define SRB_STATUS_INVALID_TARGET_ID
Definition: srb.h:355
#define SRB_STATUS(Status)
Definition: srb.h:381
#define STATUS_INVALID_BLOCK_LENGTH
Definition: udferr_usr.h:175
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:628
LONG KPRIORITY
Definition: compat.h:662
LARGE_INTEGER DeviceOffset
Definition: iotypes.h:1992
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define SCSI_ADSENSE_VOLUME_OVERFLOW
Definition: cdrw_hw.h:1284
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define SRB_STATUS_ERROR
Definition: srb.h:336
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS ErrorCode
Definition: iotypes.h:1987
#define SCSI_ADSENSE_REC_DATA_NOECC
Definition: cdrw_hw.h:1211
#define SRB_STATUS_PARITY_ERROR
Definition: srb.h:346
#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED
Definition: cdrw_hw.h:1315
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
#define SRB_STATUS_NO_HBA
Definition: srb.h:348
#define SRB_STATUS_ABORTED
Definition: srb.h:334
union _CDB * PCDB
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
GLuint index
Definition: glext.h:6031
UCHAR Information[4]
Definition: cdrw_hw.h:1172
#define DEV_SAFE_START_UNIT
Definition: cdrom.h:139
_In_ UCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR AdditionalSenseCodeQualifier
Definition: scsi.h:3748
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:528
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define SCSI_ADSENSE_SEEK_ERROR
Definition: cdrw_hw.h:1232
#define SCSI_ADSENSE_ILLEGAL_BLOCK
Definition: cdrw_hw.h:1264
#define ASSERT(a)
Definition: mode.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define SCSI_ADSENSE_REC_DATA_ECC
Definition: cdrw_hw.h:1212
#define SCSISTAT_RESERVATION_CONFLICT
Definition: cdrw_hw.h:1084
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR MajorFunctionCode
Definition: classpnp.h:482
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
NTSYSAPI LONGLONG WINAPI RtlExtendedIntegerMultiply(LONGLONG, INT)
#define SCSIOP_VERIFY
Definition: cdrw_hw.h:912
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:388
unsigned char UCHAR
Definition: xmlstorage.h:181
#define index(s, c)
Definition: various.h:29
#define SCSI_ADSENSE_BUS_RESET
Definition: cdrw_hw.h:1289
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
#define SCSI_SENSE_RECOVERED_ERROR
Definition: cdrw_hw.h:1188
#define SCSI_SENSE_ABORTED_COMMAND
Definition: cdrw_hw.h:1198
#define SCSI_SENSE_NO_SENSE
Definition: cdrw_hw.h:1187
#define SRB_STATUS_INVALID_LUN
Definition: srb.h:354
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
VOID NTAPI StartUnit(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:1082
_In_ UCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR AdditionalSenseCode
Definition: scsi.h:3744
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SRB_STATUS_TIMEOUT
Definition: srb.h:341
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
UCHAR IncorrectLength
Definition: cdrw_hw.h:1169
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
struct _IO_ERROR_LOG_PACKET * PIO_ERROR_LOG_PACKET
#define SCSI_ADSENSE_INVALID_LUN
Definition: cdrw_hw.h:1266
#define SCSI_ADSENSE_TRACK_ERROR
Definition: cdrw_hw.h:1231
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_UNEXPECTED_BUS_FREE
Definition: srb.h:350
#define SCSI_SENSE_DATA_PROTECT
Definition: cdrw_hw.h:1194
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
#define SRB_STATUS_INVALID_PATH_ID
Definition: srb.h:339
#define STATUS_SUCCESS
Definition: shellext.h:65
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
#define SCSI_ADSENSE_ILLEGAL_COMMAND
Definition: cdrw_hw.h:1263
#define VPB_MOUNTED
Definition: iotypes.h:1787
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
UCHAR ErrorCode
Definition: cdrw_hw.h:1164
#define SCSI_ADSENSE_INVALID_CDB
Definition: cdrw_hw.h:1265
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG IoDeviceCode
Definition: classpnp.h:482
LONGLONG QuadPart
Definition: typedefs.h:114
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288

◆ ScsiClassIoComplete()

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

Definition at line 1492 of file class2.c.

1523 {
1526  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1527  NTSTATUS status;
1528  BOOLEAN retry;
1529 
1530  ASSERT(*(PULONG)deviceExtension != '2slc');
1531 
1532  //
1533  // Check SRB status for success of completing request.
1534  //
1535 
1536  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1537 
1538  DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
1539 
1540  //
1541  // Release the queue if it is frozen.
1542  //
1543 
1544  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1546  }
1547 
1549  DeviceObject,
1550  srb,
1551  irpStack->MajorFunction,
1552  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1553  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1554  &status);
1555 
1556  //
1557  // If the status is verified required and the this request
1558  // should bypass verify required then retry the request.
1559  //
1560 
1561  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1563 
1565  retry = TRUE;
1566  }
1567 
1568  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1569 
1570  //
1571  // Retry request.
1572  //
1573 
1574  DebugPrint((1, "Retry request %lx\n", Irp));
1577  }
1578  } else {
1579 
1580  //
1581  // Set status for successful request.
1582  //
1583 
1585 
1586  } // end if (SRB_STATUS(srb->SrbStatus) ...
1587 
1588  //
1589  // Return SRB to list.
1590  //
1591 
1592  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1593  srb);
1594 
1595  //
1596  // Set status in completing IRP.
1597  //
1598 
1599  Irp->IoStatus.Status = status;
1600  if ((NT_SUCCESS(status)) && (Irp->Flags & IRP_PAGING_IO)) {
1601  ASSERT(Irp->IoStatus.Information);
1602  }
1603 
1604  //
1605  // Set the hard error if necessary.
1606  //
1607 
1609 
1610  //
1611  // Store DeviceObject for filesystem, and clear
1612  // in IoStatus.Information field.
1613  //
1614 
1616  Irp->IoStatus.Information = 0;
1617  }
1618 
1619  //
1620  // If pending has be returned for this irp then mark the current stack as
1621  // pending.
1622  //
1623 
1624  if (Irp->PendingReturned) {
1626  }
1627 
1628  if (deviceExtension->ClassStartIo) {
1629  if (irpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL) {
1631  }
1632  }
1633 
1634  return status;
1635 
1636 } // end ScsiClassIoComplete()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define TRUE
Definition: types.h:120
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
Definition: class2.c:2845
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
_In_ PIRP Irp
Definition: csq.h:116
unsigned char BOOLEAN
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
#define PtrToUlong(u)
Definition: config.h:107
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
unsigned int * PULONG
Definition: retypes.h:1
#define IRP_PAGING_IO
struct tagContext Context
Definition: acpixf.h:1034
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

◆ ScsiClassIoCompleteAssociated()

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

Definition at line 1641 of file class2.c.

1675 {
1678  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1679  PIRP originalIrp = Irp->AssociatedIrp.MasterIrp;
1680  LONG irpCount;
1681  NTSTATUS status;
1682  BOOLEAN retry;
1683 
1684  ASSERT(*(PULONG)deviceExtension != '2slc');
1685 
1686  //
1687  // Check SRB status for success of completing request.
1688  //
1689 
1690  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1691 
1692  DebugPrint((2,"ScsiClassIoCompleteAssociated: IRP %lx, SRB %lx", Irp, srb));
1693 
1694  //
1695  // Release the queue if it is frozen.
1696  //
1697 
1698  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1700  }
1701 
1703  DeviceObject,
1704  srb,
1705  irpStack->MajorFunction,
1706  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1707  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1708  &status);
1709 
1710  //
1711  // If the status is verified required and the this request
1712  // should bypass verify required then retry the request.
1713  //
1714 
1715  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1717 
1719  retry = TRUE;
1720  }
1721 
1722  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1723 
1724  //
1725  // Retry request. If the class driver has supplied a StartIo,
1726  // call it directly for retries.
1727  //
1728 
1729  DebugPrint((1, "Retry request %lx\n", Irp));
1730 
1731  /*
1732  if (!deviceExtension->ClassStartIo) {
1733  RetryRequest(DeviceObject, Irp, srb, TRUE);
1734  } else {
1735  deviceExtension->ClassStartIo(DeviceObject, Irp);
1736  }
1737  */
1738 
1740 
1742  }
1743 
1744 
1745 
1746  } else {
1747 
1748  //
1749  // Set status for successful request.
1750  //
1751 
1753 
1754  } // end if (SRB_STATUS(srb->SrbStatus) ...
1755 
1756  //
1757  // Return SRB to list.
1758  //
1759 
1760  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1761  srb);
1762 
1763  //
1764  // Set status in completing IRP.
1765  //
1766 
1767  Irp->IoStatus.Status = status;
1768 
1769  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial xfer IRP %lx\n", Irp));
1770 
1771  //
1772  // Get next stack location. This original request is unused
1773  // except to keep track of the completing partial IRPs so the
1774  // stack location is valid.
1775  //
1776 
1777  irpStack = IoGetNextIrpStackLocation(originalIrp);
1778 
1779  //
1780  // Update status only if error so that if any partial transfer
1781  // completes with error, then the original IRP will return with
1782  // error. If any of the asynchronous partial transfer IRPs fail,
1783  // with an error then the original IRP will return 0 bytes transfered.
1784  // This is an optimization for successful transfers.
1785  //
1786 
1787  if (!NT_SUCCESS(status)) {
1788 
1789  originalIrp->IoStatus.Status = status;
1790  originalIrp->IoStatus.Information = 0;
1791 
1792  //
1793  // Set the hard error if necessary.
1794  //
1795 
1797 
1798  //
1799  // Store DeviceObject for filesystem.
1800  //
1801 
1803  }
1804  }
1805 
1806  //
1807  // Decrement and get the count of remaining IRPs.
1808  //
1809 
1810  irpCount = InterlockedDecrement((PLONG)&irpStack->Parameters.Others.Argument1);
1811 
1812  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial IRPs left %d\n",
1813  irpCount));
1814 
1815  //
1816  // Old bug could cause irp count to negative
1817  //
1818 
1819  ASSERT(irpCount >= 0);
1820 
1821  if (irpCount == 0) {
1822 
1823  //
1824  // All partial IRPs have completed.
1825  //
1826 
1827  DebugPrint((2,
1828  "ScsiClassIoCompleteAssociated: All partial IRPs complete %lx\n",
1829  originalIrp));
1830 
1831  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
1832 
1833  //
1834  // If the class driver has supplied a startio, start the
1835  // next request.
1836  //
1837 
1838  if (deviceExtension->ClassStartIo) {
1840  }
1841  }
1842 
1843  //
1844  // Deallocate IRP and indicate the I/O system should not attempt any more
1845  // processing.
1846  //
1847 
1848  IoFreeIrp(Irp);
1850 
1851 } // end ScsiClassIoCompleteAssociated()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define TRUE
Definition: types.h:120
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
Definition: class2.c:2845
IO_STATUS_BLOCK IoStatus
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
_In_ PIRP Irp
Definition: csq.h:116
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
#define PtrToUlong(u)
Definition: config.h:107
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
#define InterlockedDecrement
Definition: armddk.h:52
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
unsigned int * PULONG
Definition: retypes.h:1
struct tagContext Context
Definition: acpixf.h:1034
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
signed int * PLONG
Definition: retypes.h:5
static SERVICE_STATUS status
Definition: service.c:31
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

◆ ScsiClassModeSense()

ULONG NTAPI ScsiClassModeSense ( IN PDEVICE_OBJECT  DeviceObject,
IN PCHAR  ModeSenseBuffer,
IN ULONG  Length,
IN UCHAR  PageMode 
)

Definition at line 3199 of file class2.c.

3228 {
3229  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3230  PCDB cdb;
3231  SCSI_REQUEST_BLOCK srb;
3232  ULONG retries = 1;
3233  NTSTATUS status;
3234 
3235  ASSERT(*(PULONG)deviceExtension != '2slc');
3236 
3237  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3238 
3239  //
3240  // Build the MODE SENSE CDB.
3241  //
3242 
3243  srb.CdbLength = 6;
3244  cdb = (PCDB)srb.Cdb;
3245 
3246  //
3247  // Set timeout value from device extension.
3248  //
3249 
3250  srb.TimeOutValue = deviceExtension->TimeOutValue;
3251 
3252  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
3253  cdb->MODE_SENSE.PageCode = PageMode;
3254  cdb->MODE_SENSE.AllocationLength = (UCHAR)Length;
3255 
3256 Retry:
3257 
3259  &srb,
3260  ModeSenseBuffer,
3261  Length,
3262  FALSE);
3263 
3264 
3265  if (status == STATUS_VERIFY_REQUIRED) {
3266 
3267  //
3268  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3269  // this status. MODE SENSE commands should be retried anyway.
3270  //
3271 
3272  if (retries--) {
3273 
3274  //
3275  // Retry request.
3276  //
3277 
3278  goto Retry;
3279  }
3280 
3281  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3283  }
3284 
3285  if (NT_SUCCESS(status)) {
3286  return(srb.DataTransferLength);
3287  } else {
3288  return(0);
3289  }
3290 
3291 } // end ScsiClassModeSense()
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1325
UCHAR Cdb[16]
Definition: srb.h:271
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
ULONG DataTransferLength
Definition: srb.h:253
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
union _CDB * PCDB
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
struct _CDB::_MODE_SENSE MODE_SENSE
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:1856
Definition: ps.c:97

◆ ScsiClassQueryTimeOutRegistryValue()

ULONG NTAPI ScsiClassQueryTimeOutRegistryValue ( IN PUNICODE_STRING  RegistryPath)

Definition at line 4817 of file class2.c.

4837 {
4838  //
4839  // Find the appropriate reg. key
4840  //
4841 
4842  PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
4843  PWSTR path;
4844  NTSTATUS status;
4845  LONG timeOut = 0;
4846  ULONG zero = 0;
4847  ULONG size;
4848 
4849  if (!RegistryPath) {
4850  return 0;
4851  }
4852 
4853  parameters = ExAllocatePool(NonPagedPool,
4854  sizeof(RTL_QUERY_REGISTRY_TABLE)*2);
4855 
4856  if (!parameters) {
4857  return 0;
4858  }
4859 
4860  size = RegistryPath->MaximumLength + sizeof(WCHAR);
4862 
4863  if (!path) {
4864  ExFreePool(parameters);
4865  return 0;
4866  }
4867 
4869  RtlCopyMemory(path, RegistryPath->Buffer, size - sizeof(WCHAR));
4870 
4871 
4872  //
4873  // Check for the Timeout value.
4874  //
4875 
4876  RtlZeroMemory(parameters,
4877  (sizeof(RTL_QUERY_REGISTRY_TABLE)*2));
4878 
4879  parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
4880  parameters[0].Name = L"TimeOutValue";
4881  parameters[0].EntryContext = &timeOut;
4882  parameters[0].DefaultType = REG_DWORD;
4883  parameters[0].DefaultData = &zero;
4884  parameters[0].DefaultLength = sizeof(ULONG);
4885 
4887  path,
4888  parameters,
4889  NULL,
4890  NULL);
4891 
4892  if (!(NT_SUCCESS(status))) {
4893  timeOut = 0;
4894  }
4895 
4896  ExFreePool(parameters);
4897  ExFreePool(path);
4898 
4899  DebugPrint((2,
4900  "ScsiClassQueryTimeOutRegistryValue: Timeout value %d\n",
4901  timeOut));
4902 
4903 
4904  return timeOut;
4905 
4906 }
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
GLsizei const GLchar ** path
Definition: glext.h:7234
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
long LONG
Definition: pedump.c:60
int zero
Definition: sehframes.cpp:29
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define REG_DWORD
Definition: sdbapi.c:596
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
Definition: ps.c:97

Referenced by CreateCdRomDeviceObject(), and CreateDiskDeviceObject().

◆ ScsiClassReadDriveCapacity()

NTSTATUS NTAPI ScsiClassReadDriveCapacity ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 714 of file class2.c.

736 {
737  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
738  ULONG retries = 1;
739  ULONG lastSector;
740  PCDB cdb;
741  PREAD_CAPACITY_DATA readCapacityBuffer;
742  SCSI_REQUEST_BLOCK srb;
744 
745  ASSERT(*(PULONG)deviceExtension != '2slc');
746 
747  //
748  // Allocate read capacity buffer from nonpaged pool.
749  //
750 
751  readCapacityBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
752  sizeof(READ_CAPACITY_DATA));
753 
754  if (!readCapacityBuffer) {
756  }
757 
758  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
759 
760  //
761  // Build the read capacity CDB.
762  //
763 
764  srb.CdbLength = 10;
765  cdb = (PCDB)srb.Cdb;
766 
767  //
768  // Set timeout value from device extension.
769  //
770 
771  srb.TimeOutValue = deviceExtension->TimeOutValue;
772 
773  cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
774 
775 Retry:
776 
778  &srb,
779  readCapacityBuffer,
780  sizeof(READ_CAPACITY_DATA),
781  FALSE);
782 
783  if (NT_SUCCESS(status)) {
784 
785  //
786  // Copy sector size from read capacity buffer to device extension
787  // in reverse byte order.
788  //
789 
790  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte0 =
791  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte3;
792 
793  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte1 =
794  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte2;
795 
796  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte2 =
797  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte1;
798 
799  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte3 =
800  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte0;
801 
802  //
803  // Copy last sector in reverse byte order.
804  //
805 
806  ((PFOUR_BYTE)&lastSector)->Byte0 =
807  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte3;
808 
809  ((PFOUR_BYTE)&lastSector)->Byte1 =
810  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte2;
811 
812  ((PFOUR_BYTE)&lastSector)->Byte2 =
813  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte1;
814 
815  ((PFOUR_BYTE)&lastSector)->Byte3 =
816  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte0;
817 
818  //
819  // Calculate sector to byte shift.
820  //
821 
822  WHICH_BIT(deviceExtension->DiskGeometry->Geometry.BytesPerSector, deviceExtension->SectorShift);
823 
824  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is %d\n",
825  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
826 
827  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is %d\n",
828  lastSector + 1));
829 
830  //
831  // Calculate number of cylinders.
832  //
833 
834  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(DEFAULT_SECTORS_PER_TRACK * DEFAULT_TRACKS_PER_CYLINDER));
835 
836  //
837  // Calculate media capacity in bytes.
838  //
839 
840  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
841  deviceExtension->PartitionLength.QuadPart =
842  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
843  deviceExtension->DiskGeometry->DiskSize.QuadPart = deviceExtension->PartitionLength.QuadPart;
844 
845  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
846 
847  //
848  // This device supports removable media.
849  //
850 
851  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
852 
853  } else {
854 
855  //
856  // Assume media type is fixed disk.
857  //
858 
859  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
860  }
861 
862  //
863  // Assume sectors per track are DEFAULT_SECTORS_PER_TRACK;
864  //
865 
866  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = DEFAULT_SECTORS_PER_TRACK;
867 
868  //
869  // Assume tracks per cylinder (number of heads) is DEFAULT_TRACKS_PER_CYLINDER.
870  //
871 
872  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = DEFAULT_TRACKS_PER_CYLINDER;
873  }
874 
876 
877  //
878  // Routine ScsiClassSendSrbSynchronous does not retry
879  // requests returned with this status.
880  // Read Capacities should be retried
881  // anyway.
882  //
883 
884  if (retries--) {
885 
886  //
887  // Retry request.
888  //
889 
890  goto Retry;
891  }
892  }
893 
894  if (!NT_SUCCESS(status)) {
895 
896  //
897  // If the read capacity fails, set the geometry to reasonable parameter
898  // so things don't fail at unexpected places. Zero the geometry
899  // except for the bytes per sector and sector shift.
900  //
901 
902  RtlZeroMemory(deviceExtension->DiskGeometry, sizeof(DISK_GEOMETRY_EX));
903  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 512;
904  deviceExtension->SectorShift = 9;
905  deviceExtension->PartitionLength.QuadPart = (LONGLONG) 0;
906  deviceExtension->DiskGeometry->DiskSize.QuadPart = (LONGLONG) 0;
907 
908  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
909 
910  //
911  // This device supports removable media.
912  //
913 
914  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
915 
916  } else {
917 
918  //
919  // Assume media type is fixed disk.
920  //
921 
922  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
923  }
924  }
925 
926  //
927  // Deallocate read capacity buffer.
928  //
929 
930  ExFreePool(readCapacityBuffer);
931 
932  return status;
933 
934 } // end ScsiClassReadDriveCapacity()
struct _FOUR_BYTE * PFOUR_BYTE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR Cdb[16]
Definition: srb.h:271
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
ULONG LogicalBlockAddress
Definition: cdrw_hw.h:1471
struct _CDB::_CDB10 CDB10
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
#define WHICH_BIT(Data, Bit)
Definition: tools.h:80
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define DEFAULT_SECTORS_PER_TRACK
Definition: class2.c:37
union _CDB * PCDB
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
int64_t LONGLONG
Definition: typedefs.h:68
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
unsigned int * PULONG
Definition: retypes.h:1
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:1856
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DEFAULT_TRACKS_PER_CYLINDER
Definition: class2.c:38
Definition: ps.c:97

◆ ScsiClassReleaseQueue()

VOID NTAPI ScsiClassReleaseQueue ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 939 of file class2.c.

963 {
964  PIO_STACK_LOCATION irpStack;
965  PIRP irp;
966  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
969  KIRQL currentIrql;
970 
971  ASSERT(*(PULONG)deviceExtension != '2slc');
972 
973  //
974  // Allocate context from nonpaged pool.
975  //
976 
978  sizeof(COMPLETION_CONTEXT));
979 
980  //
981  // Save the device object in the context for use by the completion
982  // routine.
983  //
984 
985  context->DeviceObject = DeviceObject;
986  srb = &context->Srb;
987 
988  //
989  // Zero out srb.
990  //
991 
993 
994  //
995  // Write length to SRB.
996  //
997 
999 
1000  //
1001  // Set up SCSI bus address.
1002  //
1003 
1004  srb->PathId = deviceExtension->PathId;
1005  srb->TargetId = deviceExtension->TargetId;
1006  srb->Lun = deviceExtension->Lun;
1007 
1008  //
1009  // If this device is removable then flush the queue. This will also
1010  // release it.
1011  //
1012 
1013  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1014 
1016 
1017  } else {
1018 
1020 
1021  }
1022 
1023  //
1024  // Build the asynchronous request to be sent to the port driver.
1025  //
1026 
1027  irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1028 
1029  if(irp == NULL) {
1030 
1031  //
1032  // We have no better way of dealing with this at the moment
1033  //
1034 
1035  KeBugCheck((ULONG)0x0000002DL);
1036 
1037  }
1038 
1041  context,
1042  TRUE,
1043  TRUE,
1044  TRUE);
1045 
1046  irpStack = IoGetNextIrpStackLocation(irp);
1047 
1048  irpStack->MajorFunction = IRP_MJ_SCSI;
1049 
1050  srb->OriginalRequest = irp;
1051 
1052  //
1053  // Store the SRB address in next stack for port driver.
1054  //
1055 
1056  irpStack->Parameters.Scsi.Srb = srb;
1057 
1058  //
1059  // Since this routine can cause outstanding requests to be completed, and
1060  // calling a completion routine at < DISPATCH_LEVEL is dangerous (if they
1061  // call IoStartNextPacket we will bugcheck) raise up to dispatch level before
1062  // issuing the request
1063  //
1064 
1065  currentIrql = KeGetCurrentIrql();
1066 
1067  if(currentIrql < DISPATCH_LEVEL) {
1068  KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
1069  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1070  KeLowerIrql(currentIrql);
1071  } else {
1072  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1073  }
1074 
1075  return;
1076 
1077 } // end ScsiClassReleaseQueue()
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
PVOID OriginalRequest
Definition: srb.h:258
Definition: http.c:7094
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI ScsiClassAsynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: class2.c:1217
#define SRB_FUNCTION_FLUSH_QUEUE
Definition: srb.h:321
#define SRB_FUNCTION_RELEASE_QUEUE
Definition: srb.h:311
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
UCHAR TargetId
Definition: srb.h:246
#define ASSERT(a)
Definition: mode.c:45
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2814
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
FxIrp * irp

◆ ScsiClassSendSrbAsynchronous()

NTSTATUS NTAPI ScsiClassSendSrbAsynchronous ( PDEVICE_OBJECT  DeviceObject,
PSCSI_REQUEST_BLOCK  Srb,
PIRP  Irp,
PVOID  BufferAddress,
ULONG  BufferLength,
BOOLEAN  WriteToDevice 
)

Definition at line 3370 of file class2.c.

3406 {
3407 
3408  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3409  PIO_STACK_LOCATION irpStack;
3410 
3411  PAGED_CODE();
3412 
3413  ASSERT(*(PULONG)deviceExtension != '2slc');
3414 
3415  //
3416  // Write length to SRB.
3417  //
3418 
3419  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
3420 
3421  //
3422  // Set SCSI bus address.
3423  //
3424 
3425  Srb->PathId = deviceExtension->PathId;
3426  Srb->TargetId = deviceExtension->TargetId;
3427  Srb->Lun = deviceExtension->Lun;
3428 
3429  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
3430 
3431  //
3432  // This is a violation of the SCSI spec but it is required for
3433  // some targets.
3434  //
3435 
3436  Srb->Cdb[1] |= deviceExtension->Lun << 5;
3437 
3438  //
3439  // Indicate auto request sense by specifying buffer and size.
3440  //
3441 
3442  Srb->SenseInfoBuffer = deviceExtension->SenseData;
3443  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
3444  Srb->DataBuffer = BufferAddress;
3445 
3446  if (BufferAddress != NULL) {
3447 
3448  //
3449  // Build Mdl if necessary.
3450  //
3451 
3452  if (Irp->MdlAddress == NULL) {
3453 
3455  BufferLength,
3456  FALSE,
3457  FALSE,
3458  Irp) == NULL) {
3459 
3461  }
3462 
3463  MmBuildMdlForNonPagedPool(Irp->MdlAddress);
3464 
3465  } else {
3466 
3467  //
3468  // Make sure the buffer requested matches the MDL.
3469  //
3470 
3472  }
3473 
3474  //
3475  // Set read flag.
3476  //
3477 
3479 
3480  } else {
3481 
3482  //
3483  // Clear flags.
3484  //
3485 
3486  Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
3487  }
3488 
3489  //
3490  // Disable synchronous transfer for these requests.
3491  //
3492 
3494 
3495  //
3496  // Set the transfer length.
3497  //
3498 
3499  Srb->DataTransferLength = BufferLength;
3500 
3501  //
3502  // Zero out status.
3503  //
3504 
3505  Srb->ScsiStatus = Srb->SrbStatus = 0;
3506 
3507  Srb->NextSrb = 0;
3508 
3509  //
3510  // Save a few parameters in the current stack location.
3511  //
3512 
3513  irpStack = IoGetCurrentIrpStackLocation(Irp);
3514 
3515  //
3516  // Save retry count in current Irp stack.
3517  //
3518 
3519  irpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3520 
3521  //
3522  // Set up IoCompletion routine address.
3523  //
3524 
3526 
3527  //
3528  // Get next stack location and
3529  // set major function code.
3530  //
3531 
3532  irpStack = IoGetNextIrpStackLocation(Irp);
3533 
3534  irpStack->MajorFunction = IRP_MJ_SCSI;
3535 
3536  //
3537  // Save SRB address in next stack for port driver.
3538  //
3539 
3540  irpStack->Parameters.Scsi.Srb = Srb;
3541 
3542  //
3543  // Set up Irp Address.
3544  //
3545 
3546  Srb->OriginalRequest = Irp;
3547 
3548  //
3549  // Call the port driver to process the request.
3550  //
3551 
3552  return(IoCallDriver(deviceExtension->PortDeviceObject, Irp));
3553 
3554 }
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID OriginalRequest
Definition: srb.h:258
#define MmGetMdlVirtualAddress(_Mdl)
#define TRUE
Definition: types.h:120
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
void * PVOID
Definition: retypes.h:9
#define ASSERT(a)
Definition: mode.c:45
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
NTSTATUS NTAPI ScsiClassIoComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1492
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:989
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:989
#define PAGED_CODE()

◆ ScsiClassSendSrbSynchronous()

NTSTATUS NTAPI ScsiClassSendSrbSynchronous ( PDEVICE_OBJECT  DeviceObject,
PSCSI_REQUEST_BLOCK  Srb,
PVOID  BufferAddress,
ULONG  BufferLength,
BOOLEAN  WriteToDevice 
)

Definition at line 1856 of file class2.c.

1892 {
1893  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1894  IO_STATUS_BLOCK ioStatus;
1895  ULONG controlType, mjFunction;
1896  PIRP irp;
1897  PIO_STACK_LOCATION irpStack;
1898  KEVENT event;
1900  ULONG retryCount = MAXIMUM_RETRIES;
1901  NTSTATUS status;
1902  BOOLEAN retry;
1904 
1905  PAGED_CODE();
1906 
1907  ASSERT(*(PULONG)deviceExtension != '2slc');
1908 
1909  dummy.QuadPart = 0;
1910 
1911  //
1912  // Write length to SRB.
1913  //
1914 
1915  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
1916 
1917  //
1918  // Set SCSI bus address.
1919  //
1920 
1921  Srb->PathId = deviceExtension->PathId;
1922  Srb->TargetId = deviceExtension->TargetId;
1923  Srb->Lun = deviceExtension->Lun;
1924  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
1925 
1926  //
1927  // NOTICE: The SCSI-II specification indicates that this field should be
1928  // zero; however, some target controllers ignore the logical unit number
1929  // in the IDENTIFY message and only look at the logical unit number field
1930  // in the CDB.
1931  //
1932 
1933  Srb->Cdb[1] |= deviceExtension->Lun << 5;
1934 
1935  //
1936  // Enable auto request sense.
1937  //
1938 
1939  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
1940 
1941  //
1942  // Sense buffer is in aligned nonpaged pool.
1943  //
1944 
1946 
1947  if (senseInfoBuffer == NULL) {
1948 
1949  DebugPrint((1,
1950  "ScsiClassSendSrbSynchronous: Can't allocate request sense buffer\n"));
1952  }
1953 
1954  Srb->SenseInfoBuffer = senseInfoBuffer;
1955  Srb->DataBuffer = BufferAddress;
1956 
1957  //
1958  // Start retries here.
1959  //
1960 
1961 retry:
1962 
1963  //
1964  // Set the event object to the unsignaled state.
1965  // It will be used to signal request completion.
1966  //
1967 
1969 
1970  //
1971  // Set controlType and Srb direction flags.
1972  //
1973 
1974  if (BufferAddress != NULL) {
1975 
1976  if (WriteToDevice) {
1977 
1978  controlType = IOCTL_SCSI_EXECUTE_OUT;
1979  Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
1980  mjFunction = IRP_MJ_WRITE;
1981 
1982  } else {
1983 
1984  controlType = IOCTL_SCSI_EXECUTE_IN;
1985  Srb->SrbFlags = SRB_FLAGS_DATA_IN;
1986  mjFunction = IRP_MJ_READ;
1987  }
1988 
1989  } else {
1990 
1991  BufferLength = 0;
1992  controlType = IOCTL_SCSI_EXECUTE_NONE;
1993  Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
1994  mjFunction = IRP_MJ_FLUSH_BUFFERS;
1995  }
1996 
1997  //
1998  // Build device I/O control request with data transfer.
1999  //
2001  mjFunction,
2002  deviceExtension->DeviceObject,
2003  BufferAddress,
2004  (BufferAddress) ? BufferLength : 0,
2005  &dummy,
2006  &ioStatus);
2007 
2008  if (irp == NULL) {
2010  DebugPrint((1, "ScsiClassSendSrbSynchronous: Can't allocate Irp\n"));
2012  }
2013 
2014  // Set event field
2015  irp->UserEvent = &event;
2016 
2017  //
2018  // Disable synchronous transfer for these requests.
2019  //
2020 
2022 
2023  //
2024  // Set the transfer length.
2025  //
2026 
2027  Srb->DataTransferLength = BufferLength;
2028 
2029  //
2030  // Zero out status.
2031  //
2032 
2033  Srb->ScsiStatus = Srb->SrbStatus = 0;
2034  Srb->NextSrb = 0;
2035 
2036  // Set completion routine
2038  irp,
2040  NULL,
2041  TRUE,
2042  TRUE,
2043  TRUE);
2044 
2045  //
2046  // Get next stack location.
2047  //
2048 
2049  irpStack = IoGetNextIrpStackLocation(irp);
2050 
2052  irpStack->Parameters.DeviceIoControl.IoControlCode = controlType;
2053 
2054  //
2055  // Set up SRB for execute scsi request. Save SRB address in next stack
2056  // for the port driver.
2057  //
2058 
2059  irpStack->Parameters.Scsi.Srb = Srb;
2060 
2061  //
2062  // Set up IRP Address.
2063  //
2064 
2065  Srb->OriginalRequest = irp;
2066 
2067  //
2068  // Call the port driver with the request and wait for it to complete.
2069  //
2070 
2071  status = IoCallDriver(deviceExtension->PortDeviceObject, irp);
2072 
2073  if (status == STATUS_PENDING) {
2075  }
2076 
2077  //
2078  // Check that request completed without error.
2079  //
2080 
2081  if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) {
2082 
2083  //
2084  // Release the queue if it is frozen.
2085  //
2086 
2087  if (Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2089  }
2090 
2091  //
2092  // Update status and determine if request should be retried.
2093  //
2094 
2096  Srb,
2097  IRP_MJ_SCSI,
2098  0,
2099  MAXIMUM_RETRIES - retryCount,
2100  &status);
2101 
2102  if (retry) {
2103 
2106  SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SELECTION_TIMEOUT) {
2107 
2108  LARGE_INTEGER delay;
2109 
2110  //
2111  // Delay for 2 seconds.
2112  //
2113 
2114  delay.QuadPart = (LONGLONG)( - 10 * 1000 * 1000 * 2 );
2115 
2116  //
2117  // Stall for a while to let the controller spinup.
2118  //
2119 
2121  FALSE,
2122  &delay);
2123 
2124  }
2125 
2126  //
2127  // If retries are not exhausted then retry this operation.
2128  //
2129 
2130  if (retryCount--) {
2131  goto retry;
2132  }
2133  }
2134 
2135  } else {
2136 
2138  }
2139 
2141  return status;
2142 
2143 } // end ScsiClassSendSrbSynchronous()
#define IOCTL_SCSI_EXECUTE_OUT
Definition: cdrw_hw.h:1452
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID OriginalRequest
Definition: srb.h:258
#define IRP_MJ_FLUSH_BUFFERS
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
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 SRB_STATUS(Status)
Definition: srb.h:381
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
unsigned char BOOLEAN
NTSTATUS NTAPI ClassCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4975
int64_t LONGLONG
Definition: typedefs.h:68
#define ASSERT(a)
Definition: mode.c:45
#define STATUS_PENDING
Definition: ntstatus.h:82
PFIXED_SENSE_DATA senseInfoBuffer
Definition: scsi.h:3710
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
PIRP NTAPI IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:750
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
struct _cl_event * event
Definition: glext.h:7739
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:989
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
_In_ UCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR AdditionalSenseCode
Definition: scsi.h:3744
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned char dummy
Definition: maze.c:118
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_SUCCESS
Definition: shellext.h:65
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
static SERVICE_STATUS status
Definition: service.c:31
FxIrp * irp
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:989
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define PAGED_CODE()
Definition: ps.c:97

◆ ScsiClassSplitRequest()

VOID NTAPI ScsiClassSplitRequest ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN ULONG  MaximumBytes 
)

Definition at line 1298 of file class2.c.

1329 {
1330  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1333  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
1334  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
1335  PVOID dataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
1336  ULONG dataLength = MaximumBytes;
1337  ULONG irpCount = (transferByteCount + MaximumBytes - 1) / MaximumBytes;
1338  ULONG i;
1339  PSCSI_REQUEST_BLOCK srb;
1340 
1341  DebugPrint((2, "ScsiClassSplitRequest: Requires %d IRPs\n", irpCount));
1342  DebugPrint((2, "ScsiClassSplitRequest: Original IRP %lx\n", Irp));
1343 
1344  ASSERT(*(PULONG)deviceExtension != '2slc');
1345 
1346  //
1347  // If all partial transfers complete successfully then the status and
1348  // bytes transferred are already set up. Failing a partial-transfer IRP
1349  // will set status to error and bytes transferred to 0 during
1350  // IoCompletion. Setting bytes transferred to 0 if an IRP fails allows
1351  // asynchronous partial transfers. This is an optimization for the
1352  // successful case.
1353  //
1354 
1355  Irp->IoStatus.Status = STATUS_SUCCESS;
1356  Irp->IoStatus.Information = transferByteCount;
1357 
1358  //
1359  // Save number of IRPs to complete count on current stack
1360  // of original IRP.
1361  //
1362 
1363  nextIrpStack->Parameters.Others.Argument1 = (PVOID)(ULONG_PTR) irpCount;
1364 
1365  for (i = 0; i < irpCount; i++) {
1366 
1367  PIRP newIrp;
1368  PIO_STACK_LOCATION newIrpStack;
1369 
1370  //
1371  // Allocate new IRP.
1372  //
1373 
1374  newIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1375 
1376  if (newIrp == NULL) {
1377 
1378  DebugPrint((1,"ScsiClassSplitRequest: Can't allocate Irp\n"));
1379 
1380  //
1381  // If an Irp can't be allocated then the original request cannot
1382  // be executed. If this is the first request then just fail the
1383  // original request; otherwise just return. When the pending
1384  // requests complete, they will complete the original request.
1385  // In either case set the IRP status to failure.
1386  //
1387 
1388  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1389  Irp->IoStatus.Information = 0;
1390 
1391  if (i == 0) {
1393  }
1394 
1395  return;
1396  }
1397 
1398  DebugPrint((2, "ScsiClassSplitRequest: New IRP %lx\n", newIrp));
1399 
1400  //
1401  // Write MDL address to new IRP. In the port driver the SRB data
1402  // buffer field is used as an offset into the MDL, so the same MDL
1403  // can be used for each partial transfer. This saves having to build
1404  // a new MDL for each partial transfer.
1405  //
1406 
1407  newIrp->MdlAddress = Irp->MdlAddress;
1408 
1409  //
1410  // At this point there is no current stack. IoSetNextIrpStackLocation
1411  // will make the first stack location the current stack so that the
1412  // SRB address can be written there.
1413  //
1414 
1415  IoSetNextIrpStackLocation(newIrp);
1416  newIrpStack = IoGetCurrentIrpStackLocation(newIrp);
1417 
1418  newIrpStack->MajorFunction = currentIrpStack->MajorFunction;
1419  newIrpStack->Parameters.Read.Length = dataLength;
1420  newIrpStack->Parameters.Read.ByteOffset = startingOffset;
1421  newIrpStack->DeviceObject = DeviceObject;
1422 
1423  //
1424  // Build SRB and CDB.
1425  //
1426 
1428 
1429  //
1430  // Adjust SRB for this partial transfer.
1431  //
1432 
1433  newIrpStack = IoGetNextIrpStackLocation(newIrp);
1434 
1435  srb = newIrpStack->Parameters.Others.Argument1;
1436  srb->DataBuffer = dataBuffer;
1437 
1438  //
1439  // Write original IRP address to new IRP.
1440  //
1441 
1442  newIrp->AssociatedIrp.MasterIrp = Irp;
1443 
1444  //
1445  // Set the completion routine to ScsiClassIoCompleteAssociated.
1446  //
1447 
1448  IoSetCompletionRoutine(newIrp,
1450  srb,
1451  TRUE,
1452  TRUE,
1453  TRUE);
1454 
1455  //
1456  // Call port driver with new request.
1457  //
1458 
1459  IoCallDriver(deviceExtension->PortDeviceObject, newIrp);
1460 
1461  //
1462  // Set up for next request.
1463  //
1464 
1465  dataBuffer = (PCHAR)dataBuffer + MaximumBytes;
1466 
1467  transferByteCount -= MaximumBytes;
1468 
1469  if (transferByteCount > MaximumBytes) {
1470 
1471  dataLength = MaximumBytes;
1472 
1473  } else {
1474 
1475  dataLength = transferByteCount;
1476  }
1477 
1478  //
1479  // Adjust disk byte offset.
1480  //
1481 
1482  startingOffset.QuadPart = startingOffset.QuadPart + MaximumBytes;
1483  }
1484 
1485  return;
1486 
1487 } // end ScsiClassSplitRequest()
NTSTATUS NTAPI ScsiClassIoCompleteAssociated(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1641
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MmGetMdlVirtualAddress(_Mdl)
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
PVOID dataBuffer
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
void * PVOID
Definition: retypes.h:9
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:45
ULONG dataLength
Definition: scsi.h:3751
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID NTAPI ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class2.c:2970
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
LONGLONG QuadPart
Definition: typedefs.h:114

◆ VOID()

typedef VOID ( NTAPI PCLASS_ERROR)

Variable Documentation

◆ ScsiClassAsynchronousCompletion

IO_COMPLETION_ROUTINE ScsiClassAsynchronousCompletion

Definition at line 148 of file class2.h.

Referenced by HitachProcessError(), and ResetScsiBus().