ReactOS  0.4.14-dev-317-g96040ec
read.cpp File Reference
#include "udffs.h"
Include dependency graph for read.cpp:

Go to the source code of this file.

Macros

#define UDF_BUG_CHECK_ID   UDF_FILE_READ
 
#define OVERFLOW_READ_THRESHHOLD   (0x1000)
 
#define UDF_REQ_NOT_VIA_CACHE_MGR(ptr)   (!MmIsRecursiveIoFault() && ((ptr)->ImageSectionObject != NULL))
 

Functions

NTSTATUS NTAPI UDFRead (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFPostStackOverflowRead (IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PtrUDFFCB Fcb)
 
VOID NTAPI UDFStackOverflowRead (IN PVOID Context, IN PKEVENT Event)
 
NTSTATUS UDFCommonRead (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
PVOID UDFGetCallersBuffer (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFLockCallersBuffer (PtrUDFIrpContext PtrIrpContext, PIRP Irp, BOOLEAN IsReadOperation, uint32 Length)
 
NTSTATUS UDFUnlockCallersBuffer (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVOID SystemBuffer)
 
VOID UDFMdlComplete (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN ReadCompletion)
 

Macro Definition Documentation

◆ OVERFLOW_READ_THRESHHOLD

#define OVERFLOW_READ_THRESHHOLD   (0x1000)

Definition at line 29 of file read.cpp.

◆ UDF_BUG_CHECK_ID

#define UDF_BUG_CHECK_ID   UDF_FILE_READ

Definition at line 20 of file read.cpp.

◆ UDF_REQ_NOT_VIA_CACHE_MGR

#define UDF_REQ_NOT_VIA_CACHE_MGR (   ptr)    (!MmIsRecursiveIoFault() && ((ptr)->ImageSectionObject != NULL))

Function Documentation

◆ UDFCommonRead()

NTSTATUS UDFCommonRead ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 229 of file read.cpp.

233 {
237  ULONG ReadLength = 0, TruncatedLength = 0;
238  SIZE_T NumberBytesRead = 0;
240  PtrUDFFCB Fcb = NULL;
241  PtrUDFCCB Ccb = NULL;
242  PVCB Vcb = NULL;
244  PERESOURCE PtrResourceAcquired = NULL;
245  PERESOURCE PtrResourceAcquired2 = NULL;
246  PVOID SystemBuffer = NULL;
247  PIRP TopIrp;
248 // uint32 KeyValue = 0;
249 
250  ULONG Res1Acq = 0;
251  ULONG Res2Acq = 0;
252 
253  BOOLEAN CacheLocked = FALSE;
254 
255  BOOLEAN CanWait = FALSE;
256  BOOLEAN PagingIo = FALSE;
257  BOOLEAN NonBufferedIo = FALSE;
258  BOOLEAN SynchronousIo = FALSE;
259 
260  TmPrint(("UDFCommonRead: irp %x\n", Irp));
261 
262  _SEH2_TRY {
263 
264  TopIrp = IoGetTopLevelIrp();
265  switch((ULONG_PTR)TopIrp) {
267  UDFPrint((" FSRTL_FSP_TOP_LEVEL_IRP\n"));
268  break;
270  UDFPrint((" FSRTL_CACHE_TOP_LEVEL_IRP\n"));
271  break;
273  UDFPrint((" FSRTL_MOD_WRITE_TOP_LEVEL_IRP\n"));
274 // BrutePoint()
275  break;
277  UDFPrint((" FSRTL_FAST_IO_TOP_LEVEL_IRP\n"));
278 // BrutePoint()
279  break;
280  case NULL:
281  UDFPrint((" NULL TOP_LEVEL_IRP\n"));
282  break;
283  default:
284  if(TopIrp == Irp) {
285  UDFPrint((" TOP_LEVEL_IRP\n"));
286  } else {
287  UDFPrint((" RECURSIVE_IRP, TOP = %x\n", TopIrp));
288  }
289  break;
290  }
291  // First, get a pointer to the current I/O stack location
293  ASSERT(IrpSp);
294  MmPrint((" Enter Irp, MDL=%x\n", Irp->MdlAddress));
295  if(Irp->MdlAddress) {
296  UDFTouch(Irp->MdlAddress);
297  }
298 
299  // If this happens to be a MDL read complete request, then
300  // there is not much processing that the FSD has to do.
302  // Caller wants to tell the Cache Manager that a previously
303  // allocated MDL can be freed.
304  UDFMdlComplete(PtrIrpContext, Irp, IrpSp, TRUE);
305  // The IRP has been completed.
307  }
308 
309  // If this is a request at IRQL DISPATCH_LEVEL, then post
310  // the request (your FSD may choose to process it synchronously
311  // if you implement the support correctly; obviously you will be
312  // quite constrained in what you can do at such IRQL).
313  if (IrpSp->MinorFunction & IRP_MN_DPC) {
315  }
316 
319 
320  // Get the FCB and CCB pointers
321  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
322  ASSERT(Ccb);
323  Fcb = Ccb->Fcb;
324  ASSERT(Fcb);
325  Vcb = Fcb->Vcb;
326 
327  if(Fcb->FCBFlags & UDF_FCB_DELETED) {
328  ASSERT(FALSE);
330  }
331 
332  // check for stack overflow
333  if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {
334  RC = UDFPostStackOverflowRead( PtrIrpContext, Irp, Fcb );
335  try_return(RC);
336  }
337 
338  // Disk based file systems might decide to verify the logical volume
339  // (if required and only if removable media are supported) at this time
340  // As soon as Tray is locked, we needn't call UDFVerifyVcb()
341 
342  ByteOffset = IrpSp->Parameters.Read.ByteOffset;
343 
344  CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
345  PagingIo = (Irp->Flags & IRP_PAGING_IO) ? TRUE : FALSE;
346  NonBufferedIo = (Irp->Flags & IRP_NOCACHE) ? TRUE : FALSE;
347  SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO) ? TRUE : FALSE;
348  UDFPrint((" Flags: %s %s %s %s\n",
349  CanWait ? "W" : "w", PagingIo ? "Pg" : "pg",
350  NonBufferedIo ? "NBuf" : "buff", SynchronousIo ? "Snc" : "Asc"));
351 
352  if(!NonBufferedIo &&
353  (Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB)) {
354  if(UDFIsAStream(Fcb->FileInfo)) {
355  UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
358  } else {
359  UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
362  }
363  }
364 
365  // Get some of the parameters supplied to us
366  ReadLength = IrpSp->Parameters.Read.Length;
367  if (ReadLength == 0) {
368  // a 0 byte read can be immediately succeeded
369  try_return(RC);
370  }
371  UDFPrint((" ByteOffset = %I64x, ReadLength = %x\n", ByteOffset.QuadPart, ReadLength));
372 
373  // Is this a read of the volume itself ?
374  if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
375  // Yup, we need to send this on to the disk driver after
376  // validation of the offset and length.
377  Vcb = (PVCB)Fcb;
378  Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
379  if(!CanWait)
381 
382 
383  if(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_FLUSH2_REQUIRED) {
384 
385  UDFPrint((" UDF_IRP_CONTEXT_FLUSH2_REQUIRED\n"));
387 
388  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
389  UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
390  }
391 #ifdef UDF_DELAYED_CLOSE
393 #endif //UDF_DELAYED_CLOSE
394 
395  }
396 
397  if(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_FLUSH_REQUIRED) {
398 
399  UDFPrint((" UDF_IRP_CONTEXT_FLUSH_REQUIRED\n"));
401 
402  // Acquire the volume resource exclusive
403  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
404  PtrResourceAcquired = &(Vcb->VCBResource);
405 
407 
408  UDFReleaseResource(PtrResourceAcquired);
409  PtrResourceAcquired = NULL;
410  }
411 
412  // Acquire the volume resource shared ...
413  UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
414  PtrResourceAcquired = &(Vcb->VCBResource);
415 
416 #if 0
417  if(PagingIo) {
418  CollectStatistics(Vcb, MetaDataReads);
419  CollectStatisticsEx(Vcb, MetaDataReadBytes, NumberBytesRead);
420  }
421 #endif
422 
423  // Forward the request to the lower level driver
424  // Lock the callers buffer
425  if (!NT_SUCCESS(RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, ReadLength))) {
426  try_return(RC);
427  }
428  SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
429  if(!SystemBuffer) {
431  }
432  if(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) {
433  RC = UDFReadData(Vcb, TRUE, ByteOffset.QuadPart,
434  ReadLength, FALSE, (PCHAR)SystemBuffer,
435  &NumberBytesRead);
436  } else {
437  RC = UDFTRead(Vcb, SystemBuffer, ReadLength,
438  (ULONG)(ByteOffset.QuadPart >> Vcb->BlockSizeBits),
439  &NumberBytesRead);
440  }
441  UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
442  try_return(RC);
443  }
444  Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
445 
446  // If the read request is directed to a page file (if your FSD
447  // supports paging files), send the request directly to the disk
448  // driver. For requests directed to a page file, you have to trust
449  // that the offsets will be set correctly by the VMM. You should not
450  // attempt to acquire any FSD resources either.
451  if(Fcb->FCBFlags & UDF_FCB_PAGE_FILE) {
452  NonBufferedIo = TRUE;
453  }
454 
455  if(ByteOffset.HighPart == -1) {
457  ByteOffset = FileObject->CurrentByteOffset;
458  }
459  }
460 
461  // If this read is directed to a directory, it is not allowed
462  // by the UDF FSD.
463  if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
465  try_return(RC);
466  }
467 
468  NtReqFcb = Fcb->NTRequiredFCB;
469 
470  Res1Acq = UDFIsResourceAcquired(&(NtReqFcb->MainResource));
471  if(!Res1Acq) {
472  Res1Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES1_ACQ;
473  }
474  Res2Acq = UDFIsResourceAcquired(&(NtReqFcb->PagingIoResource));
475  if(!Res2Acq) {
476  Res2Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES2_ACQ;
477  }
478 
479 #if 0
480  if(PagingIo) {
481  CollectStatistics(Vcb, UserFileReads);
482  CollectStatisticsEx(Vcb, UserFileReadBytes, NumberBytesRead);
483  }
484 #endif
485 
486  // This is a good place for oplock related processing.
487 
488  // If this is the normal file we have to check for
489  // write access according to the current state of the file locks.
490  if (!PagingIo &&
491  !FsRtlCheckLockForReadAccess( &(NtReqFcb->FileLock), Irp )) {
493  }
494 
495  // Validate start offset and length supplied.
496  // If start offset is > end-of-file, return an appropriate error. Note
497  // that since a FCB resource has already been acquired, and since all
498  // file size changes require acquisition of both FCB resources,
499  // the contents of the FCB and associated data structures
500  // can safely be examined.
501 
502  // Also note that we are using the file size in the "Common FCB Header"
503  // to perform the check. However, your FSD might decide to keep a
504  // separate copy in the FCB (or some other representation of the
505  // file associated with the FCB).
506 
507  TruncatedLength = ReadLength;
508  if (ByteOffset.QuadPart >= NtReqFcb->CommonFCBHeader.FileSize.QuadPart) {
509  // Starting offset is >= file size
511  }
512  // We can also go ahead and truncate the read length here
513  // such that it is contained within the file size
514  if( NtReqFcb->CommonFCBHeader.FileSize.QuadPart < (ByteOffset.QuadPart + ReadLength) ) {
515  TruncatedLength = (ULONG)(NtReqFcb->CommonFCBHeader.FileSize.QuadPart - ByteOffset.QuadPart);
516  // we can't get ZERO here
517  }
518  UDFPrint((" TruncatedLength = %x\n", TruncatedLength));
519 
520  // There are certain complications that arise when the same file stream
521  // has been opened for cached and non-cached access. The FSD is then
522  // responsible for maintaining a consistent view of the data seen by
523  // the caller.
524  // Also, it is possible for file streams to be mapped in both as data files
525  // and as an executable. This could also lead to consistency problems since
526  // there now exist two separate sections (and pages) containing file
527  // information.
528 
529  // The test below flushes the data cached in system memory if the current
530  // request madates non-cached access (file stream must be cached) and
531  // (a) the current request is not paging-io which indicates it is not
532  // a recursive I/O operation OR originating in the Cache Manager
533  // (b) OR the current request is paging-io BUT it did not originate via
534  // the Cache Manager (or is a recursive I/O operation) and we do
535  // have an image section that has been initialized.
536 #define UDF_REQ_NOT_VIA_CACHE_MGR(ptr) (!MmIsRecursiveIoFault() && ((ptr)->ImageSectionObject != NULL))
537 
538  if(NonBufferedIo &&
539  (NtReqFcb->SectionObject.DataSectionObject != NULL)) {
540  if(!PagingIo) {
541 
542 /* // We hold the main resource exclusive here because the flush
543  // may generate a recursive write in this thread. The PagingIo
544  // resource is held shared so the drop-and-release serialization
545  // below will work.
546  if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
547  try_return(RC = STATUS_PENDING);
548  }
549  PtrResourceAcquired = &(NtReqFcb->MainResource);
550 
551  // We hold PagingIo shared around the flush to fix a
552  // cache coherency problem.
553  UDFAcquireResourceShared(&(NtReqFcb->PagingIoResource), TRUE );*/
554 
555  MmPrint((" CcFlushCache()\n"));
556  CcFlushCache(&(NtReqFcb->SectionObject), &ByteOffset, TruncatedLength, &(Irp->IoStatus));
557 
558 /* UDFReleaseResource(&(NtReqFcb->PagingIoResource));
559  UDFReleaseResource(PtrResourceAcquired);
560  PtrResourceAcquired = NULL;
561  // If the flush failed, return error to the caller
562  if(!NT_SUCCESS(RC = Irp->IoStatus.Status)) {
563  try_return(RC);
564  }
565 
566  // Acquiring and immediately dropping the resource serializes
567  // us behind any other writes taking place (either from the
568  // lazy writer or modified page writer).*/
569  if(!Res2Acq) {
570  UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE );
571  UDFReleaseResource(&(NtReqFcb->PagingIoResource));
572  }
573  }
574  }
575 
576  // Acquire the appropriate FCB resource shared
577  if (PagingIo) {
578  // Try to acquire the FCB PagingIoResource shared
579  if(!Res2Acq) {
580  if (!UDFAcquireResourceShared(&(NtReqFcb->PagingIoResource), CanWait)) {
582  }
583  // Remember the resource that was acquired
584  PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
585  }
586  } else {
587  // Try to acquire the FCB MainResource shared
588  if(NonBufferedIo) {
589  if(!Res2Acq) {
590  if(!UDFAcquireSharedWaitForExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
592  }
593  PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
594  }
595  } else {
596  if(!Res1Acq) {
598  if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
600  }
601  // Remember the resource that was acquired
602  PtrResourceAcquired = &(NtReqFcb->MainResource);
603  }
604  }
605  }
606 
607  // This is also a good place to set whether fast-io can be performed
608  // on this particular file or not. Your FSD must make it's own
609  // determination on whether or not to allow fast-io operations.
610  // Commonly, fast-io is not allowed if any byte range locks exist
611  // on the file or if oplocks prevent fast-io. Practically any reason
612  // choosen by your FSD could result in your setting FastIoIsNotPossible
613  // OR FastIoIsQuestionable instead of FastIoIsPossible.
614 
615  NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
616 /* if(NtReqFcb->CommonFCBHeader.IsFastIoPossible == FastIoIsPossible)
617  NtReqFcb->CommonFCBHeader.IsFastIoPossible = FastIoIsQuestionable;*/
618 
619 #ifdef UDF_DISABLE_SYSTEM_CACHE_MANAGER
620  NonBufferedIo = TRUE;
621 #endif
622 
623  if(Fcb && Fcb->FileInfo && Fcb->FileInfo->Dloc) {
624  AdPrint(("UDFCommonRead: DataLoc %x, Mapping %x\n", &Fcb->FileInfo->Dloc->DataLoc, Fcb->FileInfo->Dloc->DataLoc.Mapping));
625  }
626 
627  // Branch here for cached vs non-cached I/O
628  if (!NonBufferedIo) {
629 
630  if(FileObject->Flags & FO_WRITE_THROUGH) {
631  CanWait = TRUE;
632  }
633  // The caller wishes to perform cached I/O. Initiate caching if
634  // this is the first cached I/O operation using this file object
635  if (!(FileObject->PrivateCacheMap)) {
636  // This is the first cached I/O operation. You must ensure
637  // that the FCB Common FCB Header contains valid sizes at this time
638  MmPrint((" CcInitializeCacheMap()\n"));
639  CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)(&(NtReqFcb->CommonFCBHeader.AllocationSize)),
640  FALSE, // We will not utilize pin access for this file
641  &(UDFGlobalData.CacheMgrCallBacks), // callbacks
642  NtReqFcb); // The context used in callbacks
643  MmPrint((" CcSetReadAheadGranularity()\n"));
644  CcSetReadAheadGranularity(FileObject, Vcb->SystemCacheGran);
645  }
646 
647  // Check and see if this request requires a MDL returned to the caller
648  if (IrpSp->MinorFunction & IRP_MN_MDL) {
649  // Caller does want a MDL returned. Note that this mode
650  // implies that the caller is prepared to block
651  MmPrint((" CcMdlRead()\n"));
652 // CcMdlRead(FileObject, &ByteOffset, TruncatedLength, &(Irp->MdlAddress), &(Irp->IoStatus));
653 // NumberBytesRead = Irp->IoStatus.Information;
654 // RC = Irp->IoStatus.Status;
655  NumberBytesRead = 0;
657 
658  try_return(RC);
659  }
660 
661  // This is a regular run-of-the-mill cached I/O request. Let the
662  // Cache Manager worry about it!
663  // First though, we need a buffer pointer (address) that is valid
664  SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
665  if(!SystemBuffer)
667  ASSERT(SystemBuffer);
668  MmPrint((" CcCopyRead()\n"));
669  if (!CcCopyRead(FileObject, &(ByteOffset), TruncatedLength, CanWait, SystemBuffer, &(Irp->IoStatus))) {
670  // The caller was not prepared to block and data is not immediately
671  // available in the system cache
673  }
674 
675  UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
676  // We have the data
677  RC = Irp->IoStatus.Status;
678  NumberBytesRead = Irp->IoStatus.Information;
679 
680  try_return(RC);
681 
682  } else {
683 
684  MmPrint((" Read NonBufferedIo\n"));
685 
686 #if 1
688  UDFPrint(("FSRTL_MOD_WRITE_TOP_LEVEL_IRP => CanWait\n"));
689  CanWait = TRUE;
690  } else
691  if((ULONG_PTR)TopIrp == FSRTL_CACHE_TOP_LEVEL_IRP) {
692  UDFPrint(("FSRTL_CACHE_TOP_LEVEL_IRP => CanWait\n"));
693  CanWait = TRUE;
694  }
695 
696  if(NtReqFcb->AcqSectionCount || NtReqFcb->AcqFlushCount) {
697  MmPrint((" AcqCount (%d/%d)=> CanWait ?\n", NtReqFcb->AcqSectionCount, NtReqFcb->AcqFlushCount));
698  CanWait = TRUE;
699  } else
700  {}
701 /* if((TopIrp != Irp)) {
702  UDFPrint(("(TopIrp != Irp) => CanWait\n"));
703  CanWait = TRUE;
704  } else*/
705 #endif
707  MmPrint((" !PASSIVE_LEVEL\n"));
708  CanWait = FALSE;
710  }
711  if(!CanWait && UDFIsFileCached__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength, FALSE)) {
712  MmPrint((" Locked => CanWait\n"));
713  CacheLocked = TRUE;
714  CanWait = TRUE;
715  }
716 
717  // Send the request to lower level drivers
718  if(!CanWait) {
720  }
721 
722 // ASSERT(NT_SUCCESS(RC));
723  if(!Res2Acq) {
724  if(UDFAcquireResourceSharedWithCheck(&(NtReqFcb->PagingIoResource)))
725  PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
726  }
727 
728  RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, TruncatedLength);
729  if(!NT_SUCCESS(RC)) {
730  try_return(RC);
731  }
732 
733  SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
734  if(!SystemBuffer) {
736  }
737 
738  RC = UDFReadFile__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength,
739  CacheLocked, (PCHAR)SystemBuffer, &NumberBytesRead);
740 /* // AFAIU, CacheManager wants this:
741  if(!NT_SUCCESS(RC)) {
742  NumberBytesRead = 0;
743  }*/
744 
745  UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
746 
747 #if 0
748  if(PagingIo) {
749  CollectStatistics(Vcb, UserDiskReads);
750  } else {
751  CollectStatistics2(Vcb, NonCachedDiskReads);
752  }
753 #endif
754 
755  try_return(RC);
756 
757  // For paging-io, the FSD has to trust the VMM to do the right thing
758 
759  // Here is a common method used by Windows NT native file systems
760  // that are in the process of sending a request to the disk driver.
761  // First, mark the IRP as pending, then invoke the lower level driver
762  // after setting a completion routine.
763  // Meanwhile, this particular thread can immediately return a
764  // STATUS_PENDING return code.
765  // The completion routine is then responsible for completing the IRP
766  // and unlocking appropriate resources
767 
768  // Also, at this point, the FSD might choose to utilize the
769  // information contained in the ValidDataLength field to simply
770  // return zeroes to the caller for reads extending beyond current
771  // valid data length.
772 
773  }
774 
775 try_exit: NOTHING;
776 
777  } _SEH2_FINALLY {
778 
779  if(CacheLocked) {
780  WCacheEODirect__(&(Vcb->FastCache), Vcb);
781  }
782 
783  // Release any resources acquired here ...
784  if(PtrResourceAcquired2) {
785  UDFReleaseResource(PtrResourceAcquired2);
786  }
787  if(PtrResourceAcquired) {
788  if(NtReqFcb &&
789  (PtrResourceAcquired ==
790  &(NtReqFcb->MainResource))) {
792  }
793  UDFReleaseResource(PtrResourceAcquired);
794  }
795 
796  // Post IRP if required
797  if(RC == STATUS_PENDING) {
798 
799  // Lock the callers buffer here. Then invoke a common routine to
800  // perform the post operation.
801  if (!(IrpSp->MinorFunction & IRP_MN_MDL)) {
802  RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, ReadLength);
803  ASSERT(NT_SUCCESS(RC));
804  }
805  if(PagingIo) {
806  if(Res1Acq) {
807  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_RES1_ACQ;
808  }
809  if(Res2Acq) {
810  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_RES2_ACQ;
811  }
812  }
813  // Perform the post operation which will mark the IRP pending
814  // and will return STATUS_PENDING back to us
815  RC = UDFPostRequest(PtrIrpContext, Irp);
816 
817  } else {
818  // For synchronous I/O, the FSD must maintain the current byte offset
819  // Do not do this however, if I/O is marked as paging-io
820  if (SynchronousIo && !PagingIo && NT_SUCCESS(RC)) {
821  FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + NumberBytesRead;
822  }
823  // If the read completed successfully and this was not a paging-io
824  // operation, set a flag in the CCB that indicates that a read was
825  // performed and that the file time should be updated at cleanup
826  if (NT_SUCCESS(RC) && !PagingIo) {
828  Ccb->CCBFlags |= UDF_CCB_ACCESSED;
829  }
830 
832  Irp->IoStatus.Status = RC;
833  Irp->IoStatus.Information = NumberBytesRead;
834  UDFPrint((" NumberBytesRead = %x\n", NumberBytesRead));
835  // Free up the Irp Context
836  UDFReleaseIrpContext(PtrIrpContext);
837  // complete the IRP
838  MmPrint((" Complete Irp, MDL=%x\n", Irp->MdlAddress));
839  if(Irp->MdlAddress) {
840  UDFTouch(Irp->MdlAddress);
841  }
843  }
844  } // can we complete the IRP ?
845  } _SEH2_END; // end of "__finally" processing
846 
847  return(RC);
848 } // end UDFCommonRead()
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
signed char * PCHAR
Definition: retypes.h:7
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
struct _UDFContextControlBlock * PtrUDFCCB
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
struct _FCB::@710::@713 Fcb
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define CollectStatistics2(VCB, Field)
Definition: env_spec.h:128
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_NOCACHE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
Definition: cdstruc.h:504
#define FILE_USE_FILE_POINTER_POSITION
Definition: ffsdrv.h:155
OSSTATUS UDFReadData(IN PVCB Vcb, IN BOOLEAN Translate, IN LONGLONG Offset, IN ULONG Length, IN BOOLEAN Direct, OUT PCHAR Buffer, OUT PSIZE_T ReadBytes)
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
VOID UDFMdlComplete(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN ReadCompletion)
Definition: read.cpp:1117
_SEH2_TRY
Definition: create.c:4250
#define STATUS_END_OF_FILE
Definition: shellext.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1733
#define IRP_MN_COMPLETE
Definition: iotypes.h:4064
#define UDF_IRP_CONTEXT_FLUSH2_REQUIRED
Definition: struct.h:393
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1752
#define FILE_ACTION_MODIFIED
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define FILE_ACTION_MODIFIED_STREAM
#define UDFAcquireSharedWaitForExclusive(Resource, CanWait)
Definition: env_spec_w32.h:671
unsigned char BOOLEAN
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN UDFAcquireResourceSharedWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2556
uint32 IrpContextFlags
Definition: struct.h:364
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
__inline VOID UDFNotifyFullReportChange(PVCB V, PUDF_FILE_INFO FI, ULONG E, ULONG A)
Definition: env_spec.h:99
#define UDFTouch(a)
Definition: env_spec_w32.h:303
#define UDF_VCB_SKIP_EJECT_CHECK
Definition: udf_common.h:470
#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
#define Vcb
Definition: cdprocs.h:1425
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
* PFILE_OBJECT
Definition: iotypes.h:1955
#define UDF_IRP_CONTEXT_FORCED_POST
Definition: struct.h:397
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NtReqFcb
#define CollectStatisticsEx(VCB, Field, a)
Definition: env_spec.h:124
#define OVERFLOW_READ_THRESHHOLD
Definition: read.cpp:29
PVOID UDFGetCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:871
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_FCB_DELETED
Definition: struct.h:314
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
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDFIsFileCached__(Vcb, FileInfo, Offset, Length, ForWrite)
Definition: udf_info.h:839
#define IRP_MN_MDL
Definition: iotypes.h:4063
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
OSSTATUS WCacheEODirect__(IN PW_CACHE Cache, IN PVOID Context)
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
NTSTATUS UDFUnlockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVOID SystemBuffer)
Definition: read.cpp:1034
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDF_FCB_PAGE_FILE
Definition: struct.h:302
OSSTATUS UDFTRead(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
Definition: phys_lib.cpp:596
#define IRP_MN_DPC
Definition: iotypes.h:4062
#define FSRTL_FAST_IO_TOP_LEVEL_IRP
Definition: fsrtltypes.h:62
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
__inline OSSTATUS UDFReadFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT int8 *Buffer, OUT PSIZE_T ReadBytes)
Definition: udf_info.h:666
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG_PTR SIZE_T
Definition: typedefs.h:78
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_SEH2_END
Definition: create.c:4424
NTSTATUS UDFPostStackOverflowRead(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PtrUDFFCB Fcb)
Definition: read.cpp:118
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262
_SEH2_FINALLY
Definition: create.c:4395
#define IRP_PAGING_IO
#define CollectStatistics(VCB, Field)
Definition: env_spec.h:120
ULONG UDFFlushLogicalVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PVCB Vcb, IN ULONG FlushFlags)
Definition: flush.cpp:506
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:306
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
#define UDF_IRP_CONTEXT_RES1_ACQ
Definition: struct.h:395
unsigned int ULONG
Definition: retypes.h:1
PVCB Vcb
Definition: cdstruc.h:939
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
NTSTATUS UDFLockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, BOOLEAN IsReadOperation, uint32 Length)
Definition: read.cpp:936
#define UDF_IRP_CONTEXT_RES2_ACQ
Definition: struct.h:396
#define UDF_IRP_CONTEXT_FLUSH_REQUIRED
Definition: struct.h:392
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
#define UDF_CCB_ACCESSED
Definition: struct.h:149
#define FO_WRITE_THROUGH
Definition: iotypes.h:1736
ULONG UDFIsResourceAcquired(IN PERESOURCE Resource)
Definition: misc.cpp:2518
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36

