ReactOS  0.4.14-dev-390-g34947ad
class2.c File Reference
#include <ntddk.h>
#include <ntdddisk.h>
#include <mountdev.h>
#include <scsi.h>
#include <include/class2.h>
#include <stdio.h>
#include <debug.h>
Include dependency graph for class2.c:

Go to the source code of this file.

Macros

#define INQUIRY_DATA_SIZE   2048
 
#define START_UNIT_TIMEOUT   30
 
#define DEFAULT_SECTORS_PER_TRACK   63
 
#define DEFAULT_TRACKS_PER_CYLINDER   255
 

Functions

NTSTATUS NTAPI ScsiClassCreateClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiClassReadWrite (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiClassDeviceControlDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI ScsiClassDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI ScsiClassInternalIoControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiClassShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
VOID NTAPI RetryRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
 
VOID NTAPI StartUnit (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ClassIoCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ClassCompletionRoutine (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ScsiClassPlugPlay (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
ULONG NTAPI ScsiClassInitialize (IN PVOID Argument1, IN PVOID Argument2, IN PCLASS_INIT_DATA InitializationData)
 
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)
 
NTSTATUS NTAPI ScsiClassReadDriveCapacity (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI ScsiClassReleaseQueue (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ScsiClassAsynchronousCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
VOID NTAPI ScsiClassSplitRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG MaximumBytes)
 
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)
 
NTSTATUS NTAPI ScsiClassSendSrbSynchronous (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
 
BOOLEAN NTAPI ScsiClassInterpretSenseInfo (IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
 
VOID NTAPI ScsiClassBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
ULONG NTAPI ScsiClassModeSense (IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
 
PVOID NTAPI ScsiClassFindModePage (IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
 
NTSTATUS NTAPI ScsiClassSendSrbAsynchronous (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
 
ULONG NTAPI ScsiClassFindUnclaimedDevices (IN PCLASS_INIT_DATA InitializationData, IN PSCSI_ADAPTER_BUS_INFO AdapterInformation)
 
NTSTATUS NTAPI ScsiClassCreateDeviceObject (IN PDRIVER_OBJECT DriverObject, IN PCCHAR ObjectNameBuffer, IN OPTIONAL PDEVICE_OBJECT PhysicalDeviceObject, IN OUT PDEVICE_OBJECT *DeviceObject, IN PCLASS_INIT_DATA InitializationData)
 
NTSTATUS NTAPI ScsiClassClaimDevice (IN PDEVICE_OBJECT PortDeviceObject, IN PSCSI_INQUIRY_DATA LunInfo, IN BOOLEAN Release, OUT PDEVICE_OBJECT *NewPortDeviceObject OPTIONAL)
 
VOID NTAPI ScsiClassInitializeSrbLookasideList (IN PDEVICE_EXTENSION DeviceExtension, IN ULONG NumberElements)
 
ULONG NTAPI ScsiClassQueryTimeOutRegistryValue (IN PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI ScsiClassCheckVerifyComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 

Macro Definition Documentation

◆ DEFAULT_SECTORS_PER_TRACK

#define DEFAULT_SECTORS_PER_TRACK   63

Definition at line 37 of file class2.c.

◆ DEFAULT_TRACKS_PER_CYLINDER

#define DEFAULT_TRACKS_PER_CYLINDER   255

Definition at line 38 of file class2.c.

◆ INQUIRY_DATA_SIZE

#define INQUIRY_DATA_SIZE   2048

Definition at line 29 of file class2.c.

◆ START_UNIT_TIMEOUT

#define START_UNIT_TIMEOUT   30

Definition at line 30 of file class2.c.

Function Documentation

◆ ClassCompletionRoutine()

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

Definition at line 4974 of file class2.c.

4977 {
4978  PIO_STATUS_BLOCK IoStatusBlock = Irp->UserIosb;
4979  PKEVENT Event = Irp->UserEvent;
4980  PMDL Mdl;
4981 
4982  *IoStatusBlock = Irp->IoStatus;
4983  Irp->UserIosb = NULL;
4984  Irp->UserEvent = NULL;
4985 
4986  if(Irp->MdlAddress)
4987  {
4988  Mdl = Irp->MdlAddress;
4989 
4990  // if necessary - unlock pages
4991  if ((Mdl->MdlFlags & MDL_PAGES_LOCKED) &&
4992  !(Mdl->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED))
4993  {
4994  MmUnlockPages(Mdl);
4995  }
4996 
4997  // free this mdl
4998  IoFreeMdl(Mdl);
4999  }
5000 
5001  // free irp and set event to unsignaled state
5002  IoFreeIrp(Irp);
5004 
5006 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
smooth NULL
Definition: ftsmooth.c:416
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IO_NO_INCREMENT
Definition: iotypes.h:566

Referenced by ScsiClassSendSrbSynchronous().

◆ ClassIoCompletion()

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

Definition at line 4730 of file class2.c.

4758 {
4761 
4762  //
4763  // If pending is returned for this Irp then mark current stack
4764  // as pending
4765  //
4766 
4767  if (Irp->PendingReturned) {
4768 
4769  IoMarkIrpPending( Irp );
4770  }
4771 
4772  return Irp->IoStatus.Status;
4773 }
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
IoMarkIrpPending(Irp)

Referenced by ScsiClassInternalIoControl().

◆ DriverEntry()

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

Definition at line 126 of file class2.c.

130 {
131  return STATUS_SUCCESS;
132 }
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by ScsiClassDeviceControl().

◆ RetryRequest()

VOID NTAPI RetryRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PSCSI_REQUEST_BLOCK  Srb,
BOOLEAN  Associated 
)

Definition at line 2844 of file class2.c.

2874 {
2875  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2878  ULONG transferByteCount;
2879 
2880  ASSERT(*(PULONG)deviceExtension != '2slc');
2881 
2882  //
2883  // Determine the transfer count of the request. If this is a read or a
2884  // write then the transfer count is in the Irp stack. Otherwise assume
2885  // the MDL contains the correct length. If there is no MDL then the
2886  // transfer length must be zero.
2887  //
2888 
2889  if (currentIrpStack->MajorFunction == IRP_MJ_READ ||
2890  currentIrpStack->MajorFunction == IRP_MJ_WRITE) {
2891 
2892  transferByteCount = currentIrpStack->Parameters.Read.Length;
2893 
2894  } else if (Irp->MdlAddress != NULL) {
2895 
2896  //
2897  // Note this assumes that only read and write requests are spilt and
2898  // other request do not need to be. If the data buffer address in
2899  // the MDL and the SRB don't match then transfer length is most
2900  // likely incorrect.
2901  //
2902 
2903  ASSERT(Srb->DataBuffer == MmGetMdlVirtualAddress(Irp->MdlAddress));
2904  transferByteCount = Irp->MdlAddress->ByteCount;
2905 
2906  } else {
2907 
2908  transferByteCount = 0;
2909  }
2910 
2911  //
2912  // Reset byte count of transfer in SRB Extension.
2913  //
2914 
2915  Srb->DataTransferLength = transferByteCount;
2916 
2917  //
2918  // Zero SRB statuses.
2919  //
2920 
2921  Srb->SrbStatus = Srb->ScsiStatus = 0;
2922 
2923  //
2924  // Set the no disconnect flag, disable synchronous data transfers and
2925  // disable tagged queuing. This fixes some errors.
2926  //
2927 
2928  Srb->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT |
2930 
2931  Srb->SrbFlags &= ~SRB_FLAGS_QUEUE_ACTION_ENABLE;
2932  Srb->QueueTag = SP_UNTAGGED;
2933 
2934  //
2935  // Set up major SCSI function.
2936  //
2937 
2938  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
2939 
2940  //
2941  // Save SRB address in next stack for port driver.
2942  //
2943 
2944  nextIrpStack->Parameters.Scsi.Srb = Srb;
2945 
2946  //
2947  // Set up IoCompletion routine address.
2948  //
2949 
2950  if (Associated) {
2951 
2953 
2954  } else {
2955 
2957  }
2958 
2959  //
2960  // Pass the request to the port driver.
2961  //
2962 
2963  (VOID)IoCallDriver(deviceExtension->PortDeviceObject, Irp);
2964 
2965 } // end RetryRequest()
NTSTATUS NTAPI ScsiClassIoCompleteAssociated(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1640
#define TRUE
Definition: types.h:120
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define SP_UNTAGGED
Definition: srb.h:225
#define IRP_MJ_SCSI
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#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:1491
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:388
#define VOID
Definition: acefi.h:82
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387

Referenced by ClassIoComplete(), ScsiClassIoComplete(), and ScsiClassIoCompleteAssociated().

◆ ScsiClassAsynchronousCompletion()

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

Definition at line 1216 of file class2.c.

1245 {
1247  PSCSI_REQUEST_BLOCK srb;
1248 
1249  srb = &context->Srb;
1250 
1251  //
1252  // If this is an execute srb, then check the return status and make sure.
1253  // the queue is not frozen.
1254  //
1255 
1256  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
1257 
1258  //
1259  // Check for a frozen queue.
1260  //
1261 
1262  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1263 
1264  //
1265  // Unfreeze the queue getting the device object from the context.
1266  //
1267 
1268  ScsiClassReleaseQueue(context->DeviceObject);
1269  }
1270  }
1271 
1272  //
1273  // Free the context and the Irp.
1274  //
1275 
1276  if (Irp->MdlAddress != NULL) {
1277  MmUnlockPages(Irp->MdlAddress);
1278  IoFreeMdl(Irp->MdlAddress);
1279 
1280  Irp->MdlAddress = NULL;
1281  }
1282 
1284  IoFreeIrp(Irp);
1285 
1286  //
1287  // Indicate the I/O system should stop processing the Irp completion.
1288  //
1289 
1291 
1292 } // ScsiClassAsynchronousCompletion()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:6587
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
UCHAR SrbStatus
Definition: srb.h:243
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:938
smooth NULL
Definition: ftsmooth.c:416
UCHAR Function
Definition: srb.h:242
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
struct tagContext Context
Definition: acpixf.h:1030
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by ScsiClassReleaseQueue(), and StartUnit().

◆ ScsiClassBuildRequest()

VOID NTAPI ScsiClassBuildRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 2969 of file class2.c.

3003 {
3004  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3007  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
3008  PSCSI_REQUEST_BLOCK srb;
3009  PCDB cdb;
3010  ULONG logicalBlockAddress;
3011  USHORT transferBlocks;
3012 
3013  ASSERT(*(PULONG)deviceExtension != '2slc');
3014 
3015  //
3016  // Calculate relative sector address.
3017  //
3018 
3019  logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
3020 
3021  //
3022  // Allocate an Srb.
3023  //
3024 
3025  srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
3026 
3027  srb->SrbFlags = 0;
3028 
3029  //
3030  // Write length to SRB.
3031  //
3032 
3034 
3035  //
3036  // Set up IRP Address.
3037  //
3038 
3039  srb->OriginalRequest = Irp;
3040 
3041  //
3042  // Set up target ID and logical unit number.
3043  //
3044 
3045  srb->PathId = deviceExtension->PathId;
3046  srb->TargetId = deviceExtension->TargetId;
3047  srb->Lun = deviceExtension->Lun;
3049  srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
3050 
3051  //
3052  // Save byte count of transfer in SRB Extension.
3053  //
3054 
3055  srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
3056 
3057  //
3058  // Initialize the queue actions field.
3059  //
3060 
3062 
3063  //
3064  // Queue sort key is Relative Block Address.
3065  //
3066 
3067  srb->QueueSortKey = logicalBlockAddress;
3068 
3069  //
3070  // Indicate auto request sense by specifying buffer and size.
3071  //
3072 
3073  srb->SenseInfoBuffer = deviceExtension->SenseData;
3075 
3076  //
3077  // Set timeout value of one unit per 64k bytes of data.
3078  //
3079 
3080  srb->TimeOutValue = ((srb->DataTransferLength + 0xFFFF) >> 16) *
3081  deviceExtension->TimeOutValue;
3082 
3083  //
3084  // Zero statuses.
3085  //
3086 
3087  srb->SrbStatus = srb->ScsiStatus = 0;
3088  srb->NextSrb = 0;
3089 
3090  //
3091  // Indicate that 10-byte CDB's will be used.
3092  //
3093 
3094  srb->CdbLength = 10;
3095 
3096  //
3097  // Fill in CDB fields.
3098  //
3099 
3100  cdb = (PCDB)srb->Cdb;
3101 
3102  //
3103  // Zero 12 bytes for Atapi Packets
3104  //
3105 
3107 
3108  cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
3109  transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
3110 
3111  //
3112  // Move little endian values into CDB in big endian format.
3113  //
3114 
3115  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
3116  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
3117  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
3118  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
3119 
3120  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
3121  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
3122 
3123  //
3124  // Set transfer direction flag and Cdb command.
3125  //
3126 
3127  if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
3128 
3129  DebugPrint((3, "ScsiClassBuildRequest: Read Command\n"));
3130 
3131  srb->SrbFlags |= SRB_FLAGS_DATA_IN;
3132  cdb->CDB10.OperationCode = SCSIOP_READ;
3133 
3134  } else {
3135 
3136  DebugPrint((3, "ScsiClassBuildRequest: Write Command\n"));
3137 
3138  srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
3139  cdb->CDB10.OperationCode = SCSIOP_WRITE;
3140  }
3141 
3142  //
3143  // If this is not a write-through request, then allow caching.
3144  //
3145 
3146  if (!(currentIrpStack->Flags & SL_WRITE_THROUGH)) {
3147 
3149 
3150  } else {
3151 
3152  //
3153  // If write caching is enable then force media access in the
3154  // cdb.
3155  //
3156 
3157  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
3158  cdb->CDB10.ForceUnitAccess = TRUE;
3159  }
3160  }
3161 
3162  //
3163  // Or in the default flags from the device object.
3164  //
3165 
3166  srb->SrbFlags |= deviceExtension->SrbFlags;
3167 
3168  //
3169  // Set up major SCSI function.
3170  //
3171 
3172  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
3173 
3174  //
3175  // Save SRB address in next stack for port driver.
3176  //
3177 
3178  nextIrpStack->Parameters.Scsi.Srb = srb;
3179 
3180  //
3181  // Save retry count in current IRP stack.
3182  //
3183 
3184  currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3185 
3186  //
3187  // Set up IoCompletion routine address.
3188  //
3189 
3191 
3192  return;
3193 
3194 } // end ScsiClassBuildRequest()
struct _FOUR_BYTE * PFOUR_BYTE
#define TRUE
Definition: types.h:120
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
PVOID DataBuffer
Definition: srb.h:255
ULONG DataTransferLength
Definition: srb.h:253
Definition: cdrw_hw.h:28
UCHAR CdbLength
Definition: srb.h:250
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:257
UCHAR QueueAction
Definition: srb.h:249
struct _CDB::_CDB10 CDB10
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
UCHAR ScsiStatus
Definition: srb.h:244
#define SCSIOP_READ
Definition: cdrw_hw.h:905
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
union _CDB * PCDB
void * PVOID
Definition: retypes.h:9
UCHAR TargetId
Definition: srb.h:246
#define MAXIMUM_RETRIES
Definition: class2.h:14
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
NTSTATUS NTAPI ScsiClassIoComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1491
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MAXIMUM_CDB_SIZE
Definition: srb.h:33
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define Int64ShrlMod32(a, b)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
UCHAR SenseInfoBufferLength
Definition: srb.h:251
UCHAR PathId
Definition: srb.h:245
unsigned short USHORT
Definition: pedump.c:61
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#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 SRB_FLAGS_ADAPTER_CACHE_ENABLE
Definition: srb.h:397
#define SL_WRITE_THROUGH
Definition: iotypes.h:1781
#define IRP_MJ_READ
Definition: rdpdr.c:46
PVOID SenseInfoBuffer
Definition: srb.h:256
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
ULONG QueueSortKey
Definition: srb.h:262
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by CdRomSwitchModeCompletion(), ScsiCdRomStartIo(), ScsiClassReadWrite(), and ScsiClassSplitRequest().

◆ ScsiClassCheckVerifyComplete()

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

Definition at line 4909 of file class2.c.

4938 {
4940  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4941  PDEVICE_EXTENSION physicalExtension =
4942  deviceExtension->PhysicalDevice->DeviceExtension;
4943  PIRP originalIrp;
4944 
4945  ASSERT(*(PULONG)deviceExtension != '2slc');
4946  ASSERT(*(PULONG)physicalExtension != '2slc');
4947 
4948  originalIrp = irpStack->Parameters.Others.Argument1;
4949 
4950  //
4951  // Copy the media change count and status
4952  //
4953 
4954  *((PULONG) (originalIrp->AssociatedIrp.SystemBuffer)) =
4955  physicalExtension->MediaChangeCount;
4956 
4957  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change count for"
4958  "device %d is %d\n",
4959  physicalExtension->DeviceNumber,
4960  physicalExtension->MediaChangeCount));
4961 
4962  originalIrp->IoStatus.Status = Irp->IoStatus.Status;
4963  originalIrp->IoStatus.Information = sizeof(ULONG);
4964 
4965  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
4966 
4967  IoFreeIrp(Irp);
4968 
4970 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
unsigned int ULONG
Definition: retypes.h:1
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772

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 4488 of file class2.c.

4519 {
4520  IO_STATUS_BLOCK ioStatus;
4521  PIRP irp;
4522  PIO_STACK_LOCATION irpStack;
4523  KEVENT event;
4524  NTSTATUS status;
4525  SCSI_REQUEST_BLOCK srb;
4526 
4527  PAGED_CODE();
4528 
4529  if (NewPortDeviceObject != NULL) {
4530  *NewPortDeviceObject = NULL;
4531  }
4532 
4533  //
4534  // Clear the SRB fields.
4535  //
4536 
4537  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
4538 
4539  //
4540  // Write length to SRB.
4541  //
4542 
4544 
4545  //
4546  // Set SCSI bus address.
4547  //
4548 
4549  srb.PathId = LunInfo->PathId;
4550  srb.TargetId = LunInfo->TargetId;
4551  srb.Lun = LunInfo->Lun;
4552 
4555 
4556  //
4557  // Set the event object to the unsignaled state.
4558  // It will be used to signal request completion.
4559  //
4560 
4562 
4563  //
4564  // Build synchronous request with no transfer.
4565  //
4566 
4568  PortDeviceObject,
4569  NULL,
4570  0,
4571  NULL,
4572  0,
4573  TRUE,
4574  &event,
4575  &ioStatus);
4576 
4577  if (irp == NULL) {
4578 
4579  DebugPrint((1, "ScsiClassClaimDevice: Can't allocate Irp\n"));
4581  }
4582 
4583  irpStack = IoGetNextIrpStackLocation(irp);
4584 
4585  //
4586  // Save SRB address in next stack for port driver.
4587  //
4588 
4589  irpStack->Parameters.Scsi.Srb = &srb;
4590 
4591  //
4592  // Set up IRP Address.
4593  //
4594 
4595  srb.OriginalRequest = irp;
4596 
4597  //
4598  // Call the port driver with the request and wait for it to complete.
4599  //
4600 
4601  status = IoCallDriver(PortDeviceObject, irp);
4602  if (status == STATUS_PENDING) {
4603 
4605  status = ioStatus.Status;
4606  }
4607 
4608  //
4609  // If this is a release request, then just decrement the reference count
4610  // and return. The status does not matter.
4611  //
4612 
4613  if (Release) {
4614 
4615  //ObDereferenceObject(PortDeviceObject);
4616  return STATUS_SUCCESS;
4617  }
4618 
4619  if (!NT_SUCCESS(status)) {
4620  return status;
4621  }
4622 
4623  ASSERT(srb.DataBuffer != NULL);
4624 
4625  //
4626  // Reference the new port driver object so that it will not go away while
4627  // it is being used.
4628  //
4629 
4631  0,
4632  NULL,
4633  KernelMode );
4634 
4635  if (!NT_SUCCESS(status)) {
4636 
4637  return status;
4638  }
4640 
4641  //
4642  // Return the new port device object pointer.
4643  //
4644 
4645  if (NewPortDeviceObject != NULL) {
4646  *NewPortDeviceObject = srb.DataBuffer;
4647  }
4648 
4649  return status;
4650 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID OriginalRequest
Definition: srb.h:258
_In_ BOOLEAN Release
Definition: classpnp.h:929
PVOID DataBuffer
Definition: srb.h:255
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_FUNCTION_CLAIM_DEVICE
Definition: srb.h:308
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
#define SRB_FUNCTION_RELEASE_DEVICE
Definition: srb.h:313
smooth NULL
Definition: ftsmooth.c:416
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 NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _cl_event * event
Definition: glext.h:7739
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by CreateCdRomDeviceObject(), and CreateDiskDeviceObject().

◆ ScsiClassCreateClose()

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

Definition at line 297 of file class2.c.

321 {
323 
324  ASSERT(*(PULONG)deviceExtension != '2slc');
325 
326  //
327  // Invoke the device-specific routine, if one exists. Otherwise complete
328  // with SUCCESS
329  //
330 
331  if (deviceExtension->ClassCreateClose) {
332 
333  return deviceExtension->ClassCreateClose(DeviceObject, Irp);
334 
335  } else {
336  Irp->IoStatus.Status = STATUS_SUCCESS;
337 
339  return(STATUS_SUCCESS);
340  }
341 }
_In_ PIRP Irp
Definition: csq.h:116
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int * PULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by ScsiClassInitialize().

◆ ScsiClassCreateDeviceObject()

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

Definition at line 4364 of file class2.c.

4399 {
4400  STRING ntNameString;
4401  UNICODE_STRING ntUnicodeString;
4402  NTSTATUS status;
4403  PDEVICE_OBJECT deviceObject = NULL;
4404 
4405  *DeviceObject = NULL;
4406 
4407  DebugPrint((2,
4408  "ScsiClassCreateDeviceObject: Create device object %s\n",
4409  ObjectNameBuffer));
4410 
4411  RtlInitString(&ntNameString,
4413 
4414  status = RtlAnsiStringToUnicodeString(&ntUnicodeString,
4415  &ntNameString,
4416  TRUE);
4417 
4418  if (!NT_SUCCESS(status)) {
4419 
4420  DebugPrint((1,
4421  "CreateDiskDeviceObjects: Cannot convert string %s\n",
4422  ObjectNameBuffer));
4423 
4424  ntUnicodeString.Buffer = NULL;
4425  return status;
4426  }
4427 
4429  InitializationData->DeviceExtensionSize,
4430  &ntUnicodeString,
4431  InitializationData->DeviceType,
4432  InitializationData->DeviceCharacteristics,
4433  FALSE,
4434  &deviceObject);
4435 
4436 
4437  if (!NT_SUCCESS(status)) {
4438 
4439  DebugPrint((1,
4440  "CreateDiskDeviceObjects: Can not create device object %s\n",
4441  ObjectNameBuffer));
4442 
4443  } else {
4444 
4445  PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
4446 
4447  ASSERT(*(PULONG)deviceExtension != '2slc');
4448 
4449  //
4450  // Fill in entry points
4451  //
4452 
4453  deviceExtension->ClassError = InitializationData->ClassError;
4454  deviceExtension->ClassReadWriteVerification = InitializationData->ClassReadWriteVerification;
4455  deviceExtension->ClassFindDevices = InitializationData->ClassFindDevices;
4456  deviceExtension->ClassDeviceControl = InitializationData->ClassDeviceControl;
4457  deviceExtension->ClassShutdownFlush = InitializationData->ClassShutdownFlush;
4458  deviceExtension->ClassCreateClose = InitializationData->ClassCreateClose;
4459  deviceExtension->ClassStartIo = InitializationData->ClassStartIo;
4460 
4461  deviceExtension->MediaChangeCount = 0;
4462 
4463  //
4464  // If a pointer to the physical device object was passed in then use
4465  // that. If the value was NULL, then this is the physical device so
4466  // use the pointer to the device we just created.
4467  //
4468 
4470  deviceExtension->PhysicalDevice = PhysicalDeviceObject;
4471  } else {
4472  deviceExtension->PhysicalDevice = deviceObject;
4473  }
4474 
4475  deviceExtension->DeviceName = ntUnicodeString;
4476  }
4477 
4478  deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
4479 
4480  *DeviceObject = deviceObject;
4481 
4482  return status;
4483 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
PVOID DeviceExtension
Definition: env_spec_w32.h:418
_In_z_ PCCHAR ObjectNameBuffer
Definition: classpnp.h:789
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARGUMENT_PRESENT(ArgumentPointer)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
std::wstring STRING
Definition: fontsub.cpp:33
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:680
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

◆ ScsiClassDeviceControl()

NTSTATUS NTAPI ScsiClassDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 3602 of file class2.c.

3628 {
3630  PIO_STACK_LOCATION nextStack;
3631  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3632  PSCSI_REQUEST_BLOCK srb;
3633  PCDB cdb;
3634  NTSTATUS status;
3635  ULONG modifiedIoControlCode;
3636 
3637  ASSERT(*(PULONG)deviceExtension != '2slc');
3638 
3639  if (irpStack->Parameters.DeviceIoControl.IoControlCode ==
3641 
3642  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
3645  goto SetStatusAndReturn;
3646  }
3647 
3648  //
3649  // If this is a pass through I/O control, set the minor function code
3650  // and device address and pass it to the port driver.
3651  //
3652 
3653  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH
3654  || irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) {
3655 
3656  PSCSI_PASS_THROUGH scsiPass;
3657 
3658  nextStack = IoGetNextIrpStackLocation(Irp);
3659 
3660  //
3661  // Validate the user buffer.
3662  //
3663 
3664  if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH)){
3665 
3666  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3669  goto SetStatusAndReturn;
3670  }
3671 
3672  //
3673  // Force the SCSI address to the correct value.
3674  //
3675 
3676  scsiPass = Irp->AssociatedIrp.SystemBuffer;
3677  scsiPass->PathId = deviceExtension->PathId;
3678  scsiPass->TargetId = deviceExtension->TargetId;
3679  scsiPass->Lun = deviceExtension->Lun;
3680 
3681  //
3682  // NOTICE: The SCSI-II specification indicates that this field
3683  // should be zero; however, some target controllers ignore the logical
3684  // unit number in the IDENTIFY message and only look at the logical
3685  // unit number field in the CDB.
3686  //
3687 
3688  scsiPass->Cdb[1] |= deviceExtension->Lun << 5;
3689 
3690  nextStack->Parameters = irpStack->Parameters;
3691  nextStack->MajorFunction = irpStack->MajorFunction;
3692  nextStack->MinorFunction = IRP_MN_SCSI_CLASS;
3693 
3694  status = IoCallDriver(deviceExtension->PortDeviceObject, Irp);
3695  goto SetStatusAndReturn;
3696  }
3697 
3698  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS) {
3699 
3700  PSCSI_ADDRESS scsiAddress = Irp->AssociatedIrp.SystemBuffer;
3701 
3702  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
3703  sizeof(SCSI_ADDRESS)) {
3704 
3705  //
3706  // Indicate unsuccessful status and no data transferred.
3707  //
3708 
3709  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
3710  Irp->IoStatus.Information = 0;
3713  goto SetStatusAndReturn;
3714 
3715  }
3716 
3717  scsiAddress->Length = sizeof(SCSI_ADDRESS);
3718  scsiAddress->PortNumber = deviceExtension->PortNumber;
3719  scsiAddress->PathId = deviceExtension->PathId;
3720  scsiAddress->TargetId = deviceExtension->TargetId;
3721  scsiAddress->Lun = deviceExtension->Lun;
3722  Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
3723  Irp->IoStatus.Status = STATUS_SUCCESS;
3726  goto SetStatusAndReturn;
3727  }
3728 
3729  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) {
3730 
3731  UNIMPLEMENTED;
3732  Irp->IoStatus.Information = 0;
3733  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
3736  goto SetStatusAndReturn;
3737  }
3738 
3739  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID) {
3740 
3741  //
3742  // FIXME
3743  // This is a HACK. We don't have unique ID.
3744  // We'll just return device name as unique ID.
3745  // It's unique but may not survive to a reboot,
3746  // which is not matching the requirements for
3747  // a MountMgr unique ID.
3748  //
3749 
3750  PMOUNTDEV_UNIQUE_ID uniqueId = Irp->AssociatedIrp.SystemBuffer;
3751 
3752  //
3753  // Check output buffer is big enough.
3754  //
3755 
3756  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID)) {
3757 
3758  Irp->IoStatus.Information = 0;
3759  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3762  goto SetStatusAndReturn;
3763  }
3764 
3765  //
3766  // Set size we'll return so that caller can allocate big enough buffer.
3767  //
3768 
3769  RtlZeroMemory(uniqueId, sizeof(MOUNTDEV_UNIQUE_ID));
3770  uniqueId->UniqueIdLength = deviceExtension->DeviceName.Length;
3771 
3772  //
3773  // Check buffer is big enough to contain device name.
3774  //
3775 
3776  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + uniqueId->UniqueIdLength) {
3777 
3778  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
3779  Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
3782  goto SetStatusAndReturn;
3783  }
3784 
3785  //
3786  // Copy device name.
3787  //
3788 
3789  RtlCopyMemory(uniqueId->UniqueId, deviceExtension->DeviceName.Buffer,
3790  uniqueId->UniqueIdLength);
3792 
3793  //
3794  // And return to the caller.
3795  //
3796 
3797  Irp->IoStatus.Status = STATUS_SUCCESS;
3798  Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + uniqueId->UniqueIdLength;
3800  goto SetStatusAndReturn;
3801  }
3802 
3803  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) {
3804 
3805  PMOUNTDEV_NAME name = Irp->AssociatedIrp.SystemBuffer;
3806 
3807  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
3808 
3809  Irp->IoStatus.Information = 0;
3810  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3813  goto SetStatusAndReturn;
3814  }
3815 
3816  RtlZeroMemory(name, sizeof(MOUNTDEV_NAME));
3817  name->NameLength = deviceExtension->DeviceName.Length;
3818 
3819  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + name->NameLength) {
3820 
3821  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
3822  Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
3825  goto SetStatusAndReturn;
3826  }
3827 
3828  RtlCopyMemory(name->Name, deviceExtension->DeviceName.Buffer,
3829  name->NameLength);
3831  Irp->IoStatus.Status = STATUS_SUCCESS;
3832  Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + name->NameLength;
3834  goto SetStatusAndReturn;
3835  }
3836 
3838 
3839  if (srb == NULL) {
3840 
3841  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3844  goto SetStatusAndReturn;
3845  }
3846 
3847  //
3848  // Write zeros to Srb.
3849  //
3850 
3852 
3853  cdb = (PCDB)srb->Cdb;
3854 
3855  //
3856  // Change the device type to disk for the switch statement.
3857  //
3858 
3859  modifiedIoControlCode = (irpStack->Parameters.DeviceIoControl.IoControlCode
3860  & ~0xffff0000) | (IOCTL_DISK_BASE << 16);
3861 
3862  switch (modifiedIoControlCode) {
3863 
3864  case IOCTL_DISK_CHECK_VERIFY: {
3865 
3866  PIRP irp2 = NULL;
3867  PIO_STACK_LOCATION newStack;
3868 
3869  DebugPrint((1,"ScsiDeviceIoControl: Check verify\n"));
3870 
3871  //
3872  // If a buffer for a media change count was provided, make sure it's
3873  // big enough to hold the result
3874  //
3875 
3876  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
3877 
3878  //
3879  // If the buffer is too small to hold the media change count
3880  // then return an error to the caller
3881  //
3882 
3883  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
3884  sizeof(ULONG)) {
3885 
3886  DebugPrint((3,"ScsiDeviceIoControl: media count "
3887  "buffer too small\n"));
3888 
3889  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
3890  Irp->IoStatus.Information = 0;
3891  ExFreePool(srb);
3894  goto SetStatusAndReturn;
3895 
3896  }
3897 
3898  //
3899  // The caller has provided a valid buffer. Allocate an additional
3900  // irp and stick the CheckVerify completion routine on it. We will
3901  // then send this down to the port driver instead of the irp the
3902  // caller sent in
3903  //
3904 
3905  DebugPrint((2,"ScsiDeviceIoControl: Check verify wants "
3906  "media count\n"));
3907 
3908  //
3909  // Allocate a new irp to send the TestUnitReady to the port driver
3910  //
3911 
3912  irp2 = IoAllocateIrp((CCHAR) (DeviceObject->StackSize + 3), FALSE);
3913 
3914  if(irp2 == NULL) {
3915  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3916  Irp->IoStatus.Information = 0;
3917  ExFreePool(srb);
3920  goto SetStatusAndReturn;
3921  }
3922 
3923  irp2->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
3925 
3926  //
3927  // Set the top stack location and shove the master Irp into the
3928  // top location
3929  //
3930 
3931  newStack = IoGetCurrentIrpStackLocation(irp2);
3932  newStack->Parameters.Others.Argument1 = Irp;
3933  newStack->DeviceObject = DeviceObject;
3934 
3935  //
3936  // Stick the check verify completion routine onto the stack
3937  // and prepare the irp for the port driver
3938  //
3939 
3942  NULL,
3943  TRUE,
3944  TRUE,
3945  TRUE);
3946 
3948  newStack = IoGetCurrentIrpStackLocation(irp2);
3949  newStack->DeviceObject = DeviceObject;
3950 
3951  //
3952  // Mark the master irp as pending - whether the lower level
3953  // driver completes it immediately or not this should allow it
3954  // to go all the way back up.
3955  //
3956 
3958 
3959  Irp = irp2;
3960 
3961  }
3962 
3963  //
3964  // Test Unit Ready
3965  //
3966 
3967  srb->CdbLength = 6;
3968  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
3969 
3970  //
3971  // Set timeout value.
3972  //
3973 
3974  srb->TimeOutValue = deviceExtension->TimeOutValue;
3975 
3976  //
3977  // Since this routine will always hand the request to the
3978  // port driver if there isn't a data transfer to be done
3979  // we don't have to worry about completing the request here
3980  // on an error
3981  //
3982 
3984  srb,
3985  Irp,
3986  NULL,
3987  0,
3988  FALSE);
3989 
3990  break;
3991  }
3992 
3993  case IOCTL_DISK_MEDIA_REMOVAL: {
3994 
3995  PPREVENT_MEDIA_REMOVAL MediaRemoval = Irp->AssociatedIrp.SystemBuffer;
3996 
3997  //
3998  // Prevent/Allow media removal.
3999  //
4000 
4001  DebugPrint((3,"DiskIoControl: Prevent/Allow media removal\n"));
4002 
4003  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
4004  sizeof(PREVENT_MEDIA_REMOVAL)) {
4005 
4006  //
4007  // Indicate unsuccessful status and no data transferred.
4008  //
4009 
4010  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
4011  Irp->IoStatus.Information = 0;
4012  ExFreePool(srb);
4015  goto SetStatusAndReturn;
4016  }
4017 
4018  //
4019  // Get physical device extension. This is where the
4020  // lock count is stored.
4021  //
4022 
4023  deviceExtension = deviceExtension->PhysicalDevice->DeviceExtension;
4024 
4025  //
4026  // If command succeeded then increment or decrement lock counter.
4027  //
4028 
4029  if (MediaRemoval->PreventMediaRemoval) {
4030 
4031  //
4032  // This is a lock command. Reissue the command in case bus or device
4033  // was reset and lock cleared.
4034  //
4035 
4036  InterlockedIncrement(&deviceExtension->LockCount);
4037 
4038  DebugPrint((1,
4039  "ScsiClassDeviceControl: Lock media, lock count %x on disk %x\n",
4040  deviceExtension->LockCount,
4041  deviceExtension->DeviceNumber));
4042 
4043  } else {
4044 
4045  //
4046  // This is an unlock command.
4047  //
4048 
4049  if (!deviceExtension->LockCount ||
4050  (InterlockedDecrement(&deviceExtension->LockCount) != 0)) {
4051 
4052  DebugPrint((1,
4053  "ScsiClassDeviceControl: Unlock media, lock count %x on disk %x\n",
4054  deviceExtension->LockCount,
4055  deviceExtension->DeviceNumber));
4056 
4057  //
4058  // Don't unlock because someone still wants it locked.
4059  //
4060 
4061  Irp->IoStatus.Status = STATUS_SUCCESS;
4062  ExFreePool(srb);
4065  goto SetStatusAndReturn;
4066  }
4067 
4068  DebugPrint((1,
4069  "ScsiClassDeviceControl: Unlock media, lock count %x on disk %x\n",
4070  deviceExtension->LockCount,
4071  deviceExtension->DeviceNumber));
4072  }
4073 
4074  srb->CdbLength = 6;
4075 
4076  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
4077 
4078  //
4079  // TRUE - prevent media removal.
4080  // FALSE - allow media removal.
4081  //
4082 
4083  cdb->MEDIA_REMOVAL.Prevent = MediaRemoval->PreventMediaRemoval;
4084 
4085  //
4086  // Set timeout value.
4087  //
4088 
4089  srb->TimeOutValue = deviceExtension->TimeOutValue;
4091  srb,
4092  Irp,
4093  NULL,
4094  0,
4095  FALSE);
4096 
4097  //
4098  // Some devices will not support lock/unlock.
4099  // Pretend that it worked.
4100  //
4101 
4102  break;
4103  }
4104 
4105  case IOCTL_DISK_RESERVE: {
4106 
4107  //
4108  // Reserve logical unit.
4109  //
4110 
4111  srb->CdbLength = 6;
4112 
4113  cdb->CDB6GENERIC.OperationCode = SCSIOP_RESERVE_UNIT;
4114 
4115  //
4116  // Set timeout value.
4117  //
4118 
4119  srb->TimeOutValue = deviceExtension->TimeOutValue;
4120 
4122  srb,
4123  Irp,
4124  NULL,
4125  0,
4126  FALSE);
4127 
4128  break;
4129  }
4130 
4131  case IOCTL_DISK_RELEASE: {
4132 
4133  //
4134  // Release logical unit.
4135  //
4136 
4137  srb->CdbLength = 6;
4138 
4139  cdb->CDB6GENERIC.OperationCode = SCSIOP_RELEASE_UNIT;
4140 
4141  //
4142  // Set timeout value.
4143  //
4144 
4145  srb->TimeOutValue = deviceExtension->TimeOutValue;
4146 
4148  srb,
4149  Irp,
4150  NULL,
4151  0,
4152  FALSE);
4153 
4154  break;
4155  }
4156 
4157  case IOCTL_DISK_EJECT_MEDIA: {
4158 
4159  //
4160  // Eject media.
4161  //
4162 
4163  srb->CdbLength = 6;
4164 
4165  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
4166  cdb->START_STOP.LoadEject = 1;
4167  cdb->START_STOP.Start = 0;
4168 
4169  //
4170  // Set timeout value.
4171  //
4172 
4173  srb->TimeOutValue = deviceExtension->TimeOutValue;
4175  srb,
4176  Irp,
4177  NULL,
4178  0,
4179  FALSE);
4180  break;
4181  }
4182 
4183  case IOCTL_DISK_LOAD_MEDIA: {
4184 
4185  //
4186  // Load media.
4187  //
4188 
4189  DebugPrint((3,"CdRomDeviceControl: Load media\n"));
4190 
4191  srb->CdbLength = 6;
4192 
4193  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
4194  cdb->START_STOP.LoadEject = 1;
4195  cdb->START_STOP.Start = 1;
4196 
4197  //
4198  // Set timeout value.
4199  //
4200 
4201  srb->TimeOutValue = deviceExtension->TimeOutValue;
4203  srb,
4204  Irp,
4205  NULL,
4206  0,
4207  FALSE);
4208 
4209  break;
4210  }
4211 
4213 
4214  //
4215  // Search for devices that have been powered on since the last
4216  // device search or system initialization.
4217  //
4218 
4219  DebugPrint((3,"CdRomDeviceControl: Find devices\n"));
4220  status = DriverEntry(DeviceObject->DriverObject,
4221  NULL);
4222 
4223  Irp->IoStatus.Status = status;
4224  ExFreePool(srb);
4226 
4227  break;
4228  }
4229 
4230  default: {
4231 
4232  DebugPrint((3,"ScsiIoDeviceControl: Unsupported device IOCTL\n"));
4233 
4234  //
4235  // Pass the device control to the next driver.
4236  //
4237 
4238  ExFreePool(srb);
4239 
4240  //
4241  // Copy the Irp stack parameters to the next stack location.
4242  //
4243 
4244  nextStack = IoGetNextIrpStackLocation(Irp);
4245  nextStack->Parameters = irpStack->Parameters;
4246  nextStack->MajorFunction = irpStack->MajorFunction;
4247  nextStack->MinorFunction = irpStack->MinorFunction;
4248 
4249  status = IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4250  break;
4251  }
4252 
4253  } // end switch( ...
4254 
4255 SetStatusAndReturn:
4256 
4257  return status;
4258 }
UCHAR PathId
Definition: scsi_port.h:149
UCHAR PortNumber
Definition: scsi_port.h:148
#define SCSIOP_RESERVE_UNIT
Definition: cdrw_hw.h:892
#define IOCTL_DISK_BASE
Definition: ntdddisk.h:44
#define IOCTL_DISK_EJECT_MEDIA
Definition: cdrw_usr.h:177
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
UCHAR Cdb[16]
Definition: srb.h:271
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define SCSIOP_RELEASE_UNIT
Definition: cdrw_hw.h:893
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
ULONG Length
Definition: scsi_port.h:147
USHORT UniqueIdLength
Definition: imports.h:138
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define IOCTL_STORAGE_RESET_DEVICE
Definition: ntddstor.h:129
UCHAR CdbLength
Definition: srb.h:250
ULONG TimeOutValue
Definition: srb.h:254
UCHAR TargetId
Definition: scsi_port.h:150
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IOCTL_DISK_FIND_NEW_DEVICES
Definition: cdrw_usr.h:181
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
UCHAR Cdb[16]
Definition: scsi_port.h:71
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
NTSTATUS NTAPI ScsiClassCheckVerifyComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4909
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: class2.c:126
struct _MOUNTDEV_NAME MOUNTDEV_NAME
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
struct _CDB::_START_STOP START_STOP
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
char CCHAR
Definition: typedefs.h:50
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:251
#define InterlockedDecrement
Definition: armddk.h:52
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
NTSTATUS NTAPI ScsiClassSendSrbAsynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:3369
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
#define IOCTL_DISK_LOAD_MEDIA
Definition: cdrw_usr.h:178
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
Definition: name.c:36
struct _SCSI_ADDRESS SCSI_ADDRESS
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IRP_MN_SCSI_CLASS
#define IOCTL_DISK_MEDIA_REMOVAL
Definition: cdrw_usr.h:176
#define IOCTL_DISK_RESERVE
Definition: cdrw_usr.h:179
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
UCHAR UniqueId[1]
Definition: imports.h:139
#define IOCTL_DISK_RELEASE
Definition: cdrw_usr.h:180
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by CdRomDeviceControl(), and ScsiDiskDeviceControl().

