ReactOS 0.4.15-dev-7907-g95bf896
strucsup.c File Reference
#include "fatprocs.h"
Include dependency graph for strucsup.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (FAT_BUG_CHECK_STRUCSUP)
 
#define Dbg   (DEBUG_TRACE_STRUCSUP)
 
#define FillMemory(BUF, SIZ, MASK)
 
#define IRP_CONTEXT_HEADER   (sizeof( IRP_CONTEXT ) * 0x10000 + FAT_NTC_IRP_CONTEXT)
 
#define FAT_FILL_FREE   0
 

Functions

INLINE PCCB FatAllocateCcb ()
 
INLINE VOID FatFreeCcb (IN PCCB Ccb)
 
INLINE PFCB FatAllocateFcb ()
 
INLINE VOID FatFreeFcb (IN PFCB Fcb)
 
INLINE PNON_PAGED_FCB FatAllocateNonPagedFcb ()
 
INLINE VOID FatFreeNonPagedFcb (PNON_PAGED_FCB NonPagedFcb)
 
INLINE PERESOURCE FatAllocateResource ()
 
INLINE VOID FatFreeResource (IN PERESOURCE Resource)
 
INLINE PIRP_CONTEXT FatAllocateIrpContext ()
 
INLINE VOID FatFreeIrpContext (IN PIRP_CONTEXT IrpContext)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
VOID FatTearDownVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID FatDeleteVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
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)
 
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)
 
VOID FatDeleteFcb (IN PIRP_CONTEXT IrpContext, IN PFCB *FcbPtr)
 
PCCB FatCreateCcb (IN PIRP_CONTEXT IrpContext)
 
VOID FatDeallocateCcbStrings (IN PCCB Ccb)
 
VOID FatDeleteCcb (IN PIRP_CONTEXT IrpContext, IN PCCB *Ccb)
 
PIRP_CONTEXT FatCreateIrpContext (IN PIRP Irp, IN BOOLEAN Wait)
 
VOID FatDeleteIrpContext_Real (IN PIRP_CONTEXT IrpContext)
 
PFCB FatGetNextFcbBottomUp (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb OPTIONAL, IN PFCB TerminationFcb)
 
PFCB FatGetNextFcbTopDown (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
 
BOOLEAN FatSwapVpb (IN PIRP_CONTEXT IrpContext, PVCB Vcb)
 
VOID FatConstructNamesInFcb (IN PIRP_CONTEXT IrpContext, PFCB Fcb, PDIRENT Dirent, PUNICODE_STRING Lfn OPTIONAL)
 
BOOLEAN FatIsHandleCountZero (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
PCLOSE_CONTEXT FatAllocateCloseContext (OPTIONAL PVCB Vcb)
 
VOID FatPreallocateCloseContext (PVCB Vcb)
 
VOID FatEnsureStringBufferEnough (_Inout_ PVOID String, _In_ USHORT DesiredBufferSize)
 
VOID FatFreeStringBuffer (_Inout_ PVOID String)
 
BOOLEAN FatScanForDataTrack (IN PIRP_CONTEXT IrpContext, IN PDEVICE_OBJECT TargetDeviceObject)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (FAT_BUG_CHECK_STRUCSUP)

Definition at line 23 of file strucsup.c.

◆ Dbg

#define Dbg   (DEBUG_TRACE_STRUCSUP)

Definition at line 29 of file strucsup.c.

◆ FAT_FILL_FREE

#define FAT_FILL_FREE   0

Definition at line 52 of file strucsup.c.

◆ FillMemory

#define FillMemory (   BUF,
  SIZ,
  MASK 
)
Value:
{ \
ULONG i; \
for (i = 0; i < (((SIZ)/4) - 1); i += 2) { \
((PULONG)(BUF))[i] = (MASK); \
} \
}
ULONG MASK
Definition: afilter.h:45
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
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
Definition: jssnprintf.c:29
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59

Definition at line 31 of file strucsup.c.

◆ IRP_CONTEXT_HEADER

#define IRP_CONTEXT_HEADER   (sizeof( IRP_CONTEXT ) * 0x10000 + FAT_NTC_IRP_CONTEXT)

Definition at line 39 of file strucsup.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 223 of file strucsup.c.

259{
261 PDEVICE_OBJECT RealDevice;
262 ULONG i;
263
264 STORAGE_HOTPLUG_INFO HotplugInfo;
265 STORAGE_DEVICE_NUMBER StorDeviceNumber;
267
268 //
269 // The following variables are used for abnormal unwind
270 //
271
272 PLIST_ENTRY UnwindEntryList = NULL;
273 PERESOURCE UnwindResource = NULL;
274 PERESOURCE UnwindResource2 = NULL;
275 PFILE_OBJECT UnwindFileObject = NULL;
276 PFILE_OBJECT UnwindCacheMap = NULL;
277 BOOLEAN UnwindWeAllocatedMcb = FALSE;
278 PFILE_SYSTEM_STATISTICS UnwindStatistics = NULL;
279 BOOLEAN UnwindWeAllocatedBadBlockMap = FALSE;
280 BOOLEAN CloseContextAllocated = FALSE;
281
282 PAGED_CODE();
284
285 DebugTrace(+1, Dbg, "FatInitializeVcb, Vcb = %p\n", Vcb);
286
287 _SEH2_TRY {
288
289 //
290 // We start by first zeroing out all of the VCB, this will guarantee
291 // that any stale data is wiped clean
292 //
293
294 RtlZeroMemory( Vcb, sizeof(VCB) );
295
296 //
297 // Set the proper node type code and node byte size
298 //
299
300 Vcb->VolumeFileHeader.NodeTypeCode = FAT_NTC_VCB;
301 Vcb->VolumeFileHeader.NodeByteSize = sizeof(VCB);
302
303 //
304 // Initialize the tunneling cache
305 //
306
308
309 //
310 // Insert this Vcb record on the FatData.VcbQueue
311 //
312
313 NT_ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
314
315
316#ifdef _MSC_VER
317#pragma prefast( push )
318#pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
319#pragma prefast( disable: 28193, "this will always wait" )
320#endif
321
322 (VOID)FatAcquireExclusiveGlobal( IrpContext );
323
324#ifdef _MSC_VER
325#pragma prefast( pop )
326#endif
327
328 InsertTailList( &FatData.VcbQueue, &Vcb->VcbLinks );
329 FatReleaseGlobal( IrpContext );
330 UnwindEntryList = &Vcb->VcbLinks;
331
332 //
333 // Set the Target Device Object, Vpb, and Vcb State fields
334 //
335
336
338 Vcb->TargetDeviceObject = TargetDeviceObject;
339 Vcb->Vpb = Vpb;
340
341 Vcb->CurrentDevice = Vpb->RealDevice;
342
343 //
344 // Set the removable media and defflush flags based on the storage
345 // inquiry and the old characteristic bits.
346 //
347
348 Status = FatPerformDevIoCtrl( IrpContext,
351 NULL,
352 0,
353 &HotplugInfo,
354 sizeof(HotplugInfo),
355 FALSE,
356 TRUE,
357 NULL );
358
359 if (NT_SUCCESS( Status )) {
360
361 if (HotplugInfo.MediaRemovable) {
362
364 }
365
366 //
367 // If the media or device is hot-pluggable, then set this flag.
368 //
369
370 if (HotplugInfo.MediaHotplug || HotplugInfo.DeviceHotplug) {
371
373 }
374
375 if (!HotplugInfo.WriteCacheEnableOverride) {
376
377 //
378 // If the device or media is hotplug and the override is not
379 // set, force defflush behavior for the device.
380 //
381
382 if (HotplugInfo.MediaHotplug || HotplugInfo.DeviceHotplug) {
383
385
387
388 //
389 // Now, for removables that claim to be lockable, lob a lock
390 // request and see if it works. There can unfortunately be
391 // transient, media dependent reasons that it can fail. If
392 // it does not, we must force defflush on.
393 //
394
395 } else if (HotplugInfo.MediaRemovable &&
396 !HotplugInfo.MediaHotplug) {
397
398 Status = FatToggleMediaEjectDisable( IrpContext, Vcb, TRUE );
399
400 if (!NT_SUCCESS( Status )) {
401
403
404 }
405
406 (VOID)FatToggleMediaEjectDisable( IrpContext, Vcb, FALSE );
407 }
408 }
409 }
410
411 if (FlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) {
412
414 }
415
416 //
417 // Make sure we turn on deferred flushing for floppies like we always
418 // have.
419 //
420
421 if (FlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) {
422
424 }
425
426 //
427 // Query the storage device number.
428 //
429
430 Status = FatPerformDevIoCtrl( IrpContext,
433 NULL,
434 0,
435 &StorDeviceNumber,
436 sizeof(StorDeviceNumber),
437 FALSE,
438 TRUE,
439 NULL );
440
441 if (NT_SUCCESS( Status )) {
442
443 Vcb->DeviceNumber = StorDeviceNumber.DeviceNumber;
444
445 } else {
446
447 Vcb->DeviceNumber = (ULONG)(-1);
448 }
449
451
452 //
453 // Initialize the resource variable for the Vcb
454 //
455
456 ExInitializeResourceLite( &Vcb->Resource );
457 UnwindResource = &Vcb->Resource;
458
459 ExInitializeResourceLite( &Vcb->ChangeBitMapResource );
460 UnwindResource2 = &Vcb->ChangeBitMapResource;
461
462 //
463 // Initialize the free cluster bitmap mutex.
464 //
465
466 ExInitializeFastMutex( &Vcb->FreeClusterBitMapMutex );
467
468 //
469 // Create the special file object for the virtual volume file with a close
470 // context, its pointers back to the Vcb and the section object pointer.
471 //
472 // We don't have to unwind the close context. That will happen in the close
473 // path automatically.
474 //
475
476 RealDevice = Vcb->CurrentDevice;
477
479 CloseContextAllocated = TRUE;
480
481 Vcb->VirtualVolumeFile = UnwindFileObject = IoCreateStreamFileObject( NULL, RealDevice );
482
483 FatSetFileObject( Vcb->VirtualVolumeFile,
485 Vcb,
486 NULL );
487
488 //
489 // Remember this internal, residual open.
490 //
491
492 InterlockedIncrement( (LONG*)&(Vcb->InternalOpenCount) );
493 InterlockedIncrement( (LONG*)&(Vcb->ResidualOpenCount) );
494
495 Vcb->VirtualVolumeFile->SectionObjectPointer = &Vcb->SectionObjectPointers;
496
497 Vcb->VirtualVolumeFile->ReadAccess = TRUE;
498 Vcb->VirtualVolumeFile->WriteAccess = TRUE;
499 Vcb->VirtualVolumeFile->DeleteAccess = TRUE;
500
501 //
502 // Initialize the notify structures.
503 //
504
505 InitializeListHead( &Vcb->DirNotifyList );
506
507 FsRtlNotifyInitializeSync( &Vcb->NotifySync );
508
509 //
510 // Initialize the Cache Map for the volume file. The size is
511 // initially set to that of our first read. It will be extended
512 // when we know how big the Fat is.
513 //
514
518
519 FatInitializeCacheMap( Vcb->VirtualVolumeFile,
520 &FileSizes,
521 TRUE,
523 Vcb );
524
525 UnwindCacheMap = Vcb->VirtualVolumeFile;
526
527 //
528 // Initialize the structure that will keep track of dirty fat sectors.
529 // The largest possible Mcb structures are less than 1K, so we use
530 // non paged pool.
531 //
532
533 FsRtlInitializeLargeMcb( &Vcb->DirtyFatMcb, PagedPool );
534
535 UnwindWeAllocatedMcb = TRUE;
536
537 //
538 // Initialize the structure that will keep track of bad clusters on the volume.
539 //
540 // It will be empty until it is populated by FSCTL_GET_RETRIEVAL_POINTERS with a volume handle.
541 //
542
543 FsRtlInitializeLargeMcb( &Vcb->BadBlockMcb, PagedPool );
544 UnwindWeAllocatedBadBlockMap = TRUE;
545
546 //
547 // Set the cluster index hint to the first valid cluster of a fat: 2
548 //
549
550 Vcb->ClusterHint = 2;
551
552 //
553 // Initialize the directory stream file object creation event.
554 // This event is also "borrowed" for async non-cached writes.
555 //
556
557 ExInitializeFastMutex( &Vcb->DirectoryFileCreationMutex );
558
559 //
560 // Initialize the clean volume callback Timer and DPC.
561 //
562
563 KeInitializeTimer( &Vcb->CleanVolumeTimer );
564
565 KeInitializeDpc( &Vcb->CleanVolumeDpc, FatCleanVolumeDpc, Vcb );
566
567 //
568 // Initialize the performance counters.
569 //
570
571 Vcb->Statistics = FsRtlAllocatePoolWithTag( NonPagedPoolNx,
574 UnwindStatistics = Vcb->Statistics;
575
577
578 for (i = 0; i < FatData.NumberProcessors; i += 1) {
579 Vcb->Statistics[i].Common.FileSystemType = FILESYSTEM_STATISTICS_TYPE_FAT;
580 Vcb->Statistics[i].Common.Version = 1;
581 Vcb->Statistics[i].Common.SizeOfCompleteStructure =
583 }
584
585 //
586 // Pick up a VPB right now so we know we can pull this filesystem stack off
587 // of the storage stack on demand.
588 //
589
590 Vcb->SwapVpb = FsRtlAllocatePoolWithTag( NonPagedPoolNx,
591 sizeof( VPB ),
592 TAG_VPB );
593
594 RtlZeroMemory( Vcb->SwapVpb, sizeof( VPB ) );
595
596 //
597 // Initialize the close queue listheads.
598 //
599
600 InitializeListHead( &Vcb->AsyncCloseList );
601 InitializeListHead( &Vcb->DelayedCloseList );
602
603 //
604 // Initialize the Advanced FCB Header
605 //
606
607 ExInitializeFastMutex( &Vcb->AdvancedFcbHeaderMutex );
608 FsRtlSetupAdvancedHeader( &Vcb->VolumeFileHeader,
609 &Vcb->AdvancedFcbHeaderMutex );
610
611
612 //
613 // With the Vcb now set up, set the IrpContext Vcb field.
614 //
615
616 IrpContext->Vcb = Vcb;
617
618 } _SEH2_FINALLY {
619
620 DebugUnwind( FatInitializeVcb );
621
622 //
623 // If this is an abnormal termination then undo our work
624 //
625
627
628 if (UnwindCacheMap != NULL) { FatSyncUninitializeCacheMap( IrpContext, UnwindCacheMap ); }
629 if (UnwindFileObject != NULL) { ObDereferenceObject( UnwindFileObject ); }
630 if (UnwindResource != NULL) { FatDeleteResource( UnwindResource ); }
631 if (UnwindResource2 != NULL) { FatDeleteResource( UnwindResource2 ); }
632 if (UnwindWeAllocatedMcb) { FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb ); }
633 if (UnwindWeAllocatedBadBlockMap) { FsRtlUninitializeLargeMcb(&Vcb->BadBlockMcb ); }
634 if (UnwindEntryList != NULL) {
635#ifdef _MSC_VER
636#pragma prefast( suppress: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
637#endif
638 (VOID)FatAcquireExclusiveGlobal( IrpContext );
639 RemoveEntryList( UnwindEntryList );
640 FatReleaseGlobal( IrpContext );
641 }
642 if (UnwindStatistics != NULL) { ExFreePool( UnwindStatistics ); }
643
644 //
645 // Cleanup the close context we preallocated above.
646 //
647
648 if (CloseContextAllocated && (Vcb->VirtualVolumeFile == NULL)) {
649
650 //
651 // FatAllocateCloseContext does not allocate memory, it
652 // pulls a close context off the preallocated slist queue.
653 //
654 // Doing this here is necessary to balance out the one we
655 // preallocated for the Vcb earlier in this function, but
656 // only if we failed to create the virtual volume file.
657 //
658 // If VirtualVolumeFile is not NULL, then this CloseContext
659 // will get cleaned up when the close comes in for it during
660 // Vcb teardown.
661 //
662
664
665 ExFreePool( CloseContext );
666 CloseContextAllocated = FALSE;
667 }
668 }
669
670 DebugTrace(-1, Dbg, "FatInitializeVcb -> VOID\n", 0);
671 } _SEH2_END;
672
673 //
674 // and return to our caller
675 //
676
677 UNREFERENCED_PARAMETER( IrpContext );
678
679 return;
680}
#define PAGED_CODE()
static CC_FILE_SIZES FileSizes
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_VPB
Definition: cdprocs.h:106
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
struct _VCB VCB
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
FatSetFileObject(FileObject, UserDirectoryOpen,(*Dcb), UnwindCcb=FatCreateCcb(IrpContext))
struct _PACKED_BOOT_SECTOR PACKED_BOOT_SECTOR
#define FAT_NTC_VCB
Definition: nodetype.h:28
#define TAG_VCB_STATS
Definition: nodetype.h:171
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
VOID FatInitializeCacheMap(_In_ PFILE_OBJECT FileObject, _In_ PCC_FILE_SIZES FileSizes, _In_ BOOLEAN PinAccess, _In_ PCACHE_MANAGER_CALLBACKS Callbacks, _In_ PVOID LazyWriteContext)
Definition: cachesup.c:62
VOID FatSyncUninitializeCacheMap(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject)
Definition: cachesup.c:1812
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3495
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
VOID FatPreallocateCloseContext(PVCB Vcb)
Definition: strucsup.c:3696
PCLOSE_CONTEXT FatAllocateCloseContext(OPTIONAL PVCB Vcb)
Definition: strucsup.c:3659
#define Dbg
Definition: strucsup.c:29
LARGE_INTEGER FatMaxLarge
Definition: fatdata.c:63
FAT_DATA FatData
Definition: fatdata.c:56
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define DebugUnwind(X)
Definition: fatdata.h:315
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
#define FatAcquireExclusiveGlobal(IRPCONTEXT)
Definition: fatprocs.h:1387
@ VirtualVolumeFile
Definition: fatprocs.h:1045
#define FatReleaseGlobal(IRPCONTEXT)
Definition: fatprocs.h:1636
#define FatSetVcbCondition(V, X)
Definition: fatprocs.h:1438
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB IN PDEVICE_OBJECT FsDeviceObject
Definition: fatprocs.h:1677
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
KDEFERRED_ROUTINE FatCleanVolumeDpc
Definition: fatprocs.h:1981
#define FatDeleteResource(RESRC)
Definition: fatprocs.h:1632
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:560
#define VCB_STATE_FLAG_HOTPLUGGABLE
Definition: fatstruc.h:577
#define VCB_STATE_FLAG_DEFERRED_FLUSH
Definition: fatstruc.h:568
@ VcbGood
Definition: fatstruc.h:223
struct _FILE_SYSTEM_STATISTICS FILE_SYSTEM_STATISTICS
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
VOID NTAPI FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb)
Definition: largemcb.c:1096
VOID NTAPI FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType)
Definition: largemcb.c:451
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
VOID NTAPI FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1590
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3187
long LONG
Definition: pedump.c:60
#define Vcb
Definition: cdprocs.h:1415
#define FILESYSTEM_STATISTICS_TYPE_FAT
Definition: winioctl.h:751
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
LARGE_INTEGER FileSize
Definition: cctypes.h:16
LARGE_INTEGER ValidDataLength
Definition: cctypes.h:17
LARGE_INTEGER AllocationSize
Definition: cctypes.h:15
ULONG NumberProcessors
Definition: fatstruc.h:81
CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks
Definition: fatstruc.h:160
LIST_ENTRY VcbQueue
Definition: fatstruc.h:49
Definition: typedefs.h:120
BOOLEAN WriteCacheEnableOverride
Definition: imports.h:249
BOOLEAN MediaRemovable
Definition: imports.h:246
BOOLEAN DeviceHotplug
Definition: imports.h:248
BOOLEAN MediaHotplug
Definition: imports.h:247
Definition: cdstruc.h:498
Definition: iotypes.h:189
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
VOID NTAPI FsRtlInitializeTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:892
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
LONGLONG QuadPart
Definition: typedefs.h:114
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ FatAllocateCcb()