Referenced by UDFCommonDispatch(), UDFRead(), and UDFStackOverflowRead().

◆ UDFGetCallersBuffer()

PVOID UDFGetCallersBuffer ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 871 of file read.cpp.

875 {
876  VOID *ReturnedBuffer = NULL;
877 
878  UDFPrint(("UDFGetCallersBuffer: \n"));
879 
880  // If an MDL is supplied, use it.
881  if(Irp->MdlAddress) {
882  MmPrint((" UDFGetCallersBuffer: MmGetSystemAddressForMdl(Irp->MdlAddress) MDL=%x\n", Irp->MdlAddress));
883 // ReturnedBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
884  ReturnedBuffer = MmGetSystemAddressForMdlSafer(Irp->MdlAddress);
885  } else
886  if (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_BUFFER_LOCKED) {
887  // Free buffer
888 #ifndef POST_LOCK_PAGES
889  MmPrint((" UDFGetCallersBuffer: MmGetSystemAddressForMdl(PtrIrpContext->PtrMdl) MDL=%x\n", PtrIrpContext->PtrMdl));
890  ReturnedBuffer = MmGetSystemAddressForMdlSafe(PtrIrpContext->PtrMdl, NormalPagePriority);
891 #else //POST_LOCK_PAGES
892  if(PtrIrpContext->TransitionBuffer) {
893  MmPrint((" UDFGetCallersBuffer: TransitionBuffer\n"));
894  return PtrIrpContext->TransitionBuffer;
895  }
896 
897  _SEH2_TRY {
898  MmPrint((" MmProbeAndLockPages()\n"));
899  MmProbeAndLockPages(PtrIrpContext->PtrMdl, Irp->RequestorMode,
900  ((PtrIrpContext->MajorFunction == IRP_MJ_READ) ? IoWriteAccess:IoReadAccess));
901 #ifdef UDF_DBG
902  LockBufferCounter++;
903 #endif //UDF_DBG
905  //RC = STATUS_INVALID_USER_BUFFER;
906  BrutePoint();
907  return NULL;
908  } _SEH2_END;
909 
910  MmPrint((" MmGetSystemAddressForMdlSafer()\n"));
911  ReturnedBuffer = MmGetSystemAddressForMdlSafer(PtrIrpContext->PtrMdl);
912 #endif //POST_LOCK_PAGES
913  } else {
914  MmPrint((" UDFGetCallersBuffer: Irp->UserBuffer\n"));
915  ReturnedBuffer = Irp->UserBuffer;
916  }
917 
918  return(ReturnedBuffer);
919 } // end UDFGetCallersBuffer()
#define UDFPrint(Args)
Definition: udffs.h:225
_In_ PIRP Irp
Definition: csq.h:116
#define UDF_IRP_CONTEXT_BUFFER_LOCKED
Definition: struct.h:398
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
PCHAR TransitionBuffer
Definition: struct.h:381
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
__inline PVOID MmGetSystemAddressForMdlSafer(IN PMDL Mdl)
Definition: ntifs_ex.h:101
uint32 IrpContextFlags
Definition: struct.h:364
#define BrutePoint()
Definition: env_spec_w32.h:504
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
_SEH2_END
Definition: create.c:4424
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
uint8 MajorFunction
Definition: struct.h:366
PMDL PtrMdl
Definition: struct.h:380