◆ ScsiClassDeviceControlDispatch()

NTSTATUS NTAPI ScsiClassDeviceControlDispatch ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 3558 of file class2.c.

3583 {
3584 
3585  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3586 
3587  ASSERT(*(PULONG)deviceExtension != '2slc');
3588 
3589  //
3590  // Call the class specific driver DeviceControl routine.
3591  // If it doesn't handle it, it will call back into ScsiClassDeviceControl.
3592  //
3593 
3594  ASSERT(deviceExtension->ClassDeviceControl);
3595 
3596  return deviceExtension->ClassDeviceControl(DeviceObject,Irp);
3597 }
_In_ PIRP Irp
Definition: csq.h:116
PVOID DeviceExtension
Definition: env_spec_w32.h:418
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int * PULONG
Definition: retypes.h:1

Referenced by ScsiClassInitialize().

◆ ScsiClassFindModePage()

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

Definition at line 3295 of file class2.c.

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

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

◆ ScsiClassFindUnclaimedDevices()

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

Definition at line 4316 of file class2.c.

4321 {
4322  ULONG scsiBus,deviceCount = 0;
4323  PCHAR buffer = (PCHAR)AdapterInformation;
4324  PSCSI_INQUIRY_DATA lunInfo;
4325  PINQUIRYDATA inquiryData;
4326 
4327  for (scsiBus=0; scsiBus < (ULONG)AdapterInformation->NumberOfBuses; scsiBus++) {
4328 
4329  //
4330  // Get the SCSI bus scan data for this bus.
4331  //
4332 
4333  lunInfo = (PVOID) (buffer + AdapterInformation->BusData[scsiBus].InquiryDataOffset);
4334 
4335  //
4336  // Search list for unclaimed disk devices.
4337  //
4338 
4339  while (AdapterInformation->BusData[scsiBus].InquiryDataOffset) {
4340 
4341  inquiryData = (PVOID)lunInfo->InquiryData;
4342 
4343  ASSERT(InitializationData->ClassFindDeviceCallBack);
4344 
4345  if ((InitializationData->ClassFindDeviceCallBack(inquiryData)) && (!lunInfo->DeviceClaimed)) {
4346 
4347  deviceCount++;
4348  }
4349 
4350  if (lunInfo->NextInquiryDataOffset == 0) {
4351  break;
4352  }
4353 
4354  lunInfo = (PVOID) (buffer + lunInfo->NextInquiryDataOffset);
4355  }
4356  }
4357  return deviceCount;
4358 }
signed char * PCHAR
Definition: retypes.h:7
GLuint buffer
Definition: glext.h:5915
ULONG NextInquiryDataOffset
Definition: scsi_port.h:118
void * PVOID
Definition: retypes.h:9
#define PCHAR
Definition: match.c:90
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:680
UCHAR InquiryData[1]
Definition: scsi_port.h:119
BOOLEAN DeviceClaimed
Definition: scsi_port.h:116
unsigned int ULONG
Definition: retypes.h:1

