ReactOS  0.4.15-dev-506-ga3ec01c
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 4975 of file class2.c.

4978 {
4979  PIO_STATUS_BLOCK IoStatusBlock = Irp->UserIosb;
4980  PKEVENT Event = Irp->UserEvent;
4981  PMDL Mdl;
4982 
4983  *IoStatusBlock = Irp->IoStatus;
4984  Irp->UserIosb = NULL;
4985  Irp->UserEvent = NULL;
4986 
4987  if(Irp->MdlAddress)
4988  {
4989  Mdl = Irp->MdlAddress;
4990 
4991  // if necessary - unlock pages
4992  if ((Mdl->MdlFlags & MDL_PAGES_LOCKED) &&
4993  !(Mdl->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED))
4994  {
4995  MmUnlockPages(Mdl);
4996  }
4997 
4998  // free this mdl
4999  IoFreeMdl(Mdl);
5000  }
5001 
5002  // free irp and set event to unsignaled state
5003  IoFreeIrp(Irp);
5005 
5007 }
#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:568

Referenced by ScsiClassSendSrbSynchronous().

◆ ClassIoCompletion()

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

Definition at line 4731 of file class2.c.

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

Referenced by ScsiClassDeviceControl().

◆ RetryRequest()

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

Definition at line 2845 of file class2.c.

2875 {
2876  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2879  ULONG transferByteCount;
2880 
2881  ASSERT(*(PULONG)deviceExtension != '2slc');
2882 
2883  //
2884  // Determine the transfer count of the request. If this is a read or a
2885  // write then the transfer count is in the Irp stack. Otherwise assume
2886  // the MDL contains the correct length. If there is no MDL then the
2887  // transfer length must be zero.
2888  //
2889 
2890  if (currentIrpStack->MajorFunction == IRP_MJ_READ ||
2891  currentIrpStack->MajorFunction == IRP_MJ_WRITE) {
2892 
2893  transferByteCount = currentIrpStack->Parameters.Read.Length;
2894 
2895  } else if (Irp->MdlAddress != NULL) {
2896 
2897  //
2898  // Note this assumes that only read and write requests are spilt and
2899  // other request do not need to be. If the data buffer address in
2900  // the MDL and the SRB don't match then transfer length is most
2901  // likely incorrect.
2902  //
2903 
2904  ASSERT(Srb->DataBuffer == MmGetMdlVirtualAddress(Irp->MdlAddress));
2905  transferByteCount = Irp->MdlAddress->ByteCount;
2906 
2907  } else {
2908 
2909  transferByteCount = 0;
2910  }
2911 
2912  //
2913  // Reset byte count of transfer in SRB Extension.
2914  //
2915 
2916  Srb->DataTransferLength = transferByteCount;
2917 
2918  //
2919  // Zero SRB statuses.
2920  //
2921 
2922  Srb->SrbStatus = Srb->ScsiStatus = 0;
2923 
2924  //
2925  // Set the no disconnect flag, disable synchronous data transfers and
2926  // disable tagged queuing. This fixes some errors.
2927  //
2928 
2929  Srb->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT |
2931 
2932  Srb->SrbFlags &= ~SRB_FLAGS_QUEUE_ACTION_ENABLE;
2933  Srb->QueueTag = SP_UNTAGGED;
2934 
2935  //
2936  // Set up major SCSI function.
2937  //
2938 
2939  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
2940 
2941  //
2942  // Save SRB address in next stack for port driver.
2943  //
2944 
2945  nextIrpStack->Parameters.Scsi.Srb = Srb;
2946 
2947  //
2948  // Set up IoCompletion routine address.
2949  //
2950 
2951  if (Associated) {
2952 
2954 
2955  } else {
2956 
2958  }
2959 
2960  //
2961  // Pass the request to the port driver.
2962  //
2963 
2964  (VOID)IoCallDriver(deviceExtension->PortDeviceObject, Irp);
2965 
2966 } // end RetryRequest()
NTSTATUS NTAPI ScsiClassIoCompleteAssociated(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1641
#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:498
#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:1492
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:1569
__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:2774
#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 1217 of file class2.c.

1246 {
1248  PSCSI_REQUEST_BLOCK srb;
1249 
1250  srb = &context->Srb;
1251 
1252  //
1253  // If this is an execute srb, then check the return status and make sure.
1254  // the queue is not frozen.
1255  //
1256 
1257  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
1258 
1259  //
1260  // Check for a frozen queue.
1261  //
1262 
1263  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1264 
1265  //
1266  // Unfreeze the queue getting the device object from the context.
1267  //
1268 
1269  ScsiClassReleaseQueue(context->DeviceObject);
1270  }
1271  }
1272 
1273  //
1274  // Free the context and the Irp.
1275  //
1276 
1277  if (Irp->MdlAddress != NULL) {
1278  MmUnlockPages(Irp->MdlAddress);
1279  IoFreeMdl(Irp->MdlAddress);
1280 
1281  Irp->MdlAddress = NULL;
1282  }
1283 
1285  IoFreeIrp(Irp);
1286 
1287  //
1288  // Indicate the I/O system should stop processing the Irp completion.
1289  //
1290 
1292 
1293 } // ScsiClassAsynchronousCompletion()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:7094
_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:939
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:1034
#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 2970 of file class2.c.

