ReactOS  0.4.15-dev-1374-g8d3e80e
scratch.c File Reference
#include "stddef.h"
#include "string.h"
#include "ntddk.h"
#include "ntddstor.h"
#include "cdrom.h"
#include "ioctl.h"
#include "scratch.h"
#include "mmc.h"
Include dependency graph for scratch.c:

Go to the source code of this file.

Functions

 _IRQL_requires_max_ (APC_LEVEL)
 
VOID ScratchBuffer_ResetItems (_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN ResetRequestHistory)
 
NTSTATUS ScratchBuffer_PerformNextReadWrite (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FirstTry)
 
VOID NTAPI ScratchBuffer_ReadWriteTimerRoutine (struct _KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
 
VOID NTAPI ScratchBuffer_ReadWriteEvtRequestCancel (_In_ WDFREQUEST Request)
 
VOID NTAPI ScratchBuffer_ReadWriteCompletionRoutine (_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_ PWDF_REQUEST_COMPLETION_PARAMS Params, _In_ WDFCONTEXT Context)
 
NTSTATUS ScratchBuffer_SendSrb (_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN SynchronousSrb, _When_(SynchronousSrb, _Pre_null_) _When_(!SynchronousSrb, _In_opt_) PSRB_HISTORY_ITEM *SrbHistoryItem)
 
VOID CompressSrbHistoryData (_Inout_ PSRB_HISTORY RequestHistory)
 
VOID ValidateSrbHistoryDataPresumptions (_In_ SRB_HISTORY const *RequestHistory)
 
VOID ScratchBuffer_SetupReadWriteSrb (_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST OriginalRequest, _In_ LARGE_INTEGER StartingOffset, _In_ ULONG RequiredLength, _Inout_updates_bytes_(RequiredLength) UCHAR *DataBuffer, _In_ BOOLEAN IsReadRequest, _In_ BOOLEAN UsePartialMdl)
 

Variables

EVT_WDF_REQUEST_COMPLETION_ROUTINE ScratchBuffer_ReadWriteCompletionRoutine
 
EVT_WDF_REQUEST_CANCEL ScratchBuffer_ReadWriteEvtRequestCancel
 

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 50 of file scratch.c.

70 {
71  PAGED_CODE ();
72 
73  NT_ASSERT(DeviceExtension->ScratchContext.ScratchInUse == 0);
74 
75  if (DeviceExtension->ScratchContext.ScratchHistory != NULL)
76  {
77  ExFreePool(DeviceExtension->ScratchContext.ScratchHistory);
78  DeviceExtension->ScratchContext.ScratchHistory = NULL;
79  }
80  if (DeviceExtension->ScratchContext.ScratchSense != NULL)
81  {
82  ExFreePool(DeviceExtension->ScratchContext.ScratchSense);
83  DeviceExtension->ScratchContext.ScratchSense = NULL;
84  }
85  if (DeviceExtension->ScratchContext.ScratchSrb != NULL)
86  {
87  ExFreePool(DeviceExtension->ScratchContext.ScratchSrb);
88  DeviceExtension->ScratchContext.ScratchSrb = NULL;
89  }
90  if (DeviceExtension->ScratchContext.ScratchBufferSize != 0)
91  {
92  DeviceExtension->ScratchContext.ScratchBufferSize = 0;
93  }
94  if (DeviceExtension->ScratchContext.ScratchBufferMdl != NULL)
95  {
96  IoFreeMdl(DeviceExtension->ScratchContext.ScratchBufferMdl);
97  DeviceExtension->ScratchContext.ScratchBufferMdl = NULL;
98  }
99  if (DeviceExtension->ScratchContext.ScratchBuffer != NULL)
100  {
101  ExFreePool(DeviceExtension->ScratchContext.ScratchBuffer);
102  DeviceExtension->ScratchContext.ScratchBuffer = NULL;
103  }
104 
105  if (DeviceExtension->ScratchContext.PartialMdl != NULL)
106  {
107  IoFreeMdl(DeviceExtension->ScratchContext.PartialMdl);
108  DeviceExtension->ScratchContext.PartialMdl = NULL;
109  }
110 
111  if (DeviceExtension->ScratchContext.ScratchRequest != NULL)
112  {
113  PIRP irp = WdfRequestWdmGetIrp(DeviceExtension->ScratchContext.ScratchRequest);
114  if (irp->MdlAddress)
115  {
116  irp->MdlAddress = NULL;
117  }
118  WdfObjectDelete(DeviceExtension->ScratchContext.ScratchRequest);
119  DeviceExtension->ScratchContext.ScratchRequest = NULL;
120  }
121 
122  return;
123 }
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define NULL
Definition: types.h:112
FxIrp * irp
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ CompressSrbHistoryData()

VOID CompressSrbHistoryData ( _Inout_ PSRB_HISTORY  RequestHistory)

Definition at line 1033 of file scratch.c.

1051 {
1052  ULONG i;
1053  NT_ASSERT( RequestHistory->UsedHistoryCount == RequestHistory->TotalHistoryCount );
1055 
1056  for (i=0; i < RequestHistory->UsedHistoryCount; i++)
1057  {
1058  // for each item...
1059  PSRB_HISTORY_ITEM toMatch = &( RequestHistory->History[i] );
1060  // hint: read const qualifiers backwards. i.e. srbstatus is a const UCHAR
1061  // so, "UCHAR const * const x" is read "x is a const pointer to a const UCHAR"
1062  // unfortunately, "const UCHAR" is equivalent to "UCHAR const", which causes
1063  // people no end of confusion due to its widespread use.
1064  UCHAR const srbStatus = toMatch->SrbStatus;
1065  UCHAR const sense = toMatch->NormalizedSenseData.SenseKey;
1066  UCHAR const asc = toMatch->NormalizedSenseData.AdditionalSenseCode;
1068  ULONG j;
1069 
1070  // see if there are any at higher indices with identical Sense/ASC/ASCQ
1071  for (j = i+1; (toMatch->ClassDriverUse != 0xFF) && (j < RequestHistory->UsedHistoryCount); j++)
1072  {
1073  PSRB_HISTORY_ITEM found = &( RequestHistory->History[j] );
1074  // close enough match?
1075  if ((srbStatus == found->SrbStatus) &&
1076  (sense == found->NormalizedSenseData.SenseKey) &&
1077  (asc == found->NormalizedSenseData.AdditionalSenseCode) &&
1079 
1080  // add the fields to keep reasonable track of delay times.
1083  } else {
1085  }
1086 
1087  // this found item cannot contain any compressed entries because
1088  // the first entry with a given set of sense/asc/ascq will always
1089  // either be full (0xFF) or be the only partially-full entry with
1090  // that sense/asc/ascq.
1091  NT_ASSERT(found->ClassDriverUse == 0);
1092  // add the counts so we still know how many retries total
1093  toMatch->ClassDriverUse++;
1094 
1095 
1096  // if not the last entry, need to move later entries earlier in the array
1097  if (j != RequestHistory->UsedHistoryCount-1) {
1098  // how many entries remain?
1099  SIZE_T remainingBytes = RequestHistory->UsedHistoryCount - 1 - j;
1100  remainingBytes *= sizeof(SRB_HISTORY_ITEM);
1101 
1102  // note that MOVE is required due to overlapping entries
1103  RtlMoveMemory(found, found+1, remainingBytes);
1104 
1105  // Finally, decrement the number of used history count and
1106  // decrement j to rescan the current location again
1107  --RequestHistory->UsedHistoryCount;
1108  --j;
1109  } // end moving of array elements around
1110  } // end of close enough match
1111  } // end j loop
1112  } // end i loop
1113 
1114  // unable to compress duplicate sense/asc/ascq, so just lose the most recent data
1115  if (RequestHistory->UsedHistoryCount == RequestHistory->TotalHistoryCount)
1116  {
1117  PSRB_HISTORY_ITEM item = &( RequestHistory->History[ RequestHistory->TotalHistoryCount-1 ] );
1118  RequestHistory->ClassDriverUse[0] += item->ClassDriverUse; // how many did we "lose"?
1119  RequestHistory->UsedHistoryCount--;
1120  }
1121 
1122  // finally, zero any that are no longer in use
1123  NT_ASSERT( RequestHistory->UsedHistoryCount != RequestHistory->TotalHistoryCount);
1124  {
1125  SIZE_T bytesToZero = RequestHistory->TotalHistoryCount - RequestHistory->UsedHistoryCount;
1126  bytesToZero *= sizeof(SRB_HISTORY_ITEM);
1127  RtlZeroMemory(&(RequestHistory->History[RequestHistory->UsedHistoryCount]), bytesToZero);
1128  }
1129 
1131  return;
1132 }
UCHAR SrbStatus
Definition: cdromp.h:101
UCHAR ClassDriverUse
Definition: cdromp.h:102
UCHAR SenseKey
Definition: cdrw_hw.h:1167
struct _SRB_HISTORY_ITEM SRB_HISTORY_ITEM
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG _In_ ULONG _In_opt_ SRB_HISTORY * RequestHistory
Definition: classpnp.h:482
VOID ValidateSrbHistoryDataPresumptions(_In_ SRB_HISTORY const *RequestHistory)
Definition: scratch.c:1135
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 GLint GLint j
Definition: glfuncs.h:250
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MAXULONG
Definition: typedefs.h:251
ULONG_PTR SIZE_T
Definition: typedefs.h:80
static ATOM item
Definition: dde.c:856
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
ULONG MillisecondsDelayOnRetry
Definition: cdromp.h:99
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
SENSE_DATA NormalizedSenseData
Definition: cdromp.h:100
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by ScratchBuffer_SendSrb().