Referenced by FindScsiDisks().

◆ 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 PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
#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
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
Definition: ps.c:97

Referenced by FindScsiDisks(), and ScsiCdRomFindDevices().

◆ 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 PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
#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
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
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
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 
240 
241  if (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:311
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI ScsiClassDeviceControlDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class2.c:3558
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:694
#define IRP_MJ_FLUSH_BUFFERS
NTSTATUS NTAPI ScsiClassInternalIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:4655
#define IRP_MJ_SHUTDOWN
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:4263
#define IRP_MJ_SCSI
#define sprintf(buf, format,...)
Definition: sprintf.c:55
unsigned char BOOLEAN
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
_In_ PVOID Argument2
Definition: classpnp.h:680
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
char CCHAR
Definition: typedefs.h:50
* PFILE_OBJECT
Definition: iotypes.h:1955
#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:680
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
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
NTSTATUS NTAPI ScsiClassPlugPlay(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:136
unsigned int ULONG
Definition: retypes.h:1
PDRIVER_STARTIO DriverStartIo
Definition: iotypes.h:2179
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
#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 4778 of file class2.c.

4802 {
4803  ExInitializeNPagedLookasideList(&DeviceExtension->SrbLookasideListHead,
4804  NULL,
4805  NULL,
4808  'HscS',
4810 
4811 }
smooth NULL
Definition: ftsmooth.c:416
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:222
unsigned short USHORT
Definition: pedump.c:61
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ ULONG NumberElements
Definition: classpnp.h:944

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

◆ ScsiClassInternalIoControl()

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

Definition at line 4655 of file class2.c.

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

Referenced by ScsiClassInitialize().

◆ 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 2147 of file class2.c.

2183 {
2184  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2185  PDEVICE_EXTENSION physicalExtension = deviceExtension->PhysicalDevice->DeviceExtension;
2186  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
2187  BOOLEAN retry = TRUE;
2188  BOOLEAN logError = FALSE;
2189  ULONG badSector = 0;
2190  ULONG uniqueId = 0;
2191  NTSTATUS logStatus;
2192  ULONG readSector;
2193  ULONG index;
2194  PIO_ERROR_LOG_PACKET errorLogEntry;
2195 #if DBG
2196  ULONG i;
2197 #endif
2198 
2199  ASSERT(*(PULONG)deviceExtension != '2slc');
2200 
2201  //
2202  // Check that request sense buffer is valid.
2203  //
2204 
2205 #if DBG
2206  DebugPrint((3, "Opcode %x\nParameters: ",Srb->Cdb[0]));
2207  for (i = 1; i < 12; i++) {
2208  DebugPrint((3,"%x ",Srb->Cdb[i]));
2209  }
2210  DebugPrint((3,"\n"));
2211 #endif
2212 
2213  if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID &&
2214  Srb->SenseInfoBufferLength >= FIELD_OFFSET(SENSE_DATA, CommandSpecificInformation)) {
2215 
2216  DebugPrint((1,"ScsiClassInterpretSenseInfo: Error code is %x\n",
2217  senseBuffer->ErrorCode));
2218  DebugPrint((1,"ScsiClassInterpretSenseInfo: Sense key is %x\n",
2219  senseBuffer->SenseKey));
2220  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code is %x\n",
2221  senseBuffer->AdditionalSenseCode));
2222  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code qualifier is %x\n",
2223  senseBuffer->AdditionalSenseCodeQualifier));
2224 
2225  //
2226  // Zero the additional sense code and additional sense code qualifier
2227  // if they were not returned by the device.
2228  //
2229 
2230  readSector = senseBuffer->AdditionalSenseLength +
2231  FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
2232 
2233  if (readSector > Srb->SenseInfoBufferLength) {
2234  readSector = Srb->SenseInfoBufferLength;
2235  }
2236 
2237  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCode)) {
2238  senseBuffer->AdditionalSenseCode = 0;
2239  }
2240 
2241  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCodeQualifier)) {
2242  senseBuffer->AdditionalSenseCodeQualifier = 0;
2243  }
2244 
2245  switch (senseBuffer->SenseKey & 0xf) {
2246 
2247  case SCSI_SENSE_NOT_READY:
2248 
2249  DebugPrint((1,"ScsiClassInterpretSenseInfo: Device not ready\n"));
2251 
2252  switch (senseBuffer->AdditionalSenseCode) {
2253 
2255 
2256  DebugPrint((1,"ScsiClassInterpretSenseInfo: Lun not ready\n"));
2257 
2258  switch (senseBuffer->AdditionalSenseCodeQualifier) {
2259 
2261 
2262  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2263  " In process of becoming ready\n"));
2264  break;
2265 
2267 
2268  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2269  " Manual intervention required\n"));
2271  retry = FALSE;
2272  break;
2273 
2275 
2276  DebugPrint((1, "ScsiClassInterpretSenseInfo: Format in progress\n"));
2277  retry = FALSE;
2278  break;
2279 
2281 
2282  default:
2283 
2284  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2285  " Initializing command required\n"));
2286 
2287  //
2288  // This sense code/additional sense code
2289  // combination may indicate that the device
2290  // needs to be started. Send an start unit if this
2291  // is a disk device.
2292  //
2293 
2294  if (deviceExtension->DeviceFlags & DEV_SAFE_START_UNIT) {
2296  }
2297 
2298  break;
2299 
2300  } // end switch (senseBuffer->AdditionalSenseCodeQualifier)
2301 
2302  break;
2303 
2305 
2306  DebugPrint((1,
2307  "ScsiClassInterpretSenseInfo:"
2308  " No Media in device.\n"));
2310  retry = FALSE;
2311 
2312  //
2313  // signal autorun that there isn't any media in the device
2314  //
2315 
2316  if((deviceExtension->MediaChangeEvent != NULL)&&
2317  (!deviceExtension->MediaChangeNoMedia)) {
2318  KeSetEvent(deviceExtension->MediaChangeEvent,
2319  (KPRIORITY) 0,
2320  FALSE);
2321  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2322  "Detected No Media In Device "
2323  "[irp = 0x%lx]\n", Srb->OriginalRequest));
2324  deviceExtension->MediaChangeNoMedia = TRUE;
2325  }
2326 
2327  break;
2328  } // end switch (senseBuffer->AdditionalSenseCode)
2329 
2330  break;
2331 
2333 
2334  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media write protected\n"));
2336  retry = FALSE;
2337  break;
2338 
2340 
2341  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bad media\n"));
2343 
2344  retry = FALSE;
2345  logError = TRUE;
2346  uniqueId = 256;
2347  logStatus = 0;//IO_ERR_BAD_BLOCK;
2348  break;
2349 
2351 
2352  DebugPrint((1,"ScsiClassInterpretSenseInfo: Hardware error\n"));
2354 
2355  logError = TRUE;
2356  uniqueId = 257;
2357  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2358 
2359  break;
2360 
2362 
2363  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal SCSI request\n"));
2365 
2366  switch (senseBuffer->AdditionalSenseCode) {
2367 
2369  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal command\n"));
2370  retry = FALSE;
2371  break;
2372 
2374  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal block address\n"));
2376  retry = FALSE;
2377  break;
2378 
2380  DebugPrint((1,"ScsiClassInterpretSenseInfo: Invalid LUN\n"));
2382  retry = FALSE;
2383  break;
2384 
2386  DebugPrint((1,"ScsiClassInterpretSenseInfo: Music area\n"));
2387  retry = FALSE;
2388  break;
2389 
2391  DebugPrint((1,"ScsiClassInterpretSenseInfo: Data area\n"));
2392  retry = FALSE;
2393  break;
2394 
2396  DebugPrint((1, "ScsiClassInterpretSenseInfo: Volume overflow\n"));
2397  retry = FALSE;
2398  break;
2399 
2401  DebugPrint((1, "ScsiClassInterpretSenseInfo: Invalid CDB\n"));
2402 
2403  //
2404  // Check if write cache enabled.
2405  //
2406 
2407  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
2408 
2409  //
2410  // Assume FUA is not supported.
2411  //
2412 
2413  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
2414  retry = TRUE;
2415 
2416  } else {
2417  retry = FALSE;
2418  }
2419 
2420  break;
2421 
2422  } // end switch (senseBuffer->AdditionalSenseCode)
2423 
2424  break;
2425 
2427 
2428  switch (senseBuffer->AdditionalSenseCode) {
2430  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media changed\n"));
2431 
2432  if(deviceExtension->MediaChangeEvent != NULL) {
2433 
2434  KeSetEvent(deviceExtension->MediaChangeEvent,
2435  (KPRIORITY) 0,
2436  FALSE);
2437  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2438  "New Media Found - Setting MediaChanged event"
2439  " [irp = 0x%lx]\n", Srb->OriginalRequest));
2440  deviceExtension->MediaChangeNoMedia = FALSE;
2441 
2442  }
2443  break;
2444 
2446  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bus reset\n"));
2447  break;
2448 
2449  default:
2450  DebugPrint((1,"ScsiClassInterpretSenseInfo: Unit attention\n"));
2451  break;
2452 
2453  } // end switch (senseBuffer->AdditionalSenseCode)
2454 
2455  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
2456  DeviceObject->Vpb->Flags & VPB_MOUNTED) {
2457 
2458  //
2459  // Set bit to indicate that media may have changed
2460  // and volume needs verification.
2461  //
2462 
2464 
2466  retry = FALSE;
2467 
2468  } else {
2469 
2471 
2472  }
2473 
2474  //
2475  // A media change may have occured so increment the change
2476  // count for the physical device
2477  //
2478 
2479  physicalExtension->MediaChangeCount++;
2480 
2481  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change "
2482  "count for device %d is %d\n",
2483  physicalExtension->DeviceNumber,
2484  physicalExtension->MediaChangeCount));
2485 
2486  break;
2487 
2489 
2490  DebugPrint((1,"ScsiClassInterpretSenseInfo: Command aborted\n"));
2492  break;
2493 
2495 
2496  DebugPrint((1,"ScsiClassInterpretSenseInfo: Recovered error\n"));
2498  retry = FALSE;
2499  logError = TRUE;
2500  uniqueId = 258;
2501 
2502  switch(senseBuffer->AdditionalSenseCode) {
2505  logStatus = 0;//IO_ERR_SEEK_ERROR;
2506  break;
2507 
2510  logStatus = 0;//IO_RECOVERED_VIA_ECC;
2511  break;
2512 
2513  default:
2514  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2515  break;
2516 
2517  } // end switch(senseBuffer->AdditionalSenseCode)
2518 
2519  if (senseBuffer->IncorrectLength) {
2520 
2521  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2523  }
2524 
2525  break;
2526 
2527  case SCSI_SENSE_NO_SENSE:
2528 
2529  //
2530  // Check other indicators.
2531  //
2532 
2533  if (senseBuffer->IncorrectLength) {
2534 
2535  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2537  retry = FALSE;
2538 
2539  } else {
2540 
2541  DebugPrint((1, "ScsiClassInterpretSenseInfo: No specific sense key\n"));
2543  retry = TRUE;
2544  }
2545 
2546  break;
2547 
2548  default:
2549 
2550  DebugPrint((1, "ScsiClassInterpretSenseInfo: Unrecognized sense code\n"));
2552  break;
2553 
2554  } // end switch (senseBuffer->SenseKey & 0xf)
2555 
2556  //
2557  // Try to determine the bad sector from the inquiry data.
2558  //
2559 
2560  if ((((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_READ ||
2561  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_VERIFY ||
2562  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_WRITE)) {
2563 
2564  for (index = 0; index < 4; index++) {
2565  badSector = (badSector << 8) | senseBuffer->Information[index];
2566  }
2567 
2568  readSector = 0;
2569  for (index = 0; index < 4; index++) {
2570  readSector = (readSector << 8) | Srb->Cdb[index+2];
2571  }
2572 
2573  index = (((PCDB)Srb->Cdb)->CDB10.TransferBlocksMsb << 8) |
2574  ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb;
2575 
2576  //
2577  // Make sure the bad sector is within the read sectors.
2578  //
2579 
2580  if (!(badSector >= readSector && badSector < readSector + index)) {
2581  badSector = readSector;
2582  }
2583  }
2584 
2585  } else {
2586 
2587  //
2588  // Request sense buffer not valid. No sense information
2589  // to pinpoint the error. Return general request fail.
2590  //
2591 
2592  DebugPrint((1,"ScsiClassInterpretSenseInfo: Request sense info not valid. SrbStatus %2x\n",
2593  SRB_STATUS(Srb->SrbStatus)));
2594  retry = TRUE;
2595 
2596  switch (SRB_STATUS(Srb->SrbStatus)) {
2599  case SRB_STATUS_NO_DEVICE:
2600  case SRB_STATUS_NO_HBA:
2603  retry = FALSE;
2604  break;
2605 
2607  case SRB_STATUS_ABORTED:
2608  case SRB_STATUS_TIMEOUT:
2609 
2610  //
2611  // Update the error count for the device.
2612  //
2613 
2614  deviceExtension->ErrorCount++;
2616  break;
2617 
2619  logError = TRUE;
2620  logStatus = 0;//IO_ERR_NOT_READY;
2621  uniqueId = 260;
2623  retry = FALSE;
2624  break;
2625 
2628  retry = FALSE;
2629  break;
2630 
2632 
2633  //
2634  // Update the error count for the device.
2635  //
2636 
2637  deviceExtension->ErrorCount++;
2639 
2640  //
2641  // If there was phase sequence error then limit the number of
2642  // retries.
2643  //
2644 
2645  if (RetryCount > 1 ) {
2646  retry = FALSE;
2647  }
2648 
2649  break;
2650 
2652 
2653  //
2654  // If the status needs verification bit is set. Then set
2655  // the status to need verification and no retry; otherwise,
2656  // just retry the request.
2657  //
2658 
2660 
2662  retry = FALSE;
2663  } else {
2665  }
2666 
2667  break;
2668 
2670 
2671  //
2672  // An invalid request was attempted.
2673  //
2674 
2676  retry = FALSE;
2677  break;
2678 
2681 
2682  //
2683  // Update the error count for the device.
2684  //
2685 
2686  deviceExtension->ErrorCount++;
2687 
2688  //
2689  // Fall through to below.
2690  //
2691 
2692  case SRB_STATUS_BUS_RESET:
2694  break;
2695 
2696  case SRB_STATUS_ERROR:
2697 
2699  if (Srb->ScsiStatus == 0) {
2700 
2701  //
2702  // This is some strange return code. Update the error
2703  // count for the device.
2704  //
2705 
2706  deviceExtension->ErrorCount++;
2707 
2708  } if (Srb->ScsiStatus == SCSISTAT_BUSY) {
2709 
2711 
2712  } if (Srb->ScsiStatus == SCSISTAT_RESERVATION_CONFLICT) {
2713 
2715  retry = FALSE;
2716 
2717  }
2718 
2719  break;
2720 
2721  default:
2722  logError = TRUE;
2723  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2724  uniqueId = 259;
2726  break;
2727 
2728  }
2729 
2730  //
2731  // If the error count has exceeded the error limit, then disable
2732  // any tagged queuing, multiple requests per lu queueing
2733  // and synchronous data transfers.
2734  //
2735 
2736  if (deviceExtension->ErrorCount == 4) {
2737 
2738  //
2739  // Clearing the no queue freeze flag prevents the port driver
2740  // from sending multiple requests per logical unit.
2741  //
2742 
2743  deviceExtension->SrbFlags &= ~(SRB_FLAGS_QUEUE_ACTION_ENABLE |
2745 
2746  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2747  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling tagged queuing and synchronous data tranfers.\n"));
2748 
2749  } else if (deviceExtension->ErrorCount == 8) {
2750 
2751  //
2752  // If a second threshold is reached, disable disconnects.
2753  //
2754 
2755  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
2756  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling disconnects.\n"));
2757  }
2758  }
2759 
2760  //
2761  // If there is a class specific error handler call it.
2762  //
2763 
2764  if (deviceExtension->ClassError != NULL) {
2765 
2766  deviceExtension->ClassError(DeviceObject,
2767  Srb,
2768  Status,
2769  &retry);
2770  }
2771 
2772  //
2773  // Log an error if necessary.
2774  //
2775 
2776  if (logError) {
2777 
2779  DeviceObject,
2780  sizeof(IO_ERROR_LOG_PACKET) + 5 * sizeof(ULONG));
2781 
2782  if (errorLogEntry == NULL) {
2783 
2784  //
2785  // Return if no packet could be allocated.
2786  //
2787 
2788  return retry;
2789 
2790  }
2791 
2792  if (retry && RetryCount < MAXIMUM_RETRIES) {
2793  errorLogEntry->FinalStatus = STATUS_SUCCESS;
2794  } else {
2795  errorLogEntry->FinalStatus = *Status;
2796  }
2797 
2798  //
2799  // Calculate the device offset if there is a geometry.
2800  //
2801 
2802  if (deviceExtension->DiskGeometry != NULL) {
2803 
2804  errorLogEntry->DeviceOffset.QuadPart = (LONGLONG) badSector;
2805  errorLogEntry->DeviceOffset = RtlExtendedIntegerMultiply(
2806  errorLogEntry->DeviceOffset,
2807  deviceExtension->DiskGeometry->Geometry.BytesPerSector);
2808  }
2809 
2810  errorLogEntry->ErrorCode = logStatus;
2811  errorLogEntry->SequenceNumber = 0;
2812  errorLogEntry->MajorFunctionCode = MajorFunctionCode;
2813  errorLogEntry->IoControlCode = IoDeviceCode;
2814  errorLogEntry->RetryCount = (UCHAR) RetryCount;
2815  errorLogEntry->UniqueErrorValue = uniqueId;
2816  errorLogEntry->DumpDataSize = 6 * sizeof(ULONG);
2817  errorLogEntry->DumpData[0] = Srb->PathId;
2818  errorLogEntry->DumpData[1] = Srb->TargetId;
2819  errorLogEntry->DumpData[2] = Srb->Lun;
2820  errorLogEntry->DumpData[3] = 0;
2821  errorLogEntry->DumpData[4] = Srb->SrbStatus << 8 | Srb->ScsiStatus;
2822 
2823  if (senseBuffer != NULL) {
2824  errorLogEntry->DumpData[5] = senseBuffer->SenseKey << 16 |
2825  senseBuffer->AdditionalSenseCode << 8 |
2826  senseBuffer->AdditionalSenseCodeQualifier;
2827 
2828  }
2829 
2830  //
2831  // Write the error log packet.
2832  //
2833 
2834  IoWriteErrorLogEntry(errorLogEntry);
2835  }
2836 
2837  return retry;
2838 
2839 } // 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 TRUE
Definition: types.h:120
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
NTSTATUS FinalStatus
Definition: iotypes.h:1966
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
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:620
LONG KPRIORITY
Definition: compat.h:462
LARGE_INTEGER DeviceOffset
Definition: iotypes.h:1969
#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
NTSTATUS ErrorCode
Definition: iotypes.h:1964
#define SCSI_ADSENSE_REC_DATA_NOECC
Definition: cdrw_hw.h:1211
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_PARITY_ERROR
Definition: srb.h:346
#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED
Definition: cdrw_hw.h:1315
#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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#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
NTSYSAPI LONGLONG WINAPI RtlExtendedIntegerMultiply(LONGLONG, INT)
UCHAR Information[4]
Definition: cdrw_hw.h:1172
#define MAXIMUM_RETRIES
Definition: class2.h:14
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:520
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
int64_t LONGLONG
Definition: typedefs.h:66
#define SCSI_ADSENSE_SEEK_ERROR
Definition: cdrw_hw.h:1232
#define SCSI_ADSENSE_ILLEGAL_BLOCK
Definition: cdrw_hw.h:1264
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:465
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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
Status
Definition: gdiplustypes.h:24
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI StartUnit(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:1081
#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:254
unsigned int * PULONG
Definition: retypes.h:1
UCHAR IncorrectLength
Definition: cdrw_hw.h:1169
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define DEV_SAFE_START_UNIT
Definition: class2.h:35
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
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
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define VPB_MOUNTED
Definition: iotypes.h:1764
#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:465
LONGLONG QuadPart
Definition: typedefs.h:112
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288

Referenced by CdRomDeviceControlCompletion(), CdRomSetVolumeIntermediateCompletion(), CdRomSwitchModeCompletion(), CdRomUpdateGeometryCompletion(), CdRomXACompletion(), ScsiClassIoComplete(), ScsiClassIoCompleteAssociated(), and ScsiClassSendSrbSynchronous().

◆ ScsiClassIoComplete()

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

Definition at line 1491 of file class2.c.

1522 {
1525  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1526  NTSTATUS status;
1527  BOOLEAN retry;
1528 
1529  ASSERT(*(PULONG)deviceExtension != '2slc');
1530 
1531  //
1532  // Check SRB status for success of completing request.
1533  //
1534 
1535  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1536 
1537  DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
1538 
1539  //
1540  // Release the queue if it is frozen.
1541  //
1542 
1543  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1545  }
1546 
1548  DeviceObject,
1549  srb,
1550  irpStack->MajorFunction,
1551  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1552  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1553  &status);
1554 
1555  //
1556  // If the status is verified required and the this request
1557  // should bypass verify required then retry the request.
1558  //
1559 
1560  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1562 
1564  retry = TRUE;
1565  }
1566 
1567  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1568 
1569  //
1570  // Retry request.
1571  //
1572 
1573  DebugPrint((1, "Retry request %lx\n", Irp));
1576  }
1577  } else {
1578 
1579  //
1580  // Set status for successful request.
1581  //
1582 
1584 
1585  } // end if (SRB_STATUS(srb->SrbStatus) ...
1586 
1587  //
1588  // Return SRB to list.
1589  //
1590 
1591  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1592  srb);
1593 
1594  //
1595  // Set status in completing IRP.
1596  //
1597 
1598  Irp->IoStatus.Status = status;
1599  if ((NT_SUCCESS(status)) && (Irp->Flags & IRP_PAGING_IO)) {
1600  ASSERT(Irp->IoStatus.Information);
1601  }
1602 
1603  //
1604  // Set the hard error if necessary.
1605  //
1606 
1608 
1609  //
1610  // Store DeviceObject for filesystem, and clear
1611  // in IoStatus.Information field.
1612  //
1613 
1615  Irp->IoStatus.Information = 0;
1616  }
1617 
1618  //
1619  // If pending has be returned for this irp then mark the current stack as
1620  // pending.
1621  //
1622 
1623  if (Irp->PendingReturned) {
1625  }
1626 
1627  if (deviceExtension->ClassStartIo) {
1628  if (irpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL) {
1630  }
1631  }
1632 
1633  return status;
1634 
1635 } // end ScsiClassIoComplete()
#define TRUE
Definition: types.h:120
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
Definition: class2.c:2844
#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:63
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:938
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define MAXIMUM_RETRIES
Definition: class2.h:14
#define PtrToUlong(u)
Definition: config.h:107
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:2147
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
unsigned int * PULONG
Definition: retypes.h:1
#define IRP_PAGING_IO
struct tagContext Context
Definition: acpixf.h:1030
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
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

