ReactOS  0.4.15-dev-2704-gd5265b0
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 197 of file cddata.c.

254 {
255  THREAD_CONTEXT ThreadContext = {0};
256  PIRP_CONTEXT IrpContext = NULL;
257  BOOLEAN Wait;
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 
409  case IRP_MJ_DEVICE_CONTROL :
410 
411  Status = CdCommonDevControl( IrpContext, Irp );
412  break;
413 
414  case IRP_MJ_LOCK_CONTROL :
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 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID CdSetThreadContext(_Inout_ PIRP_CONTEXT IrpContext, _In_ PTHREAD_CONTEXT ThreadContext)
Definition: cddata.c:981
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define IRP_MJ_SHUTDOWN
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IRP_CONTEXT_FLAG_MORE_PROCESSING
Definition: cdstruc.h:1214
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_SEH2_TRY
Definition: create.c:4226
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
unsigned char BOOLEAN
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define IRP_MJ_FILE_SYSTEM_CONTROL
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define CanFsdWait(I)
Definition: cdprocs.h:2001
NTSTATUS CdCompleteMdl(_In_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: cachesup.c:411
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
NTSTATUS CdCommonDevControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: devctrl.c:46
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
LONG CdExceptionFilter(_Inout_ PIRP_CONTEXT IrpContext, _In_ PEXCEPTION_POINTERS ExceptionPointer)
Definition: cddata.c:525
#define ASSERT_OPTIONAL_IRP(I)
Definition: cddata.h:251
#define NULL
Definition: types.h:112
VOID CdCleanupIrpContext(_In_ PIRP_CONTEXT IrpContext, _In_ BOOLEAN Post)
Definition: strucsup.c:1733
NTSTATUS CdCommonLockControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: lockctrl.c:35
#define CDFS_NTC_IRP_CONTEXT
Definition: nodetype.h:34
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
_Ret_valid_ PIRP_CONTEXT CdCreateIrpContext(_In_ PIRP Irp, _In_ BOOLEAN Wait)
Definition: strucsup.c:1573
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#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_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 }
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
struct Line Line
Definition: wdfdevice.h:4081
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
VOID RequestClearSendTime(_In_ WDFREQUEST Request)
Definition: common.c:111
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID _In_ LONG _In_z_ PCHAR File
Definition: wdfdevice.h:4061
VOID ScratchBuffer_ResetItems(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN ResetRequestHistory)
Definition: scratch.c:343
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ 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 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define FALSE
Definition: types.h:117
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define MmPrepareMdlForReuse(_Mdl)
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
const char * PCSTR
Definition: typedefs.h:52
#define NT_ASSERT
Definition: rtlfuncs.h:3312

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 }
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:25
#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_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:672
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:2695
#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:3128
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

◆ Cdb

◆ GetDataFromDevice

_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN GetDataFromDevice

Definition at line 53 of file scratch.h.

◆ MaximumTransferLength

_In_opt_ WDFREQUEST _In_ ULONG MaximumTransferLength

Definition at line 53 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 GetDataFromDevice
Definition: scratch.h:53
_In_opt_ WDFREQUEST OriginalRequest
Definition: scratch.h:53
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB _In_ UCHAR OprationLength
Definition: scratch.h:156
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:156
_In_opt_ WDFREQUEST _In_ ULONG TransferSize
Definition: scratch.h:156

Definition at line 156 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.

◆ TimeoutValue

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

Definition at line 156 of file scratch.h.

◆ TransferSize

_In_opt_ WDFREQUEST _In_ ULONG TransferSize

Definition at line 156 of file scratch.h.