3004 {
3005  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3008  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
3009  PSCSI_REQUEST_BLOCK srb;
3010  PCDB cdb;
3011  ULONG logicalBlockAddress;
3012  USHORT transferBlocks;
3013 
3014  ASSERT(*(PULONG)deviceExtension != '2slc');
3015 
3016  //
3017  // Calculate relative sector address.
3018  //
3019 
3020  logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
3021 
3022  //
3023  // Allocate an Srb.
3024  //
3025 
3026  srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
3027 
3028  srb->SrbFlags = 0;
3029 
3030  //
3031  // Write length to SRB.
3032  //
3033 
3035 
3036  //
3037  // Set up IRP Address.
3038  //
3039 
3040  srb->OriginalRequest = Irp;
3041 
3042  //
3043  // Set up target ID and logical unit number.
3044  //
3045 
3046  srb->PathId = deviceExtension->PathId;
3047  srb->TargetId = deviceExtension->TargetId;
3048  srb->Lun = deviceExtension->Lun;
3050  srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
3051 
3052  //
3053  // Save byte count of transfer in SRB Extension.
3054  //
3055 
3056  srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
3057 
3058  //
3059  // Initialize the queue actions field.
3060  //
3061 
3063 
3064  //
3065  // Queue sort key is Relative Block Address.
3066  //
3067 
3068  srb->QueueSortKey = logicalBlockAddress;
3069 
3070  //
3071  // Indicate auto request sense by specifying buffer and size.
3072  //
3073 
3074  srb->SenseInfoBuffer = deviceExtension->SenseData;
3076 
3077  //
3078  // Set timeout value of one unit per 64k bytes of data.
3079  //
3080 
3081  srb->TimeOutValue = ((srb->DataTransferLength + 0xFFFF) >> 16) *
3082  deviceExtension->TimeOutValue;
3083 
3084  //
3085  // Zero statuses.
3086  //
3087 
3088  srb->SrbStatus = srb->ScsiStatus = 0;
3089  srb->NextSrb = 0;
3090 
3091  //
3092  // Indicate that 10-byte CDB's will be used.
3093  //
3094 
3095  srb->CdbLength = 10;
3096 
3097  //
3098  // Fill in CDB fields.
3099  //
3100 
3101  cdb = (PCDB)srb->Cdb;
3102 
3103  //
3104  // Zero 12 bytes for Atapi Packets
3105  //
3106 
3108 
3109  cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
3110  transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
3111 
3112  //
3113  // Move little endian values into CDB in big endian format.
3114  //
3115 
3116  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
3117  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
3118  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
3119  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
3120 
3121  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
3122  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
3123 
3124  //
3125  // Set transfer direction flag and Cdb command.
3126  //
3127 
3128  if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
3129 
3130  DebugPrint((3, "ScsiClassBuildRequest: Read Command\n"));
3131 
3132  srb->SrbFlags |= SRB_FLAGS_DATA_IN;
3133  cdb->CDB10.OperationCode = SCSIOP_READ;
3134 
3135  } else {
3136 
3137  DebugPrint((3, "ScsiClassBuildRequest: Write Command\n"));
3138 
3139  srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
3140  cdb->CDB10.OperationCode = SCSIOP_WRITE;
3141  }
3142 
3143  //
3144  // If this is not a write-through request, then allow caching.
3145  //
3146 
3147  if (!(currentIrpStack->Flags & SL_WRITE_THROUGH)) {
3148 
3150 
3151  } else {
3152 
3153  //
3154  // If write caching is enable then force media access in the
3155  // cdb.
3156  //
3157 
3158  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
3159  cdb->CDB10.ForceUnitAccess = TRUE;
3160  }
3161  }
3162 
3163  //
3164  // Or in the default flags from the device object.
3165  //
3166 
3167  srb->SrbFlags |= deviceExtension->SrbFlags;
3168 
3169  //
3170  // Set up major SCSI function.
3171  //
3172 
3173  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
3174 
3175  //
3176  // Save SRB address in next stack for port driver.
3177  //
3178 
3179  nextIrpStack->Parameters.Scsi.Srb = srb;
3180 
3181  //
3182  // Save retry count in current IRP stack.
3183  //
3184 
3185  currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3186 
3187  //
3188  // Set up IoCompletion routine address.
3189  //
3190 
3192 
3193  return;
3194 
3195 } // 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:498
#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:1492
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:1569
__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:1783
#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:2774
ULONG QueueSortKey
Definition: srb.h:262
LONGLONG QuadPart
Definition: typedefs.h:113

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