Referenced by UDFCommonRead(), UDFCommonWrite(), and UDFGetVolumeBitmap().

◆ UDFLockCallersBuffer()

NTSTATUS UDFLockCallersBuffer ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
BOOLEAN  IsReadOperation,
uint32  Length 
)

Definition at line 936 of file read.cpp.

942 {
944  PMDL PtrMdl = NULL;
945 
946  UDFPrint(("UDFLockCallersBuffer: \n"));
947 
948  ASSERT(Irp);
949 
950  _SEH2_TRY {
951  // Is a MDL already present in the IRP
952  if (!(Irp->MdlAddress)) {
953  // Allocate a MDL
954 /*
955  if(!IsReadOperation) {
956  MmPrint((" Allocate TransitionBuffer\n"));
957  PtrIrpContext->TransitionBuffer = (PCHAR)DbgAllocatePool(NonPagedPool, Length);
958  if(!PtrIrpContext->TransitionBuffer) {
959  RC = STATUS_INSUFFICIENT_RESOURCES;
960  try_return(RC);
961  }
962  _SEH2_TRY {
963  RtlCopyMemory(PtrIrpContext->TransitionBuffer, Irp->UserBuffer, Length);
964  } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
965  RC = STATUS_INVALID_USER_BUFFER;
966  } _SEH2_END;
967  } else*/ {
968 
969  MmPrint((" IoAllocateMdl()\n"));
970 // if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, NULL))) {
971 
972  // This will place allocated Mdl to Irp
973  if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp))) {
975  try_return(RC);
976  }
977  MmPrint((" Alloc MDL=%x\n", PtrMdl));
978 #ifdef UDF_DBG
979  BuildMdlCounter++;
980 #endif //UDF_DBG
981  }
982  // Probe and lock the pages described by the MDL
983  // We could encounter an exception doing so, swallow the exception
984  // NOTE: The exception could be due to an unexpected (from our
985  // perspective), invalidation of the virtual addresses that comprise
986  // the passed in buffer
987 #ifndef POST_LOCK_PAGES
988  _SEH2_TRY {
989  MmPrint((" MmProbeAndLockPages()\n"));
990  MmProbeAndLockPages(PtrMdl, Irp->RequestorMode, (IsReadOperation ? IoWriteAccess:IoReadAccess));
992  MmPrint((" MmProbeAndLockPages() failed\n"));
993  Irp->MdlAddress = NULL;
995  } _SEH2_END;
996 #endif //POST_LOCK_PAGES
997 
998  if(NT_SUCCESS(RC)) {
1000  PtrIrpContext->PtrMdl = PtrMdl;
1001  }
1002  } else {
1003  MmPrint((" UDFLockCallersBuffer: do nothing, MDL=%x\n", Irp->MdlAddress));
1004  UDFTouch(Irp->MdlAddress);
1005  }
1006 
1007 try_exit: NOTHING;
1008 
1009  } _SEH2_FINALLY {
1010  if (!NT_SUCCESS(RC) && PtrMdl) {
1011  MmPrint((" Free MDL=%x\n", PtrMdl));
1012  IoFreeMdl(PtrMdl);
1013  }
1014  } _SEH2_END;
1015 
1016  return(RC);
1017 } // end UDFLockCallersBuffer()
#define UDFPrint(Args)
Definition: udffs.h:225
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define UDF_IRP_CONTEXT_BUFFER_LOCKED
Definition: struct.h:398
_SEH2_TRY
Definition: create.c:4250
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
uint32 IrpContextFlags
Definition: struct.h:364
#define UDFTouch(a)
Definition: env_spec_w32.h:303
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define try_return(S)
Definition: cdprocs.h:2189
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NOTHING
Definition: env_spec_w32.h:461
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
_SEH2_END
Definition: create.c:4424
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
_SEH2_FINALLY
Definition: create.c:4395
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:2938
PMDL PtrMdl
Definition: struct.h:380