INLINE PCCB FatAllocateCcb ( )

Definition at line 59 of file strucsup.c.

61{
63}
#define TAG_CCB
Definition: cdprocs.h:85
Definition: cdstruc.h:1067

Referenced by FatCreateCcb().

◆ FatAllocateCloseContext()

PCLOSE_CONTEXT FatAllocateCloseContext ( OPTIONAL PVCB  Vcb)

Definition at line 3659 of file strucsup.c.

3679{
3680 PAGED_CODE();
3682
3683#if DBG
3684 if (ARGUMENT_PRESENT(Vcb)) {
3685
3686 NT_ASSERT( 0 != Vcb->CloseContextCount);
3687 InterlockedDecrement( (LONG*)&Vcb->CloseContextCount);
3688 }
3689#endif
3692}
#define InterlockedDecrement
Definition: armddk.h:52
SLIST_HEADER FatCloseContextSList
Definition: fatdata.c:106
#define ARGUMENT_PRESENT(ArgumentPointer)
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:152
#define ExInterlockedPopEntrySList(SListHead, Lock)
Definition: exfuncs.h:166

Referenced by _Requires_lock_held_().

◆ FatAllocateFcb()

INLINE PFCB FatAllocateFcb ( )

Definition at line 86 of file strucsup.c.

88{
90}
#define TAG_FCB
Definition: nodetype.h:152
Definition: cdstruc.h:902

Referenced by FatCreateDcb(), and FatCreateFcb().

◆ FatAllocateIrpContext()

INLINE PIRP_CONTEXT FatAllocateIrpContext ( )

Definition at line 175 of file strucsup.c.

177{
178 return (PIRP_CONTEXT) ExAllocateFromNPagedLookasideList( &FatIrpContextLookasideList );
179}
NPAGED_LOOKASIDE_LIST FatIrpContextLookasideList
Definition: fatdata.c:102

Referenced by FatCreateIrpContext().

◆ FatAllocateNonPagedFcb()

INLINE PNON_PAGED_FCB FatAllocateNonPagedFcb ( )

Definition at line 113 of file strucsup.c.

115{
116 return (PNON_PAGED_FCB) ExAllocateFromNPagedLookasideList( &FatNonPagedFcbLookasideList );
117}
NPAGED_LOOKASIDE_LIST FatNonPagedFcbLookasideList
Definition: fatdata.c:103

Referenced by FatCreateDcb(), and FatCreateFcb().

◆ FatAllocateResource()

INLINE PERESOURCE FatAllocateResource ( )

Definition at line 140 of file strucsup.c.

142{
144
145 Resource = (PERESOURCE) ExAllocateFromNPagedLookasideList( &FatEResourceLookasideList );
146
148
149 return Resource;
150}
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
NPAGED_LOOKASIDE_LIST FatEResourceLookasideList
Definition: fatdata.c:104

Referenced by FatCreateDcb(), and FatCreateFcb().

◆ FatConstructNamesInFcb()

VOID FatConstructNamesInFcb ( IN PIRP_CONTEXT  IrpContext,
PFCB  Fcb,
PDIRENT  Dirent,
PUNICODE_STRING Lfn  OPTIONAL 
)

Definition at line 3022 of file strucsup.c.