◆ ScsiClassCheckVerifyComplete()

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

Definition at line 4910 of file class2.c.

4939 {
4941  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4942  PDEVICE_EXTENSION physicalExtension =
4943  deviceExtension->PhysicalDevice->DeviceExtension;
4944  PIRP originalIrp;
4945 
4946  ASSERT(*(PULONG)deviceExtension != '2slc');
4947  ASSERT(*(PULONG)physicalExtension != '2slc');
4948 
4949  originalIrp = irpStack->Parameters.Others.Argument1;
4950 
4951  //
4952  // Copy the media change count and status
4953  //
4954 
4955  *((PULONG) (originalIrp->AssociatedIrp.SystemBuffer)) =
4956  physicalExtension->MediaChangeCount;
4957 
4958  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change count for"
4959  "device %d is %d\n",
4960  physicalExtension->DeviceNumber,
4961  physicalExtension->MediaChangeCount));
4962 
4963  originalIrp->IoStatus.Status = Irp->IoStatus.Status;
4964  originalIrp->IoStatus.Information = sizeof(ULONG);
4965 
4966  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
4967 
4968  IoFreeIrp(Irp);
4969 
4971 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
IO_STATUS_BLOCK IoStatus
#define IO_DISK_INCREMENT
Definition: iotypes.h:570
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:1569
__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:2774

Referenced by ScsiClassDeviceControl().

◆ ScsiClassClaimDevice()

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

Definition at line 4489 of file class2.c.

4520 {
4521  IO_STATUS_BLOCK ioStatus;
4522  PIRP irp;
4523  PIO_STACK_LOCATION irpStack;
4524  KEVENT event;
4525  NTSTATUS status;
4526  SCSI_REQUEST_BLOCK srb;
4527 
4528  PAGED_CODE();
4529 
4530  if (NewPortDeviceObject != NULL) {
4531  *NewPortDeviceObject = NULL;
4532  }
4533 
4534  //
4535  // Clear the SRB fields.
4536  //
4537 
4538  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
4539 
4540  //
4541  // Write length to SRB.
4542  //
4543 
4545 
4546  //
4547  // Set SCSI bus address.
4548  //
4549 
4550  srb.PathId = LunInfo->PathId;
4551  srb.TargetId = LunInfo->TargetId;
4552  srb.Lun = LunInfo->Lun;
4553 
4556 
4557  //
4558  // Set the event object to the unsignaled state.
4559  // It will be used to signal request completion.
4560  //
4561 
4563 
4564  //
4565  // Build synchronous request with no transfer.
4566  //
4567 
4569  PortDeviceObject,
4570  NULL,
4571  0,
4572  NULL,
4573  0,
4574  TRUE,
4575  &event,
4576  &ioStatus);
4577 
4578  if (irp == NULL) {
4579 
4580  DebugPrint((1, "ScsiClassClaimDevice: Can't allocate Irp\n"));
4582  }
4583 
4584  irpStack = IoGetNextIrpStackLocation(irp);
4585 
4586  //
4587  // Save SRB address in next stack for port driver.
4588  //
4589 
4590  irpStack->Parameters.Scsi.Srb = &srb;
4591 
4592  //
4593  // Set up IRP Address.
4594  //
4595 
4596  srb.OriginalRequest = irp;
4597 
4598  //
4599  // Call the port driver with the request and wait for it to complete.
4600  //
4601 
4602  status = IoCallDriver(PortDeviceObject, irp);
4603  if (status == STATUS_PENDING) {
4604 
4606  status = ioStatus.Status;
4607  }
4608 
4609  //
4610  // If this is a release request, then just decrement the reference count
4611  // and return. The status does not matter.
4612  //
4613 
4614  if (Release) {
4615 
4616  //ObDereferenceObject(PortDeviceObject);
4617  return STATUS_SUCCESS;
4618  }
4619 
4620  if (!NT_SUCCESS(status)) {
4621  return status;
4622  }
4623 
4624  ASSERT(srb.DataBuffer != NULL);
4625 
4626  //
4627  // Reference the new port driver object so that it will not go away while
4628  // it is being used.
4629  //
4630 
4632  0,
4633  NULL,
4634  KernelMode );
4635 
4636  if (!NT_SUCCESS(status)) {
4637 
4638  return status;
4639  }
4641 
4642  //
4643  // Return the new port device object pointer.
4644  //
4645 
4646  if (NewPortDeviceObject != NULL) {
4647  *NewPortDeviceObject = srb.DataBuffer;
4648  }
4649 
4650  return status;
4651 }
#define 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 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:2774
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
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:1569
unsigned int * PULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:568
return STATUS_SUCCESS
Definition: btrfs.c:3014

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

