ReactOS  0.4.13-dev-52-g0efcfec
cachesup.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1990-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  cache.c
8 
9 Abstract:
10 
11  This module implements the cache management routines for the Fat
12  FSD and FSP, by calling the Common Cache Manager.
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_CACHESUP)
24 
25 //
26 // Local debug trace level
27 //
28 
29 #define Dbg (DEBUG_TRACE_CACHESUP)
30 
31 #if DBG
32 
33 BOOLEAN
34 FatIsCurrentOperationSynchedForDcbTeardown (
35  IN PIRP_CONTEXT IrpContext,
36  IN PDCB Dcb
37  );
38 
39 #endif
40 
41 #ifdef ALLOC_PRAGMA
42 #pragma alloc_text(PAGE, FatCloseEaFile)
43 #pragma alloc_text(PAGE, FatCompleteMdl)
44 #pragma alloc_text(PAGE, FatOpenDirectoryFile)
45 #pragma alloc_text(PAGE, FatOpenEaFile)
46 #pragma alloc_text(PAGE, FatPinMappedData)
47 #pragma alloc_text(PAGE, FatPrepareWriteDirectoryFile)
48 #pragma alloc_text(PAGE, FatPrepareWriteVolumeFile)
49 #pragma alloc_text(PAGE, FatReadDirectoryFile)
50 #pragma alloc_text(PAGE, FatReadVolumeFile)
51 #pragma alloc_text(PAGE, FatRepinBcb)
52 #pragma alloc_text(PAGE, FatSyncUninitializeCacheMap)
53 #pragma alloc_text(PAGE, FatUnpinRepinnedBcbs)
54 #pragma alloc_text(PAGE, FatZeroData)
55 #pragma alloc_text(PAGE, FatPrefetchPages)
56 #if DBG
57 #pragma alloc_text(PAGE, FatIsCurrentOperationSynchedForDcbTeardown)
58 #endif
59 #endif
60 
61 VOID
65  _In_ BOOLEAN PinAccess,
67  _In_ PVOID LazyWriteContext
68  )
69 /*++
70 
71 Routine Description:
72 
73  Wrapper over CcInitializeCacheMap and CcSetAdditionalCacheAttributesEx to initialize
74  caching and enable IO accounting on a file.
75 
76 --*/
77 
78 {
79  //
80  // Initialize caching
81  //
82 
84  FileSizes,
85  PinAccess,
86  Callbacks,
87  LazyWriteContext );
88 
89 #if (NTDDI_VERSION >= NTDDI_WIN8)
90  //
91  // Enable Disk IO Accounting for this file
92  //
93 
95 
96  CcSetAdditionalCacheAttributesEx( FileObject, CC_ENABLE_DISK_IO_ACCOUNTING );
97  }
98 #endif
99 }
100 
101 VOID
103  IN PIRP_CONTEXT IrpContext,
104  IN PVCB Vcb,
107  OUT PBCB *Bcb,
108  OUT PVOID *Buffer
109  )
110 
111 /*++
112 
113 Routine Description:
114 
115  This routine is called when the specified range of sectors is to be
116  read into the cache. In fat, the volume file only contains the boot
117  sector, reserved sectors, and the "fat(s)." Thus the volume file is
118  of fixed size and only extends up to (but not not including) the root
119  directory entry, and will never move or change size.
120 
121  The fat volume file is also peculiar in that, since it starts at the
122  logical beginning of the disk, Vbo == Lbo.
123 
124 Arguments:
125 
126  Vcb - Pointer to the VCB for the volume
127 
128  StartingVbo - The virtual offset of the first desired byte
129 
130  ByteCount - Number of bytes desired
131 
132  Bcb - Returns a pointer to the BCB which is valid until unpinned
133 
134  Buffer - Returns a pointer to the sectors, which is valid until unpinned
135 
136 --*/
137 
138 {
140 
141  PAGED_CODE();
142 
143  //
144  // Check to see that all references are within the Bios Parameter Block
145  // or the fat(s). A special case is made when StartingVbo == 0 at
146  // mounting time since we do not know how big the fat is.
147  //
148 
149  NT_ASSERT( ((StartingVbo == 0) || ((StartingVbo + ByteCount) <= (ULONG)
150  (FatRootDirectoryLbo( &Vcb->Bpb ) + PAGE_SIZE))));
151 
152  DebugTrace(+1, Dbg, "FatReadVolumeFile\n", 0);
153  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb);
154  DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo);
155  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
156 
157  //
158  // Call the Cache manager to attempt the transfer.
159  //
160 
161  Vbo.QuadPart = StartingVbo;
162 
163  if (!CcMapData( Vcb->VirtualVolumeFile,
164  &Vbo,
165  ByteCount,
166  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
167  Bcb,
168  Buffer )) {
169 
170  NT_ASSERT( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
171 
172  //
173  // Could not read the data without waiting (cache miss).
174  //
175 
176  FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
177  }
178 
179  DbgDoit( IrpContext->PinCount += 1 )
180 
181  DebugTrace(-1, Dbg, "FatReadVolumeFile -> VOID, *BCB = %p\n", *Bcb);
182 
183  return;
184 }
185 
186 
187 _Requires_lock_held_(_Global_critical_region_)
188 VOID
189 FatPrepareWriteVolumeFile (
190  IN PIRP_CONTEXT IrpContext,
191  IN PVCB Vcb,
194  OUT PBCB *Bcb,
195  OUT PVOID *Buffer,
197  IN BOOLEAN Zero
198  )
199 
200 /*++
201 
202 Routine Description:
203 
204  This routine first looks to see if the specified range of sectors,
205  is already in the cache. If so, it increments the BCB PinCount,
206  sets the BCB dirty, and returns with the location of the sectors.
207 
208  If the sectors are not in the cache and Wait is TRUE, it finds a
209  free BCB (potentially causing a flush), and clears out the entire
210  buffer. Once this is done, it increments the BCB PinCount, sets the
211  BCB dirty, and returns with the location of the sectors.
212 
213  If the sectors are not in the cache and Wait is FALSE, this routine
214  raises STATUS_CANT_WAIT.
215 
216 Arguments:
217 
218  Vcb - Pointer to the VCB for the volume
219 
220  StartingVbo - The virtual offset of the first byte to be written
221 
222  ByteCount - Number of bytes to be written
223 
224  Bcb - Returns a pointer to the BCB which is valid until unpinned
225 
226  Buffer - Returns a pointer to the sectors, which is valid until unpinned
227 
228  Reversible - Supplies TRUE if the specified range of modification should
229  be repinned so that the operation can be reversed in a controlled
230  fashion if errors are encountered.
231 
232  Zero - Supplies TRUE if the specified range of bytes should be zeroed
233 
234 --*/
235 
236 {
238 
239  PAGED_CODE();
240 
241  //
242  // Check to see that all references are within the Bios Parameter Block
243  // or the fat(s).
244  //
245 
247  (FatRootDirectoryLbo( &Vcb->Bpb ))));
248 
249  DebugTrace(+1, Dbg, "FatPrepareWriteVolumeFile\n", 0);
250  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb);
251  DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", (ULONG)StartingVbo);
252  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
253  DebugTrace( 0, Dbg, "Zero = %08lx\n", Zero);
254 
255  //
256  // Call the Cache manager to attempt the transfer.
257  //
258 
259  Vbo.QuadPart = StartingVbo;
260 
261  if (!CcPinRead( Vcb->VirtualVolumeFile,
262  &Vbo,
263  ByteCount,
264  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
265  Bcb,
266  Buffer )) {
267 
268  NT_ASSERT( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
269 
270  //
271  // Could not read the data without waiting (cache miss).
272  //
273 
274  FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
275  }
276 
277  //
278  // This keeps the data pinned until we complete the request
279  // and writes the dirty bit through to the disk.
280  //
281 
282  DbgDoit( IrpContext->PinCount += 1 )
283 
284  _SEH2_TRY {
285 
286  if (Zero) {
287 
289  }
290 
291  FatSetDirtyBcb( IrpContext, *Bcb, Vcb, Reversible );
292 
293  } _SEH2_FINALLY {
294 
296 
297  FatUnpinBcb(IrpContext, *Bcb);
298  }
299  } _SEH2_END;
300 
301  DebugTrace(-1, Dbg, "FatPrepareWriteVolumeFile -> VOID, *Bcb = %p\n", *Bcb);
302 
303  return;
304 }
305 
306 
307 _Requires_lock_held_(_Global_critical_region_)
308 VOID
309 FatReadDirectoryFile (
310  IN PIRP_CONTEXT IrpContext,
311  IN PDCB Dcb,
314  IN BOOLEAN Pin,
315  OUT PBCB *Bcb,
316  OUT PVOID *Buffer,
318  )
319 
320 /*++
321 
322 Routine Description:
323 
324  This routine is called when the specified range of sectors is to be
325  read into the cache. If the desired range falls beyond the current
326  cache mapping, the fat will be searched, and if the desired range can
327  be satisfied, the cache mapping will be extended and the MCB updated
328  accordingly.
329 
330 Arguments:
331 
332  Dcb - Pointer to the DCB for the directory
333 
334  StartingVbo - The virtual offset of the first desired byte
335 
336  ByteCount - Number of bytes desired
337 
338  Pin - Tells us if we should pin instead of just mapping.
339 
340  Bcb - Returns a pointer to the BCB which is valid until unpinned
341 
342  Buffer - Returns a pointer to the sectors, which is valid until unpinned
343 
344  Status - Returns the status of the operation.
345 
346 --*/
347 
348 {
350 
351  PAGED_CODE();
352 
353  DebugTrace(+1, Dbg, "FatReadDirectoryFile\n", 0);
354  DebugTrace( 0, Dbg, "Dcb = %p\n", Dcb);
355  DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo);
356  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
357 
358  //
359  // Check for the zero case
360  //
361 
362  if (ByteCount == 0) {
363 
364  DebugTrace(0, Dbg, "Nothing to read\n", 0);
365 
366  *Bcb = NULL;
367  *Buffer = NULL;
369 
370  DebugTrace(-1, Dbg, "FatReadDirectoryFile -> VOID\n", 0);
371  return;
372  }
373 
374  //
375  // If we need to create a directory file and initialize the
376  // cachemap, do so.
377  //
378 
379  FatOpenDirectoryFile( IrpContext, Dcb );
380 
381  //
382  // Now if the transfer is beyond the allocation size return EOF.
383  //
384 
385  if (StartingVbo >= Dcb->Header.AllocationSize.LowPart) {
386 
387  DebugTrace(0, Dbg, "End of file read for directory\n", 0);
388 
389  *Bcb = NULL;
390  *Buffer = NULL;
392 
393  DebugTrace(-1, Dbg, "FatReadDirectoryFile -> VOID\n", 0);
394  return;
395  }
396 
397  //
398  // If the caller is trying to read past the EOF, truncate the
399  // read.
400  //
401 
402  ByteCount = (Dcb->Header.AllocationSize.LowPart - StartingVbo < ByteCount) ?
403  Dcb->Header.AllocationSize.LowPart - StartingVbo : ByteCount;
404 
405  NT_ASSERT( ByteCount != 0 );
406 
407  //
408  // Call the Cache manager to attempt the transfer.
409  //
410 
411  Vbo.QuadPart = StartingVbo;
412 
413  if (Pin ?
414 
415  !CcPinRead( Dcb->Specific.Dcb.DirectoryFile,
416  &Vbo,
417  ByteCount,
418  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
419  Bcb,
420  Buffer )
421  :
422 
423  !CcMapData( Dcb->Specific.Dcb.DirectoryFile,
424  &Vbo,
425  ByteCount,
426  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
427  Bcb,
428  Buffer ) ) {
429 
430  //
431  // Could not read the data without waiting (cache miss).
432  //
433 
434  *Bcb = NULL;
435  *Buffer = NULL;
436  FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
437  }
438 
439  DbgDoit( IrpContext->PinCount += 1 )
440 
442 
443  DebugTrace(-1, Dbg, "FatReadDirectoryFile -> VOID, *BCB = %p\n", *Bcb);
444 
445  return;
446 }
447 
448 
449 _Requires_lock_held_(_Global_critical_region_)
450 VOID
451 FatPrepareWriteDirectoryFile (
452  IN PIRP_CONTEXT IrpContext,
453  IN PDCB Dcb,
456  OUT PBCB *Bcb,
457  OUT PVOID *Buffer,
458  IN BOOLEAN Zero,
461  )
462 
463 /*++
464 
465 Routine Description:
466 
467  This routine first looks to see if the specified range of sectors
468  is already in the cache. If so, it increments the BCB PinCount,
469  sets the BCB dirty, and returns TRUE with the location of the sectors.
470 
471  The IrpContext->Flags .. Wait == TRUE/FALSE actions of this routine are identical to
472  FatPrepareWriteVolumeFile() above.
473 
474 Arguments:
475 
476  Dcb - Pointer to the DCB for the directory
477 
478  StartingVbo - The virtual offset of the first byte to be written
479 
480  ByteCount - Number of bytes to be written
481 
482  Bcb - Returns a pointer to the BCB which is valid until unpinned
483 
484  Buffer - Returns a pointer to the sectors, which is valid until unpinned
485 
486  Zero - Supplies TRUE if the specified range of bytes should be zeroed
487 
488  Reversible - Supplies TRUE if the specified range of modification should
489  be repinned so that the operation can be reversed in a controlled
490  fashion if errors are encountered.
491 
492  Status - Returns the status of the operation.
493 
494 --*/
495 
496 {
498  ULONG InitialAllocation = 0;
499  BOOLEAN UnwindWeAllocatedDiskSpace = FALSE;
500  PBCB LocalBcb = NULL;
501  PVOID LocalBuffer = NULL;
502  ULONG InitialRequest = ByteCount;
503  ULONG MappingGranularity = PAGE_SIZE;
504 
505  PAGED_CODE();
506 
507  DebugTrace(+1, Dbg, "FatPrepareWriteDirectoryFile\n", 0);
508  DebugTrace( 0, Dbg, "Dcb = %p\n", Dcb);
509  DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", (ULONG)StartingVbo);
510  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
511  DebugTrace( 0, Dbg, "Zero = %08lx\n", Zero);
512 
513  *Bcb = NULL;
514  *Buffer = NULL;
515 
516  //
517  // If we need to create a directory file and initialize the
518  // cachemap, do so.
519  //
520 
521  FatOpenDirectoryFile( IrpContext, Dcb );
522 
523  //
524  // If the transfer is beyond the allocation size we need to
525  // extend the directory's allocation. The call to
526  // AddFileAllocation will raise a condition if
527  // it runs out of disk space. Note that the root directory
528  // cannot be extended.
529  //
530 
531  Vbo.QuadPart = StartingVbo;
532 
533  _SEH2_TRY {
534 
535  if (StartingVbo + ByteCount > Dcb->Header.AllocationSize.LowPart) {
536 
537  if (NodeType(Dcb) == FAT_NTC_ROOT_DCB &&
538  !FatIsFat32(Dcb->Vcb)) {
539 
540  FatRaiseStatus( IrpContext, STATUS_DISK_FULL );
541  }
542 
543  DebugTrace(0, Dbg, "Try extending normal directory\n", 0);
544 
545  InitialAllocation = Dcb->Header.AllocationSize.LowPart;
546 
547  FatAddFileAllocation( IrpContext,
548  Dcb,
549  Dcb->Specific.Dcb.DirectoryFile,
551 
552  UnwindWeAllocatedDiskSpace = TRUE;
553 
554  //
555  // Inform the cache manager of the new allocation
556  //
557 
558  Dcb->Header.FileSize.LowPart =
559  Dcb->Header.AllocationSize.LowPart;
560 
561  CcSetFileSizes( Dcb->Specific.Dcb.DirectoryFile,
562  (PCC_FILE_SIZES)&Dcb->Header.AllocationSize );
563 
564  //
565  // Set up the Bitmap buffer if it is not big enough already
566  //
567 
568  FatCheckFreeDirentBitmap( IrpContext, Dcb );
569 
570  //
571  // The newly allocated clusters should be zeroed starting at
572  // the previous allocation size
573  //
574 
575  Zero = TRUE;
576  Vbo.QuadPart = InitialAllocation;
577  ByteCount = Dcb->Header.AllocationSize.LowPart - InitialAllocation;
578  }
579 
580  while (ByteCount > 0) {
581 
582  ULONG BytesToPin;
583 
584  LocalBcb = NULL;
585 
586  //
587  // We must pin in terms of pages below the boundary of the initial request.
588  // Once we pass the end of the request, we are free to expand the pin size to
589  // VACB_MAPPING_GRANULARITY. This will prevent Cc from returning OBCBs
590  // and hence will prevent bugchecks when we then attempt to repin one, yet
591  // allow us to be more efficient by pinning in 256KB chunks instead of 4KB pages.
592  //
593 
594  if (Vbo.QuadPart > StartingVbo + InitialRequest) {
595 
596  MappingGranularity = VACB_MAPPING_GRANULARITY;
597  }
598 
599  //
600  // If the first and final byte are both described by the same page, pin
601  // the entire range. Note we pin in pages to prevent cache manager from
602  // returning OBCBs, which would result in a bugcheck on CcRepinBcb.
603  //
604 
605  if ((Vbo.QuadPart / MappingGranularity) ==
606  ((Vbo.QuadPart + ByteCount - 1) / MappingGranularity)) {
607 
608  BytesToPin = ByteCount;
609 
610  } else {
611 
612  BytesToPin = MappingGranularity -
613  ((ULONG)Vbo.QuadPart & (MappingGranularity - 1));
614  }
615 
616  if (!CcPinRead( Dcb->Specific.Dcb.DirectoryFile,
617  &Vbo,
618  BytesToPin,
619  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
620  &LocalBcb,
621  &LocalBuffer )) {
622 
623  //
624  // Could not read the data without waiting (cache miss).
625  //
626 
627  FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
628  }
629 
630  //
631  // Update our caller with the beginning of their request.
632  //
633 
634  if (*Buffer == NULL) {
635 
636  *Buffer = LocalBuffer;
637  *Bcb = LocalBcb;
638  }
639 
640  DbgDoit( IrpContext->PinCount += 1 )
641 
642  if (Zero) {
643 
644  //
645  // We set this guy dirty right now so that we can raise CANT_WAIT when
646  // it needs to be done. It'd be beautiful if we could noop the read IO
647  // since we know we don't care about it.
648  //
649 
650  RtlZeroMemory( LocalBuffer, BytesToPin );
651  CcSetDirtyPinnedData( LocalBcb, NULL );
652  }
653 
654  ByteCount -= BytesToPin;
655  Vbo.QuadPart += BytesToPin;
656 
657  if (*Bcb != LocalBcb) {
658 
659  FatRepinBcb( IrpContext, LocalBcb );
660  FatUnpinBcb( IrpContext, LocalBcb );
661  }
662  }
663 
664  //
665  // This lets us get the data pinned until we complete the request
666  // and writes the dirty bit through to the disk.
667  //
668 
669  FatSetDirtyBcb( IrpContext, *Bcb, Dcb->Vcb, Reversible );
670 
672 
673  } _SEH2_FINALLY {
674 
675  DebugUnwind( FatPrepareWriteDirectoryFile );
676 
678 
679  //
680  // Make sure we unpin the buffers.
681  //
682 
683  if (*Bcb != LocalBcb) {
684 
685  FatUnpinBcb( IrpContext, LocalBcb );
686  }
687 
688  FatUnpinBcb(IrpContext, *Bcb);
689 
690  //
691  // These steps are carefully arranged - FatTruncateFileAllocation can raise.
692  // Make sure we unpin the buffer. If FTFA raises, the effect should be benign.
693  //
694 
695  if (UnwindWeAllocatedDiskSpace == TRUE) {
696 
697  //
698  // Inform the cache manager of the change.
699  //
700 
701  FatTruncateFileAllocation( IrpContext, Dcb, InitialAllocation );
702 
703  Dcb->Header.FileSize.LowPart =
704  Dcb->Header.AllocationSize.LowPart;
705 
706  CcSetFileSizes( Dcb->Specific.Dcb.DirectoryFile,
707  (PCC_FILE_SIZES)&Dcb->Header.AllocationSize );
708  }
709  }
710 
711  DebugTrace(-1, Dbg, "FatPrepareWriteDirectoryFile -> (VOID), *Bcb = %p\n", *Bcb);
712  } _SEH2_END;
713 
714  return;
715 }
716 
717 
718 #if DBG
719 BOOLEAN FatDisableParentCheck = 0;
720 
721 BOOLEAN
722 FatIsCurrentOperationSynchedForDcbTeardown (
723  IN PIRP_CONTEXT IrpContext,
724  IN PDCB Dcb
725  )
726 {
727  PIRP Irp = IrpContext->OriginatingIrp;
729  PVCB Vcb;
730  PFCB Fcb;
731  PCCB Ccb;
732 
733  PFILE_OBJECT ToCheck[3];
734  ULONG Index = 0;
735 
736  PAGED_CODE();
737 
738  //
739  // While mounting, we're OK without having to own anything.
740  //
741 
744 
745  return TRUE;
746  }
747 
748  //
749  // With the Vcb held, the close path is blocked out.
750  //
751 
752  if (ExIsResourceAcquiredSharedLite( &Dcb->Vcb->Resource ) ||
753  ExIsResourceAcquiredExclusiveLite( &Dcb->Vcb->Resource )) {
754 
755  return TRUE;
756  }
757 
758  //
759  // Accept this assertion at face value. It comes from GetDirentForFcbOrDcb,
760  // and is reliable.
761  //
762 
763  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_PARENT_BY_CHILD )) {
764 
765  return TRUE;
766  }
767 
768  //
769  // Determine which fileobjects are around on this operation.
770  //
771 
772  if (Stack->MajorFunction == IRP_MJ_SET_INFORMATION &&
773  Stack->Parameters.SetFile.FileObject) {
774 
775  ToCheck[Index++] = Stack->Parameters.SetFile.FileObject;
776  }
777 
778  if (Stack->FileObject) {
779 
780  ToCheck[Index++] = Stack->FileObject;
781  }
782 
783  ToCheck[Index] = NULL;
784 
785  //
786  // If the fileobjects we have are for this dcb or a child of it, we are
787  // also guaranteed that this dcb isn't going anywhere (even without
788  // the Vcb).
789  //
790 
791  for (Index = 0; ToCheck[Index] != NULL; Index++) {
792 
793  (VOID) FatDecodeFileObject( ToCheck[Index], &Vcb, &Fcb, &Ccb );
794 
795  while ( Fcb ) {
796 
797  if (Fcb == Dcb) {
798 
799  return TRUE;
800  }
801 
802  Fcb = Fcb->ParentDcb;
803  }
804  }
805 
806  return FatDisableParentCheck;
807 }
808 #endif // DBG
809 
810 _Requires_lock_held_(_Global_critical_region_)
811 VOID
812 FatOpenDirectoryFile (
813  IN PIRP_CONTEXT IrpContext,
814  IN PDCB Dcb
815  )
816 
817 /*++
818 
819 Routine Description:
820 
821  This routine opens a new directory file if one is not already open.
822 
823 Arguments:
824 
825  Dcb - Pointer to the DCB for the directory
826 
827 Return Value:
828 
829  None.
830 
831 --*/
832 
833 {
834  PAGED_CODE();
835 
836  DebugTrace(+1, Dbg, "FatOpenDirectoryFile\n", 0);
837  DebugTrace( 0, Dbg, "Dcb = %p\n", Dcb);
838 
839  //
840  // If we don't have some hold on this Dcb (there are several ways), there is nothing
841  // to prevent child files from closing and tearing this branch of the tree down in the
842  // midst of our slapping this reference onto it.
843  //
844  // I really wish we had a proper Fcb synchronization model (like CDFS/UDFS/NTFS).
845  //
846 
847  NT_ASSERT( FatIsCurrentOperationSynchedForDcbTeardown( IrpContext, Dcb ));
848 
849  //
850  // If we haven't yet set the correct AllocationSize, do so.
851  //
852 
853  if (Dcb->Header.AllocationSize.QuadPart == FCB_LOOKUP_ALLOCATIONSIZE_HINT) {
854 
855  FatLookupFileAllocationSize( IrpContext, Dcb );
856 
857  Dcb->Header.FileSize.LowPart =
858  Dcb->Header.AllocationSize.LowPart;
859  }
860 
861  //
862  // Setup the Bitmap buffer if it is not big enough already
863  //
864 
865  FatCheckFreeDirentBitmap( IrpContext, Dcb );
866 
867  //
868  // Check if we need to create a directory file.
869  //
870  // We first do a spot check and then synchronize and check again.
871  //
872 
873  if (Dcb->Specific.Dcb.DirectoryFile == NULL) {
874 
875  PFILE_OBJECT DirectoryFileObject = NULL;
876 
878 
879  _SEH2_TRY {
880 
881  if (Dcb->Specific.Dcb.DirectoryFile == NULL) {
882 
883  PDEVICE_OBJECT RealDevice;
884 
885  //
886  // Create the special file object for the directory file, and set
887  // up its pointers back to the Dcb and the section object pointer.
888  // Note that setting the DirectoryFile pointer in the Dcb has
889  // to be the last thing done.
890  //
891  // Preallocate a close context since we have no Ccb for this object.
892  //
893 
894  RealDevice = Dcb->Vcb->CurrentDevice;
895 
896  DirectoryFileObject = IoCreateStreamFileObject( NULL, RealDevice );
898 
899  FatSetFileObject( DirectoryFileObject,
901  Dcb,
902  NULL );
903 
904  //
905  // Remember this internal open.
906  //
907 
908  InterlockedIncrement( (LONG*)&(Dcb->Vcb->InternalOpenCount) );
909 
910  //
911  // If this is the root directory, it is also a residual open.
912  //
913 
914  if (NodeType( Dcb ) == FAT_NTC_ROOT_DCB) {
915 
916  InterlockedIncrement( (LONG*)&(Dcb->Vcb->ResidualOpenCount) );
917  }
918 
919  DirectoryFileObject->SectionObjectPointer = &Dcb->NonPaged->SectionObjectPointers;
920 
921  DirectoryFileObject->ReadAccess = TRUE;
922  DirectoryFileObject->WriteAccess = TRUE;
923  DirectoryFileObject->DeleteAccess = TRUE;
924 
925  InterlockedIncrement( (LONG*)&Dcb->Specific.Dcb.DirectoryFileOpenCount );
926 
927  Dcb->Specific.Dcb.DirectoryFile = DirectoryFileObject;
928 
929  //
930  // Indicate we're happy with the fileobject now.
931  //
932 
933  DirectoryFileObject = NULL;
934  }
935 
936  } _SEH2_FINALLY {
937 
939 
940  //
941  // Rip the object up if we couldn't get the close context.
942  //
943 
944  if (DirectoryFileObject) {
945 
946  ObDereferenceObject( DirectoryFileObject );
947  }
948  } _SEH2_END;
949  }
950 
951  //
952  // Finally check if we need to initialize the Cache Map for the
953  // directory file. The size of the section we are going to map
954  // the current allocation size for the directory. Note that the
955  // cache manager will provide syncronization for us.
956  //
957 
958  if ( Dcb->Specific.Dcb.DirectoryFile->PrivateCacheMap == NULL ) {
959 
960  Dcb->Header.ValidDataLength = FatMaxLarge;
961  Dcb->ValidDataToDisk = MAXULONG;
962 
963  FatInitializeCacheMap( Dcb->Specific.Dcb.DirectoryFile,
964  (PCC_FILE_SIZES)&Dcb->Header.AllocationSize,
965  TRUE,
967  Dcb );
968  }
969 
970  DebugTrace(-1, Dbg, "FatOpenDirectoryFile -> VOID\n", 0);
971 
972  return;
973 }
974 
975 
976 
977 
980  IN PIRP_CONTEXT IrpContext,
981  IN PFCB EaFcb
982  )
983 
984 /*++
985 
986 Routine Description:
987 
988  This routine opens the Ea file.
989 
990 Arguments:
991 
992  EaFcb - Pointer to the Fcb for the Ea file.
993 
994 Return Value:
995 
996  Pointer to the new file object.
997 
998 --*/
999 
1000 {
1001  PFILE_OBJECT EaFileObject = NULL;
1002  PDEVICE_OBJECT RealDevice;
1003 
1004  PAGED_CODE();
1005 
1006  DebugTrace(+1, Dbg, "FatOpenEaFile\n", 0);
1007  DebugTrace( 0, Dbg, "EaFcb = %p\n", EaFcb);
1008 
1009  //
1010  // Create the special file object for the ea file, and set
1011  // up its pointers back to the Fcb and the section object pointer
1012  //
1013 
1014  RealDevice = EaFcb->Vcb->CurrentDevice;
1015 
1016  EaFileObject = IoCreateStreamFileObject( NULL, RealDevice );
1017 
1018  _SEH2_TRY {
1019 
1020  FatPreallocateCloseContext( IrpContext->Vcb);
1021 
1022  FatSetFileObject( EaFileObject,
1023  EaFile,
1024  EaFcb,
1025  NULL );
1026 
1027  //
1028  // Remember this internal, residual open.
1029  //
1030 
1031  InterlockedIncrement( (LONG*)&(EaFcb->Vcb->InternalOpenCount) );
1032  InterlockedIncrement( (LONG*)&(EaFcb->Vcb->ResidualOpenCount) );
1033 
1034  EaFileObject->SectionObjectPointer = &EaFcb->NonPaged->SectionObjectPointers;
1035 
1036  EaFileObject->ReadAccess = TRUE;
1037  EaFileObject->WriteAccess = TRUE;
1038 
1039  //
1040  // Finally check if we need to initialize the Cache Map for the
1041  // ea file. The size of the section we are going to map
1042  // the current allocation size for the Fcb.
1043  //
1044 
1045  EaFcb->Header.ValidDataLength = FatMaxLarge;
1046 
1047  FatInitializeCacheMap( EaFileObject,
1048  (PCC_FILE_SIZES)&EaFcb->Header.AllocationSize,
1049  TRUE,
1051  EaFcb );
1052 
1053  CcSetAdditionalCacheAttributes( EaFileObject, TRUE, TRUE );
1054 
1055  } _SEH2_FINALLY {
1056 
1057  //
1058  // Drop the fileobject if we're raising. Two cases: couldn't get
1059  // the close context, and it is still an UnopenedFileObject, or
1060  // we lost trying to build the cache map - in which case we're
1061  // OK for the close context if we have to.
1062  //
1063 
1064  if (_SEH2_AbnormalTermination()) {
1065 
1066  ObDereferenceObject( EaFileObject );
1067  }
1068  } _SEH2_END;
1069 
1070  DebugTrace(-1, Dbg, "FatOpenEaFile -> %p\n", EaFileObject);
1071 
1072  UNREFERENCED_PARAMETER( IrpContext );
1073 
1074  return EaFileObject;
1075 }
1076 
1077 
1078 VOID
1080  IN PIRP_CONTEXT IrpContext,
1081  IN PVCB Vcb,
1082  IN BOOLEAN FlushFirst
1083  )
1084 
1085 /*++
1086 
1087 Routine Description:
1088 
1089  This routine shuts down the ea file. Usually this is required when the volume
1090  begins to leave the system: after verify, dismount, deletion, pnp.
1091 
1092 Arguments:
1093 
1094  Vcb - the volume to close the ea file on
1095 
1096  FlushFirst - whether the file should be flushed
1097 
1098 Return Value:
1099 
1100  None. As a side effect, the EA fileobject in the Vcb is cleared.
1101 
1102  Caller must have the Vcb exclusive.
1103 
1104 --*/
1105 
1106 {
1107  PFILE_OBJECT EaFileObject = Vcb->VirtualEaFile;
1108 
1109  PAGED_CODE();
1110 
1111  DebugTrace(+1, Dbg, "FatCloseEaFile\n", 0);
1112  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb);
1113 
1114  NT_ASSERT( FatVcbAcquiredExclusive(IrpContext, Vcb) );
1115 
1116  if (EaFileObject != NULL) {
1117 
1118  EaFileObject = Vcb->VirtualEaFile;
1119 
1120  if (FlushFirst) {
1121 
1122  CcFlushCache( Vcb->VirtualEaFile->SectionObjectPointer, NULL, 0, NULL );
1123  }
1124 
1125  Vcb->VirtualEaFile = NULL;
1126 
1127  //
1128  // Empty the Mcb for the Ea file.
1129  //
1130 
1131  FatRemoveMcbEntry( Vcb, &Vcb->EaFcb->Mcb, 0, 0xFFFFFFFF );
1132 
1133  //
1134  // Uninitialize the cache for this file object and dereference it.
1135  //
1136 
1137  FatSyncUninitializeCacheMap( IrpContext, EaFileObject );
1138 
1139  ObDereferenceObject( EaFileObject );
1140  }
1141 
1142  DebugTrace(-1, Dbg, "FatCloseEaFile -> %p\n", EaFileObject);
1143 }
1144 
1145 
1146 _Requires_lock_held_(_Global_critical_region_)
1147 VOID
1148 FatSetDirtyBcb (
1149  IN PIRP_CONTEXT IrpContext,
1150  IN PBCB Bcb,
1151  IN PVCB Vcb OPTIONAL,
1153  )
1154 
1155 /*++
1156 
1157 Routine Description:
1158 
1159  This routine saves a reference to the bcb in the irp context and
1160  sets the bcb dirty. This will have the affect of keeping the page in
1161  memory until we complete the request
1162 
1163  In addition, a DPC is set to fire in 5 seconds (or if one is pending,
1164  pushed back 5 seconds) to mark the volume clean.
1165 
1166 Arguments:
1167 
1168  Bcb - Supplies the Bcb being set dirty
1169 
1170  Vcb - Supplies the volume being marked dirty
1171 
1172  Reversible - Supplies TRUE if the specified range of bcb should be repinned
1173  so that the changes can be reversed in a controlled fashion if errors
1174  are encountered.
1175 
1176 Return Value:
1177 
1178  None.
1179 
1180 --*/
1181 
1182 {
1183  DebugTrace(+1, Dbg, "FatSetDirtyBcb\n", 0 );
1184  DebugTrace( 0, Dbg, "IrpContext = %p\n", IrpContext );
1185  DebugTrace( 0, Dbg, "Bcb = %p\n", Bcb );
1186  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
1187 
1188  //
1189  // Repin the bcb as required
1190  //
1191 
1192  if (Reversible) {
1193 
1194  FatRepinBcb( IrpContext, Bcb );
1195  }
1196 
1197  //
1198  // Set the bcb dirty
1199  //
1200 
1202 
1203  //
1204  // If volume dirtying isn't disabled for this operation (for
1205  // instance, when we're changing the dirty state), set the
1206  // volume dirty if we were given a Vcb that we want to perform
1207  // clean volume processing on, and return.
1208  //
1209  // As a historical note, we used to key off of the old floppy
1210  // (now deferred flush) bit to disable dirtying behavior. Since
1211  // hotpluggable media can still be yanked while operations are
1212  // in flight, recognize that its really the case that FAT12
1213  // doesn't have the dirty bit.
1214  //
1215 
1216  if ( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_DIRTY) &&
1217  ARGUMENT_PRESENT(Vcb) &&
1218  !FatIsFat12(Vcb)) {
1219 
1220  KIRQL SavedIrql;
1221 
1222  BOOLEAN SetTimer;
1223 
1224  LARGE_INTEGER TimeSincePreviousCall;
1225  LARGE_INTEGER CurrentTime;
1226 
1227  //
1228  // "Borrow" the irp context spinlock.
1229  //
1230 
1231  KeQuerySystemTime( &CurrentTime );
1232 
1233  KeAcquireSpinLock( &FatData.GeneralSpinLock, &SavedIrql );
1234 
1235  TimeSincePreviousCall.QuadPart =
1236  CurrentTime.QuadPart - Vcb->LastFatMarkVolumeDirtyCall.QuadPart;
1237 
1238  //
1239  // If more than one second has elapsed since the prior call
1240  // to here, bump the timer up again and see if we need to
1241  // physically mark the volume dirty.
1242  //
1243 
1244  if ( (TimeSincePreviousCall.HighPart != 0) ||
1245  (TimeSincePreviousCall.LowPart > (1000 * 1000 * 10)) ) {
1246 
1247  SetTimer = TRUE;
1248 
1249  } else {
1250 
1251  SetTimer = FALSE;
1252  }
1253 
1254  KeReleaseSpinLock( &FatData.GeneralSpinLock, SavedIrql );
1255 
1256  if ( SetTimer ) {
1257 
1258  LARGE_INTEGER CleanVolumeTimer;
1259 
1260  //
1261  // We use a shorter volume clean timer for hot plug volumes.
1262  //
1263 
1264  CleanVolumeTimer.QuadPart = FlagOn( Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH)
1265  ? (LONG)-1500*1000*10
1266  : (LONG)-8*1000*1000*10;
1267 
1268  (VOID)KeCancelTimer( &Vcb->CleanVolumeTimer );
1269  (VOID)KeRemoveQueueDpc( &Vcb->CleanVolumeDpc );
1270 
1271  //
1272  // We have now synchronized with anybody clearing the dirty
1273  // flag, so we can now see if we really have to actually write
1274  // out the physical bit.
1275  //
1276 
1277  if ( !FlagOn(Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DIRTY) ) {
1278 
1279  //
1280  // We want to really mark the volume dirty now.
1281  //
1282 
1283  if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
1284 
1285  FatMarkVolume( IrpContext, Vcb, VolumeDirty );
1286  }
1287 
1288  SetFlag( Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DIRTY );
1289 
1290  //
1291  // Lock the volume if it is removable.
1292  //
1293 
1294  if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA)) {
1295 
1296  FatToggleMediaEjectDisable( IrpContext, Vcb, TRUE );
1297  }
1298  }
1299 
1300  KeAcquireSpinLock( &FatData.GeneralSpinLock, &SavedIrql );
1301 
1302  KeQuerySystemTime( &Vcb->LastFatMarkVolumeDirtyCall );
1303 
1304  KeReleaseSpinLock( &FatData.GeneralSpinLock, SavedIrql );
1305 
1306  KeSetTimer( &Vcb->CleanVolumeTimer,
1307  CleanVolumeTimer,
1308  &Vcb->CleanVolumeDpc );
1309  }
1310  }
1311 
1312  DebugTrace(-1, Dbg, "FatSetDirtyBcb -> VOID\n", 0 );
1313 }
1314 
1315 
1316 VOID
1318  IN PIRP_CONTEXT IrpContext,
1319  IN PBCB Bcb
1320  )
1321 
1322 /*++
1323 
1324 Routine Description:
1325 
1326  This routine saves a reference to the bcb in the irp context. This will
1327  have the affect of keeping the page in memory until we complete the
1328  request
1329 
1330 Arguments:
1331 
1332  Bcb - Supplies the Bcb being referenced
1333 
1334 Return Value:
1335 
1336  None.
1337 
1338 --*/
1339 
1340 {
1341  PREPINNED_BCBS Repinned;
1342  ULONG i;
1343 
1344  PAGED_CODE();
1345 
1346  DebugTrace(+1, Dbg, "FatRepinBcb\n", 0 );
1347  DebugTrace( 0, Dbg, "IrpContext = %p\n", IrpContext );
1348  DebugTrace( 0, Dbg, "Bcb = %p\n", Bcb );
1349 
1350  //
1351  // The algorithm is to search the list of repinned records until
1352  // we either find a match for the bcb or we find a null slot.
1353  //
1354 
1355  Repinned = &IrpContext->Repinned;
1356 
1357  while (TRUE) {
1358 
1359  //
1360  // For every entry in the repinned record check if the bcb's
1361  // match or if the entry is null. If the bcb's match then
1362  // we've done because we've already repinned this bcb, if
1363  // the entry is null then we know, because it's densely packed,
1364  // that the bcb is not in the list so add it to the repinned
1365  // record and repin it.
1366  //
1367 
1368  for (i = 0; i < REPINNED_BCBS_ARRAY_SIZE; i += 1) {
1369 
1370  if (Repinned->Bcb[i] == Bcb) {
1371 
1372  DebugTrace(-1, Dbg, "FatRepinBcb -> VOID\n", 0 );
1373  return;
1374  }
1375 
1376  if (Repinned->Bcb[i] == NULL) {
1377 
1378  Repinned->Bcb[i] = Bcb;
1379  CcRepinBcb( Bcb );
1380 
1381  DebugTrace(-1, Dbg, "FatRepinBcb -> VOID\n", 0 );
1382  return;
1383  }
1384  }
1385 
1386  //
1387  // We finished checking one repinned record so now locate the next
1388  // repinned record, If there isn't one then allocate and zero out
1389  // a new one.
1390  //
1391 
1392  if (Repinned->Next == NULL) {
1393 
1395  sizeof(REPINNED_BCBS),
1396  TAG_REPINNED_BCB );
1397 
1398  RtlZeroMemory( Repinned->Next, sizeof(REPINNED_BCBS) );
1399  }
1400 
1401  Repinned = Repinned->Next;
1402  }
1403 }
1404 
1405 
1406 VOID
1408  IN PIRP_CONTEXT IrpContext
1409  )
1410 
1411 /*++
1412 
1413 Routine Description:
1414 
1415  This routine frees all of the repinned bcbs, stored in an IRP context.
1416 
1417 Arguments:
1418 
1419 Return Value:
1420 
1421  None.
1422 
1423 --*/
1424 
1425 {
1426  IO_STATUS_BLOCK RaiseIosb;
1427  PREPINNED_BCBS Repinned;
1428  BOOLEAN WriteThroughToDisk;
1430  BOOLEAN ForceVerify = FALSE;
1431  ULONG i;
1432  PFCB FcbOrDcb = NULL;
1433 
1434  PAGED_CODE();
1435 
1436  DebugTrace(+1, Dbg, "FatUnpinRepinnedBcbs\n", 0 );
1437  DebugTrace( 0, Dbg, "IrpContext = %p\n", IrpContext );
1438 
1439  //
1440  // The algorithm for this procedure is to scan the entire list of
1441  // repinned records unpinning any repinned bcbs. We start off
1442  // with the first record in the irp context, and while there is a
1443  // record to scan we do the following loop.
1444  //
1445 
1446  Repinned = &IrpContext->Repinned;
1447  RaiseIosb.Status = STATUS_SUCCESS;
1448 
1449  //
1450  // WinSE bug #307418 "Occasional data corruption when
1451  // standby/resume while copying files to removable FAT
1452  // formatted media".
1453  // Extract main FCB pointer from the irp context - we
1454  // will need it later to detect new file creation operation.
1455  //
1456 
1457  if (IrpContext->MajorFunction == IRP_MJ_CREATE &&
1458  IrpContext->OriginatingIrp != NULL) {
1460 
1461  IrpSp = IoGetCurrentIrpStackLocation( IrpContext->OriginatingIrp );
1462 
1463  if (IrpSp != NULL &&
1464  IrpSp->FileObject != NULL &&
1465  IrpSp->FileObject->FsContext != NULL) {
1466 
1467  FcbOrDcb = IrpSp->FileObject->FsContext;
1468  }
1469  }
1470 
1471  //
1472  // If the request is write through or the media is deferred flush,
1473  // unpin the bcb's write through.
1474  //
1475 
1476  WriteThroughToDisk = (BOOLEAN) (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH) &&
1477  IrpContext->Vcb != NULL &&
1478  (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH) ||
1479  FlagOn(IrpContext->Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH)));
1480 
1481  while (Repinned != NULL) {
1482 
1483  //
1484  // For every non-null entry in the repinned record unpin the
1485  // repinned entry.
1486  //
1487  // If the this is removable media (therefore all requests write-
1488  // through) and the write fails, purge the cache so that we throw
1489  // away the modifications as we will be returning an error to the
1490  // user.
1491  //
1492 
1493  for (i = 0; i < REPINNED_BCBS_ARRAY_SIZE; i += 1) {
1494 
1495  if (Repinned->Bcb[i] != NULL) {
1496 
1498 
1499  if (WriteThroughToDisk &&
1500  FlagOn(IrpContext->Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH)) {
1501 
1502  FileObject = CcGetFileObjectFromBcb( Repinned->Bcb[i] );
1503  }
1504 
1505  CcUnpinRepinnedBcb( Repinned->Bcb[i],
1506  WriteThroughToDisk,
1507  &Iosb );
1508 
1509  if (!NT_SUCCESS(Iosb.Status)) {
1510 
1511  if (RaiseIosb.Status == STATUS_SUCCESS) {
1512 
1513  RaiseIosb = Iosb;
1514  }
1515 
1516  //
1517  // If this was a writethrough device, purge the cache,
1518  // except for Irp major codes that either don't handle
1519  // the error paths correctly or are simple victims like
1520  // cleanup.c.
1521  //
1522 
1523  if (FileObject &&
1524  (IrpContext->MajorFunction != IRP_MJ_CLEANUP) &&
1525  (IrpContext->MajorFunction != IRP_MJ_FLUSH_BUFFERS) &&
1526  (IrpContext->MajorFunction != IRP_MJ_SET_INFORMATION)
1527 
1528  &&
1529 
1530  //
1531  // WinSE bug #307418 "Occasional data corruption when
1532  // standby/resume while copying files to removable FAT
1533  // formatted media".
1534  // Buffer unpinning for new file creation operation can
1535  // be interrupted by system syspend. As a result some BCBs
1536  // will be successfully written to the disk while others will
1537  // be kicked back with STATUS_VERIFY_REQUIRED. Since there is
1538  // is still a chance for the failed BCBs to reach the disk
1539  // after the volume verification we'll not purge them.
1540  // Instead FatCommonCreate() will unroll the file creation
1541  // changes for these pages.
1542  //
1543 
1544  !(IrpContext->MajorFunction == IRP_MJ_CREATE &&
1545  Iosb.Status == STATUS_VERIFY_REQUIRED &&
1546  FcbOrDcb != NULL &&
1547  NodeType( FcbOrDcb ) == FAT_NTC_FCB)) {
1548 
1549  //
1550  // The call to CcPurgeCacheSection() below will
1551  // purge the entire file from memory. It will also
1552  // block until all the file's BCB's are pinned.
1553  //
1554  // We end up in a deadlock situation of there
1555  // are any other pinned BCB's in this IRP context
1556  // so the first thing we do is search the list
1557  // for BCB's pinned in the same file and unpin
1558  // them.
1559  //
1560  // We are probably not going to lose data because
1561  // it's safe to assume that all flushes will
1562  // fail after the first one fails.
1563  //
1564 
1565  ULONG j;
1566  ULONG k = i + 1;
1567  PREPINNED_BCBS RepinnedToPurge = Repinned;
1568 
1569  while( RepinnedToPurge != NULL ) {
1570 
1571  for (j = k; j < REPINNED_BCBS_ARRAY_SIZE; j++) {
1572 
1573  if (RepinnedToPurge->Bcb[j] != NULL) {
1574 
1575  if (CcGetFileObjectFromBcb( RepinnedToPurge->Bcb[j] ) == FileObject) {
1576 
1577  CcUnpinRepinnedBcb( RepinnedToPurge->Bcb[j],
1578  FALSE,
1579  &Iosb );
1580 
1581  RepinnedToPurge->Bcb[j] = NULL;
1582  }
1583  }
1584  }
1585 
1586  RepinnedToPurge = RepinnedToPurge->Next;
1587  k = 0;
1588  }
1589 
1590  CcPurgeCacheSection( FileObject->SectionObjectPointer,
1591  NULL,
1592  0,
1593  FALSE );
1594 
1595  //
1596  // Force a verify operation here since who knows
1597  // what state things are in.
1598  //
1599 
1600  ForceVerify = TRUE;
1601  }
1602  }
1603 
1604  Repinned->Bcb[i] = NULL;
1605 
1606  }
1607  }
1608 
1609  //
1610  // Now find the next repinned record in the list, and possibly
1611  // delete the one we've just processed.
1612  //
1613 
1614  if (Repinned != &IrpContext->Repinned) {
1615 
1616  PREPINNED_BCBS Saved;
1617 
1618  Saved = Repinned->Next;
1619  ExFreePool( Repinned );
1620  Repinned = Saved;
1621 
1622  } else {
1623 
1624  Repinned = Repinned->Next;
1625  IrpContext->Repinned.Next = NULL;
1626  }
1627  }
1628 
1629  //
1630  // Now if we weren't completely successful in the our unpin
1631  // then raise the iosb we got
1632  //
1633 
1634  if (!NT_SUCCESS(RaiseIosb.Status)) {
1635 
1636  if (ForceVerify && FileObject) {
1637 
1638  SetFlag(FileObject->DeviceObject->Flags, DO_VERIFY_VOLUME);
1639 
1640  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1641  FileObject->DeviceObject );
1642  }
1643 
1644  if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_RAISE )) {
1645  if (IrpContext->OriginatingIrp) {
1646  IrpContext->OriginatingIrp->IoStatus = RaiseIosb;
1647  }
1648  FatNormalizeAndRaiseStatus( IrpContext, RaiseIosb.Status );
1649  }
1650  }
1651 
1652  DebugTrace(-1, Dbg, "FatUnpinRepinnedBcbs -> VOID\n", 0 );
1653 
1654  return;
1655 }
1656 
1657 
1658 FINISHED
1660  IN PIRP_CONTEXT IrpContext,
1661  IN PVCB Vcb,
1663  IN ULONG StartingZero,
1665  )
1666 
1667 /*++
1668 
1669  **** Temporary function - Remove when CcZeroData is capable of handling
1670  non sector aligned requests.
1671 
1672 --*/
1673 {
1674 #ifndef __REACTOS__
1675  LARGE_INTEGER ZeroStart = {0,0};
1676  LARGE_INTEGER BeyondZeroEnd = {0,0};
1677 #else
1678  LARGE_INTEGER ZeroStart = {.LowPart = 0, .HighPart = 0};
1679  LARGE_INTEGER BeyondZeroEnd = {.LowPart = 0, .HighPart = 0};
1680 #endif
1681 
1682  ULONG SectorSize;
1683 
1684  BOOLEAN Finished;
1685 
1686  PAGED_CODE();
1687 
1688  SectorSize = (ULONG)Vcb->Bpb.BytesPerSector;
1689 
1690  ZeroStart.LowPart = (StartingZero + (SectorSize - 1)) & ~(SectorSize - 1);
1691 
1692  //
1693  // Detect overflow if we were asked to zero in the last sector of the file,
1694  // which must be "zeroed" already (or we're in trouble).
1695  //
1696 
1697  if (StartingZero != 0 && ZeroStart.LowPart == 0) {
1698 
1699  return TRUE;
1700  }
1701 
1702  //
1703  // Note that BeyondZeroEnd can take the value 4gb.
1704  //
1705 
1706  BeyondZeroEnd.QuadPart = ((ULONGLONG) StartingZero + ByteCount + (SectorSize - 1))
1707  & (~((LONGLONG) SectorSize - 1));
1708 
1709  //
1710  // If we were called to just zero part of a sector we are in trouble.
1711  //
1712 
1713  if ( ZeroStart.QuadPart == BeyondZeroEnd.QuadPart ) {
1714 
1715  return TRUE;
1716  }
1717 
1718  Finished = CcZeroData( FileObject,
1719  &ZeroStart,
1720  &BeyondZeroEnd,
1721  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
1722 
1723  return Finished;
1724 }
1725 
1726 
1727 NTSTATUS
1729  IN PIRP_CONTEXT IrpContext,
1730  IN PIRP Irp
1731  )
1732 
1733 /*++
1734 
1735 Routine Description:
1736 
1737  This routine performs the function of completing Mdl read and write
1738  requests. It should be called only from FatFsdRead and FatFsdWrite.
1739 
1740 Arguments:
1741 
1742  Irp - Supplies the originating Irp.
1743 
1744 Return Value:
1745 
1746  NTSTATUS - Will always be STATUS_PENDING or STATUS_SUCCESS.
1747 
1748 --*/
1749 
1750 {
1753 
1754  PAGED_CODE();
1755 
1756  DebugTrace(+1, Dbg, "FatCompleteMdl\n", 0 );
1757  DebugTrace( 0, Dbg, "IrpContext = %p\n", IrpContext );
1758  DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
1759 
1760  //
1761  // Do completion processing.
1762  //
1763 
1765 
1766  switch( IrpContext->MajorFunction ) {
1767 
1768  case IRP_MJ_READ:
1769 
1770  CcMdlReadComplete( FileObject, Irp->MdlAddress );
1771  break;
1772 
1773  case IRP_MJ_WRITE:
1774 
1776 
1777  NT_ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ));
1778 
1779  CcMdlWriteComplete( FileObject, &IrpSp->Parameters.Write.ByteOffset, Irp->MdlAddress );
1780 
1781  Irp->IoStatus.Status = STATUS_SUCCESS;
1782 
1783  break;
1784 
1785  default:
1786 
1787  DebugTrace( DEBUG_TRACE_ERROR, 0, "Illegal Mdl Complete.\n", 0);
1788 #ifdef _MSC_VER
1789 #pragma prefast( suppress: 28159, "we're very broken if we get here" )
1790 #endif
1791  FatBugCheck( IrpContext->MajorFunction, 0, 0 );
1792  }
1793 
1794  //
1795  // Mdl is now deallocated.
1796  //
1797 
1798  Irp->MdlAddress = NULL;
1799 
1800  //
1801  // Complete the request and exit right away.
1802  //
1803 
1804  FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
1805 
1806  DebugTrace(-1, Dbg, "FatCompleteMdl -> STATUS_SUCCESS\n", 0 );
1807 
1808  return STATUS_SUCCESS;
1809 }
1810 
1811 VOID
1813  IN PIRP_CONTEXT IrpContext,
1815  )
1816 
1817 /*++
1818 
1819 Routine Description:
1820 
1821  The routine performs a CcUnitializeCacheMap to LargeZero synchronously. That
1822  is it waits on the Cc event. This call is useful when we want to be certain
1823  when a close will actually some in.
1824 
1825 Return Value:
1826 
1827  None.
1828 
1829 --*/
1830 
1831 {
1832  CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent;
1833  NTSTATUS WaitStatus;
1834 
1835  UNREFERENCED_PARAMETER( IrpContext );
1836 
1837  PAGED_CODE();
1838 
1839  KeInitializeEvent( &UninitializeCompleteEvent.Event,
1841  FALSE);
1842 
1844  &FatLargeZero,
1845  &UninitializeCompleteEvent );
1846 
1847  //
1848  // Now wait for the cache manager to finish purging the file.
1849  // This will garentee that Mm gets the purge before we
1850  // delete the Vcb.
1851  //
1852 
1853 #ifdef _MSC_VER
1854 #pragma prefast( suppress: 28931, "we use WaitStatus in the debug assert, in fre builds prefast complains it's unused" )
1855 #endif
1856  WaitStatus = KeWaitForSingleObject( &UninitializeCompleteEvent.Event,
1857  Executive,
1858  KernelMode,
1859  FALSE,
1860  NULL);
1861 
1862  NT_ASSERT(WaitStatus == STATUS_SUCCESS);
1863 }
1864 
1865 VOID
1867  IN PIRP_CONTEXT IrpContext,
1868  IN PDCB Dcb,
1869  IN VBO StartingVbo,
1870  IN ULONG ByteCount,
1871  OUT PBCB *Bcb
1872  )
1873 
1874 /*++
1875 
1876 Routine Description:
1877 
1878  This routine pins data that was previously mapped before setting it dirty.
1879 
1880 Arguments:
1881 
1882  Dcb - Pointer to the DCB for the directory
1883 
1884  StartingVbo - The virtual offset of the first desired byte
1885 
1886  ByteCount - Number of bytes desired
1887 
1888  Bcb - Returns a pointer to the BCB which is valid until unpinned
1889 
1890 --*/
1891 
1892 {
1894 
1895  PAGED_CODE();
1896 
1897  DebugTrace(+1, Dbg, "FatPinMappedData\n", 0);
1898  DebugTrace( 0, Dbg, "Dcb = %p\n", Dcb);
1899  DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo);
1900  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
1901 
1902  //
1903  // Call the Cache manager to perform the operation.
1904  //
1905 
1906  Vbo.QuadPart = StartingVbo;
1907 
1908  if (!CcPinMappedData( Dcb->Specific.Dcb.DirectoryFile,
1909  &Vbo,
1910  ByteCount,
1911  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
1912  Bcb )) {
1913 
1914  //
1915  // Could not pin the data without waiting (cache miss).
1916  //
1917 
1918  FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
1919  }
1920 
1921  DebugTrace(-1, Dbg, "FatReadDirectoryFile -> VOID, *BCB = %p\n", *Bcb);
1922 
1923  return;
1924 }
1925 
1926 #if (NTDDI_VERSION >= NTDDI_WIN8)
1927 
1928 NTSTATUS
1930  IN PIRP_CONTEXT IrpContext,
1932  IN ULONG StartingPage,
1933  IN ULONG PageCount
1934  )
1935 {
1936  IO_PRIORITY_INFO PriorityInformation = {0};
1937  MM_PREFETCH_FLAGS PrefetchFlags;
1938  ULONG PageNo;
1939  NTSTATUS Status;
1940 
1941  PREAD_LIST ReadList = NULL;
1942 
1943  UNREFERENCED_PARAMETER( IrpContext );
1944 
1945  PAGED_CODE();
1946 
1947  //
1948  // Succeed zero page prefetch requests.
1949  //
1950 
1951  if (PageCount == 0) {
1952 
1953  return STATUS_SUCCESS;
1954  }
1955 
1956  //
1957  // Mm's prefetch API's "only" support fetching a ULONG worth of pages.
1958  // Make sure we don't overflow.
1959  //
1960 
1961  ASSERT( PageCount < (PFN_NUMBER)MAXULONG );
1962 
1963  IoInitializePriorityInfo( &PriorityInformation );
1964 
1965  Status = IoRetrievePriorityInfo( IrpContext->OriginatingIrp,
1966  FileObject,
1967  IrpContext->OriginatingIrp->Tail.Overlay.Thread,
1968  &PriorityInformation );
1969 
1970  if (!NT_SUCCESS( Status)) {
1971 
1972  goto Cleanup;
1973  }
1974 
1975  ReadList = ExAllocatePoolWithTag( PagedPool,
1976  FIELD_OFFSET( READ_LIST, List ) + PageCount * sizeof( FILE_SEGMENT_ELEMENT ),
1977  ' taF' );
1978 
1979  if (ReadList == NULL) {
1980 
1982  goto Cleanup;
1983  }
1984 
1985  //
1986  // Call Mm to prefetch data.
1987  //
1988 
1989  ReadList->FileObject = FileObject;
1990  ReadList->IsImage = FALSE;
1991  ReadList->NumberOfEntries = PageCount;
1992 
1993  PrefetchFlags.AllFlags = 0;
1994  PrefetchFlags.Flags.Priority = PriorityInformation.PagePriority;
1995  PrefetchFlags.Flags.RepurposePriority = SYSTEM_PAGE_PRIORITY_LEVELS - 1;
1996  PrefetchFlags.Flags.PriorityProtection = 1;
1997  ReadList->List[0].Alignment = StartingPage * PAGE_SIZE;
1998  ReadList->List[0].Alignment |= PrefetchFlags.AllFlags;
1999 
2000  for (PageNo = 1; PageNo < PageCount; PageNo++) {
2001 
2002  ReadList->List[PageNo].Alignment = ReadList->List[PageNo-1].Alignment + PAGE_SIZE;
2003  }
2004 
2005  Status = MmPrefetchPages( 1, &ReadList );
2006 
2007 Cleanup:
2008 
2009  if (ReadList != NULL) {
2010 
2011  ExFreePoolWithTag( ReadList, ' taF' );
2012  }
2013 
2014  return Status;
2015 }
2016 #endif
2017 
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
_Requires_lock_held_(_Global_critical_region_)
Definition: cachesup.c:463
* PNTSTATUS
Definition: strlen.c:14
#define DbgDoit(X)
Definition: fatdata.h:336
#define FatReleaseDirectoryFileMutex(VCB)
Definition: fatprocs.h:1504
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:384
#define IN
Definition: typedefs.h:38
FatSetFileObject(FileObject, UserDirectoryOpen,(*Dcb), UnwindCcb=FatCreateCcb(IrpContext))
#define VCB_STATE_FLAG_VOLUME_DIRTY
Definition: fatstruc.h:557
VOID FatPreallocateCloseContext(IN PVCB Vcb)
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
VOID FatSyncUninitializeCacheMap(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject)
Definition: cachesup.c:1812
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2983
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:402
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:558
VOID FatRepinBcb(IN PIRP_CONTEXT IrpContext, IN PBCB Bcb)
Definition: cachesup.c:1317
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1237
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
#define IRP_MJ_FLUSH_BUFFERS
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 VCB_STATE_FLAG_DEFERRED_FLUSH
Definition: fatstruc.h:564
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: fatstruc.h:155
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2621
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
NTSTATUS FatPrefetchPages(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN ULONG StartingPage, IN ULONG PageCount)
Definition: cachesup.c:1929
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
LARGE_INTEGER FatLargeZero
Definition: fatdata.c:62
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
Definition: cdstruc.h:1073
ULONG32 VBO
Definition: fat.h:38
#define FatIsFat12(VCB)
Definition: fatprocs.h:1439
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:148
VOID FatReadVolumeFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb, OUT PVOID *Buffer)
Definition: cachesup.c:102
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:877
Definition: cdstruc.h:504
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define REPINNED_BCBS_ARRAY_SIZE
Definition: fatstruc.h:1456
static CC_FILE_SIZES FileSizes
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
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 _MM_PREFETCH_FLAGS::@3732 Flags
struct _FCB * ParentDcb
Definition: fatstruc.h:832
PFILE_OBJECT NTAPI CcGetFileObjectFromBcb(PVOID Bcb)
Definition: fssup.c:623
VOID FatPinMappedData(IN PIRP_CONTEXT IrpContext, IN PDCB Dcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb)
Definition: cachesup.c:1866
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define IRP_CONTEXT_FLAG_DISABLE_RAISE
Definition: fatstruc.h:1565
#define STATUS_END_OF_FILE
Definition: shellext.h:62
UCHAR KIRQL
Definition: env_spec_w32.h:591
IN PFCB FcbOrDcb
Definition: fatprocs.h:297
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG PFN_NUMBER
Definition: ke.h:8
#define TAG_REPINNED_BCB
Definition: nodetype.h:169
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:412
PFILE_OBJECT FileObject
Definition: mmtypes.h:186
#define Dbg
Definition: cachesup.c:29
long LONG
Definition: pedump.c:60
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN Reversible
Definition: fatprocs.h:402
VOID FatRemoveMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN ULONG SectorCount)
Definition: fsctrl.c:599
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:537
unsigned char BOOLEAN
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject, IN BOOLEAN DisableReadAhead, IN BOOLEAN DisableWriteBehind)
Definition: logsup.c:22
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
Definition: bufpool.h:45
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:556
FILE_SEGMENT_ELEMENT List[ANYSIZE_ARRAY]
Definition: mmtypes.h:189
#define CC_ENABLE_DISK_IO_ACCOUNTING
Definition: btrfs_drv.h:1783
NodeType
Definition: Node.h:5
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3186
#define FatAcquireDirectoryFileMutex(VCB)
Definition: fatprocs.h:1499
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4047
int64_t LONGLONG
Definition: typedefs.h:66
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3515
BOOLEAN NTAPI CcMapData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *BcbResult, OUT PVOID *Buffer)
Definition: pinsup.c:694
#define DebugUnwind(X)
Definition: fatdata.h:315
FAT_DATA FatData
Definition: fatdata.c:56
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
LIST_ENTRY List
Definition: psmgr.c:57
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
if(!(yy_init))
Definition: macro.lex.yy.c:714
VOID NTAPI CcUnpinRepinnedBcb(IN PVOID Bcb, IN BOOLEAN WriteThrough, OUT PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:343
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:415
return Iosb
Definition: create.c:4426
#define SYSTEM_PAGE_PRIORITY_LEVELS
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:193
uint64_t ULONGLONG
Definition: typedefs.h:65
#define ARGUMENT_PRESENT(ArgumentPointer)
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define Vcb
Definition: cdprocs.h:1425
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
static const UCHAR Index[8]
Definition: usbohci.c:18
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
FINISHED FatZeroData(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN ULONG StartingZero, IN ULONG ByteCount)
Definition: cachesup.c:1659
#define IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH
Definition: fatstruc.h:1557
* PFILE_OBJECT
Definition: iotypes.h:1954
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:802
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG PagePriority
Definition: iotypes.h:7100
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG NumberOfEntries
Definition: mmtypes.h:187
#define VOID
Definition: acefi.h:82
ULONG LowPart
Definition: typedefs.h:104
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
static const WCHAR Cleanup[]
Definition: register.c:80
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:402
#define FatIsFat32(VCB)
Definition: fatprocs.h:1437
#define IRP_CONTEXT_FLAG_PARENT_BY_CHILD
Definition: fatstruc.h:1574
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1060
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
LOGICAL IsImage
Definition: mmtypes.h:188
#define _In_
Definition: no_sal2.h:204
__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:2812
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
ULONGLONG Alignment
Definition: iotypes.h:5075
LARGE_INTEGER FatMaxLarge
Definition: fatdata.c:63
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:354
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
_SEH2_FINALLY
Definition: create.c:4395
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS FatCompleteMdl(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: cachesup.c:1728
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:402
struct _REPINNED_BCBS * Next
Definition: fatstruc.h:1464
PBCB Bcb[REPINNED_BCBS_ARRAY_SIZE]
Definition: fatstruc.h:1473
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
Definition: fatprocs.h:1486
#define VACB_MAPPING_GRANULARITY
#define IRP_MJ_CLEANUP
VOID FatCloseEaFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN FlushFirst)
Definition: cachesup.c:1079
PFILE_OBJECT FatOpenEaFile(IN PIRP_CONTEXT IrpContext, IN PFCB EaFcb)
Definition: cachesup.c:979
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define IRP_CONTEXT_FLAG_DISABLE_DIRTY
Definition: fatstruc.h:1554
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
unsigned int ULONG
Definition: retypes.h:1
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1658
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define FatRootDirectoryLbo(B)
Definition: fat.h:445
VOID NTAPI CcRepinBcb(IN PVOID Bcb)
Definition: cachesub.c:331
BOOLEAN FINISHED
Definition: fatprocs.h:95
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_In_ ULONG SectorSize
Definition: halfuncs.h:291
BOOLEAN NTAPI CcPinMappedData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, IN OUT PVOID *Bcb)
Definition: pinsup.c:774
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2725
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4157
int k
Definition: mpi.c:3369
IN PFCB IN VBO Vbo
Definition: fatprocs.h:297
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
NTSTATUS NTAPI MmPrefetchPages(IN ULONG NumberOfLists, IN PREAD_LIST *ReadLists)
Definition: mdlsup.c:1659
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:112
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
#define NT_ASSERT
Definition: rtlfuncs.h:3312
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks
Definition: fatstruc.h:156