Referenced by RetryRequest(), ScsiClassBuildRequest(), ScsiClassSendSrbAsynchronous(), and ScsiDiskShutdownFlush().

◆ ScsiClassIoCompleteAssociated()

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

Definition at line 1640 of file class2.c.

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

Referenced by RetryRequest(), and ScsiClassSplitRequest().

◆ ScsiClassModeSense()

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

Definition at line 3198 of file class2.c.

3227 {
3228  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3229  PCDB cdb;
3230  SCSI_REQUEST_BLOCK srb;
3231  ULONG retries = 1;
3232  NTSTATUS status;
3233 
3234  ASSERT(*(PULONG)deviceExtension != '2slc');
3235 
3236  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3237 
3238  //
3239  // Build the MODE SENSE CDB.
3240  //
3241 
3242  srb.CdbLength = 6;
3243  cdb = (PCDB)srb.Cdb;
3244 
3245  //
3246  // Set timeout value from device extension.
3247  //
3248 
3249  srb.TimeOutValue = deviceExtension->TimeOutValue;
3250 
3251  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
3252  cdb->MODE_SENSE.PageCode = PageMode;
3253  cdb->MODE_SENSE.AllocationLength = (UCHAR)Length;
3254 
3255 Retry:
3256 
3258  &srb,
3259  ModeSenseBuffer,
3260  Length,
3261  FALSE);
3262 
3263 
3264  if (status == STATUS_VERIFY_REQUIRED) {
3265 
3266  //
3267  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3268  // this status. MODE SENSE commands should be retried anyway.
3269  //
3270 
3271  if (retries--) {
3272 
3273  //
3274  // Retry request.
3275  //
3276 
3277  goto Retry;
3278  }
3279 
3280  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3282  }
3283 
3284  if (NT_SUCCESS(status)) {
3285  return(srb.DataTransferLength);
3286  } else {
3287  return(0);
3288  }
3289 
3290 } // end ScsiClassModeSense()
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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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 NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2938
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:1855
Definition: ps.c:97