Referenced by UDFCommonRead(), UDFCommonWrite(), and UDFQueryDirectory().

◆ UDFMdlComplete()

VOID UDFMdlComplete ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp,
BOOLEAN  ReadCompletion 
)

Definition at line 1117 of file read.cpp.

1122 {
1123  NTSTATUS RC = STATUS_SUCCESS;
1125 
1126  UDFPrint(("UDFMdlComplete: \n"));
1127 
1129  ASSERT(FileObject);
1130 
1131  UDFTouch(Irp->MdlAddress);
1132  // Not much to do here.
1133  if (ReadCompletion) {
1134  MmPrint((" CcMdlReadComplete() MDL=%x\n", Irp->MdlAddress));
1135  CcMdlReadComplete(FileObject, Irp->MdlAddress);
1136  } else {
1137  // The Cache Manager needs the byte offset in the I/O stack location.
1138  MmPrint((" CcMdlWriteComplete() MDL=%x\n", Irp->MdlAddress));
1139  CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);
1140  }
1141 
1142  // Clear the MDL address field in the IRP so the IoCompleteRequest()
1143  // does not __try to play around with the MDL.
1144  Irp->MdlAddress = NULL;
1145 
1146  // Free up the Irp Context.
1147  UDFReleaseIrpContext(PtrIrpContext);
1148 
1149  // Complete the IRP.
1150  Irp->IoStatus.Status = RC;
1151  Irp->IoStatus.Information = 0;
1153 
1154  return;
1155 }
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define UDFPrint(Args)
Definition: udffs.h:225
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define UDFTouch(a)
Definition: env_spec_w32.h:303
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
* PFILE_OBJECT
Definition: iotypes.h:1955
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define IO_NO_INCREMENT
Definition: iotypes.h:566
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by UDFCommonRead(), and UDFCommonWrite().

