ReactOS  0.4.13-dev-544-gede3fdd
read.c File Reference
#include "cdprocs.h"
Include dependency graph for read.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_READ)
 
#define SafeZeroMemory(IC, AT, BYTE_COUNT)
 
#define READ_AHEAD_GRANULARITY   (0x10000)
 

Functions

 _Requires_lock_held_ (_Global_critical_region_)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_READ)

Definition at line 23 of file read.c.

◆ READ_AHEAD_GRANULARITY

#define READ_AHEAD_GRANULARITY   (0x10000)

Definition at line 60 of file read.c.

◆ SafeZeroMemory

#define SafeZeroMemory (   IC,
  AT,
  BYTE_COUNT 
)
Value:
{ \
_SEH2_TRY { \
RtlZeroMemory( (AT), (BYTE_COUNT) ); \
__pragma(warning(suppress: 6320)) \
CdRaiseStatus( IC, STATUS_INVALID_USER_BUFFER ); \
} _SEH2_END; \
}
boolean suppress
Definition: jpeglib.h:1005
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_SEH2_END
Definition: create.c:4424
#define AT
Definition: mbstring.h:34
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define warning(s)
Definition: debug.h:71

Definition at line 38 of file read.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 68 of file read.c.

94 {
97 
99  PFCB Fcb;
100  PCCB Ccb;
101 
102  BOOLEAN Wait;
103  ULONG PagingIo;
104  ULONG SynchronousIo;
105  ULONG NonCachedIo;
106  PVOID UserBuffer;
107 
109  LONGLONG ByteRange;
111  ULONG ReadByteCount;
112  ULONG OriginalByteCount;
113 
114  PVOID SystemBuffer;
115 
116  BOOLEAN ReleaseFile = TRUE;
117 
118  CD_IO_CONTEXT LocalIoContext;
119 
120  PAGED_CODE();
121 
122  //
123  // If this is a zero length read then return SUCCESS immediately.
124  //
125 
126  if (IrpSp->Parameters.Read.Length == 0) {
127 
128  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
129  return STATUS_SUCCESS;
130  }
131 
132  //
133  // Decode the file object and verify we support read on this. It
134  // must be a user file, stream file or volume file (for a data disk).
135  //
136 
137  TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
138 
139  // Internal lock object is acquired if return status is STATUS_PENDING
141 
142  if ((TypeOfOpen == UnopenedFileObject) ||
144 
147  }
148 
149  //
150  // Examine our input parameters to determine if this is noncached and/or
151  // a paging io operation.
152  //
153 
154  Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
155  PagingIo = FlagOn( Irp->Flags, IRP_PAGING_IO );
156  NonCachedIo = FlagOn( Irp->Flags, IRP_NOCACHE );
157  SynchronousIo = FlagOn( IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO );
158 
159 
160  //
161  // Extract the range of the Io.
162  //
163 
164  StartingOffset = IrpSp->Parameters.Read.ByteOffset.QuadPart;
165  OriginalByteCount = ByteCount = IrpSp->Parameters.Read.Length;
166 
167  ByteRange = StartingOffset + ByteCount;
168 
169  //
170  // Make sure that Dasd access is always non-cached.
171  //
172 
173  if (TypeOfOpen == UserVolumeOpen) {
174 
175  NonCachedIo = TRUE;
176  }
177 
178  //
179  // Acquire the file shared to perform the read. If we are doing paging IO,
180  // it may be the case that we would have a deadlock imminent because we may
181  // block on shared access, so starve out any exclusive waiters. This requires
182  // a degree of caution - we believe that any paging IO bursts will recede and
183  // allow the exclusive waiter in.
184  //
185 
186  if (PagingIo) {
187 
189 
190  } else {
191 
192  CdAcquireFileShared( IrpContext, Fcb );
193  }
194 
195  //
196  // Use a try-finally to facilitate cleanup.
197  //
198 
199  _SEH2_TRY {
200 
201  //
202  // Verify the Fcb. Allow reads if this is a DASD handle that is
203  // dismounting the volume.
204  //
205 
206  if ((TypeOfOpen != UserVolumeOpen) || (NULL == Ccb) ||
208 
209  CdVerifyFcbOperation( IrpContext, Fcb );
210  }
211 
212  //
213  // If this is a non-cached then check whether we need to post this
214  // request if this thread can't block.
215  //
216 
217  if (!Wait && NonCachedIo) {
218 
219  //
220  // XA requests must always be waitable.
221  //
222 
224 
225  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST );
227  }
228  }
229 
230  //
231  // If this is a user request then verify the oplock and filelock state.
232  //
233 
234  if (TypeOfOpen == UserFileOpen) {
235 
236  //
237  // We check whether we can proceed
238  // based on the state of the file oplocks.
239  //
240 
242  Irp,
243  IrpContext,
244  (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
245  (PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */
246 
247  //
248  // If the result is not STATUS_SUCCESS then the Irp was completed
249  // elsewhere.
250  //
251 
252  if (Status != STATUS_SUCCESS) {
253 
254  Irp = NULL;
255  IrpContext = NULL;
256 
257  try_return( NOTHING );
258  }
259 
260  if (!PagingIo &&
261  (Fcb->FileLock != NULL) &&
263 
265  }
266  }
267 
268  //
269  // Check request beyond end of file if this is not a read on a volume
270  // handle marked for extended DASD IO.
271  //
272 
273  if ((TypeOfOpen != UserVolumeOpen) ||
275 
276  //
277  // Complete the request if it begins beyond the end of file.
278  //
279 
280  if (StartingOffset >= Fcb->FileSize.QuadPart) {
281 
283  }
284 
285  //
286  // Truncate the read if it extends beyond the end of the file.
287  //
288 
289  if (ByteRange > Fcb->FileSize.QuadPart) {
290 
291  ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
292  ByteRange = Fcb->FileSize.QuadPart;
293  }
294  }
295 
296  //
297  // Handle the non-cached read first.
298  //
299 
300  if (NonCachedIo) {
301 
302  //
303  // If we have an unaligned transfer then post this request if
304  // we can't wait. Unaligned means that the starting offset
305  // is not on a sector boundary or the read is not integral
306  // sectors.
307  //
308 
309  ReadByteCount = BlockAlign( Fcb->Vcb, ByteCount );
310 
311  if (SectorOffset( StartingOffset ) ||
312  SectorOffset( ReadByteCount ) ||
313  (ReadByteCount > OriginalByteCount)) {
314 
315  if (!Wait) {
316 
317  CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
318  }
319 
320  //
321  // Make sure we don't overwrite the buffer.
322  //
323 
324  ReadByteCount = ByteCount;
325  }
326 
327  //
328  // Initialize the IoContext for the read.
329  // If there is a context pointer, we need to make sure it was
330  // allocated and not a stale stack pointer.
331  //
332 
333  if (IrpContext->IoContext == NULL ||
334  !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) {
335 
336  //
337  // If we can wait, use the context on the stack. Otherwise
338  // we need to allocate one.
339  //
340 
341  if (Wait) {
342 
343  IrpContext->IoContext = &LocalIoContext;
344  ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
345 
346  } else {
347 
348  IrpContext->IoContext = CdAllocateIoContext();
349  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
350  }
351  }
352 
353  RtlZeroMemory( IrpContext->IoContext, sizeof( CD_IO_CONTEXT ));
354 
355  //
356  // Store whether we allocated this context structure in the structure
357  // itself.
358  //
359 
360  IrpContext->IoContext->AllocatedContext =
361  BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
362 
363  if (Wait) {
364 
365  KeInitializeEvent( &IrpContext->IoContext->SyncEvent,
367  FALSE );
368 
369  } else {
370 
371  IrpContext->IoContext->ResourceThreadId = ExGetCurrentResourceThread();
372  IrpContext->IoContext->Resource = Fcb->Resource;
373  IrpContext->IoContext->RequestedByteCount = ByteCount;
374  }
375 
376  Irp->IoStatus.Information = ReadByteCount;
377 
378  //
379  // Call one of the NonCacheIo routines to perform the actual
380  // read.
381  //
382 
384 
385  Status = CdNonCachedXARead( IrpContext, Fcb, StartingOffset, ReadByteCount );
386 
387  } else {
388 
389  Status = CdNonCachedRead( IrpContext, Fcb, StartingOffset, ReadByteCount );
390  }
391 
392  //
393  // Don't complete this request now if STATUS_PENDING was returned.
394  //
395 
396  if (Status == STATUS_PENDING) {
397 
398  Irp = NULL;
399  ReleaseFile = FALSE;
400 
401  //
402  // Test is we should zero part of the buffer or update the
403  // synchronous file position.
404  //
405 
406  } else {
407 
408  //
409  // Convert any unknown error code to IO_ERROR.
410  //
411 
412  if (!NT_SUCCESS( Status )) {
413 
414  //
415  // Set the information field to zero.
416  //
417 
418  Irp->IoStatus.Information = 0;
419 
420  //
421  // Raise if this is a user induced error.
422  //
423 
424  if (IoIsErrorUserInduced( Status )) {
425 
426  CdRaiseStatus( IrpContext, Status );
427  }
428 
430 
431  //
432  // Check if there is any portion of the user's buffer to zero.
433  //
434 
435  } else if (ReadByteCount != ByteCount) {
436 
437  CdMapUserBuffer( IrpContext, &UserBuffer);
438 
439  SafeZeroMemory( IrpContext,
440  Add2Ptr( UserBuffer,
441  ByteCount,
442  PVOID ),
443  ReadByteCount - ByteCount );
444 
445  Irp->IoStatus.Information = ByteCount;
446  }
447 
448  //
449  // Update the file position if this is a synchronous request.
450  //
451 
452  if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) {
453 
454  IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange;
455  }
456  }
457 
458  try_return( NOTHING );
459  }
460 
461  //
462  // Handle the cached case. Start by initializing the private
463  // cache map.
464  //
465 
466  if (IrpSp->FileObject->PrivateCacheMap == NULL) {
467 
468  //
469  // Now initialize the cache map.
470  //
471 
473  (PCC_FILE_SIZES) &Fcb->AllocationSize,
474  FALSE,
476  Fcb );
477 
479  }
480 
481  //
482  // Read from the cache if this is not an Mdl read.
483  //
484 
485  if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
486 
487  //
488  // If we are in the Fsp now because we had to wait earlier,
489  // we must map the user buffer, otherwise we can use the
490  // user's buffer directly.
491  //
492 
493  CdMapUserBuffer( IrpContext, &SystemBuffer );
494 
495  //
496  // Now try to do the copy.
497  //
498 
499  if (!CcCopyRead( IrpSp->FileObject,
501  ByteCount,
502  Wait,
503  SystemBuffer,
504  &Irp->IoStatus )) {
505 
507  }
508 
509  //
510  // If the call didn't succeed, raise the error status
511  //
512 
513  if (!NT_SUCCESS( Irp->IoStatus.Status )) {
514 
515  CdNormalizeAndRaiseStatus( IrpContext, Irp->IoStatus.Status );
516  }
517 
518  //
519  // Otherwise perform the MdlRead operation.
520  //
521 
522  } else {
523 
526  ByteCount,
527  &Irp->MdlAddress,
528  &Irp->IoStatus );
529 
530  Status = Irp->IoStatus.Status;
531  }
532 
533  //
534  // Update the current file position in the user file object.
535  //
536 
537  if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) {
538 
539  IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange;
540  }
541 
542  try_exit: NOTHING;
543  } _SEH2_FINALLY {
544 
545  //
546  // Release the Fcb.
547  //
548 
549  if (ReleaseFile) {
550 
551  CdReleaseFile( IrpContext, Fcb );
552  }
553  } _SEH2_END;
554 
555  //
556  // Post the request if we got CANT_WAIT.
557  //
558 
559  if (Status == STATUS_CANT_WAIT) {
560 
561  Status = CdFsdPostRequest( IrpContext, Irp );
562 
563  //
564  // Otherwise complete the request.
565  //
566 
567  } else {
568 
569  CdCompleteRequest( IrpContext, Irp, Status );
570  }
571 
572  return Status;
573 }
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633
FILE_LOCK FileLock
Definition: fatstruc.h:1067
VOID NTAPI CcMdlRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:64
#define _Analysis_suppress_lock_checking_(lock)
Definition: no_sal2.h:685
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define Add2Ptr(PTR, INC)
#define CCB_FLAG_DISMOUNT_ON_CLOSE
Definition: cdstruc.h:1113
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
#define CdAcquireFileSharedStarveExclusive(IC, F)
Definition: cdprocs.h:1005
#define IRP_CONTEXT_FLAG_ALLOC_IO
Definition: cdstruc.h:1227
#define IRP_CONTEXT_FLAG_FORCE_POST
Definition: cdstruc.h:1222
#define CdReleaseFile(IC, F)
Definition: cdprocs.h:1008
#define SafeZeroMemory(IC, AT, BYTE_COUNT)
Definition: read.c:38
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdstruc.h:908
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO
Definition: cdstruc.h:1114
Definition: cdstruc.h:1073
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: cdstruc.h:415
#define CdMapUserBuffer(IC, UB)
Definition: cdprocs.h:376
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_NOCACHE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define READ_AHEAD_GRANULARITY
Definition: read.c:60
#define CdAcquireFileShared(IC, F)
Definition: cdprocs.h:1002
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define STATUS_END_OF_FILE
Definition: shellext.h:62
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1732
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
#define CdGetFcbOplock(F)
Definition: cdprocs.h:1086
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define SectorOffset(L)
Definition: cdprocs.h:1632
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define BlockAlign(V, L)
Definition: cdprocs.h:1648
int64_t LONGLONG
Definition: typedefs.h:66
CD_DATA CdData
Definition: cddata.c:42
#define CdAllocateIoContext()
Definition: cdprocs.h:1349
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:193
#define try_return(S)
Definition: cdprocs.h:2189
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:676
ULONG Flags
Definition: ntfs.h:520
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
#define FCB_STATE_RAWSECTOR_MASK
Definition: cdstruc.h:1058
#define IRP_MN_MDL
Definition: iotypes.h:4062
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define NOTHING
Definition: env_spec_w32.h:461
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1060
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1869
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
BOOLEAN CdVerifyFcbOperation(_In_opt_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb)
Definition: verfysup.c:615
#define IRP_PAGING_IO
#define STATUS_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:455
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:306
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PVCB Vcb
Definition: cdstruc.h:939
#define CdNormalizeAndRaiseStatus(IC, S)
Definition: cdprocs.h:1870
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1172
NTSTATUS NTAPI FsRtlNormalizeNtstatus(IN NTSTATUS NtStatusToNormalize, IN NTSTATUS NormalizedNtStatus)
Definition: filter.c:90
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2777
ULONG FcbState
Definition: cdstruc.h:977
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
IN BOOLEAN Wait
Definition: fatprocs.h:1529
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36