ReactOS 0.4.15-dev-7924-g5949c20
scratch.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define ScratchBuffer_BeginUse(context)   ScratchBuffer_BeginUseX((context), NULL, (ULONG)-1)
 

Functions

 _IRQL_requires_max_ (APC_LEVEL) VOID ScratchBuffer_Deallocate(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
 
VOID ScratchBuffer_ResetItems (_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN ResetRequestHistory)
 
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)
 
NTSTATUS ScratchBuffer_SendSrb (_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN SynchronousSrb, _When_(SynchronousSrb, _Pre_null_) _When_(!SynchronousSrb, _In_opt_) PSRB_HISTORY_ITEM *SrbHistoryItem)
 
NTSTATUS ScratchBuffer_PerformNextReadWrite (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FirstTry)
 
FORCEINLINE VOID ScratchBuffer_BeginUseX (_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_opt_ LPCSTR File, ULONG Line)
 
FORCEINLINE VOID ScratchBuffer_EndUse (_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
 
VOID CompressSrbHistoryData (_Inout_ PSRB_HISTORY RequestHistory)
 
VOID ValidateSrbHistoryDataPresumptions (_In_ SRB_HISTORY const *RequestHistory)
 

Variables

_In_opt_ WDFREQUEST OriginalRequest
 
_In_opt_ WDFREQUEST _In_ ULONG MaximumTransferLength
 
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN GetDataFromDevice
 
_In_opt_ WDFREQUEST _In_ ULONG TransferSize
 
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
 
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB _In_ UCHAR OprationLength
 
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB _In_ UCHAR _In_ ULONG TimeoutValue
 
KDEFERRED_ROUTINE ScratchBuffer_ReadWriteTimerRoutine
 

Macro Definition Documentation

◆ ScratchBuffer_BeginUse

#define ScratchBuffer_BeginUse (   context)    ScratchBuffer_BeginUseX((context), NULL, (ULONG)-1)

Definition at line 87 of file scratch.h.

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 37 of file cddata.c.

254{
255 THREAD_CONTEXT ThreadContext = {0};
256 PIRP_CONTEXT IrpContext = NULL;
258
259#ifdef CD_SANITY
260 PVOID PreviousTopLevel;
261#endif
262
264
265#if DBG
266
267 KIRQL SaveIrql = KeGetCurrentIrql();
268
269#endif
270
272
274
276
277#ifdef CD_SANITY
278 PreviousTopLevel = IoGetTopLevelIrp();
279#endif
280
281 //
282 // Loop until this request has been completed or posted.
283 //
284
285 do {
286
287 //
288 // Use a try-except to handle the exception cases.
289 //
290
291 _SEH2_TRY {
292
293 //
294 // If the IrpContext is NULL then this is the first pass through
295 // this loop.
296 //
297
298 if (IrpContext == NULL) {
299
300 //
301 // Decide if this request is waitable an allocate the IrpContext.
302 // If the file object in the stack location is NULL then this
303 // is a mount which is always waitable. Otherwise we look at
304 // the file object flags.
305 //
306
308
309 Wait = TRUE;
310
311 } else {
312
313 Wait = CanFsdWait( Irp );
314 }
315
316 IrpContext = CdCreateIrpContext( Irp, Wait );
317
318 //
319 // Update the thread context information.
320 //
321
322 CdSetThreadContext( IrpContext, &ThreadContext );
323
324#ifdef CD_SANITY
325 NT_ASSERT( !CdTestTopLevel ||
326 SafeNodeType( IrpContext->TopLevel ) == CDFS_NTC_IRP_CONTEXT );
327#endif
328
329 //
330 // Otherwise cleanup the IrpContext for the retry.
331 //
332
333 } else {
334
335 //
336 // Set the MORE_PROCESSING flag to make sure the IrpContext
337 // isn't inadvertently deleted here. Then cleanup the
338 // IrpContext to perform the retry.
339 //
340
341 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
342 CdCleanupIrpContext( IrpContext, FALSE );
343 }
344
345 //
346 // Case on the major irp code.
347 //
348
349 switch (IrpContext->MajorFunction) {
350
351 case IRP_MJ_CREATE :
352
353 Status = CdCommonCreate( IrpContext, Irp );
354 break;
355
356 case IRP_MJ_CLOSE :
357
358 Status = CdCommonClose( IrpContext, Irp );
359 break;
360
361 case IRP_MJ_READ :
362
363 //
364 // If this is an Mdl complete request, don't go through
365 // common read.
366 //
367
368 if (FlagOn( IrpContext->MinorFunction, IRP_MN_COMPLETE )) {
369
370 Status = CdCompleteMdl( IrpContext, Irp );
371
372 } else {
373
374 Status = CdCommonRead( IrpContext, Irp );
375 }
376
377 break;
378
379 case IRP_MJ_WRITE :
380
381 Status = CdCommonWrite( IrpContext, Irp );
382 break;
383
385
386 Status = CdCommonQueryInfo( IrpContext, Irp );
387 break;
388
390
391 Status = CdCommonSetInfo( IrpContext, Irp );
392 break;
393
395
396 Status = CdCommonQueryVolInfo( IrpContext, Irp );
397 break;
398
400
401 Status = CdCommonDirControl( IrpContext, Irp );
402 break;
403
405
406 Status = CdCommonFsControl( IrpContext, Irp );
407 break;
408
410
411 Status = CdCommonDevControl( IrpContext, Irp );
412 break;
413
415
416 Status = CdCommonLockControl( IrpContext, Irp );
417 break;
418
419 case IRP_MJ_CLEANUP :
420
421 Status = CdCommonCleanup( IrpContext, Irp );
422 break;
423
424 case IRP_MJ_PNP :
425
426 Status = CdCommonPnp( IrpContext, Irp );
427 break;
428
429 case IRP_MJ_SHUTDOWN :
430
431 Status = CdCommonShutdown( IrpContext, Irp );
432 break;
433
434 default :
435
437 CdCompleteRequest( IrpContext, Irp, Status );
438 }
439
441
442 Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
443 } _SEH2_END;
444
445 } while (Status == STATUS_CANT_WAIT);
446
447#ifdef CD_SANITY
448 NT_ASSERT( !CdTestTopLevel ||
449 (PreviousTopLevel == IoGetTopLevelIrp()) );
450#endif
451
453
454 NT_ASSERT( SaveIrql == KeGetCurrentIrql( ));
455
456 return Status;
457}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
LONG CdExceptionFilter(_Inout_ PIRP_CONTEXT IrpContext, _In_ PEXCEPTION_POINTERS ExceptionPointer)
Definition: cddata.c:525
VOID CdSetThreadContext(_Inout_ PIRP_CONTEXT IrpContext, _In_ PTHREAD_CONTEXT ThreadContext)
Definition: cddata.c:981
#define ASSERT_OPTIONAL_IRP(I)
Definition: cddata.h:251
NTSTATUS CdCompleteMdl(_In_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: cachesup.c:411
VOID CdCleanupIrpContext(_In_ PIRP_CONTEXT IrpContext, _In_ BOOLEAN Post)
Definition: strucsup.c:1733
#define CanFsdWait(I)
Definition: cdprocs.h:2001
NTSTATUS CdCommonLockControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: lockctrl.c:35
NTSTATUS CdCommonDevControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: devctrl.c:46
_Ret_valid_ PIRP_CONTEXT CdCreateIrpContext(_In_ PIRP Irp, _In_ BOOLEAN Wait)
Definition: strucsup.c:1573
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_CONTEXT_FLAG_MORE_PROCESSING
Definition: cdstruc.h:1214
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CDFS_NTC_IRP_CONTEXT
Definition: nodetype.h:34
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ 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_BeginUseX()

FORCEINLINE VOID ScratchBuffer_BeginUseX ( _Inout_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_opt_ LPCSTR  File,
ULONG  Line 
)

Definition at line 90 of file scratch.h.

91{
92 // NOTE: these are not "real" locks. They are simply to help
93 // avoid multiple uses of the scratch buffer. Thus, it
94 // is not critical to have atomic operations here.
95 PVOID tmp = InterlockedCompareExchangePointer((PVOID)&(DeviceExtension->ScratchContext.ScratchInUse), (PVOID)-1, NULL);
96 NT_ASSERT(tmp == NULL);
97 UNREFERENCED_PARAMETER(tmp); //defensive coding, avoid PREFAST warning.
98 DeviceExtension->ScratchContext.ScratchInUseFileName = File;
99 DeviceExtension->ScratchContext.ScratchInUseLineNumber = Line;
100 ScratchBuffer_ResetItems(DeviceExtension, TRUE);
101 RequestClearSendTime(DeviceExtension->ScratchContext.ScratchRequest);
102 return;
103}
VOID RequestClearSendTime(_In_ WDFREQUEST Request)
Definition: common.c:111
Definition: File.h:16
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
VOID ScratchBuffer_ResetItems(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN ResetRequestHistory)
Definition: scratch.c:343
Definition: ncftp.h:79

◆ ScratchBuffer_EndUse()

FORCEINLINE VOID ScratchBuffer_EndUse ( _Inout_ PCDROM_DEVICE_EXTENSION  DeviceExtension)

Definition at line 104 of file scratch.h.

105{
106 // NOTE: these are not "real" locks. They are simply to help
107 // avoid multiple uses of the scratch buffer. Thus, it
108 // is not critical to have atomic operations here.
109
110 // On lock release, we erase ScratchInUseFileName and ScratchInUseLineNumber _before_ releasing ScratchInUse,
111 // because otherwise we may erase these after the lock has been acquired again by another thread. We store the
112 // old values of ScratchInUseFileName and ScratchInUseLineNumber in local variables to facilitate debugging,
113 // if the ASSERT at the end of the function is hit.
114 PCSTR scratchInUseFileName;
115 ULONG scratchInUseLineNumber;
116 PVOID tmp;
117
118 scratchInUseFileName = DeviceExtension->ScratchContext.ScratchInUseFileName;
119 scratchInUseLineNumber = DeviceExtension->ScratchContext.ScratchInUseLineNumber;
120 UNREFERENCED_PARAMETER(scratchInUseFileName);
121 UNREFERENCED_PARAMETER(scratchInUseLineNumber);
122 DeviceExtension->ScratchContext.ScratchInUseFileName = NULL;
123 DeviceExtension->ScratchContext.ScratchInUseLineNumber = 0;
124
125 //
126 // If we have used the PartialMdl in the scratch context we should notify MM that we will be reusing it
127 // otherwise it may leak System VA if some one below us has mapped the same.
128 //
129
130 if (DeviceExtension->ScratchContext.PartialMdlIsBuilt != FALSE)
131 {
132 MmPrepareMdlForReuse(DeviceExtension->ScratchContext.PartialMdl);
133 DeviceExtension->ScratchContext.PartialMdlIsBuilt = FALSE;
134 }
135
136 tmp = InterlockedCompareExchangePointer((PVOID)&(DeviceExtension->ScratchContext.ScratchInUse), NULL, (PVOID)-1);
137 NT_ASSERT(tmp == ((PVOID)-1));
138 UNREFERENCED_PARAMETER(tmp); //defensive coding, avoid PREFAST warning.
139 return;
140}
const char * PCSTR
Definition: typedefs.h:52
#define MmPrepareMdlForReuse(_Mdl)

Referenced by _IRQL_requires_max_(), DeviceScratchPreventMediaRemoval(), DeviceScratchSyncCache(), RequestIssueShutdownFlush(), ScratchBuffer_ReadWriteCompletionRoutine(), ScratchBuffer_ReadWriteEvtRequestCancel(), and ScratchBuffer_ReadWriteTimerRoutine().

◆ 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}
#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_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 NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FxIrp * irp
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#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
struct _SENSE_DATA * PSENSE_DATA
#define SRB_STATUS_ABORTED
Definition: srb.h:342
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
VOID CompressSrbHistoryData(_Inout_ PSRB_HISTORY RequestHistory)
Definition: scratch.c:1033
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID SenseInfoBuffer
Definition: srb.h:264
ULONG InternalStatus
Definition: srb.h:269
UCHAR SrbStatus
Definition: srb.h:251
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
@ 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
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@4000 Scsi
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
ULONG DataTransferLength
Definition: srb.h:261
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

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
NTSYSAPI ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)