3099{
3100#ifndef __REACTOS__
3102#endif
3103 ULONG i;
3104
3105#ifndef __REACTOS__
3106 OEM_STRING OemA;
3107 OEM_STRING OemB;
3108#endif
3109 UNICODE_STRING Unicode;
3111 POEM_STRING LongOemName;
3112 PUNICODE_STRING LongUniName;
3113
3114 PAGED_CODE();
3115
3117
3118 NT_ASSERT( ShortName->Buffer == NULL );
3119
3120 _SEH2_TRY {
3121
3122 //
3123 // First do the short name.
3124 //
3125
3126 //
3127 // Copy over the case flags for the short name of the file
3128 //
3129
3131
3133
3134 } else {
3135
3137 }
3138
3140
3142
3143 } else {
3144
3146 }
3147
3148 ShortName->MaximumLength = 16;
3150 16,
3152
3153 Fat8dot3ToString( IrpContext, Dirent, FALSE, ShortName );
3154
3156
3157 //
3158 // If no Lfn was specified, we are done. In either case, set the
3159 // final name length.
3160 //
3161
3163
3164 if (!ARGUMENT_PRESENT(Lfn) || (Lfn->Length == 0)) {
3165
3168
3170 }
3171
3172 //
3173 // If we already set up the full filename, we could be in trouble. If the fast
3174 // path for doing it already fired, FatSetFullFileNameInFcb, it will have missed
3175 // this and could have built the full filename out of the shortname of the file.
3176 //
3177 // At that point, disaster could be inevitable since the final name length will not
3178 // match. We use this to tell the notify package what to do - FatNotifyReportChange.
3179 //
3180
3182
3183 //
3184 // We know now we have an Lfn, save away a copy.
3185 //
3186
3188
3191 Lfn->Length,
3194
3195 //
3196 // First check for no extended characters.
3197 //
3198
3199 for (i=0; i < Lfn->Length/sizeof(WCHAR); i++) {
3200
3201 if (Lfn->Buffer[i] >= 0x80) {
3202
3203 break;
3204 }
3205 }
3206
3207 if (i == Lfn->Length/sizeof(WCHAR)) {
3208
3209 //
3210 // Cool, I can go with the Oem, upcase it fast by hand.
3211 //
3212
3213 LongOemName = &Fcb->LongName.Oem.Name.Oem;
3214
3215
3217 Lfn->Length/sizeof(WCHAR),
3219 LongOemName->Length =
3220 LongOemName->MaximumLength = Lfn->Length/sizeof(WCHAR);
3221
3222 for (i=0; i < Lfn->Length/sizeof(WCHAR); i++) {
3223
3224 WCHAR c;
3225
3226 c = Lfn->Buffer[i];
3227
3228#ifdef _MSC_VER
3229#pragma warning( push )
3230#pragma warning( disable:4244 )
3231#endif
3232 LongOemName->Buffer[i] = c < 'a' ?
3233 (UCHAR)c :
3234 c <= 'z' ?
3235 c - (UCHAR)('a'-'A') :
3236 (UCHAR)c;
3237#ifdef _MSC_VER
3238#pragma warning( pop )
3239#endif
3240 }
3241
3242 //
3243 // If this name happens to be exactly the same as the short
3244 // name, don't add it to the splay table.
3245 //
3246
3247 if (FatAreNamesEqual(IrpContext, *ShortName, *LongOemName) ||
3248 (FatFindFcb( IrpContext,
3249 &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3250 LongOemName,
3251 NULL) != NULL)) {
3252
3253 ExFreePool( LongOemName->Buffer );
3254
3255 LongOemName->Buffer = NULL;
3256 LongOemName->Length =
3257 LongOemName->MaximumLength = 0;
3258
3259 } else {
3260
3262 }
3263
3265 }
3266
3267 //
3268 // Now we have the fun part. Make a copy of the Lfn.
3269 //
3270
3271#ifndef __REACTOS__
3272 OemA.Buffer = NULL;
3273 OemB.Buffer = NULL;
3274#endif
3275 Unicode.Buffer = NULL;
3276
3277 Unicode.Length =
3278 Unicode.MaximumLength = Lfn->Length;
3280 Lfn->Length,
3282
3283 RtlCopyMemory( Unicode.Buffer, Lfn->Buffer, Lfn->Length );
3284
3285#ifndef __REACTOS__
3287#endif
3288
3289#if TRUE
3290 //
3291 // Unfortunately, this next block of code breaks down when you have
3292 // two long Unicode filenames that both map to the same Oem (and are,
3293 // well, long, i.e. are not the short names). In this case, with one
3294 // in the prefix table first, the other will hit the common Oem
3295 // representation. This leads to several forms of user astonishment.
3296 //
3297 // It isn't worth it, or probably even possible, to try to figure out
3298 // when this is really safe to go through. Simply omit the attempt.
3299 //
3300 // Ex: ANSI 0x82 and 0x84 in the 1252 ANSI->UNI and 437 UNI->OEM codepages.
3301 //
3302 // 0x82 => 0x201a => 0x2c
3303 // 0x84 => 0x201e => 0x2c
3304 //
3305 // 0x2c is comma, so is FAT Oem illegal and forces shortname generation.
3306 // Since it is otherwise well-formed by the rules articulated previously,
3307 // we would have put 0x2c in the Oem prefix tree. In terms of the
3308 // argument given above, even though there exist no Y and U s.t.
3309 //
3310 // Up(Y) == Up(U) && BestOemFit(U) != BestOemFit(Y)
3311 //
3312 // there most certainly exist Y and U s.t.
3313 //
3314 // Up(Y) != Up(U) && BestOemFit(U) == BestOemFit(Y)
3315 //
3316 // and that is enough to keep us from doing this. Note that the < 0x80
3317 // case is OK since we know that the mapping in the OEM codepages are
3318 // the identity in that range.
3319 //
3320 // We still need to monocase it, though. Do this through a full down/up
3321 // transition.
3322 //
3323
3324 (VOID)RtlDowncaseUnicodeString( &Unicode, &Unicode, FALSE );
3325 (VOID)RtlUpcaseUnicodeString( &Unicode, &Unicode, FALSE );
3326#else
3327 //
3328 // Downcase and convert to upcased Oem. Only continue if we can
3329 // convert without error. Any error other than UNMAPPABLE_CHAR
3330 // is a fatal error and we raise.
3331 //
3332 // Note that even if the conversion fails, we must leave Unicode
3333 // in an upcased state.
3334 //
3335 // NB: The Rtl doesn't NULL .Buffer on error.
3336 //
3337
3338 (VOID)RtlDowncaseUnicodeString( &Unicode, &Unicode, FALSE );
3340 (VOID)RtlUpcaseUnicodeString( &Unicode, &Unicode, FALSE );
3341
3342 if (!NT_SUCCESS(Status)) {
3343
3345
3347 ExFreePool(Unicode.Buffer);
3348 FatNormalizeAndRaiseStatus( IrpContext, Status );
3349 }
3350
3351 } else {
3352
3353 //
3354 // The same as above except upcase.
3355 //
3356
3358
3359 if (!NT_SUCCESS(Status)) {
3360
3361 RtlFreeOemString( &OemA );
3362
3364
3366 ExFreePool(Unicode.Buffer);
3367 FatNormalizeAndRaiseStatus( IrpContext, Status );
3368 }
3369 }
3370 }
3371
3372 //
3373 // If the final OemNames are equal, I can use save only the Oem
3374 // name. If the name did not map, then I have to go with the UNICODE
3375 // name because I could get a case varient that didn't convert
3376 // in create, but did match the LFN.
3377 //
3378
3379 if (NT_SUCCESS(Status) && FatAreNamesEqual( IrpContext, OemA, OemB )) {
3380
3381 //
3382 // Cool, I can go with the Oem. If we didn't convert correctly,
3383 // get a fresh convert from the original LFN.
3384 //
3385
3386 ExFreePool(Unicode.Buffer);
3387
3388 RtlFreeOemString( &OemB );
3389
3390 Fcb->LongName.Oem.Name.Oem = OemA;
3391
3392 //
3393 // If this name happens to be exactly the same as the short
3394 // name, or a similar short name already exists don't add it
3395 // to the splay table (note the final condition implies a
3396 // corrupt disk.
3397 //
3398
3399 if (FatAreNamesEqual(IrpContext, *ShortName, OemA) ||
3400 (FatFindFcb( IrpContext,
3401 &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3402 &OemA,
3403 NULL) != NULL)) {
3404
3405 RtlFreeOemString( &OemA );
3406
3407 } else {
3408
3410 }
3411
3413 }
3414
3415 //
3416 // The long name must be left in UNICODE. Free the two Oem strings
3417 // if we got here just because they weren't equal.
3418 //
3419
3420 if (NT_SUCCESS(Status)) {
3421
3422 RtlFreeOemString( &OemA );
3423 RtlFreeOemString( &OemB );
3424 }
3425#endif
3426
3427 LongUniName = &Fcb->LongName.Unicode.Name.Unicode;
3428
3429 LongUniName->Length =
3430 LongUniName->MaximumLength = Unicode.Length;
3431 LongUniName->Buffer = Unicode.Buffer;
3432
3434
3435 try_exit: NOTHING;
3436 } _SEH2_FINALLY {
3437
3439
3440 if (ShortName->Buffer != NULL) {
3441
3442 ExFreePool( ShortName->Buffer );
3443 ShortName->Buffer = NULL;
3444 }
3445
3446 } else {
3447
3448 //
3449 // Creating all the names worked, so add all the names
3450 // to the splay tree.
3451 //
3452
3453 FatInsertName( IrpContext,
3454 &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3455 &Fcb->ShortName );
3456
3457 Fcb->ShortName.Fcb = Fcb;
3458
3460
3461 FatInsertName( IrpContext,
3462 &Fcb->ParentDcb->Specific.Dcb.RootOemNode,
3463 &Fcb->LongName.Oem );
3464
3465 Fcb->LongName.Oem.Fcb = Fcb;
3466 }
3467
3469
3470 FatInsertName( IrpContext,
3471 &Fcb->ParentDcb->Specific.Dcb.RootUnicodeNode,
3472 &Fcb->LongName.Unicode );
3473
3475 }
3476
3478 }
3479 } _SEH2_END;
3480
3481 return;
3482}
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define try_return(S)
Definition: cdprocs.h:2179
_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:4145
#define FAT_DIRENT_NT_BYTE_8_LOWER_CASE
Definition: fat.h:361
#define FAT_DIRENT_NT_BYTE_3_LOWER_CASE
Definition: fat.h:362
#define TAG_FILENAME_BUFFER
Definition: nodetype.h:167
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
VOID FatInsertName(IN PIRP_CONTEXT IrpContext, IN PRTL_SPLAY_LINKS *RootNode, IN PFILE_NAME_NODE Name)
Definition: splaysup.c:39
PFCB FatFindFcb(IN PIRP_CONTEXT IrpContext, IN OUT PRTL_SPLAY_LINKS *RootNode, IN PSTRING Name, OUT PBOOLEAN FileNameDos OPTIONAL)
Definition: splaysup.c:306
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1306
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2995
#define FatAreNamesEqual(IRPCONTEXT, NAMEA, NAMEB)
Definition: fatprocs.h:1158
VOID Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
Definition: namesup.c:179
#define FCB_STATE_8_LOWER_CASE
Definition: fatstruc.h:1210
#define FCB_STATE_HAS_OEM_LONG_NAME
Definition: fatstruc.h:1201
#define FCB_STATE_3_LOWER_CASE
Definition: fatstruc.h:1211
#define FCB_STATE_NAMES_IN_SPLAY_TREE
Definition: fatstruc.h:1200
#define FCB_STATE_HAS_UNICODE_LONG_NAME
Definition: fatstruc.h:1202
const GLubyte * c
Definition: glext.h:8905
VOID NTAPI RtlFreeOemString(POEM_STRING OemString)
NTSYSAPI NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN)
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
#define NOTHING
Definition: input_list.c:10
#define c
Definition: ke_i.h:80
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_UNMAPPABLE_CHARACTER
Definition: ntstatus.h:590
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _FCB * ParentDcb
Definition: fatstruc.h:836
UNICODE_STRING ExactCaseLongName
Definition: fatstruc.h:1139
UNICODE_STRING FullFileName
Definition: fatstruc.h:1122
FILE_NAME_NODE Oem
Definition: fatstruc.h:1159
FILE_NAME_NODE Unicode
Definition: fatstruc.h:1166
union _FCB::@721 LongName
USHORT FinalNameLength
Definition: fatstruc.h:1124
ULONG FcbState
Definition: cdstruc.h:971
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1115
union _FILE_NAME_NODE::@719 Name
UNICODE_STRING Unicode
Definition: fatstruc.h:695
BOOLEAN FileNameDos
Definition: fatstruc.h:704
struct _FCB * Fcb
Definition: fatstruc.h:685
OEM_STRING Oem
Definition: fatstruc.h:693
unsigned short Length
Definition: sprintf.c:451
void * Buffer
Definition: sprintf.c:453
unsigned short MaximumLength
Definition: sprintf.c:452
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
STRING OEM_STRING
Definition: umtypes.h:203
#define RtlOemStringToCountedUnicodeSize(STRING)
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by FatCreateDcb(), FatCreateFcb(), and FatSetRenameInfo().