◆ ScratchBuffer_PerformNextReadWrite()

NTSTATUS ScratchBuffer_PerformNextReadWrite ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ BOOLEAN  FirstTry 
)

Definition at line 429 of file scratch.c.

448 {
449  PCDROM_SCRATCH_READ_WRITE_CONTEXT readWriteContext = &DeviceExtension->ScratchContext.ScratchReadWriteContext;
450  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(DeviceExtension->ScratchContext.ScratchRequest);
451  WDFREQUEST originalRequest = requestContext->OriginalRequest;
453 
454  ULONG transferSize;
455  BOOLEAN usePartialMdl;
456 
457  transferSize = min((readWriteContext->EntireXferLen - readWriteContext->TransferedBytes), readWriteContext->MaxLength);
458 
459  if (FirstTry)
460  {
461  DeviceExtension->ScratchContext.NumRetries = 0;
462  }
463 
464  ScratchBuffer_ResetItems(DeviceExtension, FALSE);
465 
466  usePartialMdl = (readWriteContext->PacketsCount > 1 || readWriteContext->TransferedBytes > 0);
467 
468  ScratchBuffer_SetupReadWriteSrb(DeviceExtension,
469  originalRequest,
470  readWriteContext->StartingOffset,
471  transferSize,
472  readWriteContext->DataBuffer,
473  readWriteContext->IsRead,
474  usePartialMdl
475  );
476 
477  WdfRequestSetCompletionRoutine(DeviceExtension->ScratchContext.ScratchRequest,
479 
480  status = ScratchBuffer_SendSrb(DeviceExtension, FALSE, (FirstTry ? &readWriteContext->SrbHistoryItem : NULL));
481 
482  return status;
483 }
PSRB_HISTORY_ITEM SrbHistoryItem
Definition: cdrom.h:289
LARGE_INTEGER StartingOffset
Definition: cdrom.h:285
LONG NTSTATUS
Definition: precomp.h:26
VOID ScratchBuffer_SetupReadWriteSrb(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST OriginalRequest, _In_ LARGE_INTEGER StartingOffset, _In_ ULONG RequiredLength, _Inout_updates_bytes_(RequiredLength) UCHAR *DataBuffer, _In_ BOOLEAN IsReadRequest, _In_ BOOLEAN UsePartialMdl)
Definition: scratch.c:1212
VOID ScratchBuffer_ResetItems(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN ResetRequestHistory)
Definition: scratch.c:343
EVT_WDF_REQUEST_COMPLETION_ROUTINE ScratchBuffer_ReadWriteCompletionRoutine
Definition: scratch.c:39
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Definition: copy.c:32
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS ScratchBuffer_SendSrb(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN SynchronousSrb, _When_(SynchronousSrb, _Pre_null_) _When_(!SynchronousSrb, _In_opt_) PSRB_HISTORY_ITEM *SrbHistoryItem)
Definition: scratch.c:906
WDFREQUEST OriginalRequest
Definition: cdrom.h:633
Definition: ps.c:97

Referenced by RequestHandleReadWrite(), ScratchBuffer_ReadWriteCompletionRoutine(), and ScratchBuffer_ReadWriteTimerRoutine().

◆ ScratchBuffer_ReadWriteCompletionRoutine()

VOID NTAPI ScratchBuffer_ReadWriteCompletionRoutine ( _In_ WDFREQUEST  Request,
_In_ WDFIOTARGET  Target,
_In_ PWDF_REQUEST_COMPLETION_PARAMS  Params,
_In_ WDFCONTEXT  Context 
)

Definition at line 628 of file scratch.c.

651 {
653  PCDROM_SCRATCH_READ_WRITE_CONTEXT readWriteContext = &deviceExtension->ScratchContext.ScratchReadWriteContext;
655  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(deviceExtension->ScratchContext.ScratchRequest);
656  WDFREQUEST originalRequest = requestContext->OriginalRequest;
657 
658  if (!NT_SUCCESS(WdfRequestGetStatus(Request)))
659  {
660  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT,
661  "WdfRequestSend: %lx\n",
662  WdfRequestGetStatus(Request)
663  ));
664  }
665 
668 
669  // We are not calling ScratchBuffer_BeginUse / ScratchBuffer_EndUse in this function, because we already own
670  // the scratch buffer if this function is being called.
671 
672  if ((deviceExtension->ScratchContext.ScratchSrb->SrbStatus == SRB_STATUS_ABORTED) &&
674  {
675  // The request has been cancelled, just need to complete it
676  }
677  else if (SRB_STATUS(deviceExtension->ScratchContext.ScratchSrb->SrbStatus) != SRB_STATUS_SUCCESS)
678  {
679  // The SCSI command that we sent down has failed, retry it if necessary
680  BOOLEAN shouldRetry = TRUE;
681  LONGLONG retryIn100nsUnits = 0;
682 
683  shouldRetry = RequestSenseInfoInterpretForScratchBuffer(deviceExtension,
684  deviceExtension->ScratchContext.NumRetries,
685  &status,
686  &retryIn100nsUnits);
687 
688  if (shouldRetry)
689  {
690  deviceExtension->ScratchContext.NumRetries++;
691 
692  if (retryIn100nsUnits == 0)
693  {
694  // We take a shortcut here by calling ScratchBuffer_PerformNextReadWrite directly:
695  // this helps to avoid unnecessary context switch.
696  status = ScratchBuffer_PerformNextReadWrite(deviceExtension, FALSE);
697 
698  if (NT_SUCCESS(status))
699  {
700  // We're not done with the request yet, no need to complete it now
701  return;
702  }
703  }
704  else
705  {
706  PCDROM_REQUEST_CONTEXT originalRequestContext = RequestGetContext(originalRequest);
707  KIRQL oldIrql;
708 
709  //
710  // Initialize the spin lock and timer local to the original request.
711  //
712  if (!originalRequestContext->ReadWriteRetryInitialized)
713  {
714  KeInitializeSpinLock(&originalRequestContext->ReadWriteCancelSpinLock);
715  KeInitializeTimer(&originalRequestContext->ReadWriteTimer);
716  KeInitializeDpc(&originalRequestContext->ReadWriteDpc, ScratchBuffer_ReadWriteTimerRoutine, originalRequest);
717  originalRequestContext->ReadWriteRetryInitialized = TRUE;
718  }
719 
720  KeAcquireSpinLock(&requestContext->ReadWriteCancelSpinLock, &oldIrql);
721 
722  status = WdfRequestMarkCancelableEx(originalRequest, ScratchBuffer_ReadWriteEvtRequestCancel);
723 
724  if (status == STATUS_CANCELLED)
725  {
726  requestContext->ReadWriteIsCompleted = TRUE;
727 
728  KeReleaseSpinLock(&requestContext->ReadWriteCancelSpinLock, oldIrql);
729  }
730  else
731  {
733 
734  t.QuadPart = -retryIn100nsUnits;
735 
736  WdfObjectReference(originalRequest);
737 
738  // Use negative time to indicate that we want a relative delay
739  KeSetTimer(&originalRequestContext->ReadWriteTimer,
740  t,
741  &originalRequestContext->ReadWriteDpc
742  );
743 
744  KeReleaseSpinLock(&requestContext->ReadWriteCancelSpinLock, oldIrql);
745 
746  return;
747  }
748  }
749  }
750  }
751  else
752  {
753  // The SCSI command has succeeded
754  readWriteContext->DataBuffer += deviceExtension->ScratchContext.ScratchSrb->DataTransferLength;
755  readWriteContext->StartingOffset.QuadPart += deviceExtension->ScratchContext.ScratchSrb->DataTransferLength;
756  readWriteContext->TransferedBytes += deviceExtension->ScratchContext.ScratchSrb->DataTransferLength;
757  readWriteContext->PacketsCount--;
758 
759  // Update the SRB history item
760  if (readWriteContext->SrbHistoryItem)
761  {
762  ULONG senseSize;
763 
764  // Query the tick count and store in the history
766 
767  // Copy the SRB Status...
768  readWriteContext->SrbHistoryItem->SrbStatus = deviceExtension->ScratchContext.ScratchSrb->SrbStatus;
769 
770  // Determine the amount of valid sense data
771  if (deviceExtension->ScratchContext.ScratchSrb->SenseInfoBufferLength >=
772  RTL_SIZEOF_THROUGH_FIELD(SENSE_DATA, AdditionalSenseLength))
773  {
775  senseSize = RTL_SIZEOF_THROUGH_FIELD(SENSE_DATA, AdditionalSenseLength) +
776  sense->AdditionalSenseLength;
777  senseSize = min(senseSize, sizeof(SENSE_DATA));
778  }
779  else
780  {
781  senseSize = deviceExtension->ScratchContext.ScratchSrb->SenseInfoBufferLength;
782  }
783 
784  // Normalize the sense data copy in the history
785  RtlZeroMemory(&(readWriteContext->SrbHistoryItem->NormalizedSenseData), sizeof(SENSE_DATA));
786  RtlCopyMemory(&(readWriteContext->SrbHistoryItem->NormalizedSenseData),
787  deviceExtension->ScratchContext.ScratchSrb->SenseInfoBuffer, senseSize);
788  }
789 
790  // Check whether we need to send more SCSI commands to complete the request
791  if (readWriteContext->PacketsCount > 0)
792  {
793  status = ScratchBuffer_PerformNextReadWrite(deviceExtension, TRUE);
794 
795  if (NT_SUCCESS(status))
796  {
797  // We're not done with the request yet, no need to complete it now
798  return;
799  }
800  }
801  }
802 
803  ScratchBuffer_EndUse(deviceExtension);
804 
805 
806  RequestCompletion(deviceExtension, originalRequest, status, readWriteContext->TransferedBytes);
807 }
UCHAR SrbStatus
Definition: cdromp.h:101
PSRB_HISTORY_ITEM SrbHistoryItem
Definition: cdrom.h:289
LARGE_INTEGER StartingOffset
Definition: cdrom.h:285
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
CDROM_SCRATCH_READ_WRITE_CONTEXT ScratchReadWriteContext
Definition: cdrom.h:321
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
ULONG DataTransferLength
Definition: srb.h:253
LONG NTSTATUS
Definition: precomp.h:26
GLdouble GLdouble t
Definition: gl.h:2047
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
__inline VOID ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
Definition: scratch.h:104
NTSTATUS ScratchBuffer_PerformNextReadWrite(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FirstTry)
Definition: scratch.c:429
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
struct _CDROM_DEVICE_EXTENSION * PCDROM_DEVICE_EXTENSION
Definition: cdrom.h:216
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
BOOLEAN ReadWriteIsCompleted
Definition: cdrom.h:665
#define FALSE
Definition: types.h:117
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
unsigned char BOOLEAN
#define SRB_STATUS_ABORTED
Definition: srb.h:334
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
BOOLEAN ReadWriteRetryInitialized
Definition: cdrom.h:666
CDROM_SCRATCH_CONTEXT ScratchContext
Definition: cdrom.h:601
KTIMER ReadWriteTimer
Definition: cdrom.h:663
int64_t LONGLONG
Definition: typedefs.h:68
LARGE_INTEGER TickCountCompleted
Definition: cdromp.h:98
WDFREQUEST ScratchRequest
Definition: cdrom.h:303
EVT_WDF_REQUEST_CANCEL ScratchBuffer_ReadWriteEvtRequestCancel
Definition: scratch.c:568
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:673
PSCSI_REQUEST_BLOCK ScratchSrb
Definition: cdrom.h:304
BOOLEAN RequestSenseInfoInterpretForScratchBuffer(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ ULONG RetriedCount, _Out_ NTSTATUS *Status, _Out_ _Deref_out_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) LONGLONG *RetryIntervalIn100ns)
Definition: sense.c:2564
ULONG InternalStatus
Definition: srb.h:261
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
UCHAR SenseInfoBufferLength
Definition: srb.h:251
#define min(a, b)
Definition: monoChain.cc:55
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
struct _SENSE_DATA * PSENSE_DATA
PVOID SenseInfoBuffer
Definition: srb.h:256
VOID NTAPI ScratchBuffer_ReadWriteTimerRoutine(struct _KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
Definition: scratch.c:488
unsigned int ULONG
Definition: retypes.h:1
KSPIN_LOCK ReadWriteCancelSpinLock
Definition: cdrom.h:662
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
SENSE_DATA NormalizedSenseData
Definition: cdromp.h:100
LONGLONG QuadPart
Definition: typedefs.h:114
WDFREQUEST OriginalRequest
Definition: cdrom.h:633
Definition: ps.c:97

◆ ScratchBuffer_ReadWriteEvtRequestCancel()

VOID NTAPI ScratchBuffer_ReadWriteEvtRequestCancel ( _In_ WDFREQUEST  Request)

Definition at line 572 of file scratch.c.

591 {
592  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
593  PCDROM_DEVICE_EXTENSION deviceExtension = requestContext->DeviceExtension;
594  PCDROM_SCRATCH_READ_WRITE_CONTEXT readWriteContext = &deviceExtension->ScratchContext.ScratchReadWriteContext;
595  KIRQL oldIrql;
596 
597  KeAcquireSpinLock(&requestContext->ReadWriteCancelSpinLock, &oldIrql);
598 
599  if (KeCancelTimer(&requestContext->ReadWriteTimer))
600  {
601  //
602  // Timer is canceled, we own the request. Drop the reference we took before
603  // queueing the timer.
604  //
606  }
607  else
608  {
609  //
610  // Timer will run and drop the reference but it won't complete the request
611  // because we set IsCompleted to TRUE
612  //
613  }
614 
615  requestContext->ReadWriteIsCompleted = TRUE;
616 
617  KeReleaseSpinLock(&requestContext->ReadWriteCancelSpinLock, oldIrql);
618 
619  ScratchBuffer_EndUse(deviceExtension);
620 
621  // If WdfTimerStop returned TRUE, it means this request was scheduled for a retry
622  // and the retry has not happened yet. We just need to cancel it and release the scratch buffer.
623  RequestCompletion(deviceExtension, Request, STATUS_CANCELLED, readWriteContext->TransferedBytes);
624 }
CDROM_SCRATCH_READ_WRITE_CONTEXT ScratchReadWriteContext
Definition: cdrom.h:321
#define TRUE
Definition: types.h:120
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
__inline VOID ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
Definition: scratch.h:104
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
BOOLEAN ReadWriteIsCompleted
Definition: cdrom.h:665
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826
CDROM_SCRATCH_CONTEXT ScratchContext
Definition: cdrom.h:601
KTIMER ReadWriteTimer
Definition: cdrom.h:663
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
PCDROM_DEVICE_EXTENSION DeviceExtension
Definition: cdrom.h:631
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
KSPIN_LOCK ReadWriteCancelSpinLock
Definition: cdrom.h:662

◆ ScratchBuffer_ReadWriteTimerRoutine()

VOID NTAPI ScratchBuffer_ReadWriteTimerRoutine ( struct _KDPC Dpc,
PVOID  DeferredContext,
PVOID  SystemArgument1,
PVOID  SystemArgument2 
)

Definition at line 488 of file scratch.c.

509 {
510  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
511  PCDROM_SCRATCH_READ_WRITE_CONTEXT readWriteContext = NULL;
512  WDFREQUEST originalRequest = NULL;
513  PCDROM_REQUEST_CONTEXT requestContext = NULL;
515  KIRQL oldIrql;
516 
520 
521  if (DeferredContext == NULL)
522  {
523  // This is impossible, but definition of KDEFERRED_ROUTINE allows optional argument,
524  // and thus OACR will complain.
525 
526  return;
527  }
528 
529  originalRequest = (WDFREQUEST) DeferredContext;
530  requestContext = RequestGetContext(originalRequest);
531 
532  KeAcquireSpinLock(&requestContext->ReadWriteCancelSpinLock, &oldIrql);
533 
534  if (!requestContext->ReadWriteIsCompleted)
535  {
536  // As the first step, unregister the cancellation routine
537  status = WdfRequestUnmarkCancelable(originalRequest);
538  }
539  else
540  {
542  }
543 
544  KeReleaseSpinLock(&requestContext->ReadWriteCancelSpinLock, oldIrql);
545 
546  if (status != STATUS_CANCELLED)
547  {
548  deviceExtension = requestContext->DeviceExtension;
549  readWriteContext = &deviceExtension->ScratchContext.ScratchReadWriteContext;
550 
551  // We use timer only for retries, that's why the second parameter is always FALSE
552  status = ScratchBuffer_PerformNextReadWrite(deviceExtension, FALSE);
553 
554  if (!NT_SUCCESS(status))
555  {
556  ScratchBuffer_EndUse(deviceExtension);
557  RequestCompletion(deviceExtension, originalRequest, status, readWriteContext->TransferedBytes);
558  }
559  }
560 
561  //
562  // Drop the extra reference
563  //
564  WdfObjectDereference(originalRequest);
565 }
CDROM_SCRATCH_READ_WRITE_CONTEXT ScratchReadWriteContext
Definition: cdrom.h:321
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:107
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
Definition: scratch.h:104
NTSTATUS ScratchBuffer_PerformNextReadWrite(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FirstTry)
Definition: scratch.c:429
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
BOOLEAN ReadWriteIsCompleted
Definition: cdrom.h:665
#define FALSE
Definition: types.h:117
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826
CDROM_SCRATCH_CONTEXT ScratchContext
Definition: cdrom.h:601
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
PCDROM_DEVICE_EXTENSION DeviceExtension
Definition: cdrom.h:631
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
KSPIN_LOCK ReadWriteCancelSpinLock
Definition: cdrom.h:662
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: ps.c:97
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675

Referenced by ScratchBuffer_ReadWriteCompletionRoutine().

◆ ScratchBuffer_ResetItems()

VOID ScratchBuffer_ResetItems ( _Inout_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ BOOLEAN  ResetRequestHistory 
)

Definition at line 343 of file scratch.c.

363 {
365  WDF_REQUEST_REUSE_PARAMS reuseParams;
366  PIRP irp = NULL;
367 
368  NT_ASSERT(DeviceExtension->ScratchContext.ScratchHistory != NULL);
369  NT_ASSERT(DeviceExtension->ScratchContext.ScratchSense != NULL);
370  NT_ASSERT(DeviceExtension->ScratchContext.ScratchSrb != NULL);
371  NT_ASSERT(DeviceExtension->ScratchContext.ScratchRequest != NULL);
372  NT_ASSERT(DeviceExtension->ScratchContext.ScratchBufferSize != 0);
373  NT_ASSERT(DeviceExtension->ScratchContext.ScratchBuffer != NULL);
374  NT_ASSERT(DeviceExtension->ScratchContext.ScratchBufferMdl != NULL);
375  NT_ASSERT(DeviceExtension->ScratchContext.ScratchInUse != 0);
376 
377  irp = WdfRequestWdmGetIrp(DeviceExtension->ScratchContext.ScratchRequest);
378 
379  if (ResetRequestHistory)
380  {
381  PSRB_HISTORY history = DeviceExtension->ScratchContext.ScratchHistory;
382  RtlZeroMemory(history->History, sizeof(SRB_HISTORY_ITEM) * history->TotalHistoryCount);
383  history->ClassDriverUse[0] = 0;
384  history->ClassDriverUse[1] = 0;
385  history->ClassDriverUse[2] = 0;
386  history->ClassDriverUse[3] = 0;
387  history->UsedHistoryCount = 0;
388  }
389 
390  // re-use the KMDF request object
391 
392  // deassign the MdlAddress, this is the value we assign explicitly.
393  // this is to prevent WdfRequestReuse to release the Mdl unexpectly.
394  if (irp->MdlAddress)
395  {
396  irp->MdlAddress = NULL;
397  }
398 
400  status = WdfRequestReuse(DeviceExtension->ScratchContext.ScratchRequest, &reuseParams);
401  // WDF request to format the request befor sending it
402  if (NT_SUCCESS(status))
403  {
404  // clean up completion routine.
405  WdfRequestSetCompletionRoutine(DeviceExtension->ScratchContext.ScratchRequest, NULL, NULL);
406 
407  status = WdfIoTargetFormatRequestForInternalIoctlOthers(DeviceExtension->IoTarget,
408  DeviceExtension->ScratchContext.ScratchRequest,
410  NULL, NULL,
411  NULL, NULL,
412  NULL, NULL);
413  if (!NT_SUCCESS(status))
414  {
415  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
416  "ScratchBuffer_ResetItems: WdfIoTargetFormatRequestForInternalIoctlOthers failed, %!STATUS!\n",
417  status));
418  }
419  }
420 
421  RtlZeroMemory(DeviceExtension->ScratchContext.ScratchSense, sizeof(SENSE_DATA));
422  RtlZeroMemory(DeviceExtension->ScratchContext.ScratchSrb, sizeof(SCSI_REQUEST_BLOCK));
423 
424  return;
425 }
return STATUS_NOT_SUPPORTED
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE VOID WDF_REQUEST_REUSE_PARAMS_INIT(_Out_ PWDF_REQUEST_REUSE_PARAMS Params, _In_ ULONG Flags, _In_ NTSTATUS Status)
Definition: wdfrequest.h:364
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define NULL
Definition: types.h:112
ULONG_PTR ClassDriverUse[4]
Definition: cdromp.h:106
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
FxIrp * irp
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by _IRQL_requires_max_(), ScratchBuffer_BeginUseX(), and ScratchBuffer_PerformNextReadWrite().