Referenced by DisableWriteCache(), IsFloppyDevice(), and ScsiDiskDeviceControl().

◆ ScsiClassPlugPlay()

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

Definition at line 136 of file class2.c.

139 {
141 
143  {
144  Irp->IoStatus.Status = STATUS_SUCCESS;
146  return STATUS_SUCCESS;
147  }
148  else
149  {
150  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
152  return STATUS_NOT_SUPPORTED;
153  }
154 }
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#define IRP_MN_START_DEVICE
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define IO_NO_INCREMENT
Definition: iotypes.h:566
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by ScsiClassInitialize().

◆ ScsiClassQueryTimeOutRegistryValue()

ULONG NTAPI ScsiClassQueryTimeOutRegistryValue ( IN PUNICODE_STRING  RegistryPath)

Definition at line 4816 of file class2.c.

4836 {
4837  //
4838  // Find the appropriate reg. key
4839  //
4840 
4841  PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
4842  PWSTR path;
4843  NTSTATUS status;
4844  LONG timeOut = 0;
4845  ULONG zero = 0;
4846  ULONG size;
4847 
4848  if (!RegistryPath) {
4849  return 0;
4850  }
4851 
4852  parameters = ExAllocatePool(NonPagedPool,
4853  sizeof(RTL_QUERY_REGISTRY_TABLE)*2);
4854 
4855  if (!parameters) {
4856  return 0;
4857  }
4858 
4859  size = RegistryPath->MaximumLength + sizeof(WCHAR);
4861 
4862  if (!path) {
4863  ExFreePool(parameters);
4864  return 0;
4865  }
4866 
4869 
4870 
4871  //
4872  // Check for the Timeout value.
4873  //
4874 
4875  RtlZeroMemory(parameters,
4876  (sizeof(RTL_QUERY_REGISTRY_TABLE)*2));
4877 
4878  parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
4879  parameters[0].Name = L"TimeOutValue";
4880  parameters[0].EntryContext = &timeOut;
4881  parameters[0].DefaultType = REG_DWORD;
4882  parameters[0].DefaultData = &zero;
4883  parameters[0].DefaultLength = sizeof(ULONG);
4884 
4886  path,
4887  parameters,
4888  NULL,
4889  NULL);
4890 
4891  if (!(NT_SUCCESS(status))) {
4892  timeOut = 0;
4893  }
4894 
4895  ExFreePool(parameters);
4896  ExFreePool(path);
4897 
4898  DebugPrint((2,
4899  "ScsiClassQueryTimeOutRegistryValue: Timeout value %d\n",
4900  timeOut));
4901 
4902 
4903  return timeOut;
4904 
4905 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT MaximumLength
Definition: env_spec_w32.h:370
GLsizei const GLchar ** path
Definition: glext.h:7234
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#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
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
static double zero
Definition: j0_y0.c:96
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
Definition: services.c:325
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#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 {
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 media capacity in bytes.
832  //
833 
834  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
835 
836  //
837  // Calculate number of cylinders.
838  //
839 
840  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(DEFAULT_SECTORS_PER_TRACK * DEFAULT_TRACKS_PER_CYLINDER));
841 
842  deviceExtension->PartitionLength.QuadPart =
843  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
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 
907  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
908 
909  //
910  // This device supports removable media.
911  //
912 
913  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
914 
915  } else {
916 
917  //
918  // Assume media type is fixed disk.
919  //
920 
921  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
922  }
923  }
924 
925  //
926  // Deallocate read capacity buffer.
927  //
928 
929  ExFreePool(readCapacityBuffer);
930 
931  return status;
932 
933 } // 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
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define DEFAULT_SECTORS_PER_TRACK
Definition: class2.c:37
PVOID DeviceExtension
Definition: env_spec_w32.h:418
union _CDB * PCDB
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
int64_t LONGLONG
Definition: typedefs.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int * 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:261
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:1855
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DEFAULT_TRACKS_PER_CYLINDER
Definition: class2.c:38
Definition: ps.c:97