◆ FatCreateCcb()

PCCB FatCreateCcb ( IN PIRP_CONTEXT  IrpContext)

Definition at line 2155 of file strucsup.c.

2173{
2174 PCCB Ccb;
2175
2176 PAGED_CODE();
2177
2178 DebugTrace(+1, Dbg, "FatCreateCcb\n", 0);
2179
2180 //
2181 // Allocate a new CCB Record
2182 //
2183
2184 Ccb = FatAllocateCcb();
2185
2186 RtlZeroMemory( Ccb, sizeof(CCB) );
2187
2188 //
2189 // Set the proper node type code and node byte size
2190 //
2191
2192 Ccb->NodeTypeCode = FAT_NTC_CCB;
2193 Ccb->NodeByteSize = sizeof(CCB);
2194
2195 //
2196 // return and tell the caller
2197 //
2198
2199 DebugTrace(-1, Dbg, "FatCreateCcb -> %p\n", Ccb);
2200
2201 UNREFERENCED_PARAMETER( IrpContext );
2202
2203 return Ccb;
2204}
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
struct _CCB CCB
#define FAT_NTC_CCB
Definition: nodetype.h:32
INLINE PCCB FatAllocateCcb()
Definition: strucsup.c:59

◆ FatCreateDcb()

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 at line 1623 of file strucsup.c.

1667{
1668 PDCB Dcb = NULL;
1669
1670 //
1671 // The following variables are used for abnormal unwind
1672 //
1673
1674 PVOID UnwindStorage[2] = { NULL, NULL };
1675 PERESOURCE UnwindResource = NULL;
1676 PERESOURCE UnwindResource2 = NULL;
1677 PLIST_ENTRY UnwindEntryList = NULL;
1678 PLARGE_MCB UnwindMcb = NULL;
1679 POPLOCK UnwindOplock = NULL;
1680
1681 PAGED_CODE();
1682
1683 DebugTrace(+1, Dbg, "FatCreateDcb\n", 0);
1684
1685 _SEH2_TRY {
1686
1687 //
1688 // assert that the only time we are called is if wait is true
1689 //
1690
1691 NT_ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
1692
1693 //
1694 // Allocate a new DCB, and zero it out
1695 //
1696
1697 UnwindStorage[0] = Dcb = FatAllocateFcb();
1698
1699 RtlZeroMemory( Dcb, sizeof(DCB) );
1700
1701 UnwindStorage[1] =
1702 Dcb->NonPaged = FatAllocateNonPagedFcb();
1703
1704 RtlZeroMemory( Dcb->NonPaged, sizeof( NON_PAGED_FCB ) );
1705
1706 //
1707 // Set the proper node type code, node byte size and call backs
1708 //
1709
1710 Dcb->Header.NodeTypeCode = FAT_NTC_DCB;
1711 Dcb->Header.NodeByteSize = sizeof(DCB);
1712
1713 Dcb->FcbCondition = FcbGood;
1714
1715 //
1716 // The initial state, open count, and directory change count fields are
1717 // already zero so we can skip setting them
1718 //
1719
1720 //
1721 // Initialize the resource variable
1722 //
1723
1724
1725 UnwindResource =
1726 Dcb->Header.Resource = FatAllocateResource();
1727
1728 //
1729 // Initialize the PagingIo Resource. We no longer use the FsRtl common
1730 // shared pool because this led to a) deadlocks due to cases where files
1731 // and their parent directories shared a resource and b) there is no way
1732 // to anticipate inter-driver induced deadlock via recursive operation.
1733 //
1734
1735 UnwindResource2 =
1736 Dcb->Header.PagingIoResource = FatAllocateResource();
1737
1738 //
1739 // Insert this Dcb into our parent dcb's queue
1740 //
1741 // There is a deep reason why this goes on the head, to allow us
1742 // to easily enumerate all child directories before child files.
1743 // This is important to let us maintain whole-volume lockorder
1744 // via BottomUp enumeration.
1745 //
1746
1747 InsertHeadList( &ParentDcb->Specific.Dcb.ParentDcbQueue,
1748 &Dcb->ParentDcbLinks );
1749 UnwindEntryList = &Dcb->ParentDcbLinks;
1750
1751 //
1752 // Point back to our parent dcb
1753 //
1754
1755 Dcb->ParentDcb = ParentDcb;
1756
1757 //
1758 // Set the Vcb
1759 //
1760
1761 Dcb->Vcb = Vcb;
1762
1763 //
1764 // Set the dirent offset within the directory
1765 //
1766
1767 Dcb->LfnOffsetWithinDirectory = LfnOffsetWithinDirectory;
1768 Dcb->DirentOffsetWithinDirectory = DirentOffsetWithinDirectory;
1769
1770 //
1771 // Set the DirentFatFlags and LastWriteTime
1772 //
1773
1774 Dcb->DirentFatFlags = Dirent->Attributes;
1775
1776 Dcb->LastWriteTime = FatFatTimeToNtTime( IrpContext,
1778 0 );
1779
1780 //
1781 // These fields are only non-zero when in Chicago mode.
1782 //
1783
1784 if (FatData.ChicagoMode) {
1785
1786 LARGE_INTEGER FatSystemJanOne1980 = {0};
1787
1788 //
1789 // If either date is possibly zero, get the system
1790 // version of 1/1/80.
1791 //
1792
1793 if ((((PUSHORT)Dirent)[9] & ((PUSHORT)Dirent)[8]) == 0) {
1794
1796 &FatSystemJanOne1980 );
1797 }
1798
1799 //
1800 // Only do the really hard work if this field is non-zero.
1801 //
1802
1803 if (((PUSHORT)Dirent)[9] != 0) {
1804
1805 Dcb->LastAccessTime =
1806 FatFatDateToNtTime( IrpContext,
1807 Dirent->LastAccessDate );
1808
1809 } else {
1810
1811 Dcb->LastAccessTime = FatSystemJanOne1980;
1812 }
1813
1814 //
1815 // Only do the really hard work if this field is non-zero.
1816 //
1817
1818 if (((PUSHORT)Dirent)[8] != 0) {
1819
1820 Dcb->CreationTime =
1821 FatFatTimeToNtTime( IrpContext,
1823 Dirent->CreationMSec );
1824
1825 } else {
1826
1827 Dcb->CreationTime = FatSystemJanOne1980;
1828 }
1829 }
1830
1831 //
1832 // Initialize Advanced FCB Header fields
1833 //
1834
1835 ExInitializeFastMutex( &Dcb->NonPaged->AdvancedFcbHeaderMutex );
1836 FsRtlSetupAdvancedHeader( &Dcb->Header,
1837 &Dcb->NonPaged->AdvancedFcbHeaderMutex );
1838
1839 //
1840 // Initialize the Mcb
1841 //
1842
1844 UnwindMcb = &Dcb->Mcb;
1845
1846 //
1847 // Set the file size, first cluster of file, and allocation size
1848 // based on the information stored in the dirent
1849 //
1850
1851 Dcb->FirstClusterOfFile = (ULONG)Dirent->FirstClusterOfFile;
1852
1853 if ( FatIsFat32(Dcb->Vcb) ) {
1854
1855 Dcb->FirstClusterOfFile += Dirent->FirstClusterOfFileHi << 16;
1856 }
1857
1858 if ( Dcb->FirstClusterOfFile == 0 ) {
1859
1860 Dcb->Header.AllocationSize.QuadPart = 0;
1861
1862 } else {
1863
1864 Dcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
1865 }
1866
1867
1868 // initialize the notify queues, and the parent dcb queue.
1869 //
1870
1871 InitializeListHead( &Dcb->Specific.Dcb.ParentDcbQueue );
1872
1873 //
1874 // Setup the free dirent bitmap buffer. Since we don't know the
1875 // size of the directory, leave it zero for now.
1876 //
1877
1878 RtlInitializeBitMap( &Dcb->Specific.Dcb.FreeDirentBitmap,
1879 NULL,
1880 0 );
1881
1882 //
1883 // Set our two create dirent aids to represent that we have yet to
1884 // enumerate the directory for never used or deleted dirents.
1885 //
1886
1887 Dcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
1888 Dcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;
1889
1890#if (NTDDI_VERSION >= NTDDI_WIN8)
1891 //
1892 // Initialize the oplock structure.
1893 //
1894
1896 UnwindOplock = FatGetFcbOplock(Dcb);
1897#endif
1898
1899 //
1900 // Postpone initializing the cache map until we need to do a read/write
1901 // of the directory file.
1902
1903
1904 //
1905 // set the file names. This must be the last thing we do.
1906 //
1907
1908 FatConstructNamesInFcb( IrpContext,
1909 Dcb,
1910 Dirent,
1911 Lfn );
1912
1913 Dcb->ShortName.FileNameDos = TRUE;
1914
1915 } _SEH2_FINALLY {
1916
1918
1919 //
1920 // If this is an abnormal termination then undo our work
1921 //
1922
1924
1925 ULONG i;
1926
1927 if (UnwindOplock != NULL) { FsRtlUninitializeOplock( UnwindOplock ); }
1928 if (UnwindMcb != NULL) { FsRtlUninitializeLargeMcb( UnwindMcb ); }
1929 if (UnwindEntryList != NULL) { RemoveEntryList( UnwindEntryList ); }
1930 if (UnwindResource != NULL) { FatFreeResource( UnwindResource ); }
1931 if (UnwindResource2 != NULL) { FatFreeResource( UnwindResource2 ); }
1932
1933 for (i = 0; i < sizeof(UnwindStorage)/sizeof(PVOID); i += 1) {
1934 if (UnwindStorage[i] != NULL) { ExFreePool( UnwindStorage[i] ); }
1935 }
1936 }
1937
1938 DebugTrace(-1, Dbg, "FatCreateDcb -> %p\n", Dcb);
1939 } _SEH2_END;
1940
1941 //
1942 // return and tell the caller
1943 //
1944
1945 DebugTrace(-1, Dbg, "FatCreateDcb -> %p\n", Dcb);
1946
1947 return Dcb;
1948}
@ FcbGood
Definition: cdstruc.h:779
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB ParentDcb
Definition: create.c:4141
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4140
#define FAT_NTC_DCB
Definition: nodetype.h:30
#define ExLocalTimeToSystemTime(LocTime, SysTime)
Definition: env_spec_w32.h:738
#define InsertHeadList(ListHead, Entry)
INLINE PFCB FatAllocateFcb()
Definition: strucsup.c:86
VOID FatConstructNamesInFcb(IN PIRP_CONTEXT IrpContext, PFCB Fcb, PDIRENT Dirent, PUNICODE_STRING Lfn OPTIONAL)
Definition: strucsup.c:3022
INLINE PERESOURCE FatAllocateResource()
Definition: strucsup.c:140
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:1623
INLINE VOID FatFreeResource(IN PERESOURCE Resource)
Definition: strucsup.c:157
INLINE PNON_PAGED_FCB FatAllocateNonPagedFcb()
Definition: strucsup.c:113
LARGE_INTEGER FatJanOne1980
Definition: fatdata.c:73
#define FatGetFcbOplock(F)
Definition: fatprocs.h:1656
LARGE_INTEGER FatFatTimeToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_TIME_STAMP FatTime, _In_ UCHAR TenMilliSeconds)
Definition: timesup.c:233
LARGE_INTEGER FatFatDateToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_DATE FatDate)
Definition: timesup.c:171
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446
FCB DCB
Definition: fatstruc.h:1184
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1241
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI FsRtlUninitializeOplock(IN POPLOCK Oplock)
Definition: oplock.c:1600
VOID NTAPI FsRtlInitializeOplock(IN OUT POPLOCK Oplock)
Definition: oplock.c:1400
BOOLEAN ChicagoMode
Definition: fatstruc.h:87
LONGLONG CreationTime
Definition: cdstruc.h:1030
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
ULONG FirstClusterOfFile
Definition: fatstruc.h:818
uint16_t * PUSHORT
Definition: typedefs.h:56