4400 {
4401  STRING ntNameString;
4402  UNICODE_STRING ntUnicodeString;
4403  NTSTATUS status;
4404  PDEVICE_OBJECT deviceObject = NULL;
4405 
4406  *DeviceObject = NULL;
4407 
4408  DebugPrint((2,
4409  "ScsiClassCreateDeviceObject: Create device object %s\n",
4410  ObjectNameBuffer));
4411 
4412  RtlInitString(&ntNameString,
4414 
4415  status = RtlAnsiStringToUnicodeString(&ntUnicodeString,
4416  &ntNameString,
4417  TRUE);
4418 
4419  if (!NT_SUCCESS(status)) {
4420 
4421  DebugPrint((1,
4422  "CreateDiskDeviceObjects: Cannot convert string %s\n",
4423  ObjectNameBuffer));
4424 
4425  ntUnicodeString.Buffer = NULL;
4426  return status;
4427  }
4428 
4430  InitializationData->DeviceExtensionSize,
4431  &ntUnicodeString,
4432  InitializationData->DeviceType,
4433  InitializationData->DeviceCharacteristics,
4434  FALSE,
4435  &deviceObject);
4436 
4437 
4438  if (!NT_SUCCESS(status)) {
4439 
4440  DebugPrint((1,
4441  "CreateDiskDeviceObjects: Can not create device object %s\n",
4442  ObjectNameBuffer));
4443 
4444  } else {
4445 
4446  PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
4447 
4448  ASSERT(*(PULONG)deviceExtension != '2slc');
4449 
4450  //
4451  // Fill in entry points
4452  //
4453 
4454  deviceExtension->ClassError = InitializationData->ClassError;
4455  deviceExtension->ClassReadWriteVerification = InitializationData->ClassReadWriteVerification;
4456  deviceExtension->ClassFindDevices = InitializationData->ClassFindDevices;
4457  deviceExtension->ClassDeviceControl = InitializationData->ClassDeviceControl;
4458  deviceExtension->ClassShutdownFlush = InitializationData->ClassShutdownFlush;
4459  deviceExtension->ClassCreateClose = InitializationData->ClassCreateClose;
4460  deviceExtension->ClassStartIo = InitializationData->ClassStartIo;
4461 
4462  deviceExtension->MediaChangeCount = 0;
4463 
4464  //
4465  // If a pointer to the physical device object was passed in then use
4466  // that. If the value was NULL, then this is the physical device so
4467  // use the pointer to the device we just created.
4468  //
4469 
4471  deviceExtension->PhysicalDevice = PhysicalDeviceObject;
4472  } else {
4473  deviceExtension->PhysicalDevice = deviceObject;
4474  }
4475 
4476  deviceExtension->DeviceName = ntUnicodeString;
4477  }
4478 
4479  deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
4480 
4481  *DeviceObject = deviceObject;
4482 
4483  return status;
4484 }
#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:1155
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:1569
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 3603 of file class2.c.

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