◆ ScratchBuffer_SendSrb()

NTSTATUS ScratchBuffer_SendSrb ( _Inout_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ BOOLEAN  SynchronousSrb,
_When_(SynchronousSrb, _Pre_null_) _When_(!SynchronousSrb, _In_opt_) PSRB_HISTORY_ITEM SrbHistoryItem 
)

Definition at line 906 of file scratch.c.

930 {
932  PSCSI_REQUEST_BLOCK srb = DeviceExtension->ScratchContext.ScratchSrb;
933  PSRB_HISTORY history = DeviceExtension->ScratchContext.ScratchHistory;
935  BOOLEAN requestCancelled = FALSE;
936 
937  srb->InternalStatus = 0;
938  srb->SrbStatus = 0;
939 
940  // allocate/update history pre-command, if it is a synchronous request or we were supplied
941  // with a storage for the history item
942  if (SynchronousSrb || SrbHistoryItem != NULL)
943  {
944  // sending a packet implies a new history unit is to be used.
945  NT_ASSERT( history->UsedHistoryCount <= history->TotalHistoryCount );
946 
947  // if already all used up, remove at least one history unit
948  if (history->UsedHistoryCount == history->TotalHistoryCount )
949  {
950  CompressSrbHistoryData(history);
951  NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount );
952  }
953 
954  // thus, since we are about to increment the count, it must now be less...
955  NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount );
956 
957  // increment the number of history units in use
958  history->UsedHistoryCount++;
959 
960  // determine index to use
961  item = &( history->History[ history->UsedHistoryCount-1 ] );
962 
963  if (SrbHistoryItem != NULL)
964  {
965  *SrbHistoryItem = item;
966  }
967 
968  // zero out the history item
970 
971  // Query the tick count and store in the history
972  KeQueryTickCount(&item->TickCountSent);
973  }
974 
975  // get cancellation status;
976  {
977  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(DeviceExtension->ScratchContext.ScratchRequest);
978 
979  if (requestContext->OriginalRequest != NULL)
980  {
981  requestCancelled = WdfRequestIsCanceled(requestContext->OriginalRequest);
982  }
983  }
984 
985  if (!requestCancelled)
986  {
987  status = RequestSend(DeviceExtension,
988  DeviceExtension->ScratchContext.ScratchRequest,
989  DeviceExtension->IoTarget,
990  SynchronousSrb ? WDF_REQUEST_SEND_OPTION_SYNCHRONOUS : 0,
991  NULL);
992 
993  // If this is a synchronous request, update the history item immediately, including "normalized" sense data
994  if (SynchronousSrb)
995  {
996  ULONG senseSize;
997 
998  // Query the tick count and store in the history
999  KeQueryTickCount(&item->TickCountCompleted);
1000 
1001  // Copy the SRB Status
1002  item->SrbStatus = srb->SrbStatus;
1003 
1004  // Determine the amount of valid sense data
1005  if (srb->SenseInfoBufferLength >= RTL_SIZEOF_THROUGH_FIELD(SENSE_DATA, AdditionalSenseLength))
1006  {
1007  PSENSE_DATA sense = (PSENSE_DATA)srb->SenseInfoBuffer;
1008  senseSize = RTL_SIZEOF_THROUGH_FIELD(SENSE_DATA, AdditionalSenseLength) +
1009  sense->AdditionalSenseLength;
1010  senseSize = min(senseSize, sizeof(SENSE_DATA));
1011  }
1012  else
1013  {
1014  senseSize = srb->SenseInfoBufferLength;
1015  }
1016 
1017  // Normalize the sense data copy in the history
1018  RtlZeroMemory(&(item->NormalizedSenseData), sizeof(SENSE_DATA));
1019  RtlCopyMemory(&(item->NormalizedSenseData), srb->SenseInfoBuffer, senseSize);
1020  }
1021  }
1022  else
1023  {
1024  DeviceExtension->ScratchContext.ScratchSrb->SrbStatus = SRB_STATUS_ABORTED;
1025  DeviceExtension->ScratchContext.ScratchSrb->InternalStatus = (ULONG)STATUS_CANCELLED;
1027  }
1028 
1029  return status;
1030 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS RequestSend(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDFIOTARGET IoTarget, _In_ ULONG Flags, _Out_opt_ PBOOLEAN RequestSent)
Definition: common.c:3793
UCHAR SrbStatus
Definition: srb.h:243
VOID CompressSrbHistoryData(_Inout_ PSRB_HISTORY RequestHistory)
Definition: scratch.c:1033
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define SRB_STATUS_ABORTED
Definition: srb.h:334
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:673
ULONG InternalStatus
Definition: srb.h:261
UCHAR SenseInfoBufferLength
Definition: srb.h:251
static ATOM item
Definition: dde.c:856
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
struct _SENSE_DATA * PSENSE_DATA
PVOID SenseInfoBuffer
Definition: srb.h:256
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
WDFREQUEST OriginalRequest
Definition: cdrom.h:633
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by RequestIssueShutdownFlush(), and ScratchBuffer_PerformNextReadWrite().