Referenced by CompressSrbHistoryData().

Variable Documentation

◆ Cdb

◆ GetDataFromDevice

_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN GetDataFromDevice

Definition at line 55 of file scratch.h.

◆ MaximumTransferLength

_In_opt_ WDFREQUEST _In_ ULONG MaximumTransferLength

Definition at line 54 of file scratch.h.

◆ OprationLength

_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB _In_ UCHAR OprationLength
Initial value:
{
return ScratchBuffer_ExecuteCdbEx(DeviceExtension,
Cdb,
0)
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
_In_opt_ WDFREQUEST OriginalRequest
Definition: scratch.h:53
_In_opt_ WDFREQUEST _In_ ULONG TransferSize
Definition: scratch.h:157
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB _In_ UCHAR OprationLength
Definition: scratch.h:160
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN GetDataFromDevice
Definition: scratch.h:56

Definition at line 160 of file scratch.h.

◆ OriginalRequest

_In_opt_ WDFREQUEST OriginalRequest

Definition at line 53 of file scratch.h.

◆ ScratchBuffer_ReadWriteTimerRoutine

KDEFERRED_ROUTINE ScratchBuffer_ReadWriteTimerRoutine

Definition at line 185 of file scratch.h.

Referenced by ScratchBuffer_ReadWriteCompletionRoutine().

◆ TimeoutValue

_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB _In_ UCHAR _In_ ULONG TimeoutValue

Definition at line 161 of file scratch.h.

◆ TransferSize

_In_opt_ WDFREQUEST _In_ ULONG TransferSize

Definition at line 157 of file scratch.h.