3584 {
3585 
3586  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3587 
3588  ASSERT(*(PULONG)deviceExtension != '2slc');
3589 
3590  //
3591  // Call the class specific driver DeviceControl routine.
3592  // If it doesn't handle it, it will call back into ScsiClassDeviceControl.
3593  //
3594 
3595  ASSERT(deviceExtension->ClassDeviceControl);
3596 
3597  return deviceExtension->ClassDeviceControl(DeviceObject,Irp);
3598 }
_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:1569
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 3296 of file class2.c.

3325 {
3326  PUCHAR limit;
3327  ULONG parameterHeaderLength;
3328 
3329  limit = (PUCHAR)ModeSenseBuffer + Length;
3330  parameterHeaderLength = (Use6Byte) ? sizeof(MODE_PARAMETER_HEADER) : sizeof(MODE_PARAMETER_HEADER10);
3331 
3332 
3333  //
3334  // Skip the mode select header and block descriptors.
3335  //
3336 
3337  if (Length < parameterHeaderLength) {
3338  return(NULL);
3339  }
3340 
3341 
3342 
3343  ModeSenseBuffer += parameterHeaderLength + ((Use6Byte) ? ((PMODE_PARAMETER_HEADER) ModeSenseBuffer)->BlockDescriptorLength :
3344  ((PMODE_PARAMETER_HEADER10) ModeSenseBuffer)->BlockDescriptorLength[1]);
3345 
3346  //
3347  // ModeSenseBuffer now points at pages. Walk the pages looking for the
3348  // requested page until the limit is reached.
3349  //
3350 
3351 
3352  while ((PUCHAR)ModeSenseBuffer < limit) {
3353 
3354  if (((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageCode == PageMode) {
3355  return(ModeSenseBuffer);
3356  }
3357 
3358  //
3359  // Advance to the next page.
3360  //
3361 
3362  ModeSenseBuffer += ((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageLength + 2;
3363  }
3364 
3365  return(NULL);
3366 }
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 4317 of file class2.c.

4322 {
4323  ULONG scsiBus,deviceCount = 0;
4324  PCHAR buffer = (PCHAR)AdapterInformation;
4325  PSCSI_INQUIRY_DATA lunInfo;
4326  PINQUIRYDATA inquiryData;
4327 
4328  for (scsiBus=0; scsiBus < (ULONG)AdapterInformation->NumberOfBuses; scsiBus++) {
4329 
4330  //
4331  // Get the SCSI bus scan data for this bus.
4332  //
4333 
4334  lunInfo = (PVOID) (buffer + AdapterInformation->BusData[scsiBus].InquiryDataOffset);
4335 
4336  //
4337  // Search list for unclaimed disk devices.
4338  //
4339 
4340  while (AdapterInformation->BusData[scsiBus].InquiryDataOffset) {
4341 
4342  inquiryData = (PVOID)lunInfo->InquiryData;
4343 
4344  ASSERT(InitializationData->ClassFindDeviceCallBack);
4345 
4346  if ((InitializationData->ClassFindDeviceCallBack(inquiryData)) && (!lunInfo->DeviceClaimed)) {
4347 
4348  deviceCount++;
4349  }
4350 
4351  if (lunInfo->NextInquiryDataOffset == 0) {
4352  break;
4353  }
4354 
4355  lunInfo = (PVOID) (buffer + lunInfo->NextInquiryDataOffset);
4356  }
4357  }
4358  return deviceCount;
4359 }
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
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
#define PAGED_CODE()
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
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
#define PAGED_CODE()
Definition: ps.c:97

◆ ScsiClassInitialize()

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

Definition at line 160 of file class2.c.

185 {
186 
187 
189  ULONG portNumber = 0;
190  PDEVICE_OBJECT portDeviceObject;
192  STRING deviceNameString;
193  UNICODE_STRING unicodeDeviceName;
194  PFILE_OBJECT fileObject;
195  CCHAR deviceNameBuffer[256];
196  BOOLEAN deviceFound = FALSE;
197 
198  DebugPrint((3,"\n\nSCSI Class Driver\n"));
199 
200  //
201  // Validate the length of this structure. This is effectively a
202  // version check.
203  //
204 
205  if (InitializationData->InitializationDataSize > sizeof(CLASS_INIT_DATA)) {
206 
207  DebugPrint((0,"ScsiClassInitialize: Class driver wrong version\n"));
209  }
210 
211  //
212  // Check that each required entry is not NULL. Note that Shutdown, Flush and Error
213  // are not required entry points.
214  //
215 
216  if ((!InitializationData->ClassFindDevices) ||
217  (!InitializationData->ClassDeviceControl) ||
218  (!((InitializationData->ClassReadWriteVerification) ||
219  (InitializationData->ClassStartIo)))) {
220 
221  DebugPrint((0,
222  "ScsiClassInitialize: Class device-specific driver missing required entry\n"));
223 
225  }
226 
227  //
228  // Update driver object with entry points.
229  //
230 
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:3559
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696
#define IRP_MJ_FLUSH_BUFFERS
NTSTATUS NTAPI ScsiClassInternalIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:4656
#define IRP_MJ_SHUTDOWN
NTSTATUS NTAPI ScsiClassCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:297
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
NTSTATUS NTAPI ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:347
NTSTATUS NTAPI ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: class2.c:4264
#define IRP_MJ_SCSI
#define sprintf(buf, format,...)
Definition: sprintf.c:55
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:51
* PFILE_OBJECT
Definition: iotypes.h:1957
#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:2183
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:2181
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: ps.c:97

Referenced by DriverEntry().

◆ ScsiClassInitializeSrbLookasideList()

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

Definition at line 4779 of file class2.c.

4803 {
4804  ExInitializeNPagedLookasideList(&DeviceExtension->SrbLookasideListHead,
4805  NULL,
4806  NULL,
4809  'HscS',
4811 
4812 }
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 4656 of file class2.c.

4685 {
4687  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4688  PSCSI_REQUEST_BLOCK srb;
4689 
4690  ASSERT(*(PULONG)deviceExtension != '2slc');
4691 
4692  //
4693  // Get a pointer to the SRB.
4694  //
4695 
4696  srb = irpStack->Parameters.Scsi.Srb;
4697 
4698  //
4699  // Set SCSI bus address.
4700  //
4701 
4702  srb->PathId = deviceExtension->PathId;
4703  srb->TargetId = deviceExtension->TargetId;
4704  srb->Lun = deviceExtension->Lun;
4705 
4706  //
4707  // NOTICE: The SCSI-II specification indicates that this field should be
4708  // zero; however, some target controllers ignore the logical unit number
4709  // in the IDENTIFY message and only look at the logical unit number field
4710  // in the CDB.
4711  //
4712 
4713  srb->Cdb[1] |= deviceExtension->Lun << 5;
4714 
4715  //
4716  // Set the parameters in the next stack location.
4717  //
4718 
4719  irpStack = IoGetNextIrpStackLocation(Irp);
4720 
4721  irpStack->Parameters.Scsi.Srb = srb;
4722  irpStack->MajorFunction = IRP_MJ_SCSI;
4723  irpStack->MinorFunction = IRP_MN_SCSI_CLASS;
4724 
4726  return IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4727 }
#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:498
#define IRP_MJ_SCSI
NTSTATUS NTAPI ClassIoCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4731
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:1569
__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:2774

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

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

1523 {
1526  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1527  NTSTATUS status;
1528  BOOLEAN retry;
1529 
1530  ASSERT(*(PULONG)deviceExtension != '2slc');
1531 
1532  //
1533  // Check SRB status for success of completing request.
1534  //
1535 
1536  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1537 
1538  DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
1539 
1540  //
1541  // Release the queue if it is frozen.
1542  //
1543 
1544  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1546  }
1547 
1549  DeviceObject,
1550  srb,
1551  irpStack->MajorFunction,
1552  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1553  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1554  &status);
1555 
1556  //
1557  // If the status is verified required and the this request
1558  // should bypass verify required then retry the request.
1559  //
1560 
1561  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1563 
1565  retry = TRUE;
1566  }
1567 
1568  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1569 
1570  //
1571  // Retry request.
1572  //
1573 
1574  DebugPrint((1, "Retry request %lx\n", Irp));
1577  }
1578  } else {
1579 
1580  //
1581  // Set status for successful request.
1582  //
1583 
1585 
1586  } // end if (SRB_STATUS(srb->SrbStatus) ...
1587 
1588  //
1589  // Return SRB to list.
1590  //
1591 
1592  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1593  srb);
1594 
1595  //
1596  // Set status in completing IRP.
1597  //
1598 
1599  Irp->IoStatus.Status = status;
1600  if ((NT_SUCCESS(status)) && (Irp->Flags & IRP_PAGING_IO)) {
1601  ASSERT(Irp->IoStatus.Information);
1602  }
1603 
1604  //
1605  // Set the hard error if necessary.
1606  //
1607 
1609 
1610  //
1611  // Store DeviceObject for filesystem, and clear
1612  // in IoStatus.Information field.
1613  //
1614 
1616  Irp->IoStatus.Information = 0;
1617  }
1618 
1619  //
1620  // If pending has be returned for this irp then mark the current stack as
1621  // pending.
1622  //
1623 
1624  if (Irp->PendingReturned) {
1626  }
1627 
1628  if (deviceExtension->ClassStartIo) {
1629  if (irpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL) {
1631  }
1632  }
1633 
1634  return status;
1635 
1636 } // end ScsiClassIoComplete()
#define 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:2845
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1782
#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:2148
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__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:1034
#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:2774
return STATUS_SUCCESS
Definition: btrfs.c:3014
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 1641 of file class2.c.

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

