ReactOS  0.4.14-dev-583-g2a1ba2c
read.cpp
Go to the documentation of this file.
1 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
6 /*************************************************************************
7 *
8 * File: Read.cpp
9 *
10 * Module: UDF File System Driver (Kernel mode execution only)
11 *
12 * Description:
13 * Contains code to handle the "Read" dispatch entry point.
14 *
15 *************************************************************************/
16 
17 #include "udffs.h"
18 
19 // define the file specific bug-check id
20 #define UDF_BUG_CHECK_ID UDF_FILE_READ
21 
22 #ifdef _M_IX86
23 #if DBG
24 #define OVERFLOW_READ_THRESHHOLD (0xE00)
25 #else
26 #define OVERFLOW_READ_THRESHHOLD (0xA00)
27 #endif // UDF_DBG
28 #else // defined(_M_IX86)
29 #define OVERFLOW_READ_THRESHHOLD (0x1000)
30 #endif // defined(_M_IX86)
31 
32 //#define POST_LOCK_PAGES
33 
34 
35 /*************************************************************************
36 *
37 * Function: UDFRead()
38 *
39 * Description:
40 * The I/O Manager will invoke this routine to handle a read
41 * request
42 *
43 * Expected Interrupt Level (for execution) :
44 *
45 * IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
46 * to be deferred to a worker thread context)
47 *
48 * Return Value: STATUS_SUCCESS/Error
49 *
50 *************************************************************************/
52 NTAPI
54  PDEVICE_OBJECT DeviceObject, // the logical volume device object
55  PIRP Irp) // I/O Request Packet
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()
100 
101 
102 /*************************************************************************
103 *
104 * Function: UDFPostStackOverflowRead()
105 *
106 * Description:
107 * Post a read request that could not be processed by
108 * the fsp thread because of stack overflow potential.
109 *
110 * Arguments:
111 * Irp - Supplies the request to process.
112 * Fcb - Supplies the file.
113 *
114 * Return Value: STATUS_PENDING.
115 *
116 *************************************************************************/
117 NTSTATUS
119  IN PtrUDFIrpContext PtrIrpContext,
120  IN PIRP Irp,
122  )
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()
162 
163 /*************************************************************************
164 *
165 * Function: UDFStackOverflowRead()
166 *
167 * Description:
168 * Process a read request that could not be processed by
169 * the fsp thread because of stack overflow potential.
170 *
171 * Arguments:
172 * Context - Supplies the IrpContext being processed
173 * Event - Supplies the event to be signaled when we are done processing this
174 * request.
175 *
176 * Expected Interrupt Level (for execution) :
177 *
178 * IRQL_PASSIVE_LEVEL
179 *
180 * Return Value: None.
181 *
182 *************************************************************************/
183 VOID
184 NTAPI
186  IN PVOID Context,
188  )
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()
209 
210 
211 /*************************************************************************
212 *
213 * Function: UDFCommonRead()
214 *
215 * Description:
216 * The actual work is performed here. This routine may be invoked in one
217 * of the two possible contexts:
218 * (a) in the context of a system worker thread
219 * (b) in the context of the original caller
220 *
221 * Expected Interrupt Level (for execution) :
222 *
223 * IRQL_PASSIVE_LEVEL
224 *
225 * Return Value: STATUS_SUCCESS/Error
226 *
227 *************************************************************************/
228 NTSTATUS
230  PtrUDFIrpContext PtrIrpContext,
231  PIRP Irp
232  )
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()
849 
850 
851 #ifdef UDF_DBG
852 ULONG LockBufferCounter = 0;
853 ULONG BuildMdlCounter = 0;
854 #endif //UDF_DBG
855 
856 /*************************************************************************
857 *
858 * Function: UDFGetCallersBuffer()
859 *
860 * Description:
861 * Obtain a pointer to the caller's buffer.
862 *
863 * Expected Interrupt Level (for execution) :
864 *
865 * IRQL_PASSIVE_LEVEL
866 *
867 * Return Value: STATUS_SUCCESS/Error
868 *
869 *************************************************************************/
870 PVOID
872  PtrUDFIrpContext PtrIrpContext,
873  PIRP Irp
874  )
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()
920 
921 /*************************************************************************
922 *
923 * Function: UDFLockCallersBuffer()
924 *
925 * Description:
926 * Obtain a MDL that describes the buffer. Lock pages for I/O
927 *
928 * Expected Interrupt Level (for execution) :
929 *
930 * IRQL_PASSIVE_LEVEL
931 *
932 * Return Value: STATUS_SUCCESS/Error
933 *
934 *************************************************************************/
935 NTSTATUS
937  PtrUDFIrpContext PtrIrpContext,
938  PIRP Irp,
939  BOOLEAN IsReadOperation,
940  uint32 Length
941  )
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()
1018 
1019 /*************************************************************************
1020 *
1021 * Function: UDFUnlockCallersBuffer()
1022 *
1023 * Description:
1024 * Obtain a MDL that describes the buffer. Lock pages for I/O
1025 *
1026 * Expected Interrupt Level (for execution) :
1027 *
1028 * IRQL_PASSIVE_LEVEL
1029 *
1030 * Return Value: STATUS_SUCCESS/Error
1031 *
1032 *************************************************************************/
1033 NTSTATUS
1035  PtrUDFIrpContext PtrIrpContext,
1036  PIRP Irp,
1037  PVOID SystemBuffer
1038  )
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()
1102 
1103 /*************************************************************************
1104 *
1105 * Function: UDFMdlComplete()
1106 *
1107 * Description:
1108 * Tell Cache Manager to release MDL (and possibly flush).
1109 *
1110 * Expected Interrupt Level (for execution) :
1111 *
1112 * IRQL_PASSIVE_LEVEL
1113 *
1114 * Return Value: None.
1115 *
1116 *************************************************************************/
1118 PtrUDFIrpContext PtrIrpContext,
1119 PIRP Irp,
1121 BOOLEAN ReadCompletion)
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 }
#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
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
#define IN
Definition: typedefs.h:38
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
struct _KEVENT * PKEVENT
struct _UDFContextControlBlock * PtrUDFCCB
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
#define FsRtlEnterFileSystem
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
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
#define FsRtlExitFileSystem
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI UDFStackOverflowRead(IN PVOID Context, IN PKEVENT Event)
Definition: read.cpp:185
#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
unsigned int uint32
Definition: types.h:32
#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
NTSTATUS NTAPI UDFRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: read.cpp:53
#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_BUFFER_LOCKED
Definition: struct.h:398
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
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
VOID UDFMdlComplete(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN ReadCompletion)
Definition: read.cpp:1117
PCHAR TransitionBuffer
Definition: struct.h:381
_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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1752
#define FILE_ACTION_MODIFIED
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define FILE_ACTION_MODIFIED_STREAM
#define UDFAcquireSharedWaitForExclusive(Resource, CanWait)
Definition: env_spec_w32.h:671
unsigned char BOOLEAN
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
#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
__inline PVOID MmGetSystemAddressForMdlSafer(IN PMDL Mdl)
Definition: ntifs_ex.h:101
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 DbgWaitForSingleObject(o, to)
Definition: env_spec_w32.h:479
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
#define DbgFreePool
Definition: env_spec_w32.h:334
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#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 MyFreePool__(addr)
Definition: mem_tools.h:152
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define BrutePoint()
Definition: env_spec_w32.h:504
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:232
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
* PFILE_OBJECT
Definition: iotypes.h:1955
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
#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
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
struct _UDFIrpContext * PtrUDFIrpContext
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
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
struct _FCB::@708::@711 Fcb
#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
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
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
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
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
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:161
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
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 IRP_MJ_READ
Definition: rdpdr.c:46
#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
#define IO_NO_INCREMENT
Definition: iotypes.h:566
ERESOURCE PagingIoResource
Definition: ntfs.h:523
PVCB Vcb
Definition: cdstruc.h:939
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
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
uint8 MajorFunction
Definition: struct.h:366
NTSTATUS UDFLockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, BOOLEAN IsReadOperation, uint32 Length)
Definition: read.cpp:936
PMDL PtrMdl
Definition: struct.h:380
#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
NTSTATUS UDFCommonRead(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:229
ULONG UDFIsResourceAcquired(IN PERESOURCE Resource)
Definition: misc.cpp:2518
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36