◆ ScratchBuffer_SetupReadWriteSrb()

VOID ScratchBuffer_SetupReadWriteSrb ( _Inout_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  OriginalRequest,
_In_ LARGE_INTEGER  StartingOffset,
_In_ ULONG  RequiredLength,
_Inout_updates_bytes_(RequiredLength) UCHAR DataBuffer,
_In_ BOOLEAN  IsReadRequest,
_In_ BOOLEAN  UsePartialMdl 
)

Definition at line 1212 of file scratch.c.

1240 {
1241  //NOTE: R/W request not use the ScratchBuffer, instead, it uses the buffer associated with IRP.
1242 
1243  PSCSI_REQUEST_BLOCK srb = DeviceExtension->ScratchContext.ScratchSrb;
1244  PCDB cdb = (PCDB)srb->Cdb;
1245  LARGE_INTEGER logicalBlockAddr;
1246  ULONG numTransferBlocks;
1247 
1248  PIRP originalIrp = WdfRequestWdmGetIrp(OriginalRequest);
1249 
1250  PIRP irp = WdfRequestWdmGetIrp(DeviceExtension->ScratchContext.ScratchRequest);
1251  PIO_STACK_LOCATION irpStack = NULL;
1252 
1253  PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(DeviceExtension->ScratchContext.ScratchRequest);
1254 
1255  requestContext->OriginalRequest = OriginalRequest;
1256 
1257 
1258  logicalBlockAddr.QuadPart = Int64ShrlMod32(StartingOffset.QuadPart, DeviceExtension->SectorShift);
1259  numTransferBlocks = RequiredLength >> DeviceExtension->SectorShift;
1260 
1261  // set to use the full scratch buffer via the scratch SRB
1262  irpStack = IoGetNextIrpStackLocation(irp);
1263  irpStack->MajorFunction = IRP_MJ_SCSI;
1264  if (IsReadRequest)
1265  {
1266  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
1267  }
1268  else
1269  {
1270  irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_OUT;
1271  }
1272  irpStack->Parameters.Scsi.Srb = srb;
1273 
1274  // prepare the SRB with default values
1278  srb->SrbStatus = 0;
1279  srb->ScsiStatus = 0;
1280  srb->NextSrb = NULL;
1282  srb->SenseInfoBuffer = DeviceExtension->ScratchContext.ScratchSense;
1283 
1284  srb->DataBuffer = DataBuffer;
1286 
1287  srb->QueueSortKey = logicalBlockAddr.LowPart;
1288  if (logicalBlockAddr.QuadPart > 0xFFFFFFFF)
1289  {
1290  //
1291  // If the requested LBA is more than max ULONG set the
1292  // QueueSortKey to the maximum value, so that these
1293  // requests can be added towards the end of the queue.
1294  //
1295  srb->QueueSortKey = 0xFFFFFFFF;
1296  }
1297 
1298  srb->OriginalRequest = irp;
1299  srb->TimeOutValue = DeviceExtension->TimeOutValue;
1300 
1301  if (RequestIsRealtimeStreaming(OriginalRequest, IsReadRequest) &&
1302  !TEST_FLAG(DeviceExtension->PrivateFdoData->HackFlags, FDO_HACK_NO_STREAMING))
1303  {
1304  if (IsReadRequest)
1305  {
1306  RtlZeroMemory(&cdb->READ12, sizeof(cdb->READ12));
1307  REVERSE_BYTES(&cdb->READ12.LogicalBlock, &logicalBlockAddr.LowPart);
1308  REVERSE_BYTES(&cdb->READ12.TransferLength, &numTransferBlocks);
1309  cdb->READ12.Streaming = 1;
1310  cdb->READ12.OperationCode = SCSIOP_READ12;
1311  srb->CdbLength = sizeof(cdb->READ12);
1312  }
1313  else
1314  {
1315  RtlZeroMemory(&cdb->WRITE12, sizeof(cdb->WRITE12));
1316  REVERSE_BYTES(&cdb->WRITE12.LogicalBlock, &logicalBlockAddr.LowPart);
1317  REVERSE_BYTES(&cdb->WRITE12.TransferLength, &numTransferBlocks);
1318  cdb->WRITE12.Streaming = 1;
1319  cdb->WRITE12.OperationCode = SCSIOP_WRITE12;
1320  srb->CdbLength = sizeof(cdb->WRITE12);
1321  }
1322  }
1323  else
1324  {
1325  RtlZeroMemory(&cdb->CDB10, sizeof(cdb->CDB10));
1326  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte3;
1327  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte2;
1328  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte1;
1329  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte0;
1330  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&numTransferBlocks)->Byte1;
1331  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&numTransferBlocks)->Byte0;
1332  cdb->CDB10.OperationCode = (IsReadRequest) ? SCSIOP_READ : SCSIOP_WRITE;
1333  srb->CdbLength = sizeof(cdb->CDB10);
1334  }
1335 
1336  // Set SRB and IRP flags
1337  srb->SrbFlags = DeviceExtension->SrbFlags;
1338  if (TEST_FLAG(originalIrp->Flags, IRP_PAGING_IO) ||
1339  TEST_FLAG(originalIrp->Flags, IRP_SYNCHRONOUS_PAGING_IO))
1340  {
1342  }
1343 
1344  SET_FLAG(srb->SrbFlags, (IsReadRequest) ? SRB_FLAGS_DATA_IN : SRB_FLAGS_DATA_OUT);
1346 
1347  //
1348  // If the request is not split, we can use the original IRP MDL. If the
1349  // request needs to be split, we need to use a partial MDL. The partial MDL
1350  // is needed because more than one driver might be mapping the same MDL
1351  // and this causes problems.
1352  //
1353  if (UsePartialMdl == FALSE)
1354  {
1355  irp->MdlAddress = originalIrp->MdlAddress;
1356  }
1357  else
1358  {
1359  if (DeviceExtension->ScratchContext.PartialMdlIsBuilt != FALSE)
1360  {
1361  MmPrepareMdlForReuse(DeviceExtension->ScratchContext.PartialMdl);
1362  }
1363 
1364  IoBuildPartialMdl(originalIrp->MdlAddress, DeviceExtension->ScratchContext.PartialMdl, srb->DataBuffer, srb->DataTransferLength);
1365  DeviceExtension->ScratchContext.PartialMdlIsBuilt = TRUE;
1366  irp->MdlAddress = DeviceExtension->ScratchContext.PartialMdl;
1367  }
1368 
1369  //DBGLOGSENDPACKET(Pkt);
1370  //HISTORYLOGSENDPACKET(Pkt);
1371 
1372  //
1373  // Set the original irp here for SFIO.
1374  //
1375  srb->SrbExtension = (PVOID)(originalIrp);
1376 
1377  return;
1378 }
#define IOCTL_SCSI_EXECUTE_OUT
Definition: cdrw_hw.h:1452
BOOLEAN RequestIsRealtimeStreaming(_In_ WDFREQUEST Request, _In_ BOOLEAN IsReadRequest)
Definition: ioctl.c:6050
struct _FOUR_BYTE * PFOUR_BYTE
ULONG SrbFlags
Definition: srb.h:252
PVOID SrbExtension
Definition: srb.h:259
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:290
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
ULONG DataTransferLength
Definition: srb.h:253
Definition: cdrw_hw.h:28
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
struct _CDB::_READ12 READ12
UCHAR CdbLength
Definition: srb.h:250
struct _CDB::_WRITE12 WRITE12
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
#define SCSIOP_WRITE12
Definition: cdrw_hw.h:957
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define IRP_MJ_SCSI
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
#define FALSE
Definition: types.h:117
UCHAR ScsiStatus
Definition: srb.h:244
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define SCSIOP_READ12
Definition: cdrw_hw.h:956
union _CDB * PCDB
void * PVOID
Definition: retypes.h:9
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define SRB_CLASS_FLAGS_PAGING
Definition: cdrom.h:165
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define MmPrepareMdlForReuse(_Mdl)
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN _In_opt_ WDFREQUEST OriginalRequest
Definition: cdrom.h:989
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
#define Int64ShrlMod32(a, b)
UCHAR SenseInfoBufferLength
Definition: srb.h:251
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
#define NULL
Definition: types.h:112
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE
Definition: srb.h:397
#define IRP_PAGING_IO
#define FDO_HACK_NO_STREAMING
Definition: cdromp.h:137
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:262
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
ULONG QueueSortKey
Definition: srb.h:262
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
FxIrp * irp
#define IRP_SYNCHRONOUS_PAGING_IO
WDFREQUEST OriginalRequest
Definition: cdrom.h:633