◆ UDFPostStackOverflowRead()

NTSTATUS UDFPostStackOverflowRead ( IN PtrUDFIrpContext  PtrIrpContext,
IN PIRP  Irp,
IN PtrUDFFCB  Fcb 
)

Definition at line 118 of file read.cpp.

123 {
124  PKEVENT Event;
126 
127  UDFPrint(("Getting too close to stack limit pass request to Fsp\n"));
128 
129  // Allocate an event and get shared on the resource we will
130  // be later using the common read.
132  if(!Event)
135 
136  if ((Irp->Flags & IRP_PAGING_IO) && (Fcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource)) {
137  Resource = Fcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource;
138  } else {
139  Resource = Fcb->NTRequiredFCB->CommonFCBHeader.Resource;
140  }
141 
143 
144  _SEH2_TRY {
145  // If this read is the result of a verify, we have to
146  // tell the overflow read routne to temporarily
147  // hijack the Vcb->VerifyThread field so that reads
148  // can go through.
150  // And wait for the worker thread to complete the item
152 
153  } _SEH2_FINALLY {
154 
156  MyFreePool__( Event );
157  } _SEH2_END;
158 
159  return STATUS_PENDING;
160 
161 } // end UDFPostStackOverflowRead()
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
struct _KEVENT * PKEVENT
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI UDFStackOverflowRead(IN PVOID Context, IN PKEVENT Event)
Definition: read.cpp:185
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
_SEH2_TRY
Definition: create.c:4250
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
smooth NULL
Definition: ftsmooth.c:416
#define DbgWaitForSingleObject(o, to)
Definition: env_spec_w32.h:479
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define STATUS_PENDING
Definition: ntstatus.h:82
#define MyFreePool__(addr)
Definition: mem_tools.h:152
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:232
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_SEH2_FINALLY
Definition: create.c:4395
#define IRP_PAGING_IO
ERESOURCE PagingIoResource
Definition: ntfs.h:523
_In_ PFCB Fcb
Definition: cdprocs.h:151

