ReactOS  0.4.15-dev-509-g96a357b
read.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  Read.c
8 
9 Abstract:
10 
11  This module implements the File Read routine for Read called by the
12  dispatch driver.
13 
14 
15 --*/
16 
17 #include "fatprocs.h"
18 
19 //
20 // The Bug check file id for this module
21 //
22 
23 #define BugCheckFileId (FAT_BUG_CHECK_READ)
24 
25 //
26 // The local debug trace level
27 //
28 
29 #define Dbg (DEBUG_TRACE_READ)
30 
31 //
32 // Define stack overflow read threshhold. For the x86 we'll use a smaller
33 // threshold than for a risc platform.
34 //
35 // Empirically, the limit is a result of the (large) amount of stack
36 // neccesary to throw an exception.
37 //
38 
39 #if defined(_M_IX86)
40 #define OVERFLOW_READ_THRESHHOLD (0xE00)
41 #else
42 #define OVERFLOW_READ_THRESHHOLD (0x1000)
43 #endif // defined(_M_IX86)
44 
45 
46 //
47 // The following procedures handles read stack overflow operations.
48 //
49 
50 _Requires_lock_held_(_Global_critical_region_)
51 VOID
52 NTAPI
53 FatStackOverflowRead (
56  );
57 
58 _Requires_lock_held_(_Global_critical_region_)
60 FatPostStackOverflowRead (
61  IN PIRP_CONTEXT IrpContext,
62  IN PIRP Irp,
63  IN PFCB Fcb
64  );
65 
66 VOID
67 NTAPI
71  );
72 
73 //
74 // VOID
75 // SafeZeroMemory (
76 // IN PUCHAR At,
77 // IN ULONG ByteCount
78 // );
79 //
80 
81 //
82 // This macro just puts a nice little try-except around RtlZeroMemory
83 //
84 
85 #define SafeZeroMemory(AT,BYTE_COUNT) { \
86  _SEH2_TRY { \
87  RtlZeroMemory((AT), (BYTE_COUNT)); \
88  } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \
89  FatRaiseStatus( IrpContext, STATUS_INVALID_USER_BUFFER ); \
90  } _SEH2_END \
91 }
92 
93 //
94 // Macro to increment appropriate performance counters.
95 //
96 
97 #define CollectReadStats(VCB,OPEN_TYPE,BYTE_COUNT) { \
98  PFILESYSTEM_STATISTICS Stats = &(VCB)->Statistics[KeGetCurrentProcessorNumber() % FatData.NumberProcessors].Common; \
99  if (((OPEN_TYPE) == UserFileOpen)) { \
100  Stats->UserFileReads += 1; \
101  Stats->UserFileReadBytes += (ULONG)(BYTE_COUNT); \
102  } else if (((OPEN_TYPE) == VirtualVolumeFile || ((OPEN_TYPE) == DirectoryFile))) { \
103  Stats->MetaDataReads += 1; \
104  Stats->MetaDataReadBytes += (ULONG)(BYTE_COUNT); \
105  } \
106 }
107 
108 
109 #ifdef ALLOC_PRAGMA
110 #pragma alloc_text(PAGE, FatStackOverflowRead)
111 #pragma alloc_text(PAGE, FatPostStackOverflowRead)
112 #pragma alloc_text(PAGE, FatCommonRead)
113 #endif
114 
115 
118 NTSTATUS
119 NTAPI
120 FatFsdRead (
121  _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
123  )
124 
125 /*++
126 
127 Routine Description:
128 
129  This is the driver entry to the common read routine for NtReadFile calls.
130  For synchronous requests, the CommonRead is called with Wait == TRUE,
131  which means the request will always be completed in the current thread,
132  and never passed to the Fsp. If it is not a synchronous request,
133  CommonRead is called with Wait == FALSE, which means the request
134  will be passed to the Fsp only if there is a need to block.
135 
136 Arguments:
137 
138  VolumeDeviceObject - Supplies the volume device object where the
139  file being Read exists
140 
141  Irp - Supplies the Irp being processed
142 
143 Return Value:
144 
145  NTSTATUS - The FSD status for the IRP
146 
147 --*/
148 
149 {
150  PFCB Fcb = NULL;
152  PIRP_CONTEXT IrpContext = NULL;
153 
155 
156  DebugTrace(+1, Dbg, "FatFsdRead\n", 0);
157 
158  //
159  // Call the common Read routine, with blocking allowed if synchronous
160  //
161 
163 
164  //
165  // We are first going to do a quick check for paging file IO. Since this
166  // is a fast path, we must replicate the check for the fsdo.
167  //
168 
170 
172 
173  if ((NodeType(Fcb) == FAT_NTC_FCB) &&
175 
176  //
177  // Do the usual STATUS_PENDING things.
178  //
179 
181 
182  //
183  // If there is not enough stack to do this read, then post this
184  // read to the overflow queue.
185  //
186 
187  if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {
188 
189  KEVENT Event;
191 
192  Packet.Irp = Irp;
193  Packet.Fcb = Fcb;
194 
196 
198 
199  //
200  // And wait for the worker thread to complete the item
201  //
202 
204 
205  } else {
206 
207  //
208  // Perform the actual IO, it will be completed when the io finishes.
209  //
210 
211  FatPagingFileIo( Irp, Fcb );
212  }
213 
215 
216  return STATUS_PENDING;
217  }
218  }
219 
220  _SEH2_TRY {
221 
223 
224  IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
225 
226  //
227  // If this is an Mdl complete request, don't go through
228  // common read.
229  //
230 
231  if ( FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE) ) {
232 
233  DebugTrace(0, Dbg, "Calling FatCompleteMdl\n", 0 );
234  try_return( Status = FatCompleteMdl( IrpContext, Irp ));
235  }
236 
237  //
238  // Check if we have enough stack space to process this request. If there
239  // isn't enough then we will pass the request off to the stack overflow thread.
240  //
241 
242  if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {
243 
244  DebugTrace(0, Dbg, "Passing StackOverflowRead off\n", 0 );
245  try_return( Status = FatPostStackOverflowRead( IrpContext, Irp, Fcb ) );
246  }
247 
248  Status = FatCommonRead( IrpContext, Irp );
249 
250  try_exit: NOTHING;
252 
253  //
254  // We had some trouble trying to perform the requested
255  // operation, so we'll abort the I/O request with
256  // the error status that we get back from the
257  // execption code
258  //
259 
260  Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
261  } _SEH2_END;
262 
263  if (TopLevel) { IoSetTopLevelIrp( NULL ); }
264 
266 
267  //
268  // And return to our caller
269  //
270 
271  DebugTrace(-1, Dbg, "FatFsdRead -> %08lx\n", Status);
272 
273  UNREFERENCED_PARAMETER( VolumeDeviceObject );
274 
275  return Status;
276 }
277 
278 
279 //
280 // Internal support routine
281 //
282 
283 _Requires_lock_held_(_Global_critical_region_)
284 NTSTATUS
285 FatPostStackOverflowRead (
286  IN PIRP_CONTEXT IrpContext,
287  IN PIRP Irp,
288  IN PFCB Fcb
289  )
290 
291 /*++
292 
293 Routine Description:
294 
295  This routine posts a read request that could not be processed by
296  the fsp thread because of stack overflow potential.
297 
298 Arguments:
299 
300  Irp - Supplies the request to process.
301 
302  Fcb - Supplies the file.
303 
304 Return Value:
305 
306  STATUS_PENDING.
307 
308 --*/
309 
310 {
311  KEVENT Event;
313  PVCB Vcb;
314 
315  PAGED_CODE();
316 
317  DebugTrace(0, Dbg, "Getting too close to stack limit pass request to Fsp\n", 0 );
318 
319  //
320  // Initialize an event and get shared on the resource we will
321  // be later using the common read.
322  //
323 
325 
326  //
327  // Preacquire the resource the read path will require so we know the
328  // worker thread can proceed without waiting.
329  //
330 
331  if (FlagOn(Irp->Flags, IRP_PAGING_IO) && (Fcb->Header.PagingIoResource != NULL)) {
332 
333  Resource = Fcb->Header.PagingIoResource;
334 
335  } else {
336 
337  Resource = Fcb->Header.Resource;
338  }
339 
340  //
341  // If there are no resources assodicated with the file (case: the virtual
342  // volume file), it is OK. No resources will be acquired on the other side
343  // as well.
344  //
345 
346  if (Resource) {
347 
349  }
350 
351  if (NodeType( Fcb ) == FAT_NTC_VCB) {
352 
353  Vcb = (PVCB) Fcb;
354 
355  } else {
356 
357  Vcb = Fcb->Vcb;
358  }
359 
360  _SEH2_TRY {
361 
362  //
363  // Make the Irp just like a regular post request and
364  // then send the Irp to the special overflow thread.
365  // After the post we will wait for the stack overflow
366  // read routine to set the event that indicates we can
367  // now release the scb resource and return.
368  //
369 
370  FatPrePostIrp( IrpContext, Irp );
371 
372  //
373  // If this read is the result of a verify, we have to
374  // tell the overflow read routne to temporarily
375  // hijack the Vcb->VerifyThread field so that reads
376  // can go through.
377  //
378 
379  if (Vcb->VerifyThread == KeGetCurrentThread()) {
380 
381  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_VERIFY_READ);
382  }
383 
384  FsRtlPostStackOverflow( IrpContext, &Event, FatStackOverflowRead );
385 
386  //
387  // And wait for the worker thread to complete the item
388  //
389 
391 
392  } _SEH2_FINALLY {
393 
394  if (Resource) {
395 
397  }
398  } _SEH2_END;
399 
400  return STATUS_PENDING;
401 }
402 
403 
404 //
405 // Internal support routine
406 //
407 
408 _Requires_lock_held_(_Global_critical_region_)
409 VOID
410 NTAPI
411 FatStackOverflowRead (
412  IN PVOID Context,
414  )
415 
416 /*++
417 
418 Routine Description:
419 
420  This routine processes a read request that could not be processed by
421  the fsp thread because of stack overflow potential.
422 
423 Arguments:
424 
425  Context - Supplies the IrpContext being processed
426 
427  Event - Supplies the event to be signaled when we are done processing this
428  request.
429 
430 Return Value:
431 
432  None.
433 
434 --*/
435 
436 {
437  PIRP_CONTEXT IrpContext = Context;
438  PKTHREAD SavedVerifyThread = NULL;
439  PVCB Vcb = NULL;
440 
441  PAGED_CODE();
442 
443  //
444  // Make it now look like we can wait for I/O to complete
445  //
446 
447  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
448 
449  //
450  // If this read was as the result of a verify we have to fake out the
451  // the Vcb->VerifyThread field.
452  //
453 
454  if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_VERIFY_READ)) {
455 
456  PFCB Fcb = (PFCB)IoGetCurrentIrpStackLocation(IrpContext->OriginatingIrp)->
457  FileObject->FsContext;
458 
459  if (NodeType( Fcb ) == FAT_NTC_VCB) {
460 
461  Vcb = (PVCB) Fcb;
462 
463  } else {
464 
465  Vcb = Fcb->Vcb;
466  }
467 
468  NT_ASSERT( Vcb->VerifyThread != NULL );
469  SavedVerifyThread = Vcb->VerifyThread;
470  Vcb->VerifyThread = KeGetCurrentThread();
471  }
472 
473  //
474  // Do the read operation protected by a try-except clause
475  //
476 
477  _SEH2_TRY {
478 
479  (VOID) FatCommonRead( IrpContext, IrpContext->OriginatingIrp );
480 
482 
484 
485  //
486  // We had some trouble trying to perform the requested
487  // operation, so we'll abort the I/O request with
488  // the error status that we get back from the
489  // execption code
490  //
491 
493 
495 
496  IrpContext->ExceptionStatus = ExceptionCode = STATUS_END_OF_FILE;
497  IrpContext->OriginatingIrp->IoStatus.Information = 0;
498  }
499 
500  (VOID) FatProcessException( IrpContext, IrpContext->OriginatingIrp, ExceptionCode );
501  } _SEH2_END;
502 
503  //
504  // Restore the original VerifyVolumeThread
505  //
506 
507  if (SavedVerifyThread != NULL) {
508 
509  NT_ASSERT( Vcb->VerifyThread == KeGetCurrentThread() );
510  Vcb->VerifyThread = SavedVerifyThread;
511  }
512 
513  //
514  // Set the stack overflow item's event to tell the original
515  // thread that we're done.
516  //
517 
518  KeSetEvent( Event, 0, FALSE );
519 }
520 
521 
522 _Requires_lock_held_(_Global_critical_region_)
523 NTSTATUS
524 FatCommonRead (
525  IN PIRP_CONTEXT IrpContext,
526  IN PIRP Irp
527  )
528 
529 /*++
530 
531 Routine Description:
532 
533  This is the common read routine for NtReadFile, called from both
534  the Fsd, or from the Fsp if a request could not be completed without
535  blocking in the Fsd. This routine has no code where it determines
536  whether it is running in the Fsd or Fsp. Instead, its actions are
537  conditionalized by the Wait input parameter, which determines whether
538  it is allowed to block or not. If a blocking condition is encountered
539  with Wait == FALSE, however, the request is posted to the Fsp, who
540  always calls with WAIT == TRUE.
541 
542 Arguments:
543 
544  Irp - Supplies the Irp to process
545 
546 Return Value:
547 
548  NTSTATUS - The return status for the operation
549 
550 --*/
551 
552 {
553  PVCB Vcb;
554  PFCB FcbOrDcb;
555  PCCB Ccb;
556 
559  ULONG RequestedByteCount;
560 
564 
565  BOOLEAN PostIrp = FALSE;
566  BOOLEAN OplockPostIrp = FALSE;
567 
568  BOOLEAN FcbOrDcbAcquired = FALSE;
569 
570  BOOLEAN Wait;
571  BOOLEAN PagingIo;
572  BOOLEAN NonCachedIo;
573  BOOLEAN SynchronousIo;
574 
575 
577 
578  FAT_IO_CONTEXT StackFatIoContext;
579 
580  //
581  // A system buffer is only used if we have to access the
582  // buffer directly from the Fsp to clear a portion or to
583  // do a synchronous I/O, or a cached transfer. It is
584  // possible that our caller may have already mapped a
585  // system buffer, in which case we must remember this so
586  // we do not unmap it on the way out.
587  //
588 
589  PVOID SystemBuffer = NULL;
590 
591  LARGE_INTEGER StartingByte;
592 
593  PAGED_CODE();
594 
595  //
596  // Get current Irp stack location.
597  //
598 
601 
602  //
603  // Initialize the appropriate local variables.
604  //
605 
606  Wait = BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
607  PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
608  NonCachedIo = BooleanFlagOn(Irp->Flags,IRP_NOCACHE);
609  SynchronousIo = BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
610 
611  DebugTrace(+1, Dbg, "CommonRead\n", 0);
612  DebugTrace( 0, Dbg, " Irp = %p\n", Irp);
613  DebugTrace( 0, Dbg, " ->ByteCount = %8lx\n", IrpSp->Parameters.Read.Length);
614  DebugTrace( 0, Dbg, " ->ByteOffset.LowPart = %8lx\n", IrpSp->Parameters.Read.ByteOffset.LowPart);
615  DebugTrace( 0, Dbg, " ->ByteOffset.HighPart = %8lx\n", IrpSp->Parameters.Read.ByteOffset.HighPart);
616 
617  //
618  // Extract starting Vbo and offset.
619  //
620 
621  StartingByte = IrpSp->Parameters.Read.ByteOffset;
622 
623  StartingVbo = StartingByte.LowPart;
624 
625  ByteCount = IrpSp->Parameters.Read.Length;
626  RequestedByteCount = ByteCount;
627 
628  //
629  // Check for a null request, and return immediately
630  //
631 
632  if (ByteCount == 0) {
633 
634  Irp->IoStatus.Information = 0;
635  FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
636  return STATUS_SUCCESS;
637  }
638 
639  //
640  // Extract the nature of the read from the file object, and case on it
641  //
642 
644 
645  NT_ASSERT( Vcb != NULL );
646 
647  //
648  // Save callers who try to do cached IO to the raw volume from themselves.
649  //
650 
651  if (TypeOfOpen == UserVolumeOpen) {
652 
653  NonCachedIo = TRUE;
654  }
655 
656  NT_ASSERT(!(NonCachedIo == FALSE && TypeOfOpen == VirtualVolumeFile));
657 
658  //
659  // Collect interesting statistics. The FLAG_USER_IO bit will indicate
660  // what type of io we're doing in the FatNonCachedIo function.
661  //
662 
663  if (PagingIo) {
665 
666  if (TypeOfOpen == UserFileOpen) {
667  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_USER_IO);
668  } else {
669  ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_USER_IO);
670  }
671  }
672 
673  NT_ASSERT(!FlagOn( IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT ));
674 
675  //
676  // Allocate if necessary and initialize a FAT_IO_CONTEXT block for
677  // all non cached Io. For synchronous Io we use stack storage,
678  // otherwise we allocate pool.
679  //
680 
681  if (NonCachedIo) {
682 
683  if (IrpContext->FatIoContext == NULL) {
684 
685  if (!Wait) {
686 
687  IrpContext->FatIoContext =
688  FsRtlAllocatePoolWithTag( NonPagedPoolNx,
689  sizeof(FAT_IO_CONTEXT),
691 
692  } else {
693 
694  IrpContext->FatIoContext = &StackFatIoContext;
695 
696  SetFlag( IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT );
697  }
698  }
699 
700  RtlZeroMemory( IrpContext->FatIoContext, sizeof(FAT_IO_CONTEXT) );
701 
702  if (Wait) {
703 
704  KeInitializeEvent( &IrpContext->FatIoContext->Wait.SyncEvent,
706  FALSE );
707 
708  } else {
709 
710  if (PagingIo) {
711 
712  IrpContext->FatIoContext->Wait.Async.ResourceThreadId =
714 
715  } else {
716 
717  IrpContext->FatIoContext->Wait.Async.ResourceThreadId =
718  ((ULONG_PTR)IrpContext->FatIoContext) | 3;
719  }
720 
721  IrpContext->FatIoContext->Wait.Async.RequestedByteCount =
722  ByteCount;
723 
724  IrpContext->FatIoContext->Wait.Async.FileObject = FileObject;
725  }
726 
727  }
728 
729 
730  //
731  // These two cases correspond to either a general opened volume, ie.
732  // open ("a:"), or a read of the volume file (boot sector + fat(s))
733  //
734 
735  if ((TypeOfOpen == VirtualVolumeFile) ||
736  (TypeOfOpen == UserVolumeOpen)) {
737 
738  LBO StartingLbo;
739 
740  StartingLbo = StartingByte.QuadPart;
741 
742  DebugTrace(0, Dbg, "Type of read is User Volume or virtual volume file\n", 0);
743 
744  if (TypeOfOpen == UserVolumeOpen) {
745 
746  //
747  // Verify that the volume for this handle is still valid
748  //
749 
750  //
751  // Verify that the volume for this handle is still valid, permitting
752  // operations to proceed on dismounted volumes via the handle which
753  // performed the dismount.
754  //
755 
757 
758  FatQuickVerifyVcb( IrpContext, Vcb );
759  }
760 
761  //
762  // If the caller previously sent a format unit command, then we will allow
763  // their read/write requests to ignore the verify flag on the device, since some
764  // devices send a media change event after format unit, but we don't want to
765  // process it yet since we're probably in the process of formatting the
766  // media.
767  //
768 
770 
771  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
772  }
773 
775 
777 
778  _SEH2_TRY {
779 
780  //
781  // If the volume isn't locked, flush it.
782  //
783 
784  if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_LOCKED)) {
785 
786  FatFlushVolume( IrpContext, Vcb, Flush );
787  }
788 
789  } _SEH2_FINALLY {
790 
791  ExReleaseResourceLite( &Vcb->Resource );
792  } _SEH2_END;
793 
795  }
796 
798 
799  LBO VolumeSize;
800 
801  //
802  // Make sure we don't try to read past end of volume,
803  // reducing the byte count if necessary.
804  //
805 
806  VolumeSize = (LBO) Vcb->Bpb.BytesPerSector *
807  (Vcb->Bpb.Sectors != 0 ? Vcb->Bpb.Sectors :
808  Vcb->Bpb.LargeSectors);
809 
810  if (StartingLbo >= VolumeSize) {
811  Irp->IoStatus.Information = 0;
812  FatCompleteRequest( IrpContext, Irp, STATUS_END_OF_FILE );
813  return STATUS_END_OF_FILE;
814  }
815 
816  if (ByteCount > VolumeSize - StartingLbo) {
817 
818  ByteCount = RequestedByteCount = (ULONG) (VolumeSize - StartingLbo);
819 
820  //
821  // For async reads we had set the byte count in the FatIoContext
822  // above, so fix that here.
823  //
824 
825  if (!Wait) {
826 
827  IrpContext->FatIoContext->Wait.Async.RequestedByteCount =
828  ByteCount;
829  }
830  }
831  }
832 
833  //
834  // For DASD we have to probe and lock the user's buffer
835  //
836 
837  FatLockUserBuffer( IrpContext, Irp, IoWriteAccess, ByteCount );
838 
839 
840  } else {
841 
842  //
843  // Virtual volume file open -- increment performance counters.
844  //
845 
846  Vcb->Statistics[KeGetCurrentProcessorNumber() % FatData.NumberProcessors].Common.MetaDataDiskReads += 1;
847 
848  }
849 
850  //
851  // Read the data and wait for the results
852  //
853 
854  FatSingleAsync( IrpContext,
855  Vcb,
856  StartingLbo,
857  ByteCount,
858  Irp );
859 
860 #if (NTDDI_VERSION >= NTDDI_WIN8)
861 
862  //
863  // Account for DASD Ios
864  //
865 
867 
868  PETHREAD ThreadIssuingIo = PsGetCurrentThread();
869 
870  PsUpdateDiskCounters( PsGetThreadProcess( ThreadIssuingIo ),
871  ByteCount,
872  0,
873  1,
874  0,
875  0 );
876  }
877 
878 #endif
879 
880  if (!Wait) {
881 
882  //
883  // We, nor anybody else, need the IrpContext any more.
884  //
885 
886  IrpContext->FatIoContext = NULL;
887 
888  FatDeleteIrpContext( IrpContext );
889 
890  DebugTrace(-1, Dbg, "FatNonCachedIo -> STATUS_PENDING\n", 0);
891 
892  return STATUS_PENDING;
893  }
894 
895  FatWaitSync( IrpContext );
896 
897  //
898  // If the call didn't succeed, raise the error status
899  //
900 
901  if (!NT_SUCCESS( Status = Irp->IoStatus.Status )) {
902 
903  NT_ASSERT( KeGetCurrentThread() != Vcb->VerifyThread || Status != STATUS_VERIFY_REQUIRED );
904  FatNormalizeAndRaiseStatus( IrpContext, Status );
905  }
906 
907  //
908  // Update the current file position
909  //
910 
911  if (SynchronousIo && !PagingIo) {
912  FileObject->CurrentByteOffset.QuadPart =
913  StartingLbo + Irp->IoStatus.Information;
914  }
915 
916  DebugTrace(-1, Dbg, "CommonRead -> %08lx\n", Status );
917 
918  FatCompleteRequest( IrpContext, Irp, Status );
919  return Status;
920  }
921 
922  //
923  // At this point we know there is an Fcb/Dcb.
924  //
925 
926  NT_ASSERT( FcbOrDcb != NULL );
927 
928  //
929  // Check for a non-zero high part offset
930  //
931 
932  if ( StartingByte.HighPart != 0 ) {
933 
934  Irp->IoStatus.Information = 0;
935  FatCompleteRequest( IrpContext, Irp, STATUS_END_OF_FILE );
936  return STATUS_END_OF_FILE;
937  }
938 
939  //
940  // Use a try-finally to free Fcb/Dcb and buffers on the way out.
941  //
942 
943  _SEH2_TRY {
944 
945  //
946  // This case corresponds to a normal user read file.
947  //
948 
949  if ( TypeOfOpen == UserFileOpen
950  ) {
951 
952  ULONG FileSize;
953  ULONG ValidDataLength;
954 
955  DebugTrace(0, Dbg, "Type of read is user file open\n", 0);
956 
957  //
958  // If this is a noncached transfer and is not a paging I/O, and
959  // the file has a data section, then we will do a flush here
960  // to avoid stale data problems. Note that we must flush before
961  // acquiring the Fcb shared since the write may try to acquire
962  // it exclusive.
963  //
964 
965  if (!PagingIo && NonCachedIo
966 
967  &&
968 
969  (FileObject->SectionObjectPointer->DataSectionObject != NULL)) {
970 
972 
973 #ifndef REDUCE_SYNCHRONIZATION
974  if (!FatAcquireExclusiveFcb( IrpContext, FcbOrDcb )) {
975 
976  try_return( PostIrp = TRUE );
977  }
978 
979  ExAcquireResourceExclusiveLite( FcbOrDcb->Header.PagingIoResource, TRUE );
980 #endif //REDUCE_SYNCHRONIZATION
981 
982  CcFlushCache( FileObject->SectionObjectPointer,
983  &StartingByte,
984  ByteCount,
985  &IoStatus );
986 
987 #ifndef REDUCE_SYNCHRONIZATION
988  ExReleaseResourceLite( FcbOrDcb->Header.PagingIoResource );
989  FatReleaseFcb( IrpContext, FcbOrDcb );
990 #endif //REDUCE_SYNCHRONIZATION
991 
992  if (!NT_SUCCESS( IoStatus.Status)) {
993 
994  try_return( IoStatus.Status );
995  }
996 
997 #ifndef REDUCE_SYNCHRONIZATION
998  ExAcquireResourceExclusiveLite( FcbOrDcb->Header.PagingIoResource, TRUE );
999  ExReleaseResourceLite( FcbOrDcb->Header.PagingIoResource );
1000 #endif //REDUCE_SYNCHRONIZATION
1001  }
1002 
1003  //
1004  // We need shared access to the Fcb/Dcb before proceeding.
1005  //
1006 
1007  if ( PagingIo ) {
1008 
1009  if (!ExAcquireResourceSharedLite( FcbOrDcb->Header.PagingIoResource,
1010  TRUE )) {
1011 
1012  DebugTrace( 0, Dbg, "Cannot acquire FcbOrDcb = %p shared without waiting\n", FcbOrDcb );
1013 
1014  try_return( PostIrp = TRUE );
1015  }
1016 
1017  if (!Wait) {
1018 
1019  IrpContext->FatIoContext->Wait.Async.Resource =
1020  FcbOrDcb->Header.PagingIoResource;
1021  }
1022 
1023  } else {
1024 
1025  //
1026  // If this is async I/O, we will wait if there is an
1027  // exclusive waiter.
1028  //
1029 
1030  if (!Wait && NonCachedIo) {
1031 
1032  if (!FatAcquireSharedFcbWaitForEx( IrpContext, FcbOrDcb )) {
1033 
1034  DebugTrace( 0,
1035  Dbg,
1036  "Cannot acquire FcbOrDcb = %p shared without waiting\n",
1037  FcbOrDcb );
1038 
1039  try_return( PostIrp = TRUE );
1040  }
1041 
1042  IrpContext->FatIoContext->Wait.Async.Resource =
1043  FcbOrDcb->Header.Resource;
1044 
1045  } else {
1046 
1047  if (!FatAcquireSharedFcb( IrpContext, FcbOrDcb )) {
1048 
1049  DebugTrace( 0,
1050  Dbg,
1051  "Cannot acquire FcbOrDcb = %p shared without waiting\n",
1052  FcbOrDcb );
1053 
1054  try_return( PostIrp = TRUE );
1055  }
1056  }
1057  }
1058 
1059  FcbOrDcbAcquired = TRUE;
1060 
1061  //
1062  // Make sure the FcbOrDcb is still good
1063  //
1064 
1065  FatVerifyFcb( IrpContext, FcbOrDcb );
1066 
1067  //
1068  // We now check whether we can proceed based on the state of
1069  // the file oplocks.
1070  //
1071 
1072  if (!PagingIo) {
1073 
1075  Irp,
1076  IrpContext,
1078  FatPrePostIrp );
1079 
1080  if (Status != STATUS_SUCCESS) {
1081 
1082  OplockPostIrp = TRUE;
1083  PostIrp = TRUE;
1084  try_return( NOTHING );
1085  }
1086 
1087  //
1088  // Reset the flag indicating if Fast I/O is possible since the oplock
1089  // check could have broken existing (conflicting) oplocks.
1090  //
1091 
1092  FcbOrDcb->Header.IsFastIoPossible = FatIsFastIoPossible( FcbOrDcb );
1093 
1094  //
1095  // We have to check for read access according to the current
1096  // state of the file locks, and set FileSize from the Fcb.
1097  //
1098 
1099  if (!PagingIo &&
1101  Irp )) {
1102 
1104  }
1105  }
1106 
1107  //
1108  // Pick up our sizes and check/trim the IO.
1109  //
1110 
1111  FileSize = FcbOrDcb->Header.FileSize.LowPart;
1112  ValidDataLength = FcbOrDcb->Header.ValidDataLength.LowPart;
1113 
1114  //
1115  // If the read starts beyond End of File, return EOF.
1116  //
1117 
1118  if (StartingVbo >= FileSize) {
1119 
1120  DebugTrace( 0, Dbg, "End of File\n", 0 );
1121 
1123  }
1124 
1125  //
1126  // If the read extends beyond EOF, truncate the read
1127  //
1128 
1129  if (ByteCount > FileSize - StartingVbo) {
1130 
1131  ByteCount = RequestedByteCount = FileSize - StartingVbo;
1132 
1133  if (NonCachedIo && !Wait) {
1134 
1135  IrpContext->FatIoContext->Wait.Async.RequestedByteCount =
1136  RequestedByteCount;
1137 
1138  }
1139  }
1140 
1141  //
1142  // HANDLE THE NON-CACHED CASE
1143  //
1144 
1145  if ( NonCachedIo ) {
1146 
1147  ULONG SectorSize;
1148  ULONG BytesToRead;
1149 
1150  DebugTrace(0, Dbg, "Non cached read.\n", 0);
1151 
1152  //
1153  // Get the sector size
1154  //
1155 
1156  SectorSize = (ULONG)Vcb->Bpb.BytesPerSector;
1157 
1158  //
1159  // Start by zeroing any part of the read after Valid Data
1160  //
1161 
1162  if (ValidDataLength < FcbOrDcb->ValidDataToDisk) {
1163 
1164  ValidDataLength = FcbOrDcb->ValidDataToDisk;
1165  }
1166 
1167 
1168  if ( StartingVbo + ByteCount > ValidDataLength ) {
1169 
1170  SystemBuffer = FatMapUserBuffer( IrpContext, Irp );
1171 
1172  if (StartingVbo < ValidDataLength) {
1173 
1174  ULONG ZeroingOffset;
1175 
1176  //
1177  // Now zero out the user's request sector aligned beyond
1178  // vdl. We will handle the straddling sector at completion
1179  // time via the bytecount reduction which immediately
1180  // follows this check.
1181  //
1182  // Note that we used to post in this case for async requests.
1183  // Note also that if the request was wholly beyond VDL that
1184  // we did not post, therefore this is consistent. Synchronous
1185  // zeroing is fine for async requests.
1186  //
1187 
1188  ZeroingOffset = ((ValidDataLength - StartingVbo) + (SectorSize - 1))
1189  & ~(SectorSize - 1);
1190 
1191  //
1192  // If the offset is at or above the byte count, no harm: just means
1193  // that the read ends in the last sector and the zeroing will be
1194  // done at completion.
1195  //
1196 
1197  if (ByteCount > ZeroingOffset) {
1198 
1199  SafeZeroMemory( (PUCHAR) SystemBuffer + ZeroingOffset,
1200  ByteCount - ZeroingOffset);
1201 
1202  }
1203 
1204  } else {
1205 
1206  //
1207  // All we have to do now is sit here and zero the
1208  // user's buffer, no reading is required.
1209  //
1210 
1211  SafeZeroMemory( (PUCHAR)SystemBuffer, ByteCount );
1212 
1213  Irp->IoStatus.Information = ByteCount;
1214 
1215 
1217  }
1218  }
1219 
1220 
1221  //
1222  // Reduce the byte count to actually read if it extends beyond
1223  // Valid Data Length
1224  //
1225 
1226  ByteCount = (ValidDataLength - StartingVbo < ByteCount) ?
1227  ValidDataLength - StartingVbo : ByteCount;
1228 
1229  //
1230  // Round up to a sector boundary, and remember that if we are
1231  // reading extra bytes we will zero them out during completion.
1232  //
1233 
1234  BytesToRead = (ByteCount + (SectorSize - 1))
1235  & ~(SectorSize - 1);
1236 
1237  //
1238  // Just to help alleviate confusion. At this point:
1239  //
1240  // RequestedByteCount - is the number of bytes originally
1241  // taken from the Irp, but constrained
1242  // to filesize.
1243  //
1244  // ByteCount - is RequestedByteCount constrained to
1245  // ValidDataLength.
1246  //
1247  // BytesToRead - is ByteCount rounded up to sector
1248  // boundry. This is the number of bytes
1249  // that we must physically read.
1250  //
1251 
1252  //
1253  // If this request is not properly aligned, or extending
1254  // to a sector boundary would overflow the buffer, send it off
1255  // on a special-case path.
1256  //
1257 
1258  if ( (StartingVbo & (SectorSize - 1)) ||
1259  (BytesToRead > IrpSp->Parameters.Read.Length) ) {
1260 
1261  //
1262  // If we can't wait, we must post this.
1263  //
1264 
1265  if (!Wait) {
1266 
1267  try_return( PostIrp = TRUE );
1268  }
1269 
1270  //
1271  // Do the physical read
1272  //
1273 
1274  FatNonCachedNonAlignedRead( IrpContext,
1275  Irp,
1276  FcbOrDcb,
1277  StartingVbo,
1278  ByteCount );
1279 
1280  //
1281  // Set BytesToRead to ByteCount to satify the following ASSERT.
1282  //
1283 
1284 #ifdef _MSC_VER
1285 #pragma prefast( suppress:28931, "needed for debug build" )
1286 #endif
1287  BytesToRead = ByteCount;
1288 
1289  } else {
1290 
1291  //
1292  // Perform the actual IO
1293  //
1294 
1295 
1296  if (FatNonCachedIo( IrpContext,
1297  Irp,
1298  FcbOrDcb,
1299  StartingVbo,
1300  BytesToRead,
1301  ByteCount,
1302  0) == STATUS_PENDING) {
1303 
1304 
1305  IrpContext->FatIoContext = NULL;
1306 
1307  Irp = NULL;
1308 
1310  }
1311  }
1312 
1313  //
1314  // If the call didn't succeed, raise the error status
1315  //
1316 
1317  if (!NT_SUCCESS( Status = Irp->IoStatus.Status )) {
1318 
1319  NT_ASSERT( KeGetCurrentThread() != Vcb->VerifyThread || Status != STATUS_VERIFY_REQUIRED );
1320  FatNormalizeAndRaiseStatus( IrpContext, Status );
1321 
1322  } else {
1323 
1324  //
1325  // Else set the Irp information field to reflect the
1326  // entire desired read.
1327  //
1328 
1329  NT_ASSERT( Irp->IoStatus.Information == BytesToRead );
1330 
1331  Irp->IoStatus.Information = RequestedByteCount;
1332  }
1333 
1334  //
1335  // The transfer is complete.
1336  //
1337 
1338  try_return( Status );
1339 
1340  } // if No Intermediate Buffering
1341 
1342 
1343  //
1344  // HANDLE CACHED CASE
1345  //
1346 
1347  else {
1348 
1349  //
1350  // We delay setting up the file cache until now, in case the
1351  // caller never does any I/O to the file, and thus
1352  // FileObject->PrivateCacheMap == NULL.
1353  //
1354 
1355  if (FileObject->PrivateCacheMap == NULL) {
1356 
1357  DebugTrace(0, Dbg, "Initialize cache mapping.\n", 0);
1358 
1359  //
1360  // Get the file allocation size, and if it is less than
1361  // the file size, raise file corrupt error.
1362  //
1363 
1364  if (FcbOrDcb->Header.AllocationSize.QuadPart == FCB_LOOKUP_ALLOCATIONSIZE_HINT) {
1365 
1366  FatLookupFileAllocationSize( IrpContext, FcbOrDcb );
1367  }
1368 
1369  if ( FileSize > FcbOrDcb->Header.AllocationSize.LowPart ) {
1370 
1371  FatPopUpFileCorrupt( IrpContext, FcbOrDcb );
1372 
1374  }
1375 
1376  //
1377  // Now initialize the cache map.
1378  //
1379 
1381  (PCC_FILE_SIZES)&FcbOrDcb->Header.AllocationSize,
1382  FALSE,
1384  FcbOrDcb );
1385 
1387  }
1388 
1389 
1390  //
1391  // DO A NORMAL CACHED READ, if the MDL bit is not set,
1392  //
1393 
1394  DebugTrace(0, Dbg, "Cached read.\n", 0);
1395 
1396  if (!FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
1397 
1398  //
1399  // Get hold of the user's buffer.
1400  //
1401 
1402  SystemBuffer = FatMapUserBuffer( IrpContext, Irp );
1403 
1404  //
1405  // Now try to do the copy.
1406  //
1407 
1408 #if (NTDDI_VERSION >= NTDDI_WIN8)
1409  if (!CcCopyReadEx( FileObject,
1410  &StartingByte,
1411  ByteCount,
1412  Wait,
1413  SystemBuffer,
1414  &Irp->IoStatus,
1415  Irp->Tail.Overlay.Thread )) {
1416 #else
1417  if (!CcCopyRead( FileObject,
1418  &StartingByte,
1419  ByteCount,
1420  Wait,
1421  SystemBuffer,
1422  &Irp->IoStatus )) {
1423 #endif
1424 
1425  DebugTrace( 0, Dbg, "Cached Read could not wait\n", 0 );
1426 
1427  try_return( PostIrp = TRUE );
1428  }
1429 
1430  Status = Irp->IoStatus.Status;
1431 
1433 
1434  try_return( Status );
1435  }
1436 
1437 
1438  //
1439  // HANDLE A MDL READ
1440  //
1441 
1442  else {
1443 
1444  DebugTrace(0, Dbg, "MDL read.\n", 0);
1445 
1446  NT_ASSERT( Wait );
1447 
1449  &StartingByte,
1450  ByteCount,
1451  &Irp->MdlAddress,
1452  &Irp->IoStatus );
1453 
1454  Status = Irp->IoStatus.Status;
1455 
1457 
1458  try_return( Status );
1459  }
1460  }
1461  }
1462 
1463  //
1464  // These cases correspond to a system read directory file or
1465  // ea file.
1466  //
1467 
1468  if (( TypeOfOpen == DirectoryFile ) || ( TypeOfOpen == EaFile)
1469  ) {
1470 
1471  ULONG SectorSize;
1472 
1473 
1474 #if FASTFATDBG
1475  if ( TypeOfOpen == DirectoryFile ) {
1476  DebugTrace(0, Dbg, "Type of read is directoryfile\n", 0);
1477  } else if ( TypeOfOpen == EaFile) {
1478  DebugTrace(0, Dbg, "Type of read is eafile\n", 0);
1479  }
1480 
1481 #endif
1482 
1483  //
1484  // For the noncached case, assert that everything is sector
1485  // alligned.
1486  //
1487 
1488 #ifdef _MSC_VER
1489 #pragma prefast( suppress:28931, "needed for debug build" )
1490 #endif
1491  SectorSize = (ULONG)Vcb->Bpb.BytesPerSector;
1492 
1493  //
1494  // We make several assumptions about these two types of files.
1495  // Make sure all of them are true.
1496  //
1497 
1498  NT_ASSERT( NonCachedIo && PagingIo );
1499  NT_ASSERT( ((StartingVbo | ByteCount) & (SectorSize - 1)) == 0 );
1500 
1501 
1502  //
1503  // These calls must allways be within the allocation size
1504  //
1505 
1506  if (StartingVbo >= FcbOrDcb->Header.AllocationSize.LowPart) {
1507 
1508  DebugTrace( 0, Dbg, "PagingIo dirent started beyond EOF.\n", 0 );
1509 
1510  Irp->IoStatus.Information = 0;
1511 
1513  }
1514 
1515  if ( StartingVbo + ByteCount > FcbOrDcb->Header.AllocationSize.LowPart ) {
1516 
1517  DebugTrace( 0, Dbg, "PagingIo dirent extending beyond EOF.\n", 0 );
1518  ByteCount = FcbOrDcb->Header.AllocationSize.LowPart - StartingVbo;
1519  }
1520 
1521 
1522  //
1523  // Perform the actual IO
1524  //
1525 
1526  if (FatNonCachedIo( IrpContext,
1527  Irp,
1528  FcbOrDcb,
1529  StartingVbo,
1530  ByteCount,
1531  ByteCount,
1532  0 ) == STATUS_PENDING) {
1533 
1534  IrpContext->FatIoContext = NULL;
1535 
1536  Irp = NULL;
1537 
1539  }
1540 
1541  //
1542  // If the call didn't succeed, raise the error status
1543  //
1544 
1545  if (!NT_SUCCESS( Status = Irp->IoStatus.Status )) {
1546 
1547  NT_ASSERT( KeGetCurrentThread() != Vcb->VerifyThread || Status != STATUS_VERIFY_REQUIRED );
1548  FatNormalizeAndRaiseStatus( IrpContext, Status );
1549 
1550  } else {
1551 
1552  NT_ASSERT( Irp->IoStatus.Information == ByteCount );
1553  }
1554 
1555  try_return( Status );
1556  }
1557 
1558  //
1559  // This is the case of a user who openned a directory. No reading is
1560  // allowed.
1561  //
1562 
1563  if ( TypeOfOpen == UserDirectoryOpen ) {
1564 
1565  DebugTrace( 0, Dbg, "CommonRead -> STATUS_INVALID_PARAMETER\n", 0);
1566 
1568  }
1569 
1570  //
1571  // If we get this far, something really serious is wrong.
1572  //
1573 
1574  DebugDump("Illegal TypeOfOpen\n", 0, FcbOrDcb );
1575 
1576 #ifdef _MSC_VER
1577 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1578 #endif
1580 
1581  try_exit: NOTHING;
1582 
1583  //
1584  // If the request was not posted and there's an Irp, deal with it.
1585  //
1586 
1587  if ( Irp ) {
1588 
1589  if ( !PostIrp ) {
1590 
1591  ULONG ActualBytesRead;
1592 
1593  DebugTrace( 0, Dbg, "Completing request with status = %08lx\n",
1594  Status);
1595 
1596  DebugTrace( 0, Dbg, " Information = %08lx\n",
1597  Irp->IoStatus.Information);
1598 
1599  //
1600  // Record the total number of bytes actually read
1601  //
1602 
1603  ActualBytesRead = (ULONG)Irp->IoStatus.Information;
1604 
1605  //
1606  // If the file was opened for Synchronous IO, update the current
1607  // file position.
1608  //
1609 
1610  if (SynchronousIo && !PagingIo) {
1611 
1612  FileObject->CurrentByteOffset.LowPart =
1613  StartingVbo + (NT_ERROR( Status ) ? 0 : ActualBytesRead);
1614  }
1615 
1616  //
1617  // If this was not PagingIo, mark that the last access
1618  // time on the dirent needs to be updated on close.
1619  //
1620 
1621  if (NT_SUCCESS(Status) && !PagingIo) {
1622 
1624  }
1625 
1626  } else {
1627 
1628  DebugTrace( 0, Dbg, "Passing request to Fsp\n", 0 );
1629 
1630  if (!OplockPostIrp) {
1631 
1632  Status = FatFsdPostRequest( IrpContext, Irp );
1633  }
1634  }
1635  }
1636 
1637  } _SEH2_FINALLY {
1638 
1639  DebugUnwind( FatCommonRead );
1640 
1641  //
1642  // If the FcbOrDcb has been acquired, release it.
1643  //
1644 
1645  if (FcbOrDcbAcquired && Irp) {
1646 
1647  if ( PagingIo ) {
1648 
1649  ExReleaseResourceLite( FcbOrDcb->Header.PagingIoResource );
1650 
1651  } else {
1652 
1654  }
1655  }
1656 
1657  //
1658  // Complete the request if we didn't post it and no exception
1659  //
1660  // Note that FatCompleteRequest does the right thing if either
1661  // IrpContext or Irp are NULL
1662  //
1663 
1664  if (!PostIrp) {
1665 
1666  //
1667  // If we had a stack io context, we have to make sure the contents
1668  // are cleaned up before we leave.
1669  //
1670  // At present with zero mdls, this will only really happen on exceptional
1671  // termination where we failed to dispatch the IO. Cleanup of zero mdls
1672  // normally occurs during completion, but when we bail we must make sure
1673  // the cleanup occurs here or the fatiocontext will go out of scope.
1674  //
1675  // If the operation was posted, cleanup occured there.
1676  //
1677 
1678  if (FlagOn(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT)) {
1679 
1680  if (IrpContext->FatIoContext->ZeroMdl) {
1681  IoFreeMdl( IrpContext->FatIoContext->ZeroMdl );
1682  }
1683 
1684  ClearFlag(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT);
1685  IrpContext->FatIoContext = NULL;
1686  }
1687 
1688  if (!_SEH2_AbnormalTermination()) {
1689 
1690  FatCompleteRequest( IrpContext, Irp, Status );
1691  }
1692  }
1693 
1694  DebugTrace(-1, Dbg, "CommonRead -> %08lx\n", Status );
1695  } _SEH2_END;
1696 
1697  return Status;
1698 }
1699 
1700 //
1701 // Local support routine
1702 //
1703 
1704 VOID
1705 NTAPI
1707  IN PVOID Context,
1708  IN PKEVENT Event
1709  )
1710 
1711 /*++
1712 
1713 Routine Description:
1714 
1715  The routine simply call FatPagingFileIo. It is invoked in cases when
1716  there was not enough stack space to perform the pagefault in the
1717  original thread. It is also responsible for freeing the packet pool.
1718 
1719 Arguments:
1720 
1721  Irp - Supplies the Irp being processed
1722 
1723  Fcb - Supplies the paging file Fcb, since we have it handy.
1724 
1725 Return Value:
1726 
1727  VOID
1728 
1729 --*/
1730 
1731 {
1733 
1734  FatPagingFileIo( Packet->Irp, Packet->Fcb );
1735 
1736  //
1737  // Set the stack overflow item's event to tell the original
1738  // thread that we're done.
1739  //
1740 
1741  KeSetEvent( Event, 0, FALSE );
1742 
1743  return;
1744 }
1745 
1746 
1747 
#define IRP_CONTEXT_FLAG_VERIFY_READ
Definition: ext2fs.h:1083
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1772
VOID NTAPI CcMdlRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:64
#define IN
Definition: typedefs.h:39
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2992
#define FsRtlEnterFileSystem
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
PVOID FatMapUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
Definition: deviosup.c:3357
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1240
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
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
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: fatstruc.h:158
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2630
#define CCB_FLAG_SENT_FORMAT_UNIT
Definition: fatstruc.h:1344
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2659
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
#define IRP_CONTEXT_STACK_IO_CONTEXT
Definition: ext2fs.h:1084
VOID FatLockUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
Definition: deviosup.c:3276
#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO
Definition: cdstruc.h:1114
Definition: cdstruc.h:1073
ULONG32 VBO
Definition: fat.h:38
unsigned char * PUCHAR
Definition: retypes.h:3
VOID NTAPI FatOplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: workque.c:35
LONG NTSTATUS
Definition: precomp.h:26
#define FatDeviceIsFatFsdo(D)
Definition: fatprocs.h:3092
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
VOID NTAPI FsRtlPostPagingFileStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:206
#define IRP_NOCACHE
Definition: cdstruc.h:504
#define READ_AHEAD_GRANULARITY
Definition: read.c:60
VOID FatWaitSync(IN PIRP_CONTEXT IrpContext)
Definition: deviosup.c:2367
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2974
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
struct _FCB::@711::@714 Fcb
_SEH2_TRY
Definition: create.c:4226
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2410
#define STATUS_END_OF_FILE
Definition: shellext.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1735
#define IRP_MN_COMPLETE
Definition: iotypes.h:4066
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:337
IN PFCB FcbOrDcb
Definition: fatprocs.h:306
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:588
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
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:843
ULONG NumberProcessors
Definition: fatstruc.h:80
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1194
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1754
VOID FatPagingFileIo(IN PIRP Irp, IN PFCB Fcb)
Definition: deviosup.c:211
LONGLONG LBO
Definition: fat.h:34
#define FatGetFcbOplock(F)
Definition: fatprocs.h:1656
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:437
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define SafeZeroMemory(AT, BYTE_COUNT)
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define TAG_FAT_IO_CONTEXT
Definition: nodetype.h:165
#define OVERFLOW_READ_THRESHHOLD
Definition: read.c:42
VOID NTAPI FatOverflowPagingFileRead(IN PVOID Context, IN PKEVENT Event)
Definition: read.c:1706
NodeType
Definition: Node.h:5
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2289
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define IRP_CONTEXT_FLAG_USER_IO
Definition: ext2fs.h:1086
_Acquires_shared_lock_ Fcb FINISHED FatAcquireSharedFcbWaitForEx(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
#define CCB_FLAG_COMPLETE_DISMOUNT
Definition: fatstruc.h:1330
#define DebugUnwind(X)
Definition: fatdata.h:315
FAT_DATA FatData
Definition: fatdata.c:56
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
#define VCB_STATE_FLAG_LOCKED
Definition: fatstruc.h:558
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define try_return(S)
Definition: cdprocs.h:2179
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:676
FCB * PFCB
Definition: cdstruc.h:1046
#define Vcb
Definition: cdprocs.h:1415
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:232
#define _Inout_
Definition: no_sal2.h:244
#define NT_ERROR(Status)
Definition: umtypes.h:106
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1957
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define CanFsdWait(I)
Definition: cdprocs.h:2001
ULONG Flags
Definition: ntfs.h:532
#define Dbg
Definition: read.c:29
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define CCB_FLAG_DASD_FLUSH_DONE
Definition: fatstruc.h:1280
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
#define VOID
Definition: acefi.h:82
#define IRP_MN_MDL
Definition: iotypes.h:4065
ULONG LowPart
Definition: typedefs.h:105
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
union _FCB::@711 Specific
DRIVER_DISPATCH(nfs41_FsdDispatch)
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:411
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1063
Status
Definition: gdiplustypes.h:24
_Function_class_(IO_COMPLETION_ROUTINE)
Definition: read.c:67
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID FatInitializeCacheMap(_In_ PFILE_OBJECT FileObject, _In_ PCC_FILE_SIZES FileSizes, _In_ BOOLEAN PinAccess, _In_ PCACHE_MANAGER_CALLBACKS Callbacks, _In_ PVOID LazyWriteContext)
Definition: cachesup.c:62
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2815
_SEH2_END
Definition: create.c:4400
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
ULONG ValidDataToDisk
Definition: fatstruc.h:927
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define FatIsFastIoPossible(FCB)
Definition: fatprocs.h:2810
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_SEH2_FINALLY
Definition: create.c:4371
_Requires_lock_held_(_Global_critical_region_)
Definition: read.c:68
#define IRP_PAGING_IO
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
NTSTATUS FatCompleteMdl(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: cachesup.c:1728
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:306
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
PVCB Vcb
Definition: cdstruc.h:939
#define FAT_NTC_VCB
Definition: nodetype.h:28
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1172
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ ULONG SectorSize
Definition: halfuncs.h:291
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2774
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define FatDeleteIrpContext(IRPCONTEXT)
Definition: fatprocs.h:1762
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1569
#define CollectReadStats(VCB, OPEN_TYPE, BYTE_COUNT)
return STATUS_SUCCESS
Definition: btrfs.c:3014
VOID NTAPI FatPrePostIrp(IN PVOID Context, IN PIRP Irp)
Definition: workque.c:91
IoMarkIrpPending(Irp)
VOID FatQuickVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1662
ULONG FcbState
Definition: cdstruc.h:977
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
#define FAT_NTC_FCB
Definition: nodetype.h:29
VOID FatSingleAsync(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN LBO Lbo, IN ULONG ByteCount, IN PIRP Irp)
Definition: deviosup.c:1990
LONGLONG QuadPart
Definition: typedefs.h:113
#define PAGED_CODE()
IN BOOLEAN Wait
Definition: fatprocs.h:1538
#define DebugDump(STR, LEVEL, PTR)
Definition: fatdata.h:314
#define NT_ASSERT
Definition: rtlfuncs.h:3312
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36