Referenced by CreateCdRomDeviceObject(), CreateDiskDeviceObject(), ScsiDiskDeviceControl(), and UpdateRemovableGeometry().

◆ ScsiClassReadWrite()

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

Definition at line 347 of file class2.c.

372 {
375  ULONG transferPages;
376  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
377  ULONG maximumTransferLength = deviceExtension->PortCapabilities->MaximumTransferLength;
379 
380  ASSERT(*(PULONG)deviceExtension != '2slc');
381 
383  !(currentIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME)) {
384 
385  //
386  // if DO_VERIFY_VOLUME bit is set
387  // in device object flags, fail request.
388  //
389 
391 
392  Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
393  Irp->IoStatus.Information = 0;
394 
396  return STATUS_VERIFY_REQUIRED;
397  }
398 
399  //
400  // Invoke the device specific routine to do whatever it needs to verify
401  // this request.
402  //
403 
404  ASSERT(deviceExtension->ClassReadWriteVerification);
405 
406  status = deviceExtension->ClassReadWriteVerification(DeviceObject,Irp);
407 
408  if (!NT_SUCCESS(status)) {
409 
410  //
411  // It is up to the device specific driver to set the Irp status.
412  //
413 
415  return status;
416  } else if (status == STATUS_PENDING) {
417 
419  return STATUS_PENDING;
420  }
421 
422  //
423  // Check for a zero length IO, as several macros will turn this into
424  // seemingly a 0xffffffff length request.
425  //
426 
427  if (transferByteCount == 0) {
428  Irp->IoStatus.Status = STATUS_SUCCESS;
429  Irp->IoStatus.Information = 0;
431  return STATUS_SUCCESS;
432 
433  }
434 
435  if (deviceExtension->ClassStartIo) {
436 
438 
440  Irp,
441  NULL,
442  NULL);
443 
444  return STATUS_PENDING;
445  }
446 
447  //
448  // Mark IRP with status pending.
449  //
450 
452 
453  //
454  // Add partition byte offset to make starting byte relative to
455  // beginning of disk. In addition, add in skew for DM Driver, if any.
456  //
457 
458  currentIrpStack->Parameters.Read.ByteOffset.QuadPart += (deviceExtension->StartingOffset.QuadPart +
459  deviceExtension->DMByteSkew);
460 
461  //
462  // Calculate number of pages in this transfer.
463  //
464 
465  transferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
466  currentIrpStack->Parameters.Read.Length);
467 
468  //
469  // Check if request length is greater than the maximum number of
470  // bytes that the hardware can transfer.
471  //
472 
473  if (currentIrpStack->Parameters.Read.Length > maximumTransferLength ||
474  transferPages > deviceExtension->PortCapabilities->MaximumPhysicalPages) {
475 
476  DebugPrint((2,"ScsiClassReadWrite: Request greater than maximum\n"));
477  DebugPrint((2,"ScsiClassReadWrite: Maximum is %lx\n",
478  maximumTransferLength));
479  DebugPrint((2,"ScsiClassReadWrite: Byte count is %lx\n",
480  currentIrpStack->Parameters.Read.Length));
481 
482  transferPages =
483  deviceExtension->PortCapabilities->MaximumPhysicalPages - 1;
484 
485  if (maximumTransferLength > transferPages << PAGE_SHIFT ) {
486  maximumTransferLength = transferPages << PAGE_SHIFT;
487  }
488 
489  //
490  // Check that maximum transfer size is not zero.
491  //
492 
493  if (maximumTransferLength == 0) {
494  maximumTransferLength = PAGE_SIZE;
495  }
496 
497  //
498  // Mark IRP with status pending.
499  //
500 
502 
503  //
504  // Request greater than port driver maximum.
505  // Break up into smaller routines.
506  //
507 
508  ScsiClassSplitRequest(DeviceObject, Irp, maximumTransferLength);
509 
510 
511  return STATUS_PENDING;
512  }
513 
514  //
515  // Build SRB and CDB for this IRP.
516  //
517 
519 
520  //
521  // Return the results of the call to the port driver.
522  //
523 
524  return IoCallDriver(deviceExtension->PortDeviceObject, Irp);
525 
526 } // end ScsiClassReadWrite()
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
VOID NTAPI ScsiClassSplitRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG MaximumBytes)
Definition: class2.c:1297
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
unsigned int * PULONG
Definition: retypes.h:1
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:2969
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by ScsiClassInitialize().