Referenced by FatCreateDcb().

◆ FatCreateFcb()

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 at line 1252 of file strucsup.c.

1301{
1302 PFCB Fcb = NULL;
1304
1305 //
1306 // The following variables are used for abnormal unwind
1307 //
1308
1309 PVOID UnwindStorage[2] = { NULL, NULL };
1310 PERESOURCE UnwindResource = NULL;
1311 PERESOURCE UnwindResource2 = NULL;
1312 PLIST_ENTRY UnwindEntryList = NULL;
1313 PLARGE_MCB UnwindMcb = NULL;
1314 PFILE_LOCK UnwindFileLock = NULL;
1315 POPLOCK UnwindOplock = NULL;
1316
1317 PAGED_CODE();
1318
1319 UNREFERENCED_PARAMETER( OrigLfn );
1320
1321 DebugTrace(+1, Dbg, "FatCreateFcb\n", 0);
1322
1323 _SEH2_TRY {
1324
1325 //
1326 // Determine the pool type we should be using for the fcb and the
1327 // mcb structure
1328 //
1329
1330 if (IsPagingFile) {
1331
1332 PoolType = NonPagedPoolNx;
1333 Fcb = UnwindStorage[0] = FsRtlAllocatePoolWithTag( NonPagedPoolNx,
1334 sizeof(FCB),
1335 TAG_FCB );
1336 } else {
1337
1339 Fcb = UnwindStorage[0] = FatAllocateFcb();
1340
1341 }
1342
1343 //
1344 // ... and zero it out
1345 //
1346
1347 RtlZeroMemory( Fcb, sizeof(FCB) );
1348
1349 UnwindStorage[1] =
1351
1352 RtlZeroMemory( Fcb->NonPaged, sizeof( NON_PAGED_FCB ) );
1353
1354 //
1355 // Set the proper node type code, node byte size, and call backs
1356 //
1357
1358 Fcb->Header.NodeTypeCode = FAT_NTC_FCB;
1359 Fcb->Header.NodeByteSize = sizeof(FCB);
1360
1362
1363 //
1364 // Check to see if we need to set the Fcb state to indicate that this
1365 // is a paging/system file. This will prevent it from being opened
1366 // again.
1367 //
1368
1369 if (IsPagingFile) {
1370
1372 }
1373
1374 //
1375 // The initial state, open count, and segment objects fields are already
1376 // zero so we can skip setting them
1377 //
1378
1379 //
1380 // Initialize the resource variable
1381 //
1382
1383
1384 UnwindResource =
1385 Fcb->Header.Resource = FatAllocateResource();
1386
1387 //
1388 // Initialize the PagingIo Resource. We no longer use the FsRtl common
1389 // shared pool because this led to a) deadlocks due to cases where files
1390 // and their parent directories shared a resource and b) there is no way
1391 // to anticipate inter-driver induced deadlock via recursive operation.
1392 //
1393
1394 if (SingleResource) {
1395
1396 Fcb->Header.PagingIoResource = Fcb->Header.Resource;
1397
1398 } else {
1399
1400 UnwindResource2 =
1401 Fcb->Header.PagingIoResource = FatAllocateResource();
1402 }
1403
1404 //
1405 // Insert this fcb into our parent dcb's queue.
1406 //
1407 // There is a deep reason why this goes on the tail, to allow us
1408 // to easily enumerate all child directories before child files.
1409 // This is important to let us maintain whole-volume lockorder
1410 // via BottomUp enumeration.
1411 //
1412
1413 InsertTailList( &ParentDcb->Specific.Dcb.ParentDcbQueue,
1414 &Fcb->ParentDcbLinks );
1415 UnwindEntryList = &Fcb->ParentDcbLinks;
1416
1417 //
1418 // Point back to our parent dcb
1419 //
1420
1422
1423 //
1424 // Set the Vcb
1425 //
1426
1427 Fcb->Vcb = Vcb;
1428
1429 //
1430 // Set the dirent offset within the directory
1431 //
1432
1433 Fcb->LfnOffsetWithinDirectory = LfnOffsetWithinDirectory;
1434 Fcb->DirentOffsetWithinDirectory = DirentOffsetWithinDirectory;
1435
1436 //
1437 // Set the DirentFatFlags and LastWriteTime
1438 //
1439
1440 Fcb->DirentFatFlags = Dirent->Attributes;
1441
1442 Fcb->LastWriteTime = FatFatTimeToNtTime( IrpContext,
1444 0 );
1445
1446 //
1447 // These fields are only non-zero when in Chicago mode.
1448 //
1449
1450 if (FatData.ChicagoMode) {
1451
1452 LARGE_INTEGER FatSystemJanOne1980 = {0};
1453
1454 //
1455 // If either date is possibly zero, get the system
1456 // version of 1/1/80.
1457 //
1458
1459 if ((((PUSHORT)Dirent)[9] & ((PUSHORT)Dirent)[8]) == 0) {
1460
1462 &FatSystemJanOne1980 );
1463 }
1464
1465 //
1466 // Only do the really hard work if this field is non-zero.
1467 //
1468
1469 if (((PUSHORT)Dirent)[9] != 0) {
1470
1472 FatFatDateToNtTime( IrpContext,
1473 Dirent->LastAccessDate );
1474
1475 } else {
1476
1477 Fcb->LastAccessTime = FatSystemJanOne1980;
1478 }
1479
1480 //
1481 // Only do the really hard work if this field is non-zero.
1482 //
1483
1484 if (((PUSHORT)Dirent)[8] != 0) {
1485
1486 Fcb->CreationTime =
1487 FatFatTimeToNtTime( IrpContext,
1489 Dirent->CreationMSec );
1490
1491 } else {
1492
1493 Fcb->CreationTime = FatSystemJanOne1980;
1494 }
1495 }
1496
1497 //
1498 // Initialize Advanced FCB Header fields
1499 //
1500
1502 FsRtlSetupAdvancedHeader( &Fcb->Header,
1504
1505 //
1506 // To make FAT match the present functionality of NTFS, disable
1507 // stream contexts on paging files
1508 //
1509
1510 if (IsPagingFile) {
1511
1514 }
1515
1516 //
1517 // Initialize the Mcb
1518 //
1519
1521 UnwindMcb = &Fcb->Mcb;
1522
1523 //
1524 // Set the file size, valid data length, first cluster of file,
1525 // and allocation size based on the information stored in the dirent
1526 //
1527
1528 Fcb->Header.FileSize.LowPart = Dirent->FileSize;
1529
1530 Fcb->Header.ValidDataLength.LowPart = Dirent->FileSize;
1531
1532 Fcb->ValidDataToDisk = Dirent->FileSize;
1533
1535
1536 if ( FatIsFat32(Vcb) ) {
1537
1538 Fcb->FirstClusterOfFile += Dirent->FirstClusterOfFileHi << 16;
1539 }
1540
1541 if ( Fcb->FirstClusterOfFile == 0 ) {
1542
1543 Fcb->Header.AllocationSize.QuadPart = 0;
1544
1545 } else {
1546
1547 Fcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
1548 }
1549
1550
1551 //
1552 // Initialize the Fcb's file lock record
1553 //
1554
1556 UnwindFileLock = &Fcb->Specific.Fcb.FileLock;
1557
1558 //
1559 // Initialize the oplock structure.
1560 //
1561
1563 UnwindOplock = FatGetFcbOplock(Fcb);
1564
1565 //
1566 // Indicate that Fast I/O is possible
1567 //
1568
1569 Fcb->Header.IsFastIoPossible = TRUE;
1570
1571 //
1572 // Set the file names. This must be the last thing we do.
1573 //
1574
1575 FatConstructNamesInFcb( IrpContext,
1576 Fcb,
1577 Dirent,
1578 Lfn );
1579
1580 //
1581 // Drop the shortname hint so prefix searches can figure out
1582 // what they found
1583 //
1584
1586
1587 } _SEH2_FINALLY {
1588
1590
1591 //
1592 // If this is an abnormal termination then undo our work
1593 //
1594
1596
1597 ULONG i;
1598
1599 if (UnwindOplock != NULL) { FsRtlUninitializeOplock( UnwindOplock ); }
1600 if (UnwindFileLock != NULL) { FsRtlUninitializeFileLock( UnwindFileLock ); }
1601 if (UnwindMcb != NULL) { FsRtlUninitializeLargeMcb( UnwindMcb ); }
1602 if (UnwindEntryList != NULL) { RemoveEntryList( UnwindEntryList ); }
1603 if (UnwindResource != NULL) { FatFreeResource( UnwindResource ); }
1604 if (UnwindResource2 != NULL) { FatFreeResource( UnwindResource2 ); }
1605
1606 for (i = 0; i < sizeof(UnwindStorage)/sizeof(PVOID); i += 1) {
1607 if (UnwindStorage[i] != NULL) { ExFreePool( UnwindStorage[i] ); }
1608 }
1609 }
1610
1611 DebugTrace(-1, Dbg, "FatCreateFcb -> %p\n", Fcb);
1612 } _SEH2_END;
1613
1614 //
1615 // return and tell the caller
1616 //
1617
1618 return Fcb;
1619}
struct _FCB FCB
#define FAT_NTC_FCB
Definition: nodetype.h:29
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:1252
#define FCB_STATE_SYSTEM_FILE
Definition: fatstruc.h:1199
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1262
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
#define FSRTL_FLAG2_IS_PAGING_FILE
Definition: fsrtltypes.h:57
#define FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS
Definition: fsrtltypes.h:55
LIST_ENTRY ParentDcbLinks
Definition: fatstruc.h:828
VBO LfnOffsetWithinDirectory
Definition: fatstruc.h:913
PVCB Vcb
Definition: cdstruc.h:933
union _FCB::@720 Specific
CD_MCB Mcb
Definition: cdstruc.h:1016
struct _FCB::@720::@723 Fcb
FCB_CONDITION FcbCondition
Definition: fatstruc.h:850
ULONG ValidDataToDisk
Definition: fatstruc.h:928
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:921
UCHAR DirentFatFlags
Definition: fatstruc.h:1133
PNON_PAGED_FCB NonPaged
Definition: fatstruc.h:811
VBO DirentOffsetWithinDirectory
Definition: fatstruc.h:906
FAST_MUTEX AdvancedFcbHeaderMutex
Definition: fatstruc.h:750
INT POOL_TYPE
Definition: typedefs.h:78
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815

Referenced by FatCreateFcb().

◆ FatCreateIrpContext()

PIRP_CONTEXT FatCreateIrpContext ( IN PIRP  Irp,
IN BOOLEAN  Wait 
)

Definition at line 2301 of file strucsup.c.