3228 {
3229  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3230  PCDB cdb;
3231  SCSI_REQUEST_BLOCK srb;
3232  ULONG retries = 1;
3233  NTSTATUS status;
3234 
3235  ASSERT(*(PULONG)deviceExtension != '2slc');
3236 
3237  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3238 
3239  //
3240  // Build the MODE SENSE CDB.
3241  //
3242 
3243  srb.CdbLength = 6;
3244  cdb = (PCDB)srb.Cdb;
3245 
3246  //
3247  // Set timeout value from device extension.
3248  //
3249 
3250  srb.TimeOutValue = deviceExtension->TimeOutValue;
3251 
3252  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
3253  cdb->MODE_SENSE.PageCode = PageMode;
3254  cdb->MODE_SENSE.AllocationLength = (UCHAR)Length;
3255 
3256 Retry:
3257 
3259  &srb,
3260  ModeSenseBuffer,
3261  Length,
3262  FALSE);
3263 
3264 
3265  if (status == STATUS_VERIFY_REQUIRED) {
3266 
3267  //
3268  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3269  // this status. MODE SENSE commands should be retried anyway.
3270  //
3271 
3272  if (retries--) {
3273 
3274  //
3275  // Retry request.
3276  //
3277 
3278  goto Retry;
3279  }
3280 
3281  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3283  }
3284 
3285  if (NT_SUCCESS(status)) {
3286  return(srb.DataTransferLength);
3287  } else {
3288  return(0);
3289  }
3290 
3291 } // end ScsiClassModeSense()
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:1569
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:3014
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:1856
Definition: ps.c:97

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:4137
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define IO_NO_INCREMENT
Definition: iotypes.h:568
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by ScsiClassInitialize().

