ReactOS 0.4.16-dev-340-g0540c21
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}
#define PAGED_CODE()
#define NULL
Definition: types.h:112
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IoFreeMdl
Definition: fxmdl.h:89
FxIrp * irp
#define NT_ASSERT
Definition: rtlfuncs.h:3327

◆ 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}
struct _SRB_HISTORY_ITEM SRB_HISTORY_ITEM
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG _In_ ULONG _In_opt_ SRB_HISTORY * RequestHistory
Definition: classpnp.h:487
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
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
static ATOM item
Definition: dde.c:856
VOID ValidateSrbHistoryDataPresumptions(_In_ SRB_HISTORY const *RequestHistory)
Definition: scratch.c:1135
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
UCHAR SenseKey
Definition: cdrw_hw.h:1167
UCHAR ClassDriverUse
Definition: cdromp.h:102
ULONG MillisecondsDelayOnRetry
Definition: cdromp.h:99
UCHAR SrbStatus
Definition: cdromp.h:101
SENSE_DATA NormalizedSenseData
Definition: cdromp.h:100
#define MAXULONG
Definition: typedefs.h:251
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: xmlstorage.h:181

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}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define min(a, b)
Definition: monoChain.cc:55
@ FirstTry
Definition: copy.c:25
EVT_WDF_REQUEST_COMPLETION_ROUTINE ScratchBuffer_ReadWriteCompletionRoutine
Definition: scratch.c:39
VOID ScratchBuffer_ResetItems(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN ResetRequestHistory)
Definition: scratch.c:343
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
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
#define STATUS_SUCCESS
Definition: shellext.h:65
WDFREQUEST OriginalRequest
Definition: cdrom.h:633
PSRB_HISTORY_ITEM SrbHistoryItem
Definition: cdrom.h:289
LARGE_INTEGER StartingOffset
Definition: cdrom.h:285
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{
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.
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
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) +
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));
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 {
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}
struct _CDROM_DEVICE_EXTENSION * PCDROM_DEVICE_EXTENSION
Definition: cdrom.h:218
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
VOID RequestCompletion(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
Definition: common.c:3439
struct _SENSE_DATA * PSENSE_DATA
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define SRB_STATUS_ABORTED
Definition: srb.h:342
#define SRB_STATUS(Status)
Definition: srb.h:389
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
GLdouble GLdouble t
Definition: gl.h:2047
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:680
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
EVT_WDF_REQUEST_CANCEL ScratchBuffer_ReadWriteEvtRequestCancel
Definition: scratch.c:568
NTSTATUS ScratchBuffer_PerformNextReadWrite(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FirstTry)
Definition: scratch.c:429
FORCEINLINE VOID ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
Definition: scratch.h:104
KDEFERRED_ROUTINE ScratchBuffer_ReadWriteTimerRoutine
Definition: scratch.h:185
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
CDROM_SCRATCH_CONTEXT ScratchContext
Definition: cdrom.h:601
KSPIN_LOCK ReadWriteCancelSpinLock
Definition: cdrom.h:662
BOOLEAN ReadWriteIsCompleted
Definition: cdrom.h:665
KTIMER ReadWriteTimer
Definition: cdrom.h:663
BOOLEAN ReadWriteRetryInitialized
Definition: cdrom.h:666
PSCSI_REQUEST_BLOCK ScratchSrb
Definition: cdrom.h:304
CDROM_SCRATCH_READ_WRITE_CONTEXT ScratchReadWriteContext
Definition: cdrom.h:321
WDFREQUEST ScratchRequest
Definition: cdrom.h:303
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID SenseInfoBuffer
Definition: srb.h:264
ULONG DataTransferLength
Definition: srb.h:261
ULONG InternalStatus
Definition: srb.h:269
UCHAR SrbStatus
Definition: srb.h:251
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
LARGE_INTEGER TickCountCompleted
Definition: cdromp.h:98
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
int64_t LONGLONG
Definition: typedefs.h:68
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308

◆ 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;
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}
PCDROM_DEVICE_EXTENSION DeviceExtension
Definition: cdrom.h:631
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826

◆ 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
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
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}
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689

◆ 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}
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
ULONG_PTR ClassDriverUse[4]
Definition: cdromp.h:106
@ WDF_REQUEST_REUSE_NO_FLAGS
Definition: wdfrequest.h:92
FORCEINLINE VOID WDF_REQUEST_REUSE_PARAMS_INIT(_Out_ PWDF_REQUEST_REUSE_PARAMS Params, _In_ ULONG Flags, _In_ NTSTATUS Status)
Definition: wdfrequest.h:364

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 {
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}
NTSTATUS RequestSend(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDFIOTARGET IoTarget, _In_ ULONG Flags, _Out_opt_ PBOOLEAN RequestSent)
Definition: common.c:3793
VOID CompressSrbHistoryData(_Inout_ PSRB_HISTORY RequestHistory)
Definition: scratch.c:1033
@ WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
Definition: wdfrequest.h:109

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}
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN _In_opt_ WDFREQUEST OriginalRequest
Definition: cdrom.h:994
#define SRB_CLASS_FLAGS_PAGING
Definition: cdrom.h:165
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define FDO_HACK_NO_STREAMING
Definition: cdromp.h:137
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define IOCTL_SCSI_EXECUTE_OUT
Definition: cdrw_hw.h:1452
#define SCSIOP_READ12
Definition: cdrw_hw.h:956
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define SCSIOP_WRITE12
Definition: cdrw_hw.h:957
union _CDB * PCDB
#define SCSIOP_READ
Definition: cdrw_hw.h:905
BOOLEAN RequestIsRealtimeStreaming(_In_ WDFREQUEST Request, _In_ BOOLEAN IsReadRequest)
Definition: ioctl.c:6050
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:282
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:423
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE
Definition: srb.h:405
struct _FOUR_BYTE * PFOUR_BYTE
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
#define Int64ShrlMod32(a, b)
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@3980::@4002 Scsi
struct _IO_STACK_LOCATION::@1581::@1582 DeviceIoControl
ULONG TimeOutValue
Definition: srb.h:262
PVOID OriginalRequest
Definition: srb.h:266
PVOID DataBuffer
Definition: srb.h:263
UCHAR QueueAction
Definition: srb.h:257
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
ULONG QueueSortKey
Definition: srb.h:270
UCHAR Function
Definition: srb.h:250
UCHAR ScsiStatus
Definition: srb.h:252
PVOID SrbExtension
Definition: srb.h:267
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:265
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
void * PVOID
Definition: typedefs.h:50
Definition: cdrw_hw.h:28
struct _CDB::_CDB10 CDB10
struct _CDB::_READ12 READ12
struct _CDB::_WRITE12 WRITE12
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:30
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IRP_MJ_SCSI
#define IRP_PAGING_IO
#define IRP_SYNCHRONOUS_PAGING_IO
#define MmPrepareMdlForReuse(_Mdl)

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 );
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 );
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}
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
@ DPFLTR_CDROM_ID
Definition: dpfilter.h:35
#define DbgPrintEx(cmpid, lvl, fmt,...)
Definition: kdinit.c:24

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().