2324{
2325 PIRP_CONTEXT IrpContext;
2327
2328 PAGED_CODE();
2329
2330 DebugTrace(+1, Dbg, "FatCreateIrpContext\n", 0);
2331
2333
2334 //
2335 // The only operations a filesystem device object should ever receive
2336 // are create/teardown of fsdo handles and operations which do not
2337 // occur in the context of fileobjects (i.e., mount).
2338 //
2339
2341
2342 if (IrpSp->FileObject != NULL &&
2346
2348 }
2349
2351
2355
2358
2360 }
2361
2362 //
2363 // Attemtp to allocate from the region first and failing that allocate
2364 // from pool.
2365 //
2366
2367 DebugDoit( FatFsdEntryCount += 1);
2368
2369 IrpContext = FatAllocateIrpContext();
2370
2371 //
2372 // Zero out the irp context.
2373 //
2374
2375 RtlZeroMemory( IrpContext, sizeof(IRP_CONTEXT) );
2376
2377 //
2378 // Set the proper node type code and node byte size
2379 //
2380
2381 IrpContext->NodeTypeCode = FAT_NTC_IRP_CONTEXT;
2382 IrpContext->NodeByteSize = sizeof(IRP_CONTEXT);
2383
2384 //
2385 // Set the originating Irp field
2386 //
2387
2388 IrpContext->OriginatingIrp = Irp;
2389
2390 //
2391 // Major/Minor Function codes
2392 //
2393
2394 IrpContext->MajorFunction = IrpSp->MajorFunction;
2395 IrpContext->MinorFunction = IrpSp->MinorFunction;
2396
2397 //
2398 // Copy RealDevice for workque algorithms, and also set Write Through
2399 // and Removable Media if there is a file object. Only file system
2400 // control Irps won't have a file object, and they should all have
2401 // a Vpb as the first IrpSp location.
2402 //
2403
2404 if (IrpSp->FileObject != NULL) {
2405
2407
2408 IrpContext->RealDevice = FileObject->DeviceObject;
2409 IrpContext->Vcb = &((PVOLUME_DEVICE_OBJECT)(IrpSp->DeviceObject))->Vcb;
2410
2411 //
2412 // See if the request is Write Through. Look for both FileObjects opened
2413 // as write through, and non-cached requests with the SL_WRITE_THROUGH flag set.
2414 //
2415 // The latter can only originate from kernel components. (Note - NtWriteFile()
2416 // does redundantly set the SL_W_T flag for all requests it issues on write
2417 // through file objects)
2418 //
2419
2420 if (IsFileWriteThrough( FileObject, IrpContext->Vcb ) ||
2422 BooleanFlagOn( Irp->Flags, IRP_NOCACHE) &&
2424
2425 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
2426 }
2427 } else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) {
2428
2429 IrpContext->RealDevice = IrpSp->Parameters.MountVolume.Vpb->RealDevice;
2430 }
2431
2432 //
2433 // Set the wait parameter
2434 //
2435
2436 if (Wait) { SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); }
2437
2438 //
2439 // Set the recursive file system call parameter. We set it true if
2440 // the TopLevelIrp field in the thread local storage is not the current
2441 // irp, otherwise we leave it as FALSE.
2442 //
2443
2444 if ( IoGetTopLevelIrp() != Irp) {
2445
2446 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
2447 }
2448
2449 //
2450 // return and tell the caller
2451 //
2452
2453 DebugTrace(-1, Dbg, "FatCreateIrpContext -> %p\n", IrpContext);
2454
2455 return IrpContext;
2456}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
VOLUME_DEVICE_OBJECT * PVOLUME_DEVICE_OBJECT
Definition: cdstruc.h:769
_In_ PIRP Irp
Definition: csq.h:116
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define FAT_NTC_IRP_CONTEXT
Definition: nodetype.h:33
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1088
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
INLINE PIRP_CONTEXT FatAllocateIrpContext()
Definition: strucsup.c:175
#define DebugDoit(X)
Definition: fatdata.h:316
#define IsFileWriteThrough(FO, VCB)
Definition: fatprocs.h:2796
#define FatDeviceIsFatFsdo(D)
Definition: fatprocs.h:3095
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1566
#define FSCTL_INVALIDATE_VOLUMES
Definition: nt_native.h:847
#define ExRaiseStatus
Definition: ntoskrnl.h:114
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
struct _IO_STACK_LOCATION::@3978::@3998 MountVolume
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3993 FileSystemControl
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
#define IRP_MJ_SHUTDOWN
#define SL_WRITE_THROUGH
Definition: iotypes.h:1824
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404
#define IRP_NOCACHE
#define IRP_MJ_CLEANUP

Referenced by _Function_class_(), _Requires_lock_held_(), FatMultiAsyncCompletionRoutine(), and FatSingleAsyncCompletionRoutine().

◆ FatDeallocateCcbStrings()

VOID FatDeallocateCcbStrings ( IN PCCB  Ccb)

Definition at line 2209 of file strucsup.c.

2227{
2228 PAGED_CODE();
2229
2230 //
2231 // If we allocated query template buffers, deallocate them now.
2232 //
2233
2235
2236 NT_ASSERT( Ccb->UnicodeQueryTemplate.Buffer);
2238 RtlFreeUnicodeString( &Ccb->UnicodeQueryTemplate );
2239 }
2240
2242
2243 NT_ASSERT( Ccb->OemQueryTemplate.Wild.Buffer );
2245 RtlFreeOemString( &Ccb->OemQueryTemplate.Wild );
2246 }
2247
2249}
#define CCB_FLAG_FREE_UNICODE
Definition: fatstruc.h:1260
#define CCB_FLAG_CLOSE_CONTEXT
Definition: fatstruc.h:1324
#define CCB_FLAG_FREE_OEM_BEST_FIT
Definition: fatstruc.h:1259
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
ULONG Flags
Definition: ntfs.h:536

Referenced by FatDeleteCcb().

◆ FatDeleteCcb()

VOID FatDeleteCcb ( IN PIRP_CONTEXT  IrpContext,
IN PCCB Ccb 
)

Definition at line 2254 of file strucsup.c.

2276{
2277 PAGED_CODE();
2278
2279 DebugTrace(+1, Dbg, "FatDeleteCcb, Ccb = %p\n", *Ccb);
2280
2282
2283 //
2284 // Deallocate the Ccb record
2285 //
2286
2287 FatFreeCcb( *Ccb );
2288 *Ccb = NULL;
2289
2290 //
2291 // return and tell the caller
2292 //
2293
2294 DebugTrace(-1, Dbg, "FatDeleteCcb -> VOID\n", 0);
2295
2296 UNREFERENCED_PARAMETER( IrpContext );
2297}
VOID FatDeallocateCcbStrings(IN PCCB Ccb)
Definition: strucsup.c:2209
INLINE VOID FatFreeCcb(IN PCCB Ccb)
Definition: strucsup.c:70

Referenced by if().

◆ FatDeleteFcb()

VOID FatDeleteFcb ( IN PIRP_CONTEXT  IrpContext,
IN PFCB FcbPtr 
)

Definition at line 1952 of file strucsup.c.

1975{
1976 PFCB Fcb = *FcbPtr;
1977
1978 PAGED_CODE();
1979
1980 DebugTrace(+1, Dbg, "FatDeleteFcb, Fcb = %p\n", Fcb);
1981
1982 //
1983 // We can only delete this record if the open count is zero.
1984 //
1985
1986 if (Fcb->OpenCount != 0) {
1987
1988 DebugDump("Error deleting Fcb, Still Open\n", 0, Fcb);
1989#ifdef _MSC_VER
1990#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1991#endif
1992 FatBugCheck( 0, 0, 0 );
1993 }
1994
1995 //
1996 // Better be an FCB/DCB.
1997 //
1998
1999 if ((Fcb->Header.NodeTypeCode != FAT_NTC_DCB) &&
2000 (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) &&
2001 (Fcb->Header.NodeTypeCode != FAT_NTC_FCB)) {
2002
2003#ifdef _MSC_VER
2004#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
2005#endif
2006 FatBugCheck( 0, 0, 0 );
2007 }
2008
2009 //
2010 // If this is a DCB then remove every Notify record from the two
2011 // notify queues
2012 //
2013
2014 if ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) ||
2015 (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) {
2016
2017 //
2018 // If we allocated a free dirent bitmap buffer, free it.
2019 //
2020
2021 if ((Fcb->Specific.Dcb.FreeDirentBitmap.Buffer != NULL) &&
2022 (Fcb->Specific.Dcb.FreeDirentBitmap.Buffer !=
2023 &Fcb->Specific.Dcb.FreeDirentBitmapBuffer[0])) {
2024
2025 ExFreePool(Fcb->Specific.Dcb.FreeDirentBitmap.Buffer);
2026 }
2027
2028#if (NTDDI_VERSION >= NTDDI_WIN8)
2029 //
2030 // Uninitialize the oplock.
2031 //
2032
2034#endif
2035
2036 NT_ASSERT( Fcb->Specific.Dcb.DirectoryFileOpenCount == 0 );
2037 NT_ASSERT( IsListEmpty(&Fcb->Specific.Dcb.ParentDcbQueue) );
2038 NT_ASSERT( NULL == Fcb->Specific.Dcb.DirectoryFile);
2039
2040 } else {
2041
2042 //
2043 // Uninitialize the byte range file locks and opportunistic locks
2044 //
2045
2048 }
2049
2050
2051 //
2052 // Release any Filter Context structures associated with this FCB
2053 //
2054
2056
2057 //
2058 // Uninitialize the Mcb
2059 //
2060
2062
2063 //
2064 // If this is not the root dcb then we need to remove ourselves from
2065 // our parents Dcb queue
2066 //
2067
2068 if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) {
2069
2071 }
2072
2073 //
2074 // Remove the entry from the splay table if there is still is one.
2075 //
2076
2078
2079 FatRemoveNames( IrpContext, Fcb );
2080 }
2081
2082 //
2083 // Free the file name pool if allocated.
2084 //
2085
2086 if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) {
2087
2088 //
2089 // If we blew up at inconvenient times, the shortname
2090 // could be null even though you will *never* see this
2091 // normally. Rename is a good example of this case.
2092 //
2093
2094 if (Fcb->ShortName.Name.Oem.Buffer) {
2095
2096 ExFreePool( Fcb->ShortName.Name.Oem.Buffer );
2097 }
2098
2099 if (Fcb->FullFileName.Buffer) {
2100
2102 }
2103 }
2104
2106
2108 }
2109
2110#ifdef SYSCACHE_COMPILE
2111
2112 if (Fcb->WriteMask) {
2113
2114 ExFreePool( Fcb->WriteMask );
2115 }
2116
2117#endif
2118
2119 //
2120 // Finally deallocate the Fcb and non-paged fcb records
2121 //
2122
2123 FatFreeResource( Fcb->Header.Resource );
2124
2125 if (Fcb->Header.PagingIoResource != Fcb->Header.Resource) {
2126
2127 FatFreeResource( Fcb->Header.PagingIoResource );
2128 }
2129
2130 //
2131 // If an Event was allocated, get rid of it.
2132 //
2133
2135
2137 }
2138
2140
2141 Fcb->Header.NodeTypeCode = NTC_UNDEFINED;
2142
2143 FatFreeFcb( Fcb );
2144 *FcbPtr = NULL;
2145
2146 //
2147 // and return to our caller
2148 //
2149
2150 DebugTrace(-1, Dbg, "FatDeleteFcb -> VOID\n", 0);
2151}
#define NTC_UNDEFINED
Definition: nodetype.h:25
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
INLINE VOID FatFreeFcb(IN PFCB Fcb)
Definition: strucsup.c:97
INLINE VOID FatFreeNonPagedFcb(PNON_PAGED_FCB NonPagedFcb)
Definition: strucsup.c:124
#define DebugDump(STR, LEVEL, PTR)
Definition: fatdata.h:314
VOID FatRemoveNames(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: splaysup.c:222
VOID NTAPI FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader)
Definition: filtrctx.c:368
CLONG OpenCount
Definition: fatstruc.h:881
struct _FCB::@720::@722 Dcb
PKEVENT OutstandingAsyncEvent
Definition: fatstruc.h:743

Referenced by FatDeleteVcb(), and if().

◆ FatDeleteIrpContext_Real()

VOID FatDeleteIrpContext_Real ( IN PIRP_CONTEXT  IrpContext)

Definition at line 2461 of file strucsup.c.