Referenced by ScratchBuffer_PerformNextReadWrite().

◆ ValidateSrbHistoryDataPresumptions()

VOID ValidateSrbHistoryDataPresumptions ( _In_ SRB_HISTORY const RequestHistory)

Definition at line 1135 of file scratch.c.

1138 {
1139 #if DBG
1140  // validate that all fully-compressed items are before any non-fully-compressed items of any particular sense/asc/ascq
1141  // validate that there is at most one partially-compressed item of any particular sense/asc/ascq
1142  // validate that all items of any particular sense/asc/ascq that are uncompressed are at the end
1143  // THUS: A(255) A(255) A( 40) A( 0) A( 0) is legal for all types with A as sense/asc/ascq
1144  // A(0) B(255) A( 0) B( 17) B( 0) is also legal because A/B are different types of error
1145 
1146  ULONG i;
1147  for (i = 0; i < RequestHistory->UsedHistoryCount; i++)
1148  {
1149  SRB_HISTORY_ITEM const * toMatch = &( RequestHistory->History[i] );
1150  UCHAR const srbStatus = toMatch->SrbStatus;
1151  UCHAR const sense = toMatch->NormalizedSenseData.SenseKey;
1152  UCHAR const asc = toMatch->NormalizedSenseData.AdditionalSenseCode;
1154  ULONG j;
1155 
1156  BOOLEAN foundPartiallyCompressedItem =
1157  (toMatch->ClassDriverUse != 0) &&
1158  (toMatch->ClassDriverUse != 0xFF) ;
1159  BOOLEAN foundUncompressedItem =
1160  (toMatch->ClassDriverUse == 0) ;
1161 
1162  for (j = i+1; j < RequestHistory->UsedHistoryCount; j++)
1163  {
1164  SRB_HISTORY_ITEM const * found = &( RequestHistory->History[j] );
1165  if ((srbStatus == found->SrbStatus) &&
1166  (sense == found->NormalizedSenseData.SenseKey) &&
1167  (asc == found->NormalizedSenseData.AdditionalSenseCode) &&
1169  )
1170  {
1171  // found a matching type, so validate ordering rules
1172  if (foundUncompressedItem && (found->ClassDriverUse != 0))
1173  {
1175  "History data has compressed history following uncompressed history "
1176  "for srbstatus/sense/asc/ascq of %02x/%02x/%02x/%02x at indices %d (%08x) and %d (%08x)\n",
1177  srbStatus, sense, asc, ascq,
1178  i,i, j,j
1179  );
1180  NT_ASSERT(FALSE);
1181  }
1182  else if (foundPartiallyCompressedItem && (found->ClassDriverUse == 0xFF))
1183  {
1185  "History data has fully compressed history following partially compressed history "
1186  "for srbstatus/sense/asc/ascq of %02x/%02x/%02x/%02x at indices %d (%08x) and %d (%08x)\n",
1187  srbStatus, sense, asc, ascq,
1188  i,i, j,j
1189  );
1190  NT_ASSERT(FALSE);
1191  }
1192 
1193  // update if we have now found partially compressed and/or uncompressed items
1194  if (found->ClassDriverUse == 0)
1195  {
1196  foundUncompressedItem = TRUE;
1197  }
1198  else if (found->ClassDriverUse != 0xFF)
1199  {
1200  foundPartiallyCompressedItem = TRUE;
1201  }
1202  } // end match of (toMatch,found)
1203  } // end loop j
1204  } // end loop i
1205 #else
1207 #endif
1208  return;
1209 }
UCHAR SrbStatus
Definition: cdromp.h:101
UCHAR ClassDriverUse
Definition: cdromp.h:102
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSYSAPI ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG _In_ ULONG _In_opt_ SRB_HISTORY * RequestHistory
Definition: classpnp.h:482
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
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 GLint GLint j
Definition: glfuncs.h:250
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
unsigned char UCHAR
Definition: xmlstorage.h:181
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 DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
unsigned int ULONG
Definition: retypes.h:1
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
SENSE_DATA NormalizedSenseData
Definition: cdromp.h:100
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by CompressSrbHistoryData().

Variable Documentation

◆ ScratchBuffer_ReadWriteCompletionRoutine

EVT_WDF_REQUEST_COMPLETION_ROUTINE ScratchBuffer_ReadWriteCompletionRoutine

Definition at line 39 of file scratch.c.

Referenced by ScratchBuffer_PerformNextReadWrite().

◆ ScratchBuffer_ReadWriteEvtRequestCancel

EVT_WDF_REQUEST_CANCEL ScratchBuffer_ReadWriteEvtRequestCancel

Definition at line 568 of file scratch.c.

Referenced by ScratchBuffer_ReadWriteCompletionRoutine().