ReactOS  0.4.15-dev-1054-gd029a62
strucsup.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  StrucSup.c
8 
9 Abstract:
10 
11  This module implements the Fat in-memory data structure manipulation
12  routines
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_STRUCSUP)
24 
25 //
26 // The debug trace level
27 //
28 
29 #define Dbg (DEBUG_TRACE_STRUCSUP)
30 
31 #define FillMemory(BUF,SIZ,MASK) { \
32  ULONG i; \
33  for (i = 0; i < (((SIZ)/4) - 1); i += 2) { \
34  ((PULONG)(BUF))[i] = (MASK); \
35  ((PULONG)(BUF))[i+1] = (ULONG)PsGetCurrentThread(); \
36  } \
37 }
38 
39 #define IRP_CONTEXT_HEADER (sizeof( IRP_CONTEXT ) * 0x10000 + FAT_NTC_IRP_CONTEXT)
40 
41 //
42 // Local macros.
43 //
44 // Define our lookaside list allocators. For the time being, and perhaps
45 // permanently, the paged structures don't come off of lookasides. This
46 // is due to complications with clean unload as FAT can be in the paging
47 // path, making it really hard to find the right time to empty them.
48 //
49 // Fortunately, the hit rates on the Fcb/Ccb lists weren't stunning.
50 //
51 
52 #define FAT_FILL_FREE 0
53 
54 INLINE
55 PCCB
57  )
58 {
59  return (PCCB) FsRtlAllocatePoolWithTag( PagedPool, sizeof(CCB), TAG_CCB );
60 }
61 
62 INLINE
63 VOID
65  IN PCCB Ccb
66  )
67 {
68 #if FAT_FILL_FREE
70 #endif
71 
72  ExFreePool( Ccb );
73 }
74 
75 INLINE
76 PFCB
78  )
79 {
80  return (PFCB) FsRtlAllocatePoolWithTag( PagedPool, sizeof(FCB), TAG_FCB );
81 }
82 
83 INLINE
84 VOID
86  IN PFCB Fcb
87  )
88 {
89 #if FAT_FILL_FREE
91 #endif
92 
93  ExFreePool( Fcb );
94 }
95 
96 #ifdef __REACTOS__
97 static
98 #endif
99 INLINE
102  )
103 {
104  return (PNON_PAGED_FCB) ExAllocateFromNPagedLookasideList( &FatNonPagedFcbLookasideList );
105 }
106 
107 #ifdef __REACTOS__
108 static
109 #endif
110 INLINE
111 VOID
113  PNON_PAGED_FCB NonPagedFcb
114  )
115 {
116 #if FAT_FILL_FREE
117  RtlFillMemoryUlong(NonPagedFcb, sizeof(NON_PAGED_FCB), FAT_FILL_FREE);
118 #endif
119 
120  ExFreeToNPagedLookasideList( &FatNonPagedFcbLookasideList, (PVOID) NonPagedFcb );
121 }
122 
123 #ifdef __REACTOS__
124 static
125 #endif
126 INLINE
129  )
130 {
132 
133  Resource = (PERESOURCE) ExAllocateFromNPagedLookasideList( &FatEResourceLookasideList );
134 
136 
137  return Resource;
138 }
139 
140 #ifdef __REACTOS__
141 static
142 #endif
143 INLINE
144 VOID
147  )
148 {
150 
151 #if FAT_FILL_FREE
153 #endif
154 
155  ExFreeToNPagedLookasideList( &FatEResourceLookasideList, (PVOID) Resource );
156 }
157 
158 #ifdef __REACTOS__
159 static
160 #endif
161 INLINE
164  )
165 {
166  return (PIRP_CONTEXT) ExAllocateFromNPagedLookasideList( &FatIrpContextLookasideList );
167 }
168 
169 #ifdef __REACTOS__
170 static
171 #endif
172 INLINE
173 VOID
175  IN PIRP_CONTEXT IrpContext
176  )
177 {
178 #if FAT_FILL_FREE
179  RtlFillMemoryUlong(IrpContext, sizeof(IRP_CONTEXT), FAT_FILL_FREE);
180 #endif
181 
182  ExFreeToNPagedLookasideList( &FatIrpContextLookasideList, (PVOID) IrpContext );
183 }
184 
185 #ifdef ALLOC_PRAGMA
186 #pragma alloc_text(PAGE, FatInitializeVcb)
187 #pragma alloc_text(PAGE, FatTearDownVcb)
188 #pragma alloc_text(PAGE, FatDeleteVcb)
189 #pragma alloc_text(PAGE, FatCreateRootDcb)
190 #pragma alloc_text(PAGE, FatCreateFcb)
191 #pragma alloc_text(PAGE, FatCreateDcb)
192 #pragma alloc_text(PAGE, FatDeleteFcb)
193 #pragma alloc_text(PAGE, FatCreateCcb)
194 #pragma alloc_text(PAGE, FatDeallocateCcbStrings)
195 #pragma alloc_text(PAGE, FatDeleteCcb)
196 #pragma alloc_text(PAGE, FatGetNextFcbTopDown)
197 #pragma alloc_text(PAGE, FatGetNextFcbBottomUp)
198 #pragma alloc_text(PAGE, FatConstructNamesInFcb)
199 #pragma alloc_text(PAGE, FatCheckFreeDirentBitmap)
200 #pragma alloc_text(PAGE, FatCreateIrpContext)
201 #pragma alloc_text(PAGE, FatDeleteIrpContext_Real)
202 #pragma alloc_text(PAGE, FatIsHandleCountZero)
203 #pragma alloc_text(PAGE, FatAllocateCloseContext)
204 #pragma alloc_text(PAGE, FatPreallocateCloseContext)
205 #pragma alloc_text(PAGE, FatEnsureStringBufferEnough)
206 #pragma alloc_text(PAGE, FatFreeStringBuffer)
207 #pragma alloc_text(PAGE, FatScanForDataTrack)
208 #endif
209 
210 
211 _Requires_lock_held_(_Global_critical_region_)
212 VOID
213 FatInitializeVcb (
214  IN PIRP_CONTEXT IrpContext,
215  IN OUT PVCB Vcb,
217  IN PVPB Vpb,
219  )
220 
221 /*++
222 
223 Routine Description:
224 
225  This routine initializes and inserts a new Vcb record into the in-memory
226  data structure. The Vcb record "hangs" off the end of the Volume device
227  object and must be allocated by our caller.
228 
229 Arguments:
230 
231  Vcb - Supplies the address of the Vcb record being initialized.
232 
233  TargetDeviceObject - Supplies the address of the target device object to
234  associate with the Vcb record.
235 
236  Vpb - Supplies the address of the Vpb to associate with the Vcb record.
237 
238  FsDeviceObject - The filesystem device object that the mount was directed
239  too.
240 
241 Return Value:
242 
243  None.
244 
245 --*/
246 
247 {
249  PDEVICE_OBJECT RealDevice;
250  ULONG i;
251 
252  STORAGE_HOTPLUG_INFO HotplugInfo;
253  STORAGE_DEVICE_NUMBER StorDeviceNumber;
255 
256  //
257  // The following variables are used for abnormal unwind
258  //
259 
260  PLIST_ENTRY UnwindEntryList = NULL;
261  PERESOURCE UnwindResource = NULL;
262  PERESOURCE UnwindResource2 = NULL;
263  PFILE_OBJECT UnwindFileObject = NULL;
264  PFILE_OBJECT UnwindCacheMap = NULL;
265  BOOLEAN UnwindWeAllocatedMcb = FALSE;
266  PFILE_SYSTEM_STATISTICS UnwindStatistics = NULL;
267  BOOLEAN UnwindWeAllocatedBadBlockMap = FALSE;
268  BOOLEAN CloseContextAllocated = FALSE;
269 
270  PAGED_CODE();
272 
273  DebugTrace(+1, Dbg, "FatInitializeVcb, Vcb = %p\n", Vcb);
274 
275  _SEH2_TRY {
276 
277  //
278  // We start by first zeroing out all of the VCB, this will guarantee
279  // that any stale data is wiped clean
280  //
281 
282  RtlZeroMemory( Vcb, sizeof(VCB) );
283 
284  //
285  // Set the proper node type code and node byte size
286  //
287 
288  Vcb->VolumeFileHeader.NodeTypeCode = FAT_NTC_VCB;
289  Vcb->VolumeFileHeader.NodeByteSize = sizeof(VCB);
290 
291  //
292  // Initialize the tunneling cache
293  //
294 
296 
297  //
298  // Insert this Vcb record on the FatData.VcbQueue
299  //
300 
301  NT_ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
302 
303 
304 #ifdef _MSC_VER
305 #pragma prefast( push )
306 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
307 #pragma prefast( disable: 28193, "this will always wait" )
308 #endif
309 
310  (VOID)FatAcquireExclusiveGlobal( IrpContext );
311 
312 #ifdef _MSC_VER
313 #pragma prefast( pop )
314 #endif
315 
316  InsertTailList( &FatData.VcbQueue, &Vcb->VcbLinks );
317  FatReleaseGlobal( IrpContext );
318  UnwindEntryList = &Vcb->VcbLinks;
319 
320  //
321  // Set the Target Device Object, Vpb, and Vcb State fields
322  //
323 
324 
326  Vcb->TargetDeviceObject = TargetDeviceObject;
327  Vcb->Vpb = Vpb;
328 
329  Vcb->CurrentDevice = Vpb->RealDevice;
330 
331  //
332  // Set the removable media and defflush flags based on the storage
333  // inquiry and the old characteristic bits.
334  //
335 
336  Status = FatPerformDevIoCtrl( IrpContext,
339  NULL,
340  0,
341  &HotplugInfo,
342  sizeof(HotplugInfo),
343  FALSE,
344  TRUE,
345  NULL );
346 
347  if (NT_SUCCESS( Status )) {
348 
349  if (HotplugInfo.MediaRemovable) {
350 
352  }
353 
354  //
355  // If the media or device is hot-pluggable, then set this flag.
356  //
357 
358  if (HotplugInfo.MediaHotplug || HotplugInfo.DeviceHotplug) {
359 
361  }
362 
363  if (!HotplugInfo.WriteCacheEnableOverride) {
364 
365  //
366  // If the device or media is hotplug and the override is not
367  // set, force defflush behavior for the device.
368  //
369 
370  if (HotplugInfo.MediaHotplug || HotplugInfo.DeviceHotplug) {
371 
373 
375 
376  //
377  // Now, for removables that claim to be lockable, lob a lock
378  // request and see if it works. There can unfortunately be
379  // transient, media dependent reasons that it can fail. If
380  // it does not, we must force defflush on.
381  //
382 
383  } else if (HotplugInfo.MediaRemovable &&
384  !HotplugInfo.MediaHotplug) {
385 
386  Status = FatToggleMediaEjectDisable( IrpContext, Vcb, TRUE );
387 
388  if (!NT_SUCCESS( Status )) {
389 
391 
392  }
393 
394  (VOID)FatToggleMediaEjectDisable( IrpContext, Vcb, FALSE );
395  }
396  }
397  }
398 
399  if (FlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) {
400 
402  }
403 
404  //
405  // Make sure we turn on deferred flushing for floppies like we always
406  // have.
407  //
408 
409  if (FlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) {
410 
412  }
413 
414  //
415  // Query the storage device number.
416  //
417 
418  Status = FatPerformDevIoCtrl( IrpContext,
421  NULL,
422  0,
423  &StorDeviceNumber,
424  sizeof(StorDeviceNumber),
425  FALSE,
426  TRUE,
427  NULL );
428 
429  if (NT_SUCCESS( Status )) {
430 
431  Vcb->DeviceNumber = StorDeviceNumber.DeviceNumber;
432 
433  } else {
434 
435  Vcb->DeviceNumber = (ULONG)(-1);
436  }
437 
439 
440  //
441  // Initialize the resource variable for the Vcb
442  //
443 
444  ExInitializeResourceLite( &Vcb->Resource );
445  UnwindResource = &Vcb->Resource;
446 
447  ExInitializeResourceLite( &Vcb->ChangeBitMapResource );
448  UnwindResource2 = &Vcb->ChangeBitMapResource;
449 
450  //
451  // Initialize the free cluster bitmap mutex.
452  //
453 
454  ExInitializeFastMutex( &Vcb->FreeClusterBitMapMutex );
455 
456  //
457  // Create the special file object for the virtual volume file with a close
458  // context, its pointers back to the Vcb and the section object pointer.
459  //
460  // We don't have to unwind the close context. That will happen in the close
461  // path automatically.
462  //
463 
464  RealDevice = Vcb->CurrentDevice;
465 
467  CloseContextAllocated = TRUE;
468 
469  Vcb->VirtualVolumeFile = UnwindFileObject = IoCreateStreamFileObject( NULL, RealDevice );
470 
471  FatSetFileObject( Vcb->VirtualVolumeFile,
473  Vcb,
474  NULL );
475 
476  //
477  // Remember this internal, residual open.
478  //
479 
480  InterlockedIncrement( (LONG*)&(Vcb->InternalOpenCount) );
481  InterlockedIncrement( (LONG*)&(Vcb->ResidualOpenCount) );
482 
483  Vcb->VirtualVolumeFile->SectionObjectPointer = &Vcb->SectionObjectPointers;
484 
485  Vcb->VirtualVolumeFile->ReadAccess = TRUE;
486  Vcb->VirtualVolumeFile->WriteAccess = TRUE;
487  Vcb->VirtualVolumeFile->DeleteAccess = TRUE;
488 
489  //
490  // Initialize the notify structures.
491  //
492 
493  InitializeListHead( &Vcb->DirNotifyList );
494 
495  FsRtlNotifyInitializeSync( &Vcb->NotifySync );
496 
497  //
498  // Initialize the Cache Map for the volume file. The size is
499  // initially set to that of our first read. It will be extended
500  // when we know how big the Fat is.
501  //
502 
506 
507  FatInitializeCacheMap( Vcb->VirtualVolumeFile,
508  &FileSizes,
509  TRUE,
511  Vcb );
512 
513  UnwindCacheMap = Vcb->VirtualVolumeFile;
514 
515  //
516  // Initialize the structure that will keep track of dirty fat sectors.
517  // The largest possible Mcb structures are less than 1K, so we use
518  // non paged pool.
519  //
520 
521  FsRtlInitializeLargeMcb( &Vcb->DirtyFatMcb, PagedPool );
522 
523  UnwindWeAllocatedMcb = TRUE;
524 
525  //
526  // Initialize the structure that will keep track of bad clusters on the volume.
527  //
528  // It will be empty until it is populated by FSCTL_GET_RETRIEVAL_POINTERS with a volume handle.
529  //
530 
531  FsRtlInitializeLargeMcb( &Vcb->BadBlockMcb, PagedPool );
532  UnwindWeAllocatedBadBlockMap = TRUE;
533 
534  //
535  // Set the cluster index hint to the first valid cluster of a fat: 2
536  //
537 
538  Vcb->ClusterHint = 2;
539 
540  //
541  // Initialize the directory stream file object creation event.
542  // This event is also "borrowed" for async non-cached writes.
543  //
544 
545  ExInitializeFastMutex( &Vcb->DirectoryFileCreationMutex );
546 
547  //
548  // Initialize the clean volume callback Timer and DPC.
549  //
550 
551  KeInitializeTimer( &Vcb->CleanVolumeTimer );
552 
553  KeInitializeDpc( &Vcb->CleanVolumeDpc, FatCleanVolumeDpc, Vcb );
554 
555  //
556  // Initialize the performance counters.
557  //
558 
559  Vcb->Statistics = FsRtlAllocatePoolWithTag( NonPagedPoolNx,
561  TAG_VCB_STATS );
562  UnwindStatistics = Vcb->Statistics;
563 
565 
566  for (i = 0; i < FatData.NumberProcessors; i += 1) {
567  Vcb->Statistics[i].Common.FileSystemType = FILESYSTEM_STATISTICS_TYPE_FAT;
568  Vcb->Statistics[i].Common.Version = 1;
569  Vcb->Statistics[i].Common.SizeOfCompleteStructure =
570  sizeof(FILE_SYSTEM_STATISTICS);
571  }
572 
573  //
574  // Pick up a VPB right now so we know we can pull this filesystem stack off
575  // of the storage stack on demand.
576  //
577 
578  Vcb->SwapVpb = FsRtlAllocatePoolWithTag( NonPagedPoolNx,
579  sizeof( VPB ),
580  TAG_VPB );
581 
582  RtlZeroMemory( Vcb->SwapVpb, sizeof( VPB ) );
583 
584  //
585  // Initialize the close queue listheads.
586  //
587 
588  InitializeListHead( &Vcb->AsyncCloseList );
589  InitializeListHead( &Vcb->DelayedCloseList );
590 
591  //
592  // Initialize the Advanced FCB Header
593  //
594 
595  ExInitializeFastMutex( &Vcb->AdvancedFcbHeaderMutex );
596  FsRtlSetupAdvancedHeader( &Vcb->VolumeFileHeader,
597  &Vcb->AdvancedFcbHeaderMutex );
598 
599 
600  //
601  // With the Vcb now set up, set the IrpContext Vcb field.
602  //
603 
604  IrpContext->Vcb = Vcb;
605 
606  } _SEH2_FINALLY {
607 
608  DebugUnwind( FatInitializeVcb );
609 
610  //
611  // If this is an abnormal termination then undo our work
612  //
613 
615 
616  if (UnwindCacheMap != NULL) { FatSyncUninitializeCacheMap( IrpContext, UnwindCacheMap ); }
617  if (UnwindFileObject != NULL) { ObDereferenceObject( UnwindFileObject ); }
618  if (UnwindResource != NULL) { FatDeleteResource( UnwindResource ); }
619  if (UnwindResource2 != NULL) { FatDeleteResource( UnwindResource2 ); }
620  if (UnwindWeAllocatedMcb) { FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb ); }
621  if (UnwindWeAllocatedBadBlockMap) { FsRtlUninitializeLargeMcb(&Vcb->BadBlockMcb ); }
622  if (UnwindEntryList != NULL) {
623 #ifdef _MSC_VER
624 #pragma prefast( suppress: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
625 #endif
626  (VOID)FatAcquireExclusiveGlobal( IrpContext );
627  RemoveEntryList( UnwindEntryList );
628  FatReleaseGlobal( IrpContext );
629  }
630  if (UnwindStatistics != NULL) { ExFreePool( UnwindStatistics ); }
631 
632  //
633  // Cleanup the close context we preallocated above.
634  //
635 
636  if (CloseContextAllocated && (Vcb->VirtualVolumeFile == NULL)) {
637 
638  //
639  // FatAllocateCloseContext does not allocate memory, it
640  // pulls a close context off the preallocated slist queue.
641  //
642  // Doing this here is necessary to balance out the one we
643  // preallocated for the Vcb earlier in this function, but
644  // only if we failed to create the virtual volume file.
645  //
646  // If VirtualVolumeFile is not NULL, then this CloseContext
647  // will get cleaned up when the close comes in for it during
648  // Vcb teardown.
649  //
650 
652 
653  ExFreePool( CloseContext );
654  CloseContextAllocated = FALSE;
655  }
656  }
657 
658  DebugTrace(-1, Dbg, "FatInitializeVcb -> VOID\n", 0);
659  } _SEH2_END;
660 
661  //
662  // and return to our caller
663  //
664 
665  UNREFERENCED_PARAMETER( IrpContext );
666 
667  return;
668 }
669 
670 
671 VOID
673  IN PIRP_CONTEXT IrpContext,
674  IN PVCB Vcb
675  )
676 
677 /*++
678 
679 Routine Description:
680 
681  This routine tries to remove all internal opens from the volume.
682 
683 Arguments:
684 
685  IrpContext - Supplies the context for the overall request.
686 
687  Vcb - Supplies the Vcb to be torn down.
688 
689 Return Value:
690 
691  None
692 
693 --*/
694 
695 {
696  PFILE_OBJECT DirectoryFileObject;
697 
698 
699  PAGED_CODE();
700 
701  //
702  // Get rid of the virtual volume file, if we need to.
703  //
704 
705  if (Vcb->VirtualVolumeFile != NULL) {
706 
707  //
708  // Uninitialize the cache
709  //
710 
711  CcUninitializeCacheMap( Vcb->VirtualVolumeFile,
712  &FatLargeZero,
713  NULL );
714 
715  FsRtlTeardownPerStreamContexts( &Vcb->VolumeFileHeader );
716 
717  ObDereferenceObject( Vcb->VirtualVolumeFile );
718 
719  Vcb->VirtualVolumeFile = NULL;
720  }
721 
722  //
723  // Close down the EA file.
724  //
725 
726  FatCloseEaFile( IrpContext, Vcb, FALSE );
727 
728  //
729  // Close down the root directory stream..
730  //
731 
732  if (Vcb->RootDcb != NULL) {
733 
734  DirectoryFileObject = Vcb->RootDcb->Specific.Dcb.DirectoryFile;
735 
736  if (DirectoryFileObject != NULL) {
737 
738  //
739  // Tear down this directory file.
740  //
741 
742  CcUninitializeCacheMap( DirectoryFileObject,
743  &FatLargeZero,
744  NULL );
745 
746  Vcb->RootDcb->Specific.Dcb.DirectoryFile = NULL;
747  ObDereferenceObject( DirectoryFileObject );
748  }
749  }
750 
751  //
752  // The VCB can no longer be used.
753  //
754 
756 }
757 
758 
759 VOID
761  IN PIRP_CONTEXT IrpContext,
762  IN PVCB Vcb
763  )
764 
765 /*++
766 
767 Routine Description:
768 
769  This routine removes the Vcb record from Fat's in-memory data
770  structures. It also will remove all associated underlings
771  (i.e., FCB records).
772 
773 Arguments:
774 
775  Vcb - Supplies the Vcb to be removed
776 
777 Return Value:
778 
779  None
780 
781 --*/
782 
783 {
784  PFCB Fcb;
785 
786  PAGED_CODE();
787 
788  DebugTrace(+1, Dbg, "FatDeleteVcb, Vcb = %p\n", Vcb);
789 
790  //
791  // If the IrpContext points to the VCB being deleted NULL out the stail
792  // pointer.
793  //
794 
795  if (IrpContext->Vcb == Vcb) {
796 
797  IrpContext->Vcb = NULL;
798 
799  }
800 
801  //
802  // Chuck the backpocket Vpb we kept just in case.
803  //
804 
805  if (Vcb->SwapVpb) {
806 
807  ExFreePool( Vcb->SwapVpb );
808 
809  }
810 
811  //
812  // Free the VPB, if we need to.
813  //
814 
815  if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VPB_MUST_BE_FREED )) {
816 
817  //
818  // We swapped the VPB, so we need to free the main one.
819  //
820 
821  ExFreePool( Vcb->Vpb );
822  }
823 
824  if (Vcb->VolumeGuidPath.Buffer) {
825  ExFreePool( Vcb->VolumeGuidPath.Buffer );
826  Vcb->VolumeGuidPath.Buffer = NULL;
827  }
828 
829  //
830  // Remove this record from the global list of all Vcb records.
831  // Note that the global lock must already be held when calling
832  // this function.
833  //
834 
835  RemoveEntryList( &(Vcb->VcbLinks) );
836 
837  //
838  // Make sure the direct access open count is zero, and the open file count
839  // is also zero.
840  //
841 
842  if ((Vcb->DirectAccessOpenCount != 0) || (Vcb->OpenFileCount != 0)) {
843 
844 #ifdef _MSC_VER
845 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
846 #endif
847  FatBugCheck( 0, 0, 0 );
848  }
849 
850  //
851  // Remove the EaFcb and dereference the Fcb for the Ea file if it
852  // exists.
853  //
854 
855  if (Vcb->EaFcb != NULL) {
856 
857  Vcb->EaFcb->OpenCount = 0;
858  FatDeleteFcb( IrpContext, &Vcb->EaFcb );
859  }
860 
861  //
862  // Remove the Root Dcb
863  //
864 
865  if (Vcb->RootDcb != NULL) {
866 
867  //
868  // Rundown stale child Fcbs that may be hanging around. Yes, this
869  // can happen. No, the create path isn't perfectly defensive about
870  // tearing down branches built up on creates that don't wind up
871  // succeeding. Normal system operation usually winds up having
872  // cleaned them out through re-visiting, but ...
873  //
874  // Just pick off Fcbs from the bottom of the tree until we run out.
875  // Then we delete the root Dcb.
876  //
877 
878  while( (Fcb = FatGetNextFcbBottomUp( IrpContext, NULL, Vcb->RootDcb )) != Vcb->RootDcb ) {
879 
880  FatDeleteFcb( IrpContext, &Fcb );
881  }
882 
883  FatDeleteFcb( IrpContext, &Vcb->RootDcb );
884  }
885 
886  //
887  // Uninitialize the notify sychronization object.
888  //
889 
890  FsRtlNotifyUninitializeSync( &Vcb->NotifySync );
891 
892  //
893  // Uninitialize the resource variable for the Vcb
894  //
895 
896  FatDeleteResource( &Vcb->Resource );
897  FatDeleteResource( &Vcb->ChangeBitMapResource );
898 
899  //
900  // If allocation support has been setup, free it.
901  //
902 
903  if (Vcb->FreeClusterBitMap.Buffer != NULL) {
904 
905  FatTearDownAllocationSupport( IrpContext, Vcb );
906  }
907 
908  //
909  // UnInitialize the Mcb structure that kept track of dirty fat sectors.
910  //
911 
912  FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb );
913 
914  //
915  // Uninitialize the Mcb structure that kept track of bad sectors.
916  //
917 
918  FsRtlUninitializeLargeMcb( &Vcb->BadBlockMcb );
919 
920  //
921  // Free the pool for the stached copy of the boot sector
922  //
923 
924  if ( Vcb->First0x24BytesOfBootSector ) {
925 
926  ExFreePool( Vcb->First0x24BytesOfBootSector );
927  Vcb->First0x24BytesOfBootSector = NULL;
928  }
929 
930  //
931  // Cancel the CleanVolume Timer and Dpc
932  //
933 
934  (VOID)KeCancelTimer( &Vcb->CleanVolumeTimer );
935 
936  (VOID)KeRemoveQueueDpc( &Vcb->CleanVolumeDpc );
937 
938  //
939  // Free the performance counters memory
940  //
941 
942  ExFreePool( Vcb->Statistics );
943 
944  //
945  // Clean out the tunneling cache
946  //
947 
948  FsRtlDeleteTunnelCache(&Vcb->Tunnel);
949 
950  //
951  // Dereference the target device object.
952  //
953 
954  ObDereferenceObject( Vcb->TargetDeviceObject );
955 
956  //
957  // We better have used all the close contexts we allocated. There could be
958  // one remaining if we're doing teardown due to a final close coming in on
959  // a directory file stream object. It will be freed on the way back up.
960  //
961 
962  NT_ASSERT( Vcb->CloseContextCount <= 1);
963 
964  //
965  // And zero out the Vcb, this will help ensure that any stale data is
966  // wiped clean
967  //
968 
969  RtlZeroMemory( Vcb, sizeof(VCB) );
970 
971  //
972  // return and tell the caller
973  //
974 
975  DebugTrace(-1, Dbg, "FatDeleteVcb -> VOID\n", 0);
976 
977  return;
978 }
979 
980 
981 _Requires_lock_held_(_Global_critical_region_)
982 VOID
983 FatCreateRootDcb (
984  IN PIRP_CONTEXT IrpContext,
985  IN PVCB Vcb
986  )
987 
988 /*++
989 
990 Routine Description:
991 
992  This routine allocates, initializes, and inserts a new root DCB record
993  into the in memory data structure.
994 
995 Arguments:
996 
997  Vcb - Supplies the Vcb to associate the new DCB under
998 
999 Return Value:
1000 
1001  None. The Vcb is modified in-place.
1002 
1003 --*/
1004 
1005 {
1006  PDCB Dcb = NULL;
1007 
1008  //
1009  // The following variables are used for abnormal unwind
1010  //
1011 
1012  PVOID UnwindStorage[2] = { NULL, NULL };
1013  PERESOURCE UnwindResource = NULL;
1014  PERESOURCE UnwindResource2 = NULL;
1015  PLARGE_MCB UnwindMcb = NULL;
1016  PFILE_OBJECT UnwindFileObject = NULL;
1017 
1018  PAGED_CODE();
1019 
1020  DebugTrace(+1, Dbg, "FatCreateRootDcb, Vcb = %p\n", Vcb);
1021 
1022  _SEH2_TRY {
1023 
1024  //
1025  // Make sure we don't already have a root dcb for this vcb
1026  //
1027 
1028  if (Vcb->RootDcb != NULL) {
1029 
1030  DebugDump("Error trying to create multiple root dcbs\n", 0, Vcb);
1031 #ifdef _MSC_VER
1032 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1033 #endif
1034  FatBugCheck( 0, 0, 0 );
1035  }
1036 
1037  //
1038  // Allocate a new DCB and zero it out, we use Dcb locally so we don't
1039  // have to continually reference through the Vcb
1040  //
1041 
1042  UnwindStorage[0] = Dcb = Vcb->RootDcb = FsRtlAllocatePoolWithTag( NonPagedPoolNx,
1043  sizeof(DCB),
1044  TAG_FCB );
1045 
1046  RtlZeroMemory( Dcb, sizeof(DCB));
1047 
1048  UnwindStorage[1] =
1049  Dcb->NonPaged = FatAllocateNonPagedFcb();
1050 
1051  RtlZeroMemory( Dcb->NonPaged, sizeof( NON_PAGED_FCB ) );
1052 
1053  //
1054  // Set the proper node type code, node byte size, and call backs
1055  //
1056 
1057  Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB;
1058  Dcb->Header.NodeByteSize = sizeof(DCB);
1059 
1060  Dcb->FcbCondition = FcbGood;
1061 
1062  //
1063  // The parent Dcb, initial state, open count, dirent location
1064  // information, and directory change count fields are already zero so
1065  // we can skip setting them
1066  //
1067 
1068  //
1069  // Initialize the resource variable
1070  //
1071 
1072  UnwindResource =
1073  Dcb->Header.Resource = FatAllocateResource();
1074 
1075  //
1076  // Initialize the PagingIo Resource. We no longer use the FsRtl common
1077  // shared pool because this led to a) deadlocks due to cases where files
1078  // and their parent directories shared a resource and b) there is no way
1079  // to anticipate inter-driver induced deadlock via recursive operation.
1080  //
1081 
1082  UnwindResource2 =
1083  Dcb->Header.PagingIoResource = FatAllocateResource();
1084 
1085  //
1086  // The root Dcb has an empty parent dcb links field
1087  //
1088 
1089  InitializeListHead( &Dcb->ParentDcbLinks );
1090 
1091  //
1092  // Set the Vcb
1093  //
1094 
1095  Dcb->Vcb = Vcb;
1096 
1097  //
1098  // initialize the parent dcb queue.
1099  //
1100 
1101  InitializeListHead( &Dcb->Specific.Dcb.ParentDcbQueue );
1102 
1103  //
1104  // Set the full file name up.
1105  //
1106 
1107  Dcb->FullFileName.Buffer = L"\\";
1108  Dcb->FullFileName.Length = (USHORT)2;
1109  Dcb->FullFileName.MaximumLength = (USHORT)4;
1110 
1111  Dcb->ShortName.Name.Oem.Buffer = "\\";
1112  Dcb->ShortName.Name.Oem.Length = (USHORT)1;
1113  Dcb->ShortName.Name.Oem.MaximumLength = (USHORT)2;
1114 
1115  //
1116  // Construct a lie about file properties since we don't
1117  // have a proper "." entry to look at.
1118  //
1119 
1120  Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY;
1121 
1122  //
1123  // Initialize Advanced FCB Header fields
1124  //
1125 
1126  ExInitializeFastMutex( &Dcb->NonPaged->AdvancedFcbHeaderMutex );
1127  FsRtlSetupAdvancedHeader( &Dcb->Header,
1128  &Dcb->NonPaged->AdvancedFcbHeaderMutex );
1129 
1130  //
1131  // Initialize the Mcb, and setup its mapping. Note that the root
1132  // directory is a fixed size so we can set it everything up now.
1133  //
1134 
1135  FsRtlInitializeLargeMcb( &Dcb->Mcb, NonPagedPoolNx );
1136  UnwindMcb = &Dcb->Mcb;
1137 
1138  if (FatIsFat32(Vcb)) {
1139 
1140  //
1141  // The first cluster of fat32 roots comes from the BPB
1142  //
1143 
1144  Dcb->FirstClusterOfFile = Vcb->Bpb.RootDirFirstCluster;
1145 
1146  } else {
1147 
1148  FatAddMcbEntry( Vcb, &Dcb->Mcb,
1149  0,
1150  FatRootDirectoryLbo( &Vcb->Bpb ),
1151  FatRootDirectorySize( &Vcb->Bpb ));
1152  }
1153 
1154  if (FatIsFat32(Vcb)) {
1155 
1156  //
1157  // Find the size of the fat32 root. As a side-effect, this will create
1158  // MCBs for the entire root. In the process of doing this, we may
1159  // discover that the FAT chain is bogus and raise corruption.
1160  //
1161 
1162  Dcb->Header.AllocationSize.LowPart = 0xFFFFFFFF;
1163  FatLookupFileAllocationSize( IrpContext, Dcb);
1164 
1165  Dcb->Header.FileSize.QuadPart =
1166  Dcb->Header.AllocationSize.QuadPart;
1167  } else {
1168 
1169  //
1170  // set the allocation size to real size of the root directory
1171  //
1172 
1173  Dcb->Header.FileSize.QuadPart =
1174  Dcb->Header.AllocationSize.QuadPart = FatRootDirectorySize( &Vcb->Bpb );
1175 
1176  }
1177 
1178  //
1179  // Set our two create dirent aids to represent that we have yet to
1180  // enumerate the directory for never used or deleted dirents.
1181  //
1182 
1183  Dcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
1184  Dcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;
1185 
1186  //
1187  // Setup the free dirent bitmap buffer.
1188  //
1189 
1190  RtlInitializeBitMap( &Dcb->Specific.Dcb.FreeDirentBitmap,
1191  NULL,
1192  0 );
1193 
1194  FatCheckFreeDirentBitmap( IrpContext, Dcb );
1195 
1196 #if (NTDDI_VERSION >= NTDDI_WIN8)
1197  //
1198  // Initialize the oplock structure.
1199  //
1200 
1202 #endif
1203 
1204  } _SEH2_FINALLY {
1205 
1206  DebugUnwind( FatCreateRootDcb );
1207 
1208  //
1209  // If this is an abnormal termination then undo our work
1210  //
1211 
1212  if (_SEH2_AbnormalTermination()) {
1213 
1214  ULONG i;
1215 
1216  if (UnwindFileObject != NULL) { ObDereferenceObject( UnwindFileObject ); }
1217  if (UnwindMcb != NULL) { FsRtlUninitializeLargeMcb( UnwindMcb ); }
1218  if (UnwindResource != NULL) { FatFreeResource( UnwindResource ); }
1219  if (UnwindResource2 != NULL) { FatFreeResource( UnwindResource2 ); }
1220 
1221  for (i = 0; i < sizeof(UnwindStorage)/sizeof(PVOID); i += 1) {
1222  if (UnwindStorage[i] != NULL) { ExFreePool( UnwindStorage[i] ); }
1223  }
1224 
1225  //
1226  // Re-zero the entry in the Vcb.
1227  //
1228 
1229  Vcb->RootDcb = NULL;
1230  }
1231 
1232  DebugTrace(-1, Dbg, "FatCreateRootDcb -> %p\n", Dcb);
1233  } _SEH2_END;
1234 
1235  return;
1236 }
1237 
1238 
1239 PFCB
1241  IN PIRP_CONTEXT IrpContext,
1242  IN PVCB Vcb,
1243  IN PDCB ParentDcb,
1244  IN ULONG LfnOffsetWithinDirectory,
1245  IN ULONG DirentOffsetWithinDirectory,
1246  IN PDIRENT Dirent,
1248  IN PUNICODE_STRING OrigLfn OPTIONAL,
1249  IN BOOLEAN IsPagingFile,
1250  IN BOOLEAN SingleResource
1251  )
1252 
1253 /*++
1254 
1255 Routine Description:
1256 
1257  This routine allocates, initializes, and inserts a new Fcb record into
1258  the in-memory data structures.
1259 
1260 Arguments:
1261 
1262  Vcb - Supplies the Vcb to associate the new FCB under.
1263 
1264  ParentDcb - Supplies the parent dcb that the new FCB is under.
1265 
1266  LfnOffsetWithinDirectory - Supplies the offset of the LFN. If there is
1267  no LFN associated with this file then this value is same as
1268  DirentOffsetWithinDirectory.
1269 
1270  DirentOffsetWithinDirectory - Supplies the offset, in bytes from the
1271  start of the directory file where the dirent for the fcb is located
1272 
1273  Dirent - Supplies the dirent for the fcb being created
1274 
1275  Lfn - Supplies a long UNICODE name associated with this file.
1276 
1277  IsPagingFile - Indicates if we are creating an FCB for a paging file
1278  or some other type of file.
1279 
1280  SingleResource - Indicates if this Fcb should share a single resource
1281  as both main and paging.
1282 
1283 Return Value:
1284 
1285  PFCB - Returns a pointer to the newly allocated FCB
1286 
1287 --*/
1288 
1289 {
1290  PFCB Fcb = NULL;
1292 
1293  //
1294  // The following variables are used for abnormal unwind
1295  //
1296 
1297  PVOID UnwindStorage[2] = { NULL, NULL };
1298  PERESOURCE UnwindResource = NULL;
1299  PERESOURCE UnwindResource2 = NULL;
1300  PLIST_ENTRY UnwindEntryList = NULL;
1301  PLARGE_MCB UnwindMcb = NULL;
1302  PFILE_LOCK UnwindFileLock = NULL;
1303  POPLOCK UnwindOplock = NULL;
1304 
1305  PAGED_CODE();
1306 
1307  UNREFERENCED_PARAMETER( OrigLfn );
1308 
1309  DebugTrace(+1, Dbg, "FatCreateFcb\n", 0);
1310 
1311  _SEH2_TRY {
1312 
1313  //
1314  // Determine the pool type we should be using for the fcb and the
1315  // mcb structure
1316  //
1317 
1318  if (IsPagingFile) {
1319 
1320  PoolType = NonPagedPoolNx;
1321  Fcb = UnwindStorage[0] = FsRtlAllocatePoolWithTag( NonPagedPoolNx,
1322  sizeof(FCB),
1323  TAG_FCB );
1324  } else {
1325 
1326  PoolType = PagedPool;
1327  Fcb = UnwindStorage[0] = FatAllocateFcb();
1328 
1329  }
1330 
1331  //
1332  // ... and zero it out
1333  //
1334 
1335  RtlZeroMemory( Fcb, sizeof(FCB) );
1336 
1337  UnwindStorage[1] =
1339 
1340  RtlZeroMemory( Fcb->NonPaged, sizeof( NON_PAGED_FCB ) );
1341 
1342  //
1343  // Set the proper node type code, node byte size, and call backs
1344  //
1345 
1346  Fcb->Header.NodeTypeCode = FAT_NTC_FCB;
1347  Fcb->Header.NodeByteSize = sizeof(FCB);
1348 
1350 
1351  //
1352  // Check to see if we need to set the Fcb state to indicate that this
1353  // is a paging/system file. This will prevent it from being opened
1354  // again.
1355  //
1356 
1357  if (IsPagingFile) {
1358 
1360  }
1361 
1362  //
1363  // The initial state, open count, and segment objects fields are already
1364  // zero so we can skip setting them
1365  //
1366 
1367  //
1368  // Initialize the resource variable
1369  //
1370 
1371 
1372  UnwindResource =
1373  Fcb->Header.Resource = FatAllocateResource();
1374 
1375  //
1376  // Initialize the PagingIo Resource. We no longer use the FsRtl common
1377  // shared pool because this led to a) deadlocks due to cases where files
1378  // and their parent directories shared a resource and b) there is no way
1379  // to anticipate inter-driver induced deadlock via recursive operation.
1380  //
1381 
1382  if (SingleResource) {
1383 
1384  Fcb->Header.PagingIoResource = Fcb->Header.Resource;
1385 
1386  } else {
1387 
1388  UnwindResource2 =
1389  Fcb->Header.PagingIoResource = FatAllocateResource();
1390  }
1391 
1392  //
1393  // Insert this fcb into our parent dcb's queue.
1394  //
1395  // There is a deep reason why this goes on the tail, to allow us
1396  // to easily enumerate all child directories before child files.
1397  // This is important to let us maintain whole-volume lockorder
1398  // via BottomUp enumeration.
1399  //
1400 
1401  InsertTailList( &ParentDcb->Specific.Dcb.ParentDcbQueue,
1402  &Fcb->ParentDcbLinks );
1403  UnwindEntryList = &Fcb->ParentDcbLinks;
1404 
1405  //
1406  // Point back to our parent dcb
1407  //
1408 
1409  Fcb->ParentDcb = ParentDcb;
1410 
1411  //
1412  // Set the Vcb
1413  //
1414 
1415  Fcb->Vcb = Vcb;
1416 
1417  //
1418  // Set the dirent offset within the directory
1419  //
1420 
1421  Fcb->LfnOffsetWithinDirectory = LfnOffsetWithinDirectory;
1422  Fcb->DirentOffsetWithinDirectory = DirentOffsetWithinDirectory;
1423 
1424  //
1425  // Set the DirentFatFlags and LastWriteTime
1426  //
1427 
1428  Fcb->DirentFatFlags = Dirent->Attributes;
1429 
1430  Fcb->LastWriteTime = FatFatTimeToNtTime( IrpContext,
1432  0 );
1433 
1434  //
1435  // These fields are only non-zero when in Chicago mode.
1436  //
1437 
1438  if (FatData.ChicagoMode) {
1439 
1440  LARGE_INTEGER FatSystemJanOne1980 = {0};
1441 
1442  //
1443  // If either date is possibly zero, get the system
1444  // version of 1/1/80.
1445  //
1446 
1447  if ((((PUSHORT)Dirent)[9] & ((PUSHORT)Dirent)[8]) == 0) {
1448 
1450  &FatSystemJanOne1980 );
1451  }
1452 
1453  //
1454  // Only do the really hard work if this field is non-zero.
1455  //
1456 
1457  if (((PUSHORT)Dirent)[9] != 0) {
1458 
1459  Fcb->LastAccessTime =
1460  FatFatDateToNtTime( IrpContext,
1461  Dirent->LastAccessDate );
1462 
1463  } else {
1464 
1465  Fcb->LastAccessTime = FatSystemJanOne1980;
1466  }
1467 
1468  //
1469  // Only do the really hard work if this field is non-zero.
1470  //
1471 
1472  if (((PUSHORT)Dirent)[8] != 0) {
1473 
1474  Fcb->CreationTime =
1475  FatFatTimeToNtTime( IrpContext,
1477  Dirent->CreationMSec );
1478 
1479  } else {
1480 
1481  Fcb->CreationTime = FatSystemJanOne1980;
1482  }
1483  }
1484 
1485  //
1486  // Initialize Advanced FCB Header fields
1487  //
1488 
1490  FsRtlSetupAdvancedHeader( &Fcb->Header,
1492 
1493  //
1494  // To make FAT match the present functionality of NTFS, disable
1495  // stream contexts on paging files
1496  //
1497 
1498  if (IsPagingFile) {
1499 
1502  }
1503 
1504  //
1505  // Initialize the Mcb
1506  //
1507 
1509  UnwindMcb = &Fcb->Mcb;
1510 
1511  //
1512  // Set the file size, valid data length, first cluster of file,
1513  // and allocation size based on the information stored in the dirent
1514  //
1515 
1516  Fcb->Header.FileSize.LowPart = Dirent->FileSize;
1517 
1518  Fcb->Header.ValidDataLength.LowPart = Dirent->FileSize;
1519 
1520  Fcb->ValidDataToDisk = Dirent->FileSize;
1521 
1523 
1524  if ( FatIsFat32(Vcb) ) {
1525 
1526  Fcb->FirstClusterOfFile += Dirent->FirstClusterOfFileHi << 16;
1527  }
1528 
1529  if ( Fcb->FirstClusterOfFile == 0 ) {
1530 
1531  Fcb->Header.AllocationSize.QuadPart = 0;
1532 
1533  } else {
1534 
1535  Fcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
1536  }
1537 
1538 
1539  //
1540  // Initialize the Fcb's file lock record
1541  //
1542 
1543  FsRtlInitializeFileLock( &Fcb->Specific.Fcb.FileLock, NULL, NULL );
1544  UnwindFileLock = &Fcb->Specific.Fcb.FileLock;
1545 
1546  //
1547  // Initialize the oplock structure.
1548  //
1549 
1551  UnwindOplock = FatGetFcbOplock(Fcb);
1552 
1553  //
1554  // Indicate that Fast I/O is possible
1555  //
1556 
1557  Fcb->Header.IsFastIoPossible = TRUE;
1558 
1559  //
1560  // Set the file names. This must be the last thing we do.
1561  //
1562 
1563  FatConstructNamesInFcb( IrpContext,
1564  Fcb,
1565  Dirent,
1566  Lfn );
1567 
1568  //
1569  // Drop the shortname hint so prefix searches can figure out
1570  // what they found
1571  //
1572 
1574 
1575  } _SEH2_FINALLY {
1576 
1578 
1579  //
1580  // If this is an abnormal termination then undo our work
1581  //
1582 
1583  if (_SEH2_AbnormalTermination()) {
1584 
1585  ULONG i;
1586 
1587  if (UnwindOplock != NULL) { FsRtlUninitializeOplock( UnwindOplock ); }
1588  if (UnwindFileLock != NULL) { FsRtlUninitializeFileLock( UnwindFileLock ); }
1589  if (UnwindMcb != NULL) { FsRtlUninitializeLargeMcb( UnwindMcb ); }
1590  if (UnwindEntryList != NULL) { RemoveEntryList( UnwindEntryList ); }
1591  if (UnwindResource != NULL) { FatFreeResource( UnwindResource ); }
1592  if (UnwindResource2 != NULL) { FatFreeResource( UnwindResource2 ); }
1593 
1594  for (i = 0; i < sizeof(UnwindStorage)/sizeof(PVOID); i += 1) {
1595  if (UnwindStorage[i] != NULL) { ExFreePool( UnwindStorage[i] ); }
1596  }
1597  }
1598 
1599  DebugTrace(-1, Dbg, "FatCreateFcb -> %p\n", Fcb);
1600  } _SEH2_END;
1601 
1602  //
1603  // return and tell the caller
1604  //
1605 
1606  return Fcb;
1607 }
1608 
1609 
1610 PDCB
1612  IN PIRP_CONTEXT IrpContext,
1613  IN PVCB Vcb,
1614  IN PDCB ParentDcb,
1615  IN ULONG LfnOffsetWithinDirectory,
1616  IN ULONG DirentOffsetWithinDirectory,
1617  IN PDIRENT Dirent,
1619  )
1620 
1621 /*++
1622 
1623 Routine Description:
1624 
1625  This routine allocates, initializes, and inserts a new Dcb record into
1626  the in memory data structures.
1627 
1628 Arguments:
1629 
1630  Vcb - Supplies the Vcb to associate the new DCB under.
1631 
1632  ParentDcb - Supplies the parent dcb that the new DCB is under.
1633 
1634  LfnOffsetWithinDirectory - Supplies the offset of the LFN. If there is
1635  no LFN associated with this file then this value is same as
1636  DirentOffsetWithinDirectory.
1637 
1638  DirentOffsetWithinDirectory - Supplies the offset, in bytes from the
1639  start of the directory file where the dirent for the fcb is located
1640 
1641  Dirent - Supplies the dirent for the dcb being created
1642 
1643  FileName - Supplies the file name of the file relative to the directory
1644  it's in (e.g., the file \config.sys is called "CONFIG.SYS" without
1645  the preceding backslash).
1646 
1647  Lfn - Supplies a long UNICODE name associated with this directory.
1648 
1649 Return Value:
1650 
1651  PDCB - Returns a pointer to the newly allocated DCB
1652 
1653 --*/
1654 
1655 {
1656  PDCB Dcb = NULL;
1657 
1658  //
1659  // The following variables are used for abnormal unwind
1660  //
1661 
1662  PVOID UnwindStorage[2] = { NULL, NULL };
1663  PERESOURCE UnwindResource = NULL;
1664  PERESOURCE UnwindResource2 = NULL;
1665  PLIST_ENTRY UnwindEntryList = NULL;
1666  PLARGE_MCB UnwindMcb = NULL;
1667  POPLOCK UnwindOplock = NULL;
1668 
1669  PAGED_CODE();
1670 
1671  DebugTrace(+1, Dbg, "FatCreateDcb\n", 0);
1672 
1673  _SEH2_TRY {
1674 
1675  //
1676  // assert that the only time we are called is if wait is true
1677  //
1678 
1679  NT_ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
1680 
1681  //
1682  // Allocate a new DCB, and zero it out
1683  //
1684 
1685  UnwindStorage[0] = Dcb = FatAllocateFcb();
1686 
1687  RtlZeroMemory( Dcb, sizeof(DCB) );
1688 
1689  UnwindStorage[1] =
1690  Dcb->NonPaged = FatAllocateNonPagedFcb();
1691 
1692  RtlZeroMemory( Dcb->NonPaged, sizeof( NON_PAGED_FCB ) );
1693 
1694  //
1695  // Set the proper node type code, node byte size and call backs
1696  //
1697 
1698  Dcb->Header.NodeTypeCode = FAT_NTC_DCB;
1699  Dcb->Header.NodeByteSize = sizeof(DCB);
1700 
1701  Dcb->FcbCondition = FcbGood;
1702 
1703  //
1704  // The initial state, open count, and directory change count fields are
1705  // already zero so we can skip setting them
1706  //
1707 
1708  //
1709  // Initialize the resource variable
1710  //
1711 
1712 
1713  UnwindResource =
1714  Dcb->Header.Resource = FatAllocateResource();
1715 
1716  //
1717  // Initialize the PagingIo Resource. We no longer use the FsRtl common
1718  // shared pool because this led to a) deadlocks due to cases where files
1719  // and their parent directories shared a resource and b) there is no way
1720  // to anticipate inter-driver induced deadlock via recursive operation.
1721  //
1722 
1723  UnwindResource2 =
1724  Dcb->Header.PagingIoResource = FatAllocateResource();
1725 
1726  //
1727  // Insert this Dcb into our parent dcb's queue
1728  //
1729  // There is a deep reason why this goes on the head, to allow us
1730  // to easily enumerate all child directories before child files.
1731  // This is important to let us maintain whole-volume lockorder
1732  // via BottomUp enumeration.
1733  //
1734 
1735  InsertHeadList( &ParentDcb->Specific.Dcb.ParentDcbQueue,
1736  &Dcb->ParentDcbLinks );
1737  UnwindEntryList = &Dcb->ParentDcbLinks;
1738 
1739  //
1740  // Point back to our parent dcb
1741  //
1742 
1743  Dcb->ParentDcb = ParentDcb;
1744 
1745  //
1746  // Set the Vcb
1747  //
1748 
1749  Dcb->Vcb = Vcb;
1750 
1751  //
1752  // Set the dirent offset within the directory
1753  //
1754 
1755  Dcb->LfnOffsetWithinDirectory = LfnOffsetWithinDirectory;
1756  Dcb->DirentOffsetWithinDirectory = DirentOffsetWithinDirectory;
1757 
1758  //
1759  // Set the DirentFatFlags and LastWriteTime
1760  //
1761 
1762  Dcb->DirentFatFlags = Dirent->Attributes;
1763 
1764  Dcb->LastWriteTime = FatFatTimeToNtTime( IrpContext,
1766  0 );
1767 
1768  //
1769  // These fields are only non-zero when in Chicago mode.
1770  //
1771 
1772  if (FatData.ChicagoMode) {
1773 
1774  LARGE_INTEGER FatSystemJanOne1980 = {0};
1775 
1776  //
1777  // If either date is possibly zero, get the system
1778  // version of 1/1/80.
1779  //
1780 
1781  if ((((PUSHORT)Dirent)[9] & ((PUSHORT)Dirent)[8]) == 0) {
1782 
1784  &FatSystemJanOne1980 );
1785  }
1786 
1787  //
1788  // Only do the really hard work if this field is non-zero.
1789  //
1790 
1791  if (((PUSHORT)Dirent)[9] != 0) {
1792 
1793  Dcb->LastAccessTime =
1794  FatFatDateToNtTime( IrpContext,
1795  Dirent->LastAccessDate );
1796 
1797  } else {
1798 
1799  Dcb->LastAccessTime = FatSystemJanOne1980;
1800  }
1801 
1802  //
1803  // Only do the really hard work if this field is non-zero.
1804  //
1805 
1806  if (((PUSHORT)Dirent)[8] != 0) {
1807 
1808  Dcb->CreationTime =
1809  FatFatTimeToNtTime( IrpContext,
1811  Dirent->CreationMSec );
1812 
1813  } else {
1814 
1815  Dcb->CreationTime = FatSystemJanOne1980;
1816  }
1817  }
1818 
1819  //
1820  // Initialize Advanced FCB Header fields
1821  //
1822 
1823  ExInitializeFastMutex( &Dcb->NonPaged->AdvancedFcbHeaderMutex );
1824  FsRtlSetupAdvancedHeader( &Dcb->Header,
1825  &Dcb->NonPaged->AdvancedFcbHeaderMutex );
1826 
1827  //
1828  // Initialize the Mcb
1829  //
1830 
1832  UnwindMcb = &Dcb->Mcb;
1833 
1834  //
1835  // Set the file size, first cluster of file, and allocation size
1836  // based on the information stored in the dirent
1837  //
1838 
1839  Dcb->FirstClusterOfFile = (ULONG)Dirent->FirstClusterOfFile;
1840 
1841  if ( FatIsFat32(Dcb->Vcb) ) {
1842 
1843  Dcb->FirstClusterOfFile += Dirent->FirstClusterOfFileHi << 16;
1844  }
1845 
1846  if ( Dcb->FirstClusterOfFile == 0 ) {
1847 
1848  Dcb->Header.AllocationSize.QuadPart = 0;
1849 
1850  } else {
1851 
1852  Dcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
1853  }
1854 
1855 
1856  // initialize the notify queues, and the parent dcb queue.
1857  //
1858 
1859  InitializeListHead( &Dcb->Specific.Dcb.ParentDcbQueue );
1860 
1861  //
1862  // Setup the free dirent bitmap buffer. Since we don't know the
1863  // size of the directory, leave it zero for now.
1864  //
1865 
1866  RtlInitializeBitMap( &Dcb->Specific.Dcb.FreeDirentBitmap,
1867  NULL,
1868  0 );
1869 
1870  //
1871  // Set our two create dirent aids to represent that we have yet to
1872  // enumerate the directory for never used or deleted dirents.
1873  //
1874 
1875  Dcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
1876  Dcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;
1877 
1878 #if (NTDDI_VERSION >= NTDDI_WIN8)
1879  //
1880  // Initialize the oplock structure.
1881  //
1882 
1884  UnwindOplock = FatGetFcbOplock(Dcb);
1885 #endif
1886 
1887  //
1888  // Postpone initializing the cache map until we need to do a read/write
1889  // of the directory file.
1890 
1891 
1892  //
1893  // set the file names. This must be the last thing we do.
1894  //
1895 
1896  FatConstructNamesInFcb( IrpContext,
1897  Dcb,
1898  Dirent,
1899  Lfn );
1900 
1901  Dcb->ShortName.FileNameDos = TRUE;
1902 
1903  } _SEH2_FINALLY {
1904 
1906 
1907  //
1908  // If this is an abnormal termination then undo our work
1909  //
1910 
1911  if (_SEH2_AbnormalTermination()) {
1912 
1913  ULONG i;
1914 
1915  if (UnwindOplock != NULL) { FsRtlUninitializeOplock( UnwindOplock ); }
1916  if (UnwindMcb != NULL) { FsRtlUninitializeLargeMcb( UnwindMcb ); }
1917  if (UnwindEntryList != NULL) { RemoveEntryList( UnwindEntryList ); }
1918  if (UnwindResource != NULL) { FatFreeResource( UnwindResource ); }
1919  if (UnwindResource2 != NULL) { FatFreeResource( UnwindResource2 ); }
1920 
1921  for (i = 0; i < sizeof(UnwindStorage)/sizeof(PVOID); i += 1) {
1922  if (UnwindStorage[i] != NULL) { ExFreePool( UnwindStorage[i] ); }
1923  }
1924  }
1925 
1926  DebugTrace(-1, Dbg, "FatCreateDcb -> %p\n", Dcb);
1927  } _SEH2_END;
1928 
1929  //
1930  // return and tell the caller
1931  //
1932 
1933  DebugTrace(-1, Dbg, "FatCreateDcb -> %p\n", Dcb);
1934 
1935  return Dcb;
1936 }
1937 
1938 
1939 VOID
1941  IN PIRP_CONTEXT IrpContext,
1942  IN PFCB *FcbPtr
1943  )
1944 
1945 /*++
1946 
1947 Routine Description:
1948 
1949  This routine deallocates and removes an FCB, DCB, or ROOT DCB record
1950  from Fat's in-memory data structures. It also will remove all
1951  associated underlings (i.e., Notify irps, and child FCB/DCB records).
1952 
1953 Arguments:
1954 
1955  Fcb - Supplies the FCB/DCB/ROOT DCB to be removed
1956 
1957 Return Value:
1958 
1959  None
1960 
1961 --*/
1962 
1963 {
1964  PFCB Fcb = *FcbPtr;
1965 
1966  PAGED_CODE();
1967 
1968  DebugTrace(+1, Dbg, "FatDeleteFcb, Fcb = %p\n", Fcb);
1969 
1970  //
1971  // We can only delete this record if the open count is zero.
1972  //
1973 
1974  if (Fcb->OpenCount != 0) {
1975 
1976  DebugDump("Error deleting Fcb, Still Open\n", 0, Fcb);
1977 #ifdef _MSC_VER
1978 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1979 #endif
1980  FatBugCheck( 0, 0, 0 );
1981  }
1982 
1983  //
1984  // Better be an FCB/DCB.
1985  //
1986 
1987  if ((Fcb->Header.NodeTypeCode != FAT_NTC_DCB) &&
1988  (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) &&
1989  (Fcb->Header.NodeTypeCode != FAT_NTC_FCB)) {
1990 
1991 #ifdef _MSC_VER
1992 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1993 #endif
1994  FatBugCheck( 0, 0, 0 );
1995  }
1996 
1997  //
1998  // If this is a DCB then remove every Notify record from the two
1999  // notify queues
2000  //
2001 
2002  if ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) ||
2003  (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) {
2004 
2005  //
2006  // If we allocated a free dirent bitmap buffer, free it.
2007  //
2008 
2009  if ((Fcb->Specific.Dcb.FreeDirentBitmap.Buffer != NULL) &&
2010  (Fcb->Specific.Dcb.FreeDirentBitmap.Buffer !=
2011  &Fcb->Specific.Dcb.FreeDirentBitmapBuffer[0])) {
2012 
2013  ExFreePool(Fcb->Specific.Dcb.FreeDirentBitmap.Buffer);
2014  }
2015 
2016 #if (NTDDI_VERSION >= NTDDI_WIN8)
2017  //
2018  // Uninitialize the oplock.
2019  //
2020 
2022 #endif
2023 
2024  NT_ASSERT( Fcb->Specific.Dcb.DirectoryFileOpenCount == 0 );
2025  NT_ASSERT( IsListEmpty(&Fcb->Specific.Dcb.ParentDcbQueue) );
2026  NT_ASSERT( NULL == Fcb->Specific.Dcb.DirectoryFile);
2027 
2028  } else {
2029 
2030  //
2031  // Uninitialize the byte range file locks and opportunistic locks
2032  //
2033 
2034  FsRtlUninitializeFileLock( &Fcb->Specific.Fcb.FileLock );
2036  }
2037 
2038 
2039  //
2040  // Release any Filter Context structures associated with this FCB
2041  //
2042 
2044 
2045  //
2046  // Uninitialize the Mcb
2047  //
2048 
2050 
2051  //
2052  // If this is not the root dcb then we need to remove ourselves from
2053  // our parents Dcb queue
2054  //
2055 
2056  if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) {
2057 
2059  }
2060 
2061  //
2062  // Remove the entry from the splay table if there is still is one.
2063  //
2064 
2066 
2067  FatRemoveNames( IrpContext, Fcb );
2068  }
2069 
2070  //
2071  // Free the file name pool if allocated.
2072  //
2073 
2074  if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) {
2075 
2076  //
2077  // If we blew up at inconvenient times, the shortname
2078  // could be null even though you will *never* see this
2079  // normally. Rename is a good example of this case.
2080  //
2081 
2082  if (Fcb->ShortName.Name.Oem.Buffer) {
2083 
2084  ExFreePool( Fcb->ShortName.Name.Oem.Buffer );
2085  }
2086 
2087  if (Fcb->FullFileName.Buffer) {
2088 
2090  }
2091  }
2092 
2093  if (Fcb->ExactCaseLongName.Buffer) {
2094 
2096  }
2097 
2098 #ifdef SYSCACHE_COMPILE
2099 
2100  if (Fcb->WriteMask) {
2101 
2102  ExFreePool( Fcb->WriteMask );
2103  }
2104 
2105 #endif
2106 
2107  //
2108  // Finally deallocate the Fcb and non-paged fcb records
2109  //
2110 
2111  FatFreeResource( Fcb->Header.Resource );
2112 
2113  if (Fcb->Header.PagingIoResource != Fcb->Header.Resource) {
2114 
2115  FatFreeResource( Fcb->Header.PagingIoResource );
2116  }
2117 
2118  //
2119  // If an Event was allocated, get rid of it.
2120  //
2121 
2123 
2125  }
2126 
2128 
2129  Fcb->Header.NodeTypeCode = NTC_UNDEFINED;
2130 
2131  FatFreeFcb( Fcb );
2132  *FcbPtr = NULL;
2133 
2134  //
2135  // and return to our caller
2136  //
2137 
2138  DebugTrace(-1, Dbg, "FatDeleteFcb -> VOID\n", 0);
2139 }
2140 
2141 
2142 PCCB
2144  IN PIRP_CONTEXT IrpContext
2145  )
2146 
2147 /*++
2148 
2149 Routine Description:
2150 
2151  This routine creates a new CCB record
2152 
2153 Arguments:
2154 
2155 Return Value:
2156 
2157  CCB - returns a pointer to the newly allocate CCB
2158 
2159 --*/
2160 
2161 {
2162  PCCB Ccb;
2163 
2164  PAGED_CODE();
2165 
2166  DebugTrace(+1, Dbg, "FatCreateCcb\n", 0);
2167 
2168  //
2169  // Allocate a new CCB Record
2170  //
2171 
2172  Ccb = FatAllocateCcb();
2173 
2174  RtlZeroMemory( Ccb, sizeof(CCB) );
2175 
2176  //
2177  // Set the proper node type code and node byte size
2178  //
2179 
2180  Ccb->NodeTypeCode = FAT_NTC_CCB;
2181  Ccb->NodeByteSize = sizeof(CCB);
2182 
2183  //
2184  // return and tell the caller
2185  //
2186 
2187  DebugTrace(-1, Dbg, "FatCreateCcb -> %p\n", Ccb);
2188 
2189  UNREFERENCED_PARAMETER( IrpContext );
2190 
2191  return Ccb;
2192 }
2193 
2194 
2195 
2196 VOID
2198  IN PCCB Ccb
2199  )
2200 /*++
2201 
2202 Routine Description:
2203 
2204  This routine deallocates CCB query templates
2205 
2206 Arguments:
2207 
2208  Ccb - Supplies the CCB
2209 
2210 Return Value:
2211 
2212  None
2213 
2214 --*/
2215 {
2216  PAGED_CODE();
2217 
2218  //
2219  // If we allocated query template buffers, deallocate them now.
2220  //
2221 
2223 
2224  NT_ASSERT( Ccb->UnicodeQueryTemplate.Buffer);
2226  RtlFreeUnicodeString( &Ccb->UnicodeQueryTemplate );
2227  }
2228 
2230 
2231  NT_ASSERT( Ccb->OemQueryTemplate.Wild.Buffer );
2233  RtlFreeOemString( &Ccb->OemQueryTemplate.Wild );
2234  }
2235 
2237 }
2238 
2239 
2240 
2241 VOID
2243  IN PIRP_CONTEXT IrpContext,
2244  IN PCCB *Ccb
2245  )
2246 
2247 /*++
2248 
2249 Routine Description:
2250 
2251  This routine deallocates and removes the specified CCB record
2252  from the Fat in memory data structures
2253 
2254 Arguments:
2255 
2256  Ccb - Supplies the CCB to remove
2257 
2258 Return Value:
2259 
2260  None
2261 
2262 --*/
2263 
2264 {
2265  PAGED_CODE();
2266 
2267  DebugTrace(+1, Dbg, "FatDeleteCcb, Ccb = %p\n", *Ccb);
2268 
2270 
2271  //
2272  // Deallocate the Ccb record
2273  //
2274 
2275  FatFreeCcb( *Ccb );
2276  *Ccb = NULL;
2277 
2278  //
2279  // return and tell the caller
2280  //
2281 
2282  DebugTrace(-1, Dbg, "FatDeleteCcb -> VOID\n", 0);
2283 
2284  UNREFERENCED_PARAMETER( IrpContext );
2285 }
2286 
2287 
2290  IN PIRP Irp,
2291  IN BOOLEAN Wait
2292  )
2293 
2294 /*++
2295 
2296 Routine Description:
2297 
2298  This routine creates a new IRP_CONTEXT record
2299 
2300 Arguments:
2301 
2302  Irp - Supplies the originating Irp.
2303 
2304  Wait - Supplies the wait value to store in the context
2305 
2306 Return Value:
2307 
2308  PIRP_CONTEXT - returns a pointer to the newly allocate IRP_CONTEXT Record
2309 
2310 --*/
2311 
2312 {
2313  PIRP_CONTEXT IrpContext;
2315 
2316  PAGED_CODE();
2317 
2318  DebugTrace(+1, Dbg, "FatCreateIrpContext\n", 0);
2319 
2321 
2322  //
2323  // The only operations a filesystem device object should ever receive
2324  // are create/teardown of fsdo handles and operations which do not
2325  // occur in the context of fileobjects (i.e., mount).
2326  //
2327 
2329 
2330  if (IrpSp->FileObject != NULL &&
2334 
2336  }
2337 
2338  NT_ASSERT( IrpSp->FileObject != NULL ||
2339 
2342  IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_INVALIDATE_VOLUMES) ||
2343 
2346 
2348  }
2349 
2350  //
2351  // Attemtp to allocate from the region first and failing that allocate
2352  // from pool.
2353  //
2354 
2355  DebugDoit( FatFsdEntryCount += 1);
2356 
2357  IrpContext = FatAllocateIrpContext();
2358 
2359  //
2360  // Zero out the irp context.
2361  //
2362 
2363  RtlZeroMemory( IrpContext, sizeof(IRP_CONTEXT) );
2364 
2365  //
2366  // Set the proper node type code and node byte size
2367  //
2368 
2369  IrpContext->NodeTypeCode = FAT_NTC_IRP_CONTEXT;
2370  IrpContext->NodeByteSize = sizeof(IRP_CONTEXT);
2371 
2372  //
2373  // Set the originating Irp field
2374  //
2375 
2376  IrpContext->OriginatingIrp = Irp;
2377 
2378  //
2379  // Major/Minor Function codes
2380  //
2381 
2382  IrpContext->MajorFunction = IrpSp->MajorFunction;
2383  IrpContext->MinorFunction = IrpSp->MinorFunction;
2384 
2385  //
2386  // Copy RealDevice for workque algorithms, and also set Write Through
2387  // and Removable Media if there is a file object. Only file system
2388  // control Irps won't have a file object, and they should all have
2389  // a Vpb as the first IrpSp location.
2390  //
2391 
2392  if (IrpSp->FileObject != NULL) {
2393 
2395 
2396  IrpContext->RealDevice = FileObject->DeviceObject;
2397  IrpContext->Vcb = &((PVOLUME_DEVICE_OBJECT)(IrpSp->DeviceObject))->Vcb;
2398 
2399  //
2400  // See if the request is Write Through. Look for both FileObjects opened
2401  // as write through, and non-cached requests with the SL_WRITE_THROUGH flag set.
2402  //
2403  // The latter can only originate from kernel components. (Note - NtWriteFile()
2404  // does redundantly set the SL_W_T flag for all requests it issues on write
2405  // through file objects)
2406  //
2407 
2408  if (IsFileWriteThrough( FileObject, IrpContext->Vcb ) ||
2409  ( (IrpSp->MajorFunction == IRP_MJ_WRITE) &&
2410  BooleanFlagOn( Irp->Flags, IRP_NOCACHE) &&
2412 
2413  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
2414  }
2415  } else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) {
2416 
2417  IrpContext->RealDevice = IrpSp->Parameters.MountVolume.Vpb->RealDevice;
2418  }
2419 
2420  //
2421  // Set the wait parameter
2422  //
2423 
2424  if (Wait) { SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); }
2425 
2426  //
2427  // Set the recursive file system call parameter. We set it true if
2428  // the TopLevelIrp field in the thread local storage is not the current
2429  // irp, otherwise we leave it as FALSE.
2430  //
2431 
2432  if ( IoGetTopLevelIrp() != Irp) {
2433 
2434  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
2435  }
2436 
2437  //
2438  // return and tell the caller
2439  //
2440 
2441  DebugTrace(-1, Dbg, "FatCreateIrpContext -> %p\n", IrpContext);
2442 
2443  return IrpContext;
2444 }
2445 
2446 
2447 
2448 VOID
2450  IN PIRP_CONTEXT IrpContext
2451  )
2452 
2453 /*++
2454 
2455 Routine Description:
2456 
2457  This routine deallocates and removes the specified IRP_CONTEXT record
2458  from the Fat in memory data structures. It should only be called
2459  by FatCompleteRequest.
2460 
2461 Arguments:
2462 
2463  IrpContext - Supplies the IRP_CONTEXT to remove
2464 
2465 Return Value:
2466 
2467  None
2468 
2469 --*/
2470 
2471 {
2472  PAGED_CODE();
2473 
2474  DebugTrace(+1, Dbg, "FatDeleteIrpContext, IrpContext = %p\n", IrpContext);
2475 
2476  NT_ASSERT( IrpContext->NodeTypeCode == FAT_NTC_IRP_CONTEXT );
2477  NT_ASSERT( IrpContext->PinCount == 0 );
2478 
2479 
2480  //
2481  // If there is a FatIoContext that was allocated, free it.
2482  //
2483 
2484  if (IrpContext->FatIoContext != NULL) {
2485 
2486  if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT)) {
2487 
2488  if (IrpContext->FatIoContext->ZeroMdl) {
2489  IoFreeMdl( IrpContext->FatIoContext->ZeroMdl );
2490  }
2491 
2492  ExFreePool( IrpContext->FatIoContext );
2493  }
2494  }
2495 
2496  //
2497  // Drop the IrpContext.
2498  //
2499 
2500  FatFreeIrpContext( IrpContext );
2501 
2502  //
2503  // return and tell the caller
2504  //
2505 
2506  DebugTrace(-1, Dbg, "FatDeleteIrpContext -> VOID\n", 0);
2507 
2508  return;
2509 }
2510 
2511 
2512 PFCB
2514  IN PIRP_CONTEXT IrpContext,
2515  IN PFCB Fcb OPTIONAL,
2516  IN PFCB TerminationFcb
2517  )
2518 
2519 /*++
2520 
2521 Routine Description:
2522 
2523  This routine is used to iterate through Fcbs in a tree. In order to match
2524  the lockorder for getting multiple Fcbs (so this can be used for acquiring
2525  all Fcbs), this version does a bottom-up enumeration.
2526 
2527  This is different than the old one, now called TopDown. The problem with
2528  lockorder was very well hidden.
2529 
2530  The transition rule is still pretty simple:
2531 
2532  A) If you have an adjacent sibling, go to it
2533  1) Descend to its leftmost child
2534  B) Else go to your parent
2535 
2536  If this routine is called with in invalid TerminationFcb it will fail,
2537  badly.
2538 
2539  The TerminationFcb is the last Fcb returned in the enumeration.
2540 
2541  This method is incompatible with the possibility that ancestors may vanish
2542  based on operations done on the last returned node. For instance,
2543  FatPurgeReferencedFileObjects cannot use BottomUp enumeration.
2544 
2545 Arguments:
2546 
2547  Fcb - Supplies the current Fcb. This is NULL if enumeration is starting.
2548 
2549  TerminationFcb - The root Fcb of the tree in which the enumeration starts
2550  and at which it inclusively stops.
2551 
2552 Return Value:
2553 
2554  The next Fcb in the enumeration, or NULL if Fcb was the final one.
2555 
2556 --*/
2557 
2558 {
2559  PFCB NextFcb;
2560 
2561  PAGED_CODE();
2562  UNREFERENCED_PARAMETER( IrpContext );
2563 
2564  NT_ASSERT( FatVcbAcquiredExclusive( IrpContext, TerminationFcb->Vcb ) ||
2565  FlagOn( TerminationFcb->Vcb->VcbState, VCB_STATE_FLAG_LOCKED ) );
2566 
2567  //
2568  // Do we need to begin the enumeration?
2569  //
2570 
2571  if (Fcb != NULL) {
2572 
2573  //
2574  // Did we complete?
2575  //
2576 
2577  if (Fcb == TerminationFcb) {
2578 
2579  return NULL;
2580  }
2581 
2582  //
2583  // Do we have a sibling to return?
2584  //
2585 
2586  NextFcb = FatGetNextSibling( Fcb );
2587 
2588  //
2589  // If not, return our parent. We are done with this branch.
2590  //
2591 
2592  if (NextFcb == NULL) {
2593 
2594  return Fcb->ParentDcb;
2595  }
2596 
2597  } else {
2598 
2599  NextFcb = TerminationFcb;
2600  }
2601 
2602  //
2603  // Decend to its furthest child (if it exists) and return it.
2604  //
2605 
2606  for (;
2607  NodeType( NextFcb ) != FAT_NTC_FCB && FatGetFirstChild( NextFcb ) != NULL;
2608  NextFcb = FatGetFirstChild( NextFcb )) {
2609  }
2610 
2611  return NextFcb;
2612 }
2613 
2614 PFCB
2616  IN PIRP_CONTEXT IrpContext,
2617  IN PFCB Fcb,
2618  IN PFCB TerminationFcb
2619  )
2620 
2621 /*++
2622 
2623 Routine Description:
2624 
2625  This routine is used to iterate through Fcbs in a tree, from the top down.
2626 
2627  The rule is very simple:
2628 
2629  A) If you have a child, go to it, else
2630  B) If you have an older sibling, go to it, else
2631  C) Go to your parent's older sibling.
2632 
2633  If this routine is called with in invalid TerminationFcb it will fail,
2634  badly.
2635 
2636  The Termination Fcb is never returned. If it is the root of the tree you
2637  are traversing, visit it first.
2638 
2639  This routine never returns direct ancestors of Fcb, and thus is useful when
2640  making Fcb's go away (which may tear up the tree).
2641 
2642 Arguments:
2643 
2644  Fcb - Supplies the current Fcb
2645 
2646  TerminationFcb - The Fcb at which the enumeration should (non-inclusivly)
2647  stop. Assumed to be a directory.
2648 
2649 Return Value:
2650 
2651  The next Fcb in the enumeration, or NULL if Fcb was the final one.
2652 
2653 --*/
2654 
2655 {
2656  PFCB Sibling;
2657 
2658  PAGED_CODE();
2659  UNREFERENCED_PARAMETER( IrpContext );
2660 
2661  NT_ASSERT( FatVcbAcquiredExclusive( IrpContext, Fcb->Vcb ) ||
2663 
2664  //
2665  // If this was a directory (ie. not a file), get the child. If
2666  // there aren't any children and this is our termination Fcb,
2667  // return NULL.
2668  //
2669 
2670  if ( ((NodeType(Fcb) == FAT_NTC_DCB) ||
2671  (NodeType(Fcb) == FAT_NTC_ROOT_DCB)) &&
2672  !IsListEmpty(&Fcb->Specific.Dcb.ParentDcbQueue) ) {
2673 
2674  return FatGetFirstChild( Fcb );
2675  }
2676 
2677  //
2678  // Were we only meant to do one iteration?
2679  //
2680 
2681  if ( Fcb == TerminationFcb ) {
2682 
2683  return NULL;
2684  }
2685 
2686  Sibling = FatGetNextSibling(Fcb);
2687 
2688  while (TRUE) {
2689 
2690  //
2691  // Do we still have an "older" sibling in this directory who is
2692  // not the termination Fcb?
2693  //
2694 
2695  if ( Sibling != NULL ) {
2696 
2697  return (Sibling != TerminationFcb) ? Sibling : NULL;
2698  }
2699 
2700  //
2701  // OK, let's move on to out parent and see if he is the termination
2702  // node or has any older siblings.
2703  //
2704 
2705  if ( Fcb->ParentDcb == TerminationFcb ) {
2706 
2707  return NULL;
2708  }
2709 
2710  Fcb = Fcb->ParentDcb;
2711 
2712  Sibling = FatGetNextSibling(Fcb);
2713  }
2714 }
2715 
2716 
2717 BOOLEAN
2719  IN PIRP_CONTEXT IrpContext,
2720  PVCB Vcb
2721  )
2722 
2723 /*++
2724 
2725 Routine Description:
2726 
2727  This routine swaps the VPB for this VCB if it has not been done already.
2728  This means the device object will get our spare VPB and we will cleanup
2729  the one used while the volume was mounted.
2730 
2731 Arguments:
2732 
2733  IrpContext - Supplies the context for the overall request.
2734 
2735  Vcb - Supplies the VCB to swap the VPB on.
2736 
2737 Return Value:
2738 
2739  TRUE - If the VPB was actually swapped.
2740 
2741  FALSE - If the VPB was already swapped.
2742 
2743 --*/
2744 
2745 {
2746  BOOLEAN Result = FALSE;
2747  PVPB OldVpb;
2749 
2750 
2751  //
2752  // Make sure we have not already swapped it.
2753  //
2754 
2755  OldVpb = Vcb->Vpb;
2756 
2757 #ifdef _MSC_VER
2758 #pragma prefast( push )
2759 #pragma prefast( disable: 28175, "touching Vpb is ok for a filesystem" )
2760 #endif
2761 
2762  if (!FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VPB_MUST_BE_FREED ) && OldVpb->RealDevice->Vpb == OldVpb) {
2763 
2764  //
2765  // If not the final reference and we are forcing the disconnect,
2766  // then swap out the Vpb. We must preserve the REMOVE_PENDING flag
2767  // so that the device is not remounted in the middle of a PnP remove
2768  // operation.
2769  //
2770 
2771  NT_ASSERT( Vcb->SwapVpb != NULL );
2772 
2773  Vcb->SwapVpb->Type = IO_TYPE_VPB;
2774  Vcb->SwapVpb->Size = sizeof( VPB );
2775  Vcb->SwapVpb->RealDevice = OldVpb->RealDevice;
2776 
2777  Vcb->SwapVpb->RealDevice->Vpb = Vcb->SwapVpb;
2778 
2779  Vcb->SwapVpb->Flags = FlagOn( OldVpb->Flags, VPB_REMOVE_PENDING );
2780 
2781  //
2782  // If we are working on a mount request, we need to make sure we update
2783  // the VPB in the IRP, since the one it points to may no longer be valid.
2784  //
2785 
2786  if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL && IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) {
2787 
2788  //
2789  // Get the IRP stack.
2790  //
2791 
2792  IrpSp = IoGetCurrentIrpStackLocation( IrpContext->OriginatingIrp );
2793 
2794  NT_ASSERT( IrpSp->FileObject == NULL );
2795 
2796  //
2797  // Check the VPB in the IRP to see if it is the one we are swapping.
2798  //
2799 
2800  if (IrpSp->Parameters.MountVolume.Vpb == OldVpb) {
2801 
2802  //
2803  // Change the IRP to point to the swap VPB.
2804  //
2805 
2806  IrpSp->Parameters.MountVolume.Vpb = Vcb->SwapVpb;
2807  }
2808  }
2809 
2810 #ifdef _MSC_VER
2811 #pragma prefast( pop )
2812 #endif
2813 
2814  //
2815  // We place the volume in the Bad state (as opposed to NotMounted) so
2816  // that it is not eligible for a remount. Also indicate we used up
2817  // the swap.
2818  //
2819 
2820  Vcb->SwapVpb = NULL;
2823 
2824  Result = TRUE;
2825  }
2826 
2827  return Result;
2828 }
2829 
2830 
2831 _Requires_lock_held_(_Global_critical_region_)
2832 BOOLEAN
2833 FatCheckForDismount (
2834  IN PIRP_CONTEXT IrpContext,
2835  PVCB Vcb,
2836  IN BOOLEAN Force
2837  )
2838 
2839 /*++
2840 
2841 Routine Description:
2842 
2843  This routine determines if a volume is ready for deletion. It
2844  correctly synchronizes with creates en-route to the file system.
2845 
2846 Arguments:
2847 
2848  Vcb - Supplies the volume to examine
2849 
2850  Force - Specifies whether we want this Vcb forcibly disconnected
2851  from the driver stack if it will not be deleted (a new vpb will
2852  be installed if neccesary). Caller is responsible for making
2853  sure that the volume has been marked in such a way that attempts
2854  to operate through the realdevice are blocked (i.e., move the vcb
2855  out of the mounted state).
2856 
2857 Return Value:
2858 
2859  BOOLEAN - TRUE if the volume was deleted, FALSE otherwise.
2860 
2861 --*/
2862 
2863 {
2864  KIRQL SavedIrql;
2865  BOOLEAN VcbDeleted = FALSE;
2866 
2867 
2868  //
2869  // If the VCB condition is good and we are not forcing, just return.
2870  //
2871 
2872  if (Vcb->VcbCondition == VcbGood && !Force) {
2873 
2874  return FALSE;
2875  }
2876 
2877  //
2878  // Now check for a zero Vpb count on an unmounted volume. These
2879  // volumes will be deleted as they now have no file objects and
2880  // there are no creates en route to this volume.
2881  //
2882 
2883  IoAcquireVpbSpinLock( &SavedIrql );
2884 
2885  if (Vcb->Vpb->ReferenceCount == Vcb->ResidualOpenCount && Vcb->OpenFileCount == 0) {
2886 
2887  PVPB Vpb = Vcb->Vpb;
2888 
2889 #if DBG
2890  UNICODE_STRING VolumeLabel;
2891 
2892  //
2893  // Setup the VolumeLabel string
2894  //
2895 
2896  VolumeLabel.Length = Vcb->Vpb->VolumeLabelLength;
2898  VolumeLabel.Buffer = &Vcb->Vpb->VolumeLabel[0];
2899 
2902  "FASTFAT: Dismounting Volume %Z\n",
2903  &VolumeLabel));
2904 #endif // DBG
2905 
2906  //
2907  // Swap this VCB's VPB.
2908  //
2909 
2910  FatSwapVpb( IrpContext,
2911  Vcb );
2912 
2913  //
2914  // Clear the VPB_MOUNTED bit. New opens should not come in due
2915  // to the swapped VPB, but having the flag cleared helps debugging.
2916  // Note that we must leave the Vpb->DeviceObject field set until
2917  // after the FatTearDownVcb call as closes will have to make their
2918  // way back to us.
2919  //
2920 
2921  ClearFlag( Vpb->Flags, VPB_MOUNTED );
2922 
2923  //
2924  // If this Vpb was locked, clear this flag now.
2925  //
2926 
2928 
2929  IoReleaseVpbSpinLock( SavedIrql );
2930 
2931  //
2932  // We are going to attempt the dismount, so mark the VCB as having
2933  // a dismount in progress.
2934  //
2935 
2938 
2939  //
2940  // Close down our internal opens.
2941  //
2942 
2943  FatTearDownVcb( IrpContext,
2944  Vcb );
2945 
2946  //
2947  // Process any delayed closes.
2948  //
2949 
2950  FatFspClose( Vcb );
2951 
2952  //
2953  // Grab the VPB lock again so that we can recheck our counts.
2954  //
2955 
2956  IoAcquireVpbSpinLock( &SavedIrql );
2957 
2958  //
2959  // See if we can delete this VCB.
2960  //
2961 
2962  if (Vcb->Vpb->ReferenceCount == 0 && Vcb->InternalOpenCount == 0) {
2963 
2964  Vpb->DeviceObject = NULL;
2965 
2966  IoReleaseVpbSpinLock( SavedIrql );
2967 
2968  FatDeleteVcb( IrpContext, Vcb );
2969 
2973  Vcb ) );
2974 
2975  VcbDeleted = TRUE;
2976 
2977  } else {
2978 
2979  IoReleaseVpbSpinLock( SavedIrql );
2980 
2983  }
2984 
2985  } else if (Force) {
2986 
2987  //
2988  // The requester is forcing the issue. We need to swap the VPB with our spare.
2989  //
2990 
2991  FatSwapVpb( IrpContext,
2992  Vcb );
2993 
2994  IoReleaseVpbSpinLock( SavedIrql );
2995 
2996  } else {
2997 
2998  //
2999  // Just drop the Vpb spinlock.
3000  //
3001 
3002  IoReleaseVpbSpinLock( SavedIrql );
3003  }
3004 
3005  return VcbDeleted;
3006 }
3007 
3008 
3009 VOID
3011  IN PIRP_CONTEXT IrpContext,
3012  PFCB Fcb,
3013  PDIRENT Dirent,
3015  )
3016 
3017 /*++
3018 
3019 Routine Description:
3020 
3021  This routine places the short name in the dirent in the first set of
3022  STRINGs in the Fcb. If a long file name (Lfn) was specified, then
3023  we must decide whether we will store its Oem equivolent in the same
3024  prefix table as the short name, or rather just save the upcased
3025  version of the UNICODE string in the FCB.
3026 
3027  For looking up Fcbs, the first approach will be faster, so we want to
3028  do this as much as possible. Here are the rules that I have thought
3029  through extensively to determine when it is safe to store only Oem
3030  version of the UNICODE name.
3031 
3032  - If the UNICODE name contains no extended characters (>0x80), use Oem.
3033 
3034  - Let U be the upcased version of the UNICODE name.
3035  Let Up(x) be the function that upcases a UNICODE string.
3036  Let Down(x) be the function that upcases a UNICODE string.
3037  Let OemToUni(x) be the function that converts an Oem string to Unicode.
3038  Let UniToOem(x) be the function that converts a Unicode string to Oem.
3039  Let BestOemFit(x) be the function that creates the Best uppercase Oem
3040  fit for the UNICODE string x.
3041 
3042  BestOemFit(x) = UniToOem(Up(OemToUni(UniToOem(x)))) <1>
3043 
3044  if (BestOemFit(U) == BestOemFit(Down(U)) <2>
3045 
3046  then I know that there exists no UNICODE string Y such that:
3047 
3048  Up(Y) == Up(U) <3>
3049 
3050  AND
3051 
3052  BestOemFit(U) != BestOemFit(Y) <4>
3053 
3054  Consider string U as a collection of one character strings. The
3055  conjecture is clearly true for each sub-string, thus it is true
3056  for the entire string.
3057 
3058  Equation <1> is what we use to convert an incoming unicode name in
3059  FatCommonCreate() to Oem. The double conversion is done to provide
3060  better visual best fitting for characters in the Ansi code page but
3061  not in the Oem code page. A single Nls routine is provided to do
3062  this conversion efficiently.
3063 
3064  The idea is that with U, I only have to worry about a case varient Y
3065  matching it in a unicode compare, and I have shown that any case varient
3066  of U (the set Y defined in equation <3>), when filtered through <1>
3067  (as in create), will match the Oem string defined in <1>.
3068 
3069  Thus I do not have to worry about another UNICODE string missing in
3070  the prefix lookup, but matching when comparing LFNs in the directory.
3071 
3072 Arguments:
3073 
3074  Fcb - The Fcb we are supposed to fill in. Note that ParentDcb must
3075  already be filled in.
3076 
3077  Dirent - The gives up the short name.
3078 
3079  Lfn - If provided, this gives us the long name.
3080 
3081 Return Value:
3082 
3083  None
3084 
3085 --*/
3086 
3087 {
3088 #ifndef __REACTOS__
3089  NTSTATUS Status;
3090 #endif
3091  ULONG i;
3092 
3093 #ifndef __REACTOS__
3094  OEM_STRING OemA;
3095  OEM_STRING OemB;
3096 #endif
3097  UNICODE_STRING Unicode;
3099  POEM_STRING LongOemName;
3100  PUNICODE_STRING LongUniName;
3101 
3102  PAGED_CODE();
3103 
3105 
3106  NT_ASSERT( ShortName->Buffer == NULL );
3107 
3108  _SEH2_TRY {
3109 
3110  //
3111  // First do the short name.
3112  //
3113 
3114  //
3115  // Copy over the case flags for the short name of the file
3116  //
3117 
3119 
3121 
3122  } else {
3123 
3125  }
3126 
3128 
3130 
3131  } else {
3132 
3134  }
3135 
3136  ShortName->MaximumLength = 16;
3138  16,
3140 
3141  Fat8dot3ToString( IrpContext, Dirent, FALSE, ShortName );
3142 
3144 
3145  //
3146  // If no Lfn was specified, we are done. In either case, set the
3147  // final name length.
3148  //
3149 
3151 
3152  if (!ARGUMENT_PRESENT(Lfn) || (Lfn->Length == 0)) {
3153 
3156 
3157  try_return( NOTHING );
3158  }
3159 
3160  //
3161  // If we already set up the full filename, we could be in trouble. If the fast
3162  // path for doing it already fired, FatSetFullFileNameInFcb, it will have missed
3163  // this and could have built the full filename out of the shortname of the file.
3164  //
3165  // At that point, disaster could be inevitable since the final name length will not
3166  // match. We use this to tell the notify package what to do - FatNotifyReportChange.
3167  //
3168 
3170 
3171  //
3172  // We know now we have an Lfn, save away a copy.
3173  //
3174 
3176 
3179  Lfn->Length,
3182 
3183  //
3184  // First check for no extended characters.
3185  //
3186 
3187  for (i=0; i < Lfn->Length/sizeof(WCHAR); i++) {
3188 
3189  if (Lfn->Buffer[i] >= 0x80) {
3190 
3191  break;
3192  }
3193  }
3194 
3195  if (i == Lfn->Length/sizeof(WCHAR)) {
3196 
3197  //
3198  // Cool, I can go with the Oem, upcase it fast by hand.
3199  //
3200 
3201  LongOemName = &Fcb->LongName.Oem.Name.Oem;
3202 
3203 
3204  LongOemName->Buffer = FsRtlAllocatePoolWithTag( PagedPool,
3205  Lfn->Length/sizeof(WCHAR),
3207  LongOemName->Length =
3208  LongOemName->MaximumLength = Lfn->Length/sizeof(WCHAR);
3209 
3210  for (i=0; i < Lfn->Length/sizeof(WCHAR); i++) {
3211 
3212  WCHAR c;
3213 
3214  c = Lfn->Buffer[i];
3215 
3216 #ifdef _MSC_VER
3217 #pragma warning( push )
3218 #pragma warning( disable:4244 )
3219 #endif
3220  LongOemName->Buffer[i] = c < 'a' ?
3221  (UCHAR)c :
3222  c <= 'z' ?
3223  c - (UCHAR)('a'-'A') :
3224  (UCHAR)c;
3225 #ifdef _MSC_VER
3226 #pragma warning( pop )
3227 #endif
3228  }
3229 
3230  //
3231  // If this name happens to be exactly the same as the short
3232  // name, don't add it to the splay table.
3233  //
3234 
3235  if (FatAreNamesEqual(IrpContext, *ShortName, *LongOemName) ||
3236  (FatFindFcb( IrpContext,
3237  &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3238  LongOemName,
3239  NULL) != NULL)) {
3240 
3241  ExFreePool( LongOemName->Buffer );
3242 
3243  LongOemName->Buffer = NULL;
3244  LongOemName->Length =
3245  LongOemName->MaximumLength = 0;
3246 
3247  } else {
3248 
3250  }
3251 
3252  try_return( NOTHING );
3253  }
3254 
3255  //
3256  // Now we have the fun part. Make a copy of the Lfn.
3257  //
3258 
3259 #ifndef __REACTOS__
3260  OemA.Buffer = NULL;
3261  OemB.Buffer = NULL;
3262 #endif
3263  Unicode.Buffer = NULL;
3264 
3265  Unicode.Length =
3266  Unicode.MaximumLength = Lfn->Length;
3268  Lfn->Length,
3270 
3271  RtlCopyMemory( Unicode.Buffer, Lfn->Buffer, Lfn->Length );
3272 
3273 #ifndef __REACTOS__
3275 #endif
3276 
3277 #if TRUE
3278  //
3279  // Unfortunately, this next block of code breaks down when you have
3280  // two long Unicode filenames that both map to the same Oem (and are,
3281  // well, long, i.e. are not the short names). In this case, with one
3282  // in the prefix table first, the other will hit the common Oem
3283  // representation. This leads to several forms of user astonishment.
3284  //
3285  // It isn't worth it, or probably even possible, to try to figure out
3286  // when this is really safe to go through. Simply omit the attempt.
3287  //
3288  // Ex: ANSI 0x82 and 0x84 in the 1252 ANSI->UNI and 437 UNI->OEM codepages.
3289  //
3290  // 0x82 => 0x201a => 0x2c
3291  // 0x84 => 0x201e => 0x2c
3292  //
3293  // 0x2c is comma, so is FAT Oem illegal and forces shortname generation.
3294  // Since it is otherwise well-formed by the rules articulated previously,
3295  // we would have put 0x2c in the Oem prefix tree. In terms of the
3296  // argument given above, even though there exist no Y and U s.t.
3297  //
3298  // Up(Y) == Up(U) && BestOemFit(U) != BestOemFit(Y)
3299  //
3300  // there most certainly exist Y and U s.t.
3301  //
3302  // Up(Y) != Up(U) && BestOemFit(U) == BestOemFit(Y)
3303  //
3304  // and that is enough to keep us from doing this. Note that the < 0x80
3305  // case is OK since we know that the mapping in the OEM codepages are
3306  // the identity in that range.
3307  //
3308  // We still need to monocase it, though. Do this through a full down/up
3309  // transition.
3310  //
3311 
3312  (VOID)RtlDowncaseUnicodeString( &Unicode, &Unicode, FALSE );
3313  (VOID)RtlUpcaseUnicodeString( &Unicode, &Unicode, FALSE );
3314 #else
3315  //
3316  // Downcase and convert to upcased Oem. Only continue if we can
3317  // convert without error. Any error other than UNMAPPABLE_CHAR
3318  // is a fatal error and we raise.
3319  //
3320  // Note that even if the conversion fails, we must leave Unicode
3321  // in an upcased state.
3322  //
3323  // NB: The Rtl doesn't NULL .Buffer on error.
3324  //
3325 
3326  (VOID)RtlDowncaseUnicodeString( &Unicode, &Unicode, FALSE );
3328  (VOID)RtlUpcaseUnicodeString( &Unicode, &Unicode, FALSE );
3329 
3330  if (!NT_SUCCESS(Status)) {
3331 
3333 
3335  ExFreePool(Unicode.Buffer);
3336  FatNormalizeAndRaiseStatus( IrpContext, Status );
3337  }
3338 
3339  } else {
3340 
3341  //
3342  // The same as above except upcase.
3343  //
3344 
3346 
3347  if (!NT_SUCCESS(Status)) {
3348 
3349  RtlFreeOemString( &OemA );
3350 
3352 
3354  ExFreePool(Unicode.Buffer);
3355  FatNormalizeAndRaiseStatus( IrpContext, Status );
3356  }
3357  }
3358  }
3359 
3360  //
3361  // If the final OemNames are equal, I can use save only the Oem
3362  // name. If the name did not map, then I have to go with the UNICODE
3363  // name because I could get a case varient that didn't convert
3364  // in create, but did match the LFN.
3365  //
3366 
3367  if (NT_SUCCESS(Status) && FatAreNamesEqual( IrpContext, OemA, OemB )) {
3368 
3369  //
3370  // Cool, I can go with the Oem. If we didn't convert correctly,
3371  // get a fresh convert from the original LFN.
3372  //
3373 
3374  ExFreePool(Unicode.Buffer);
3375 
3376  RtlFreeOemString( &OemB );
3377 
3378  Fcb->LongName.Oem.Name.Oem = OemA;
3379 
3380  //
3381  // If this name happens to be exactly the same as the short
3382  // name, or a similar short name already exists don't add it
3383  // to the splay table (note the final condition implies a
3384  // corrupt disk.
3385  //
3386 
3387  if (FatAreNamesEqual(IrpContext, *ShortName, OemA) ||
3388  (FatFindFcb( IrpContext,
3389  &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3390  &OemA,
3391  NULL) != NULL)) {
3392 
3393  RtlFreeOemString( &OemA );
3394 
3395  } else {
3396 
3398  }
3399 
3400  try_return( NOTHING );
3401  }
3402 
3403  //
3404  // The long name must be left in UNICODE. Free the two Oem strings
3405  // if we got here just because they weren't equal.
3406  //
3407 
3408  if (NT_SUCCESS(Status)) {
3409 
3410  RtlFreeOemString( &OemA );
3411  RtlFreeOemString( &OemB );
3412  }
3413 #endif
3414 
3415  LongUniName = &Fcb->LongName.Unicode.Name.Unicode;
3416 
3417  LongUniName->Length =
3418  LongUniName->MaximumLength = Unicode.Length;
3419  LongUniName->Buffer = Unicode.Buffer;
3420 
3422 
3423  try_exit: NOTHING;
3424  } _SEH2_FINALLY {
3425 
3426  if (_SEH2_AbnormalTermination()) {
3427 
3428  if (ShortName->Buffer != NULL) {
3429 
3430  ExFreePool( ShortName->Buffer );
3431  ShortName->Buffer = NULL;
3432  }
3433 
3434  } else {
3435 
3436  //
3437  // Creating all the names worked, so add all the names
3438  // to the splay tree.
3439  //
3440 
3441  FatInsertName( IrpContext,
3442  &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3443  &Fcb->ShortName );
3444 
3445  Fcb->ShortName.Fcb = Fcb;
3446 
3448 
3449  FatInsertName( IrpContext,
3450  &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3451  &Fcb->LongName.Oem );
3452 
3453  Fcb->LongName.Oem.Fcb = Fcb;
3454  }
3455 
3457 
3458  FatInsertName( IrpContext,
3459  &Fcb->ParentDcb->Specific.Dcb.RootUnicodeNode,
3460  &Fcb->LongName.Unicode );
3461 
3462  Fcb->LongName.Unicode.Fcb = Fcb;
3463  }
3464 
3466  }
3467  } _SEH2_END;
3468 
3469  return;
3470 }
3471 
3472 
3473 _Requires_lock_held_(_Global_critical_region_)
3474 VOID
3475 FatCheckFreeDirentBitmap (
3476  IN PIRP_CONTEXT IrpContext,
3477  IN PDCB Dcb
3478  )
3479 
3480 /*++
3481 
3482 Routine Description:
3483 
3484  This routine checks if the size of the free dirent bitmap is
3485  sufficient to for the current directory size. It is called
3486  whenever we grow a directory.
3487 
3488 Arguments:
3489 
3490  Dcb - Supplies the directory in question.
3491 
3492 Return Value:
3493 
3494  None
3495 
3496 --*/
3497 
3498 {
3499  ULONG OldNumberOfDirents;
3500  ULONG NewNumberOfDirents;
3501 
3502  PAGED_CODE();
3503  UNREFERENCED_PARAMETER( IrpContext );
3504 
3505  //
3506  // Setup the Bitmap buffer if it is not big enough already
3507  //
3508 
3509  NT_ASSERT( Dcb->Header.AllocationSize.QuadPart != FCB_LOOKUP_ALLOCATIONSIZE_HINT );
3510 
3511  OldNumberOfDirents = Dcb->Specific.Dcb.FreeDirentBitmap.SizeOfBitMap;
3512  NewNumberOfDirents = Dcb->Header.AllocationSize.LowPart / sizeof(DIRENT);
3513 
3514  //
3515  // Do the usual unsync/sync check.
3516  //
3517 
3518  if (NewNumberOfDirents > OldNumberOfDirents) {
3519 
3521 
3522  _SEH2_TRY {
3523 
3524  PULONG OldBitmapBuffer;
3526 
3527  ULONG BytesInBitmapBuffer;
3528  ULONG BytesInOldBitmapBuffer;
3529 
3530  OldNumberOfDirents = Dcb->Specific.Dcb.FreeDirentBitmap.SizeOfBitMap;
3531  NewNumberOfDirents = Dcb->Header.AllocationSize.LowPart / sizeof(DIRENT);
3532 
3533  if (NewNumberOfDirents > OldNumberOfDirents) {
3534 
3535  //
3536  // Remember the old bitmap
3537  //
3538 
3539  OldBitmapBuffer = Dcb->Specific.Dcb.FreeDirentBitmap.Buffer;
3540 
3541  //
3542  // Now make a new bitmap bufffer
3543  //
3544 
3545  BytesInBitmapBuffer = NewNumberOfDirents / 8;
3546 
3547  BytesInOldBitmapBuffer = OldNumberOfDirents / 8;
3548 
3549  if (DCB_UNION_SLACK_SPACE >= BytesInBitmapBuffer) {
3550 
3551  BitmapBuffer = &Dcb->Specific.Dcb.FreeDirentBitmapBuffer[0];
3552 
3553  } else {
3554 
3556  BytesInBitmapBuffer,
3558  }
3559 
3560  //
3561  // Copy the old buffer to the new buffer, free the old one, and zero
3562  // the rest of the new one. Only do the first two steps though if
3563  // we moved out of the initial buffer.
3564  //
3565 
3566  if ((OldNumberOfDirents != 0) &&
3567  (BitmapBuffer != &Dcb->Specific.Dcb.FreeDirentBitmapBuffer[0])) {
3568 
3570  OldBitmapBuffer,
3571  BytesInOldBitmapBuffer );
3572 
3573  if (OldBitmapBuffer != &Dcb->Specific.Dcb.FreeDirentBitmapBuffer[0]) {
3574 
3575  ExFreePool( OldBitmapBuffer );
3576  }
3577  }
3578 
3579  NT_ASSERT( BytesInBitmapBuffer > BytesInOldBitmapBuffer );
3580 
3581  RtlZeroMemory( (PUCHAR)BitmapBuffer + BytesInOldBitmapBuffer,
3582  BytesInBitmapBuffer - BytesInOldBitmapBuffer );
3583 
3584  //
3585  // Now initialize the new bitmap.
3586  //
3587 
3588  RtlInitializeBitMap( &Dcb->Specific.Dcb.FreeDirentBitmap,
3589  BitmapBuffer,
3590  NewNumberOfDirents );
3591  }
3592 
3593  } _SEH2_FINALLY {
3594 
3596  } _SEH2_END;
3597  }
3598 }
3599 
3600 
3601 BOOLEAN
3603  IN PIRP_CONTEXT IrpContext,
3604  IN PVCB Vcb
3605  )
3606 
3607 /*++
3608 
3609 Routine Description:
3610 
3611  This routine decides if the handle count on the volume is zero.
3612 
3613 Arguments:
3614 
3615  Vcb - The volume in question
3616 
3617 Return Value:
3618 
3619  BOOLEAN - TRUE if there are no open handles on the volume, FALSE
3620  otherwise.
3621 
3622 --*/
3623 
3624 {
3625  PFCB Fcb;
3626 
3627  PAGED_CODE();
3628 
3629  Fcb = Vcb->RootDcb;
3630 
3631  while (Fcb != NULL) {
3632 
3633  if (Fcb->UncleanCount != 0) {
3634 
3635  return FALSE;
3636  }
3637 
3638  Fcb = FatGetNextFcbTopDown(IrpContext, Fcb, Vcb->RootDcb);
3639  }
3640 
3641  return TRUE;
3642 }
3643 
3644 
3646 
3648  OPTIONAL PVCB Vcb
3649  )
3650 /*++
3651 
3652 Routine Description:
3653 
3654  This routine preallocates a close context, presumeably on behalf
3655  of a fileobject which does not have a structure we can embed one
3656  in.
3657 
3658 Arguments:
3659 
3660  None.
3661 
3662 Return Value:
3663 
3664  None.
3665 
3666 --*/
3667 {
3668  PAGED_CODE();
3670 
3671 #if DBG
3672  if (ARGUMENT_PRESENT(Vcb)) {
3673 
3674  NT_ASSERT( 0 != Vcb->CloseContextCount);
3675  InterlockedDecrement( (LONG*)&Vcb->CloseContextCount);
3676  }
3677 #endif
3680 }
3681 
3682 
3683 VOID
3685  PVCB Vcb
3686  )
3687 
3688 /*++
3689 
3690 Routine Description:
3691 
3692  This routine preallocates a close context, presumeably on behalf
3693  of a fileobject which does not have a structure we can embed one
3694  in.
3695 
3696 Arguments:
3697 
3698  None.
3699 
3700 Return Value:
3701 
3702  None.
3703 
3704 --*/
3705 
3706 {
3707  PCLOSE_CONTEXT CloseContext;
3708 
3709  PAGED_CODE();
3710 
3712 
3713  CloseContext = FsRtlAllocatePoolWithTag( PagedPool,
3714  sizeof(CLOSE_CONTEXT),
3716 
3718  (PSLIST_ENTRY) CloseContext,
3720 
3721  DbgDoit( InterlockedIncrement( (LONG*)&Vcb->CloseContextCount));
3722 }
3723 
3724 
3725 
3726 VOID
3729  _In_ USHORT DesiredBufferSize
3730  )
3731 
3732 /*++
3733 
3734 Routine Description:
3735 
3736  Ensures that a string string (STRING, UNICODE_STRING, ANSI_STRING, OEM_STRING)
3737  has a buffer >= DesiredBufferSize, allocating from pool if neccessary. Any
3738  existing pool buffer will be freed if a new one is allocated.
3739 
3740  NOTE: No copy of old buffer contents is performed on reallocation.
3741 
3742  Will raise on allocation failure.
3743 
3744 Arguments:
3745 
3746  String - pointer to string structure
3747 
3748  DesiredBufferSize - (bytes) minimum required buffer size
3749 
3750 --*/
3751 
3752 {
3753  PSTRING LocalString = String;
3754 
3755  PAGED_CODE();
3756 
3757  if (LocalString->MaximumLength < DesiredBufferSize) {
3758 
3759  FatFreeStringBuffer( LocalString);
3760 
3761  LocalString->Buffer = FsRtlAllocatePoolWithTag( PagedPool,
3762  DesiredBufferSize,
3764  NT_ASSERT( LocalString->Buffer);
3765 
3766  LocalString->MaximumLength = DesiredBufferSize;
3767  }
3768 }
3769 
3770 
3771 VOID
3774  )
3775 
3776 /*++
3777 
3778 Routine Description:
3779 
3780  Frees the buffer of an string (STRING, UNICODE_STRING, ANSI_STRING, OEM_STRING)
3781  structure if it is not within the current thread's stack limits.
3782 
3783  Regardless of action performed, on exit String->Buffer will be set to NULL and
3784  String->MaximumLength to zero.
3785 
3786 Arguments:
3787 
3788  String - pointer to string structure
3789 
3790 --*/
3791 
3792 {
3793  ULONG_PTR High, Low;
3794  PSTRING LocalString = String;
3795 
3796  PAGED_CODE();
3797 
3798  if (NULL != LocalString->Buffer) {
3799 
3800  IoGetStackLimits( &Low, &High );
3801 
3802  if (((ULONG_PTR)(LocalString->Buffer) < Low) ||
3803  ((ULONG_PTR)(LocalString->Buffer) > High)) {
3804 
3805  ExFreePool( LocalString->Buffer);
3806  }
3807 
3808  LocalString->Buffer = NULL;
3809  }
3810 
3811  LocalString->MaximumLength = LocalString->Length = 0;
3812 }
3813 
3814 
3815 BOOLEAN
3817  IN PIRP_CONTEXT IrpContext,
3819  )
3820 
3821 /*++
3822 
3823 Routine Description:
3824 
3825  This routine is called to verify and process the TOC for this disk.
3826 
3827  FAT queries for the TOC to avoid trying to mount on CD-DA/CD-E media, Doing data reads on
3828  audio/leadin of that media sends a lot of drives into what could charitably be called
3829  "conniptions" which take a couple seconds to clear and would also convince FAT that the
3830  device was busted, and fail the mount (not letting CDFS get its crack).
3831 
3832  There is special handling of PD media. These things fail the TOC read, but return
3833  a special error code so FAT knows to continue to try the mount anyway.
3834 
3835 Arguments:
3836 
3837  TargetDeviceObject - Device object to send TOC request to.
3838 
3839 Return Value:
3840 
3841  BOOLEAN - TRUE if we found a TOC with a single data track.
3842 
3843 --*/
3844 
3845 {
3846  NTSTATUS Status;
3848 
3849  ULONG LocalTrackCount;
3850  ULONG LocalTocLength;
3851 
3852  PCDROM_TOC CdromToc;
3853  BOOLEAN Result = FALSE;
3854 
3855  PAGED_CODE();
3856 
3857  CdromToc = FsRtlAllocatePoolWithTag( PagedPool,
3858  sizeof( CDROM_TOC ),
3859  TAG_IO_BUFFER );
3860 
3861  RtlZeroMemory( CdromToc, sizeof( CDROM_TOC ));
3862 
3863  _SEH2_TRY {
3864 
3865  //
3866  // Go ahead and read the table of contents
3867  //
3868 
3869  Status = FatPerformDevIoCtrl( IrpContext,
3872  NULL,
3873  0,
3874  CdromToc,
3875  sizeof( CDROM_TOC ),
3876  FALSE,
3877  TRUE,
3878  &Iosb );
3879 
3880  //
3881  // Nothing to process if this request fails.
3882  //
3883 
3884  if (Status != STATUS_SUCCESS) {
3885 
3886  //
3887  // If we get the special error indicating a failed TOC read on PD media just
3888  // plow ahead with the mount (see comments above).
3889  //
3890 
3892 
3893  Result = TRUE;
3894 
3895  }
3896 
3897  try_leave( NOTHING );
3898  }
3899 
3900  //
3901  // Get the number of tracks and stated size of this structure.
3902  //
3903 
3904  LocalTrackCount = CdromToc->LastTrack - CdromToc->FirstTrack + 1;
3905  LocalTocLength = PtrOffset( CdromToc, &CdromToc->TrackData[LocalTrackCount + 1] );
3906 
3907  //
3908  // Get out if there is an immediate problem with the TOC, or more than
3909  // one track.
3910  //
3911 
3912  if ((LocalTocLength > Iosb.Information) ||
3913  (CdromToc->FirstTrack > CdromToc->LastTrack) ||
3914  (LocalTrackCount != 1)) {
3915 
3916  try_leave( NOTHING);
3917  }
3918 
3919  //
3920  // Is it a data track? DVD-RAM reports single, data, track.
3921  //
3922 
3923  Result = BooleanFlagOn( CdromToc->TrackData[ 0].Control, 0x04 );
3924  }
3925  _SEH2_FINALLY {
3926 
3927  ExFreePool( CdromToc);
3928  } _SEH2_END;
3929 
3930  return Result;
3931 }
3932 
3933 
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1303
PFCB FatGetNextFcbBottomUp(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb OPTIONAL, IN PFCB TerminationFcb)
Definition: strucsup.c:2513
struct _FCB * Fcb
Definition: fatstruc.h:684
#define DbgDoit(X)
Definition: fatdata.h:336
LONGLONG CreationTime
Definition: cdstruc.h:1036
#define FatReleaseDirectoryFileMutex(VCB)
Definition: fatprocs.h:1513
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:921
#define TAG_FCB
Definition: vfat.h:541
#define IN
Definition: typedefs.h:39
FatSetFileObject(FileObject, UserDirectoryOpen,(*Dcb), UnwindCcb=FatCreateCcb(IrpContext))
#define FCB_STATE_SYSTEM_FILE
Definition: fatstruc.h:1198
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define FatReleaseGlobal(IRPCONTEXT)
Definition: fatprocs.h:1636
#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:2992
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define TAG_DYNAMIC_NAME_BUFFER
Definition: nodetype.h:186
INLINE VOID FatFreeIrpContext(IN PIRP_CONTEXT IrpContext)
Definition: strucsup.c:174
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1240
#define DebugDoit(X)
Definition: fatdata.h:316
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
USHORT Flags
Definition: iotypes.h:171
LARGE_INTEGER FatFatDateToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_DATE FatDate)
Definition: timesup.c:171
FILE_NAME_NODE Oem
Definition: fatstruc.h:1158
VOID FatTearDownVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: strucsup.c:672
#define VCB_STATE_FLAG_DEFERRED_FLUSH
Definition: fatstruc.h:567
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1261
UCHAR FirstTrack
Definition: ntddcdrm.h:197
#define PtrOffset(BASE, OFFSET)
Definition: cdprocs.h:1547
#define IRP_MJ_SHUTDOWN
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING Lfn
Definition: create.c:4137
#define Dbg
Definition: strucsup.c:29
BOOLEAN DeviceHotplug
Definition: imports.h:248
_In_ PIRP Irp
Definition: csq.h:116
INLINE VOID FatFreeNonPagedFcb(PNON_PAGED_FCB NonPagedFcb)
Definition: strucsup.c:112
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
Definition: cdstruc.h:908
VOID Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
Definition: namesup.c:179
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
struct _FCB::@712::@715 Fcb
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1278
#define VCB_STATE_FLAG_DISMOUNT_IN_PROGRESS
Definition: fatstruc.h:574
#define IRP_CONTEXT_STACK_IO_CONTEXT
Definition: ext2fs.h:1084
union _FCB::@713 LongName
#define CCB_FLAG_FREE_OEM_BEST_FIT
Definition: fatstruc.h:1258
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
LARGE_INTEGER FatLargeZero
Definition: fatdata.c:62
Definition: cdstruc.h:1073
unsigned char * PUCHAR
Definition: retypes.h:3
#define FSRTL_FLAG2_IS_PAGING_FILE
Definition: fsrtltypes.h:57
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPushEntrySList(union _SLIST_HEADER *, struct _SINGLE_LIST_ENTRY *, unsigned long *)
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
LONG NTSTATUS
Definition: precomp.h:26
PFCB FatFindFcb(IN PIRP_CONTEXT IrpContext, IN OUT PRTL_SPLAY_LINKS *RootNode, IN PSTRING Name, OUT PBOOLEAN FileNameDos OPTIONAL)
Definition: splaysup.c:306
#define FatDeviceIsFatFsdo(D)
Definition: fatprocs.h:3092
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:151
FCB DCB
Definition: fatstruc.h:1183
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
#define IRP_NOCACHE
SLIST_HEADER FatCloseContextSList
Definition: fatdata.c:106
#define ExRaiseStatus
Definition: ntoskrnl.h:96
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:877
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define FCB_STATE_3_LOWER_CASE
Definition: fatstruc.h:1210
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
#define FCB_STATE_HAS_UNICODE_LONG_NAME
Definition: fatstruc.h:1201
Definition: cdstruc.h:504
unsigned short Length
Definition: sprintf.c:451
Definition: strmini.h:380
struct _FCB::@712::@714 Dcb
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
VOID FatDeleteVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: strucsup.c:760
static WCHAR String[]
Definition: stringtable.c:55
BOOLEAN ChicagoMode
Definition: fatstruc.h:86
static CC_FILE_SIZES FileSizes
VOID NTAPI FsRtlUninitializeOplock(IN POPLOCK Oplock)
Definition: oplock.c:1602
STRING OEM_STRING
Definition: umtypes.h:203
LIST_ENTRY ParentDcbLinks
Definition: fatstruc.h:827
ULONG VcbState
Definition: cdstruc.h:546
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB ParentDcb
Definition: create.c:4137
#define InsertTailList(ListHead, Entry)
NPAGED_LOOKASIDE_LIST FatNonPagedFcbLookasideList
Definition: fatdata.c:103
VOLUME_DEVICE_OBJECT * PVOLUME_DEVICE_OBJECT
Definition: cdstruc.h:775
#define FAT_NTC_CCB
Definition: nodetype.h:32
VOID FatFreeStringBuffer(_Inout_ PVOID String)
Definition: strucsup.c:3772
struct _PACKED_BOOT_SECTOR PACKED_BOOT_SECTOR
struct _FCB * ParentDcb
Definition: fatstruc.h:835
#define TAG_VPB
Definition: cdprocs.h:106
KDEFERRED_ROUTINE FatCleanVolumeDpc
Definition: fatprocs.h:1981
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
INLINE VOID FatFreeCcb(IN PCCB Ccb)
Definition: strucsup.c:64
PDCB FatCreateDcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PDCB ParentDcb, IN ULONG LfnOffsetWithinDirectory, IN ULONG DirentOffsetWithinDirectory, IN PDIRENT Dirent, IN PUNICODE_STRING Lfn OPTIONAL)
Definition: strucsup.c:1611
LARGE_INTEGER FileSize
Definition: cctypes.h:16
NPAGED_LOOKASIDE_LIST FatIrpContextLookasideList
Definition: fatdata.c:102
_SEH2_TRY
Definition: create.c:4226
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
INLINE PIRP_CONTEXT FatAllocateIrpContext()
Definition: strucsup.c:163
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FAT_DIRENT_NT_BYTE_8_LOWER_CASE
Definition: fat.h:361
BOOLEAN FileNameDos
Definition: fatstruc.h:703
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FatGetFirstChild(DIR)
Definition: fatprocs.h:1785
BOOLEAN MediaHotplug
Definition: imports.h:247
LARGE_INTEGER FatFatTimeToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_TIME_STAMP FatTime, _In_ UCHAR TenMilliSeconds)
Definition: timesup.c:233
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
NTSYSAPI NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN)
void * Buffer
Definition: sprintf.c:453
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:920
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define FCB_STATE_NAMES_IN_SPLAY_TREE
Definition: fatstruc.h:1199
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPopEntrySList(union _SLIST_HEADER *, unsigned long *)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
ULONG NumberProcessors
Definition: fatstruc.h:80
#define FALSE
Definition: types.h:117
struct _VCB VCB
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1194
#define FSCTL_INVALIDATE_VOLUMES
Definition: nt_native.h:847
long LONG
Definition: pedump.c:60
LARGE_INTEGER FatJanOne1980
Definition: fatdata.c:73
union _FILE_NAME_NODE::@711 Name
#define FatGetFcbOplock(F)
Definition: fatprocs.h:1656
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define VPB_LOCKED
Definition: iotypes.h:1788
BOOLEAN FatScanForDataTrack(IN PIRP_CONTEXT IrpContext, IN PDEVICE_OBJECT TargetDeviceObject)
Definition: strucsup.c:3816
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
UCHAR DirentFatFlags
Definition: fatstruc.h:1132
VOID FatDeleteCcb(IN PIRP_CONTEXT IrpContext, IN PCCB *Ccb)
Definition: strucsup.c:2242
PNON_PAGED_FCB NonPaged
Definition: fatstruc.h:810
VOID NTAPI FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType)
Definition: largemcb.c:450
#define NTC_UNDEFINED
Definition: nodetype.h:25
unsigned char BOOLEAN
struct _FCB FCB
smooth NULL
Definition: ftsmooth.c:416
FILE_NAME_NODE Unicode
Definition: fatstruc.h:1165
#define VCB_STATE_FLAG_HOTPLUGGABLE
Definition: fatstruc.h:576
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define FatRootDirectorySize(B)
Definition: fat.h:427
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define MAXIMUM_VOLUME_LABEL_LENGTH
Definition: iotypes.h:156
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:559
PFCB FatGetNextFcbTopDown(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
Definition: strucsup.c:2615
VOID FatTearDownAllocationSupport(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: allocsup.c:547
NodeType
Definition: Node.h:5
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
#define CCB_FLAG_FREE_UNICODE
Definition: fatstruc.h:1259
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS FatPerformDevIoCtrl(IN PIRP_CONTEXT IrpContext, IN ULONG IoControlCode, IN PDEVICE_OBJECT Device, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: deviosup.c:3621
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3186
#define FatAcquireDirectoryFileMutex(VCB)
Definition: fatprocs.h:1508
OEM_STRING Oem
Definition: fatstruc.h:692
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
#define try_leave(S)
Definition: cdprocs.h:2180
VOID FatRemoveNames(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: splaysup.c:222
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4383
VOID FatDeleteIrpContext_Real(IN PIRP_CONTEXT IrpContext)
Definition: strucsup.c:2449
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3495
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4382
#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
BOOLEAN WriteCacheEnableOverride
Definition: imports.h:249
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2289
VOID NTAPI FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader)
Definition: filtrctx.c:368
#define INLINE
Definition: rosdhcp.h:56
PCLOSE_CONTEXT FatAllocateCloseContext(OPTIONAL PVCB Vcb)
Definition: strucsup.c:3647
#define VCB_STATE_FLAG_LOCKED
Definition: fatstruc.h:558
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define VPB_DIRECT_WRITES_ALLOWED
Definition: iotypes.h:1792
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FatGetNextSibling(FILE)
Definition: fatprocs.h:1791
#define try_return(S)
Definition: cdprocs.h:2179
VOID FatInsertName(IN PIRP_CONTEXT IrpContext, IN PRTL_SPLAY_LINKS *RootNode, IN PFILE_NAME_NODE Name)
Definition: splaysup.c:39
INT POOL_TYPE
Definition: typedefs.h:78
#define ARGUMENT_PRESENT(ArgumentPointer)
VOID NTAPI FsRtlInitializeOplock(IN OUT POPLOCK Oplock)
Definition: oplock.c:1402
#define IRP_MJ_FILE_SYSTEM_CONTROL
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:174
VBO LfnOffsetWithinDirectory
Definition: fatstruc.h:912
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define Vcb
Definition: cdprocs.h:1415
VOID NTAPI FsRtlInitializeTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:891
const GLubyte * c
Definition: glext.h:8905
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS
Definition: fsrtltypes.h:55
BOOLEAN FatSwapVpb(IN PIRP_CONTEXT IrpContext, PVCB Vcb)
Definition: strucsup.c:2718
#define PSLIST_ENTRY
Definition: rtltypes.h:134
#define _Inout_
Definition: no_sal2.h:244
#define TAG_FILENAME_BUFFER
Definition: nodetype.h:167
VOID FatDeleteFcb(IN PIRP_CONTEXT IrpContext, IN PFCB *FcbPtr)
Definition: strucsup.c:1940
#define TAG_CCB
Definition: cdprocs.h:85
* PFILE_OBJECT
Definition: iotypes.h:1978
struct _IRP_CONTEXT IRP_CONTEXT
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
NPAGED_LOOKASIDE_LIST FatEResourceLookasideList
Definition: fatdata.c:104
UNICODE_STRING FullFileName
Definition: fatstruc.h:1121
Definition: strmini.h:378
#define FAT_FILL_FREE
Definition: strucsup.c:52
ULONG Flags
Definition: ntfs.h:532
UCHAR LastTrack
Definition: ntddcdrm.h:198
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
CD_MCB Mcb
Definition: cdstruc.h:1022
FAST_MUTEX AdvancedFcbHeaderMutex
Definition: fatstruc.h:749
unsigned char UCHAR
Definition: xmlstorage.h:181
INLINE VOID FatFreeResource(IN PERESOURCE Resource)
Definition: strucsup.c:145
VOID FatPreallocateCloseContext(PVCB Vcb)
Definition: strucsup.c:3684
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
Status
Definition: gdiplustypes.h:24
#define TAG_DIRENT_BITMAP
Definition: nodetype.h:159
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
#define DCB_UNION_SLACK_SPACE
Definition: fatstruc.h:1229
#define FAT_NTC_IRP_CONTEXT
Definition: nodetype.h:33
UCHAR Control
Definition: ntddcdrm.h:137
#define VOID
Definition: acefi.h:82
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB IN PDEVICE_OBJECT FsDeviceObject
Definition: fatprocs.h:1673
CLONG UncleanCount
Definition: fatstruc.h:872
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
struct _CCB CCB
LARGE_INTEGER ValidDataLength
Definition: cctypes.h:17
#define FCB_STATE_8_LOWER_CASE
Definition: fatstruc.h:1209
#define NOTHING
Definition: env_spec_w32.h:461
Definition: typedefs.h:119
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define FatAreNamesEqual(IRPCONTEXT, NAMEA, NAMEB)
Definition: fatprocs.h:1158
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446
#define FatSetVcbCondition(V, X)
Definition: fatprocs.h:1438
#define FCB_STATE_HAS_OEM_LONG_NAME
Definition: fatstruc.h:1200
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
#define IO_TYPE_VPB
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
PFCB FatCreateFcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PDCB ParentDcb, IN ULONG LfnOffsetWithinDirectory, IN ULONG DirentOffsetWithinDirectory, IN PDIRENT Dirent, IN PUNICODE_STRING Lfn OPTIONAL, IN PUNICODE_STRING OrigLfn OPTIONAL, IN BOOLEAN IsPagingFile, IN BOOLEAN SingleResource)
Definition: strucsup.c:1240
struct _VPB VPB
INLINE VOID FatFreeFcb(IN PFCB Fcb)
Definition: strucsup.c:85
BOOLEAN FatAddMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN LBO Lbo, IN ULONG SectorCount)
Definition: fsctrl.c:364
LIST_ENTRY VcbQueue
Definition: fatstruc.h:48
INLINE PFCB FatAllocateFcb()
Definition: strucsup.c:77
#define _In_
Definition: no_sal2.h:204
UNICODE_STRING Unicode
Definition: fatstruc.h:694
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
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:3148
#define FAT_DIRENT_NT_BYTE_3_LOWER_CASE
Definition: fat.h:362
_SEH2_END
Definition: create.c:4400
VBO DirentOffsetWithinDirectory
Definition: fatstruc.h:905
LARGE_INTEGER AllocationSize
Definition: cctypes.h:15
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_UNMAPPABLE_CHARACTER
Definition: ntstatus.h:590
ULONG ValidDataToDisk
Definition: fatstruc.h:927
unsigned short USHORT
Definition: pedump.c:61
PCCB FatCreateCcb(IN PIRP_CONTEXT IrpContext)
Definition: strucsup.c:2143
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:286
#define ExLocalTimeToSystemTime(LocTime, SysTime)
Definition: env_spec_w32.h:738
INLINE PCCB FatAllocateCcb()
Definition: strucsup.c:56
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PKEVENT OutstandingAsyncEvent
Definition: fatstruc.h:742
#define VCB_STATE_FLAG_VPB_MUST_BE_FREED
Definition: fatstruc.h:573
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
VOID FatDeallocateCcbStrings(IN PCCB Ccb)
Definition: strucsup.c:2197
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define IsFileWriteThrough(FO, VCB)
Definition: fatprocs.h:2793
_SEH2_FINALLY
Definition: create.c:4371
VOID NTAPI FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb)
Definition: largemcb.c:1053
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI IoGetStackLimits(OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit)
Definition: util.c:78
CLONG OpenCount
Definition: fatstruc.h:880
#define TAG_IO_BUFFER
Definition: cdprocs.h:95
#define SL_WRITE_THROUGH
Definition: iotypes.h:1804
#define FAT_NTC_DCB
Definition: nodetype.h:30
ULONG FirstClusterOfFile
Definition: fatstruc.h:817
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
Definition: fatprocs.h:1495
VOID NTAPI RtlFreeOemString(POEM_STRING OemString)
#define IRP_MJ_CLEANUP
VOID FatCloseEaFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN FlushFirst)
Definition: cachesup.c:1079
VOID NTAPI FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1561
Definition: iotypes.h:168
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
#define DIRENT
Definition: fatfs.h:187
#define c
Definition: ke_i.h:80
ULONG ERESOURCE
Definition: env_spec_w32.h:594
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]
Definition: ntddcdrm.h:199
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:424
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1561
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PVCB Vcb
Definition: cdstruc.h:939
#define FAT_NTC_VCB
Definition: nodetype.h:28
#define FatRootDirectoryLbo(B)
Definition: fat.h:445
#define TAG_VCB_STATS
Definition: nodetype.h:171
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1639
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
struct _FILE_SYSTEM_STATISTICS FILE_SYSTEM_STATISTICS
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
VOID NTAPI FsRtlDeleteTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:690
BOOLEAN MediaRemovable
Definition: imports.h:246
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1673
#define TAG_FAT_CLOSE_CONTEXT
Definition: nodetype.h:164
return STATUS_SUCCESS
Definition: btrfs.c:3014
unsigned short MaximumLength
Definition: sprintf.c:452
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
USHORT FinalNameLength
Definition: fatstruc.h:1123
#define VPB_MOUNTED
Definition: iotypes.h:1787
INLINE PERESOURCE FatAllocateResource()
Definition: strucsup.c:128
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1114
_Requires_lock_held_(_Global_critical_region_)
Definition: strucsup.c:1915
#define CCB_FLAG_CLOSE_CONTEXT
Definition: fatstruc.h:1323
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4137
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220
#define FatDeleteResource(RESRC)
Definition: fatprocs.h:1632
ULONG FcbState
Definition: cdstruc.h:977
unsigned short * PUSHORT
Definition: retypes.h:2
union _FCB::@712 Specific
INLINE PNON_PAGED_FCB FatAllocateNonPagedFcb()
Definition: strucsup.c:101
#define FAT_NTC_FCB
Definition: nodetype.h:29
UNICODE_STRING ExactCaseLongName
Definition: fatstruc.h:1138
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define FILESYSTEM_STATISTICS_TYPE_FAT
Definition: winioctl.h:673
#define RtlOemStringToCountedUnicodeSize(STRING)
VOID FatConstructNamesInFcb(IN PIRP_CONTEXT IrpContext, PFCB Fcb, PDIRENT Dirent, PUNICODE_STRING Lfn OPTIONAL)
Definition: strucsup.c:3010
LONGLONG QuadPart
Definition: typedefs.h:114
VOID FatEnsureStringBufferEnough(_Inout_ PVOID String, _In_ USHORT DesiredBufferSize)
Definition: strucsup.c:3727
#define FatAcquireExclusiveGlobal(IRPCONTEXT)
Definition: fatprocs.h:1387
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1415
#define PAGED_CODE()
IN BOOLEAN Wait
Definition: fatprocs.h:1538
#define DebugDump(STR, LEVEL, PTR)
Definition: fatdata.h:314
#define NT_ASSERT
Definition: rtlfuncs.h:3312
BOOLEAN FatIsHandleCountZero(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: strucsup.c:3602
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
FCB_CONDITION FcbCondition
Definition: fatstruc.h:849
CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks
Definition: fatstruc.h:159