2483{
2484 PAGED_CODE();
2485
2486 DebugTrace(+1, Dbg, "FatDeleteIrpContext, IrpContext = %p\n", IrpContext);
2487
2488 NT_ASSERT( IrpContext->NodeTypeCode == FAT_NTC_IRP_CONTEXT );
2489 NT_ASSERT( IrpContext->PinCount == 0 );
2490
2491
2492 //
2493 // If there is a FatIoContext that was allocated, free it.
2494 //
2495
2496 if (IrpContext->FatIoContext != NULL) {
2497
2498 if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT)) {
2499
2500 if (IrpContext->FatIoContext->ZeroMdl) {
2501 IoFreeMdl( IrpContext->FatIoContext->ZeroMdl );
2502 }
2503
2504 ExFreePool( IrpContext->FatIoContext );
2505 }
2506 }
2507
2508 //
2509 // Drop the IrpContext.
2510 //
2511
2512 FatFreeIrpContext( IrpContext );
2513
2514 //
2515 // return and tell the caller
2516 //
2517
2518 DebugTrace(-1, Dbg, "FatDeleteIrpContext -> VOID\n", 0);
2519
2520 return;
2521}
#define IRP_CONTEXT_STACK_IO_CONTEXT
Definition: ext2fs.h:1093
INLINE VOID FatFreeIrpContext(IN PIRP_CONTEXT IrpContext)
Definition: strucsup.c:186
#define IoFreeMdl
Definition: fxmdl.h:89

◆ FatDeleteVcb()

VOID FatDeleteVcb ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 772 of file strucsup.c.

795{
796 PFCB Fcb;
797
798 PAGED_CODE();
799
800 DebugTrace(+1, Dbg, "FatDeleteVcb, Vcb = %p\n", Vcb);
801
802 //
803 // If the IrpContext points to the VCB being deleted NULL out the stail
804 // pointer.
805 //
806
807 if (IrpContext->Vcb == Vcb) {
808
809 IrpContext->Vcb = NULL;
810
811 }
812
813 //
814 // Chuck the backpocket Vpb we kept just in case.
815 //
816
817 if (Vcb->SwapVpb) {
818
819 ExFreePool( Vcb->SwapVpb );
820
821 }
822
823 //
824 // Free the VPB, if we need to.
825 //
826
827 if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VPB_MUST_BE_FREED )) {
828
829 //
830 // We swapped the VPB, so we need to free the main one.
831 //
832
833 ExFreePool( Vcb->Vpb );
834 }
835
836 if (Vcb->VolumeGuidPath.Buffer) {
837 ExFreePool( Vcb->VolumeGuidPath.Buffer );
838 Vcb->VolumeGuidPath.Buffer = NULL;
839 }
840
841 //
842 // Remove this record from the global list of all Vcb records.
843 // Note that the global lock must already be held when calling
844 // this function.
845 //
846
847 RemoveEntryList( &(Vcb->VcbLinks) );
848
849 //
850 // Make sure the direct access open count is zero, and the open file count
851 // is also zero.
852 //
853
854 if ((Vcb->DirectAccessOpenCount != 0) || (Vcb->OpenFileCount != 0)) {
855
856#ifdef _MSC_VER
857#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
858#endif
859 FatBugCheck( 0, 0, 0 );
860 }
861
862 //
863 // Remove the EaFcb and dereference the Fcb for the Ea file if it
864 // exists.
865 //
866
867 if (Vcb->EaFcb != NULL) {
868
869 Vcb->EaFcb->OpenCount = 0;
870 FatDeleteFcb( IrpContext, &Vcb->EaFcb );
871 }
872
873 //
874 // Remove the Root Dcb
875 //
876
877 if (Vcb->RootDcb != NULL) {
878
879 //
880 // Rundown stale child Fcbs that may be hanging around. Yes, this
881 // can happen. No, the create path isn't perfectly defensive about
882 // tearing down branches built up on creates that don't wind up
883 // succeeding. Normal system operation usually winds up having
884 // cleaned them out through re-visiting, but ...
885 //
886 // Just pick off Fcbs from the bottom of the tree until we run out.
887 // Then we delete the root Dcb.
888 //
889
890 while( (Fcb = FatGetNextFcbBottomUp( IrpContext, NULL, Vcb->RootDcb )) != Vcb->RootDcb ) {
891
892 FatDeleteFcb( IrpContext, &Fcb );
893 }
894
895 FatDeleteFcb( IrpContext, &Vcb->RootDcb );
896 }
897
898 //
899 // Uninitialize the notify sychronization object.
900 //
901
902 FsRtlNotifyUninitializeSync( &Vcb->NotifySync );
903
904 //
905 // Uninitialize the resource variable for the Vcb
906 //
907
908 FatDeleteResource( &Vcb->Resource );
909 FatDeleteResource( &Vcb->ChangeBitMapResource );
910
911 //
912 // If allocation support has been setup, free it.
913 //
914
915 if (Vcb->FreeClusterBitMap.Buffer != NULL) {
916
917 FatTearDownAllocationSupport( IrpContext, Vcb );
918 }
919
920 //
921 // UnInitialize the Mcb structure that kept track of dirty fat sectors.
922 //
923
924 FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb );
925
926 //
927 // Uninitialize the Mcb structure that kept track of bad sectors.
928 //
929
930 FsRtlUninitializeLargeMcb( &Vcb->BadBlockMcb );
931
932 //
933 // Free the pool for the stached copy of the boot sector
934 //
935
936 if ( Vcb->First0x24BytesOfBootSector ) {
937
938 ExFreePool( Vcb->First0x24BytesOfBootSector );
939 Vcb->First0x24BytesOfBootSector = NULL;
940 }
941
942 //
943 // Cancel the CleanVolume Timer and Dpc
944 //
945
946 (VOID)KeCancelTimer( &Vcb->CleanVolumeTimer );
947
948 (VOID)KeRemoveQueueDpc( &Vcb->CleanVolumeDpc );
949
950 //
951 // Free the performance counters memory
952 //
953
954 ExFreePool( Vcb->Statistics );
955
956 //
957 // Clean out the tunneling cache
958 //
959
960 FsRtlDeleteTunnelCache(&Vcb->Tunnel);
961
962 //
963 // Dereference the target device object.
964 //
965
966 ObDereferenceObject( Vcb->TargetDeviceObject );
967
968 //
969 // We better have used all the close contexts we allocated. There could be
970 // one remaining if we're doing teardown due to a final close coming in on
971 // a directory file stream object. It will be freed on the way back up.
972 //
973
974 NT_ASSERT( Vcb->CloseContextCount <= 1);
975
976 //
977 // And zero out the Vcb, this will help ensure that any stale data is
978 // wiped clean
979 //
980
981 RtlZeroMemory( Vcb, sizeof(VCB) );
982
983 //
984 // return and tell the caller
985 //
986
987 DebugTrace(-1, Dbg, "FatDeleteVcb -> VOID\n", 0);
988
989 return;
990}
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:878
VOID FatTearDownAllocationSupport(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: allocsup.c:549
VOID FatDeleteFcb(IN PIRP_CONTEXT IrpContext, IN PFCB *FcbPtr)
Definition: strucsup.c:1952
PFCB FatGetNextFcbBottomUp(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb OPTIONAL, IN PFCB TerminationFcb)
Definition: strucsup.c:2525
#define VCB_STATE_FLAG_VPB_MUST_BE_FREED
Definition: fatstruc.h:574
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1668
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI FsRtlDeleteTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:691

◆ FatEnsureStringBufferEnough()

VOID FatEnsureStringBufferEnough ( _Inout_ PVOID  String,
_In_ USHORT  DesiredBufferSize 
)

Definition at line 3739 of file strucsup.c.

3764{
3765 PSTRING LocalString = String;
3766
3767 PAGED_CODE();
3768
3769 if (LocalString->MaximumLength < DesiredBufferSize) {
3770
3771 FatFreeStringBuffer( LocalString);
3772
3774 DesiredBufferSize,
3776 NT_ASSERT( LocalString->Buffer);
3777
3778 LocalString->MaximumLength = DesiredBufferSize;
3779 }
3780}
#define TAG_DYNAMIC_NAME_BUFFER
Definition: nodetype.h:186
VOID FatFreeStringBuffer(_Inout_ PVOID String)
Definition: strucsup.c:3784
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

◆ FatFreeCcb()

INLINE VOID FatFreeCcb ( IN PCCB  Ccb)

Definition at line 70 of file strucsup.c.

73{
74#if FAT_FILL_FREE
76#endif
77
78 ExFreePool( Ccb );
79}
#define FAT_FILL_FREE
Definition: strucsup.c:52
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55

Referenced by FatDeleteCcb().

◆ FatFreeFcb()

INLINE VOID FatFreeFcb ( IN PFCB  Fcb)

Definition at line 97 of file strucsup.c.

100{
101#if FAT_FILL_FREE
103#endif
104
105 ExFreePool( Fcb );
106}

Referenced by FatDeleteFcb().

◆ FatFreeIrpContext()

INLINE VOID FatFreeIrpContext ( IN PIRP_CONTEXT  IrpContext)

Definition at line 186 of file strucsup.c.

189{
190#if FAT_FILL_FREE
191 RtlFillMemoryUlong(IrpContext, sizeof(IRP_CONTEXT), FAT_FILL_FREE);
192#endif
193
194 ExFreeToNPagedLookasideList( &FatIrpContextLookasideList, (PVOID) IrpContext );
195}

Referenced by FatDeleteIrpContext_Real().

◆ FatFreeNonPagedFcb()

INLINE VOID FatFreeNonPagedFcb ( PNON_PAGED_FCB  NonPagedFcb)

Definition at line 124 of file strucsup.c.

127{
128#if FAT_FILL_FREE
129 RtlFillMemoryUlong(NonPagedFcb, sizeof(NON_PAGED_FCB), FAT_FILL_FREE);
130#endif
131
132 ExFreeToNPagedLookasideList( &FatNonPagedFcbLookasideList, (PVOID) NonPagedFcb );
133}

Referenced by FatDeleteFcb().

◆ FatFreeResource()

INLINE VOID FatFreeResource ( IN PERESOURCE  Resource)

Definition at line 157 of file strucsup.c.

160{
162
163#if FAT_FILL_FREE
165#endif
166
167 ExFreeToNPagedLookasideList( &FatEResourceLookasideList, (PVOID) Resource );
168}
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
ULONG ERESOURCE
Definition: env_spec_w32.h:594

Referenced by FatCreateDcb(), FatCreateFcb(), and FatDeleteFcb().

◆ FatFreeStringBuffer()

VOID FatFreeStringBuffer ( _Inout_ PVOID  String)

Definition at line 3784 of file strucsup.c.

3804{
3806 PSTRING LocalString = String;
3807
3808 PAGED_CODE();
3809
3810 if (NULL != LocalString->Buffer) {
3811
3813
3814 if (((ULONG_PTR)(LocalString->Buffer) < Low) ||
3815 ((ULONG_PTR)(LocalString->Buffer) > High)) {
3816
3817 ExFreePool( LocalString->Buffer);
3818 }
3819
3820 LocalString->Buffer = NULL;
3821 }
3822
3823 LocalString->MaximumLength = LocalString->Length = 0;
3824}
VOID NTAPI IoGetStackLimits(OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit)
Definition: util.c:78
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by FatEnsureStringBufferEnough().

◆ FatGetNextFcbBottomUp()

PFCB FatGetNextFcbBottomUp ( IN PIRP_CONTEXT  IrpContext,
IN PFCB Fcb  OPTIONAL,
IN PFCB  TerminationFcb 
)

Definition at line 2525 of file strucsup.c.

2570{
2571 PFCB NextFcb;
2572
2573 PAGED_CODE();
2574 UNREFERENCED_PARAMETER( IrpContext );
2575
2576 NT_ASSERT( FatVcbAcquiredExclusive( IrpContext, TerminationFcb->Vcb ) ||
2577 FlagOn( TerminationFcb->Vcb->VcbState, VCB_STATE_FLAG_LOCKED ) );
2578
2579 //
2580 // Do we need to begin the enumeration?
2581 //
2582
2583 if (Fcb != NULL) {
2584
2585 //
2586 // Did we complete?
2587 //
2588
2589 if (Fcb == TerminationFcb) {
2590
2591 return NULL;
2592 }
2593
2594 //
2595 // Do we have a sibling to return?
2596 //
2597
2598 NextFcb = FatGetNextSibling( Fcb );
2599
2600 //
2601 // If not, return our parent. We are done with this branch.
2602 //
2603
2604 if (NextFcb == NULL) {
2605
2606 return Fcb->ParentDcb;
2607 }
2608
2609 } else {
2610
2611 NextFcb = TerminationFcb;
2612 }
2613
2614 //
2615 // Decend to its furthest child (if it exists) and return it.
2616 //
2617
2618 for (;
2619 NodeType( NextFcb ) != FAT_NTC_FCB && FatGetFirstChild( NextFcb ) != NULL;
2620 NextFcb = FatGetFirstChild( NextFcb )) {
2621 }
2622
2623 return NextFcb;
2624}
#define NodeType(P)
Definition: nodetype.h:51
#define FatGetNextSibling(FILE)
Definition: fatprocs.h:1791
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
Definition: fatprocs.h:1495
#define FatGetFirstChild(DIR)
Definition: fatprocs.h:1785
#define VCB_STATE_FLAG_LOCKED
Definition: fatstruc.h:559

Referenced by FatDeleteVcb(), and FatSetRenameInfo().

◆ FatGetNextFcbTopDown()

PFCB FatGetNextFcbTopDown ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PFCB  TerminationFcb 
)

