ReactOS 0.4.15-dev-8119-g4fb2fdb
read.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1989-2000 Microsoft Corporation
4
5Module Name:
6
7 Read.c
8
9Abstract:
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_)
51VOID
53FatStackOverflowRead (
56 );
57
58_Requires_lock_held_(_Global_critical_region_)
60FatPostStackOverflowRead (
61 IN PIRP_CONTEXT IrpContext,
62 IN PIRP Irp,
63 IN PFCB Fcb
64 );
65
66VOID
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
119NTAPI
120FatFsdRead (
121 _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
123 )
124
125/*++
126
127Routine 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
136Arguments:
137
138 VolumeDeviceObject - Supplies the volume device object where the
139 file being Read exists
140
141 Irp - Supplies the Irp being processed
142
143Return 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
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
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_)
285FatPostStackOverflowRead (
286 IN PIRP_CONTEXT IrpContext,
287 IN PIRP Irp,
288 IN PFCB Fcb
289 )
290
291/*++
292
293Routine 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
298Arguments:
299
300 Irp - Supplies the request to process.
301
302 Fcb - Supplies the file.
303
304Return Value:
305
306 STATUS_PENDING.
307
308--*/
309
310{
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_)
409VOID
410NTAPI
411FatStackOverflowRead (
414 )
415
416/*++
417
418Routine 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
423Arguments:
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
430Return 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_)
524FatCommonRead (
525 IN PIRP_CONTEXT IrpContext,
526 IN PIRP Irp
527 )
528
529/*++
530
531Routine 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
542Arguments:
543
544 Irp - Supplies the Irp to process
545
546Return Value:
547
548 NTSTATUS - The return status for the operation
549
550--*/
551
552{
553 PVCB Vcb;
555 PCCB Ccb;
556
559 ULONG RequestedByteCount;
560
564
565 BOOLEAN PostIrp = FALSE;
566 BOOLEAN OplockPostIrp = FALSE;
567
568 BOOLEAN FcbOrDcbAcquired = FALSE;
569
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) ||
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;
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
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
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;
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
950 ) {
951
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
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
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;
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
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,
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,
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
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,
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
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
1704VOID
1705NTAPI
1709 )
1710
1711/*++
1712
1713Routine 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
1719Arguments:
1720
1721 Irp - Supplies the Irp being processed
1722
1723 Fcb - Supplies the paging file Fcb, since we have it handy.
1724
1725Return 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
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
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
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
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 CanFsdWait(I)
Definition: cdprocs.h:2001
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
@ UserDirectoryOpen
Definition: cdprocs.h:576
@ UserFileOpen
Definition: cdprocs.h:577
@ UserVolumeOpen
Definition: cdprocs.h:575
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define try_return(S)
Definition: cdprocs.h:2179
#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO
Definition: cdstruc.h:1108
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
struct _VCB * PVCB
Definition: fatstruc.h:557
FCB * PFCB
Definition: cdstruc.h:1040
#define _Requires_lock_held_(lock)
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NodeType(P)
Definition: nodetype.h:51
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
LONGLONG LBO
Definition: fat.h:34
ULONG32 VBO
Definition: fat.h:38
#define FAT_NTC_FCB
Definition: nodetype.h:29
#define FAT_NTC_VCB
Definition: nodetype.h:28
#define TAG_FAT_IO_CONTEXT
Definition: nodetype.h:165
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define ULONG_PTR
Definition: config.h:101
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define IRP_CONTEXT_FLAG_USER_IO
Definition: ext2fs.h:1095
#define IRP_CONTEXT_FLAG_VERIFY_READ
Definition: ext2fs.h:1092
#define IRP_CONTEXT_STACK_IO_CONTEXT
Definition: ext2fs.h:1093
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
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
NTSTATUS FatCompleteMdl(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: cachesup.c:1728
PVOID FatMapUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
Definition: deviosup.c:3357
VOID FatWaitSync(IN PIRP_CONTEXT IrpContext)
Definition: deviosup.c:2367
VOID FatSingleAsync(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN LBO Lbo, IN ULONG ByteCount, IN PIRP Irp)
Definition: deviosup.c:1990
VOID FatLockUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
Definition: deviosup.c:3276
VOID FatPagingFileIo(IN PIRP Irp, IN PFCB Fcb)
Definition: deviosup.c:211
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
FAT_DATA FatData
Definition: fatdata.c:56
#define DebugDump(STR, LEVEL, PTR)
Definition: fatdata.h:314
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define DebugUnwind(X)
Definition: fatdata.h:315
VOID FatQuickVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1662
#define FatDeleteIrpContext(IRPCONTEXT)
Definition: fatprocs.h:1762
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:412
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
@ DirectoryFile
Definition: fatprocs.h:1046
@ VirtualVolumeFile
Definition: fatprocs.h:1045
@ EaFile
Definition: fatprocs.h:1047
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
VOID NTAPI FatPrePostIrp(IN PVOID Context, IN PIRP Irp)
Definition: workque.c:91
#define FatDeviceIsFatFsdo(D)
Definition: fatprocs.h:3095
IN PFCB FcbOrDcb
Definition: fatprocs.h:306
#define FatIsFastIoPossible(FCB)
Definition: fatprocs.h:2813
VOID NTAPI FatOplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: workque.c:35
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2995
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2977
_Acquires_shared_lock_ Fcb FINISHED FatAcquireSharedFcbWaitForEx(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
@ Flush
Definition: fatprocs.h:1054
#define FatGetFcbOplock(F)
Definition: fatprocs.h:1656
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define VCB_STATE_FLAG_LOCKED
Definition: fatstruc.h:559
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1574
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1241
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
#define CCB_FLAG_DASD_FLUSH_DONE
Definition: fatstruc.h:1281
#define CCB_FLAG_SENT_FORMAT_UNIT
Definition: fatstruc.h:1345
#define CCB_FLAG_COMPLETE_DISMOUNT
Definition: fatstruc.h:1331
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:672
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define READ_AHEAD_GRANULARITY
Definition: read.c:60
#define SafeZeroMemory(IC, AT, BYTE_COUNT)
Definition: read.c:38
#define OVERFLOW_READ_THRESHHOLD
Definition: read.c:42
#define CollectReadStats(VCB, OPEN_TYPE, BYTE_COUNT)
#define Dbg
Definition: read.c:29
VOID NTAPI FatOverflowPagingFileRead(IN PVOID Context, IN PKEVENT Event)
Definition: read.c:1706
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define IoFreeMdl
Definition: fxmdl.h:89
Status
Definition: gdiplustypes.h:25
#define KeGetCurrentThread
Definition: hal.h:55
#define NOTHING
Definition: input_list.c:10
IoMarkIrpPending(Irp)
if(dx< 0)
Definition: linetemp.h:194
#define _Function_class_(x)
Definition: ms_sal.h:2946
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
#define KernelMode
Definition: asm.h:34
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ NotificationEvent
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
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
#define STATUS_PENDING
Definition: ntstatus.h:82
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:1170
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define IRP_MJ_READ
Definition: rdpdr.c:46
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:232
VOID NTAPI FsRtlPostPagingFileStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:206
Definition: cdstruc.h:1067
ULONG NumberProcessors
Definition: fatstruc.h:81
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: fatstruc.h:159
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PVCB Vcb
Definition: cdstruc.h:933
struct _FCB::@724::@727 Fcb
union _FCB::@724 Specific
ULONG ValidDataToDisk
Definition: fatstruc.h:928
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG FcbState
Definition: cdstruc.h:971
struct _IO_STACK_LOCATION::@3983::@3987 Read
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1568 Parameters
Definition: cdstruc.h:498
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define NT_ERROR(Status)
Definition: umtypes.h:106
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_In_ ULONG SectorSize
Definition: halfuncs.h:291
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_PAGING_IO
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MN_MDL
Definition: iotypes.h:4419
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_NOCACHE
@ Executive
Definition: ketypes.h:415
@ IoWriteAccess
Definition: ketypes.h:864
#define NT_ASSERT
Definition: rtlfuncs.h:3310