◆ ScsiClassQueryTimeOutRegistryValue()

ULONG NTAPI ScsiClassQueryTimeOutRegistryValue ( IN PUNICODE_STRING  RegistryPath)

Definition at line 4817 of file class2.c.

4837 {
4838  //
4839  // Find the appropriate reg. key
4840  //
4841 
4842  PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
4843  PWSTR path;
4844  NTSTATUS status;
4845  LONG timeOut = 0;
4846  ULONG zero = 0;
4847  ULONG size;
4848 
4849  if (!RegistryPath) {
4850  return 0;
4851  }
4852 
4853  parameters = ExAllocatePool(NonPagedPool,
4854  sizeof(RTL_QUERY_REGISTRY_TABLE)*2);
4855 
4856  if (!parameters) {
4857  return 0;
4858  }
4859 
4860  size = RegistryPath->MaximumLength + sizeof(WCHAR);
4862 
4863  if (!path) {
4864  ExFreePool(parameters);
4865  return 0;
4866  }
4867 
4870 
4871 
4872  //
4873  // Check for the Timeout value.
4874  //
4875 
4876  RtlZeroMemory(parameters,
4877  (sizeof(RTL_QUERY_REGISTRY_TABLE)*2));
4878 
4879  parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
4880  parameters[0].Name = L"TimeOutValue";
4881  parameters[0].EntryContext = &timeOut;
4882  parameters[0].DefaultType = REG_DWORD;
4883  parameters[0].DefaultData = &zero;
4884  parameters[0].DefaultLength = sizeof(ULONG);
4885 
4887  path,
4888  parameters,
4889  NULL,
4890  NULL);
4891 
4892  if (!(NT_SUCCESS(status))) {
4893  timeOut = 0;
4894  }
4895 
4896  ExFreePool(parameters);
4897  ExFreePool(path);
4898 
4899  DebugPrint((2,
4900  "ScsiClassQueryTimeOutRegistryValue: Timeout value %d\n",
4901  timeOut));
4902 
4903 
4904  return timeOut;
4905 
4906 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
USHORT MaximumLength
Definition: env_spec_w32.h:370
GLsizei const GLchar ** path
Definition: glext.h:7234
uint16_t * PWSTR
Definition: typedefs.h:55
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
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
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:28
#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 number of cylinders.
832  //
833 
834  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(DEFAULT_SECTORS_PER_TRACK * DEFAULT_TRACKS_PER_CYLINDER));
835 
836  //
837  // Calculate media capacity in bytes.
838  //
839 
840  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
841  deviceExtension->PartitionLength.QuadPart =
842  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
843  deviceExtension->DiskGeometry->DiskSize.QuadPart = deviceExtension->PartitionLength.QuadPart;
844 
845  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
846 
847  //
848  // This device supports removable media.
849  //
850 
851  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
852 
853  } else {
854 
855  //
856  // Assume media type is fixed disk.
857  //
858 
859  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
860  }
861 
862  //
863  // Assume sectors per track are DEFAULT_SECTORS_PER_TRACK;
864  //
865 
866  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = DEFAULT_SECTORS_PER_TRACK;
867 
868  //
869  // Assume tracks per cylinder (number of heads) is DEFAULT_TRACKS_PER_CYLINDER.
870  //
871 
872  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = DEFAULT_TRACKS_PER_CYLINDER;
873  }
874 
876 
877  //
878  // Routine ScsiClassSendSrbSynchronous does not retry
879  // requests returned with this status.
880  // Read Capacities should be retried
881  // anyway.
882  //
883 
884  if (retries--) {
885 
886  //
887  // Retry request.
888  //
889 
890  goto Retry;
891  }
892  }
893 
894  if (!NT_SUCCESS(status)) {
895 
896  //
897  // If the read capacity fails, set the geometry to reasonable parameter
898  // so things don't fail at unexpected places. Zero the geometry
899  // except for the bytes per sector and sector shift.
900  //
901 
902  RtlZeroMemory(deviceExtension->DiskGeometry, sizeof(DISK_GEOMETRY_EX));
903  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 512;
904  deviceExtension->SectorShift = 9;
905  deviceExtension->PartitionLength.QuadPart = (LONGLONG) 0;
906  deviceExtension->DiskGeometry->DiskSize.QuadPart = (LONGLONG) 0;
907 
908  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
909 
910  //
911  // This device supports removable media.
912  //
913 
914  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
915 
916  } else {
917 
918  //
919  // Assume media type is fixed disk.
920  //
921 
922  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
923  }
924  }
925 
926  //
927  // Deallocate read capacity buffer.
928  //
929 
930  ExFreePool(readCapacityBuffer);
931 
932  return status;
933 
934 } // end ScsiClassReadDriveCapacity()
struct _FOUR_BYTE * PFOUR_BYTE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR Cdb[16]
Definition: srb.h:271
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
ULONG LogicalBlockAddress
Definition: cdrw_hw.h:1471
struct _CDB::_CDB10 CDB10
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
#define WHICH_BIT(Data, Bit)
Definition: tools.h:80
#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:67
#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:1569
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:1856
#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:1298
#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:1782
#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:1569
__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:2970
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:568
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2774
return STATUS_SUCCESS
Definition: btrfs.c:3014
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 939 of file class2.c.

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

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

3406 {
3407 
3408  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3409  PIO_STACK_LOCATION irpStack;
3410 
3411  PAGED_CODE();
3412 
3413  ASSERT(*(PULONG)deviceExtension != '2slc');
3414 
3415  //
3416  // Write length to SRB.
3417  //
3418 
3419