Definition at line 2627 of file strucsup.c.

2667{
2668 PFCB Sibling;
2669
2670 PAGED_CODE();
2671 UNREFERENCED_PARAMETER( IrpContext );
2672
2673 NT_ASSERT( FatVcbAcquiredExclusive( IrpContext, Fcb->Vcb ) ||
2675
2676 //
2677 // If this was a directory (ie. not a file), get the child. If
2678 // there aren't any children and this is our termination Fcb,
2679 // return NULL.
2680 //
2681
2682 if ( ((NodeType(Fcb) == FAT_NTC_DCB) ||
2683 (NodeType(Fcb) == FAT_NTC_ROOT_DCB)) &&
2684 !IsListEmpty(&Fcb->Specific.Dcb.ParentDcbQueue) ) {
2685
2686 return FatGetFirstChild( Fcb );
2687 }
2688
2689 //
2690 // Were we only meant to do one iteration?
2691 //
2692
2693 if ( Fcb == TerminationFcb ) {
2694
2695 return NULL;
2696 }
2697
2698 Sibling = FatGetNextSibling(Fcb);
2699
2700 while (TRUE) {
2701
2702 //
2703 // Do we still have an "older" sibling in this directory who is
2704 // not the termination Fcb?
2705 //
2706
2707 if ( Sibling != NULL ) {
2708
2709 return (Sibling != TerminationFcb) ? Sibling : NULL;
2710 }
2711
2712 //
2713 // OK, let's move on to out parent and see if he is the termination
2714 // node or has any older siblings.
2715 //
2716
2717 if ( Fcb->ParentDcb == TerminationFcb ) {
2718
2719 return NULL;
2720 }
2721
2722 Fcb = Fcb->ParentDcb;
2723
2724 Sibling = FatGetNextSibling(Fcb);
2725 }
2726}
ULONG VcbState
Definition: cdstruc.h:540

Referenced by _Requires_lock_held_(), and FatIsHandleCountZero().

◆ FatIsHandleCountZero()

BOOLEAN FatIsHandleCountZero ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 3614 of file strucsup.c.

3636{
3637 PFCB Fcb;
3638
3639 PAGED_CODE();
3640
3641 Fcb = Vcb->RootDcb;
3642
3643 while (Fcb != NULL) {
3644
3645 if (Fcb->UncleanCount != 0) {
3646
3647 return FALSE;
3648 }
3649
3650 Fcb = FatGetNextFcbTopDown(IrpContext, Fcb, Vcb->RootDcb);
3651 }
3652
3653 return TRUE;
3654}
PFCB FatGetNextFcbTopDown(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
Definition: strucsup.c:2627
CLONG UncleanCount
Definition: fatstruc.h:873

◆ FatPreallocateCloseContext()

VOID FatPreallocateCloseContext ( PVCB  Vcb)

Definition at line 3696 of file strucsup.c.

3718{
3719 PCLOSE_CONTEXT CloseContext;
3720
3721 PAGED_CODE();
3722
3724
3725 CloseContext = FsRtlAllocatePoolWithTag( PagedPool,
3726 sizeof(CLOSE_CONTEXT),
3728
3730 (PSLIST_ENTRY) CloseContext,
3732
3733 DbgDoit( InterlockedIncrement( (LONG*)&Vcb->CloseContextCount));
3734}
#define TAG_FAT_CLOSE_CONTEXT
Definition: nodetype.h:164
#define DbgDoit(X)
Definition: fatdata.h:336
#define ExInterlockedPushEntrySList(SListHead, SListEntry, Lock)
Definition: exfuncs.h:163
#define PSLIST_ENTRY
Definition: rtltypes.h:134

Referenced by _Requires_lock_held_().

◆ FatScanForDataTrack()

BOOLEAN FatScanForDataTrack ( IN PIRP_CONTEXT  IrpContext,
IN PDEVICE_OBJECT  TargetDeviceObject 
)

Definition at line 3828 of file strucsup.c.

3857{
3860
3861 ULONG LocalTrackCount;
3862 ULONG LocalTocLength;
3863
3864 PCDROM_TOC CdromToc;
3866
3867 PAGED_CODE();
3868
3870 sizeof( CDROM_TOC ),
3871 TAG_IO_BUFFER );
3872
3873 RtlZeroMemory( CdromToc, sizeof( CDROM_TOC ));
3874
3875 _SEH2_TRY {
3876
3877 //
3878 // Go ahead and read the table of contents
3879 //
3880
3881 Status = FatPerformDevIoCtrl( IrpContext,
3884 NULL,
3885 0,
3886 CdromToc,
3887 sizeof( CDROM_TOC ),
3888 FALSE,
3889 TRUE,
3890 &Iosb );
3891
3892 //
3893 // Nothing to process if this request fails.
3894 //
3895
3896 if (Status != STATUS_SUCCESS) {
3897
3898 //
3899 // If we get the special error indicating a failed TOC read on PD media just
3900 // plow ahead with the mount (see comments above).
3901 //
3902
3904
3905 Result = TRUE;
3906
3907 }
3908
3909 try_leave( NOTHING );
3910 }
3911
3912 //
3913 // Get the number of tracks and stated size of this structure.
3914 //
3915
3916 LocalTrackCount = CdromToc->LastTrack - CdromToc->FirstTrack + 1;
3917 LocalTocLength = PtrOffset( CdromToc, &CdromToc->TrackData[LocalTrackCount + 1] );
3918
3919 //
3920 // Get out if there is an immediate problem with the TOC, or more than
3921 // one track.
3922 //
3923
3924 if ((LocalTocLength > Iosb.Information) ||
3925 (CdromToc->FirstTrack > CdromToc->LastTrack) ||
3926 (LocalTrackCount != 1)) {
3927
3929 }
3930
3931 //
3932 // Is it a data track? DVD-RAM reports single, data, track.
3933 //
3934
3935 Result = BooleanFlagOn( CdromToc->TrackData[ 0].Control, 0x04 );
3936 }
3938
3939 ExFreePool( CdromToc);
3940 } _SEH2_END;
3941
3942 return Result;
3943}
#define TAG_IO_BUFFER
Definition: cdprocs.h:95
#define try_leave(S)
Definition: cdprocs.h:2180
#define PtrOffset(BASE, OFFSET)
Definition: cdprocs.h:1547
return Iosb
Definition: create.c:4402
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]
Definition: ntddcdrm.h:199
UCHAR LastTrack
Definition: ntddcdrm.h:198
UCHAR FirstTrack
Definition: ntddcdrm.h:197
UCHAR Control
Definition: ntddcdrm.h:137
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
_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:409

◆ FatSwapVpb()

BOOLEAN FatSwapVpb ( IN PIRP_CONTEXT  IrpContext,
PVCB  Vcb 
)

Definition at line 2730 of file strucsup.c.

2757{
2759 PVPB OldVpb;
2761
2762
2763 //
2764 // Make sure we have not already swapped it.
2765 //
2766
2767 OldVpb = Vcb->Vpb;
2768
2769#ifdef _MSC_VER
2770#pragma prefast( push )
2771#pragma prefast( disable: 28175, "touching Vpb is ok for a filesystem" )
2772#endif
2773
2774 if (!FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VPB_MUST_BE_FREED ) && OldVpb->RealDevice->Vpb == OldVpb) {
2775
2776 //
2777 // If not the final reference and we are forcing the disconnect,
2778 // then swap out the Vpb. We must preserve the REMOVE_PENDING flag
2779 // so that the device is not remounted in the middle of a PnP remove
2780 // operation.
2781 //
2782
2783 NT_ASSERT( Vcb->SwapVpb != NULL );
2784
2785 Vcb->SwapVpb->Type = IO_TYPE_VPB;
2786 Vcb->SwapVpb->Size = sizeof( VPB );
2787 Vcb->SwapVpb->RealDevice = OldVpb->RealDevice;
2788
2789 Vcb->SwapVpb->RealDevice->Vpb = Vcb->SwapVpb;
2790
2791 Vcb->SwapVpb->Flags = FlagOn( OldVpb->Flags, VPB_REMOVE_PENDING );
2792
2793 //
2794 // If we are working on a mount request, we need to make sure we update
2795 // the VPB in the IRP, since the one it points to may no longer be valid.
2796 //
2797
2798 if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL && IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) {
2799
2800 //
2801 // Get the IRP stack.
2802 //
2803
2804 IrpSp = IoGetCurrentIrpStackLocation( IrpContext->OriginatingIrp );
2805
2807
2808 //
2809 // Check the VPB in the IRP to see if it is the one we are swapping.
2810 //
2811
2812 if (IrpSp->Parameters.MountVolume.Vpb == OldVpb) {
2813
2814 //
2815 // Change the IRP to point to the swap VPB.
2816 //
2817
2818 IrpSp->Parameters.MountVolume.Vpb = Vcb->SwapVpb;
2819 }
2820 }
2821
2822#ifdef _MSC_VER
2823#pragma prefast( pop )
2824#endif
2825
2826 //
2827 // We place the volume in the Bad state (as opposed to NotMounted) so
2828 // that it is not eligible for a remount. Also indicate we used up
2829 // the swap.
2830 //
2831
2832 Vcb->SwapVpb = NULL;
2835
2836 Result = TRUE;
2837 }
2838
2839 return Result;
2840}
@ VcbBad
Definition: fatstruc.h:225
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
USHORT Flags
Definition: iotypes.h:192
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:195
#define IO_TYPE_VPB
struct _VPB VPB

◆ FatTearDownVcb()

VOID FatTearDownVcb ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 684 of file strucsup.c.

707{
708 PFILE_OBJECT DirectoryFileObject;
709
710
711 PAGED_CODE();
712
713 //
714 // Get rid of the virtual volume file, if we need to.
715 //
716
717 if (Vcb->VirtualVolumeFile != NULL) {
718
719 //
720 // Uninitialize the cache
721 //
722
723 CcUninitializeCacheMap( Vcb->VirtualVolumeFile,
725 NULL );
726
727 FsRtlTeardownPerStreamContexts( &Vcb->VolumeFileHeader );
728
729 ObDereferenceObject( Vcb->VirtualVolumeFile );
730
731 Vcb->VirtualVolumeFile = NULL;
732 }
733
734 //
735 // Close down the EA file.
736 //
737
738 FatCloseEaFile( IrpContext, Vcb, FALSE );
739
740 //
741 // Close down the root directory stream..
742 //
743
744 if (Vcb->RootDcb != NULL) {
745
746 DirectoryFileObject = Vcb->RootDcb->Specific.Dcb.DirectoryFile;
747
748 if (DirectoryFileObject != NULL) {
749
750 //
751 // Tear down this directory file.
752 //
753
754 CcUninitializeCacheMap( DirectoryFileObject,
756 NULL );
757
758 Vcb->RootDcb->Specific.Dcb.DirectoryFile = NULL;
759 ObDereferenceObject( DirectoryFileObject );
760 }
761 }
762
763 //
764 // The VCB can no longer be used.
765 //
766
768}
VOID FatCloseEaFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN FlushFirst)
Definition: cachesup.c:1079
LARGE_INTEGER FatLargeZero
Definition: fatdata.c:62
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286