ReactOS 0.4.16-dev-336-gb667d82
cachesup.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1990-2000 Microsoft Corporation
4
5Module Name:
6
7 cache.c
8
9Abstract:
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
34FatIsCurrentOperationSynchedForDcbTeardown (
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
61VOID
65 _In_ BOOLEAN PinAccess,
67 _In_ PVOID LazyWriteContext
68 )
69/*++
70
71Routine 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
85 PinAccess,
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
101VOID
103 IN PIRP_CONTEXT IrpContext,
104 IN PVCB Vcb,
107 OUT PBCB *Bcb,
109 )
110
111/*++
112
113Routine 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
124Arguments:
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_)
188VOID
189FatPrepareWriteVolumeFile (
190 IN PIRP_CONTEXT IrpContext,
191 IN PVCB Vcb,
194 OUT PBCB *Bcb,
198 )
199
200/*++
201
202Routine 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
216Arguments:
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_)
308VOID
309FatReadDirectoryFile (
310 IN PIRP_CONTEXT IrpContext,
311 IN PDCB Dcb,
314 IN BOOLEAN Pin,
315 OUT PBCB *Bcb,
318 )
319
320/*++
321
322Routine 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
330Arguments:
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_)
450VOID
451FatPrepareWriteDirectoryFile (
452 IN PIRP_CONTEXT IrpContext,
453 IN PDCB Dcb,
456 OUT PBCB *Bcb,
461 )
462
463/*++
464
465Routine 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
474Arguments:
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
719BOOLEAN FatDisableParentCheck = 0;
720
722FatIsCurrentOperationSynchedForDcbTeardown (
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
742 if (Stack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
743 Stack->MinorFunction == IRP_MN_MOUNT_VOLUME) {
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_)
811VOID
812FatOpenDirectoryFile (
813 IN PIRP_CONTEXT IrpContext,
814 IN PDCB Dcb
815 )
816
817/*++
818
819Routine Description:
820
821 This routine opens a new directory file if one is not already open.
822
823Arguments:
824
825 Dcb - Pointer to the DCB for the directory
826
827Return 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
986Routine Description:
987
988 This routine opens the Ea file.
989
990Arguments:
991
992 EaFcb - Pointer to the Fcb for the Ea file.
993
994Return 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
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
1078VOID
1080 IN PIRP_CONTEXT IrpContext,
1081 IN PVCB Vcb,
1082 IN BOOLEAN FlushFirst
1083 )
1084
1085/*++
1086
1087Routine 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
1092Arguments:
1093
1094 Vcb - the volume to close the ea file on
1095
1096 FlushFirst - whether the file should be flushed
1097
1098Return 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_)
1147VOID
1148FatSetDirtyBcb (
1149 IN PIRP_CONTEXT IrpContext,
1150 IN PBCB Bcb,
1153 )
1154
1155/*++
1156
1157Routine 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
1166Arguments:
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
1176Return 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) &&
1218 !FatIsFat12(Vcb)) {
1219
1220 KIRQL SavedIrql;
1221
1223
1224 LARGE_INTEGER TimeSincePreviousCall;
1225 LARGE_INTEGER CurrentTime;
1226
1227 //
1228 // "Borrow" the irp context spinlock.
1229 //
1230
1231 KeQuerySystemTime( &CurrentTime );
1232
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
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
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
1301
1302 KeQuerySystemTime( &Vcb->LastFatMarkVolumeDirtyCall );
1303
1305
1306 KeSetTimer( &Vcb->CleanVolumeTimer,
1307 CleanVolumeTimer,
1308 &Vcb->CleanVolumeDpc );
1309 }
1310 }
1311
1312 DebugTrace(-1, Dbg, "FatSetDirtyBcb -> VOID\n", 0 );
1313}
1314
1315
1316VOID
1318 IN PIRP_CONTEXT IrpContext,
1319 IN PBCB Bcb
1320 )
1321
1322/*++
1323
1324Routine 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
1330Arguments:
1331
1332 Bcb - Supplies the Bcb being referenced
1333
1334Return 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),
1397
1398 RtlZeroMemory( Repinned->Next, sizeof(REPINNED_BCBS) );
1399 }
1400
1401 Repinned = Repinned->Next;
1402 }
1403}
1404
1405
1406VOID
1408 IN PIRP_CONTEXT IrpContext
1409 )
1410
1411/*++
1412
1413Routine Description:
1414
1415 This routine frees all of the repinned bcbs, stored in an IRP context.
1416
1417Arguments:
1418
1419Return 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
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 = {{0,0}};
1679 LARGE_INTEGER BeyondZeroEnd = {{0,0}};
1680#endif
1681
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
1729 IN PIRP_CONTEXT IrpContext,
1730 IN PIRP Irp
1731 )
1732
1733/*++
1734
1735Routine 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
1740Arguments:
1741
1742 Irp - Supplies the originating Irp.
1743
1744Return 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
1811VOID
1813 IN PIRP_CONTEXT IrpContext,
1815 )
1816
1817/*++
1818
1819Routine 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
1825Return 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
1865VOID
1867 IN PIRP_CONTEXT IrpContext,
1868 IN PDCB Dcb,
1871 OUT PBCB *Bcb
1872 )
1873
1874/*++
1875
1876Routine Description:
1877
1878 This routine pins data that was previously mapped before setting it dirty.
1879
1880Arguments:
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
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;
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
2007Cleanup:
2008
2009 if (ReadList != NULL) {
2010
2011 ExFreePoolWithTag( ReadList, ' taF' );
2012 }
2013
2014 return Status;
2015}
2016#endif
2017
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
static CC_FILE_SIZES FileSizes
NodeType
Definition: Node.h:6
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
#define CC_ENABLE_DISK_IO_ACCOUNTING
Definition: btrfs_drv.h:1845
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
VOID NTAPI CcUnpinRepinnedBcb(IN PVOID Bcb, IN BOOLEAN WriteThrough, OUT PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:343
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
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
VOID NTAPI CcRepinBcb(IN PVOID Bcb)
Definition: cachesub.c:331
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
Definition: bufpool.h:45
#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:33
static const WCHAR Cleanup[]
Definition: register.c:80
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:878
#define NodeType(P)
Definition: nodetype.h:51
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
FatSetFileObject(FileObject, UserDirectoryOpen,(*Dcb), UnwindCcb=FatCreateCcb(IrpContext))
return Iosb
Definition: create.c:4402
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4140
#define FatRootDirectoryLbo(B)
Definition: fat.h:445
ULONG32 VBO
Definition: fat.h:38
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define FAT_NTC_FCB
Definition: nodetype.h:29
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define TAG_REPINNED_BCB
Definition: nodetype.h:169
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#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 DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1088
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
VOID FatCloseEaFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN FlushFirst)
Definition: cachesup.c:1079
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
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
VOID FatPinMappedData(IN PIRP_CONTEXT IrpContext, IN PDCB Dcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb)
Definition: cachesup.c:1866
FINISHED FatZeroData(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN ULONG StartingZero, IN ULONG ByteCount)
Definition: cachesup.c:1659
PFILE_OBJECT FatOpenEaFile(IN PIRP_CONTEXT IrpContext, IN PFCB EaFcb)
Definition: cachesup.c:979
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
NTSTATUS FatPrefetchPages(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN ULONG StartingPage, IN ULONG PageCount)
Definition: cachesup.c:1929
VOID FatSyncUninitializeCacheMap(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject)
Definition: cachesup.c:1812
#define Dbg
Definition: cachesup.c:29
VOID FatRepinBcb(IN PIRP_CONTEXT IrpContext, IN PBCB Bcb)
Definition: cachesup.c:1317
NTSTATUS FatCompleteMdl(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: cachesup.c:1728
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3495
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
LARGE_INTEGER FatMaxLarge
Definition: fatdata.c:63
LARGE_INTEGER FatLargeZero
Definition: fatdata.c:62
FAT_DATA FatData
Definition: fatdata.c:56
#define DbgDoit(X)
Definition: fatdata.h:336
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define DebugUnwind(X)
Definition: fatdata.h:315
@ VolumeDirty
Definition: fatprocs.h:1956
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
Definition: fatprocs.h:1496
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:415
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:547
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:413
#define FatAcquireDirectoryFileMutex(VCB)
Definition: fatprocs.h:1509
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
VOID FatPreallocateCloseContext(IN PVCB Vcb)
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2634
@ DirectoryFile
Definition: fatprocs.h:1047
@ EaFile
Definition: fatprocs.h:1048
#define FatIsFat12(VCB)
Definition: fatprocs.h:1449
#define FatReleaseDirectoryFileMutex(VCB)
Definition: fatprocs.h:1514
IN PFCB FcbOrDcb
Definition: fatprocs.h:307
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:428
VOID FatRemoveMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN ULONG SectorCount)
Definition: fsctrl.c:599
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:419
IN PFCB IN VBO Vbo
Definition: fatprocs.h:308
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2996
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2978
BOOLEAN FINISHED
Definition: fatprocs.h:105
#define FatIsFat32(VCB)
Definition: fatprocs.h:1447
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN Reversible
Definition: fatprocs.h:417
#define VCB_STATE_FLAG_VOLUME_DIRTY
Definition: fatstruc.h:561
#define IRP_CONTEXT_FLAG_PARENT_BY_CHILD
Definition: fatstruc.h:1582
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:560
#define IRP_CONTEXT_FLAG_DISABLE_RAISE
Definition: fatstruc.h:1573
#define VCB_STATE_FLAG_DEFERRED_FLUSH
Definition: fatstruc.h:568
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:562
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1241
#define IRP_CONTEXT_FLAG_DISABLE_DIRTY
Definition: fatstruc.h:1562
#define REPINNED_BCBS_ARRAY_SIZE
Definition: fatstruc.h:1464
#define IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH
Definition: fatstruc.h:1565
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
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:195
PFILE_OBJECT NTAPI CcGetFileObjectFromBcb(PVOID Bcb)
Definition: fssup.c:625
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:414
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
Status
Definition: gdiplustypes.h:25
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
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
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject, IN BOOLEAN DisableReadAhead, IN BOOLEAN DisableWriteBehind)
Definition: logsup.c:22
NTSTATUS NTAPI MmPrefetchPages(IN ULONG NumberOfLists, IN PREAD_LIST *ReadLists)
Definition: mdlsup.c:1850
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
* PNTSTATUS
Definition: strlen.c:14
int k
Definition: mpi.c:3369
#define KernelMode
Definition: asm.h:34
#define _In_
Definition: no_sal2.h:158
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define ARGUMENT_PRESENT(ArgumentPointer)
@ SynchronizationEvent
#define SYSTEM_PAGE_PRIORITY_LEVELS
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1624
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3187
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
#define Vcb
Definition: cdprocs.h:1415
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
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
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 _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: cdstruc.h:1067
CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks
Definition: fatstruc.h:160
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:152
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: fatstruc.h:159
Definition: cdstruc.h:902
struct _FCB * ParentDcb
Definition: fatstruc.h:836
ULONG PagePriority
Definition: iotypes.h:7457
union _IO_STACK_LOCATION::@1581 Parameters
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _IO_STACK_LOCATION::@3980::@3985 Write
PFILE_OBJECT FileObject
Definition: mmtypes.h:186
FILE_SEGMENT_ELEMENT List[ANYSIZE_ARRAY]
Definition: mmtypes.h:189
ULONG NumberOfEntries
Definition: mmtypes.h:187
LOGICAL IsImage
Definition: mmtypes.h:188
struct _REPINNED_BCBS * Next
Definition: fatstruc.h:1472
PBCB Bcb[REPINNED_BCBS_ARRAY_SIZE]
Definition: fatstruc.h:1481
Definition: cdstruc.h:498
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define MAXULONG
Definition: typedefs.h:251
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int64_t LONGLONG
Definition: typedefs.h:68
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONGLONG Alignment
Definition: iotypes.h:5432
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
struct _MM_PREFETCH_FLAGS::@4138 Flags
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define VACB_MAPPING_GRANULARITY
_In_ ULONG SectorSize
Definition: halfuncs.h:291
#define IRP_MJ_FILE_SYSTEM_CONTROL
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404
#define IRP_MJ_CLEANUP
@ Executive
Definition: ketypes.h:415
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NT_ASSERT
Definition: rtlfuncs.h:3327