Referenced by UDFCommonRead().

◆ UDFRead()

NTSTATUS NTAPI UDFRead ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 53 of file read.cpp.

56 {
58  PtrUDFIrpContext PtrIrpContext = NULL;
59  BOOLEAN AreWeTopLevel = FALSE;
60 
61  TmPrint(("UDFRead: \n"));
62 
65  ASSERT(Irp);
66 
67  // set the top level context
68  AreWeTopLevel = UDFIsIrpTopLevel(Irp);
69  ASSERT(!UDFIsFSDevObj(DeviceObject));
70 
71  _SEH2_TRY {
72 
73  // get an IRP context structure and issue the request
74  PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
75  if(PtrIrpContext) {
76  RC = UDFCommonRead(PtrIrpContext, Irp);
77  } else {
79  Irp->IoStatus.Status = RC;
80  Irp->IoStatus.Information = 0;
81  // complete the IRP
83  }
84 
86 
87  RC = UDFExceptionHandler(PtrIrpContext, Irp);
88 
90  } _SEH2_END;
91 
92  if (AreWeTopLevel) {
94  }
95 
97 
98  return(RC);
99 } // end UDFRead()
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
_SEH2_TRY
Definition: create.c:4250
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
_SEH2_END
Definition: create.c:4424
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSTATUS UDFCommonRead(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:229

Referenced by UDFInitializeFunctionPointers().

◆ UDFStackOverflowRead()

VOID NTAPI UDFStackOverflowRead ( IN PVOID  Context,
IN PKEVENT  Event 
)

Definition at line 185 of file read.cpp.

189 {
190  PtrUDFIrpContext PtrIrpContext = (PtrUDFIrpContext)Context;
191  NTSTATUS RC;
192 
193  UDFPrint(("UDFStackOverflowRead: \n"));
194  // Make it now look like we can wait for I/O to complete
195  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_CAN_BLOCK;
196 
197  // Do the read operation protected by a try-except clause
198  _SEH2_TRY {
199  UDFCommonRead(PtrIrpContext, PtrIrpContext->Irp);
201  RC = UDFExceptionHandler(PtrIrpContext, PtrIrpContext->Irp);
203  } _SEH2_END;
204 
205  // Set the stack overflow item's event to tell the original
206  // thread that we're done.
207  KeSetEvent( Event, 0, FALSE );
208 } // end UDFStackOverflowRead()
#define UDFPrint(Args)
Definition: udffs.h:225
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
LONG NTSTATUS
Definition: precomp.h:26
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
_SEH2_TRY
Definition: create.c:4250
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
uint32 IrpContextFlags
Definition: struct.h:364
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
struct _UDFIrpContext * PtrUDFIrpContext
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
_SEH2_END
Definition: create.c:4424
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
NTSTATUS UDFCommonRead(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:229

Referenced by UDFPostStackOverflowRead().

◆ UDFUnlockCallersBuffer()

NTSTATUS UDFUnlockCallersBuffer ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PVOID  SystemBuffer 
)

Definition at line 1034 of file read.cpp.

1039 {
1040  NTSTATUS RC = STATUS_SUCCESS;
1041 
1042  UDFPrint(("UDFUnlockCallersBuffer: \n"));
1043 
1044  ASSERT(Irp);
1045 
1046  _SEH2_TRY {
1047  // Is a nonPaged buffer already present in the IRP
1048  if (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_BUFFER_LOCKED) {
1049 
1050  UDFPrint((" UDF_IRP_CONTEXT_BUFFER_LOCKED MDL=%x, Irp MDL=%x\n", PtrIrpContext->PtrMdl, Irp->MdlAddress));
1051  if(PtrIrpContext->TransitionBuffer) {
1052  MmPrint((" UDFUnlockCallersBuffer: free TransitionBuffer\n"));
1053  DbgFreePool(PtrIrpContext->TransitionBuffer);
1054  PtrIrpContext->TransitionBuffer = NULL;
1056  try_return(RC);
1057  }
1058  // Free buffer
1059  KeFlushIoBuffers( PtrIrpContext->PtrMdl, TRUE, FALSE );
1060 // MmPrint((" IrpCtx->Mdl, MmUnmapLockedPages()\n"));
1061 // MmUnmapLockedPages(SystemBuffer, PtrIrpContext->PtrMdl);
1062 
1063  // This will be done in IoCompleteIrp !!!
1064 
1065  //MmPrint((" MmUnlockPages()\n"));
1066  //MmUnlockPages(PtrIrpContext->PtrMdl);
1067 
1068 #ifdef UDF_DBG
1069  LockBufferCounter--;
1070 #endif //UDF_DBG
1071 
1072  // This will be done in IoCompleteIrp !!!
1073 
1074  //IoFreeMdl(PtrIrpContext->PtrMdl);
1075 
1076 #ifdef UDF_DBG
1077  BuildMdlCounter--;
1078 #endif //UDF_DBG
1079  UDFTouch(PtrIrpContext->PtrMdl);
1080  PtrIrpContext->PtrMdl = NULL;
1082  } else
1083  if(Irp->MdlAddress) {
1084 // MmPrint((" Irp->Mdl, MmUnmapLockedPages()\n"));
1085 // MmUnmapLockedPages(SystemBuffer, Irp->MdlAddress);
1086  UDFPrint((" UDF_IRP_CONTEXT_BUFFER_LOCKED MDL=%x, Irp MDL=%x\n", PtrIrpContext->PtrMdl, Irp->MdlAddress));
1087  UDFTouch(Irp->MdlAddress);
1088  KeFlushIoBuffers( Irp->MdlAddress,
1089  ((IoGetCurrentIrpStackLocation(Irp))->MajorFunction) == IRP_MJ_READ,
1090  FALSE );
1091  } else
1092  { ; }
1093 
1094 try_exit: NOTHING;
1095 
1096  } _SEH2_FINALLY {
1097  NOTHING;
1098  } _SEH2_END;
1099 
1100  return(RC);
1101 } // end UDFUnlockCallersBuffer()
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define UDF_IRP_CONTEXT_BUFFER_LOCKED
Definition: struct.h:398
PCHAR TransitionBuffer
Definition: struct.h:381
_SEH2_TRY
Definition: create.c:4250
smooth NULL
Definition: ftsmooth.c:416
uint32 IrpContextFlags
Definition: struct.h:364
#define DbgFreePool
Definition: env_spec_w32.h:334
#define UDFTouch(a)
Definition: env_spec_w32.h:303
#define try_return(S)
Definition: cdprocs.h:2189
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NOTHING
Definition: env_spec_w32.h:461
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_SEH2_END
Definition: create.c:4424
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:161
_SEH2_FINALLY
Definition: create.c:4395
#define IRP_MJ_READ
Definition: rdpdr.c:46
return STATUS_SUCCESS
Definition: btrfs.c:2938
PMDL PtrMdl
Definition: struct.h:380

Referenced by UDFCommonRead(), UDFCommonWrite(), and UDFGetVolumeBitmap().