◆ ScsiClassReleaseQueue()

VOID NTAPI ScsiClassReleaseQueue ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 938 of file class2.c.

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

Referenced by CdRomDeviceControlCompletion(), CdRomMediaChangeCompletion(), CdRomSetVolumeIntermediateCompletion(), CdRomSwitchModeCompletion(), CdRomUpdateGeometryCompletion(), CdRomXACompletion(), ScsiClassAsynchronousCompletion(), ScsiClassIoComplete(), ScsiClassIoCompleteAssociated(), ScsiClassSendSrbSynchronous(), and ToshibaProcessErrorCompletion().

◆ ScsiClassSendSrbAsynchronous()

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

Definition at line 3369 of file class2.c.

3405 {
3406 
3407  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3408  PIO_STACK_LOCATION irpStack;
3409 
3410  PAGED_CODE();
3411 
3412  ASSERT(*(PULONG)deviceExtension != '2slc');
3413 
3414  //
3415  // Write length to SRB.
3416  //
3417 
3418  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
3419 
3420  //
3421  // Set SCSI bus address.
3422  //
3423 
3424  Srb->PathId = deviceExtension->PathId;
3425  Srb->TargetId = deviceExtension->TargetId;
3426  Srb->Lun = deviceExtension->Lun;
3427 
3428  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
3429 
3430  //
3431  // This is a violation of the SCSI spec but it is required for
3432  // some targets.
3433  //
3434 
3435  Srb->Cdb[1] |= deviceExtension->Lun << 5;
3436 
3437  //
3438  // Indicate auto request sense by specifying buffer and size.
3439  //
3440 
3441  Srb->SenseInfoBuffer = deviceExtension->SenseData;
3442  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
3443  Srb->DataBuffer = BufferAddress;
3444 
3445  if (BufferAddress != NULL) {
3446 
3447  //
3448  // Build Mdl if necessary.
3449  //
3450 
3451  if (Irp->MdlAddress == NULL) {
3452 
3453  if (IoAllocateMdl(BufferAddress,