ReactOS 0.4.15-dev-7788-g1ad9096
fatprocs.h File Reference
#include <ntifs.h>
#include <ntddscsi.h>
#include <scsi.h>
#include <ntddcdrm.h>
#include <ntdddisk.h>
#include <ntddstor.h>
#include <ntintsafe.h>
#include "nodetype.h"
#include "fat.h"
#include "lfn.h"
#include "fatstruc.h"
#include "fatdata.h"
Include dependency graph for fatprocs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _FAT_ENUMERATION_CONTEXT
 
union  _UCHAR1
 
union  _UCHAR2
 
union  _UCHAR4
 

Macros

#define INLINE   __inline
 
#define Add2Ptr(P, I)   ((PVOID)((PUCHAR)(P) + (I)))
 
#define MAX_ULONG   ((ULONG)-1)
 
#define MAX_USHORT   ((USHORT)-1)
 
#define FAT_CREATE_INITIAL_NAME_BUF_SIZE   32
 
#define FatUnpinBcb(IRPCONTEXT, BCB)
 
#define FatDirectoryKey(FcbOrDcb)   ((ULONGLONG)((FcbOrDcb)->CreationTime.QuadPart ^ (FcbOrDcb)->FirstClusterOfFile))
 
#define FatUpcaseEaName(IRPCONTEXT, NAME, UPCASEDNAME)    RtlUpperString( UPCASEDNAME, NAME )
 
#define SizeOfFullEa(EA)   (4+1+1+2+(EA)->EaNameLength+1+(EA)->EaValueLength)
 
#define FatAreNamesEqual(IRPCONTEXT, NAMEA, NAMEB)
 
#define FatIsNameShortOemValid(IRPCONTEXT, NAME, CAN_CONTAIN_WILD_CARDS, PATH_NAME_OK, LEADING_BACKSLASH_OK)
 
#define FatIsNameLongOemValid(IRPCONTEXT, NAME, CAN_CONTAIN_WILD_CARDS, PATH_NAME_OK, LEADING_BACKSLASH_OK)
 
#define FatAcquireExclusiveGlobal(IRPCONTEXT)
 
#define FatAcquireSharedGlobal(IRPCONTEXT)
 
#define FatAcquireExclusiveVolume(IRPCONTEXT, VCB)
 
#define FatReleaseVolume(IRPCONTEXT, VCB)
 
#define FatSetVcbCondition(V, X)   (V)->VcbCondition = (X)
 
#define FatIsFat32(VCB)   ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 32))
 
#define FatIsFat16(VCB)   ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 16))
 
#define FatIsFat12(VCB)   ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 12))
 
#define FatAcquireExclusiveVcb(IC, V)   FatAcquireExclusiveVcb_Real( IC, V, FALSE)
 
#define FatAcquireExclusiveVcbNoOpCheck(IC, V)   FatAcquireExclusiveVcb_Real( IC, V, TRUE)
 
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
 
#define FatFcbAcquiredShared(IRPCONTEXT, FCB)
 
#define FatFcbAcquiredExclusive(IRPCONTEXT, FCB)
 
#define FatAcquireDirectoryFileMutex(VCB)
 
#define FatReleaseDirectoryFileMutex(VCB)
 
#define FatConvertToSharedFcb(IRPCONTEXT, Fcb)
 
#define FatDeleteResource(RESRC)
 
#define FatReleaseGlobal(IRPCONTEXT)
 
#define FatReleaseVcb(IRPCONTEXT, Vcb)
 
#define FatReleaseFcb(IRPCONTEXT, Fcb)
 
#define FatGetFcbOplock(F)   &(F)->Header.Oplock
 
#define FatDeleteIrpContext(IRPCONTEXT)
 
#define FatGetFirstChild(DIR)
 
#define FatGetNextSibling(FILE)
 
#define FatIsRawDevice(IC, S)
 
#define CompareNames(NAMEA, NAMEB)
 
#define PtrOffset(BASE, OFFSET)   ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
 
#define WordAlign(Ptr)
 
#define LongAlign(Ptr)
 
#define QuadAlign(Ptr)
 
#define CopyUchar1(Dst, Src)
 
#define CopyUchar2(Dst, Src)
 
#define CopyUchar4(Dst, Src)
 
#define CopyU4char(Dst, Src)
 
#define FatNotifyReportChange(I, V, F, FL, A)
 
#define CanFsdWait(IRP)   IoIsOperationSynchronous(Irp)
 
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
 
#define IsFileDeleted(IRPCONTEXT, FCB)
 
#define IsFileWriteThrough(FO, VCB)
 
#define FatIsFastIoPossible(FCB)
 
#define FatIsNodeTypeOplockable(N)
 
#define FatIsFileOplockable(F)
 
#define IsFileObjectReadOnly(FO)   (!((FO)->WriteAccess | (FO)->DeleteAccess))
 
#define DebugBreakOnStatus(S)
 
#define FatRaiseStatus(IRPCONTEXT, STATUS)
 
#define FatResetExceptionState(IRPCONTEXT)
 
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
 
#define try_return(S)   { S; goto try_exit; }
 
#define try_leave(S)   { S; _SEH2_LEAVE; }
 
#define FatGenerateFileIdFromDirentOffset(ParentDcb, DirentOffset)
 
#define FatGenerateFileIdFromFcb(Fcb)    FatGenerateFileIdFromDirentOffset( (Fcb)->ParentDcb, (Fcb)->DirentOffsetWithinDirectory )
 
#define FATDOT   ((ULONG)0x2020202E)
 
#define FATDOTDOT   ((ULONG)0x20202E2E)
 
#define FatGenerateFileIdFromDirentAndOffset(Dcb, Dirent, DirentOffset)
 
#define FatDeviceIsFatFsdo(D)   (((D) == FatData.DiskFileSystemDeviceObject) || ((D) == FatData.CdromFileSystemDeviceObject))
 
#define BlockAlign(P, V)   ((ASSERT( V != 0)), (((P)) + (V-1) & (0-(V))))
 
#define BlockAlignTruncate(P, V)   ((P) & (0-(V)))
 
#define IsDirectory(FcbOrDcb)   ((NodeType((FcbOrDcb)) == FAT_NTC_DCB) || (NodeType((FcbOrDcb)) == FAT_NTC_ROOT_DCB))
 

Typedefs

typedef BOOLEAN FINISHED
 
typedef struct _FAT_ENUMERATION_CONTEXT FAT_ENUMERATION_CONTEXT
 
typedef struct _FAT_ENUMERATION_CONTEXTPFAT_ENUMERATION_CONTEXT
 
typedef enum _TYPE_OF_OPEN TYPE_OF_OPEN
 
typedef enum _FAT_FLUSH_TYPE FAT_FLUSH_TYPE
 
typedef enum _COMPARISON COMPARISON
 
typedef enum _FAT_VOLUME_STATE FAT_VOLUME_STATE
 
typedef enum _FAT_VOLUME_STATEPFAT_VOLUME_STATE
 
typedef union _UCHAR1 UCHAR1
 
typedef union _UCHAR1PUCHAR1
 
typedef union _UCHAR2 UCHAR2
 
typedef union _UCHAR2PUCHAR2
 
typedef union _UCHAR4 UCHAR4
 
typedef union _UCHAR4PUCHAR4
 

Enumerations

enum  _TYPE_OF_OPEN {
  UnopenedFileObject = 0 , StreamFileOpen , UserVolumeOpen , UserDirectoryOpen ,
  UserFileOpen , BeyondValidType , UnopenedFileObject = 1 , UserFileOpen ,
  UserDirectoryOpen , UserVolumeOpen , VirtualVolumeFile , DirectoryFile ,
  EaFile
}
 
enum  _FAT_FLUSH_TYPE { NoFlush = 0 , Flush , FlushAndInvalidate , FlushWithoutPurge }
 
enum  _COMPARISON { IsLessThan , IsGreaterThan , IsEqual }
 
enum  _FAT_VOLUME_STATE { VolumeClean , VolumeDirty , VolumeDirtyWithSurfaceTest }
 

Functions

VOID FatFreeStringBuffer (_Inout_ PVOID String)
 
VOID FatExtendString (_Inout_ PVOID String, _In_ USHORT DesiredBufferSize, _In_ BOOLEAN FreeOldBuffer, __out_opt PBOOLEAN NeedsFree)
 
VOID FatEnsureStringBufferEnough (_Inout_ PVOID String, _In_ USHORT DesiredBufferSize)
 
BOOLEAN FatAddMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN LBO Lbo, IN ULONG SectorCount)
 
BOOLEAN FatLookupMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount OPTIONAL, OUT PULONG Index OPTIONAL)
 
BOOLEAN FatLookupLastMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG Index OPTIONAL)
 
BOOLEAN FatGetNextMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount)
 
VOID FatRemoveMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN ULONG SectorCount)
 
BOOLEAN FatCheckFileAccess (PIRP_CONTEXT IrpContext, IN UCHAR DirentAttributes, IN PACCESS_MASK DesiredAccess)
 
BOOLEAN FatCheckManageVolumeAccess (_In_ PIRP_CONTEXT IrpContext, _In_ PACCESS_STATE AccessState, _In_ KPROCESSOR_MODE ProcessorMode)
 
NTSTATUS FatExplicitDeviceAccessGranted (IN PIRP_CONTEXT IrpContext, IN PDEVICE_OBJECT DeviceObject, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE ProcessorMode)
 
static INLINE BOOLEAN FatIsIoRangeValid (IN PVCB Vcb, IN LARGE_INTEGER Start, IN ULONG Length)
 
VOID FatLookupFatEntry (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN ULONG FatIndex, IN OUT PULONG FatEntry, IN OUT PFAT_ENUMERATION_CONTEXT Context)
 
VOID FatSetupAllocationSupport (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID FatTearDownAllocationSupport (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
 _Requires_lock_held_ (_Global_critical_region_) VOID FatLookupFileAllocation(IN PIRP_CONTEXT IrpContext
 
UCHAR FatLogOf (IN ULONG Value)
 
VOID FatReadVolumeFile (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb, OUT PVOID *Buffer)
 
PFILE_OBJECT FatOpenEaFile (IN PIRP_CONTEXT IrpContext, IN PFCB EaFcb)
 
VOID FatCloseEaFile (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN FlushFirst)
 
VOID FatRepinBcb (IN PIRP_CONTEXT IrpContext, IN PBCB Bcb)
 
VOID FatUnpinRepinnedBcbs (IN PIRP_CONTEXT IrpContext)
 
FINISHED FatZeroData (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN ULONG StartingZero, IN ULONG ByteCount)
 
NTSTATUS FatCompleteMdl (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
VOID FatPinMappedData (IN PIRP_CONTEXT IrpContext, IN PDCB Dcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb)
 
NTSTATUS FatPrefetchPages (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN ULONG StartingPage, IN ULONG PageCount)
 
VOID FatInitializeCacheMap (_In_ PFILE_OBJECT FileObject, _In_ PCC_FILE_SIZES FileSizes, _In_ BOOLEAN PinAccess, _In_ PCACHE_MANAGER_CALLBACKS Callbacks, _In_ PVOID LazyWriteContext)
 
VOID FatSyncUninitializeCacheMap (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject)
 
VOID FatPagingFileIo (IN PIRP Irp, IN PFCB Fcb)
 
VOID FatMultipleAsync (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PIRP Irp, IN ULONG MultipleIrpCount, IN PIO_RUN IoRuns)
 
VOID FatSingleAsync (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN LBO Lbo, IN ULONG ByteCount, IN PIRP Irp)
 
VOID FatWaitSync (IN PIRP_CONTEXT IrpContext)
 
VOID FatLockUserBuffer (IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
 
PVOID FatBufferUserBuffer (IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN ULONG BufferLength)
 
PVOID FatMapUserBuffer (IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
 
NTSTATUS FatToggleMediaEjectDisable (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
 
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)
 
PMDL FatBuildZeroMdl (__in PIRP_CONTEXT IrpContext, __in ULONG Length)
 
VOID FatTunnelFcbOrDcb (IN PFCB FcbOrDcb, IN PCCB Ccb OPTIONAL)
 
VOID FatConstructDirent (IN PIRP_CONTEXT IrpContext, IN OUT PDIRENT Dirent, IN POEM_STRING FileName, IN BOOLEAN ComponentReallyLowercase, IN BOOLEAN ExtensionReallyLowercase, IN PUNICODE_STRING Lfn OPTIONAL, IN USHORT Attributes, IN BOOLEAN ZeroAndSetTimeFields, IN PLARGE_INTEGER SetCreationTime OPTIONAL)
 
VOID FatConstructLabelDirent (IN PIRP_CONTEXT IrpContext, IN OUT PDIRENT Dirent, IN POEM_STRING Label)
 
VOID FatReadEaSet (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN USHORT EaHandle, IN POEM_STRING FileName, IN BOOLEAN ReturnEntireSet, OUT PEA_RANGE EaSetRange)
 
VOID FatDeletePackedEa (IN PIRP_CONTEXT IrpContext, IN OUT PEA_SET_HEADER EaSetHeader, IN OUT PULONG PackedEasLength, IN ULONG Offset)
 
VOID FatAppendPackedEa (IN PIRP_CONTEXT IrpContext, IN OUT PEA_SET_HEADER *EaSetHeader, IN OUT PULONG PackedEasLength, IN OUT PULONG AllocationLength, IN PFILE_FULL_EA_INFORMATION FullEa, IN ULONG BytesPerCluster)
 
ULONG FatLocateNextEa (IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN ULONG PreviousOffset)
 
BOOLEAN FatLocateEaByName (IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN POEM_STRING EaName, OUT PULONG Offset)
 
BOOLEAN FatIsEaNameValid (IN PIRP_CONTEXT IrpContext, IN OEM_STRING Name)
 
VOID FatPinEaRange (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT VirtualEaFile, IN PFCB EaFcb, IN OUT PEA_RANGE EaRange, IN ULONG StartingVbo, IN ULONG Length, IN NTSTATUS ErrorStatus)
 
VOID FatMarkEaRangeDirty (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT EaFileObject, IN OUT PEA_RANGE EaRange)
 
VOID FatUnpinEaRange (IN PIRP_CONTEXT IrpContext, IN OUT PEA_RANGE EaRange)
 
VOID FatSetFileObject (IN PFILE_OBJECT FileObject OPTIONAL, IN TYPE_OF_OPEN TypeOfOpen, IN PVOID VcbOrFcbOrDcb, IN PCCB Ccb OPTIONAL)
 
TYPE_OF_OPEN FatDecodeFileObject (_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
 
BOOLEAN FatIsBootSectorFat (IN PPACKED_BOOT_SECTOR BootSector)
 
NTSTATUS FatUnlockVolumeInternal (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject OPTIONAL)
 
static INLINE BOOLEAN FatIsNameLongUnicodeValid (PIRP_CONTEXT IrpContext, PUNICODE_STRING Name, BOOLEAN CanContainWildcards, BOOLEAN PathNameOk, BOOLEAN LeadingBackslashOk)
 
BOOLEAN FatIsNameInExpression (IN PIRP_CONTEXT IrpContext, IN OEM_STRING Expression, IN OEM_STRING Name)
 
VOID FatStringTo8dot3 (_In_ PIRP_CONTEXT IrpContext, _In_ OEM_STRING InputString, _Out_writes_bytes_(11) PFAT8DOT3 Output8dot3)
 
VOID Fat8dot3ToString (_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
 
VOID FatSetFullNameInFcb (_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ PUNICODE_STRING FinalName)
 
VOID FatUnicodeToUpcaseOem (IN PIRP_CONTEXT IrpContext, IN POEM_STRING OemString, IN PUNICODE_STRING UnicodeString)
 
VOID FatEvaluateNameCase (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING Name, IN OUT BOOLEAN *AllLowerComponent, IN OUT BOOLEAN *AllLowerExtension, IN OUT BOOLEAN *CreateLfn)
 
BOOLEAN FatSpaceInName (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING UnicodeName)
 
VOID FatUnicodeRestoreShortNameCase (IN PUNICODE_STRING ShortNameWithCase, IN BOOLEAN LowerCase8, IN BOOLEAN LowerCase3)
 
 _Acquires_exclusive_lock_ (Vcb->Resource)) FINISHED FatAcquireExclusiveVcb_Real(IN PIRP_CONTEXT IrpContext
 
 _Acquires_shared_lock_ (Vcb->Resource)) FINISHED FatAcquireSharedVcb(IN PIRP_CONTEXT IrpContext
 
_Acquires_shared_lock_ Fcb FINISHED FatAcquireSharedFcbWaitForEx (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
 
BOOLEAN FatAcquireVolumeForClose (IN PVOID Vcb, IN BOOLEAN Wait)
 
VOID FatReleaseVolumeFromClose (IN PVOID Vcb)
 
 _Function_class_ (FAST_IO_ACQUIRE_FOR_CCFLUSH) _Requires_lock_held_(_Global_critical_region_) NTSTATUS NTAPI FatAcquireForCcFlush(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_RELEASE_FOR_CCFLUSH) _Requires_lock_held_(_Global_critical_region_) NTSTATUS NTAPI FatReleaseForCcFlush(IN PFILE_OBJECT FileObject
 
BOOLEAN NTAPI FatNoOpAcquire (IN PVOID Fcb, IN BOOLEAN Wait)
 
VOID NTAPI FatNoOpRelease (IN PVOID Fcb)
 
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 *Fcb)
 
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 FatGetNextFcbTopDown (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
 
PFCB FatGetNextFcbBottomUp (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
 
VOID FatConstructNamesInFcb (IN PIRP_CONTEXT IrpContext, PFCB Fcb, PDIRENT Dirent, PUNICODE_STRING Lfn OPTIONAL)
 
ULONG FatVolumeUncleanCount (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID FatPreallocateCloseContext (IN PVCB Vcb)
 
PCLOSE_CONTEXT FatAllocateCloseContext (IN PVCB Vcb)
 
VOID FatInsertName (IN PIRP_CONTEXT IrpContext, IN PRTL_SPLAY_LINKS *RootNode, IN PFILE_NAME_NODE Name)
 
VOID FatRemoveNames (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
 
PFCB FatFindFcb (IN PIRP_CONTEXT IrpContext, IN OUT PRTL_SPLAY_LINKS *RootNode, IN PSTRING Name, OUT PBOOLEAN FileNameDos OPTIONAL)
 
BOOLEAN FatIsHandleCountZero (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
COMPARISON FatCompareNames (IN PSTRING NameA, IN PSTRING NameB)
 
 _Success_ (return !=FALSE) BOOLEAN FatNtTimeToFatTime(_In_ PIRP_CONTEXT IrpContext
 
LARGE_INTEGER FatFatTimeToNtTime (_In_ PIRP_CONTEXT IrpContext, _In_ FAT_TIME_STAMP FatTime, _In_ UCHAR TenMilliSeconds)
 
LARGE_INTEGER FatFatDateToNtTime (_In_ PIRP_CONTEXT IrpContext, _In_ FAT_DATE FatDate)
 
FAT_TIME_STAMP FatGetCurrentFatTime (_In_ PIRP_CONTEXT IrpContext)
 
VOID FatMarkFcbCondition (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN FCB_CONDITION FcbCondition, IN BOOLEAN Recursive)
 
VOID FatVerifyVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID NTAPI FatCleanVolumeDpc (_In_ PKDPC Dpc, _In_opt_ PVOID DeferredContext, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
 
VOID NTAPI FatFspMarkVolumeDirtyWithRecover (PVOID Parameter)
 
VOID FatCheckDirtyBit (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID FatQuickVerifyVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID FatVerifyOperationIsLegal (IN PIRP_CONTEXT IrpContext)
 
VOID NTAPI FatOplockComplete (IN PVOID Context, IN PIRP Irp)
 
VOID NTAPI FatPrePostIrp (IN PVOID Context, IN PIRP Irp)
 
VOID FatAddToWorkque (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatFsdPostRequest (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
 _Function_class_ (IRP_MJ_CLEANUP) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdCleanup(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_CLOSE) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdClose(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_CREATE) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdCreate(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_DEVICE_CONTROL) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdDeviceControl(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_DIRECTORY_CONTROL) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdDirectoryControl(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_QUERY_EA) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdQueryEa(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_SET_EA) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdSetEa(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_QUERY_INFORMATION) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdQueryInformation(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_SET_INFORMATION) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdSetInformation(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_FLUSH_BUFFERS) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdFlushBuffers(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_FILE_SYSTEM_CONTROL) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdFileSystemControl(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_LOCK_CONTROL) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdLockControl(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_PNP) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdPnp(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_READ) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdRead(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_SHUTDOWN) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdShutdown(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_QUERY_VOLUME_INFORMATION) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdQueryVolumeInformation(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_SET_VOLUME_INFORMATION) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdSetVolumeInformation(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
 _Function_class_ (IRP_MJ_WRITE) _Function_class_(DRIVER_DISPATCH) NTSTATUS NTAPI FatFsdWrite(_In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject
 
VOID NTAPI FatFspDispatch (_In_ PVOID Context)
 
NTSTATUS FatCommonQueryEa (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatCommonSetEa (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatFlushFat (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
NTSTATUS FatHijackIrpAndFlushDevice (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT TargetDeviceObject)
 
VOID FatFlushFatEntries (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN ULONG Cluster, IN ULONG Count)
 
VOID FatFlushDirentForFile (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
 
VOID FatCompleteRequest_Real (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN NTSTATUS Status)
 
BOOLEAN FatIsIrpTopLevel (IN PIRP Irp)
 
 _Function_class_ (FAST_IO_CHECK_IF_POSSIBLE) BOOLEAN NTAPI FatFastIoCheckIfPossible(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_QUERY_BASIC_INFO) BOOLEAN NTAPI FatFastQueryBasicInfo(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_QUERY_STANDARD_INFO) BOOLEAN NTAPI FatFastQueryStdInfo(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_QUERY_NETWORK_OPEN_INFO) BOOLEAN NTAPI FatFastQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_LOCK) BOOLEAN NTAPI FatFastLock(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_UNLOCK_SINGLE) BOOLEAN NTAPI FatFastUnlockSingle(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_UNLOCK_ALL) BOOLEAN NTAPI FatFastUnlockAll(IN PFILE_OBJECT FileObject
 
 _Function_class_ (FAST_IO_UNLOCK_ALL_BY_KEY) BOOLEAN NTAPI FatFastUnlockAllByKey(IN PFILE_OBJECT FileObject
 
VOID FatExamineFatEntries (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN ULONG StartIndex OPTIONAL, IN ULONG EndIndex OPTIONAL, IN BOOLEAN SetupWindows, IN PFAT_WINDOW SwitchToWindow OPTIONAL, IN PULONG BitMapBuffer OPTIONAL)
 
BOOLEAN FatScanForDataTrack (IN PIRP_CONTEXT IrpContext, IN PDEVICE_OBJECT TargetDeviceObject)
 
ULONG FatExceptionFilter (IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
 
CLUSTER_TYPE FatInterpretClusterType (IN PVCB Vcb, IN FAT_ENTRY Entry)
 

Variables

IN PFCB FcbOrDcb
 
IN PFCB IN VBO Vbo
 
IN PFCB IN VBO OUT PLBO Lbo
 
IN PFCB IN VBO OUT PLBO OUT PULONG ByteCount
 
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
 
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN OUT PBOOLEAN EndOnMax
 
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN OUT PBOOLEAN OUT PULONG Index OPTIONAL
 
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
 
IN PVCB Vcb
 
IN PVCB IN ULONG AbsoluteClusterHint
 
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN ExactMatchRequired
 
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
 
IN PVCB IN PLARGE_MCB IN BOOLEAN ZeroOnDeallocate
 
IN PVCB IN OUT PLARGE_MCB IN VBO SplitAtVbo
 
IN PVCB IN OUT PLARGE_MCB IN VBO OUT PLARGE_MCB RemainingMcb
 
IN PVCB IN OUT PLARGE_MCB IN PLARGE_MCB SecondMcb
 
IN PVCB IN ULONG FatIndex
 
IN PVCB IN ULONG IN FAT_ENTRY FatEntry
 
IN PVCB IN VBO StartingVbo
 
IN PVCB IN VBO IN ULONG OUT PBCBBcb
 
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOIDBuffer
 
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN Reversible
 
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
 
IN PDCB Dcb
 
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
 
IN PDCB IN VBO IN ULONG IN BOOLEAN OUT PBCB OUT PVOID OUT PNTSTATUS Status
 
IN PIRP Irp
 
IN PIRP IN PFCB IN ULONG IN ULONG IN ULONG UserByteCount
 
IN PIRP IN PFCB IN ULONG IN ULONG IN ULONG IN ULONG StreamFlags
 
IN PDCB ParentDirectory
 
IN PDCB IN ULONG DirentsNeeded
 
IN PDCB IN ULONG IN BOOLEAN RescanDir
 
IN PDCB IN PDIRENT ParentDirent
 
IN PFCB IN PDELETE_CONTEXT DeleteContext IN BOOLEAN DeleteEa
 
IN PDCB IN PCCB Ccb
 
IN PDCB IN PCCB IN VBO OffsetToStartSearchFrom
 
IN PDCB IN PCCB IN VBO IN OUT PULONG Flags
 
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENTDirent
 
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
 
IN PDCB IN POEM_STRING FileName
 
IN PDCB IN PUNICODE_STRING Lfn
 
IN PDCB IN PUNICODE_STRING IN PUNICODE_STRING LfnTmp
 
IN PFCB IN BOOLEAN ReturnOnFailure
 
IN PDCB TargetDcb
 
IN PDCB IN ULONG LfnOffset
 
IN PDCB IN ULONG IN ULONG DirentOffset
 
IN PFCB Fcb
 
IN PFILE_OBJECT FileObject
 
IN PVCB IN PDIRENT OUT PULONG EaLength
 
IN PVCB IN PDIRENT OUT PULONG NeedEaCount
 
IN PVCB IN PUCHAR IN ULONG Length
 
IN PVCB IN PUCHAR IN ULONG IN POEM_STRING OUT PUSHORT EaHandle
 
IN OUT PVCB OUT PDIRENTEaDirent
 
IN OUT PVCB OUT PDIRENT OUT PBCBEaBcb
 
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
 
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN IN BOOLEAN ExclusiveFcb
 
IN PVCB IN PBCB OUT PDIRENT IN USHORT IN POEM_STRING Filename
 
IN PVCB IN ULONG EaSetLength
 
IN PVCB IN ULONG IN PBCB OUT PDIRENT OUT PUSHORT OUT PEA_RANGE EaSetRange
 
IN PFCB IN FAT_FLUSH_TYPE FlushType
 
IN PDCB Parent
 
IN PDCB IN POEM_STRING OemName
 
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
 
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
 
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEANAllLowerComponent
 
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN IN OUT BOOLEANAllLowerExtension
 
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN IN OUT BOOLEAN IN OUT BOOLEANCreateLfn
 
IN PVCB IN BOOLEAN NoOpCheck
 
IN BOOLEAN Wait
 
IN PDEVICE_OBJECT DeviceObject
 
OUT PVOIDCompletionContext
 
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
 
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
 
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB IN PDEVICE_OBJECT FsDeviceObject
 
PVCB IN BOOLEAN Force
 
_In_ PLARGE_INTEGER NtTime
 
_In_ PLARGE_INTEGER _In_ BOOLEAN Rounding
 
_In_ PLARGE_INTEGER _In_ BOOLEAN _Out_ PFAT_TIME_STAMP FatTime
 
_In_ PLARGE_INTEGER _In_ BOOLEAN _Out_ PFAT_TIME_STAMP _Out_opt_ PUCHAR TenMsecs
 
KDEFERRED_ROUTINE FatCleanVolumeDpc
 
IN PVCB IN FAT_VOLUME_STATE VolumeState
 
WORKER_THREAD_ROUTINE FatFspMarkVolumeDirtyWithRecover
 
_In_ PIRP _In_ PDEVICE_OBJECT Device
 
WORKER_THREAD_ROUTINE FatFspDispatch
 
IN PFCB IN PCCB IN TYPE_OF_OPEN TypeOfOpen
 
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
 
IN PLARGE_INTEGER FileOffset
 
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
 
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
 
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
 
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
 
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
 
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN FailImmediately
 
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN BOOLEAN ExclusiveLock
 
IN PIRP IN NTSTATUS ExceptionCode
 

Macro Definition Documentation

◆ Add2Ptr

#define Add2Ptr (   P,
  I 
)    ((PVOID)((PUCHAR)(P) + (I)))

Definition at line 80 of file fatprocs.h.

◆ BlockAlign

#define BlockAlign (   P,
  V 
)    ((ASSERT( V != 0)), (((P)) + (V-1) & (0-(V))))

Definition at line 3103 of file fatprocs.h.

◆ BlockAlignTruncate

#define BlockAlignTruncate (   P,
  V 
)    ((P) & (0-(V)))

Definition at line 3104 of file fatprocs.h.

◆ CanFsdWait

#define CanFsdWait (   IRP)    IoIsOperationSynchronous(Irp)

Definition at line 2370 of file fatprocs.h.

◆ CompareNames

#define CompareNames (   NAMEA,
  NAMEB 
)
Value:
( \
*(PUCHAR)(NAMEA)->Buffer != *(PUCHAR)(NAMEB)->Buffer ? \
*(PUCHAR)(NAMEA)->Buffer < *(PUCHAR)(NAMEB)->Buffer ? \
FatCompareNames((PSTRING)(NAMEA), (PSTRING)(NAMEB)) \
)
@ IsLessThan
Definition: fatprocs.h:1884
@ IsGreaterThan
Definition: fatprocs.h:1885
unsigned char * PUCHAR
Definition: typedefs.h:53

Definition at line 1899 of file fatprocs.h.

◆ CopyU4char

#define CopyU4char (   Dst,
  Src 
)
Value:
{ \
*((UNALIGNED UCHAR4 *)(Dst)) = *((UCHAR4 *)(Src)); \
}
#define UNALIGNED
Definition: crtdefs.h:144
#define Dst
Definition: mesh.h:153

Definition at line 2153 of file fatprocs.h.

◆ CopyUchar1

#define CopyUchar1 (   Dst,
  Src 
)
Value:
{ \
*((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
}

Definition at line 2133 of file fatprocs.h.

◆ CopyUchar2

#define CopyUchar2 (   Dst,
  Src 
)
Value:
{ \
*((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
}

Definition at line 2141 of file fatprocs.h.

◆ CopyUchar4

#define CopyUchar4 (   Dst,
  Src 
)
Value:
{ \
*((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
}

Definition at line 2149 of file fatprocs.h.

◆ DebugBreakOnStatus

#define DebugBreakOnStatus (   S)

Definition at line 2974 of file fatprocs.h.

◆ FAT_CREATE_INITIAL_NAME_BUF_SIZE

#define FAT_CREATE_INITIAL_NAME_BUF_SIZE   32

Definition at line 111 of file fatprocs.h.

◆ FatAcquireDirectoryFileMutex

#define FatAcquireDirectoryFileMutex (   VCB)
Value:
{ \
NT_ASSERT(KeAreApcsDisabled()); \
ExAcquireFastMutexUnsafe(&(VCB)->DirectoryFileCreationMutex); \
}
BOOLEAN NTAPI KeAreApcsDisabled(VOID)
Definition: apc.c:958
Definition: cdstruc.h:498

Definition at line 1508 of file fatprocs.h.

◆ FatAcquireExclusiveGlobal

#define FatAcquireExclusiveGlobal (   IRPCONTEXT)
Value:
( \
ExAcquireResourceExclusiveLite( &FatData.Resource, BooleanFlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT) ) \
)
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
FAT_DATA FatData
Definition: fatdata.c:56
ERESOURCE Resource
Definition: fatstruc.h:68
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Definition at line 1387 of file fatprocs.h.

◆ FatAcquireExclusiveVcb

#define FatAcquireExclusiveVcb (   IC,
  V 
)    FatAcquireExclusiveVcb_Real( IC, V, FALSE)

Definition at line 1460 of file fatprocs.h.

◆ FatAcquireExclusiveVcbNoOpCheck

#define FatAcquireExclusiveVcbNoOpCheck (   IC,
  V 
)    FatAcquireExclusiveVcb_Real( IC, V, TRUE)

Definition at line 1461 of file fatprocs.h.

◆ FatAcquireExclusiveVolume

#define FatAcquireExclusiveVolume (   IRPCONTEXT,
  VCB 
)
Value:
{ \
PFCB __FFFFFcb = NULL; \
NT_ASSERT(FlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT)); \
(VOID)FatAcquireExclusiveVcb( (IRPCONTEXT), (VCB) ); \
while ( (__FFFFFcb = FatGetNextFcbBottomUp((IRPCONTEXT), __FFFFFcb, (VCB)->RootDcb)) != NULL) { \
(VOID)FatAcquireExclusiveFcb((IRPCONTEXT), __FFFFFcb ); \
} \
}
#define VOID
Definition: acefi.h:82
struct _VCB VCB
#define NULL
Definition: types.h:112
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define FatAcquireExclusiveVcb(IC, V)
Definition: fatprocs.h:1460
PFCB FatGetNextFcbBottomUp(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
Definition: strucsup.c:2525
Definition: cdstruc.h:902

Definition at line 1409 of file fatprocs.h.

◆ FatAcquireSharedGlobal

#define FatAcquireSharedGlobal (   IRPCONTEXT)
Value:
( \
ExAcquireResourceSharedLite( &FatData.Resource, BooleanFlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT) ) \
)

Definition at line 1391 of file fatprocs.h.

◆ FatAreNamesEqual

#define FatAreNamesEqual (   IRPCONTEXT,
  NAMEA,
  NAMEB 
)
Value:
( \
((ULONG)(NAMEA).Length == (ULONG)(NAMEB).Length) && \
(RtlEqualMemory( &(NAMEA).Buffer[0], \
&(NAMEB).Buffer[0], \
(NAMEA).Length )) \
)
Definition: bufpool.h:45
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
uint32_t ULONG
Definition: typedefs.h:59

Definition at line 1158 of file fatprocs.h.

◆ FatCompleteRequest

#define FatCompleteRequest (   IRPCONTEXT,
  IRP,
  STATUS 
)
Value:
{ \
FatCompleteRequest_Real(IRPCONTEXT,IRP,STATUS); \
}
#define STATUS
Definition: blue.h:116

Definition at line 2633 of file fatprocs.h.

◆ FatConvertToSharedFcb

#define FatConvertToSharedFcb (   IRPCONTEXT,
  Fcb 
)
Value:
{ \
ExConvertExclusiveToSharedLite( (Fcb)->Header.Resource ); \
}
Definition: Header.h:9
IN PFCB Fcb
Definition: fatprocs.h:820

Definition at line 1609 of file fatprocs.h.

◆ FatDeleteIrpContext

#define FatDeleteIrpContext (   IRPCONTEXT)
Value:
{ \
FatDeleteIrpContext_Real((IRPCONTEXT)); \
}

Definition at line 1762 of file fatprocs.h.

◆ FatDeleteResource

#define FatDeleteResource (   RESRC)
Value:
{ \
ExDeleteResourceLite( (RESRC) ); \
}

Definition at line 1632 of file fatprocs.h.

◆ FatDeviceIsFatFsdo

#define FatDeviceIsFatFsdo (   D)    (((D) == FatData.DiskFileSystemDeviceObject) || ((D) == FatData.CdromFileSystemDeviceObject))

Definition at line 3095 of file fatprocs.h.

◆ FatDirectoryKey

#define FatDirectoryKey (   FcbOrDcb)    ((ULONGLONG)((FcbOrDcb)->CreationTime.QuadPart ^ (FcbOrDcb)->FirstClusterOfFile))

Definition at line 850 of file fatprocs.h.

◆ FATDOT

#define FATDOT   ((ULONG)0x2020202E)

Definition at line 3074 of file fatprocs.h.

◆ FATDOTDOT

#define FATDOTDOT   ((ULONG)0x20202E2E)

Definition at line 3075 of file fatprocs.h.

◆ FatFcbAcquiredExclusive

#define FatFcbAcquiredExclusive (   IRPCONTEXT,
  FCB 
)
Value:
( \
ExIsResourceAcquiredExclusiveLite((FCB)->Header.Resource) \
)

Definition at line 1504 of file fatprocs.h.

◆ FatFcbAcquiredShared

#define FatFcbAcquiredShared (   IRPCONTEXT,
  FCB 
)
Value:
( \
ExIsResourceAcquiredSharedLite((FCB)->Header.Resource) \
)

Definition at line 1500 of file fatprocs.h.

◆ FatGenerateFileIdFromDirentAndOffset

#define FatGenerateFileIdFromDirentAndOffset (   Dcb,
  Dirent,
  DirentOffset 
)
Value:
((*((PULONG)(Dirent)->FileName)) == FATDOT ? FatGenerateFileIdFromFcb(Dcb) : \
((*((PULONG)(Dirent)->FileName)) == FATDOTDOT ? ((Dcb)->ParentDcb ? \
0) : \
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB ParentDcb
Definition: create.c:4141
#define FATDOTDOT
Definition: fatprocs.h:3075
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT * Dirent
Definition: fatprocs.h:729
#define FatGenerateFileIdFromDirentOffset(ParentDcb, DirentOffset)
Definition: fatprocs.h:3054
IN PDCB IN ULONG IN ULONG DirentOffset
Definition: fatprocs.h:790
#define FatGenerateFileIdFromFcb(Fcb)
Definition: fatprocs.h:3066
#define FATDOT
Definition: fatprocs.h:3074
IN PDCB Dcb
Definition: fatprocs.h:424
uint32_t * PULONG
Definition: typedefs.h:59

Definition at line 3077 of file fatprocs.h.

◆ FatGenerateFileIdFromDirentOffset

#define FatGenerateFileIdFromDirentOffset (   ParentDcb,
  DirentOffset 
)
Value:
FatGetLboFromIndex( (ParentDcb)->Vcb, \
(ParentDcb)->FirstClusterOfFile ) : \
(ParentDcb)->Vcb->AllocationSupport.RootDirectoryLbo) + \
: \
0)
#define NodeType(P)
Definition: nodetype.h:51
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
IN PVCB Vcb
Definition: fatprocs.h:343
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446

Definition at line 3054 of file fatprocs.h.

◆ FatGenerateFileIdFromFcb

#define FatGenerateFileIdFromFcb (   Fcb)     FatGenerateFileIdFromDirentOffset( (Fcb)->ParentDcb, (Fcb)->DirentOffsetWithinDirectory )

Definition at line 3066 of file fatprocs.h.

◆ FatGetFcbOplock

#define FatGetFcbOplock (   F)    &(F)->Header.Oplock

Definition at line 1656 of file fatprocs.h.

◆ FatGetFirstChild

#define FatGetFirstChild (   DIR)
Value:
((PFCB)( \
IsListEmpty(&(DIR)->Specific.Dcb.ParentDcbQueue) ? NULL : \
CONTAINING_RECORD((DIR)->Specific.Dcb.ParentDcbQueue.Flink, \
DCB, \
ParentDcbLinks.Flink)))
FCB * PFCB
Definition: cdstruc.h:1040
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
Definition: dirent.h:40

Definition at line 1785 of file fatprocs.h.

◆ FatGetNextSibling

#define FatGetNextSibling (   FILE)
Value:
((PFCB)( \
&(FILE)->ParentDcb->Specific.Dcb.ParentDcbQueue.Flink == \
(PVOID)(FILE)->ParentDcbLinks.Flink ? NULL : \
CONTAINING_RECORD((FILE)->ParentDcbLinks.Flink, \
FCB, \
ParentDcbLinks.Flink)))
void * PVOID
Definition: typedefs.h:50

Definition at line 1791 of file fatprocs.h.

◆ FatIsFastIoPossible

#define FatIsFastIoPossible (   FCB)
Value:
((BOOLEAN) \
((((FCB)->FcbCondition != FcbGood) || \
(NodeType( (FCB) ) != FAT_NTC_FCB) || \
: \
(!FsRtlAreThereCurrentFileLocks( &(FCB)->Specific.Fcb.FileLock ) && \
((FCB)->NonPaged->OutstandingAsyncWrites == 0) && \
: \
) \
) \
)
struct _FCB FCB
@ FcbGood
Definition: cdstruc.h:779
#define FAT_NTC_FCB
Definition: nodetype.h:29
#define FatGetFcbOplock(F)
Definition: fatprocs.h:1656
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:570
#define FsRtlAreThereCurrentFileLocks(FL)
Definition: fsrtlfuncs.h:1584
@ FastIoIsQuestionable
Definition: fsrtltypes.h:242
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240
@ FastIoIsPossible
Definition: fsrtltypes.h:241
BOOLEAN NTAPI FsRtlOplockIsFastIoPossible(IN POPLOCK Oplock)
Definition: oplock.c:1564
#define BOOLEAN
Definition: pedump.c:73
ULONG VcbState
Definition: cdstruc.h:540

Definition at line 2813 of file fatprocs.h.

◆ FatIsFat12

#define FatIsFat12 (   VCB)    ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 12))

Definition at line 1448 of file fatprocs.h.

◆ FatIsFat16

#define FatIsFat16 (   VCB)    ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 16))

Definition at line 1447 of file fatprocs.h.

◆ FatIsFat32

#define FatIsFat32 (   VCB)    ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 32))

Definition at line 1446 of file fatprocs.h.

◆ FatIsFileOplockable

#define FatIsFileOplockable (   F)
Value:
( \
FatIsNodeTypeOplockable( NodeType( (F) )) \
)
#define F(x, y, z)
Definition: md5.c:51

Definition at line 2851 of file fatprocs.h.

◆ FatIsNameLongOemValid

#define FatIsNameLongOemValid (   IRPCONTEXT,
  NAME,
  CAN_CONTAIN_WILD_CARDS,
  PATH_NAME_OK,
  LEADING_BACKSLASH_OK 
)
Value:
( \
FsRtlIsHpfsDbcsLegal((NAME), \
(CAN_CONTAIN_WILD_CARDS), \
(PATH_NAME_OK), \
(LEADING_BACKSLASH_OK)) \
)
@ NAME
Definition: inflate.c:164

Definition at line 1205 of file fatprocs.h.

◆ FatIsNameShortOemValid

#define FatIsNameShortOemValid (   IRPCONTEXT,
  NAME,
  CAN_CONTAIN_WILD_CARDS,
  PATH_NAME_OK,
  LEADING_BACKSLASH_OK 
)
Value:
( \
FsRtlIsFatDbcsLegal((NAME), \
(CAN_CONTAIN_WILD_CARDS), \
(PATH_NAME_OK), \
(LEADING_BACKSLASH_OK)) \
)

Definition at line 1198 of file fatprocs.h.

◆ FatIsNodeTypeOplockable

#define FatIsNodeTypeOplockable (   N)
Value:
( \
((N) == FAT_NTC_FCB) || \
((N) == FAT_NTC_ROOT_DCB) || \
((N) == FAT_NTC_DCB) \
)
#define N
Definition: crc32.c:57
#define FAT_NTC_DCB
Definition: nodetype.h:30

Definition at line 2837 of file fatprocs.h.

◆ FatIsRawDevice

#define FatIsRawDevice (   IC,
  S 
)
Value:
( \
)
#define S(x)
Definition: test.h:217
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141

Definition at line 1845 of file fatprocs.h.

◆ FatNormalizeAndRaiseStatus

#define FatNormalizeAndRaiseStatus (   IRPCONTEXT,
  STATUS 
)
Value:
{ \
(IRPCONTEXT)->ExceptionStatus = (STATUS); \
}
NTSTATUS NTAPI FsRtlNormalizeNtstatus(IN NTSTATUS NtStatusToNormalize, IN NTSTATUS NormalizedNtStatus)
Definition: filter.c:90
#define STATUS_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:469

Definition at line 2995 of file fatprocs.h.

◆ FatNotifyReportChange

#define FatNotifyReportChange (   I,
  V,
  F,
  FL,
  A 
)
Value:
{ \
if ((F)->FullFileName.Buffer == NULL) { \
FatSetFullFileNameInFcb((I),(F)); \
} \
NT_ASSERT( (F)->FullFileName.Length != 0 ); \
NT_ASSERT( (F)->FinalNameLength != 0 ); \
NT_ASSERT( (F)->FullFileName.Length > (F)->FinalNameLength ); \
NT_ASSERT( (F)->FullFileName.Buffer[((F)->FullFileName.Length - (F)->FinalNameLength)/sizeof(WCHAR) - 1] == L'\\' ); \
FsRtlNotifyFullReportChange( (V)->NotifySync, \
&(V)->DirNotifyList, \
(PSTRING)&(F)->FullFileName, \
(USHORT) ((F)->FullFileName.Length - \
(F)->FinalNameLength), \
(ULONG)FL, \
(ULONG)A, \
(PVOID)NULL ); \
}
Definition: ehthrow.cxx:93
#define I(s)
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
__wchar_t WCHAR
Definition: xmlstorage.h:180

Definition at line 2168 of file fatprocs.h.

◆ FatRaiseStatus

#define FatRaiseStatus (   IRPCONTEXT,
  STATUS 
)
Value:
{ \
(IRPCONTEXT)->ExceptionStatus = (STATUS); \
DebugBreakOnStatus( (STATUS) ) \
ExRaiseStatus( (STATUS) ); \
}

Definition at line 2977 of file fatprocs.h.

◆ FatReleaseDirectoryFileMutex

#define FatReleaseDirectoryFileMutex (   VCB)
Value:
{ \
NT_ASSERT(KeAreApcsDisabled()); \
ExReleaseFastMutexUnsafe(&(VCB)->DirectoryFileCreationMutex); \
}

Definition at line 1513 of file fatprocs.h.

◆ FatReleaseFcb

#define FatReleaseFcb (   IRPCONTEXT,
  Fcb 
)
Value:
{ \
ExReleaseResourceLite( (Fcb)->Header.Resource ); \
}

Definition at line 1644 of file fatprocs.h.

◆ FatReleaseGlobal

#define FatReleaseGlobal (   IRPCONTEXT)
Value:
{ \
ExReleaseResourceLite( &(FatData.Resource) ); \
}

Definition at line 1636 of file fatprocs.h.

◆ FatReleaseVcb

#define FatReleaseVcb (   IRPCONTEXT,
  Vcb 
)
Value:
{ \
ExReleaseResourceLite( &((Vcb)->Resource) ); \
}
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843

Definition at line 1640 of file fatprocs.h.

◆ FatReleaseVolume

#define FatReleaseVolume (   IRPCONTEXT,
  VCB 
)
Value:
{ \
PFCB __FFFFFcb = NULL; \
NT_ASSERT(FlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT)); \
while ( (__FFFFFcb = FatGetNextFcbBottomUp((IRPCONTEXT), __FFFFFcb, (VCB)->RootDcb)) != NULL) { \
(VOID)ExReleaseResourceLite( __FFFFFcb->Header.Resource ); \
} \
FatReleaseVcb((IRPCONTEXT), (VCB)); \
}
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925

Definition at line 1418 of file fatprocs.h.

◆ FatResetExceptionState

#define FatResetExceptionState (   IRPCONTEXT)
Value:
{ \
(IRPCONTEXT)->ExceptionStatus = STATUS_SUCCESS; \
}
#define STATUS_SUCCESS
Definition: shellext.h:65

Definition at line 2983 of file fatprocs.h.

◆ FatSetVcbCondition

#define FatSetVcbCondition (   V,
  X 
)    (V)->VcbCondition = (X)

Definition at line 1438 of file fatprocs.h.

◆ FatUnpinBcb

#define FatUnpinBcb (   IRPCONTEXT,
  BCB 
)
Value:
{ \
if ((BCB) != NULL) { \
CcUnpinData((BCB)); \
(BCB) = NULL; \
} \
}

Definition at line 546 of file fatprocs.h.

◆ FatUpcaseEaName

#define FatUpcaseEaName (   IRPCONTEXT,
  NAME,
  UPCASEDNAME 
)     RtlUpperString( UPCASEDNAME, NAME )

Definition at line 868 of file fatprocs.h.

◆ FatVcbAcquiredExclusive

#define FatVcbAcquiredExclusive (   IRPCONTEXT,
  VCB 
)
Value:
( \
ExIsResourceAcquiredExclusiveLite(&(VCB)->Resource) || \
ExIsResourceAcquiredExclusiveLite(&FatData.Resource) \
)

Definition at line 1495 of file fatprocs.h.

◆ INLINE

#define INLINE   __inline

Definition at line 77 of file fatprocs.h.

◆ IsDirectory

#define IsDirectory (   FcbOrDcb)    ((NodeType((FcbOrDcb)) == FAT_NTC_DCB) || (NodeType((FcbOrDcb)) == FAT_NTC_ROOT_DCB))

Definition at line 3106 of file fatprocs.h.

◆ IsFileDeleted

#define IsFileDeleted (   IRPCONTEXT,
  FCB 
)
Value:
(FlagOn((FCB)->FcbState, FCB_STATE_DELETE_ON_CLOSE) && \
((FCB)->UncleanCount == 0))
Dcb UncleanCount
Definition: create.c:4340
#define FCB_STATE_DELETE_ON_CLOSE
Definition: fatstruc.h:1193

Definition at line 2781 of file fatprocs.h.

◆ IsFileObjectReadOnly

#define IsFileObjectReadOnly (   FO)    (!((FO)->WriteAccess | (FO)->DeleteAccess))

Definition at line 2866 of file fatprocs.h.

◆ IsFileWriteThrough

#define IsFileWriteThrough (   FO,
  VCB 
)
Value:
( \
BooleanFlagOn((FO)->Flags, FO_WRITE_THROUGH) \
)
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779

Definition at line 2796 of file fatprocs.h.

◆ LongAlign

#define LongAlign (   Ptr)
Value:
( \
((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898

Definition at line 2096 of file fatprocs.h.

◆ MAX_ULONG

#define MAX_ULONG   ((ULONG)-1)

Definition at line 83 of file fatprocs.h.

◆ MAX_USHORT

#define MAX_USHORT   ((USHORT)-1)

Definition at line 87 of file fatprocs.h.

◆ PtrOffset

#define PtrOffset (   BASE,
  OFFSET 
)    ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))

Definition at line 2080 of file fatprocs.h.

◆ QuadAlign

#define QuadAlign (   Ptr)
Value:
( \
((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
)

Definition at line 2105 of file fatprocs.h.

◆ SizeOfFullEa

#define SizeOfFullEa (   EA)    (4+1+1+2+(EA)->EaNameLength+1+(EA)->EaValueLength)

Definition at line 1030 of file fatprocs.h.

◆ try_leave

#define try_leave (   S)    { S; _SEH2_LEAVE; }

Definition at line 3030 of file fatprocs.h.

◆ try_return

#define try_return (   S)    { S; goto try_exit; }

Definition at line 3029 of file fatprocs.h.

◆ WordAlign

#define WordAlign (   Ptr)
Value:
( \
((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
)

Definition at line 2087 of file fatprocs.h.

Typedef Documentation

◆ COMPARISON

◆ FAT_ENUMERATION_CONTEXT

◆ FAT_FLUSH_TYPE

◆ FAT_VOLUME_STATE

◆ FINISHED

typedef BOOLEAN FINISHED

Definition at line 104 of file fatprocs.h.

◆ PFAT_ENUMERATION_CONTEXT

◆ PFAT_VOLUME_STATE

◆ PUCHAR1

typedef union _UCHAR1 * PUCHAR1

◆ PUCHAR2

typedef union _UCHAR2 * PUCHAR2

◆ PUCHAR4

typedef union _UCHAR4 * PUCHAR4

◆ TYPE_OF_OPEN

◆ UCHAR1

typedef union _UCHAR1 UCHAR1

◆ UCHAR2

typedef union _UCHAR2 UCHAR2

◆ UCHAR4

typedef union _UCHAR4 UCHAR4

Enumeration Type Documentation

◆ _COMPARISON

Enumerator
IsLessThan 
IsGreaterThan 
IsEqual 

Definition at line 1883 of file fatprocs.h.

1883 {
1884 IsLessThan,
1886 IsEqual
1887} COMPARISON;
@ IsEqual
Definition: fatprocs.h:1886
enum _COMPARISON COMPARISON

◆ _FAT_FLUSH_TYPE

Enumerator
NoFlush 
Flush 
FlushAndInvalidate 
FlushWithoutPurge 

Definition at line 1051 of file fatprocs.h.

1051 {
1052
1053 NoFlush = 0,
1054 Flush,
1057
enum _FAT_FLUSH_TYPE FAT_FLUSH_TYPE
@ FlushWithoutPurge
Definition: fatprocs.h:1056
@ Flush
Definition: fatprocs.h:1054
@ FlushAndInvalidate
Definition: fatprocs.h:1055
@ NoFlush
Definition: fatprocs.h:1053

◆ _FAT_VOLUME_STATE

Enumerator
VolumeClean 
VolumeDirty 
VolumeDirtyWithSurfaceTest 

Definition at line 1953 of file fatprocs.h.

1953 {
@ VolumeClean
Definition: fatprocs.h:1954
@ VolumeDirty
Definition: fatprocs.h:1955
@ VolumeDirtyWithSurfaceTest
Definition: fatprocs.h:1956
enum _FAT_VOLUME_STATE * PFAT_VOLUME_STATE
enum _FAT_VOLUME_STATE FAT_VOLUME_STATE

◆ _TYPE_OF_OPEN

Enumerator
UnopenedFileObject 
StreamFileOpen 
UserVolumeOpen 
UserDirectoryOpen 
UserFileOpen 
BeyondValidType 
UnopenedFileObject 
UserFileOpen 
UserDirectoryOpen 
UserVolumeOpen 
VirtualVolumeFile 
DirectoryFile 
EaFile 

Definition at line 1039 of file fatprocs.h.

1039 {
1040
1047 EaFile,
1048} TYPE_OF_OPEN;
@ UnopenedFileObject
Definition: fatprocs.h:1041
@ UserDirectoryOpen
Definition: fatprocs.h:1043
@ DirectoryFile
Definition: fatprocs.h:1046
@ UserFileOpen
Definition: fatprocs.h:1042
@ UserVolumeOpen
Definition: fatprocs.h:1044
@ VirtualVolumeFile
Definition: fatprocs.h:1045
@ EaFile
Definition: fatprocs.h:1047
enum _TYPE_OF_OPEN TYPE_OF_OPEN

Function Documentation

◆ _Acquires_exclusive_lock_()

_Acquires_exclusive_lock_ ( Vcb->  Resource)

◆ _Acquires_shared_lock_()

_Acquires_shared_lock_ ( Vcb->  Resource)

◆ _Function_class_() [1/28]

_Function_class_ ( FAST_IO_ACQUIRE_FOR_CCFLUSH  )

◆ _Function_class_() [2/28]

_Function_class_ ( FAST_IO_CHECK_IF_POSSIBLE  )

◆ _Function_class_() [3/28]

_Function_class_ ( FAST_IO_LOCK  )

◆ _Function_class_() [4/28]

_Function_class_ ( FAST_IO_QUERY_BASIC_INFO  )

◆ _Function_class_() [5/28]

_Function_class_ ( FAST_IO_QUERY_NETWORK_OPEN_INFO  )

◆ _Function_class_() [6/28]

_Function_class_ ( FAST_IO_QUERY_STANDARD_INFO  )

◆ _Function_class_() [7/28]

_Function_class_ ( FAST_IO_RELEASE_FOR_CCFLUSH  )

◆ _Function_class_() [8/28]

_Function_class_ ( FAST_IO_UNLOCK_ALL  )

◆ _Function_class_() [9/28]

_Function_class_ ( FAST_IO_UNLOCK_ALL_BY_KEY  )

◆ _Function_class_() [10/28]

_Function_class_ ( FAST_IO_UNLOCK_SINGLE  )

◆ _Function_class_() [11/28]

_Function_class_ ( IRP_MJ_CLEANUP  )

◆ _Function_class_() [12/28]

_Function_class_ ( IRP_MJ_CLOSE  )

◆ _Function_class_() [13/28]

_Function_class_ ( IRP_MJ_CREATE  )

◆ _Function_class_() [14/28]

_Function_class_ ( IRP_MJ_DEVICE_CONTROL  )

◆ _Function_class_() [15/28]

_Function_class_ ( IRP_MJ_DIRECTORY_CONTROL  )

◆ _Function_class_() [16/28]

_Function_class_ ( IRP_MJ_FILE_SYSTEM_CONTROL  )

◆ _Function_class_() [17/28]

_Function_class_ ( IRP_MJ_FLUSH_BUFFERS  )

◆ _Function_class_() [18/28]

_Function_class_ ( IRP_MJ_LOCK_CONTROL  )

◆ _Function_class_() [19/28]

_Function_class_ ( IRP_MJ_PNP  )

◆ _Function_class_() [20/28]

_Function_class_ ( IRP_MJ_QUERY_EA  )

◆ _Function_class_() [21/28]

_Function_class_ ( IRP_MJ_QUERY_INFORMATION  )

◆ _Function_class_() [22/28]

_Function_class_ ( IRP_MJ_QUERY_VOLUME_INFORMATION  )

◆ _Function_class_() [23/28]

_Function_class_ ( IRP_MJ_READ  )

◆ _Function_class_() [24/28]

_Function_class_ ( IRP_MJ_SET_EA  )

◆ _Function_class_() [25/28]

_Function_class_ ( IRP_MJ_SET_INFORMATION  )

◆ _Function_class_() [26/28]

_Function_class_ ( IRP_MJ_SET_VOLUME_INFORMATION  )

◆ _Function_class_() [27/28]

_Function_class_ ( IRP_MJ_SHUTDOWN  )

◆ _Function_class_() [28/28]

_Function_class_ ( IRP_MJ_WRITE  )

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

◆ _Success_()

_Success_ ( return = FALSE)

Definition at line 1028 of file fsctrl.c.

3189{
3191
3192 PVPB Vpb = Vcb->Vpb;
3193 PVPB OldVpb;
3194
3195 BOOLEAN Remount = FALSE;
3196
3197 PAGED_CODE();
3198
3199 UNREFERENCED_PARAMETER( IrpContext );
3200
3201 //
3202 // Check whether we are looking for a device only Mvcb.
3203 //
3204
3205 for (Link = CdData.VcbQueue.Flink;
3206 Link != &CdData.VcbQueue;
3207 Link = Link->Flink) {
3208
3209 *OldVcb = CONTAINING_RECORD( Link, VCB, VcbLinks );
3210
3211 //
3212 // Skip ourselves.
3213 //
3214
3215 if (Vcb == *OldVcb) { continue; }
3216
3217 //
3218 // Look at the Vpb and state of the previous Vcb.
3219 //
3220
3221 OldVpb = (*OldVcb)->Vpb;
3222
3223 if ((OldVpb != Vpb) &&
3224 (OldVpb->RealDevice == Vpb->RealDevice) &&
3225 ((*OldVcb)->VcbCondition == VcbNotMounted)) {
3226
3227 //
3228 // If the current disk is a raw disk then it can match a previous music or
3229 // raw disk.
3230 //
3231
3232 if (FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK)) {
3233
3234 if (FlagOn( (*OldVcb)->VcbState, VCB_STATE_AUDIO_DISK )) {
3235
3236 //
3237 // If we have both TOC then fail the remount if the lengths
3238 // are different or they don't match.
3239 //
3240
3241 if ((Vcb->TocLength != (*OldVcb)->TocLength) ||
3242 ((Vcb->TocLength != 0) &&
3243 !RtlEqualMemory( Vcb->CdromToc,
3244 (*OldVcb)->CdromToc,
3245 Vcb->TocLength ))) {
3246
3247 continue;
3248 }
3249
3250 Remount = TRUE;
3251 break;
3252 }
3253
3254 //
3255 // The current disk is not a raw disk. Go ahead and compare
3256 // serial numbers, volume label and TOC.
3257 //
3258
3259 }
3260 else if ((OldVpb->SerialNumber == Vpb->SerialNumber) &&
3261 (Vcb->TocLength == (*OldVcb)->TocLength) &&
3262 ((Vcb->TocLength == 0) || RtlEqualMemory( Vcb->CdromToc,
3263 (*OldVcb)->CdromToc,
3264 Vcb->TocLength )) &&
3265 (Vpb->VolumeLabelLength == OldVpb->VolumeLabelLength) &&
3266 (RtlEqualMemory( OldVpb->VolumeLabel,
3267 Vpb->VolumeLabel,
3268 Vpb->VolumeLabelLength ))) {
3269 //
3270 // Remember the old Vcb. Then set the return value to
3271 // TRUE and break.
3272 //
3273
3274 Remount = TRUE;
3275 break;
3276 }
3277 }
3278 }
3279
3280 return Remount;
3281}
#define PAGED_CODE()
unsigned char BOOLEAN
CD_DATA CdData
Definition: cddata.c:42
#define VCB_STATE_AUDIO_DISK
Definition: cdstruc.h:712
@ VcbNotMounted
Definition: cdstruc.h:490
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define Vcb
Definition: cdprocs.h:1415
LIST_ENTRY VcbQueue
Definition: cdstruc.h:334
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: iotypes.h:189
WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH/sizeof(WCHAR)]
Definition: iotypes.h:198
USHORT VolumeLabelLength
Definition: iotypes.h:193
ULONG SerialNumber
Definition: iotypes.h:196
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:195
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static int Link(const char **args)
Definition: vfdcmd.c:2414

◆ Fat8dot3ToString()

VOID Fat8dot3ToString ( _In_ PIRP_CONTEXT  IrpContext,
_In_ PDIRENT  Dirent,
_In_ BOOLEAN  RestoreCase,
_Out_ POEM_STRING  OutputString 
)

Definition at line 179 of file namesup.c.

208{
210 ULONG BaseLength, ExtensionLength;
211
212 PAGED_CODE();
213
214 DebugTrace(+1, Dbg, "Fat8dot3ToString\n", 0);
215
216 //
217 // First, find the length of the base component.
218 //
219
220 for (BaseLength = 8; BaseLength > 0; BaseLength -= 1) {
221
222 if (Dirent->FileName[BaseLength - 1] != UCHAR_SP) {
223
224 break;
225 }
226 }
227
228 //
229 // Now find the length of the extension.
230 //
231
232 for (ExtensionLength = 3; ExtensionLength > 0; ExtensionLength -= 1) {
233
234 if (Dirent->FileName[8 + ExtensionLength - 1] != UCHAR_SP) {
235
236 break;
237 }
238 }
239
240 //
241 // If there was a base part, copy it and check the case. Don't forget
242 // if the first character needs to be changed from 0x05 to 0xe5.
243 //
244
245 if (BaseLength != 0) {
246
247 RtlCopyMemory( OutputString->Buffer, Dirent->FileName, BaseLength );
248
249 if (OutputString->Buffer[0] == FAT_DIRENT_REALLY_0E5) {
250
251 OutputString->Buffer[0] = 0xe5;
252 }
253
254 //
255 // Now if we are to restore case, look for A-Z
256 //
257
258 if (FatData.ChicagoMode &&
259 RestoreCase &&
261
262 for (StringIndex = 0; StringIndex < BaseLength; StringIndex += 1) {
263
264 //
265 // Depending on whether the media was built in a system that was
266 // running with "code page invariance" (see FatEvaluateNameCase),
267 // there could be double-byte OEM characters lying in wait here.
268 // Gotta skip them.
269 //
270
271 if (FsRtlIsLeadDbcsCharacter(OutputString->Buffer[StringIndex])) {
272
273 StringIndex += 1;
274 continue;
275 }
276
277 if ((OutputString->Buffer[StringIndex] >= 'A') &&
278 (OutputString->Buffer[StringIndex] <= 'Z')) {
279
280 OutputString->Buffer[StringIndex] += 'a' - 'A';
281 }
282 }
283 }
284 }
285
286 //
287 // If there was an extension, copy that over. Else we now know the
288 // size of the string.
289 //
290
291 if (ExtensionLength != 0) {
292
293 PUCHAR o, d;
294
295 //
296 // Now add the dot
297 //
298
299 OutputString->Buffer[BaseLength++] = '.';
300
301 //
302 // Copy over the extension into the output buffer.
303 //
304
305 o = (PUCHAR)&OutputString->Buffer[BaseLength];
306 d = &Dirent->FileName[8];
307
308 switch (ExtensionLength) {
309 case 3:
310 *o++ = *d++;
311 case 2:
312 *o++ = *d++;
313 case 1:
314 *o++ = *d++;
315 }
316
317 //
318 // Set the output string length
319 //
320
321 OutputString->Length = (USHORT)(BaseLength + ExtensionLength);
322
323 //
324 // Now if we are to restore case, look for A-Z
325 //
326
327 if (FatData.ChicagoMode &&
328 RestoreCase &&
330
331 for (StringIndex = BaseLength;
332 StringIndex < OutputString->Length;
333 StringIndex++ ) {
334
335 //
336 // Depending on whether the media was built in a system that was
337 // running with "code page invariance" (see FatEvaluateNameCase),
338 // there could be double-byte OEM characters lying in wait here.
339 // Gotta skip them.
340 //
341
342 if (FsRtlIsLeadDbcsCharacter(OutputString->Buffer[StringIndex])) {
343
344 StringIndex += 1;
345 continue;
346 }
347
348 if ((OutputString->Buffer[StringIndex] >= 'A') &&
349 (OutputString->Buffer[StringIndex] <= 'Z')) {
350
351 OutputString->Buffer[StringIndex] += 'a' - 'A';
352 }
353 }
354 }
355
356 } else {
357
358 //
359 // Set the output string length
360 //
361
362 OutputString->Length = (USHORT)BaseLength;
363 }
364
365 //
366 // And return to our caller
367 //
368
369 DebugTrace(-1, Dbg, "Fat8dot3ToString, OutputString = \"%Z\" -> VOID\n", OutputString);
370
371 UNREFERENCED_PARAMETER( IrpContext );
372
373 return;
374}
PAGED_CODE()
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
switch(r->id)
Definition: btrfs.c:3046
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
Definition: init.c:428
#define FAT_DIRENT_NT_BYTE_8_LOWER_CASE
Definition: fat.h:361
#define FAT_DIRENT_REALLY_0E5
Definition: fat.h:335
#define FAT_DIRENT_NT_BYTE_3_LOWER_CASE
Definition: fat.h:362
#define UCHAR_SP
Definition: nodetype.h:143
#define Dbg
Definition: namesup.c:18
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define d
Definition: ke_i.h:81
BOOLEAN ChicagoMode
Definition: fatstruc.h:87
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR StringIndex
Definition: wdfusb.h:1080

Referenced by _Requires_lock_held_(), and FatConstructNamesInFcb().

◆ FatAcquireSharedFcbWaitForEx()

_Acquires_shared_lock_ Fcb FINISHED FatAcquireSharedFcbWaitForEx ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb 
)

Referenced by _Requires_lock_held_().

◆ FatAcquireVolumeForClose()

BOOLEAN FatAcquireVolumeForClose ( IN PVOID  Vcb,
IN BOOLEAN  Wait 
)

◆ FatAddMcbEntry()

BOOLEAN FatAddMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN VBO  Vbo,
IN LBO  Lbo,
IN ULONG  SectorCount 
)

Definition at line 364 of file fsctrl.c.

372{
374#if DBG
375 VBO SparseVbo;
376 LONGLONG SparseByteCount;
377#endif
378
379 PAGED_CODE();
380
381 if (SectorCount) {
382
383 //
384 // Round up sectors, but be careful as SectorCount approaches 4Gb.
385 // Note that for x>0, (x+m-1)/m = ((x-1)/m)+(m/m) = ((x-1)/m)+1
386 //
387
388 SectorCount--;
390 SectorCount++;
391 }
392
395
396 NT_ASSERT( SectorCount != 0 );
397
398 if (Mcb != &Vcb->DirtyFatMcb) {
399 NT_ASSERT( FatNonSparseMcb( Vcb, Mcb, &SparseVbo, &SparseByteCount ) ||
400 ((SparseVbo == Vbo) && (SparseByteCount == SectorCount )) );
401 }
402
404 ((LONGLONG) Vbo),
405 ((LONGLONG) Lbo),
406 ((LONGLONG) SectorCount) );
407
408 if (Mcb != &Vcb->DirtyFatMcb) {
409 NT_ASSERT( FatNonSparseMcb( Vcb, Mcb, &SparseVbo, &SparseByteCount ) ||
410 ((SparseVbo == Vbo) && (SparseByteCount == SectorCount )) );
411 }
412
413 return Result;
414}
ULONG32 VBO
Definition: fat.h:38
#define MCB_SCALE_LOG2
IN PFCB IN VBO OUT PLBO Lbo
Definition: fatprocs.h:308
IN PFCB IN VBO Vbo
Definition: fatprocs.h:307
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:348
BOOLEAN NTAPI FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount)
Definition: largemcb.c:288
ULONG SectorCount
Definition: part_xbox.c:31
int64_t LONGLONG
Definition: typedefs.h:68
_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
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by _Requires_lock_held_(), FatComputeMoveFileSplicePoints(), FatExamineFatEntries(), and FatSetFatRun().

◆ FatAddToWorkque()

VOID FatAddToWorkque ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 280 of file workque.c.

304{
305 KIRQL SavedIrql;
307
309
310 //
311 // Check if this request has an associated file object, and thus volume
312 // device object.
313 //
314
315 if ( IrpSp->FileObject != NULL ) {
316
318
321 DeviceObject );
322
323 //
324 // Check to see if this request should be sent to the overflow
325 // queue. If not, then send it off to an exworker thread.
326 //
327
328 KeAcquireSpinLock( &Vdo->OverflowQueueSpinLock, &SavedIrql );
329
331
332 //
333 // We cannot currently respond to this IRP so we'll just enqueue it
334 // to the overflow queue on the volume.
335 //
336
338 &IrpContext->WorkQueueItem.List );
339
340 Vdo->OverflowQueueCount += 1;
341
342 KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql );
343
344 return;
345
346 } else {
347
348 //
349 // We are going to send this Irp to an ex worker thread so up
350 // the count.
351 //
352
353 Vdo->PostedRequestCount += 1;
354
355 KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql );
356 }
357 }
358
359 //
360 // Send it off.....
361 //
362
363 ExInitializeWorkItem( &IrpContext->WorkQueueItem,
365 IrpContext );
366
367#ifdef _MSC_VER
368#pragma prefast( suppress:28159, "prefast indicates this is an obsolete API but it is ok for fastfat to keep using it." )
369#endif
370 ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue );
371
372 return;
373}
_In_ PIRP Irp
Definition: csq.h:116
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define FSP_PER_DEVICE_THRESHOLD
Definition: workque.c:24
WORKER_THREAD_ROUTINE FatFspDispatch
Definition: fatprocs.h:2380
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
__volatile LONG PostedRequestCount
Definition: cdstruc.h:739
KSPIN_LOCK OverflowQueueSpinLock
Definition: cdstruc.h:760
LIST_ENTRY OverflowQueue
Definition: cdstruc.h:754
ULONG OverflowQueueCount
Definition: cdstruc.h:746
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ CriticalWorkQueue
Definition: extypes.h:189
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793

Referenced by _Requires_lock_held_(), FatFsdPostRequest(), and FatOplockComplete().

◆ FatAllocateCloseContext()

PCLOSE_CONTEXT FatAllocateCloseContext ( IN PVCB  Vcb)

◆ FatAppendPackedEa()

VOID FatAppendPackedEa ( IN PIRP_CONTEXT  IrpContext,
IN OUT PEA_SET_HEADER EaSetHeader,
IN OUT PULONG  PackedEasLength,
IN OUT PULONG  AllocationLength,
IN PFILE_FULL_EA_INFORMATION  FullEa,
IN ULONG  BytesPerCluster 
)

Definition at line 2967 of file easup.c.

3010{
3011 ULONG PackedEaSize;
3012 PPACKED_EA ThisPackedEa;
3013 OEM_STRING EaName;
3014
3015 PAGED_CODE();
3016
3017 DebugTrace(+1, Dbg, "FatAppendPackedEa...\n", 0);
3018
3019 //
3020 // As a quick check see if the computed packed ea size plus the
3021 // current packed ea list size will overflow the buffer. Full Ea and
3022 // packed Ea only differ by 4 in their size
3023 //
3024
3025 PackedEaSize = SizeOfFullEa( FullEa ) - 4;
3026
3027 if ( PackedEaSize + *PackedEasLength > *AllocationLength ) {
3028
3029 //
3030 // We will overflow our current work buffer so allocate a larger
3031 // one and copy over the current buffer
3032 //
3033
3034 PVOID Temp;
3035 ULONG NewAllocationSize;
3036 ULONG OldAllocationSize;
3037
3038 DebugTrace(0, Dbg, "Allocate a new ea list buffer\n", 0);
3039
3040 //
3041 // Compute a new size and allocate space. Always increase the
3042 // allocation in cluster increments.
3043 //
3044
3045 NewAllocationSize = (SIZE_OF_EA_SET_HEADER
3046 + PackedEaSize
3047 + *PackedEasLength
3048 + BytesPerCluster - 1)
3049 & ~(BytesPerCluster - 1);
3050
3052 NewAllocationSize,
3054
3055 //
3056 // Move over the existing ea list, and deallocate the old one
3057 //
3058
3059 RtlCopyMemory( Temp,
3060 *EaSetHeader,
3061 OldAllocationSize = *AllocationLength
3063
3064 ExFreePool( *EaSetHeader );
3065
3066 //
3067 // Set up so we will use the new packed ea list
3068 //
3069
3070 *EaSetHeader = Temp;
3071
3072 //
3073 // Zero out the added memory.
3074 //
3075
3076 RtlZeroMemory( &(*EaSetHeader)->PackedEas[*AllocationLength],
3077 NewAllocationSize - OldAllocationSize );
3078
3079 *AllocationLength = NewAllocationSize - SIZE_OF_EA_SET_HEADER;
3080 }
3081
3082 //
3083 // Determine if we need to increment our need ea changes count
3084 //
3085
3086 if ( FlagOn(FullEa->Flags, FILE_NEED_EA )) {
3087
3088 //
3089 // The NeedEaCount field is long aligned so we will write
3090 // directly to it.
3091 //
3092
3093 (*EaSetHeader)->NeedEaCount++;
3094 }
3095
3096 //
3097 // Now copy over the ea, full ea's and packed ea are identical except
3098 // that full ea also have a next ea offset that we skip over
3099 //
3100 // Before:
3101 // UsedSize Allocated
3102 // | |
3103 // V V
3104 // +xxxxxxxx+-----------------------------+
3105 //
3106 // After:
3107 // UsedSize Allocated
3108 // | |
3109 // V V
3110 // +xxxxxxxx+yyyyyyyyyyyyyyyy+------------+
3111 //
3112
3113 ThisPackedEa = (PPACKED_EA) (RtlOffsetToPointer( (*EaSetHeader)->PackedEas,
3114 *PackedEasLength ));
3115
3116 RtlCopyMemory( ThisPackedEa,
3117 (PUCHAR) FullEa + 4,
3118 PackedEaSize );
3119
3120 //
3121 // Now convert the name to uppercase.
3122 //
3123
3124 EaName.MaximumLength = EaName.Length = FullEa->EaNameLength;
3125 EaName.Buffer = ThisPackedEa->EaName;
3126
3127 FatUpcaseEaName( IrpContext, &EaName, &EaName );
3128
3129 //
3130 // Increment the used size in the packed ea list structure
3131 //
3132
3133 *PackedEasLength += PackedEaSize;
3134
3135 //
3136 // And return to our caller
3137 //
3138
3139 DebugTrace(-1, Dbg, "FatAppendPackedEa -> VOID\n", 0);
3140
3141 UNREFERENCED_PARAMETER( IrpContext );
3142
3143 return;
3144}
PACKED_EA * PPACKED_EA
Definition: fat.h:700
#define SIZE_OF_EA_SET_HEADER
Definition: fat.h:674
#define TAG_EA_SET_HEADER
Definition: nodetype.h:161
#define Dbg
Definition: easup.c:22
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define FatUpcaseEaName(IRPCONTEXT, NAME, UPCASEDNAME)
Definition: fatprocs.h:868
#define SizeOfFullEa(EA)
Definition: fatprocs.h:1030
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
CHAR EaName[1]
Definition: fat.h:698
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
STRING OEM_STRING
Definition: umtypes.h:203
#define FILE_NEED_EA

Referenced by FatCommonSetEa().

◆ FatBufferUserBuffer()

PVOID FatBufferUserBuffer ( IN PIRP_CONTEXT  IrpContext,
IN OUT PIRP  Irp,
IN ULONG  BufferLength 
)

Definition at line 3411 of file deviosup.c.

3438{
3439 PUCHAR UserBuffer;
3440
3441 UNREFERENCED_PARAMETER( IrpContext );
3442
3443 PAGED_CODE();
3444
3445 //
3446 // Handle the no buffer case.
3447 //
3448
3449 if (BufferLength == 0) {
3450
3451 return NULL;
3452 }
3453
3454 //
3455 // If there is no system buffer we must have been supplied an Mdl
3456 // describing the users input buffer, which we will now snapshot.
3457 //
3458
3459 if (Irp->AssociatedIrp.SystemBuffer == NULL) {
3460
3461 UserBuffer = FatMapUserBuffer( IrpContext, Irp );
3462
3463 Irp->AssociatedIrp.SystemBuffer = FsRtlAllocatePoolWithQuotaTag( NonPagedPoolNx,
3466
3467 //
3468 // Set the flags so that the completion code knows to deallocate the
3469 // buffer.
3470 //
3471
3473
3474 _SEH2_TRY {
3475
3476 RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer,
3477 UserBuffer,
3478 BufferLength );
3479
3481
3483
3485 FatRaiseStatus( IrpContext,
3487 } _SEH2_END;
3488 }
3489
3490 return Irp->AssociatedIrp.SystemBuffer;
3491}
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_IO_USER_BUFFER
Definition: nodetype.h:184
PVOID FatMapUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
Definition: deviosup.c:3357
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2977
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
PVOID NTAPI FsRtlAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:189
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define IRP_DEALLOCATE_BUFFER
#define IRP_BUFFERED_IO

Referenced by FatCommonSetEa().

◆ FatBuildZeroMdl()

PMDL FatBuildZeroMdl ( __in PIRP_CONTEXT  IrpContext,
__in ULONG  Length 
)

Definition at line 3734 of file deviosup.c.

3757{
3758 PMDL ZeroMdl;
3759 ULONG SavedByteCount;
3761 ULONG i;
3762
3763 UNREFERENCED_PARAMETER( IrpContext );
3764
3765 //
3766 // Spin down trying to get an MDL which can describe our operation.
3767 //
3768
3769 while (TRUE) {
3770
3772
3773 //
3774 // Throttle ourselves to what we've physically allocated. Note that
3775 // we could have started with an odd multiple of this number. If we
3776 // tried for exactly that size and failed, we're toast.
3777 //
3778
3779 if (ZeroMdl || (Length <= PAGE_SIZE)) {
3780
3781 break;
3782 }
3783
3784 //
3785 // Fallback by half and round down to a page multiple.
3786 //
3787
3788 ASSERT( IrpContext->Vcb->Bpb.BytesPerSector <= PAGE_SIZE );
3790 if (Length < PAGE_SIZE) {
3791 Length = PAGE_SIZE;
3792 }
3793 }
3794
3795 if (ZeroMdl == NULL) {
3796 return NULL;
3797 }
3798
3799 //
3800 // If we have throttled all the way down, stop and just build a
3801 // simple MDL describing our previous allocation.
3802 //
3803
3804 if (Length == PAGE_SIZE) {
3805
3806 MmBuildMdlForNonPagedPool( ZeroMdl );
3807 return ZeroMdl;
3808 }
3809
3810 //
3811 // Now we will temporarily lock the allocated pages
3812 // only, and then replicate the page frame numbers through
3813 // the entire Mdl to keep writing the same pages of zeros.
3814 //
3815 // It would be nice if Mm exported a way for us to not have
3816 // to pull the Mdl apart and rebuild it ourselves, but this
3817 // is so bizarre a purpose as to be tolerable.
3818 //
3819
3820 SavedByteCount = ZeroMdl->ByteCount;
3821 ZeroMdl->ByteCount = PAGE_SIZE;
3822 MmBuildMdlForNonPagedPool( ZeroMdl );
3823
3824 ZeroMdl->MdlFlags &= ~MDL_SOURCE_IS_NONPAGED_POOL;
3825 ZeroMdl->MdlFlags |= MDL_PAGES_LOCKED;
3826 ZeroMdl->MappedSystemVa = NULL;
3827 ZeroMdl->StartVa = NULL;
3828 ZeroMdl->ByteCount = SavedByteCount;
3829 Page = MmGetMdlPfnArray( ZeroMdl );
3830 for (i = 1; i < (ADDRESS_AND_SIZE_TO_SPAN_PAGES( 0, SavedByteCount )); i++) {
3831 *(Page + i) = *(Page);
3832 }
3833
3834
3835 return ZeroMdl;
3836}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define BlockAlignTruncate(P, V)
Definition: fatprocs.h:3104
#define IoAllocateMdl
Definition: fxmdl.h:88
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
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
#define ASSERT(a)
Definition: mode.c:44
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
ULONG * PPFN_NUMBER
Definition: ke.h:9
PVOID ZeroPage
Definition: fatstruc.h:163
#define MmGetMdlPfnArray(_Mdl)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19

◆ FatCheckDirtyBit()

VOID FatCheckDirtyBit ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 1185 of file verfysup.c.

1207{
1208 BOOLEAN Dirty;
1209
1211 PBCB BootSectorBcb;
1212
1213 UNICODE_STRING VolumeLabel;
1214
1215 PAGED_CODE();
1216
1217 //
1218 // Look in the boot sector
1219 //
1220
1221 FatReadVolumeFile( IrpContext,
1222 Vcb,
1223 0,
1224 sizeof(PACKED_BOOT_SECTOR),
1225 &BootSectorBcb,
1226 (PVOID *)&BootSector );
1227
1228 _SEH2_TRY {
1229
1230 //
1231 // Check if the magic bit is set
1232 //
1233
1234 if (IsBpbFat32(&BootSector->PackedBpb)) {
1235 Dirty = BooleanFlagOn( ((PPACKED_BOOT_SECTOR_EX)BootSector)->CurrentHead,
1237 } else {
1238 Dirty = BooleanFlagOn( BootSector->CurrentHead, FAT_BOOT_SECTOR_DIRTY );
1239 }
1240
1241 //
1242 // Setup the VolumeLabel string
1243 //
1244
1245 VolumeLabel.Length = Vcb->Vpb->VolumeLabelLength;
1247 VolumeLabel.Buffer = &Vcb->Vpb->VolumeLabel[0];
1248
1249 if ( Dirty ) {
1250
1251 //
1252 // Do not trigger the mounted dirty bit if this is a verify
1253 // and the volume is a boot or paging device. We know that
1254 // a boot or paging device cannot leave the system, and thus
1255 // that on its mount we will have figured this out correctly.
1256 //
1257 // This logic is a reasonable change. Why?
1258 // 'cause setup cracked a non-exclusive DASD handle near the
1259 // end of setup, wrote some data, closed the handle and we
1260 // set the verify bit ... came back around and saw that other
1261 // arbitrary activity had left the volume in a temporarily dirty
1262 // state.
1263 //
1264 // Of course, the real problem is that we don't have a journal.
1265 //
1266
1267 if (!(IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1268 IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME &&
1270
1273 "FASTFAT: WARNING! Mounting Dirty Volume %Z\n",
1274 &VolumeLabel));
1275
1277 }
1278
1279 } else {
1280
1281 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
1282
1285 "FASTFAT: Volume %Z has been cleaned.\n",
1286 &VolumeLabel));
1287
1289
1290 } else {
1291
1292 (VOID)FsRtlBalanceReads( Vcb->TargetDeviceObject );
1293 }
1294 }
1295
1296 } _SEH2_FINALLY {
1297
1298 FatUnpinBcb( IrpContext, BootSectorBcb );
1299 } _SEH2_END;
1300}
@ DPFLTR_FASTFAT_ID
Definition: dpfilter.h:61
#define IsBpbFat32(bpb)
Definition: fat.h:101
#define FAT_BOOT_SECTOR_DIRTY
Definition: fat.h:213
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
VOID FatReadVolumeFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb, OUT PVOID *Buffer)
Definition: cachesup.c:102
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
#define VCB_STATE_FLAG_BOOT_OR_PAGING_FILE
Definition: fatstruc.h:567
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:562
NTSTATUS NTAPI FsRtlBalanceReads(PDEVICE_OBJECT TargetDevice)
Definition: faulttol.c:35
#define _SEH2_FINALLY
Definition: filesup.c:21
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define MAXIMUM_VOLUME_LABEL_LENGTH
Definition: iotypes.h:177
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114

◆ FatCheckFileAccess()

BOOLEAN FatCheckFileAccess ( PIRP_CONTEXT  IrpContext,
IN UCHAR  DirentAttributes,
IN PACCESS_MASK  DesiredAccess 
)

Definition at line 39 of file acchksup.c.

64{
66
67 DebugTrace(+1, Dbg, "FatCheckFileAccess\n", 0);
68 DebugTrace( 0, Dbg, "DirentAttributes = %8lx\n", DirentAttributes);
69 DebugTrace( 0, Dbg, "DesiredAccess = %8lx\n", *DesiredAccess);
70
71 PAGED_CODE();
72
73 //
74 // This procedures is programmed like a string of filters each
75 // filter checks to see if some access is allowed, if it is not allowed
76 // the filter return FALSE to the user without further checks otherwise
77 // it moves on to the next filter. The filter check is to check for
78 // desired access flags that are not allowed for a particular dirent
79 //
80
81 Result = TRUE;
82
83 _SEH2_TRY {
84
85 //
86 // Check for Volume ID or Device Dirents, these are not allowed user
87 // access at all
88 //
89
90 if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_VOLUME_ID) ||
91 FlagOn(DirentAttributes, FAT_DIRENT_ATTR_DEVICE)) {
92
93 DebugTrace(0, Dbg, "Cannot access volume id or device\n", 0);
94
96 }
97
98 //
99 // Check the desired access for the object - we only blackball that
100 // we do not understand. The model of filesystems using ACLs is that
101 // they do not type the ACL to the object the ACL is on. Permissions
102 // are not checked for consistency vs. the object type - dir/file.
103 //
104
105 if (FlagOn(*DesiredAccess, ~(DELETE |
108 WRITE_DAC |
120 MAXIMUM_ALLOWED))) {
121
122 DebugTrace(0, Dbg, "Cannot open object\n", 0);
123
125 }
126
127 //
128 // Check for a read-only Dirent
129 //
130
131 if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_READ_ONLY)) {
132
133 //
134 // Check the desired access for a read-only dirent. AccessMask will contain
135 // the flags we're going to allow.
136 //
137
143
144 //
145 // If this is a subdirectory also allow add file/directory and delete.
146 //
147
148 if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_DIRECTORY)) {
149
151 }
152
154
155 DebugTrace(0, Dbg, "Cannot open readonly\n", 0);
156
158 }
159 }
160
161 try_exit: NOTHING;
162 } _SEH2_FINALLY {
163
165
166 DebugTrace(-1, Dbg, "FatCheckFileAccess -> %08lx\n", Result);
167 } _SEH2_END;
168
169 UNREFERENCED_PARAMETER( IrpContext );
170
171 return Result;
172}
BOOLEAN FatCheckFileAccess(PIRP_CONTEXT IrpContext, IN UCHAR DirentAttributes, IN PACCESS_MASK DesiredAccess)
Definition: acchksup.c:39
#define Dbg
Definition: acchksup.c:22
#define try_return(S)
Definition: cdprocs.h:2179
#define FAT_DIRENT_ATTR_READ_ONLY
Definition: fat.h:368
#define FAT_DIRENT_ATTR_VOLUME_ID
Definition: fat.h:371
#define FAT_DIRENT_ATTR_DIRECTORY
Definition: fat.h:372
#define FAT_DIRENT_ATTR_DEVICE
Definition: fat.h:374
#define DebugUnwind(X)
Definition: fatdata.h:315
#define NOTHING
Definition: input_list.c:10
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define WRITE_DAC
Definition: nt_native.h:59
#define FILE_READ_DATA
Definition: nt_native.h:628
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_DELETE_CHILD
Definition: nt_native.h:645
#define FILE_READ_EA
Definition: nt_native.h:638
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define WRITE_OWNER
Definition: nt_native.h:60
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define FILE_WRITE_EA
Definition: nt_native.h:640
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658

Referenced by FatCheckFileAccess().

◆ FatCheckManageVolumeAccess()

BOOLEAN FatCheckManageVolumeAccess ( _In_ PIRP_CONTEXT  IrpContext,
_In_ PACCESS_STATE  AccessState,
_In_ KPROCESSOR_MODE  ProcessorMode 
)

Definition at line 176 of file acchksup.c.

201{
202 PRIVILEGE_SET PrivilegeSet;
203
204 PAGED_CODE();
205
206 PrivilegeSet.PrivilegeCount = 1;
208 PrivilegeSet.Privilege[0].Luid = RtlConvertLongToLuid( SE_MANAGE_VOLUME_PRIVILEGE );
209 PrivilegeSet.Privilege[0].Attributes = 0;
210
211 if (SePrivilegeCheck( &PrivilegeSet,
212 &AccessState->SubjectSecurityContext,
213 ProcessorMode )) {
214
215 return TRUE;
216 }
217
218 UNREFERENCED_PARAMETER( IrpContext );
219
220 return FALSE;
221}
#define SE_MANAGE_VOLUME_PRIVILEGE
Definition: security.c:682
BOOLEAN NTAPI SePrivilegeCheck(_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a set of privileges exist and match within a security subject context.
Definition: priv.c:698
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
$ULONG Control
Definition: setypes.h:87
$ULONG PrivilegeCount
Definition: setypes.h:86
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83

Referenced by FatExplicitDeviceAccessGranted().

◆ FatCleanVolumeDpc()

VOID NTAPI FatCleanVolumeDpc ( _In_ PKDPC  Dpc,
_In_opt_ PVOID  DeferredContext,
_In_opt_ PVOID  SystemArgument1,
_In_opt_ PVOID  SystemArgument2 
)

Definition at line 654 of file verfysup.c.

679{
680 PVCB Vcb;
682
686
688
689
690 //
691 // If there is still dirty data (highly unlikely), set the timer for a
692 // second in the future.
693 //
694
695 if (CcIsThereDirtyData(Vcb->Vpb)) {
696
697 LARGE_INTEGER TwoSecondsFromNow;
698
699 TwoSecondsFromNow.QuadPart = (LONG)-2*1000*1000*10;
700
701 KeSetTimer( &Vcb->CleanVolumeTimer,
702 TwoSecondsFromNow,
703 &Vcb->CleanVolumeDpc );
704
705 return;
706 }
707
708 //
709 // If we couldn't get pool, oh well....
710 //
711
712 Packet = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLEAN_AND_DIRTY_VOLUME_PACKET), ' taF');
713
714 if ( Packet ) {
715
716 Packet->Vcb = Vcb;
717 Packet->Irp = NULL;
718
719 //
720 // Clear the dirty flag now since we cannot synchronize after this point.
721 //
722
724
726
727#ifdef _MSC_VER
728#pragma prefast( suppress:28159, "prefast indicates this is an obsolete API, but it is ok for fastfat to keep using it" )
729#endif
731 }
732
733 return;
734}
struct _VCB * PVCB
Definition: fatstruc.h:557
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI FatDeferredCleanVolume(_In_ PVOID Parameter)
Definition: verfysup.c:499
#define VCB_STATE_FLAG_VOLUME_DIRTY
Definition: fatstruc.h:561
BOOLEAN NTAPI CcIsThereDirtyData(IN PVPB Vpb)
Definition: logsup.c:55
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
long LONG
Definition: pedump.c:60
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689

◆ FatCloseEaFile()

VOID FatCloseEaFile ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN BOOLEAN  FlushFirst 
)

Definition at line 1079 of file cachesup.c.

1106{
1107 PFILE_OBJECT EaFileObject = Vcb->VirtualEaFile;
1108
1109 PAGED_CODE();
1110
1111 DebugTrace(+1, Dbg, "FatCloseEaFile\n", 0);
1112 DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb);
1113
1114 NT_ASSERT( FatVcbAcquiredExclusive(IrpContext, Vcb) );
1115
1116 if (EaFileObject != NULL) {
1117
1118 EaFileObject = Vcb->VirtualEaFile;
1119
1120 if (FlushFirst) {
1121
1122 CcFlushCache( Vcb->VirtualEaFile->SectionObjectPointer, NULL, 0, NULL );
1123 }
1124
1125 Vcb->VirtualEaFile = NULL;
1126
1127 //
1128 // Empty the Mcb for the Ea file.
1129 //
1130
1131 FatRemoveMcbEntry( Vcb, &Vcb->EaFcb->Mcb, 0, 0xFFFFFFFF );
1132
1133 //
1134 // Uninitialize the cache for this file object and dereference it.
1135 //
1136
1137 FatSyncUninitializeCacheMap( IrpContext, EaFileObject );
1138
1139 ObDereferenceObject( EaFileObject );
1140 }
1141
1142 DebugTrace(-1, Dbg, "FatCloseEaFile -> %p\n", EaFileObject);
1143}
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
VOID FatSyncUninitializeCacheMap(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject)
Definition: cachesup.c:1812
#define Dbg
Definition: cachesup.c:29
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
Definition: fatprocs.h:1495
VOID FatRemoveMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN ULONG SectorCount)
Definition: fsctrl.c:599
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by FatTearDownVcb().

◆ FatCommonQueryEa()

NTSTATUS FatCommonQueryEa ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 250 of file ea.c.

272{
273#if 0
275
277
279 ULONG UserBufferLength;
280
281 PUCHAR UserEaList;
282 ULONG UserEaListLength;
283 ULONG UserEaIndex;
286 BOOLEAN IndexSpecified;
287
288 PVCB Vcb;
289 PCCB Ccb;
290
291 PFCB Fcb;
293 PBCB Bcb;
294
296 PBCB EaBcb;
297 BOOLEAN LockedEaFcb;
298
299 PEA_SET_HEADER EaSetHeader;
301
302 USHORT ExtendedAttributes;
303#endif
304
305 PAGED_CODE();
306
309
310#if 0
311 //
312 // Get the current Irp stack location
313 //
314
316
317 DebugTrace(+1, Dbg, "FatCommonQueryEa...\n", 0);
318 DebugTrace( 0, Dbg, " Wait = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
319 DebugTrace( 0, Dbg, " Irp = %p\n", Irp );
320 DebugTrace( 0, Dbg, " ->SystemBuffer = %p\n", Irp->AssociatedIrp.SystemBuffer );
321 DebugTrace( 0, Dbg, " ->Length = %08lx\n", IrpSp->Parameters.QueryEa.Length );
322 DebugTrace( 0, Dbg, " ->EaList = %08lx\n", IrpSp->Parameters.QueryEa.EaList );
323 DebugTrace( 0, Dbg, " ->EaListLength = %08lx\n", IrpSp->Parameters.QueryEa.EaListLength );
324 DebugTrace( 0, Dbg, " ->EaIndex = %08lx\n", IrpSp->Parameters.QueryEa.EaIndex );
325 DebugTrace( 0, Dbg, " ->RestartScan = %08lx\n", FlagOn(IrpSp->Flags, SL_RESTART_SCAN));
326 DebugTrace( 0, Dbg, " ->ReturnSingleEntry = %08lx\n", FlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY));
327 DebugTrace( 0, Dbg, " ->IndexSpecified = %08lx\n", FlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED));
328
329 Irp->IoStatus.Status = STATUS_SUCCESS;
330 Irp->IoStatus.Information = 0;
331
332 //
333 // Check that the file object is associated with either a user file
334 // or directory open. We don't allow Ea operations on the root
335 // directory.
336 //
337
338 {
339 TYPE_OF_OPEN OpenType;
340
341 if (((OpenType = FatDecodeFileObject( IrpSp->FileObject,
342 &Vcb,
343 &Fcb,
344 &Ccb )) != UserFileOpen
345 && OpenType != UserDirectoryOpen) ||
346
347 (NodeType( Fcb )) == FAT_NTC_ROOT_DCB) {
348
350
351 DebugTrace(-1, Dbg,
352 "FatCommonQueryEa -> %08lx\n",
354
356 }
357 }
358
359 //
360 // Fat32 does not support ea's.
361 //
362
363 if (FatIsFat32(Vcb)) {
364
366 DebugTrace(-1, Dbg,
367 "FatCommonQueryEa -> %08lx\n",
370 }
371
372 //
373 // Acquire shared access to the Fcb and enqueue the Irp if we didn't
374 // get access.
375 //
376
377 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
378
379 DebugTrace(0, Dbg, "FatCommonQueryEa: Thread can't wait\n", 0);
380
381 Status = FatFsdPostRequest( IrpContext, Irp );
382
383 DebugTrace(-1, Dbg, "FatCommonQueryEa -> %08lx\n", Status );
384
385 return Status;
386 }
387
388 FatAcquireSharedFcb( IrpContext, Fcb );
389
390 //
391 // Reference our input parameters to make things easier
392 //
393
394 UserBufferLength = IrpSp->Parameters.QueryEa.Length;
395 UserEaList = IrpSp->Parameters.QueryEa.EaList;
396 UserEaListLength = IrpSp->Parameters.QueryEa.EaListLength;
397 UserEaIndex = IrpSp->Parameters.QueryEa.EaIndex;
400 IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);
401
402 //
403 // Initialize our local values.
404 //
405
406 LockedEaFcb = FALSE;
407 Bcb = NULL;
408 EaBcb = NULL;
409
411
412 RtlZeroMemory( &EaSetRange, sizeof( EA_RANGE ));
413
414 try {
415
416 PPACKED_EA FirstPackedEa;
417 ULONG PackedEasLength;
418
419 Buffer = FatMapUserBuffer( IrpContext, Irp );
420
421 //
422 // We verify that the Fcb is still valid.
423 //
424
425 FatVerifyFcb( IrpContext, Fcb );
426
427 //
428 // We need to get the dirent for the Fcb to recover the Ea handle.
429 //
430
431 FatGetDirentFromFcbOrDcb( IrpContext, Fcb, &Dirent, &Bcb );
432
433 //
434 // Verify that the Ea file is in a consistant state. If the
435 // Ea modification count in the Fcb doesn't match that in
436 // the CCB, then the Ea file has been changed from under
437 // us. If we are not starting the search from the beginning
438 // of the Ea set, we return an error.
439 //
440
441 if (UserEaList == NULL
442 && Ccb->OffsetOfNextEaToReturn != 0
443 && !IndexSpecified
444 && !RestartScan
446
447 DebugTrace(0, Dbg,
448 "FatCommonQueryEa: Ea file in unknown state\n", 0);
449
451
453 }
454
455 //
456 // Show that the Ea's for this file are consistant for this
457 // file handle.
458 //
459
461
462 //
463 // If the handle value is 0, then the file has no Eas. We dummy up
464 // an ea list to use below.
465 //
466
467 ExtendedAttributes = Dirent->ExtendedAttributes;
468
469 FatUnpinBcb( IrpContext, Bcb );
470
471 if (ExtendedAttributes == 0) {
472
473 DebugTrace(0, Dbg,
474 "FatCommonQueryEa: Zero handle, no Ea's for this file\n", 0);
475
476 FirstPackedEa = (PPACKED_EA) NULL;
477
478 PackedEasLength = 0;
479
480 } else {
481
482 //
483 // We need to get the Ea file for this volume. If the
484 // operation doesn't complete due to blocking, then queue the
485 // Irp to the Fsp.
486 //
487
488 FatGetEaFile( IrpContext,
489 Vcb,
490 &EaDirent,
491 &EaBcb,
492 FALSE,
493 FALSE );
494
495 LockedEaFcb = TRUE;
496
497 //
498 // If the above operation completed and the Ea file did not exist,
499 // the disk has been corrupted. There is an existing Ea handle
500 // without any Ea data.
501 //
502
503 if (Vcb->VirtualEaFile == NULL) {
504
505 DebugTrace(0, Dbg,
506 "FatCommonQueryEa: No Ea file found when expected\n", 0);
507
509
511 }
512
513 //
514 // We need to try to get the Ea set for the desired file. If
515 // blocking is necessary then we'll post the request to the Fsp.
516 //
517
518 FatReadEaSet( IrpContext,
519 Vcb,
520 ExtendedAttributes,
522 TRUE,
523 &EaSetRange );
524
525 EaSetHeader = (PEA_SET_HEADER) EaSetRange.Data;
526
527 //
528 // Find the start and length of the Eas.
529 //
530
531 FirstPackedEa = (PPACKED_EA) EaSetHeader->PackedEas;
532
533 PackedEasLength = GetcbList( EaSetHeader ) - 4;
534 }
535
536 //
537 // Protect our access to the user buffer since IO dosn't do this
538 // for us in this path unless we had specified that our driver
539 // requires buffering for these large requests. We don't, so ...
540 //
541
542 try {
543
544 //
545 // Let's clear the output buffer.
546 //
547
548 RtlZeroMemory( Buffer, UserBufferLength );
549
550 //
551 // We now satisfy the user's request depending on whether he
552 // specified an Ea name list, an Ea index or restarting the
553 // search.
554 //
555
556 //
557 // The user has supplied a list of Ea names.
558 //
559
560 if (UserEaList != NULL) {
561
562 Irp->IoStatus = FatQueryEaUserEaList( IrpContext,
563 Ccb,
564 FirstPackedEa,
565 PackedEasLength,
566 Buffer,
567 UserBufferLength,
568 UserEaList,
569 UserEaListLength,
571
572 //
573 // The user supplied an index into the Ea list.
574 //
575
576 } else if (IndexSpecified) {
577
578 Irp->IoStatus = FatQueryEaIndexSpecified( IrpContext,
579 Ccb,
580 FirstPackedEa,
581 PackedEasLength,
582 Buffer,
583 UserBufferLength,
584 UserEaIndex,
586
587 //
588 // Else perform a simple scan, taking into account the restart
589 // flag and the position of the next Ea stored in the Ccb.
590 //
591
592 } else {
593
594 Irp->IoStatus = FatQueryEaSimpleScan( IrpContext,
595 Ccb,
596 FirstPackedEa,
597 PackedEasLength,
598 Buffer,
599 UserBufferLength,
602 ? 0
603 : Ccb->OffsetOfNextEaToReturn );
604 }
605
608
609 //
610 // We must have had a problem filling in the user's buffer, so fail.
611 //
612
613 Irp->IoStatus.Status = GetExceptionCode();
614 Irp->IoStatus.Information = 0;
615 }
616
617 Status = Irp->IoStatus.Status;
618
619 try_exit: NOTHING;
620 } finally {
621
623
624 //
625 // Release the Fcb for the file object, and the Ea Fcb if
626 // successfully locked.
627 //
628
629 FatReleaseFcb( IrpContext, Fcb );
630
631 if (LockedEaFcb) {
632
633 FatReleaseFcb( IrpContext, Vcb->EaFcb );
634 }
635
636 //
637 // Unpin the dirents for the Fcb, EaFcb and EaSetFcb if necessary.
638 //
639
640 FatUnpinBcb( IrpContext, Bcb );
641 FatUnpinBcb( IrpContext, EaBcb );
642
643 FatUnpinEaRange( IrpContext, &EaSetRange );
644
645 if (!AbnormalTermination()) {
646
647 FatCompleteRequest( IrpContext, Irp, Status );
648 }
649
650 DebugTrace(-1, Dbg, "FatCommonQueryEa -> %08lx\n", Status);
651 }
652
653 return Status;
654#endif
655}
NodeType
Definition: Node.h:6
#define except(x)
Definition: btrfs_drv.h:136
@ UserDirectoryOpen
Definition: cdprocs.h:576
@ UserFileOpen
Definition: cdprocs.h:577
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
enum _TYPE_OF_OPEN TYPE_OF_OPEN
IO_STATUS_BLOCK FatQueryEaIndexSpecified(IN PIRP_CONTEXT IrpContext, OUT PCCB Ccb, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, OUT PUCHAR UserBuffer, IN ULONG UserBufferLength, IN ULONG UserEaIndex, IN BOOLEAN ReturnSingleEntry)
NTSTATUS FatCommonQueryEa(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: ea.c:250
IO_STATUS_BLOCK FatQueryEaSimpleScan(IN PIRP_CONTEXT IrpContext, OUT PCCB Ccb, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, OUT PUCHAR UserBuffer, IN ULONG UserBufferLength, IN BOOLEAN ReturnSingleEntry, ULONG StartOffset)
IO_STATUS_BLOCK FatQueryEaUserEaList(IN PIRP_CONTEXT IrpContext, OUT PCCB Ccb, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, OUT PUCHAR UserBuffer, IN ULONG UserBufferLength, IN PUCHAR UserEaList, IN ULONG UserEaListLength, IN BOOLEAN ReturnSingleEntry)
#define Dbg
Definition: ea.c:23
EA_SET_HEADER * PEA_SET_HEADER
Definition: fat.h:672
#define GetcbList(EASET)
Definition: fat.h:678
VOID FatUnpinEaRange(IN PIRP_CONTEXT IrpContext, IN OUT PEA_RANGE EaRange)
Definition: easup.c:3782
VOID FatReadEaSet(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN USHORT EaHandle, IN POEM_STRING FileName, IN BOOLEAN ReturnEntireSet, OUT PEA_RANGE EaSetRange)
Definition: easup.c:1306
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:414
IN PVCB IN ULONG IN PBCB OUT PDIRENT OUT PUSHORT OUT PEA_RANGE EaSetRange
Definition: fatprocs.h:951
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
IN OUT PVCB OUT PDIRENT OUT PBCB * EaBcb
Definition: fatprocs.h:915
IN OUT PVCB OUT PDIRENT * EaDirent
Definition: fatprocs.h:914
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2299
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN ReturnSingleEntry
Definition: fltkernel.h:2295
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define STATUS_EA_CORRUPT_ERROR
Definition: ntstatus.h:319
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:318
#define STATUS_EAS_NOT_SUPPORTED
Definition: ntstatus.h:315
#define AbnormalTermination()
Definition: seh.h:28
#define GetExceptionCode()
Definition: seh.h:27
Definition: cdstruc.h:1067
UCHAR PackedEas[1]
Definition: fat.h:670
ULONG EaModificationCount
Definition: fatstruc.h:1107
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1115
union _FILE_NAME_NODE::@718 Name
OEM_STRING Oem
Definition: fatstruc.h:693
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1837
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
#define SL_RESTART_SCAN
Definition: iotypes.h:1835

Referenced by _Function_class_(), FatCommonQueryEa(), and FatFspDispatch().

◆ FatCommonSetEa()

NTSTATUS FatCommonSetEa ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 659 of file ea.c.

681{
682#if 0
684
686
687 USHORT ExtendedAttributes;
688
690 ULONG UserBufferLength;
691
692 PVCB Vcb;
693 PCCB Ccb;
694
695 PFCB Fcb;
697 PBCB Bcb = NULL;
698
700 PBCB EaBcb = NULL;
701
702 PEA_SET_HEADER EaSetHeader = NULL;
703
704 PEA_SET_HEADER PrevEaSetHeader;
705 PEA_SET_HEADER NewEaSetHeader;
707
708 BOOLEAN AcquiredVcb = FALSE;
709 BOOLEAN AcquiredFcb = FALSE;
710 BOOLEAN AcquiredParentDcb = FALSE;
711 BOOLEAN AcquiredRootDcb = FALSE;
712 BOOLEAN AcquiredEaFcb = FALSE;
713#endif
714
715 PAGED_CODE();
716
719
720#if 0
721
722 //
723 // The following booleans are used in the unwind process.
724 //
725
726 //
727 // Get the current Irp stack location
728 //
729
731
732 DebugTrace(+1, Dbg, "FatCommonSetEa...\n", 0);
733 DebugTrace( 0, Dbg, " Wait = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
734 DebugTrace( 0, Dbg, " Irp = %p\n", Irp );
735 DebugTrace( 0, Dbg, " ->SystemBuffer = %p\n", Irp->AssociatedIrp.SystemBuffer );
736 DebugTrace( 0, Dbg, " ->Length = %08lx\n", IrpSp->Parameters.SetEa.Length );
737
738 Irp->IoStatus.Status = STATUS_SUCCESS;
739 Irp->IoStatus.Information = 0;
740
741 //
742 // Check that the file object is associated with either a user file
743 // or directory open.
744 //
745
746 {
747 TYPE_OF_OPEN OpenType;
748
749 if (((OpenType = FatDecodeFileObject( IrpSp->FileObject,
750 &Vcb,
751 &Fcb,
752 &Ccb )) != UserFileOpen
753 && OpenType != UserDirectoryOpen) ||
754
755 (NodeType( Fcb )) == FAT_NTC_ROOT_DCB) {
756
758
759 DebugTrace(-1, Dbg,
760 "FatCommonSetEa -> %08lx\n",
762
764 }
765 }
766
767 //
768 // Fat32 does not support ea's.
769 //
770
771 if (FatIsFat32(Vcb)) {
772
774 DebugTrace(-1, Dbg,
775 "FatCommonSetEa -> %08lx\n",
778 }
779
780 //
781 // Reference our input parameters to make things easier
782 //
783
784 UserBufferLength = IrpSp->Parameters.SetEa.Length;
785
786 //
787 // Since we ask for no outside help (direct or buffered IO), it
788 // is our responsibility to insulate ourselves from the
789 // deviousness of the user above. Now, buffer and validate the
790 // contents.
791 //
792
793 Buffer = FatBufferUserBuffer( IrpContext, Irp, UserBufferLength );
794
795 //
796 // Check the validity of the buffer with the new eas. We really
797 // need to do this always since we don't know, if it was already
798 // buffered, that we buffered and checked it or some overlying
799 // filter buffered without checking.
800 //
801
803 UserBufferLength,
804 (PULONG)&Irp->IoStatus.Information );
805
806 if (!NT_SUCCESS( Status )) {
807
808 FatCompleteRequest( IrpContext, Irp, Status );
809 DebugTrace(-1, Dbg,
810 "FatCommonSetEa -> %08lx\n",
811 Status);
812 return Status;
813 }
814
815 //
816 // Acquire exclusive access to the Fcb. If this is a write-through operation
817 // we will need to pick up the other possible streams that can be modified in
818 // this operation so that the locking order is preserved - the root directory
819 // (dirent addition if EA database doesn't already exist) and the parent
820 // directory (addition of the EA handle to the object's dirent).
821 //
822 // We are primarily synchronizing with directory enumeration here.
823 //
824 // If we cannot wait need to send things off to the fsp.
825 //
826
827 if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {
828
829 DebugTrace(0, Dbg, "FatCommonSetEa: Set Ea must be waitable\n", 0);
830
831 Status = FatFsdPostRequest( IrpContext, Irp );
832
833 DebugTrace(-1, Dbg, "FatCommonSetEa -> %08lx\n", Status );
834
835 return Status;
836 }
837
838 //
839 // Set this handle as having modified the file
840 //
841
843
844 RtlZeroMemory( &EaSetRange, sizeof( EA_RANGE ));
845
846 try {
847
848 ULONG PackedEasLength;
849 BOOLEAN PreviousEas;
850 ULONG AllocationLength;
851 ULONG BytesPerCluster;
853
855
856 //
857 // Now go pick up everything
858 //
859
860 FatAcquireSharedVcb( IrpContext, Fcb->Vcb );
861 AcquiredVcb = TRUE;
862 FatAcquireExclusiveFcb( IrpContext, Fcb );
863 AcquiredFcb = TRUE;
864
865 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH)) {
866
867 if (Fcb->ParentDcb) {
868
869 FatAcquireExclusiveFcb( IrpContext, Fcb->ParentDcb );
870 AcquiredParentDcb = TRUE;
871 }
872
873 FatAcquireExclusiveFcb( IrpContext, Fcb->Vcb->RootDcb );
874 AcquiredRootDcb = TRUE;
875 }
876
877 //
878 // We verify that the Fcb is still valid.
879 //
880
881 FatVerifyFcb( IrpContext, Fcb );
882
883 //
884 // We need to get the dirent for the Fcb to recover the Ea handle.
885 //
886
887 FatGetDirentFromFcbOrDcb( IrpContext, Fcb, &Dirent, &Bcb );
888
889 DebugTrace(0, Dbg, "FatCommonSetEa: Dirent Address -> %p\n",
890 Dirent );
891 DebugTrace(0, Dbg, "FatCommonSetEa: Dirent Bcb -> %p\n",
892 Bcb);
893
894 //
895 // If the handle value is 0, then the file has no Eas. In that
896 // case we allocate memory to hold the Eas to be added. If there
897 // are existing Eas for the file, then we must read from the
898 // file and copy the Eas.
899 //
900
901 ExtendedAttributes = Dirent->ExtendedAttributes;
902
903 FatUnpinBcb( IrpContext, Bcb );
904
905 if (ExtendedAttributes == 0) {
906
907 PreviousEas = FALSE;
908
909 DebugTrace(0, Dbg,
910 "FatCommonSetEa: File has no current Eas\n", 0 );
911
912 } else {
913
914 PreviousEas = TRUE;
915
916 DebugTrace(0, Dbg, "FatCommonSetEa: File has previous Eas\n", 0 );
917
918 FatGetEaFile( IrpContext,
919 Vcb,
920 &EaDirent,
921 &EaBcb,
922 FALSE,
923 TRUE );
924
925 AcquiredEaFcb = TRUE;
926
927 //
928 // If we didn't get the file then there is an error on
929 // the disk.
930 //
931
932 if (Vcb->VirtualEaFile == NULL) {
933
936 }
937 }
938
939 DebugTrace(0, Dbg, "FatCommonSetEa: EaBcb -> %p\n", EaBcb);
940
941 DebugTrace(0, Dbg, "FatCommonSetEa: EaDirent -> %p\n", EaDirent);
942
943 //
944 // If the file has existing ea's, we need to read them to
945 // determine the size of the buffer allocation.
946 //
947
948 if (PreviousEas) {
949
950 //
951 // We need to try to get the Ea set for the desired file.
952 //
953
954 FatReadEaSet( IrpContext,
955 Vcb,
956 ExtendedAttributes,
958 TRUE,
959 &EaSetRange );
960
961 PrevEaSetHeader = (PEA_SET_HEADER) EaSetRange.Data;
962
963 //
964 // We now must allocate pool memory for our copy of the
965 // EaSetHeader and then copy the Ea data into it. At that
966 // time we can unpin the EaSet.
967 //
968
969 PackedEasLength = GetcbList( PrevEaSetHeader ) - 4;
970
971 //
972 // Else we will create a dummy EaSetHeader.
973 //
974
975 } else {
976
977 PackedEasLength = 0;
978 }
979
980 BytesPerCluster = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster;
981
982 AllocationLength = (PackedEasLength
984 + BytesPerCluster - 1)
985 & ~(BytesPerCluster - 1);
986
987 EaSetHeader = FsRtlAllocatePoolWithTag( PagedPool,
988 AllocationLength,
990
991 //
992 // Copy the existing Eas over to pool memory.
993 //
994
995 if (PreviousEas) {
996
997 RtlCopyMemory( EaSetHeader, PrevEaSetHeader, AllocationLength );
998
999 FatUnpinEaRange( IrpContext, &EaSetRange );
1000
1001 } else {
1002
1003 RtlZeroMemory( EaSetHeader, AllocationLength );
1004
1005 RtlCopyMemory( EaSetHeader->OwnerFileName,
1006 Fcb->ShortName.Name.Oem.Buffer,
1007 Fcb->ShortName.Name.Oem.Length );
1008 }
1009
1010
1011 AllocationLength -= SIZE_OF_EA_SET_HEADER;
1012
1013 DebugTrace(0, Dbg, "FatCommonSetEa: Initial Ea set -> %p\n",
1014 EaSetHeader);
1015
1016 //
1017 // At this point we have either read in the current eas for the file
1018 // or we have initialized a new empty buffer for the eas. Now for
1019 // each full ea in the input user buffer we do the specified operation
1020 // on the ea
1021 //
1022
1023 for (FullEa = (PFILE_FULL_EA_INFORMATION) Buffer;
1024 FullEa < (PFILE_FULL_EA_INFORMATION) &Buffer[UserBufferLength];
1025 FullEa = (PFILE_FULL_EA_INFORMATION) (FullEa->NextEntryOffset == 0 ?
1026 &Buffer[UserBufferLength] :
1027 (PUCHAR) FullEa + FullEa->NextEntryOffset)) {
1028
1029 OEM_STRING EaName;
1030 ULONG Offset;
1031
1032 EaName.MaximumLength = EaName.Length = FullEa->EaNameLength;
1033 EaName.Buffer = &FullEa->EaName[0];
1034
1035 DebugTrace(0, Dbg, "FatCommonSetEa: Next Ea name -> %Z\n",
1036 &EaName);
1037
1038 //
1039 // Make sure the ea name is valid
1040 //
1041
1042 if (!FatIsEaNameValid( IrpContext,EaName )) {
1043
1044 Irp->IoStatus.Information = (PUCHAR)FullEa - Buffer;
1046 try_return( Status );
1047 }
1048
1049 //
1050 // Check that no invalid ea flags are set.
1051 //
1052
1053 //
1054 // TEMPCODE We are returning STATUS_INVALID_EA_NAME
1055 // until a more appropriate error code exists.
1056 //
1057
1058 if (FullEa->Flags != 0
1059 && FullEa->Flags != FILE_NEED_EA) {
1060
1061 Irp->IoStatus.Information = (PUCHAR)FullEa - (PUCHAR)Buffer;
1063 }
1064
1065 //
1066 // See if we can locate the ea name in the ea set
1067 //
1068
1069 if (FatLocateEaByName( IrpContext,
1070 (PPACKED_EA) EaSetHeader->PackedEas,
1071 PackedEasLength,
1072 &EaName,
1073 &Offset )) {
1074
1075 DebugTrace(0, Dbg, "FatCommonSetEa: Found Ea name\n", 0);
1076
1077 //
1078 // We found the ea name so now delete the current entry,
1079 // and if the new ea value length is not zero then we
1080 // replace if with the new ea
1081 //
1082
1083 FatDeletePackedEa( IrpContext,
1084 EaSetHeader,
1085 &PackedEasLength,
1086 Offset );
1087 }
1088
1089 if (FullEa->EaValueLength != 0) {
1090
1091 FatAppendPackedEa( IrpContext,
1092 &EaSetHeader,
1093 &PackedEasLength,
1094 &AllocationLength,
1095 FullEa,
1096 BytesPerCluster );
1097 }
1098 }
1099
1100 //
1101 // If there are any ea's not removed, we
1102 // call 'AddEaSet' to insert them into the Fat chain.
1103 //
1104
1105 if (PackedEasLength != 0) {
1106
1107 LARGE_INTEGER EaOffset;
1108
1109 EaOffset.HighPart = 0;
1110
1111 //
1112 // If the packed eas length (plus 4 bytes) is greater
1113 // than the maximum allowed ea size, we return an error.
1114 //
1115
1116 if (PackedEasLength + 4 > MAXIMUM_EA_SIZE) {
1117
1118 DebugTrace( 0, Dbg, "Ea length is greater than maximum\n", 0 );
1119
1121 }
1122
1123 //
1124 // We need to now read the ea file if we haven't already.
1125 //
1126
1127 if (EaDirent == NULL) {
1128
1129 FatGetEaFile( IrpContext,
1130 Vcb,
1131 &EaDirent,
1132 &EaBcb,
1133 TRUE,
1134 TRUE );
1135
1136 AcquiredEaFcb = TRUE;
1137 }
1138
1139 FatGetDirentFromFcbOrDcb( IrpContext, Fcb, &Dirent, &Bcb );
1140
1141 RtlZeroMemory( &EaSetRange, sizeof( EA_RANGE ));
1142
1143 FatAddEaSet( IrpContext,
1144 Vcb,
1145 PackedEasLength + SIZE_OF_EA_SET_HEADER,
1146 EaBcb,
1147 EaDirent,
1148 &EaHandle,
1149 &EaSetRange );
1150
1151 NewEaSetHeader = (PEA_SET_HEADER) EaSetRange.Data;
1152
1153 DebugTrace(0, Dbg, "FatCommonSetEa: Adding an ea set\n", 0);
1154
1155 //
1156 // Store the length of the new Ea's into the EaSetHeader.
1157 // This is the PackedEasLength + 4.
1158 //
1159
1160 PackedEasLength += 4;
1161
1162 CopyU4char( EaSetHeader->cbList, &PackedEasLength );
1163
1164 //
1165 // Copy all but the first four bytes of EaSetHeader into
1166 // NewEaSetHeader. The signature and index fields have
1167 // already been filled in.
1168 //
1169
1170 RtlCopyMemory( &NewEaSetHeader->NeedEaCount,
1171 &EaSetHeader->NeedEaCount,
1172 PackedEasLength + SIZE_OF_EA_SET_HEADER - 8 );
1173
1174 FatMarkEaRangeDirty( IrpContext, Vcb->VirtualEaFile, &EaSetRange );
1175 FatUnpinEaRange( IrpContext, &EaSetRange );
1176
1177 CcFlushCache( Vcb->VirtualEaFile->SectionObjectPointer, NULL, 0, NULL );
1178
1179 } else {
1180
1181 FatGetDirentFromFcbOrDcb( IrpContext, Fcb, &Dirent, &Bcb );
1182
1183 EaHandle = 0;
1184 }
1185
1186 //
1187 // Now we do a wholesale replacement of the ea for the file
1188 //
1189
1190 if (PreviousEas) {
1191
1192 FatDeleteEaSet( IrpContext,
1193 Vcb,
1194 EaBcb,
1195 EaDirent,
1196 ExtendedAttributes,
1197 &Fcb->ShortName.Name.Oem );
1198
1199 CcFlushCache( Vcb->VirtualEaFile->SectionObjectPointer, NULL, 0, NULL );
1200 }
1201
1202 if (PackedEasLength != 0 ) {
1203
1205 }
1206
1207 //
1208 // Mark the dirent with the new ea's
1209 //
1210
1211 Dirent->ExtendedAttributes = EaHandle;
1212
1213 FatSetDirtyBcb( IrpContext, Bcb, Vcb, TRUE );
1214
1215 //
1216 // We call the notify package to report that the ea's were
1217 // modified.
1218 //
1219
1220 FatNotifyReportChange( IrpContext,
1221 Vcb,
1222 Fcb,
1225
1226 Irp->IoStatus.Information = 0;
1228
1229 try_exit: NOTHING;
1230
1231 //
1232 // Unpin the dirents for the Fcb and EaFcb if necessary.
1233 //
1234
1235 FatUnpinBcb( IrpContext, Bcb );
1236 FatUnpinBcb( IrpContext, EaBcb );
1237
1238 FatUnpinRepinnedBcbs( IrpContext );
1239
1240 } finally {
1241
1243
1244 //
1245 // If this is an abnormal termination, we need to clean up
1246 // any locked resources.
1247 //
1248
1249 if (AbnormalTermination()) {
1250
1251 //
1252 // Unpin the dirents for the Fcb, EaFcb and EaSetFcb if necessary.
1253 //
1254
1255 FatUnpinBcb( IrpContext, Bcb );
1256 FatUnpinBcb( IrpContext, EaBcb );
1257
1258 FatUnpinEaRange( IrpContext, &EaSetRange );
1259 }
1260
1261 //
1262 // Release the Fcbs/Vcb acquired.
1263 //
1264
1265 if (AcquiredEaFcb) {
1266 FatReleaseFcb( IrpContext, Vcb->EaFcb );
1267 }
1268
1269 if (AcquiredFcb) {
1270 FatReleaseFcb( IrpContext, Fcb );
1271 }
1272
1273 if (AcquiredParentDcb) {
1274 FatReleaseFcb( IrpContext, Fcb->ParentDcb );
1275 }
1276
1277 if (AcquiredRootDcb) {
1278 FatReleaseFcb( IrpContext, Fcb->Vcb->RootDcb );
1279 }
1280
1281 if (AcquiredVcb) {
1282 FatReleaseVcb( IrpContext, Fcb->Vcb );
1283 }
1284
1285 //
1286 // Deallocate our Ea buffer.
1287 //
1288
1289 if (EaSetHeader != NULL) {
1290
1291 ExFreePool( EaSetHeader );
1292 }
1293
1294 //
1295 // Complete the irp.
1296 //
1297
1298 if (!AbnormalTermination()) {
1299
1300 FatCompleteRequest( IrpContext, Irp, Status );
1301 }
1302
1303 DebugTrace(-1, Dbg, "FatCommonSetEa -> %08lx\n", Status);
1304 }
1305
1306 //
1307 // And return to our caller
1308 //
1309
1310 return Status;
1311#endif
1312}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS FatCommonSetEa(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: ea.c:659
#define MAXIMUM_EA_SIZE
Definition: fat.h:676
VOID FatMarkEaRangeDirty(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT EaFileObject, IN OUT PEA_RANGE EaRange)
Definition: easup.c:3709
VOID FatAppendPackedEa(IN PIRP_CONTEXT IrpContext, IN OUT PEA_SET_HEADER *EaSetHeader, IN OUT PULONG PackedEasLength, IN OUT PULONG AllocationLength, IN PFILE_FULL_EA_INFORMATION FullEa, IN ULONG BytesPerCluster)
Definition: easup.c:2967
VOID FatDeletePackedEa(IN PIRP_CONTEXT IrpContext, IN OUT PEA_SET_HEADER EaSetHeader, IN OUT PULONG PackedEasLength, IN ULONG Offset)
Definition: easup.c:3148
BOOLEAN FatLocateEaByName(IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN POEM_STRING EaName, OUT PULONG Offset)
Definition: easup.c:3344
BOOLEAN FatIsEaNameValid(IN PIRP_CONTEXT IrpContext, IN OEM_STRING Name)
Definition: easup.c:3429
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1088
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
PVOID FatBufferUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN ULONG BufferLength)
Definition: deviosup.c:3411
#define FatNotifyReportChange(I, V, F, FL, A)
Definition: fatprocs.h:2168
IN PVCB IN PUCHAR IN ULONG IN POEM_STRING OUT PUSHORT EaHandle
Definition: fatprocs.h:898
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1640
#define CopyU4char(Dst, Src)
Definition: fatprocs.h:2153
struct _FILE_FULL_EA_INFORMATION * PFILE_FULL_EA_INFORMATION
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
#define STATUS_INVALID_EA_NAME
Definition: ntstatus.h:199
#define STATUS_EA_TOO_LARGE
Definition: ntstatus.h:316
ULONG32 NeedEaCount
Definition: fat.h:666
UCHAR cbList[4]
Definition: fat.h:669
UCHAR OwnerFileName[14]
Definition: fat.h:667
struct _FCB * ParentDcb
Definition: fatstruc.h:836
PVCB Vcb
Definition: cdstruc.h:933
struct _FCB * RootDcb
Definition: fatstruc.h:285
#define FILE_ACTION_MODIFIED
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define FILE_NOTIFY_CHANGE_EA

Referenced by _Function_class_(), FatCommonSetEa(), and FatFspDispatch().

◆ FatCompareNames()

COMPARISON FatCompareNames ( IN PSTRING  NameA,
IN PSTRING  NameB 
)

Definition at line 421 of file splaysup.c.

449{
450 ULONG i;
451 ULONG MinLength;
452
453 PAGED_CODE();
454
455 //
456 // Figure out the minimum of the two lengths
457 //
458
459 MinLength = NameA->Length < NameB->Length ? NameA->Length :
460 NameB->Length;
461
462 //
463 // Loop through looking at all of the characters in both strings
464 // testing for equalilty, less than, and greater than
465 //
466
467 i = (ULONG)RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength );
468
469
470 if (i < MinLength) {
471
472 return NameA->Buffer[i] < NameB->Buffer[i] ? IsLessThan :
474 }
475
476 if (NameA->Length < NameB->Length) {
477
478 return IsLessThan;
479 }
480
481 if (NameA->Length > NameB->Length) {
482
483 return IsGreaterThan;
484 }
485
486 return IsEqual;
487}
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

◆ FatCompleteMdl()

NTSTATUS FatCompleteMdl ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 1728 of file cachesup.c.

1750{
1753
1754 PAGED_CODE();
1755
1756 DebugTrace(+1, Dbg, "FatCompleteMdl\n", 0 );
1757 DebugTrace( 0, Dbg, "IrpContext = %p\n", IrpContext );
1758 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
1759
1760 //
1761 // Do completion processing.
1762 //
1763
1765
1766 switch( IrpContext->MajorFunction ) {
1767
1768 case IRP_MJ_READ:
1769
1770 CcMdlReadComplete( FileObject, Irp->MdlAddress );
1771 break;
1772
1773 case IRP_MJ_WRITE:
1774
1776
1777 NT_ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ));
1778
1779 CcMdlWriteComplete( FileObject, &IrpSp->Parameters.Write.ByteOffset, Irp->MdlAddress );
1780
1781 Irp->IoStatus.Status = STATUS_SUCCESS;
1782
1783 break;
1784
1785 default:
1786
1787 DebugTrace( DEBUG_TRACE_ERROR, 0, "Illegal Mdl Complete.\n", 0);
1788#ifdef _MSC_VER
1789#pragma prefast( suppress: 28159, "we're very broken if we get here" )
1790#endif
1791 FatBugCheck( IrpContext->MajorFunction, 0, 0 );
1792 }
1793
1794 //
1795 // Mdl is now deallocated.
1796 //
1797
1798 Irp->MdlAddress = NULL;
1799
1800 //
1801 // Complete the request and exit right away.
1802 //
1803
1804 FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
1805
1806 DebugTrace(-1, Dbg, "FatCompleteMdl -> STATUS_SUCCESS\n", 0 );
1807
1808 return STATUS_SUCCESS;
1809}
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

Referenced by _Function_class_().

◆ FatCompleteRequest_Real()

VOID FatCompleteRequest_Real ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp,
IN NTSTATUS  Status 
)

Definition at line 733 of file fatdata.c.

757{
758 PAGED_CODE();
759
760#if DBG
761 if ( (FatBreakOnInterestingIrpCompletion != 0) && (Status == FatBreakOnInterestingIrpCompletion) ) {
763 }
764
765#endif
766
767 //
768 // If we have an Irp Context then unpin all of the repinned bcbs
769 // we might have collected.
770 //
771
772 if (IrpContext != NULL) {
773
774 NT_ASSERT( IrpContext->Repinned.Bcb[0] == NULL );
775
776 FatUnpinRepinnedBcbs( IrpContext );
777 }
778
779 //
780 // Delete the Irp context before completing the IRP so if
781 // we run into some of the asserts, we can still backtrack
782 // through the IRP.
783 //
784
785 if (IrpContext != NULL) {
786
787 FatDeleteIrpContext( IrpContext );
788 }
789
790 //
791 // If we have an Irp then complete the irp.
792 //
793
794 if (Irp != NULL) {
795
796 //
797 // We got an error, so zero out the information field before
798 // completing the request if this was an input operation.
799 // Otherwise IopCompleteRequest will try to copy to the user's buffer.
800 //
801
802 if ( NT_ERROR(Status) &&
803 FlagOn(Irp->Flags, IRP_INPUT_OPERATION) ) {
804
805 Irp->IoStatus.Information = 0;
806 }
807
808 Irp->IoStatus.Status = Status;
809
811 }
812
813 return;
814}
#define FatDeleteIrpContext(IRPCONTEXT)
Definition: fatprocs.h:1762
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define IoCompleteRequest
Definition: irp.c:1240
#define NT_ERROR(Status)
Definition: umtypes.h:106
#define IRP_INPUT_OPERATION
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

◆ FatConstructDirent()

VOID FatConstructDirent ( IN PIRP_CONTEXT  IrpContext,
IN OUT PDIRENT  Dirent,
IN POEM_STRING  FileName,
IN BOOLEAN  ComponentReallyLowercase,
IN BOOLEAN  ExtensionReallyLowercase,
IN PUNICODE_STRING Lfn  OPTIONAL,
IN USHORT  Attributes,
IN BOOLEAN  ZeroAndSetTimeFields,
IN PLARGE_INTEGER SetCreationTime  OPTIONAL 
)

Definition at line 2171 of file dirsup.c.

2218{
2219 PAGED_CODE();
2220
2221 DebugTrace(+1, Dbg, "FatConstructDirent\n", 0);
2222
2223 DebugTrace( 0, Dbg, " Dirent = %p\n", Dirent);
2224 DebugTrace( 0, Dbg, " FileName = %Z\n", FileName);
2225 DebugTrace( 0, Dbg, " Attributes = %08lx\n", Attributes);
2226
2227 if (ZeroAndSetTimeFields) {
2228
2229 RtlZeroMemory( Dirent, sizeof(DIRENT) );
2230 }
2231
2232 //
2233 // We just merrily go and fill up the dirent with the fields given.
2234 //
2235
2236 FatStringTo8dot3( IrpContext, *FileName, (PFAT8DOT3)&Dirent->FileName[0] );
2237
2238 if (ZeroAndSetTimeFields || SetCreationTime) {
2239
2240 LARGE_INTEGER Time, SaveTime;
2241
2243
2244 if (FatData.ChicagoMode) {
2245
2246 if (!SetCreationTime || !FatNtTimeToFatTime( IrpContext,
2247 SetCreationTime,
2248 FALSE,
2250 &Dirent->CreationMSec )) {
2251
2252 //
2253 // No tunneled time or the tunneled time was bogus. Since we aren't
2254 // responsible for initializing the to-be-created Fcb with creation
2255 // time, we can't do the usual thing and let NtTimeToFatTime perform
2256 // rounding on the timestamp - this would mess up converting to the
2257 // LastWriteTime below.
2258 //
2259
2260 SaveTime = Time;
2261
2262 if (!FatNtTimeToFatTime( IrpContext,
2263 &SaveTime,
2264 FALSE,
2266 &Dirent->CreationMSec )) {
2267
2268 //
2269 // Failed again. Wow.
2270 //
2271
2273 Dirent->CreationMSec = 0;
2274 }
2275 }
2276 }
2277
2278 if (ZeroAndSetTimeFields) {
2279
2280 //
2281 // We only touch the other timestamps if we are initializing the dirent
2282 //
2283
2284 if (!FatNtTimeToFatTime( IrpContext,
2285 &Time,
2286 TRUE,
2288 NULL )) {
2289
2290 DebugTrace( 0, Dbg, "Current time invalid.\n", 0);
2291
2293 }
2294
2295 if (FatData.ChicagoMode) {
2296
2297 Dirent->LastAccessDate = Dirent->LastWriteTime.Date;
2298 }
2299 }
2300 }
2301
2302 //
2303 // Copy the attributes
2304 //
2305
2306 Dirent->Attributes = (UCHAR)Attributes;
2307
2308 //
2309 // Set the magic bit here, to tell dirctrl.c that this name is really
2310 // lowercase.
2311 //
2312
2313 Dirent->NtByte = 0;
2314
2315 if (ComponentReallyLowercase) {
2316
2318 }
2319
2320 if (ExtensionReallyLowercase) {
2321
2323 }
2324
2325 //
2326 // See if we have to create an Lfn entry
2327 //
2328
2329 if (ARGUMENT_PRESENT(Lfn)) {
2330
2331 UCHAR DirentChecksum;
2332 UCHAR DirentsInLfn;
2333 UCHAR LfnOrdinal;
2334 PWCHAR LfnBuffer;
2335 PLFN_DIRENT LfnDirent;
2336
2338
2339 DirentChecksum = FatComputeLfnChecksum( Dirent );
2340
2341 LfnOrdinal =
2342 DirentsInLfn = (UCHAR)FAT_LFN_DIRENTS_NEEDED(Lfn);
2343
2344 LfnBuffer = &Lfn->Buffer[(DirentsInLfn - 1) * 13];
2345
2346 NT_ASSERT( DirentsInLfn <= MAX_LFN_DIRENTS );
2347
2348 for (LfnDirent = (PLFN_DIRENT)Dirent - DirentsInLfn;
2349 LfnDirent < (PLFN_DIRENT)Dirent;
2350 LfnDirent += 1, LfnOrdinal -= 1, LfnBuffer -= 13) {
2351
2352 WCHAR FinalLfnBuffer[13];
2353 PWCHAR Buffer;
2354
2355 //
2356 // We need to special case the "final" dirent.
2357 //
2358
2359 if (LfnOrdinal == DirentsInLfn) {
2360
2361 ULONG i;
2362 ULONG RemainderChars;
2363
2364 RemainderChars = (Lfn->Length / sizeof(WCHAR)) % 13;
2365
2366 LfnDirent->Ordinal = LfnOrdinal | FAT_LAST_LONG_ENTRY;
2367
2368 if (RemainderChars != 0) {
2369
2370 RtlCopyMemory( FinalLfnBuffer,
2371 LfnBuffer,
2372 RemainderChars * sizeof(WCHAR) );
2373
2374 for (i = RemainderChars; i < 13; i++) {
2375
2376 //
2377 // Figure out which character to use.
2378 //
2379
2380 if (i == RemainderChars) {
2381
2382 FinalLfnBuffer[i] = 0x0000;
2383
2384 } else {
2385
2386 FinalLfnBuffer[i] = 0xffff;
2387 }
2388 }
2389
2390 Buffer = FinalLfnBuffer;
2391
2392 } else {
2393
2394 Buffer = LfnBuffer;
2395 }
2396
2397 } else {
2398
2399 LfnDirent->Ordinal = LfnOrdinal;
2400
2401 Buffer = LfnBuffer;
2402 }
2403
2404 //
2405 // Now fill in the name.
2406 //
2407
2408 RtlCopyMemory( &LfnDirent->Name1[0],
2409 &Buffer[0],
2410 5 * sizeof(WCHAR) );
2411
2412 RtlCopyMemory( &LfnDirent->Name2[0],
2413 &Buffer[5],
2414 6 * sizeof(WCHAR) );
2415
2416 RtlCopyMemory( &LfnDirent->Name3[0],
2417 &Buffer[11],
2418 2 * sizeof(WCHAR) );
2419
2420 //
2421 // And the other fields
2422 //
2423
2424 LfnDirent->Attributes = FAT_DIRENT_ATTR_LFN;
2425
2426 LfnDirent->Type = 0;
2427
2428 LfnDirent->Checksum = DirentChecksum;
2429
2430 LfnDirent->MustBeZero = 0;
2431 }
2432 }
2433
2434 DebugTrace(-1, Dbg, "FatConstructDirent -> (VOID)\n", 0);
2435 return;
2436}
PAGED_CODE()
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: dirsup.c:425
_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
FAT8DOT3 * PFAT8DOT3
Definition: fat.h:296
#define FAT_DIRENT_ATTR_LFN
Definition: fat.h:375
#define MAX_LFN_DIRENTS
Definition: lfn.h:51
#define FAT_LAST_LONG_ENTRY
Definition: lfn.h:35
LFN_DIRENT * PLFN_DIRENT
Definition: lfn.h:44
#define FAT_LFN_DIRENTS_NEEDED(NAME)
Definition: lfn.h:53
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
UCHAR FatComputeLfnChecksum(PDIRENT Dirent)
Definition: dirsup.c:2878
#define Dbg
Definition: dirsup.c:28
VOID FatStringTo8dot3(_In_ PIRP_CONTEXT IrpContext, _In_ OEM_STRING InputString, _Out_writes_bytes_(11) PFAT8DOT3 Output8dot3)
Definition: namesup.c:79
static PLARGE_INTEGER Time
Definition: time.c:105
#define ARGUMENT_PRESENT(ArgumentPointer)
LONGLONG CreationTime
Definition: cdstruc.h:1030
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
uint16_t * PWCHAR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by FatSetRenameInfo().

◆ FatConstructLabelDirent()

VOID FatConstructLabelDirent ( IN PIRP_CONTEXT  IrpContext,
IN OUT PDIRENT  Dirent,
IN POEM_STRING  Label 
)

Definition at line 2440 of file dirsup.c.

2465{
2466 PAGED_CODE();
2467
2468 DebugTrace(+1, Dbg, "FatConstructLabelDirent\n", 0);
2469
2470 DebugTrace( 0, Dbg, " Dirent = %p\n", Dirent);
2471 DebugTrace( 0, Dbg, " Label = %Z\n", Label);
2472
2473 RtlZeroMemory( Dirent, sizeof(DIRENT) );
2474
2475 //
2476 // We just merrily go and fill up the dirent with the fields given.
2477 //
2478
2479 RtlCopyMemory( Dirent->FileName, Label->Buffer, Label->Length );
2480
2481 //
2482 // Pad the label with spaces, not nulls.
2483 //
2484
2485 RtlFillMemory( &Dirent->FileName[Label->Length], 11 - Label->Length, ' ');
2486
2487 Dirent->LastWriteTime = FatGetCurrentFatTime( IrpContext );
2488
2489 Dirent->Attributes = FAT_DIRENT_ATTR_VOLUME_ID;
2490 Dirent->ExtendedAttributes = 0;
2491 Dirent->FileSize = 0;
2492
2493 DebugTrace(-1, Dbg, "FatConstructLabelDirent -> (VOID)\n", 0);
2494 return;
2495}
PWCHAR Label
Definition: format.c:70
FAT_TIME_STAMP FatGetCurrentFatTime(_In_ PIRP_CONTEXT IrpContext)
Definition: timesup.c:317
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599

Referenced by FatSetFsLabelInfo().

◆ 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}
#define TAG_FILENAME_BUFFER
Definition: nodetype.h:167
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
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 c
Definition: ke_i.h:80
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_UNMAPPABLE_CHARACTER
Definition: ntstatus.h:590
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
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::@720 LongName
USHORT FinalNameLength
Definition: fatstruc.h:1124
ULONG FcbState
Definition: cdstruc.h:971
UNICODE_STRING Unicode
Definition: fatstruc.h:695
BOOLEAN FileNameDos
Definition: fatstruc.h:704
struct _FCB * Fcb
Definition: fatstruc.h:685
unsigned short Length
Definition: sprintf.c:451
void * Buffer
Definition: sprintf.c:453
unsigned short MaximumLength
Definition: sprintf.c:452
#define RtlOemStringToCountedUnicodeSize(STRING)

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}
struct _CCB CCB
#define FAT_NTC_CCB
Definition: nodetype.h:32
INLINE PCCB FatAllocateCcb()
Definition: strucsup.c:59
#define Dbg
Definition: strucsup.c:29

◆ 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}
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4140
#define ExLocalTimeToSystemTime(LocTime, SysTime)
Definition: env_spec_w32.h:738
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertHeadList(ListHead, Entry)
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
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
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
FCB DCB
Definition: fatstruc.h:1184
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1241
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
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
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
ULONG FirstClusterOfFile
Definition: fatstruc.h:818
uint16_t * PUSHORT
Definition: typedefs.h:56
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

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}
#define TAG_FCB
Definition: nodetype.h:152
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
union _FCB::@719 Specific
CD_MCB Mcb
Definition: cdstruc.h:1016
FCB_CONDITION FcbCondition
Definition: fatstruc.h:850
struct _FCB::@719::@722 Fcb
ULONG ValidDataToDisk
Definition: fatstruc.h:928
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
2354 IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_INVALIDATE_VOLUMES) ||
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}
VOLUME_DEVICE_OBJECT * PVOLUME_DEVICE_OBJECT
Definition: cdstruc.h:769
#define FAT_NTC_IRP_CONTEXT
Definition: nodetype.h:33
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_CREATE
Definition: rdpdr.c:44
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#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().

◆ FatDecodeFileObject()

TYPE_OF_OPEN FatDecodeFileObject ( _In_ PFILE_OBJECT  FileObject,
_Outptr_ PVCB Vcb,
_Outptr_ PFCB FcbOrDcb,
_Outptr_ PCCB Ccb 
)

Definition at line 176 of file filobsup.c.

227{
230 PVOID FsContext2;
231
232 PAGED_CODE();
233
234 DebugTrace(+1, Dbg, "FatDecodeFileObject, FileObject = %p\n", FileObject);
235
236 //
237 // Reference the fs context fields of the file object, and zero out
238 // the out pointer parameters.
239 //
240
241 FsContext = FileObject->FsContext;
242 FsContext2 = FileObject->FsContext2;
243
244 //
245 // Special case the situation where FsContext is null
246 //
247
248 if (FsContext == NULL) {
249
250 *Ccb = NULL;
251 *FcbOrDcb = NULL;
252 *Vcb = NULL;
253
255
256 } else {
257
258 //
259 // Now we can case on the node type code of the fscontext pointer
260 // and set the appropriate out pointers
261 //
262
263 switch (NodeType(FsContext)) {
264
265 case FAT_NTC_VCB:
266
267 *Ccb = FsContext2;
268 *FcbOrDcb = NULL;
269 *Vcb = FsContext;
270
272
273 break;
274
275 case FAT_NTC_ROOT_DCB:
276 case FAT_NTC_DCB:
277
278 *Ccb = FsContext2;
280 *Vcb = (*FcbOrDcb)->Vcb;
281
283
284 DebugTrace(0, Dbg, "Referencing directory: %wZ\n", &(*FcbOrDcb)->FullFileName);
285
286 break;
287
288 case FAT_NTC_FCB:
289
290 *Ccb = FsContext2;
292 *Vcb = (*FcbOrDcb)->Vcb;
293
294 if (*Ccb != NULL ) {
295
297 DebugTrace(0, Dbg, "Referencing file: %wZ\n", &(*FcbOrDcb)->FullFileName);
298
299 } else {
300
301 //
302 // No Ccb means this is a special open.
303 //
304
305
306 if ( *FcbOrDcb == (*Vcb)->EaFcb ) {
307
309 DebugTrace(0, Dbg, "Referencing EA file: %wZ\n", &(*FcbOrDcb)->FullFileName);
310
311 } else {
312
313#ifdef _MSC_VER
314#pragma prefast(suppress:28159, "things are seriously wrong if we get here")
315#endif
317
318 }
319
320 }
321
322 break;
323
324 default:
325
326#ifdef _MSC_VER
327#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
328#endif
330 }
331 }
332
333 //
334 // and return to our caller
335 //
336
337 DebugTrace(0, Dbg, "FatDecodeFileObject -> VCB(%p)\n", *Vcb);
338 DebugTrace(0, Dbg, "FatDecodeFileObject -> FCB(%p)\n", *FcbOrDcb);
339 DebugTrace(0, Dbg, "FatDecodeFileObject -> CCB(%p)\n", *Ccb);
340 DebugTrace(-1, Dbg, "FatDecodeFileObject -> TypeOfOpen = %08lx\n", TypeOfOpen);
341
342 return TypeOfOpen;
343}
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
@ UnopenedFileObject
Definition: cdprocs.h:573
@ UserVolumeOpen
Definition: cdprocs.h:575
#define FAT_NTC_VCB
Definition: nodetype.h:28
#define Dbg
Definition: filobsup.c:28
IN PFCB FcbOrDcb
Definition: fatprocs.h:306
_Inout_ PLIST_ENTRY _In_ PVOID FsContext
Definition: fltkernel.h:2239

Referenced by _Function_class_(), _Requires_lock_held_(), FatAllowExtendedDasdIo(), FatCommonQueryEa(), FatCommonSetEa(), FatDeferredFlush(), FatFspDispatch(), FatIsVolumeDirty(), FatIsVolumeMounted(), FatSetRenameInfo(), FatSetZeroOnDeallocate(), and FatUnlockVolume().

◆ 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 Fcb 
)

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
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::@719::@721 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

◆ FatDeletePackedEa()

VOID FatDeletePackedEa ( IN PIRP_CONTEXT  IrpContext,
IN OUT PEA_SET_HEADER  EaSetHeader,
IN OUT PULONG  PackedEasLength,
IN ULONG  Offset 
)

Definition at line 3148 of file easup.c.

3183{
3184 PPACKED_EA PackedEa;
3185 ULONG PackedEaSize;
3186
3187 PAGED_CODE();
3188
3189 DebugTrace(+1, Dbg, "FatDeletePackedEa, Offset = %08lx\n", Offset);
3190
3191 //
3192 // Get a reference to the packed ea and figure out its size
3193 //
3194
3195 PackedEa = (PPACKED_EA) (&EaSetHeader->PackedEas[Offset]);
3196
3197 SizeOfPackedEa( PackedEa, &PackedEaSize );
3198
3199 //
3200 // Determine if we need to decrement our need ea changes count
3201 //
3202
3203 if (FlagOn(PackedEa->Flags, EA_NEED_EA_FLAG)) {
3204
3205 EaSetHeader->NeedEaCount--;
3206 }
3207
3208 //
3209 // Shrink the ea list over the deleted ea. The amount to copy is the
3210 // total size of the ea list minus the offset to the end of the ea
3211 // we're deleting.
3212 //
3213 // Before:
3214 // Offset Offset+PackedEaSize UsedSize Allocated
3215 // | | | |
3216 // V V V V
3217 // +xxxxxxxx+yyyyyyyyyyyyyyyy+zzzzzzzzzzzzzzzzzz+------------+
3218 //
3219 // After
3220 // Offset UsedSize Allocated
3221 // | | |
3222 // V V V
3223 // +xxxxxxxx+zzzzzzzzzzzzzzzzzz+-----------------------------+
3224 //
3225
3226 RtlCopyMemory( PackedEa,
3227 (PUCHAR) PackedEa + PackedEaSize,
3228 *PackedEasLength - (Offset + PackedEaSize) );
3229
3230 //
3231 // And zero out the remaing part of the ea list, to make things
3232 // nice and more robust
3233 //
3234
3235 RtlZeroMemory( &EaSetHeader->PackedEas[*PackedEasLength - PackedEaSize],
3236 PackedEaSize );
3237
3238 //
3239 // Decrement the used size by the amount we just removed
3240 //
3241
3242 *PackedEasLength -= PackedEaSize;
3243
3244 //
3245 // And return to our caller
3246 //
3247
3248 DebugTrace(-1, Dbg, "FatDeletePackedEa -> VOID\n", 0);
3249
3250 UNREFERENCED_PARAMETER( IrpContext );
3251
3252 return;
3253}
#define EA_NEED_EA_FLAG
Definition: fat.h:745
#define SizeOfPackedEa(EA, SIZE)
Definition: fat.h:738
UCHAR Flags
Definition: fat.h:695

Referenced by FatCommonSetEa().

◆ 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 FatDeleteResource(RESRC)
Definition: fatprocs.h:1632
#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

◆ FatEvaluateNameCase()

VOID FatEvaluateNameCase ( IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  Name,
IN OUT BOOLEAN AllLowerComponent,
IN OUT BOOLEAN AllLowerExtension,
IN OUT BOOLEAN CreateLfn 
)

Definition at line 891 of file namesup.c.

922{
923 ULONG i;
924 UCHAR Uppers = 0;
925 UCHAR Lowers = 0;
926
927 BOOLEAN ExtensionPresent = FALSE;
928
929 PAGED_CODE();
930 UNREFERENCED_PARAMETER( IrpContext );
931
932 *CreateLfn = FALSE;
933
934 for (i = 0; i < UnicodeName->Length / sizeof(WCHAR); i++) {
935
936 WCHAR c;
937
938 c = UnicodeName->Buffer[i];
939
940 if ((c >= 'A') && (c <= 'Z')) {
941
942 Uppers += 1;
943
944 } else if ((c >= 'a') && (c <= 'z')) {
945
946 Lowers += 1;
947
948 } else if ((c >= 0x0080) && FatData.CodePageInvariant) {
949
950 break;
951 }
952
953 //
954 // If we come to a period, figure out if the extension was
955 // all one case.
956 //
957
958 if (c == L'.') {
959
960 *CreateLfn = (Lowers != 0) && (Uppers != 0);
961
962 *AllLowerComponent = !(*CreateLfn) && (Lowers != 0);
963
964 ExtensionPresent = TRUE;
965
966 //
967 // Now reset the uppers and lowers count.
968 //
969
970 Uppers = Lowers = 0;
971 }
972 }
973
974 //
975 // Now check again for creating an LFN.
976 //
977
978 *CreateLfn = (*CreateLfn ||
979 (i != UnicodeName->Length / sizeof(WCHAR)) ||
980 ((Lowers != 0) && (Uppers != 0)));
981
982 //
983 // Now we know the final state of CreateLfn, update the two
984 // "AllLower" booleans.
985 //
986
987 if (ExtensionPresent) {
988
989 *AllLowerComponent = !(*CreateLfn) && *AllLowerComponent;
990 *AllLowerExtension = !(*CreateLfn) && (Lowers != 0);
991
992 } else {
993
994 *AllLowerComponent = !(*CreateLfn) && (Lowers != 0);
996 }
997
998 return;
999}
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN IN OUT BOOLEAN IN OUT BOOLEAN * CreateLfn
Definition: fatprocs.h:1311
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN * AllLowerComponent
Definition: fatprocs.h:1308
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1305
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN IN OUT BOOLEAN * AllLowerExtension
Definition: fatprocs.h:1309
BOOLEAN CodePageInvariant
Definition: fatstruc.h:115

Referenced by FatSetRenameInfo().

◆ FatExamineFatEntries()

VOID FatExamineFatEntries ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN ULONG StartIndex  OPTIONAL,
IN ULONG EndIndex  OPTIONAL,
IN BOOLEAN  SetupWindows,
IN PFAT_WINDOW SwitchToWindow  OPTIONAL,
IN PULONG BitMapBuffer  OPTIONAL 
)

Definition at line 4720 of file allocsup.c.

4770{
4772 ULONG Page = 0;
4773 ULONG Offset = 0;
4776 FAT_ENTRY FirstFatEntry = FAT_CLUSTER_AVAILABLE;
4777 PUSHORT FatBuffer;
4778 PVOID pv;
4779 PBCB Bcb = NULL;
4780 ULONG EntriesPerWindow;
4781
4782 ULONG ClustersThisRun;
4783 ULONG StartIndexOfThisRun;
4784
4785 PULONG FreeClusterCount = NULL;
4786
4787 PFAT_WINDOW CurrentWindow = NULL;
4788
4789 PVOID NewBitMapBuffer = NULL;
4790 PRTL_BITMAP BitMap = NULL;
4791 RTL_BITMAP PrivateBitMap;
4792
4793 ULONG ClusterSize = 0;
4794 ULONG PrefetchPages = 0;
4795 ULONG FatPages = 0;
4796
4797 VBO BadClusterVbo = 0;
4798 LBO Lbo = 0;
4799
4800 enum RunType {
4802 AllocatedClusters,
4803 UnknownClusters
4804 } CurrentRun;
4805
4806 PAGED_CODE();
4807
4808 //
4809 // Now assert correct usage.
4810 //
4811
4812 FatIndexBitSize = Vcb->AllocationSupport.FatIndexBitSize;
4813
4814 NT_ASSERT( !(SetupWindows && (SwitchToWindow || BitMapBuffer)));
4815 NT_ASSERT( !(SetupWindows && FatIndexBitSize != 32));
4816
4817 if (Vcb->NumberOfWindows > 1) {
4818
4819 //
4820 // FAT32: Calculate the number of FAT entries covered by a window. This is
4821 // equal to the number of bits in the freespace bitmap, the size of which
4822 // is hardcoded.
4823 //
4824
4825 EntriesPerWindow = MAX_CLUSTER_BITMAP_SIZE;
4826
4827 } else {
4828
4829 EntriesPerWindow = Vcb->AllocationSupport.NumberOfClusters;
4830 }
4831
4832 //
4833 // We will also fill in the cumulative count of free clusters for
4834 // the entire volume. If this is not appropriate, NULL it out
4835 // shortly.
4836 //
4837
4838 FreeClusterCount = &Vcb->AllocationSupport.NumberOfFreeClusters;
4839
4840 if (SetupWindows) {
4841
4842 NT_ASSERT(BitMapBuffer == NULL);
4843
4844 //
4845 // In this case we're just supposed to scan the fat and set up
4846 // the information regarding where the buckets fall and how many
4847 // free clusters are in each.
4848 //
4849 // It is fine to monkey with the real windows, we must be able
4850 // to do this to activate the volume.
4851 //
4852
4853 BitMap = NULL;
4854
4855 CurrentWindow = &Vcb->Windows[0];
4856 CurrentWindow->FirstCluster = StartIndex;
4857 CurrentWindow->ClustersFree = 0;
4858
4859 //
4860 // We always wish to calculate total free clusters when
4861 // setting up the FAT windows.
4862 //
4863
4864 } else if (BitMapBuffer == NULL) {
4865
4866 //
4867 // We will be filling in the free cluster bitmap for the volume.
4868 // Careful, we can raise out of here and be hopelessly hosed if
4869 // we built this up in the main bitmap/window itself.
4870 //
4871 // For simplicity's sake, we'll do the swap for everyone. FAT32
4872 // provokes the need since we can't tolerate partial results
4873 // when switching windows.
4874 //
4875
4876 NT_ASSERT( SwitchToWindow );
4877
4878 CurrentWindow = SwitchToWindow;
4879 StartIndex = CurrentWindow->FirstCluster;
4880 EndIndex = CurrentWindow->LastCluster;
4881
4882 BitMap = &PrivateBitMap;
4883 NewBitMapBuffer = FsRtlAllocatePoolWithTag( PagedPool,
4884 (EntriesPerWindow + 7) / 8,
4886
4887 RtlInitializeBitMap( &PrivateBitMap,
4888 NewBitMapBuffer,
4889 EndIndex - StartIndex + 1);
4890
4891 if ((FatIndexBitSize == 32) &&
4892 (Vcb->NumberOfWindows > 1)) {
4893
4894 //
4895 // We do not wish count total clusters here.
4896 //
4897
4898 FreeClusterCount = NULL;
4899
4900 }
4901
4902 } else {
4903
4904 BitMap = &PrivateBitMap;
4905 RtlInitializeBitMap(&PrivateBitMap,
4906 BitMapBuffer,
4907 EndIndex - StartIndex + 1);
4908
4909 //
4910 // We do not count total clusters here.
4911 //
4912
4913 FreeClusterCount = NULL;
4914 }
4915
4916 //
4917 // Now, our start index better be in the file heap.
4918 //
4919
4920 NT_ASSERT( StartIndex >= 2 );
4921
4922 _SEH2_TRY {
4923
4924 //
4925 // Pick up the initial chunk of the FAT and first entry.
4926 //
4927
4928 if (FatIndexBitSize == 12) {
4929
4930 //
4931 // We read in the entire fat in the 12 bit case.
4932 //
4933
4934 FatReadVolumeFile( IrpContext,
4935 Vcb,
4936 FatReservedBytes( &Vcb->Bpb ),
4937 FatBytesPerFat( &Vcb->Bpb ),
4938 &Bcb,
4939 (PVOID *)&FatBuffer );
4940
4941 FatLookup12BitEntry(FatBuffer, 0, &FirstFatEntry);
4942
4943 } else {
4944
4945 //
4946 // Read in one page of fat at a time. We cannot read in the
4947 // all of the fat we need because of cache manager limitations.
4948 //
4949
4950 ULONG BytesPerEntry = FatIndexBitSize >> 3;
4951
4952 FatPages = (FatReservedBytes(&Vcb->Bpb) + FatBytesPerFat(&Vcb->Bpb) + (PAGE_SIZE - 1)) / PAGE_SIZE;
4953 Page = (FatReservedBytes(&Vcb->Bpb) + StartIndex * BytesPerEntry) / PAGE_SIZE;
4954
4955 Offset = Page * PAGE_SIZE;
4956
4957 //
4958 // Prefetch the FAT entries in memory for optimal performance.
4959 //
4960
4961 PrefetchPages = FatPages - Page;
4962
4963 if (PrefetchPages > FAT_PREFETCH_PAGE_COUNT) {
4964
4965 PrefetchPages = ALIGN_UP_BY(Page, FAT_PREFETCH_PAGE_COUNT) - Page;
4966 }
4967
4968#if (NTDDI_VERSION >= NTDDI_WIN8)
4969 FatPrefetchPages( IrpContext,
4970 Vcb->VirtualVolumeFile,
4971 Page,
4972 PrefetchPages );
4973#endif
4974
4975 FatReadVolumeFile( IrpContext,
4976 Vcb,
4977 Offset,
4978 PAGE_SIZE,
4979 &Bcb,
4980 &pv);
4981
4982 if (FatIndexBitSize == 32) {
4983
4984 FatBuffer = (PUSHORT)((PUCHAR)pv +
4985 (FatReservedBytes(&Vcb->Bpb) + StartIndex * BytesPerEntry) %
4986 PAGE_SIZE);
4987
4988 FirstFatEntry = *((PULONG)FatBuffer);
4989 FirstFatEntry = FirstFatEntry & FAT32_ENTRY_MASK;
4990
4991 } else {
4992
4993 FatBuffer = (PUSHORT)((PUCHAR)pv +
4994 FatReservedBytes(&Vcb->Bpb) % PAGE_SIZE) + 2;
4995
4996 FirstFatEntry = *FatBuffer;
4997 }
4998
4999 }
5000
5001 ClusterSize = 1 << (Vcb->AllocationSupport.LogOfBytesPerCluster);
5002
5003 CurrentRun = (FirstFatEntry == FAT_CLUSTER_AVAILABLE) ?
5004 FreeClusters : AllocatedClusters;
5005
5006 StartIndexOfThisRun = StartIndex;
5007
5008 for (FatIndex = StartIndex; FatIndex <= EndIndex; FatIndex++) {
5009
5010 if (FatIndexBitSize == 12) {
5011
5013
5014 } else {
5015
5016 //
5017 // If we are setting up the FAT32 windows and have stepped into a new
5018 // bucket, finalize this one and move forward.
5019 //
5020
5021 if (SetupWindows &&
5022 FatIndex > StartIndex &&
5023 (FatIndex - 2) % EntriesPerWindow == 0) {
5024
5025 CurrentWindow->LastCluster = FatIndex - 1;
5026
5027 if (CurrentRun == FreeClusters) {
5028
5029 //
5030 // We must be counting clusters in order to modify the
5031 // contents of the window.
5032 //
5033
5034 NT_ASSERT( FreeClusterCount );
5035
5036 ClustersThisRun = FatIndex - StartIndexOfThisRun;
5037 CurrentWindow->ClustersFree += ClustersThisRun;
5038
5039 if (FreeClusterCount) {
5040 *FreeClusterCount += ClustersThisRun;
5041 }
5042
5043 } else {
5044
5045 NT_ASSERT(CurrentRun == AllocatedClusters);
5046
5047 }
5048
5049 StartIndexOfThisRun = FatIndex;
5050 CurrentRun = UnknownClusters;
5051
5052 CurrentWindow++;
5053 CurrentWindow->ClustersFree = 0;
5054 CurrentWindow->FirstCluster = FatIndex;
5055 }
5056
5057 //
5058 // If we just stepped onto a new page, grab a new pointer.
5059 //
5060
5061 if (((ULONG_PTR)FatBuffer & (PAGE_SIZE - 1)) == 0) {
5062
5063 FatUnpinBcb( IrpContext, Bcb );
5064
5065 Page++;
5066 Offset += PAGE_SIZE;
5067
5068#if (NTDDI_VERSION >= NTDDI_WIN8)
5069 //
5070 // If we have exhausted all the prefetch pages, prefetch the next chunk.
5071 //
5072
5073 if (--PrefetchPages == 0) {
5074
5075 PrefetchPages = FatPages - Page;
5076
5077 if (PrefetchPages > FAT_PREFETCH_PAGE_COUNT) {
5078
5079 PrefetchPages = FAT_PREFETCH_PAGE_COUNT;
5080 }
5081
5082 FatPrefetchPages( IrpContext,
5083 Vcb->VirtualVolumeFile,
5084 Page,
5085 PrefetchPages );
5086 }
5087#endif
5088
5089 FatReadVolumeFile( IrpContext,
5090 Vcb,
5091 Offset,
5092 PAGE_SIZE,
5093 &Bcb,
5094 &pv );
5095
5096 FatBuffer = (PUSHORT)pv;
5097 }
5098
5099 if (FatIndexBitSize == 32) {
5100
5101#ifndef __REACTOS__
5102#ifdef _MSC_VER
5103#pragma warning( suppress: 4213 )
5104#endif
5105 FatEntry = *((PULONG)FatBuffer)++;
5107#else
5108 FatEntry = *((PULONG)FatBuffer);
5109 FatBuffer += 2; /* PUSHORT FatBuffer */
5111#endif
5112
5113 } else {
5114
5115 FatEntry = *FatBuffer;
5116 FatBuffer += 1;
5117 }
5118 }
5119
5120 if (CurrentRun == UnknownClusters) {
5121
5122 CurrentRun = (FatEntry == FAT_CLUSTER_AVAILABLE) ?
5123 FreeClusters : AllocatedClusters;
5124 }
5125
5126 //
5127 // Are we switching from a free run to an allocated run?
5128 //
5129
5130 if (CurrentRun == FreeClusters &&
5132
5133 ClustersThisRun = FatIndex - StartIndexOfThisRun;
5134
5135 if (FreeClusterCount) {
5136
5137 *FreeClusterCount += ClustersThisRun;
5138 CurrentWindow->ClustersFree += ClustersThisRun;
5139 }
5140
5141 if (BitMap) {
5142
5143 RtlClearBits( BitMap,
5144 StartIndexOfThisRun - StartIndex,
5145 ClustersThisRun );
5146 }
5147
5148 CurrentRun = AllocatedClusters;
5149 StartIndexOfThisRun = FatIndex;
5150 }
5151
5152 //
5153 // Are we switching from an allocated run to a free run?
5154 //
5155
5156 if (CurrentRun == AllocatedClusters &&
5158
5159 ClustersThisRun = FatIndex - StartIndexOfThisRun;
5160
5161 if (BitMap) {
5162
5163 RtlSetBits( BitMap,
5164 StartIndexOfThisRun - StartIndex,
5165 ClustersThisRun );
5166 }
5167
5168 CurrentRun = FreeClusters;
5169 StartIndexOfThisRun = FatIndex;
5170 }
5171
5172 //
5173 // If the entry is marked bad, add it to the bad block MCB
5174 //
5175
5176 if ((SetupWindows || (Vcb->NumberOfWindows == 1)) &&
5178
5179 //
5180 // This cluster is marked bad.
5181 // Add it to the BadBlockMcb.
5182 //
5183
5185 FatAddMcbEntry( Vcb, &Vcb->BadBlockMcb, BadClusterVbo, Lbo, ClusterSize );
5186 BadClusterVbo += ClusterSize;
5187 }
5188 }
5189
5190 //
5191 // If we finished the scan, then we know about all the possible bad clusters.
5192 //
5193
5195
5196 //
5197 // Now we have to record the final run we encountered
5198 //
5199
5200 ClustersThisRun = FatIndex - StartIndexOfThisRun;
5201
5202 if (CurrentRun == FreeClusters) {
5203
5204 if (FreeClusterCount) {
5205
5206 *FreeClusterCount += ClustersThisRun;
5207 CurrentWindow->ClustersFree += ClustersThisRun;
5208 }
5209
5210 if (BitMap) {
5211
5212 RtlClearBits( BitMap,
5213 StartIndexOfThisRun - StartIndex,
5214 ClustersThisRun );
5215 }
5216
5217 } else {
5218
5219 if (BitMap) {
5220
5221 RtlSetBits( BitMap,
5222 StartIndexOfThisRun - StartIndex,
5223 ClustersThisRun );
5224 }
5225 }
5226
5227 //
5228 // And finish the last window if we are in setup.
5229 //
5230
5231 if (SetupWindows) {
5232
5233 CurrentWindow->LastCluster = FatIndex - 1;
5234 }
5235
5236 //
5237 // Now switch the active window if required. We've succesfully gotten everything
5238 // nailed down.
5239 //
5240 // If we were tracking the free cluster count, this means we should update the
5241 // window. This is the case of FAT12/16 initialization.
5242 //
5243
5244 if (SwitchToWindow) {
5245
5246 if (Vcb->FreeClusterBitMap.Buffer) {
5247
5248 ExFreePool( Vcb->FreeClusterBitMap.Buffer );
5249 }
5250
5251 RtlInitializeBitMap( &Vcb->FreeClusterBitMap,
5252 NewBitMapBuffer,
5253 EndIndex - StartIndex + 1 );
5254
5255 NewBitMapBuffer = NULL;
5256
5257 Vcb->CurrentWindow = SwitchToWindow;
5258 Vcb->ClusterHint = (ULONG)-1;
5259
5260 if (FreeClusterCount) {
5261
5262 NT_ASSERT( !SetupWindows );
5263
5264 Vcb->CurrentWindow->ClustersFree = *FreeClusterCount;
5265 }
5266 }
5267
5268 //
5269 // Make sure plausible things occured ...
5270 //
5271
5272 if (!SetupWindows && BitMapBuffer == NULL) {
5273
5275 }
5276
5277 NT_ASSERT(Vcb->AllocationSupport.NumberOfFreeClusters <= Vcb->AllocationSupport.NumberOfClusters);
5278
5279 } _SEH2_FINALLY {
5280
5281 //
5282 // Unpin the last bcb and drop the temporary bitmap buffer if it exists.
5283 //
5284
5285 FatUnpinBcb( IrpContext, Bcb);
5286
5287 if (NewBitMapBuffer) {
5288
5289 ExFreePool( NewBitMapBuffer );
5290 }
5291 } _SEH2_END;
5292}
#define ALIGN_UP_BY(size, align)
DWORD ClusterSize
Definition: format.c:67
LONGLONG LBO
Definition: fat.h:34
#define FAT32_ENTRY_MASK
Definition: fat.h:227
#define FatReservedBytes(B)
Definition: fat.h:414
#define FatLookup12BitEntry(FAT, INDEX, ENTRY)
Definition: fat.h:584
#define FatIndexBitSize(B)
Definition: fat.h:515
#define FAT_CLUSTER_AVAILABLE
Definition: fat.h:255
#define FatBytesPerFat(B)
Definition: fat.h:410
#define FatGetLboFromIndex(VCB, FAT_INDEX)
Definition: fat.h:559
#define TAG_FAT_BITMAP
Definition: nodetype.h:163
NTSTATUS FreeClusters(PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONG ClustersToFree)
Definition: attrib.c:1057
CLUSTER_TYPE FatInterpretClusterType(IN PVCB Vcb, IN FAT_ENTRY Entry)
Definition: allocsup.c:3473
#define MAX_CLUSTER_BITMAP_SIZE
Definition: allocsup.c:247
#define FAT_PREFETCH_PAGE_COUNT
Definition: allocsup.c:36
#define ASSERT_CURRENT_WINDOW_GOOD(VCB)
Definition: allocsup.c:83
NTSTATUS FatPrefetchPages(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN ULONG StartingPage, IN ULONG PageCount)
Definition: cachesup.c:1929
BOOLEAN FatAddMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN LBO Lbo, IN ULONG SectorCount)
Definition: fsctrl.c:364
IN PVCB IN ULONG FatIndex
Definition: fatprocs.h:383
IN PVCB IN ULONG IN FAT_ENTRY FatEntry
Definition: fatprocs.h:385
#define VCB_STATE_FLAG_BAD_BLOCKS_POPULATED
Definition: fatstruc.h:576
@ FatClusterBad
Definition: fatstruc.h:1749
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
Definition: fsck.fat.h:192
ULONG ClustersFree
Definition: fatstruc.h:175
ULONG FirstCluster
Definition: fatstruc.h:173
ULONG LastCluster
Definition: fatstruc.h:174
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by FatSetupAllocationSupport().

◆ FatExceptionFilter()

ULONG FatExceptionFilter ( IN PIRP_CONTEXT  IrpContext,
IN PEXCEPTION_POINTERS  ExceptionPointer 
)

Definition at line 204 of file fatdata.c.

229{
231
232 ExceptionCode = ExceptionPointer->ExceptionRecord->ExceptionCode;
233 DebugTrace(0, DEBUG_TRACE_UNWIND, "FatExceptionFilter %X\n", ExceptionCode);
234 DebugDump("FatExceptionFilter\n", Dbg, NULL );
235
236#if DBG
237
238 if( FatBreakOnInterestingExceptionStatus != 0 && ExceptionCode == FatBreakOnInterestingExceptionStatus ) {
240 }
241
242#endif
243
244 //
245 // If the exception is STATUS_IN_PAGE_ERROR, get the I/O error code
246 // from the exception record.
247 //
248
250 if (ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
251 ExceptionCode = (NTSTATUS)ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
252 }
253 }
254
255 //
256 // If there is not an irp context, we must have had insufficient resources.
257 //
258
259 if ( !ARGUMENT_PRESENT( IrpContext ) ) {
260
262
263#ifdef _MSC_VER
264#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
265#endif
266 FatBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
267 (ULONG_PTR)ExceptionPointer->ContextRecord,
268 (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
269 }
270
272 }
273
274 //
275 // For the purposes of processing this exception, let's mark this
276 // request as being able to wait and disable write through if we
277 // aren't posting it.
278 //
279
280 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
281
284
286 }
287
288 if ( IrpContext->ExceptionStatus == 0 ) {
289
291
292 IrpContext->ExceptionStatus = ExceptionCode;
293
295
296 } else {
297
298#ifdef _MSC_VER
299#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
300#endif
301 FatBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
302 (ULONG_PTR)ExceptionPointer->ContextRecord,
303 (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
304 }
305
306 } else {
307
308 //
309 // We raised this code explicitly ourselves, so it had better be
310 // expected.
311 //
312
313 NT_ASSERT( IrpContext->ExceptionStatus == ExceptionCode );
315 }
316
318}
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774
#define NTSTATUS
Definition: precomp.h:21
#define Dbg
Definition: fatdata.c:28
#define IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH
Definition: fatstruc.h:1565
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130

Referenced by _Function_class_(), _Requires_lock_held_(), FatFlushFat(), FatFspDispatch(), FatFspMarkVolumeDirtyWithRecover(), FatMultiAsyncCompletionRoutine(), and FatSingleAsyncCompletionRoutine().

◆ FatExplicitDeviceAccessGranted()

NTSTATUS FatExplicitDeviceAccessGranted ( IN PIRP_CONTEXT  IrpContext,
IN PDEVICE_OBJECT  DeviceObject,
IN PACCESS_STATE  AccessState,
IN KPROCESSOR_MODE  ProcessorMode 
)

Definition at line 225 of file acchksup.c.

255{
257
258 PACCESS_TOKEN OriginalAccessToken;
259 PACCESS_TOKEN RestrictedAccessToken;
260
261 PACCESS_TOKEN *EffectiveToken;
262
264
265 PAGED_CODE();
266
267 UNREFERENCED_PARAMETER( IrpContext );
268
269 //
270 // If the access state indicates that specific access other
271 // than traverse was acquired, either Everyone does have such
272 // access or explicit access was granted. In both cases, we're
273 // happy to let this proceed.
274 //
275
276 if (AccessState->PreviouslyGrantedAccess & (SPECIFIC_RIGHTS_ALL ^
277 FILE_TRAVERSE)) {
278
279 return STATUS_SUCCESS;
280 }
281
282 //
283 // If the manage volume privilege is held, this also permits access.
284 //
285
286 if (FatCheckManageVolumeAccess( IrpContext,
288 ProcessorMode )) {
289
290 return STATUS_SUCCESS;
291 }
292
293 //
294 // Capture the subject context as a prelude to everything below.
295 //
296
297 SeLockSubjectContext( &AccessState->SubjectSecurityContext );
298
299 //
300 // Convert the token in the subject context into one which does not
301 // acquire access through the Everyone SID.
302 //
303 // The logic for deciding which token is effective comes from
304 // SeQuerySubjectContextToken; since there is no natural way
305 // of getting a pointer to it, do it by hand.
306 //
307
308 if (ARGUMENT_PRESENT( AccessState->SubjectSecurityContext.ClientToken )) {
309 EffectiveToken = &AccessState->SubjectSecurityContext.ClientToken;
310 } else {
311 EffectiveToken = &AccessState->SubjectSecurityContext.PrimaryToken;
312 }
313
314 OriginalAccessToken = *EffectiveToken;
315 Status = FatCreateRestrictEveryoneToken( OriginalAccessToken, &RestrictedAccessToken );
316
317 if (!NT_SUCCESS(Status)) {
318
319 SeReleaseSubjectContext( &AccessState->SubjectSecurityContext );
320 return Status;
321 }
322
323 //
324 // Now see if the resulting context has access to the device through
325 // its explicitly granted access. We swap in our restricted token
326 // for this check as the effective client token.
327 //
328
329 *EffectiveToken = RestrictedAccessToken;
330
331#ifdef _MSC_VER
332#pragma prefast( suppress: 28175, "we're a file system, this is ok to touch" )
333#endif
334 SeAccessCheck( DeviceObject->SecurityDescriptor,
335 &AccessState->SubjectSecurityContext,
336 FALSE,
337 AccessState->OriginalDesiredAccess,
338 0,
339 NULL,
341 ProcessorMode,
343 &Status );
344
345 *EffectiveToken = OriginalAccessToken;
346
347 //
348 // Cleanup and return.
349 //
350
351 SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
352 ObDereferenceObject( RestrictedAccessToken );
353
354 return Status;
355}
BOOLEAN NTAPI SeAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, _In_ BOOLEAN SubjectContextLocked, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK PreviouslyGrantedAccess, _Out_ PPRIVILEGE_SET *Privileges, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:1994
NTSTATUS FatCreateRestrictEveryoneToken(IN PACCESS_TOKEN Token, OUT PACCESS_TOKEN *RestrictedToken)
Definition: acchksup.c:359
BOOLEAN FatCheckManageVolumeAccess(_In_ PIRP_CONTEXT IrpContext, _In_ PACCESS_STATE AccessState, _In_ KPROCESSOR_MODE ProcessorMode)
Definition: acchksup.c:176
#define SPECIFIC_RIGHTS_ALL
Definition: nt_native.h:71
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3267
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20

◆ FatExtendString()

VOID FatExtendString ( _Inout_ PVOID  String,
_In_ USHORT  DesiredBufferSize,
_In_ BOOLEAN  FreeOldBuffer,
__out_opt PBOOLEAN  NeedsFree 
)

◆ FatFatDateToNtTime()

LARGE_INTEGER FatFatDateToNtTime ( _In_ PIRP_CONTEXT  IrpContext,
_In_ FAT_DATE  FatDate 
)

Definition at line 171 of file timesup.c.

193{
196
197 PAGED_CODE();
198
199 //
200 // Pack the input time/date into a time field record
201 //
202
203 TimeFields.Year = (USHORT)(FatDate.Year + 1980);
204 TimeFields.Month = (USHORT)(FatDate.Month);
205 TimeFields.Day = (USHORT)(FatDate.Day);
210
211 //
212 // Convert the time field record to Nt LARGE_INTEGER, and set it to zero
213 // if we were given a bogus time.
214 //
215
217
218 Time.LowPart = 0;
219 Time.HighPart = 0;
220
221 } else {
222
224 }
225
226 return Time;
227
228 UNREFERENCED_PARAMETER( IrpContext );
229}
BOOLEAN RtlTimeFieldsToTime(IN PTIME_FIELDS TimeFields, IN PLARGE_INTEGER Time)
static PTIME_FIELDS TimeFields
Definition: time.c:104
USHORT Milliseconds
Definition: env_spec_w32.h:717
ULONG LowPart
Definition: typedefs.h:106

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

◆ FatFatTimeToNtTime()

LARGE_INTEGER FatFatTimeToNtTime ( _In_ PIRP_CONTEXT  IrpContext,
_In_ FAT_TIME_STAMP  FatTime,
_In_ UCHAR  TenMilliSeconds 
)

Definition at line 233 of file timesup.c.

258{
261
262 PAGED_CODE();
263
264 //
265 // Pack the input time/date into a time field record
266 //
267
268 TimeFields.Year = (USHORT)(FatTime.Date.Year + 1980);
269 TimeFields.Month = (USHORT)(FatTime.Date.Month);
270 TimeFields.Day = (USHORT)(FatTime.Date.Day);
271 TimeFields.Hour = (USHORT)(FatTime.Time.Hour);
272 TimeFields.Minute = (USHORT)(FatTime.Time.Minute);
273 TimeFields.Second = (USHORT)(FatTime.Time.DoubleSeconds * 2);
274
275 if (TenMilliSeconds != 0) {
276
277 TimeFields.Second += (USHORT)(TenMilliSeconds / 100);
278 TimeFields.Milliseconds = (USHORT)((TenMilliSeconds % 100) * 10);
279
280 } else {
281
283 }
284
285 //
286 // If the second value is greater than 59 then we truncate it to 0.
287 // Note that this can't happen with a proper FAT timestamp.
288 //
289
290 if (TimeFields.Second > 59) {
291
292 TimeFields.Second = 0;
293 }
294
295 //
296 // Convert the time field record to Nt LARGE_INTEGER, and set it to zero
297 // if we were given a bogus time.
298 //
299
301
302 Time.LowPart = 0;
303 Time.HighPart = 0;
304
305 } else {
306
308 }
309
310 return Time;
311
312 UNREFERENCED_PARAMETER( IrpContext );
313}
_In_ PLARGE_INTEGER _In_ BOOLEAN _Out_ PFAT_TIME_STAMP FatTime
Definition: fatprocs.h:1916

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

◆ FatFindFcb()

PFCB FatFindFcb ( IN PIRP_CONTEXT  IrpContext,
IN OUT PRTL_SPLAY_LINKS RootNode,
IN PSTRING  Name,
OUT PBOOLEAN FileNameDos  OPTIONAL 
)

Definition at line 306 of file splaysup.c.

335{
336 COMPARISON Comparison;
338 PRTL_SPLAY_LINKS Links;
339
340 PAGED_CODE();
341 UNREFERENCED_PARAMETER( IrpContext );
342
343 Links = *RootNode;
344
345 while (Links != NULL) {
346
347 Node = CONTAINING_RECORD(Links, FILE_NAME_NODE, Links);
348
349 //
350 // Compare the prefix in the tree with the full name
351 //
352
353 Comparison = CompareNames(&Node->Name.Oem, Name);
354
355 //
356 // See if they don't match
357 //
358
359 if (Comparison == IsGreaterThan) {
360
361 //
362 // The prefix is greater than the full name
363 // so we go down the left child
364 //
365
366 Links = RtlLeftChild(Links);
367
368 //
369 // And continue searching down this tree
370 //
371
372 } else if (Comparison == IsLessThan) {
373
374 //
375 // The prefix is less than the full name
376 // so we go down the right child
377 //
378
379 Links = RtlRightChild(Links);
380
381 //
382 // And continue searching down this tree
383 //
384
385 } else {
386
387 //
388 // We found it.
389 //
390 // Splay the tree and save the new root.
391 //
392
393 *RootNode = RtlSplay(Links);
394
395 //
396 // Tell the caller what kind of name we hit
397 //
398
399 if (FileNameDos) {
400
401 *FileNameDos = Node->FileNameDos;
402 }
403
404 return Node->Fcb;
405 }
406 }
407
408 //
409 // We didn't find the Fcb.
410 //
411
412 return NULL;
413}
union node Node
Definition: types.h:1255
#define CompareNames(NAMEA, NAMEB)
Definition: fatprocs.h:1899
PCONFIGURATION_COMPONENT_DATA RootNode
Definition: macharm.c:19
Definition: dlist.c:348
#define RtlRightChild(Links)
#define RtlLeftChild(Links)
NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlSplay(_Inout_ PRTL_SPLAY_LINKS Links)

Referenced by FatConstructNamesInFcb().

◆ FatFlushDirentForFile()

VOID FatFlushDirentForFile ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb 
)

Definition at line 1264 of file flush.c.

1285{
1288
1289 PAGED_CODE();
1290
1292
1293 CcFlushCache( &Fcb->ParentDcb->NonPaged->SectionObjectPointers,
1294 &FileOffset,
1295 sizeof( DIRENT ),
1296 &Iosb );
1297
1298 if (NT_SUCCESS(Iosb.Status)) {
1299 Iosb.Status = FatHijackIrpAndFlushDevice( IrpContext,
1300 IrpContext->OriginatingIrp,
1302 }
1303
1304 if (!NT_SUCCESS(Iosb.Status)) {
1305 FatNormalizeAndRaiseStatus(IrpContext, Iosb.Status);
1306 }
1307}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
return Iosb
Definition: create.c:4402
NTSTATUS FatHijackIrpAndFlushDevice(IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT TargetDeviceObject)
Definition: flush.c:1101
PDEVICE_OBJECT TargetDeviceObject
Definition: cdstruc.h:517

◆ FatFlushFat()

NTSTATUS FatFlushFat ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 801 of file flush.c.

824{
825 PBCB Bcb;
826 PVOID DontCare;
829
830 NTSTATUS ReturnStatus = STATUS_SUCCESS;
831
832 PAGED_CODE();
833
834 //
835 // If this volume is write protected, no need to flush.
836 //
837
838 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED)) {
839
840 return STATUS_SUCCESS;
841 }
842
843 //
844 // Make sure the Vcb is OK.
845 //
846
847 _SEH2_TRY {
848
849 FatVerifyVcb( IrpContext, Vcb );
850
853
854 FatResetExceptionState( IrpContext );
855 } _SEH2_END;
856
857 if (Vcb->VcbCondition != VcbGood) {
858
859 return STATUS_FILE_INVALID;
860 }
861
862 //
863 // The only way we have to correctly synchronize things is to
864 // repin stuff, and then unpin repin it.
865 //
866 // With NT 5.0, we can use some new cache manager support to make
867 // this a lot more efficient (important for FAT32). Since we're
868 // only worried about ranges that are dirty - and since we're a
869 // modified-no-write stream - we can assume that if there is no
870 // BCB, there is no work to do in the range. I.e., the lazy writer
871 // beat us to it.
872 //
873 // This is much better than reading the entire FAT in and trying
874 // to punch it out (see the test in the write path to blow
875 // off writes that don't correspond to dirty ranges of the FAT).
876 // For FAT32, this would be a *lot* of reading.
877 //
878
879 if (Vcb->AllocationSupport.FatIndexBitSize != 12) {
880
881 //
882 // Walk through the Fat, one page at a time.
883 //
884
885 ULONG NumberOfPages;
886 ULONG Page;
887
888 NumberOfPages = ( FatReservedBytes(&Vcb->Bpb) +
889 FatBytesPerFat(&Vcb->Bpb) +
890 (PAGE_SIZE - 1) ) / PAGE_SIZE;
891
892
893 for ( Page = 0, Offset.QuadPart = 0;
894 Page < NumberOfPages;
895 Page++, Offset.LowPart += PAGE_SIZE ) {
896
897 _SEH2_TRY {
898
899 if (CcPinRead( Vcb->VirtualVolumeFile,
900 &Offset,
901 PAGE_SIZE,
903 &Bcb,
904 &DontCare )) {
905
907 CcRepinBcb( Bcb );
908 CcUnpinData( Bcb );
910
911 if (!NT_SUCCESS(Iosb.Status)) {
912
913 ReturnStatus = Iosb.Status;
914 }
915 }
916
918
919 ReturnStatus = IrpContext->ExceptionStatus;
920 continue;
921 } _SEH2_END;
922 }
923
924 } else {
925
926 //
927 // We read in the entire fat in the 12 bit case.
928 //
929
930 Offset.QuadPart = FatReservedBytes( &Vcb->Bpb );
931
932 _SEH2_TRY {
933
934 if (CcPinRead( Vcb->VirtualVolumeFile,
935 &Offset,
936 FatBytesPerFat( &Vcb->Bpb ),
938 &Bcb,
939 &DontCare )) {
940
942 CcRepinBcb( Bcb );
943 CcUnpinData( Bcb );
945
946 if (!NT_SUCCESS(Iosb.Status)) {
947
948 ReturnStatus = Iosb.Status;
949 }
950 }
951
953
954 ReturnStatus = IrpContext->ExceptionStatus;
955 } _SEH2_END;
956 }
957
958 return ReturnStatus;
959}
VOID NTAPI CcUnpinRepinnedBcb(IN PVOID Bcb, IN BOOLEAN WriteThrough, OUT PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:343
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
VOID NTAPI CcRepinBcb(IN PVOID Bcb)
Definition: cachesub.c:331
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2983
VOID FatVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:270
@ VcbGood
Definition: fatstruc.h:223
#define PIN_IF_BCB
#define PIN_WAIT
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:802
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158

Referenced by _Requires_lock_held_().

◆ FatFlushFatEntries()

VOID FatFlushFatEntries ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN ULONG  Cluster,
IN ULONG  Count 
)

Definition at line 1191 of file flush.c.

1218{
1221
1223
1224 PAGED_CODE();
1225
1226 FileOffset.HighPart = 0;
1227 FileOffset.LowPart = FatReservedBytes( &Vcb->Bpb );
1228
1229 if (Vcb->AllocationSupport.FatIndexBitSize == 12) {
1230
1231 FileOffset.LowPart += Cluster * 3 / 2;
1232 ByteCount = (Count * 3 / 2) + 1;
1233
1234 } else if (Vcb->AllocationSupport.FatIndexBitSize == 32) {
1235
1236 FileOffset.LowPart += Cluster * sizeof(ULONG);
1237 ByteCount = Count * sizeof(ULONG);
1238
1239 } else {
1240
1241 FileOffset.LowPart += Cluster * sizeof( USHORT );
1242 ByteCount = Count * sizeof( USHORT );
1243
1244 }
1245
1246 CcFlushCache( &Vcb->SectionObjectPointers,
1247 &FileOffset,
1248 ByteCount,
1249 &Iosb );
1250
1251 if (NT_SUCCESS(Iosb.Status)) {
1252 Iosb.Status = FatHijackIrpAndFlushDevice( IrpContext,
1253 IrpContext->OriginatingIrp,
1254 Vcb->TargetDeviceObject );
1255 }
1256
1257 if (!NT_SUCCESS(Iosb.Status)) {
1258 FatNormalizeAndRaiseStatus(IrpContext, Iosb.Status);
1259 }
1260}
int Count
Definition: noreturn.cpp:7
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099

◆ 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

Referenced by FatEnsureStringBufferEnough().

◆ FatFsdPostRequest()

NTSTATUS FatFsdPostRequest ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 229 of file workque.c.

254{
255 PAGED_CODE();
256
258 NT_ASSERT( IrpContext->OriginatingIrp == Irp );
259
260 FatPrePostIrp( IrpContext, Irp );
261
262 FatAddToWorkque( IrpContext, Irp );
263
264 //
265 // And return to our caller
266 //
267
268 return STATUS_PENDING;
269}
VOID NTAPI FatPrePostIrp(IN PVOID Context, IN PIRP Irp)
Definition: workque.c:91
VOID FatAddToWorkque(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:280
#define STATUS_PENDING
Definition: ntstatus.h:82

Referenced by _Requires_lock_held_(), FatCommonQueryEa(), FatCommonSetEa(), FatMultiAsyncCompletionRoutine(), and FatSingleAsyncCompletionRoutine().

◆ FatFspDispatch()

VOID NTAPI FatFspDispatch ( _In_ PVOID  Context)

Definition at line 41 of file fspdisp.c.

65{
67
68
69 PIRP Irp;
70 PIRP_CONTEXT IrpContext;
72 BOOLEAN VcbDeleted;
73 BOOLEAN ExceptionCompletedIrp = FALSE;
74
76
78
79 PAGED_CODE();
80
81 IrpContext = (PIRP_CONTEXT)Context;
82
83 Irp = IrpContext->OriginatingIrp;
84
86
87 //
88 // Now because we are the Fsp we will force the IrpContext to
89 // indicate true on Wait.
90 //
91
93
94 //
95 // If this request has an associated volume device object, remember it.
96 //
97
98 if ( IrpSp->FileObject != NULL ) {
99
102 DeviceObject );
103 } else {
104
105 VolDo = NULL;
106 }
107
108 //
109 // Now case on the function code. For each major function code,
110 // either call the appropriate FSP routine or case on the minor
111 // function and then call the FSP routine. The FSP routine that
112 // we call is responsible for completing the IRP, and not us.
113 // That way the routine can complete the IRP and then continue
114 // post processing as required. For example, a read can be
115 // satisfied right away and then read can be done.
116 //
117 // We'll do all of the work within an exception handler that
118 // will be invoked if ever some underlying operation gets into
119 // trouble (e.g., if FatReadSectorsSync has trouble).
120 //
121
122 while ( TRUE ) {
123
124 ExceptionCompletedIrp = FALSE;
125
126 DebugTrace(0, Dbg, "FatFspDispatch: Irp = %p\n", Irp);
127
128 //
129 // If this Irp was top level, note it in our thread local storage.
130 //
131
133
134 if ( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) ) {
135
137
138 } else {
139
141 }
142
143 MajorFunction = IrpContext->MajorFunction;
144
145 _SEH2_TRY {
146
147 switch ( MajorFunction ) {
148
149 //
150 // For Create Operation,
151 //
152
153 case IRP_MJ_CREATE:
154
155 Status = FatCommonCreate( IrpContext, Irp );
156 break;
157
158 //
159 // For close operations. We do a little kludge here in case
160 // this close causes a volume to go away. It will NULL the
161 // VolDo local variable so that we will not try to look at
162 // the overflow queue.
163 //
164
165 case IRP_MJ_CLOSE:
166
167 {
168 PVCB Vcb;
169 PFCB Fcb;
170 PCCB Ccb;
172
173 //
174 // Extract and decode the file object
175 //
176
178
179 //
180 // Do the close. We have a slightly different format
181 // for this call because of the async closes.
182 //
183
184 Status = FatCommonClose( Vcb,
185 Fcb,
186 Ccb,
188 TRUE,
189 TRUE,
190 &VcbDeleted );
191
192 //
193 // If the VCB was deleted, do not try to access it later.
194 //
195
196 if (VcbDeleted) {
197
198 VolDo = NULL;
199 }
200
202
203 FatCompleteRequest( IrpContext, Irp, Status );
204
205 break;
206 }
207
208 //
209 // For read operations
210 //
211
212 case IRP_MJ_READ:
213
214 (VOID) FatCommonRead( IrpContext, Irp );
215 break;
216
217 //
218 // For write operations,
219 //
220
221 case IRP_MJ_WRITE:
222
223 (VOID) FatCommonWrite( IrpContext, Irp );
224 break;
225
226 //
227 // For Query Information operations,
228 //
229
231
232 (VOID) FatCommonQueryInformation( IrpContext, Irp );
233 break;
234
235 //
236 // For Set Information operations,
237 //
238
240
241 (VOID) FatCommonSetInformation( IrpContext, Irp );
242 break;
243
244 //
245 // For Query EA operations,
246 //
247
248 case IRP_MJ_QUERY_EA:
249
250 (VOID) FatCommonQueryEa( IrpContext, Irp );
251 break;
252
253 //
254 // For Set EA operations,
255 //
256
257 case IRP_MJ_SET_EA:
258
259 (VOID) FatCommonSetEa( IrpContext, Irp );
260 break;
261
262 //
263 // For Flush buffers operations,
264 //
265
267
268 (VOID) FatCommonFlushBuffers( IrpContext, Irp );
269 break;
270
271 //
272 // For Query Volume Information operations,
273 //
274
276
277 (VOID) FatCommonQueryVolumeInfo( IrpContext, Irp );
278 break;
279
280 //
281 // For Set Volume Information operations,
282 //
283
285
286 (VOID) FatCommonSetVolumeInfo( IrpContext, Irp );
287 break;
288
289 //
290 // For File Cleanup operations,
291 //
292
293 case IRP_MJ_CLEANUP:
294
295 (VOID) FatCommonCleanup( IrpContext, Irp );
296 break;
297
298 //
299 // For Directory Control operations,
300 //
301
303
304 (VOID) FatCommonDirectoryControl( IrpContext, Irp );
305 break;
306
307 //
308 // For File System Control operations,
309 //
310
312
313 (VOID) FatCommonFileSystemControl( IrpContext, Irp );
314 break;
315
316 //
317 // For Lock Control operations,
318 //
319
321
322 (VOID) FatCommonLockControl( IrpContext, Irp );
323 break;
324
325 //
326 // For Device Control operations,
327 //
328
330
331 (VOID) FatCommonDeviceControl( IrpContext, Irp );
332 break;
333
334 //
335 // For the Shutdown operation,
336 //
337
338 case IRP_MJ_SHUTDOWN:
339
340 (VOID) FatCommonShutdown( IrpContext, Irp );
341 break;
342
343 //
344 // For plug and play operations.
345 //
346
347 case IRP_MJ_PNP:
348
349 //
350 // I don't believe this should ever occur, but allow for the unexpected.
351 //
352
353 (VOID) FatCommonPnp( IrpContext, Irp );
354 break;
355
356 //
357 // For any other major operations, return an invalid
358 // request.
359 //
360
361 default:
362
364 break;
365
366 }
367
369
370 //
371 // We had some trouble trying to perform the requested
372 // operation, so we'll abort the I/O request with
373 // the error status that we get back from the
374 // execption code.
375 //
376
377 (VOID) FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
378 ExceptionCompletedIrp = TRUE;
379 } _SEH2_END;
380
382
384
385
386 if (MajorFunction == IRP_MJ_CREATE && !ExceptionCompletedIrp && Status != STATUS_PENDING) {
387
388 //
389 // Creates are completed here. IrpContext is also freed here.
390 //
391
392 FatCompleteRequest( IrpContext, Irp, Status );
393 }
394
395 //
396 // If there are any entries on this volume's overflow queue, service
397 // them.
398 //
399
400 if ( VolDo != NULL ) {
401
402 PVOID Entry;
403
404 //
405 // We have a volume device object so see if there is any work
406 // left to do in its overflow queue.
407 //
408
409 Entry = FatRemoveOverflowEntry( VolDo );
410
411 //
412 // There wasn't an entry, break out of the loop and return to
413 // the Ex Worker thread.
414 //
415
416 if ( Entry == NULL ) {
417
418 break;
419 }
420
421 //
422 // Extract the IrpContext, Irp, and IrpSp, and loop.
423 //
424
425 IrpContext = CONTAINING_RECORD( Entry,
427 WorkQueueItem.List );
428
430
431 Irp = IrpContext->OriginatingIrp;
432
434
435 continue;
436
437 } else {
438
439 break;
440 }
441 }
442
443 return;
444}
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_CONTEXT_FLAG_IN_FSP
Definition: cdstruc.h:1219
IRP_CONTEXT * PIRP_CONTEXT
Definition: cdstruc.h:1211
PVOID FatRemoveOverflowEntry(IN PVOLUME_DEVICE_OBJECT VolDo)
Definition: fspdisp.c:452
#define Dbg
Definition: fspdisp.c:32
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
base of all file and directory entries
Definition: entries.h:83
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
#define IRP_MJ_QUERY_EA
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MJ_SET_EA
#define IRP_MJ_FLUSH_BUFFERS

◆ FatFspMarkVolumeDirtyWithRecover()

VOID NTAPI FatFspMarkVolumeDirtyWithRecover ( PVOID  Parameter)

Definition at line 1098 of file verfysup.c.

1123{
1125 PVCB Vcb;
1126 IRP_CONTEXT IrpContext;
1127 PIRP Irp;
1128
1129 DebugTrace(+1, Dbg, "FatFspMarkVolumeDirtyWithRecover\n", 0);
1130
1132
1133 Vcb = Packet->Vcb;
1134 Irp = Packet->Irp;
1135
1136 //
1137 // Dummy up the IrpContext so we can call our worker routines
1138 //
1139
1140 RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT));
1141
1142 SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1143 IrpContext.OriginatingIrp = Irp;
1144
1145 //
1146 // Make us appear as a top level FSP request so that we will
1147 // receive any errors from the operation.
1148 //
1149
1151
1152 //
1153 // Try to write out the dirty bit. If something goes wrong, we
1154 // tried.
1155 //
1156
1157 _SEH2_TRY {
1158
1160
1161 FatMarkVolume( &IrpContext, Vcb, VolumeDirtyWithSurfaceTest );
1162
1164
1165 NOTHING;
1166 } _SEH2_END;
1167
1169
1170 //
1171 // Now complete the originating Irp or set the synchronous event.
1172 //
1173
1174 if (Packet->Event) {
1175 KeSetEvent( Packet->Event, 0, FALSE );
1176 } else {
1178 }
1179
1180 DebugTrace(-1, Dbg, "FatFspMarkVolumeDirtyWithRecover -> VOID\n", 0);
1181}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define Dbg
Definition: verfysup.c:29
struct _CLEAN_AND_DIRTY_VOLUME_PACKET * PCLEAN_AND_DIRTY_VOLUME_PACKET
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

◆ FatGetCurrentFatTime()

FAT_TIME_STAMP FatGetCurrentFatTime ( _In_ PIRP_CONTEXT  IrpContext)

Definition at line 317 of file timesup.c.

335{
339
340 PAGED_CODE();
341
342 //
343 // Get the current system time, and map it into a time field record.
344 //
345
347
349
350 //
351 // Always add almost two seconds to round up to the nearest double second.
352 //
353
355
357
358 //
359 // Now simply copy over the information
360 //
361
362 FatTime.Time.DoubleSeconds = (USHORT)(TimeFields.Second / 2);
363 FatTime.Time.Minute = (USHORT)(TimeFields.Minute);
364 FatTime.Time.Hour = (USHORT)(TimeFields.Hour);
365
366 FatTime.Date.Year = (USHORT)(TimeFields.Year - 1980);
367 FatTime.Date.Month = (USHORT)(TimeFields.Month);
368 FatTime.Date.Day = (USHORT)(TimeFields.Day);
369
370 UNREFERENCED_PARAMETER( IrpContext );
371
372 return FatTime;
373}
BOOLEAN RtlTimeToTimeFields(IN PLARGE_INTEGER Time, IN PTIME_FIELDS TimeFields)
#define ExSystemTimeToLocalTime(SysTime, LocTime)
Definition: env_spec_w32.h:729
#define AlmostTwoSeconds
Definition: fatdata.h:125

Referenced by FatConstructLabelDirent().

◆ FatGetNextFcbBottomUp()

PFCB FatGetNextFcbBottomUp ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
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 FatGetNextSibling(FILE)
Definition: fatprocs.h:1791
#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}

Referenced by _Requires_lock_held_(), and FatIsHandleCountZero().

◆ FatGetNextMcbEntry()

BOOLEAN FatGetNextMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN ULONG  RunIndex,
OUT PVBO  Vbo,
OUT PLBO  Lbo,
OUT PULONG  ByteCount 
)

Definition at line 541 of file fsctrl.c.

550{
551 BOOLEAN Results;
552 LONGLONG LiVbo;
553 LONGLONG LiLbo;
554 LONGLONG LiSectorCount;
555
556 PAGED_CODE();
557
558 LiVbo = LiLbo = 0;
559
561 RunIndex,
562 &LiVbo,
563 &LiLbo,
564 &LiSectorCount );
565
566 if (Results) {
567
568 *Vbo = ((VBO) LiVbo) << MCB_SCALE_LOG2;
569
570 if (((ULONG) LiLbo) != -1) {
571
572 *Lbo = ((LBO) LiLbo) << MCB_SCALE_LOG2;
573
574 } else {
575
576 *Lbo = 0;
577 }
578
579 *ByteCount = ((ULONG) LiSectorCount) << MCB_SCALE_LOG2;
580
581 if ((*ByteCount == 0) && (LiSectorCount != 0)) {
582
583 //
584 // If 'ByteCount' overflows, then this is likely a file of
585 // max supported size (2^32 - 1) in one contiguous run.
586 //
587
588 NT_ASSERT( RunIndex == 0 );
589
590 *ByteCount = 0xFFFFFFFF;
591 }
592 }
593
594 return Results;
595}
_Must_inspect_result_ _In_ ULONG RunIndex
Definition: fsrtlfuncs.h:538
BOOLEAN NTAPI FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount)
Definition: largemcb.c:392

Referenced by _Requires_lock_held_(), FatComputeMoveFileSplicePoints(), and FatPagingFileIo().

◆ FatHijackIrpAndFlushDevice()

NTSTATUS FatHijackIrpAndFlushDevice ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp,
IN PDEVICE_OBJECT  TargetDeviceObject 
)

Definition at line 1101 of file flush.c.

1130{
1131 KEVENT Event;
1133 PIO_STACK_LOCATION NextIrpSp;
1134
1135 PAGED_CODE();
1136
1137 UNREFERENCED_PARAMETER( IrpContext );
1138
1139 //
1140 // Get the next stack location, and copy over the stack location
1141 //
1142
1144
1145 NextIrpSp = IoGetNextIrpStackLocation( Irp );
1147 NextIrpSp->MinorFunction = 0;
1148
1149 //
1150 // Set up the completion routine
1151 //
1152
1154
1157 &Event,
1158 TRUE,
1159 TRUE,
1160 TRUE );
1161
1162 //
1163 // Send the request.
1164 //
1165
1167
1168 if (Status == STATUS_PENDING) {
1169
1171
1172 Status = Irp->IoStatus.Status;
1173 }
1174
1175 //
1176 // If the driver doesn't support flushes, return SUCCESS.
1177 //
1178
1181 }
1182
1183 Irp->IoStatus.Status = 0;
1184 Irp->IoStatus.Information = 0;
1185
1186 return Status;
1187}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
IO_COMPLETION_ROUTINE FatHijackCompletionRoutine
Definition: flush.c:57
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
#define IoCallDriver
Definition: irp.c:1225
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
@ Executive
Definition: ketypes.h:415

Referenced by _Requires_lock_held_(), FatFlushDirentForFile(), and FatFlushFatEntries().

◆ FatInitializeCacheMap()

VOID FatInitializeCacheMap ( _In_ PFILE_OBJECT  FileObject,
_In_ PCC_FILE_SIZES  FileSizes,
_In_ BOOLEAN  PinAccess,
_In_ PCACHE_MANAGER_CALLBACKS  Callbacks,
_In_ PVOID  LazyWriteContext 
)

Definition at line 62 of file cachesup.c.

78{
79 //
80 // Initialize caching
81 //
82
85 PinAccess,
87 LazyWriteContext );
88
89#if (NTDDI_VERSION >= NTDDI_WIN8)
90 //
91 // Enable Disk IO Accounting for this file
92 //
93
95
96 CcSetAdditionalCacheAttributesEx( FileObject, CC_ENABLE_DISK_IO_ACCOUNTING );
97 }
98#endif
99}
static CC_FILE_SIZES FileSizes
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
#define CC_ENABLE_DISK_IO_ACCOUNTING
Definition: btrfs_drv.h:1845
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195

Referenced by _Requires_lock_held_(), FatOpenEaFile(), and FatSetupAllocationSupport().

◆ FatInsertName()

VOID FatInsertName ( IN PIRP_CONTEXT  IrpContext,
IN PRTL_SPLAY_LINKS RootNode,
IN PFILE_NAME_NODE  Name 
)

Definition at line 39 of file splaysup.c.

66{
67 COMPARISON Comparison;
69
70 PAGED_CODE();
71
73
75
76 //
77 // If we are the first entry in the tree, just become the root.
78 //
79
80 if (*RootNode == NULL) {
81
82 *RootNode = &Name->Links;
83
84 return;
85 }
86
88
89 while (TRUE) {
90
91 //
92 // Compare the prefix in the tree with the prefix we want
93 // to insert. Note that Oem here doesn't mean anything.
94 //
95
96 Comparison = CompareNames(&Node->Name.Oem, &Name->Name.Oem);
97
98 //
99 // We should never find the name in the table already.
100 //
101
102 if (Comparison == IsEqual) {
103
104 //
105 // Almost. If the removable media was taken to another machine and
106 // back, and we have something like:
107 //
108 // Old: abcdef~1 / abcdefxyz
109 // New: abcdef~1 / abcdefxyzxyz
110 //
111 // but a handle was kept open to abcdefxyz so we couldn't purge
112 // away the Fcb in the verify path ... opening abcdefxyzxyz will
113 // try to insert a duplicate shortname. Bang!
114 //
115 // Invalidate it and the horse it came in on. This new one wins.
116 // The old one is gone. Only if the old one is in normal state
117 // do we really have a problem.
118 //
119
120 if (Node->Fcb->FcbState == FcbGood) {
121
122#ifdef _MSC_VER
123#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
124#endif
126 }
127
128 //
129 // Note, once we zap the prefix links we need to restart our walk
130 // of the tree. Note that we aren't properly synchronized to
131 // recursively mark bad.
132 //
133
134 FatMarkFcbCondition( IrpContext, Node->Fcb, FcbBad, FALSE );
135 FatRemoveNames( IrpContext, Node->Fcb );
136
137 goto Restart;
138 }
139
140 //
141 // If the tree prefix is greater than the new prefix then
142 // we go down the left subtree
143 //
144
145 if (Comparison == IsGreaterThan) {
146
147 //
148 // We want to go down the left subtree, first check to see
149 // if we have a left subtree
150 //
151
152 if (RtlLeftChild(&Node->Links) == NULL) {
153
154 //
155 // there isn't a left child so we insert ourselves as the
156 // new left child
157 //
158
159 RtlInsertAsLeftChild(&Node->Links, &Name->Links);
160
161 //
162 // and exit the while loop
163 //
164
165 break;
166
167 } else {
168
169 //
170 // there is a left child so simply go down that path, and
171 // go back to the top of the loop
172 //
173
176 Links );
177 }
178
179 } else {
180
181 //
182 // The tree prefix is either less than or a proper prefix
183 // of the new string. We treat both cases a less than when
184 // we do insert. So we want to go down the right subtree,
185 // first check to see if we have a right subtree
186 //
187
188 if (RtlRightChild(&Node->Links) == NULL) {
189
190 //
191 // These isn't a right child so we insert ourselves as the
192 // new right child
193 //
194
195 RtlInsertAsRightChild(&Node->Links, &Name->Links);
196
197 //
198 // and exit the while loop
199 //
200
201 break;
202
203 } else {
204
205 //
206 // there is a right child so simply go down that path, and
207 // go back to the top of the loop
208 //
209
212 Links );
213 }
214
215 }
216 }
217
218 return;
219}
@ FcbBad
Definition: cdstruc.h:780
VOID FatMarkFcbCondition(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN FCB_CONDITION FcbCondition, IN BOOLEAN Recursive)
@ Restart
Definition: sacdrv.h:269
VOID FatRemoveNames(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: splaysup.c:222
#define RtlInsertAsRightChild(ParentLinks, ChildLinks)
#define RtlInitializeSplayLinks(Links)
#define RtlInsertAsLeftChild(ParentLinks, ChildLinks)

Referenced by FatConstructNamesInFcb().

◆ FatInterpretClusterType()

CLUSTER_TYPE FatInterpretClusterType ( IN PVCB  Vcb,
IN FAT_ENTRY  Entry 
)

Definition at line 3473 of file allocsup.c.

3499{
3500 DebugTrace(+1, Dbg, "InterpretClusterType\n", 0);
3501 DebugTrace( 0, Dbg, " Vcb = %p\n", Vcb);
3502 DebugTrace( 0, Dbg, " Entry = %8lx\n", Entry);
3503
3504 PAGED_CODE();
3505
3506 switch(Vcb->AllocationSupport.FatIndexBitSize ) {
3507 case 32:
3509 break;
3510
3511 case 12:
3512 NT_ASSERT( Entry <= 0xfff );
3513 if (Entry >= 0x0ff0) {
3514 Entry |= 0x0FFFF000;
3515 }
3516 break;
3517
3518 default:
3519 case 16:
3520 NT_ASSERT( Entry <= 0xffff );
3521 if (Entry >= 0x0fff0) {
3522 Entry |= 0x0FFF0000;
3523 }
3524 break;
3525 }
3526
3528
3529 DebugTrace(-1, Dbg, "FatInterpretClusterType -> FatClusterAvailable\n", 0);
3530
3531 return FatClusterAvailable;
3532
3533 } else if (Entry < FAT_CLUSTER_RESERVED) {
3534
3535 DebugTrace(-1, Dbg, "FatInterpretClusterType -> FatClusterNext\n", 0);
3536
3537 return FatClusterNext;
3538
3539 } else if (Entry < FAT_CLUSTER_BAD) {
3540
3541 DebugTrace(-1, Dbg, "FatInterpretClusterType -> FatClusterReserved\n", 0);
3542
3543 return FatClusterReserved;
3544
3545 } else if (Entry == FAT_CLUSTER_BAD) {
3546
3547 DebugTrace(-1, Dbg, "FatInterpretClusterType -> FatClusterBad\n", 0);
3548
3549 return FatClusterBad;
3550
3551 } else {
3552
3553 DebugTrace(-1, Dbg, "FatInterpretClusterType -> FatClusterLast\n", 0);
3554
3555 return FatClusterLast;
3556 }
3557}
#define FAT_CLUSTER_BAD
Definition: fat.h:257
#define FAT_CLUSTER_RESERVED
Definition: fat.h:256
#define Dbg
Definition: allocsup.c:28
@ FatClusterLast
Definition: fatstruc.h:1750
@ FatClusterReserved
Definition: fatstruc.h:1748
@ FatClusterAvailable
Definition: fatstruc.h:1747
@ FatClusterNext
Definition: fatstruc.h:1751

Referenced by _Requires_lock_held_(), and FatExamineFatEntries().

◆ FatIsBootSectorFat()

BOOLEAN FatIsBootSectorFat ( IN PPACKED_BOOT_SECTOR  BootSector)

Definition at line 2522 of file fsctrl.c.

2542{
2544 BIOS_PARAMETER_BLOCK Bpb = {0};
2545
2546 DebugTrace(+1, Dbg, "FatIsBootSectorFat, BootSector = %p\n", BootSector);
2547
2548 //
2549 // The result is true unless we decide that it should be false
2550 //
2551
2552 Result = TRUE;
2553
2554 //
2555 // Unpack the bios and then test everything
2556 //
2557
2558 FatUnpackBios( &Bpb, &BootSector->PackedBpb );
2559 if (Bpb.Sectors != 0) { Bpb.LargeSectors = 0; }
2560
2561 if ((BootSector->Jump[0] != 0xe9) &&
2562 (BootSector->Jump[0] != 0xeb) &&
2563 (BootSector->Jump[0] != 0x49)) {
2564
2565 Result = FALSE;
2566
2567 //
2568 // Enforce some sanity on the sector size (easy check)
2569 //
2570
2571 } else if ((Bpb.BytesPerSector != 128) &&
2572 (Bpb.BytesPerSector != 256) &&
2573 (Bpb.BytesPerSector != 512) &&
2574 (Bpb.BytesPerSector != 1024) &&
2575 (Bpb.BytesPerSector != 2048) &&
2576 (Bpb.BytesPerSector != 4096)) {
2577
2578 Result = FALSE;
2579
2580 //
2581 // Likewise on the clustering.
2582 //
2583
2584 } else if ((Bpb.SectorsPerCluster != 1) &&
2585 (Bpb.SectorsPerCluster != 2) &&
2586 (Bpb.SectorsPerCluster != 4) &&
2587 (Bpb.SectorsPerCluster != 8) &&
2588 (Bpb.SectorsPerCluster != 16) &&
2589 (Bpb.SectorsPerCluster != 32) &&
2590 (Bpb.SectorsPerCluster != 64) &&
2591 (Bpb.SectorsPerCluster != 128)) {
2592
2593 Result = FALSE;
2594
2595 //
2596 // Likewise on the reserved sectors (must reflect at least the boot sector!)
2597 //
2598
2599 } else if (Bpb.ReservedSectors == 0) {
2600
2601 Result = FALSE;
2602
2603 //
2604 // No FATs? Wrong ...
2605 //
2606
2607 } else if (Bpb.Fats == 0) {
2608
2609 Result = FALSE;
2610
2611 //
2612 // Prior to DOS 3.2 might contains value in both of Sectors and
2613 // Sectors Large.
2614 //
2615
2616 } else if ((Bpb.Sectors == 0) && (Bpb.LargeSectors == 0)) {
2617
2618 Result = FALSE;
2619
2620 //
2621 // Check that FAT32 (SectorsPerFat == 0) claims some FAT space and
2622 // is of a version we recognize, currently Version 0.0.
2623 //
2624
2625 } else if (Bpb.SectorsPerFat == 0 && ( Bpb.LargeSectorsPerFat == 0 ||
2626 Bpb.FsVersion != 0 )) {
2627
2628 Result = FALSE;
2629
2630 } else if ((Bpb.Media != 0xf0) &&
2631 (Bpb.Media != 0xf8) &&
2632 (Bpb.Media != 0xf9) &&
2633 (Bpb.Media != 0xfb) &&
2634 (Bpb.Media != 0xfc) &&
2635 (Bpb.Media != 0xfd) &&
2636 (Bpb.Media != 0xfe) &&
2637 (Bpb.Media != 0xff) &&
2638 (!FatData.FujitsuFMR || ((Bpb.Media != 0x00) &&
2639 (Bpb.Media != 0x01) &&
2640 (Bpb.Media != 0xfa)))) {
2641
2642 Result = FALSE;
2643
2644 //
2645 // If this isn't FAT32, then there better be a claimed root directory
2646 // size here ...
2647 //
2648
2649 } else if (Bpb.SectorsPerFat != 0 && Bpb.RootEntries == 0) {
2650
2651 Result = FALSE;
2652
2653 //
2654 // If this is FAT32 (i.e., extended BPB), look for and refuse to mount
2655 // mirror-disabled volumes. If we did, we would need to only write to
2656 // the FAT# indicated in the ActiveFat field. The only user of this is
2657 // the FAT->FAT32 converter after the first pass of protected mode work
2658 // (booting into realmode) and NT should absolutely not be attempting
2659 // to mount such an in-transition volume.
2660 //
2661
2662 } else if (Bpb.SectorsPerFat == 0 && Bpb.MirrorDisabled) {
2663
2664 Result = FALSE;
2665 }
2666
2667 DebugTrace(-1, Dbg, "FatIsBootSectorFat -> %08lx\n", Result);
2668
2669 return Result;
2670}
#define FatUnpackBios(Bios, Pbios)
Definition: fat.h:136
#define Dbg
Definition: fsctrl.c:30
USHORT ReservedSectors
Definition: fat.h:106
USHORT BytesPerSector
Definition: fat.h:104
USHORT FsVersion
Definition: fat.h:126
USHORT Sectors
Definition: fat.h:109
ULONG MirrorDisabled
Definition: fat.h:122
ULONG32 LargeSectors
Definition: fat.h:115
ULONG32 LargeSectorsPerFat
Definition: fat.h:116
USHORT RootEntries
Definition: fat.h:108
UCHAR SectorsPerCluster
Definition: fat.h:105
USHORT SectorsPerFat
Definition: fat.h:111
BOOLEAN FujitsuFMR
Definition: fatstruc.h:95

◆ FatIsEaNameValid()

BOOLEAN FatIsEaNameValid ( IN PIRP_CONTEXT  IrpContext,
IN OEM_STRING  Name 
)

Definition at line 3429 of file easup.c.

3457{
3458 ULONG Index;
3459
3460 UCHAR Char;
3461
3462 PAGED_CODE();
3463
3464 UNREFERENCED_PARAMETER( IrpContext );
3465
3466 //
3467 // Empty names are not valid.
3468 //
3469
3470 if ( Name.Length == 0 ) { return FALSE; }
3471
3472 //
3473 // At this point we should only have a single name, which can't have
3474 // more than 254 characters
3475 //
3476
3477 if ( Name.Length > 254 ) { return FALSE; }
3478
3479 for ( Index = 0; Index < (ULONG)Name.Length; Index += 1 ) {
3480
3481 Char = Name.Buffer[ Index ];
3482
3483 //
3484 // Skip over and Dbcs chacters
3485 //
3486
3487 if ( FsRtlIsLeadDbcsCharacter( Char ) ) {
3488
3489 NT_ASSERT( Index != (ULONG)(Name.Length - 1) );
3490
3491 Index += 1;
3492
3493 continue;
3494 }
3495
3496 //
3497 // Make sure this character is legal, and if a wild card, that
3498 // wild cards are permissible.
3499 //
3500
3501 if ( !FsRtlIsAnsiCharacterLegalFat(Char, FALSE) ) {
3502
3503 return FALSE;
3504 }
3505 }
3506
3507 return TRUE;
3508}
#define FsRtlIsAnsiCharacterLegalFat(C, WILD)
Definition: fsrtlfuncs.h:1611
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by FatCommonSetEa().

◆ 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

◆ FatIsIoRangeValid()

static INLINE BOOLEAN FatIsIoRangeValid ( IN PVCB  Vcb,
IN LARGE_INTEGER  Start,
IN ULONG  Length 
)
static

Definition at line 218 of file fatprocs.h.

248{
249
251
252 //
253 // The only restriction on a FAT object is that the filesize must
254 // fit in 32bits, i.e. <= 0xffffffff. This then implies that the
255 // range of valid byte offsets is [0, fffffffe].
256 //
257 // Two phases which check for illegality
258 //
259 // - if the high 32bits are nonzero
260 // - if the length would cause a 32bit overflow
261 //
262
263 return !(Start.HighPart ||
264 Start.LowPart + Length < Start.LowPart);
265}
@ Start
Definition: partlist.h:33

Referenced by _Requires_lock_held_().

◆ FatIsIrpTopLevel()

BOOLEAN FatIsIrpTopLevel ( IN PIRP  Irp)

Definition at line 817 of file fatdata.c.

841{
842 PAGED_CODE();
843
844 if ( IoGetTopLevelIrp() == NULL ) {
845
847
848 return TRUE;
849
850 } else {
851
852 return FALSE;
853 }
854}

Referenced by _Function_class_(), and _Requires_lock_held_().

◆ FatIsNameInExpression()

BOOLEAN FatIsNameInExpression ( IN PIRP_CONTEXT  IrpContext,
IN OEM_STRING  Expression,
IN OEM_STRING  Name 
)

Definition at line 35 of file namesup.c.

64{
65 PAGED_CODE();
66
67 //
68 // Call the appropriate FsRtl routine do to the real work
69 //
70
72 &Name );
73
74 UNREFERENCED_PARAMETER( IrpContext );
75}
PCWSTR Expression
BOOLEAN NTAPI FsRtlIsDbcsInExpression(IN PANSI_STRING Expression, IN PANSI_STRING Name)
Definition: dbcsname.c:160

◆ FatIsNameLongUnicodeValid()

static INLINE BOOLEAN FatIsNameLongUnicodeValid ( PIRP_CONTEXT  IrpContext,
PUNICODE_STRING  Name,
BOOLEAN  CanContainWildcards,
BOOLEAN  PathNameOk,
BOOLEAN  LeadingBackslashOk 
)
static

Definition at line 1215 of file fatprocs.h.

1222{
1223 ULONG i;
1224
1225 UNREFERENCED_PARAMETER( IrpContext );
1226 UNREFERENCED_PARAMETER( LeadingBackslashOk );
1227 UNREFERENCED_PARAMETER( PathNameOk );
1228
1229 //
1230 // I'm not bothering to do the whole thing, just enough to make this call look
1231 // the same as the others.
1232 //
1233
1234 NT_ASSERT( !PathNameOk && !LeadingBackslashOk );
1235
1236 for (i=0; i < Name->Length/sizeof(WCHAR); i++) {
1237
1238 if ((Name->Buffer[i] < 0x80) &&
1239 !(FsRtlIsAnsiCharacterLegalHpfs(Name->Buffer[i], CanContainWildcards))) {
1240
1241 return FALSE;
1242 }
1243 }
1244
1245 return TRUE;
1246}
#define FsRtlIsAnsiCharacterLegalHpfs(C, WILD)
Definition: fsrtlfuncs.h:1614

◆ FatLocateEaByName()

BOOLEAN FatLocateEaByName ( IN PIRP_CONTEXT  IrpContext,
IN PPACKED_EA  FirstPackedEa,
IN ULONG  PackedEasLength,
IN POEM_STRING  EaName,
OUT PULONG  Offset 
)

Definition at line 3344 of file easup.c.

3377{
3378 PPACKED_EA PackedEa;
3380
3381 PAGED_CODE();
3382
3383 DebugTrace(+1, Dbg, "FatLocateEaByName, EaName = %Z\n", EaName);
3384
3385 //
3386 // For each packed ea in the list check its name against the
3387 // ea name we're searching for
3388 //
3389
3390 for ( *Offset = 0;
3391 *Offset < PackedEasLength;
3392 *Offset = FatLocateNextEa( IrpContext,
3393 FirstPackedEa,
3394 PackedEasLength,
3395 *Offset )) {
3396
3397 //
3398 // Reference the packed ea and get a string to its name
3399 //
3400
3401 PackedEa = (PPACKED_EA) ((PUCHAR) FirstPackedEa + *Offset);
3402
3403 Name.Buffer = &PackedEa->EaName[0];
3404 Name.Length = PackedEa->EaNameLength;
3405 Name.MaximumLength = PackedEa->EaNameLength;
3406
3407 //
3408 // Compare the two strings, if they are equal then we've
3409 // found the caller's ea
3410 //
3411
3412 if ( RtlCompareString( EaName, &Name, TRUE ) == 0 ) {
3413
3414 DebugTrace(-1, Dbg, "FatLocateEaByName -> TRUE, *Offset = %08lx\n", *Offset);
3415 return TRUE;
3416 }
3417 }
3418
3419 //
3420 // We've exhausted the ea list without finding a match so return false
3421 //
3422
3423 DebugTrace(-1, Dbg, "FatLocateEaByName -> FALSE\n", 0);
3424 return FALSE;
3425}
struct NameRec_ * Name
Definition: cdprocs.h:460
ULONG FatLocateNextEa(IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN ULONG PreviousOffset)
Definition: easup.c:3257
NTSYSAPI LONG NTAPI RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
UCHAR EaNameLength
Definition: fat.h:696

Referenced by FatCommonSetEa().

◆ FatLocateNextEa()

ULONG FatLocateNextEa ( IN PIRP_CONTEXT  IrpContext,
IN PPACKED_EA  FirstPackedEa,
IN ULONG  PackedEasLength,
IN ULONG  PreviousOffset 
)

Definition at line 3257 of file easup.c.

3291{
3292 PPACKED_EA PackedEa;
3293 ULONG PackedEaSize;
3294 ULONG Offset;
3295
3296 PAGED_CODE();
3297
3298 DebugTrace(+1, Dbg, "FatLocateNextEa, PreviousOffset = %08lx\n",
3299 PreviousOffset);
3300
3301 //
3302 // Make sure the previous offset is within the used size range
3303 //
3304
3305 if ( PreviousOffset >= PackedEasLength ) {
3306
3307 DebugTrace(-1, Dbg, "FatLocateNextEa -> 0xffffffff\n", 0);
3308 return 0xffffffff;
3309 }
3310
3311 //
3312 // Get a reference to the previous packed ea, and compute its size
3313 //
3314
3315 PackedEa = (PPACKED_EA) ((PUCHAR) FirstPackedEa + PreviousOffset );
3316 SizeOfPackedEa( PackedEa, &PackedEaSize );
3317
3318 //
3319 // Compute to the next ea
3320 //
3321
3322 Offset = PreviousOffset + PackedEaSize;
3323
3324 //
3325 // Now, if the new offset is beyond the ea size then we know
3326 // that there isn't one so, we return an offset of 0xffffffff.
3327 // otherwise we'll leave the new offset alone.
3328 //
3329
3330 if ( Offset >= PackedEasLength ) {
3331
3332 Offset = 0xffffffff;
3333 }
3334
3335 DebugTrace(-1, Dbg, "FatLocateNextEa -> %08lx\n", Offset);
3336
3337 UNREFERENCED_PARAMETER( IrpContext );
3338
3339 return Offset;
3340}

Referenced by FatLocateEaByName().

◆ FatLockUserBuffer()

VOID FatLockUserBuffer ( IN PIRP_CONTEXT  IrpContext,
IN OUT PIRP  Irp,
IN LOCK_OPERATION  Operation,
IN ULONG  BufferLength 
)

Definition at line 3276 of file deviosup.c.

3309{
3310 PMDL Mdl = NULL;
3311
3312 PAGED_CODE();
3313
3314 if (Irp->MdlAddress == NULL) {
3315
3316 //
3317 // Allocate the Mdl, and Raise if we fail.
3318 //
3319
3320 Mdl = IoAllocateMdl( Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp );
3321
3322 if (Mdl == NULL) {
3323
3325 }
3326
3327 //
3328 // Now probe the buffer described by the Irp. If we get an exception,
3329 // deallocate the Mdl and return the appropriate "expected" status.
3330 //
3331
3332 _SEH2_TRY {
3333
3335 Irp->RequestorMode,
3336 Operation );
3337
3339
3341
3343
3344 IoFreeMdl( Mdl );
3345 Irp->MdlAddress = NULL;
3346
3347 FatRaiseStatus( IrpContext,
3349 } _SEH2_END;
3350 }
3351
3352 UNREFERENCED_PARAMETER( IrpContext );
3353}
FP_OP Operation
Definition: fpcontrol.c:150
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl

Referenced by _Requires_lock_held_(), and FatPrePostIrp().

◆ FatLogOf()

UCHAR FatLogOf ( IN ULONG  Value)

Definition at line 4655 of file allocsup.c.

4676{
4677 UCHAR Log = 0;
4678
4679#if FASTFATDBG
4680 ULONG OrigValue = Value;
4681#endif
4682
4683 PAGED_CODE();
4684
4685 //
4686 // Knock bits off until we we get a one at position 0
4687 //
4688
4689 while ( (Value & 0xfffffffe) != 0 ) {
4690
4691 Log++;
4692 Value >>= 1;
4693 }
4694
4695 //
4696 // If there was more than one bit set, the file system messed up,
4697 // Bug Check.
4698 //
4699
4700 if (Value != 0x1) {
4701
4702 DebugTrace(+1, Dbg, "LogOf\n", 0);
4703 DebugTrace( 0, Dbg, " Value = %8lx\n", OrigValue);
4704
4705 DebugTrace( 0, Dbg, "Received non power of 2.\n", 0);
4706
4707 DebugTrace(-1, Dbg, "LogOf -> %8lx\n", Log);
4708
4709#ifdef _MSC_VER
4710#pragma prefast( suppress: 28159, "we bugcheck here because our internal data structures are seriously corrupted if this happens" )
4711#endif
4712 FatBugCheck( Value, Log, 0 );
4713 }
4714
4715 return Log;
4716}
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by FatSetupAllocationSupport().

◆ FatLookupFatEntry()

VOID FatLookupFatEntry ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN ULONG  FatIndex,
IN OUT PULONG  FatEntry,
IN OUT PFAT_ENUMERATION_CONTEXT  Context 
)

Definition at line 3565 of file allocsup.c.

3598{
3599 PAGED_CODE();
3600
3601 DebugTrace(+1, Dbg, "FatLookupFatEntry\n", 0);
3602 DebugTrace( 0, Dbg, " Vcb = %p\n", Vcb);
3603 DebugTrace( 0, Dbg, " FatIndex = %4x\n", FatIndex);
3604 DebugTrace( 0, Dbg, " FatEntry = %8lx\n", FatEntry);
3605
3606 //
3607 // Make sure they gave us a valid fat index.
3608 //
3609
3610 FatVerifyIndexIsValid(IrpContext, Vcb, FatIndex);
3611
3612 //
3613 // Case on 12 or 16 bit fats.
3614 //
3615 // In the 12 bit case (mostly floppies) we always have the whole fat
3616 // (max 6k bytes) pinned during allocation operations. This is possibly
3617 // a wee bit slower, but saves headaches over fat entries with 8 bits
3618 // on one page, and 4 bits on the next.
3619 //
3620 // The 16 bit case always keeps the last used page pinned until all
3621 // operations are done and it is unpinned.
3622 //
3623
3624 //
3625 // DEAL WITH 12 BIT CASE
3626 //
3627
3628 if (Vcb->AllocationSupport.FatIndexBitSize == 12) {
3629
3630 //
3631 // Check to see if the fat is already pinned, otherwise pin it.
3632 //
3633
3634 if (Context->Bcb == NULL) {
3635
3636 FatReadVolumeFile( IrpContext,
3637 Vcb,
3638 FatReservedBytes( &Vcb->Bpb ),
3639 FatBytesPerFat( &Vcb->Bpb ),
3640 &Context->Bcb,
3641 &Context->PinnedPage );
3642 }
3643
3644 //
3645 // Load the return value.
3646 //
3647
3648
3650
3651 } else if (Vcb->AllocationSupport.FatIndexBitSize == 32) {
3652
3653 //
3654 // DEAL WITH 32 BIT CASE
3655 //
3656
3657 ULONG PageEntryOffset;
3658 ULONG OffsetIntoVolumeFile;
3659
3660 //
3661 // Initialize two local variables that help us.
3662 //
3663 OffsetIntoVolumeFile = FatReservedBytes(&Vcb->Bpb) + FatIndex * sizeof(FAT_ENTRY);
3664 PageEntryOffset = (OffsetIntoVolumeFile % PAGE_SIZE) / sizeof(FAT_ENTRY);
3665
3666 //
3667 // Check to see if we need to read in a new page of fat
3668 //
3669
3670 if ((Context->Bcb == NULL) ||
3671 (OffsetIntoVolumeFile / PAGE_SIZE != Context->VboOfPinnedPage / PAGE_SIZE)) {
3672
3673 //
3674 // The entry wasn't in the pinned page, so must we unpin the current
3675 // page (if any) and read in a new page.
3676 //
3677
3678 FatUnpinBcb( IrpContext, Context->Bcb );
3679
3680 FatReadVolumeFile( IrpContext,
3681 Vcb,
3682 OffsetIntoVolumeFile & ~(PAGE_SIZE - 1),
3683 PAGE_SIZE,
3684 &Context->Bcb,
3685 &Context->PinnedPage );
3686
3687 Context->VboOfPinnedPage = OffsetIntoVolumeFile & ~(PAGE_SIZE - 1);
3688 }
3689
3690 //
3691 // Grab the fat entry from the pinned page, and return
3692 //
3693
3694 *FatEntry = ((PULONG)(Context->PinnedPage))[PageEntryOffset] & FAT32_ENTRY_MASK;
3695
3696 } else {
3697
3698 //
3699 // DEAL WITH 16 BIT CASE
3700 //
3701
3702 ULONG PageEntryOffset;
3703 ULONG OffsetIntoVolumeFile;
3704
3705 //
3706 // Initialize two local variables that help us.
3707 //
3708
3709 OffsetIntoVolumeFile = FatReservedBytes(&Vcb->Bpb) + FatIndex * sizeof(USHORT);
3710 PageEntryOffset = (OffsetIntoVolumeFile % PAGE_SIZE) / sizeof(USHORT);
3711
3712 //
3713 // Check to see if we need to read in a new page of fat
3714 //
3715
3716 if ((Context->Bcb == NULL) ||
3717 (OffsetIntoVolumeFile / PAGE_SIZE != Context->VboOfPinnedPage / PAGE_SIZE)) {
3718
3719 //
3720 // The entry wasn't in the pinned page, so must we unpin the current
3721 // page (if any) and read in a new page.
3722 //
3723
3724 FatUnpinBcb( IrpContext, Context->Bcb );
3725
3726 FatReadVolumeFile( IrpContext,
3727 Vcb,
3728 OffsetIntoVolumeFile & ~(PAGE_SIZE - 1),
3729 PAGE_SIZE,
3730 &Context->Bcb,
3731 &Context->PinnedPage );
3732
3733 Context->VboOfPinnedPage = OffsetIntoVolumeFile & ~(PAGE_SIZE - 1);
3734 }
3735
3736 //
3737 // Grab the fat entry from the pinned page, and return
3738 //
3739
3740 *FatEntry = ((PUSHORT)(Context->PinnedPage))[PageEntryOffset];
3741 }
3742
3743 DebugTrace(-1, Dbg, "FatLookupFatEntry -> (VOID)\n", 0);
3744 return;
3745}
#define FatVerifyIndexIsValid(IC, V, I)
Definition: fat.h:532

Referenced by _Requires_lock_held_().

◆ FatLookupLastMcbEntry()

BOOLEAN FatLookupLastMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
OUT PVBO  Vbo,
OUT PLBO  Lbo,
OUT PULONG Index  OPTIONAL 
)

Definition at line 494 of file fsctrl.c.

502{
503 BOOLEAN Results;
504 LONGLONG LiVbo;
505 LONGLONG LiLbo;
506 ULONG LocalIndex;
507
508 PAGED_CODE();
509
510 LiVbo = LiLbo = 0;
511 LocalIndex = 0;
512
514 &LiVbo,
515 &LiLbo,
516 &LocalIndex );
517
518 *Vbo = ((VBO) LiVbo) << MCB_SCALE_LOG2;
519
520 if (((ULONG) LiLbo) != -1) {
521
522 *Lbo = ((LBO) LiLbo) << MCB_SCALE_LOG2;
523
524 *Lbo += (MCB_SCALE - 1);
525 *Vbo += (MCB_SCALE - 1);
526
527 } else {
528
529 *Lbo = 0;
530 }
531
532 if (Index) {
533 *Index = LocalIndex;
534 }
535
536 return Results;
537}
#define MCB_SCALE
BOOLEAN NTAPI FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, OUT PLONGLONG LargeVbn, OUT PLONGLONG LargeLbn, OUT PULONG Index)
Definition: largemcb.c:671

Referenced by _Requires_lock_held_().

◆ FatLookupMcbEntry()

BOOLEAN FatLookupMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN VBO  Vbo,
OUT PLBO  Lbo,
OUT PULONG ByteCount  OPTIONAL,
OUT PULONG Index  OPTIONAL 
)

Definition at line 418 of file fsctrl.c.

426{
427 BOOLEAN Results;
428 LONGLONG LiLbo;
429 LONGLONG LiSectorCount;
431
432 LiLbo = 0;
433 LiSectorCount = 0;
434
436
437 Results = FsRtlLookupLargeMcbEntry( Mcb,
438 (Vbo >> MCB_SCALE_LOG2),
439 &LiLbo,
440 ARGUMENT_PRESENT(ByteCount) ? &LiSectorCount : NULL,
441 NULL,
442 NULL,
443 Index );
444
445 if ((ULONG) LiLbo != -1) {
446
447 *Lbo = (((LBO) LiLbo) << MCB_SCALE_LOG2);
448
449 if (Results) {
450
451 *Lbo += Remainder;
452 }
453
454 } else {
455
456 *Lbo = 0;
457 }
458
460
461 *ByteCount = (ULONG) LiSectorCount;
462
463 if (*ByteCount) {
464
466
467 //
468 // If ByteCount overflows, then this is likely the case of
469 // a file of max-supported size (4GiB - 1), allocated in a
470 // single continuous run.
471 //
472
473 if (*ByteCount == 0) {
474
475 *ByteCount = 0xFFFFFFFF;
476 }
477
478 if (Results) {
479
481 }
482 }
483
484 }
485
486 return Results;
487}
#define MCB_SCALE_MODULO
BOOLEAN NTAPI FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn OPTIONAL, OUT PLONGLONG SectorCountFromLbn OPTIONAL, OUT PLONGLONG StartingLbn OPTIONAL, OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, OUT PULONG Index OPTIONAL)
Definition: largemcb.c:560
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3045

Referenced by _Requires_lock_held_(), FatComputeMoveFileSplicePoints(), and FatPagingFileIo().

◆ FatMapUserBuffer()

PVOID FatMapUserBuffer ( IN PIRP_CONTEXT  IrpContext,
IN OUT PIRP  Irp 
)

Definition at line 3357 of file deviosup.c.

3382{
3383 UNREFERENCED_PARAMETER( IrpContext );
3384
3385 PAGED_CODE();
3386
3387 //
3388 // If there is no Mdl, then we must be in the Fsd, and we can simply
3389 // return the UserBuffer field from the Irp.
3390 //
3391
3392 if (Irp->MdlAddress == NULL) {
3393
3394 return Irp->UserBuffer;
3395
3396 } else {
3397
3398 PVOID Address = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute );
3399
3400 if (Address == NULL) {
3401
3403 }
3404
3405 return Address;
3406 }
3407}
@ NormalPagePriority
Definition: imports.h:56
static WCHAR Address[46]
Definition: ping.c:68
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

Referenced by _Requires_lock_held_(), FatBufferUserBuffer(), and FatCommonQueryEa().

◆ FatMarkEaRangeDirty()

VOID FatMarkEaRangeDirty ( IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  EaFileObject,
IN OUT PEA_RANGE  EaRange 
)

Definition at line 3709 of file easup.c.

3735{
3736 PBCB *NextBcb;
3737 ULONG BcbCount;
3738
3739 PAGED_CODE();
3740
3741 UNREFERENCED_PARAMETER( IrpContext );
3742
3743 //
3744 // If there is an auxilary buffer we need to copy the data back into the cache.
3745 //
3746
3747 if (EaRange->AuxilaryBuffer == TRUE) {
3748
3749 LARGE_INTEGER LargeVbo;
3750
3751 LargeVbo.QuadPart = EaRange->StartingVbo;
3752
3753 CcCopyWrite( EaFileObject,
3754 &LargeVbo,
3755 EaRange->Length,
3756 TRUE,
3757 EaRange->Data );
3758 }
3759
3760 //
3761 // Now walk through the Bcb chain and mark everything dirty.
3762 //
3763
3764 BcbCount = EaRange->BcbChainLength;
3765 NextBcb = EaRange->BcbChain;
3766
3767 while (BcbCount--) {
3768
3769 if (*NextBcb != NULL) {
3770
3771 CcSetDirtyPinnedData( *NextBcb, NULL );
3772 }
3773
3774 NextBcb += 1;
3775 }
3776
3777 return;
3778}
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129

Referenced by FatCommonSetEa().

◆ FatMarkFcbCondition()

VOID FatMarkFcbCondition ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN FCB_CONDITION  FcbCondition,
IN BOOLEAN  Recursive 
)

Referenced by FatInsertName().

◆ FatMultipleAsync()

VOID FatMultipleAsync ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PIRP  Irp,
IN ULONG  MultipleIrpCount,
IN PIO_RUN  IoRuns 
)

Definition at line 1622 of file deviosup.c.

1680{
1681 PIRP Irp;
1683 PMDL Mdl;
1684 BOOLEAN Wait;
1686#ifndef __REACTOS__
1687 BOOLEAN IsAWrite = FALSE;
1688 ULONG Length = 0;
1689#endif
1690
1691 ULONG UnwindRunCount = 0;
1692
1693 BOOLEAN ExceptionExpected = TRUE;
1694
1695 PAGED_CODE();
1696
1697 DebugTrace(+1, Dbg, "FatMultipleAsync\n", 0);
1698 DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
1699 DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
1700 DebugTrace( 0, Dbg, "MasterIrp = %p\n", MasterIrp );
1701 DebugTrace( 0, Dbg, "MultipleIrpCount = %08lx\n", MultipleIrpCount );
1702 DebugTrace( 0, Dbg, "IoRuns = %08lx\n", IoRuns );
1703
1704 //
1705 // If this I/O originating during FatVerifyVolume, bypass the
1706 // verify logic.
1707 //
1708
1709 if (Vcb->VerifyThread == KeGetCurrentThread()) {
1710
1711 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
1712 }
1713
1714 //
1715 // Set up things according to whether this is truely async.
1716 //
1717
1718 Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
1719
1720 Context = IrpContext->FatIoContext;
1721
1722 //
1723 // Finish initializing Context, for use in Read/Write Multiple Asynch.
1724 //
1725
1726 Context->MasterIrp = MasterIrp;
1727
1728 IrpSp = IoGetCurrentIrpStackLocation( MasterIrp );
1729#ifndef __REACTOS__
1730 IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
1731 Length = IrpSp->Parameters.Read.Length;
1732#endif
1733
1734 _SEH2_TRY {
1735
1736 //
1737 // Itterate through the runs, doing everything that can fail
1738 //
1739
1740 for ( UnwindRunCount = 0;
1741 UnwindRunCount < MultipleIrpCount;
1742 UnwindRunCount++ ) {
1743
1744 //
1745 // Create an associated IRP, making sure there is one stack entry for
1746 // us, as well.
1747 //
1748
1749 IoRuns[UnwindRunCount].SavedIrp = 0;
1750
1751 Irp = IoMakeAssociatedIrp( MasterIrp,
1752 (CCHAR)(Vcb->TargetDeviceObject->StackSize + 1) );
1753
1754 if (Irp == NULL) {
1755
1757 }
1758
1759 IoRuns[UnwindRunCount].SavedIrp = Irp;
1760
1761 //
1762 // Allocate and build a partial Mdl for the request.
1763 //
1764
1765 Mdl = IoAllocateMdl( (PCHAR)MasterIrp->UserBuffer +
1766 IoRuns[UnwindRunCount].Offset,
1767 IoRuns[UnwindRunCount].ByteCount,
1768 FALSE,
1769 FALSE,
1770 Irp );
1771
1772 if (Mdl == NULL) {
1773
1775 }
1776
1777 //
1778 // Sanity Check
1779 //
1780
1781 NT_ASSERT( Mdl == Irp->MdlAddress );
1782
1783 IoBuildPartialMdl( MasterIrp->MdlAddress,
1784 Mdl,
1785 (PCHAR)MasterIrp->UserBuffer +
1786 IoRuns[UnwindRunCount].Offset,
1787 IoRuns[UnwindRunCount].ByteCount );
1788
1789 //
1790 // Get the first IRP stack location in the associated Irp
1791 //
1792
1795
1796 //
1797 // Setup the Stack location to describe our read.
1798 //
1799
1800 IrpSp->MajorFunction = IrpContext->MajorFunction;
1801 IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].ByteCount;
1802 IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].Vbo;
1803
1804 //
1805 // Set up the completion routine address in our stack frame.
1806 //
1807
1809 Wait ?
1812 Context,
1813 TRUE,
1814 TRUE,
1815 TRUE );
1816
1817 //
1818 // Setup the next IRP stack location in the associated Irp for the disk
1819 // driver beneath us.
1820 //
1821
1823
1824 //
1825 // Setup the Stack location to do a read from the disk driver.
1826 //
1827
1828 IrpSp->MajorFunction = IrpContext->MajorFunction;
1829 IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].ByteCount;
1830 IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].Lbo;
1831
1832 //
1833 // If this Irp is the result of a WriteThough operation,
1834 // tell the device to write it through.
1835 //
1836
1837 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH )) {
1838
1840 }
1841
1842 //
1843 // If this I/O requires override verify, bypass the verify logic.
1844 //
1845
1846 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
1847
1849 }
1850 }
1851
1852 //
1853 // Now we no longer expect an exception. If the driver raises, we
1854 // must bugcheck, because we do not know how to recover from that
1855 // case.
1856 //
1857
1858 ExceptionExpected = FALSE;
1859
1860 //
1861 // We only need to set the associated IRP count in the master irp to
1862 // make it a master IRP. But we set the count to one more than our
1863 // caller requested, because we do not want the I/O system to complete
1864 // the I/O. We also set our own count.
1865 //
1866
1867 Context->IrpCount = MultipleIrpCount;
1868 MasterIrp->AssociatedIrp.IrpCount = MultipleIrpCount;
1869
1870 if (Wait) {
1871
1872 MasterIrp->AssociatedIrp.IrpCount += 1;
1873 }
1874 else if (FlagOn( Context->Wait.Async.ResourceThreadId, 3 )) {
1875
1876 //
1877 // For async requests if we acquired locks, transition the lock owners to an
1878 // object, since when we return this thread could go away before request
1879 // completion, and the resource package may try to boost priority.
1880 //
1881
1882 if (Context->Wait.Async.Resource != NULL) {
1883
1884 ExSetResourceOwnerPointer( Context->Wait.Async.Resource,
1885 (PVOID)Context->Wait.Async.ResourceThreadId );
1886 }
1887
1888 if (Context->Wait.Async.Resource2 != NULL) {
1889
1890 ExSetResourceOwnerPointer( Context->Wait.Async.Resource2,
1891 (PVOID)Context->Wait.Async.ResourceThreadId );
1892 }
1893 }
1894
1895 //
1896 // Back up a copy of the IrpContext flags for later use in async completion.
1897 //
1898
1899 Context->IrpContextFlags = IrpContext->Flags;
1900
1901 //
1902 // Now that all the dangerous work is done, issue the read requests
1903 //
1904
1905 for (UnwindRunCount = 0;
1906 UnwindRunCount < MultipleIrpCount;
1907 UnwindRunCount++) {
1908
1909 Irp = IoRuns[UnwindRunCount].SavedIrp;
1910
1911 DebugDoit( FatIoCallDriverCount += 1);
1912
1913 //
1914 // If IoCallDriver returns an error, it has completed the Irp
1915 // and the error will be caught by our completion routines
1916 // and dealt with as a normal IO error.
1917 //
1918
1919 (VOID)FatLowLevelReadWrite( IrpContext,
1920 Vcb->TargetDeviceObject,
1921 Irp,
1922 Vcb );
1923 }
1924
1925 //
1926 // We just issued an IO to the storage stack, update the counters indicating so.
1927 //
1928
1930
1931 FatUpdateIOCountersPCW( IsAWrite, Length );
1932 }
1933
1934 } _SEH2_FINALLY {
1935
1936 ULONG i;
1937
1939
1940 //
1941 // Only allocating the spinlock, making the associated Irps
1942 // and allocating the Mdls can fail.
1943 //
1944
1945 if ( _SEH2_AbnormalTermination() ) {
1946
1947 //
1948 // If the driver raised, we are hosed. He is not supposed to raise,
1949 // and it is impossible for us to figure out how to clean up.
1950 //
1951
1952 if (!ExceptionExpected) {
1953 NT_ASSERT( ExceptionExpected );
1954#ifdef _MSC_VER
1955#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1956#endif
1957 FatBugCheck( 0, 0, 0 );
1958 }
1959
1960 //
1961 // Unwind
1962 //
1963
1964 for (i = 0; i <= UnwindRunCount; i++) {
1965
1966 if ( (Irp = IoRuns[i].SavedIrp) != NULL ) {
1967
1968 if ( Irp->MdlAddress != NULL ) {
1969
1970 IoFreeMdl( Irp->MdlAddress );
1971 }
1972
1973 IoFreeIrp( Irp );
1974 }
1975 }
1976 }
1977
1978 //
1979 // And return to our caller
1980 //
1981
1982 DebugTrace(-1, Dbg, "FatMultipleAsync -> VOID\n", 0);
1983 } _SEH2_END;
1984
1985 return;
1986}
#define FatLowLevelReadWrite(IRPCONTEXT, DO, IRP, VCB)
Definition: deviosup.c:163
VOID FatMultipleAsync(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PIRP MasterIrp, IN ULONG MultipleIrpCount, IN PIO_RUN IoRuns)
Definition: deviosup.c:1622
#define Dbg
Definition: deviosup.c:28
IO_COMPLETION_ROUTINE FatMultiSyncCompletionRoutine
Definition: deviosup.c:68
IO_COMPLETION_ROUTINE FatMultiAsyncCompletionRoutine
Definition: deviosup.c:78
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1574
#define KeGetCurrentThread
Definition: hal.h:55
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2050
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PIRP NTAPI IoMakeAssociatedIrp(IN PIRP Irp, IN CCHAR StackSize)
Definition: irp.c:1925
char CCHAR
Definition: typedefs.h:51
char * PCHAR
Definition: typedefs.h:51
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2680
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823

Referenced by _Requires_lock_held_(), and FatMultipleAsync().

◆ FatNoOpAcquire()

BOOLEAN NTAPI FatNoOpAcquire ( IN PVOID  Fcb,
IN BOOLEAN  Wait 
)

Definition at line 795 of file resrcsup.c.

819{
822
823 PAGED_CODE();
824
825 //
826 // This is a kludge because Cc is really the top level. We it
827 // enters the file system, we will think it is a resursive call
828 // and complete the request with hard errors or verify. It will
829 // have to deal with them, somehow....
830 //
831
833
835
836 return TRUE;
837}
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60

◆ FatNoOpRelease()

VOID NTAPI FatNoOpRelease ( IN PVOID  Fcb)

Definition at line 842 of file resrcsup.c.

863{
864 PAGED_CODE();
865
866 //
867 // Clear the kludge at this point.
868 //
869
871
873
875
876 return;
877}

◆ FatOpenEaFile()

PFILE_OBJECT FatOpenEaFile ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  EaFcb 
)

Definition at line 979 of file cachesup.c.

1000{
1001 PFILE_OBJECT EaFileObject = NULL;
1002 PDEVICE_OBJECT RealDevice;
1003
1004 PAGED_CODE();
1005
1006 DebugTrace(+1, Dbg, "FatOpenEaFile\n", 0);
1007 DebugTrace( 0, Dbg, "EaFcb = %p\n", EaFcb);
1008
1009 //
1010 // Create the special file object for the ea file, and set
1011 // up its pointers back to the Fcb and the section object pointer
1012 //
1013
1014 RealDevice = EaFcb->Vcb->CurrentDevice;
1015
1016 EaFileObject = IoCreateStreamFileObject( NULL, RealDevice );
1017
1018 _SEH2_TRY {
1019
1020 FatPreallocateCloseContext( IrpContext->Vcb);
1021
1022 FatSetFileObject( EaFileObject,
1023 EaFile,
1024 EaFcb,
1025 NULL );
1026
1027 //
1028 // Remember this internal, residual open.
1029 //
1030
1031 InterlockedIncrement( (LONG*)&(EaFcb->Vcb->InternalOpenCount) );
1032 InterlockedIncrement( (LONG*)&(EaFcb->Vcb->ResidualOpenCount) );
1033
1034 EaFileObject->SectionObjectPointer = &EaFcb->NonPaged->SectionObjectPointers;
1035
1036 EaFileObject->ReadAccess = TRUE;
1037 EaFileObject->WriteAccess = TRUE;
1038
1039 //
1040 // Finally check if we need to initialize the Cache Map for the
1041 // ea file. The size of the section we are going to map
1042 // the current allocation size for the Fcb.
1043 //
1044
1045 EaFcb->Header.ValidDataLength = FatMaxLarge;
1046
1047 FatInitializeCacheMap( EaFileObject,
1048 (PCC_FILE_SIZES)&EaFcb->Header.AllocationSize,
1049 TRUE,
1051 EaFcb );
1052
1053 CcSetAdditionalCacheAttributes( EaFileObject, TRUE, TRUE );
1054
1055 } _SEH2_FINALLY {
1056
1057 //
1058 // Drop the fileobject if we're raising. Two cases: couldn't get
1059 // the close context, and it is still an UnopenedFileObject, or
1060 // we lost trying to build the cache map - in which case we're
1061 // OK for the close context if we have to.
1062 //
1063
1065
1066 ObDereferenceObject( EaFileObject );
1067 }
1068 } _SEH2_END;
1069
1070 DebugTrace(-1, Dbg, "FatOpenEaFile -> %p\n", EaFileObject);
1071
1072 UNREFERENCED_PARAMETER( IrpContext );
1073
1074 return EaFileObject;
1075}
#define InterlockedIncrement
Definition: armddk.h:53
FatSetFileObject(FileObject, UserDirectoryOpen,(*Dcb), UnwindCcb=FatCreateCcb(IrpContext))
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
LARGE_INTEGER FatMaxLarge
Definition: fatdata.c:63
VOID FatPreallocateCloseContext(IN PVCB Vcb)
VOID NTAPI CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject, IN BOOLEAN DisableReadAhead, IN BOOLEAN DisableWriteBehind)
Definition: logsup.c:22
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3187
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: fatstruc.h:159

◆ FatOplockComplete()

VOID NTAPI FatOplockComplete ( IN PVOID  Context,
IN PIRP  Irp 
)

Definition at line 35 of file workque.c.

61{
62 PAGED_CODE();
63
64 //
65 // Check on the return value in the Irp.
66 //
67
68 if (Irp->IoStatus.Status == STATUS_SUCCESS) {
69
70 //
71 // Insert the Irp context in the workqueue.
72 //
73
75
76 //
77 // Otherwise complete the request.
78 //
79
80 } else {
81
82 FatCompleteRequest( (PIRP_CONTEXT) Context, Irp, Irp->IoStatus.Status );
83 }
84
85 return;
86}

Referenced by _Requires_lock_held_(), and FatSetRenameInfo().

◆ FatPagingFileIo()

VOID FatPagingFileIo ( IN PIRP  Irp,
IN PFCB  Fcb 
)

Definition at line 211 of file deviosup.c.

236{
237 //
238 // Declare some local variables for enumeration through the
239 // runs of the file.
240 //
241
242 VBO Vbo;
244
245 PMDL Mdl;
246 LBO NextLbo;
247 VBO NextVbo = 0;
248 ULONG NextByteCount;
249 ULONG RemainingByteCount;
250 BOOLEAN MustSucceed;
251
252 ULONG FirstIndex;
253 ULONG CurrentIndex;
254 ULONG LastIndex;
255
256 LBO LastLbo;
257 ULONG LastByteCount;
258
259 BOOLEAN MdlIsReserve = FALSE;
260 BOOLEAN IrpIsMaster = FALSE;
262 LONG IrpCount;
263
264 PIRP AssocIrp;
266 PIO_STACK_LOCATION NextIrpSp;
267 ULONG BufferOffset;
269
270#ifndef __REACTOS__
271 BOOLEAN IsAWrite = FALSE;
272#endif
273
274 DebugTrace(+1, Dbg, "FatPagingFileIo\n", 0);
275 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
276 DebugTrace( 0, Dbg, "Fcb = %p\n", Fcb );
277
279
280 //
281 // Initialize some locals.
282 //
283
284 BufferOffset = 0;
287
288 Vbo = IrpSp->Parameters.Read.ByteOffset.LowPart;
289 ByteCount = IrpSp->Parameters.Read.Length;
290#ifndef __REACTOS__
291 IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
292#endif
293
294 MustSucceed = FatLookupMcbEntry( Fcb->Vcb, &Fcb->Mcb,
295 Vbo,
296 &NextLbo,
297 &NextByteCount,
298 &FirstIndex);
299
300 //
301 // If this run isn't present, something is very wrong.
302 //
303
304 if (!MustSucceed) {
305
306#ifdef _MSC_VER
307#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
308#endif
310 }
311
312#if (NTDDI_VERSION >= NTDDI_WIN8)
313
314 //
315 // Charge the IO to paging file to current thread
316 //
317
319
320 PETHREAD ThreadIssuingIo = PsGetCurrentThread();
321 BOOLEAN IsWriteOperation = FALSE;
322
324 IsWriteOperation = TRUE;
325 }
326
327 PsUpdateDiskCounters( PsGetThreadProcess( ThreadIssuingIo ),
328 (IsWriteOperation ? 0 : ByteCount ), // bytes to read
329 (IsWriteOperation ? ByteCount : 0), // bytes to write
330 (IsWriteOperation ? 0 : 1), // # of reads
331 (IsWriteOperation ? 1 : 0), // # of writes
332 0 );
333 }
334#endif
335
336 // See if the write covers a single valid run, and if so pass
337 // it on.
338 //
339
340 if ( NextByteCount >= ByteCount ) {
341
342 DebugTrace( 0, Dbg, "Passing Irp on to Disk Driver\n", 0 );
343
344 //
345 // Setup the next IRP stack location for the disk driver beneath us.
346 //
347
348 NextIrpSp = IoGetNextIrpStackLocation( Irp );
349
350 NextIrpSp->MajorFunction = IrpSp->MajorFunction;
351 NextIrpSp->Parameters.Read.Length = ByteCount;
352 NextIrpSp->Parameters.Read.ByteOffset.QuadPart = NextLbo;
353
354 //
355 // Since this is Paging file IO, we'll just ignore the verify bit.
356 //
357
359
360 //
361 // Set up the completion routine address in our stack frame.
362 // This is only invoked on error or cancel, and just copies
363 // the error Status into master irp's iosb.
364 //
365 // If the error implies a media problem, it also enqueues a
366 // worker item to write out the dirty bit so that the next
367 // time we run we will do a autochk /r
368 //
369
372 Irp,
373 FALSE,
374 TRUE,
375 TRUE );
376
377 //
378 // Issue the read/write request
379 //
380 // If IoCallDriver returns an error, it has completed the Irp
381 // and the error will be dealt with as a normal IO error.
382 //
383
385
386 //
387 // We just issued an IO to the storage stack, update the counters indicating so.
388 //
389
391
393 }
394
395 DebugTrace(-1, Dbg, "FatPagingFileIo -> VOID\n", 0);
396 return;
397 }
398
399 //
400 // Find out how may runs there are.
401 //
402
403 MustSucceed = FatLookupMcbEntry( Fcb->Vcb, &Fcb->Mcb,
404 Vbo + ByteCount - 1,
405 &LastLbo,
406 &LastByteCount,
407 &LastIndex);
408
409 //
410 // If this run isn't present, something is very wrong.
411 //
412
413 if (!MustSucceed) {
414
415#ifdef _MSC_VER
416#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
417#endif
418 FatBugCheck( Vbo + ByteCount - 1, 1, 0 );
419 }
420
421 CurrentIndex = FirstIndex;
422
423 //
424 // Now set up the Irp->IoStatus. It will be modified by the
425 // multi-completion routine in case of error or verify required.
426 //
427
428 Irp->IoStatus.Status = STATUS_SUCCESS;
429 Irp->IoStatus.Information = ByteCount;
430
431 //
432 // Loop while there are still byte writes to satisfy. The way we'll work this
433 // is to hope for the best - one associated IRP per run, which will let us be
434 // completely async after launching all the IO.
435 //
436 // IrpCount will indicate the remaining number of associated Irps to launch.
437 //
438 // All we have to do is make sure IrpCount doesn't hit zero before we're building
439 // the very last Irp. If it is positive when we're done, it means we have to
440 // wait for the rest of the associated Irps to come back before we complete the
441 // master by hand.
442 //
443 // This will keep the master from completing early.
444 //
445
446 Irp->AssociatedIrp.IrpCount = IrpCount = LastIndex - FirstIndex + 1;
447
448 while (CurrentIndex <= LastIndex) {
449
450 //
451 // Reset this for unwinding purposes
452 //
453
454 AssocIrp = NULL;
455
456 //
457 // If next run is larger than we need, "ya get what ya need".
458 //
459
460 if (NextByteCount > ByteCount) {
461 NextByteCount = ByteCount;
462 }
463
464 RemainingByteCount = 0;
465
466 //
467 // Allocate and build a partial Mdl for the request.
468 //
469
470 Mdl = IoAllocateMdl( (PCHAR)Irp->UserBuffer + BufferOffset,
471 NextByteCount,
472 FALSE,
473 FALSE,
474 AssocIrp );
475
476 if (Mdl == NULL) {
477
478 //
479 // Pick up the reserve MDL
480 //
481
483
485 MdlIsReserve = TRUE;
486
487 //
488 // Trim to fit the size of the reserve MDL.
489 //
490
491 if (NextByteCount > FAT_RESERVE_MDL_SIZE * PAGE_SIZE) {
492
493 RemainingByteCount = NextByteCount - FAT_RESERVE_MDL_SIZE * PAGE_SIZE;
494 NextByteCount = FAT_RESERVE_MDL_SIZE * PAGE_SIZE;
495 }
496 }
497
498 IoBuildPartialMdl( Irp->MdlAddress,
499 Mdl,
500 (PCHAR)Irp->UserBuffer + BufferOffset,
501 NextByteCount );
502
503 //
504 // Now that we have properly bounded this piece of the transfer, it is
505 // time to read/write it. We can simplify life slightly by always
506 // re-using the master IRP for cases where we use the reserve MDL,
507 // since we'll always be synchronous for those and can use a single
508 // completion context on our local stack.
509 //
510 // We also must prevent ourselves from issuing an associated IRP that would
511 // complete the master UNLESS this is the very last IRP we'll issue.
512 //
513 // This logic looks a bit complicated, but is hopefully understandable.
514 //
515
516 if (!MdlIsReserve &&
517 (IrpCount != 1 ||
518 (CurrentIndex == LastIndex &&
519 RemainingByteCount == 0))) {
520
521 AssocIrp = IoMakeAssociatedIrp( Irp, (CCHAR)(DeviceObject->StackSize + 1) );
522 }
523
524 if (AssocIrp == NULL) {
525
526 AssocIrp = Irp;
527 IrpIsMaster = TRUE;
528
529 //
530 // We need to drain the associated Irps so we can reliably figure out if
531 // the master Irp is showing a failed status, in which case we bail out
532 // immediately - as opposed to putting the value in the status field in
533 // jeopardy due to our re-use of the master Irp.
534 //
535
536 while (Irp->AssociatedIrp.IrpCount != IrpCount) {
537
539 }
540
541 //
542 // Note that since we failed to launch this associated Irp, that the completion
543 // code at the bottom will take care of completing the master Irp.
544 //
545
546 if (!NT_SUCCESS(Irp->IoStatus.Status)) {
547
548 NT_ASSERT( IrpCount );
549 break;
550 }
551
552 } else {
553
554 //
555 // Indicate we used an associated Irp.
556 //
557
558 IrpCount -= 1;
559 }
560
561 //
562 // With an associated IRP, we must take over the first stack location so
563 // we can have one to put the completion routine on. When re-using the
564 // master IRP, its already there.
565 //
566
567 if (!IrpIsMaster) {
568
569 //
570 // Get the first IRP stack location in the associated Irp
571 //
572
573 IoSetNextIrpStackLocation( AssocIrp );
574 NextIrpSp = IoGetCurrentIrpStackLocation( AssocIrp );
575
576 //
577 // Setup the Stack location to describe our read.
578 //
579
580 NextIrpSp->MajorFunction = IrpSp->MajorFunction;
581 NextIrpSp->Parameters.Read.Length = NextByteCount;
582 NextIrpSp->Parameters.Read.ByteOffset.QuadPart = Vbo;
583
584 //
585 // We also need the VolumeDeviceObject in the Irp stack in case
586 // we take the failure path.
587 //
588
589 NextIrpSp->DeviceObject = IrpSp->DeviceObject;
590
591 } else {
592
593 //
594 // Save the MDL in the IRP and prepare the stack
595 // context for the completion routine.
596 //
597
599 Context.RestoreMdl = Irp->MdlAddress;
600 }
601
602 //
603 // And drop our Mdl into the Irp.
604 //
605
606 AssocIrp->MdlAddress = Mdl;
607
608 //
609 // Set up the completion routine address in our stack frame.
610 // For true associated IRPs, this is only invoked on error or
611 // cancel, and just copies the error Status into master irp's
612 // iosb.
613 //
614 // If the error implies a media problem, it also enqueues a
615 // worker item to write out the dirty bit so that the next
616 // time we run we will do a autochk /r
617 //
618
619 if (IrpIsMaster) {
620
621 IoSetCompletionRoutine( AssocIrp,
623 &Context,
624 TRUE,
625 TRUE,
626 TRUE );
627
628 } else {
629
630 IoSetCompletionRoutine( AssocIrp,
632 Irp,
633 FALSE,
634 TRUE,
635 TRUE );
636 }
637
638 //
639 // Setup the next IRP stack location for the disk driver beneath us.
640 //
641
642 NextIrpSp = IoGetNextIrpStackLocation( AssocIrp );
643
644 //
645 // Since this is paging file IO, we'll just ignore the verify bit.
646 //
647
649
650 //
651 // Setup the Stack location to do a read from the disk driver.
652 //
653
654 NextIrpSp->MajorFunction = IrpSp->MajorFunction;
655 NextIrpSp->Parameters.Read.Length = NextByteCount;
656 NextIrpSp->Parameters.Read.ByteOffset.QuadPart = NextLbo;
657
658 (VOID)IoCallDriver( DeviceObject, AssocIrp );
659
660 //
661 // We just issued an IO to the storage stack, update the counters indicating so.
662 //
663
665
666 FatUpdateIOCountersPCW( IsAWrite, (ULONG64)NextByteCount );
667 }
668
669 //
670 // Wait for the Irp in the catch case and drop the flags.
671 //
672
673 if (IrpIsMaster) {
674
676 IrpIsMaster = MdlIsReserve = FALSE;
677
678 //
679 // If the Irp is showing a failed status, there is no point in continuing.
680 // In doing so, we get to avoid squirreling away the failed status in case
681 // we were to re-use the master irp again.
682 //
683 // Note that since we re-used the master, we must not have issued the "last"
684 // associated Irp, and thus the completion code at the bottom will take care
685 // of that for us.
686 //
687
688 if (!NT_SUCCESS(Irp->IoStatus.Status)) {
689
690 NT_ASSERT( IrpCount );
691 break;
692 }
693 }
694
695 //
696 // Now adjust everything for the next pass through the loop.
697 //
698
699 Vbo += NextByteCount;
700 BufferOffset += NextByteCount;
701 ByteCount -= NextByteCount;
702
703 //
704 // Try to lookup the next run, if we are not done and we got
705 // all the way through the current run.
706 //
707
708 if (RemainingByteCount) {
709
710 //
711 // Advance the Lbo/Vbo if we have more to do in the current run.
712 //
713
714 NextLbo += NextByteCount;
715 NextVbo += NextByteCount;
716
717 NextByteCount = RemainingByteCount;
718
719 } else {
720
721 CurrentIndex += 1;
722
723 if ( CurrentIndex <= LastIndex ) {
724
725 NT_ASSERT( ByteCount != 0 );
726
728 CurrentIndex,
729 &NextVbo,
730 &NextLbo,
731 &NextByteCount );
732
733 NT_ASSERT( NextVbo == Vbo );
734 }
735 }
736 } // while ( CurrentIndex <= LastIndex )
737
738 //
739 // If we didn't get enough associated Irps going to make this asynchronous, we
740 // twiddle our thumbs and wait for those we did launch to complete.
741 //
742
743 if (IrpCount) {
744
745 while (Irp->AssociatedIrp.IrpCount != IrpCount) {
746
748 }
749
751 }
752
753 DebugTrace(-1, Dbg, "FatPagingFileIo -> VOID\n", 0);
754 return;
755}
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutineCatch
Definition: deviosup.c:128
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutine
Definition: deviosup.c:118
KEVENT FatReserveEvent
Definition: fatdata.c:123
LARGE_INTEGER Fat30Milliseconds
Definition: fatdata.c:70
PMDL FatReserveMdl
Definition: fatdata.c:119
#define FAT_RESERVE_MDL_SIZE
Definition: fatdata.h:70
BOOLEAN FatLookupMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount OPTIONAL, OUT PULONG Index OPTIONAL)
Definition: fsctrl.c:418
BOOLEAN FatGetNextMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount)
Definition: fsctrl.c:541
unsigned __int64 ULONG64
Definition: imports.h:198
@ SynchronizationEvent

Referenced by _Function_class_(), and FatOverflowPagingFileRead().

◆ FatPerformDevIoCtrl()

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 at line 3621 of file deviosup.c.

3666{
3668 PIRP Irp;
3669 KEVENT Event;
3670 IO_STATUS_BLOCK LocalIosb;
3671 PIO_STATUS_BLOCK IosbToUse = &LocalIosb;
3672
3673 PAGED_CODE();
3674
3675 UNREFERENCED_PARAMETER( IrpContext );
3676
3677 //
3678 // Check if the user gave us an Iosb.
3679 //
3680
3681 if (ARGUMENT_PRESENT( Iosb )) {
3682
3683 IosbToUse = Iosb;
3684 }
3685
3686 IosbToUse->Status = 0;
3687 IosbToUse->Information = 0;
3688
3690
3692 Device,
3698 &Event,
3699 IosbToUse );
3700
3701 if (Irp == NULL) {
3702
3704 }
3705
3706 if (OverrideVerify) {
3707
3709 }
3710
3712
3713 //
3714 // We check for device not ready by first checking Status
3715 // and then if status pending was returned, the Iosb status
3716 // value.
3717 //
3718
3719 if (Status == STATUS_PENDING) {
3720
3722 Executive,
3723 KernelMode,
3724 FALSE,
3726
3727 Status = IosbToUse->Status;
3728 }
3729
3730 return Status;
3731}
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:720

Referenced by _Requires_lock_held_(), and FatScanForDataTrack().

◆ FatPinEaRange()

VOID FatPinEaRange ( IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  VirtualEaFile,
IN PFCB  EaFcb,
IN OUT PEA_RANGE  EaRange,
IN ULONG  StartingVbo,
IN ULONG  Length,
IN NTSTATUS  ErrorStatus 
)

Definition at line 3512 of file easup.c.

3553{
3554 LARGE_INTEGER LargeVbo;
3556 PBCB *NextBcb;
3557 PVOID Buffer;
3558 PCHAR DestinationBuffer = NULL;
3559 BOOLEAN FirstPage = TRUE;
3560
3561 PAGED_CODE();
3562
3563 //
3564 // Verify that the entire read is contained within the Ea file.
3565 //
3566
3567 if (Length == 0
3568 || StartingVbo >= EaFcb->Header.AllocationSize.LowPart
3569 || (EaFcb->Header.AllocationSize.LowPart - StartingVbo) < Length) {
3570
3571 FatRaiseStatus( IrpContext, ErrorStatus );
3572 }
3573
3574 //
3575 // If the read will span a section, the system addresses may not be contiguous.
3576 // Allocate a separate buffer in this case.
3577 //
3578
3579 if (((StartingVbo & (EA_SECTION_SIZE - 1)) + Length) > EA_SECTION_SIZE) {
3580
3581 EaRange->Data = FsRtlAllocatePoolWithTag( PagedPool,
3582 Length,
3583 TAG_EA_DATA );
3584 EaRange->AuxilaryBuffer = TRUE;
3585
3586 DestinationBuffer = EaRange->Data;
3587
3588 } else {
3589
3590 //
3591 // PREfix correctly notes that if we don't decide here to have an aux buffer
3592 // and the flag is up in the EaRange, we'll party on random memory since
3593 // DestinationBuffer won't be set; however, this will never happen due to
3594 // initialization of ea ranges and the cleanup in UnpinEaRange.
3595 //
3596
3597 NT_ASSERT( EaRange->AuxilaryBuffer == FALSE );
3598 }
3599
3600
3601 //
3602 // If the read will require more pages than our structure will hold then
3603 // allocate an auxilary buffer. We have to figure the number of pages
3604 // being requested so we have to include the page offset of the first page of
3605 // the request.
3606 //
3607
3608 EaRange->BcbChainLength = (USHORT) (((StartingVbo & (PAGE_SIZE - 1)) + Length + PAGE_SIZE - 1) / PAGE_SIZE);
3609
3610 if (EaRange->BcbChainLength > EA_BCB_ARRAY_SIZE) {
3611
3612 EaRange->BcbChain = FsRtlAllocatePoolWithTag( PagedPool,
3613 sizeof( PBCB ) * EaRange->BcbChainLength,
3614 TAG_BCB );
3615
3616 RtlZeroMemory( EaRange->BcbChain, sizeof( PBCB ) * EaRange->BcbChainLength );
3617
3618 } else {
3619
3620 EaRange->BcbChain = (PBCB *) &EaRange->BcbArray;
3621 }
3622
3623 //
3624 // Store the byte range data in the Ea Range structure.
3625 //
3626
3627 EaRange->StartingVbo = StartingVbo;
3628 EaRange->Length = Length;
3629
3630 //
3631 // Compute the initial pin length.
3632 //
3633
3635
3636 //
3637 // For each page in the range; pin the page and update the Bcb count, copy to
3638 // the auxiliary buffer.
3639 //
3640
3641 NextBcb = EaRange->BcbChain;
3642
3643 while (Length != 0) {
3644
3645 //
3646 // Pin the page and remember the data start.
3647 //
3648
3649 LargeVbo.QuadPart = StartingVbo;
3650
3651 if (ByteCount > Length) {
3652
3653 ByteCount = Length;
3654 }
3655
3656 if (!CcPinRead( VirtualEaFile,
3657 &LargeVbo,
3658 ByteCount,
3659 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
3660 NextBcb,
3661 &Buffer )) {
3662
3663 //
3664 // Could not read the data without waiting (cache miss).
3665 //
3666
3667 FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
3668 }
3669
3670 //
3671 // Increment the Bcb pointer and copy to the auxilary buffer if necessary.
3672 //
3673
3674 NextBcb += 1;
3675
3676 if (EaRange->AuxilaryBuffer == TRUE) {
3677
3678 RtlCopyMemory( DestinationBuffer,
3679 Buffer,
3680 ByteCount );
3681
3682 DestinationBuffer = (PCHAR) Add2Ptr( DestinationBuffer, ByteCount );
3683 }
3684
3686 Length -= ByteCount;
3687
3688 //
3689 // If this is the first page then update the Ea Range structure.
3690 //
3691
3692 if (FirstPage) {
3693
3694 FirstPage = FALSE;
3696
3697 if (EaRange->AuxilaryBuffer == FALSE) {
3698
3699 EaRange->Data = Buffer;
3700 }
3701 }
3702 }
3703
3704 return;
3705}
#define TAG_BCB
Definition: nodetype.h:157
#define TAG_EA_DATA
Definition: nodetype.h:160
#define EA_SECTION_SIZE
Definition: easup.c:49
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:412
#define EA_BCB_ARRAY_SIZE
Definition: fatstruc.h:1717
#define Add2Ptr(PTR, INC)
#define PCHAR
Definition: match.c:90

Referenced by FatReadEaSet().

◆ FatPinMappedData()

VOID FatPinMappedData ( IN PIRP_CONTEXT  IrpContext,
IN PDCB  Dcb,
IN VBO  StartingVbo,
IN ULONG  ByteCount,
OUT PBCB Bcb 
)

Definition at line 1866 of file cachesup.c.

1892{
1894
1895 PAGED_CODE();
1896
1897 DebugTrace(+1, Dbg, "FatPinMappedData\n", 0);
1898 DebugTrace( 0, Dbg, "Dcb = %p\n", Dcb);
1899 DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo);
1900 DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
1901
1902 //
1903 // Call the Cache manager to perform the operation.
1904 //
1905
1906 Vbo.QuadPart = StartingVbo;
1907
1908 if (!CcPinMappedData( Dcb->Specific.Dcb.DirectoryFile,
1909 &Vbo,
1910 ByteCount,
1911 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
1912 Bcb )) {
1913
1914 //
1915 // Could not pin the data without waiting (cache miss).
1916 //
1917
1918 FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
1919 }
1920
1921 DebugTrace(-1, Dbg, "FatReadDirectoryFile -> VOID, *BCB = %p\n", *Bcb);
1922
1923 return;
1924}
BOOLEAN NTAPI CcPinMappedData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, IN OUT PVOID *Bcb)
Definition: pinsup.c:774

◆ FatPreallocateCloseContext()

VOID FatPreallocateCloseContext ( IN PVCB  Vcb)

Referenced by FatOpenEaFile().

◆ FatPrefetchPages()

NTSTATUS FatPrefetchPages ( IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  FileObject,
IN ULONG  StartingPage,
IN ULONG  PageCount 
)

Definition at line 1929 of file cachesup.c.

1935{
1936 IO_PRIORITY_INFO PriorityInformation = {0};
1937 MM_PREFETCH_FLAGS PrefetchFlags;
1938 ULONG PageNo;
1940
1941 PREAD_LIST ReadList = NULL;
1942
1943 UNREFERENCED_PARAMETER( IrpContext );
1944
1945 PAGED_CODE();
1946
1947 //
1948 // Succeed zero page prefetch requests.
1949 //
1950
1951 if (PageCount == 0) {
1952
1953 return STATUS_SUCCESS;
1954 }
1955
1956 //
1957 // Mm's prefetch API's "only" support fetching a ULONG worth of pages.
1958 // Make sure we don't overflow.
1959 //
1960
1961 ASSERT( PageCount < (PFN_NUMBER)MAXULONG );
1962
1963 IoInitializePriorityInfo( &PriorityInformation );
1964
1965 Status = IoRetrievePriorityInfo( IrpContext->OriginatingIrp,
1966 FileObject,
1967 IrpContext->OriginatingIrp->Tail.Overlay.Thread,
1968 &PriorityInformation );
1969
1970 if (!NT_SUCCESS( Status)) {
1971
1972 goto Cleanup;
1973 }
1974
1975 ReadList = ExAllocatePoolWithTag( PagedPool,
1976 FIELD_OFFSET( READ_LIST, List ) + PageCount * sizeof( FILE_SEGMENT_ELEMENT ),
1977 ' taF' );
1978
1979 if (ReadList == NULL) {
1980
1982 goto Cleanup;
1983 }
1984
1985 //
1986 // Call Mm to prefetch data.
1987 //
1988
1989 ReadList->FileObject = FileObject;
1990 ReadList->IsImage = FALSE;
1991 ReadList->NumberOfEntries = PageCount;
1992
1993 PrefetchFlags.AllFlags = 0;
1994 PrefetchFlags.Flags.Priority = PriorityInformation.PagePriority;
1995 PrefetchFlags.Flags.RepurposePriority = SYSTEM_PAGE_PRIORITY_LEVELS - 1;
1996 PrefetchFlags.Flags.PriorityProtection = 1;
1997 ReadList->List[0].Alignment = StartingPage * PAGE_SIZE;
1998 ReadList->List[0].Alignment |= PrefetchFlags.AllFlags;
1999
2000 for (PageNo = 1; PageNo < PageCount; PageNo++) {
2001
2002 ReadList->List[PageNo].Alignment = ReadList->List[PageNo-1].Alignment + PAGE_SIZE;
2003 }
2004
2005 Status = MmPrefetchPages( 1, &ReadList );
2006
2007Cleanup:
2008
2009 if (ReadList != NULL) {
2010
2011 ExFreePoolWithTag( ReadList, ' taF' );
2012 }
2013
2014 return Status;
2015}
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS NTAPI MmPrefetchPages(IN ULONG NumberOfLists, IN PREAD_LIST *ReadLists)
Definition: mdlsup.c:1655
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define SYSTEM_PAGE_PRIORITY_LEVELS
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG PagePriority
Definition: iotypes.h:7457
PFILE_OBJECT FileObject
Definition: mmtypes.h:186
FILE_SEGMENT_ELEMENT List[ANYSIZE_ARRAY]
Definition: mmtypes.h:189
ULONG NumberOfEntries
Definition: mmtypes.h:187
LOGICAL IsImage
Definition: mmtypes.h:188
#define MAXULONG
Definition: typedefs.h:251
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONGLONG Alignment
Definition: iotypes.h:5432
struct _MM_PREFETCH_FLAGS::@4131 Flags
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550

Referenced by FatExamineFatEntries().

◆ FatPrePostIrp()

VOID NTAPI FatPrePostIrp ( IN PVOID  Context,
IN PIRP  Irp 
)

Definition at line 91 of file workque.c.

116{
118 PIRP_CONTEXT IrpContext;
119
120 PAGED_CODE();
121
122 //
123 // If there is no Irp, we are done.
124 //
125
126 if (Irp == NULL) {
127
128 return;
129 }
130
132
133 IrpContext = (PIRP_CONTEXT) Context;
134
135 //
136 // If there is a STACK FatIoContext pointer, clean and NULL it.
137 //
138
139 if ((IrpContext->FatIoContext != NULL) &&
140 FlagOn(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT)) {
141
142 ClearFlag(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT);
143 IrpContext->FatIoContext = NULL;
144 }
145
146 //
147 // We need to lock the user's buffer, unless this is an MDL-read,
148 // in which case there is no user buffer.
149 //
150 // **** we need a better test than non-MDL (read or write)!
151
152 if (IrpContext->MajorFunction == IRP_MJ_READ ||
153 IrpContext->MajorFunction == IRP_MJ_WRITE) {
154
155 //
156 // If not an Mdl request, lock the user's buffer.
157 //
158
159 if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
160
161 FatLockUserBuffer( IrpContext,
162 Irp,
163 (IrpContext->MajorFunction == IRP_MJ_READ) ?
165 (IrpContext->MajorFunction == IRP_MJ_READ) ?
166 IrpSp->Parameters.Read.Length : IrpSp->Parameters.Write.Length );
167 }
168
169 //
170 // We also need to check whether this is a query file operation.
171 //
172
173 } else if (IrpContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL
174 && IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
175
176 FatLockUserBuffer( IrpContext,
177 Irp,
179 IrpSp->Parameters.QueryDirectory.Length );
180
181 //
182 // We also need to check whether this is a query ea operation.
183 //
184
185 } else if (IrpContext->MajorFunction == IRP_MJ_QUERY_EA) {
186
187 FatLockUserBuffer( IrpContext,
188 Irp,
190 IrpSp->Parameters.QueryEa.Length );
191
192 //
193 // We also need to check whether this is a set ea operation.
194 //
195
196 } else if (IrpContext->MajorFunction == IRP_MJ_SET_EA) {
197
198 FatLockUserBuffer( IrpContext,
199 Irp,
201 IrpSp->Parameters.SetEa.Length );
202
203 //
204 // These two FSCTLs use neither I/O, so check for them.
205 //
206
207 } else if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
208 (IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST) &&
209 ((IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_VOLUME_BITMAP) ||
210 (IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_RETRIEVAL_POINTERS))) {
211
212 FatLockUserBuffer( IrpContext,
213 Irp,
215 IrpSp->Parameters.FileSystemControl.OutputBufferLength );
216 }
217
218 //
219 // Mark that we've already returned pending to the user
220 //
221
223
224 return;
225}
VOID FatLockUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
Definition: deviosup.c:3276
IoMarkIrpPending(Irp)
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:95
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:94
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define IRP_MN_MDL
Definition: iotypes.h:4419
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864

Referenced by _Requires_lock_held_(), and FatFsdPostRequest().

◆ FatQuickVerifyVcb()

VOID FatQuickVerifyVcb ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 1662 of file verfysup.c.

1685{
1686 PAGED_CODE();
1687
1688 //
1689 // If the real device needs to be verified we'll set the
1690 // DeviceToVerify to be our real device and raise VerifyRequired.
1691 //
1692
1693 if (FlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME)) {
1694
1695 DebugTrace(0, Dbg, "The Vcb needs to be verified\n", 0);
1696
1697 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1698 Vcb->Vpb->RealDevice );
1699
1701 }
1702
1703 //
1704 // Based on the condition of the Vcb we'll either return to our
1705 // caller or raise an error condition
1706 //
1707
1708 switch (Vcb->VcbCondition) {
1709
1710 case VcbGood:
1711
1712 DebugTrace(0, Dbg, "The Vcb is good\n", 0);
1713
1714 //
1715 // Do a check here of an operation that would try to modify a
1716 // write protected media.
1717 //
1718
1719 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) &&
1720 ((IrpContext->MajorFunction == IRP_MJ_WRITE) ||
1721 (IrpContext->MajorFunction == IRP_MJ_SET_INFORMATION) ||
1722 (IrpContext->MajorFunction == IRP_MJ_SET_EA) ||
1723 (IrpContext->MajorFunction == IRP_MJ_FLUSH_BUFFERS) ||
1724 (IrpContext->MajorFunction == IRP_MJ_SET_VOLUME_INFORMATION) ||
1725 (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1726 IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST &&
1727 IoGetCurrentIrpStackLocation(IrpContext->OriginatingIrp)->Parameters.FileSystemControl.FsControlCode ==
1729
1730 //
1731 // Set the real device for the pop-up info, and set the verify
1732 // bit in the device object, so that we will force a verify
1733 // in case the user put the correct media back in.
1734 //
1735
1736
1737 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1738 Vcb->Vpb->RealDevice );
1739
1741
1743 }
1744
1745 break;
1746
1747 case VcbNotMounted:
1748
1749 DebugTrace(0, Dbg, "The Vcb is not mounted\n", 0);
1750
1751 //
1752 // Set the real device for the pop-up info, and set the verify
1753 // bit in the device object, so that we will force a verify
1754 // in case the user put the correct media back in.
1755 //
1756
1757 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1758 Vcb->Vpb->RealDevice );
1759
1760 FatRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
1761
1762 break;
1763
1764 case VcbBad:
1765
1766 DebugTrace(0, Dbg, "The Vcb is bad\n", 0);
1767
1768 if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DISMOUNTED )) {
1769
1771
1772 } else {
1773
1774 FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
1775 }
1776 break;
1777
1778 default:
1779
1780 DebugDump("Invalid VcbCondition\n", 0, Vcb);
1781#ifdef _MSC_VER
1782#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1783#endif
1784 FatBugCheck( Vcb->VcbCondition, 0, 0 );
1785 }
1786}
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
BOOLEAN FatMarkDevForVerifyIfVcbMounted(IN PVCB Vcb)
Definition: verfysup.c:213
#define VCB_STATE_FLAG_VOLUME_DISMOUNTED
Definition: fatstruc.h:572
@ VcbBad
Definition: fatstruc.h:225
#define FSCTL_MARK_VOLUME_DIRTY
Definition: nt_native.h:838
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140

Referenced by _Requires_lock_held_(), and FatVerifyVcb().

◆ FatReadEaSet()

VOID FatReadEaSet ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN USHORT  EaHandle,
IN POEM_STRING  FileName,
IN BOOLEAN  ReturnEntireSet,
OUT PEA_RANGE  EaSetRange 
)

Definition at line 1306 of file easup.c.

1350{
1351 ULONG BytesPerCluster = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster;
1352
1353 ULONG EaOffsetVbo;
1354 EA_RANGE EaOffsetRange;
1355 USHORT EaOffsetCluster;
1356
1357 EA_RANGE EaHeaderRange;
1358 PEA_FILE_HEADER EaHeader;
1359
1360 ULONG EaSetVbo;
1361 PEA_SET_HEADER EaSet;
1362
1363 ULONG CbList;
1364
1365 PAGED_CODE();
1366
1368
1369 DebugTrace(+1, Dbg, "FatReadEaSet\n", 0);
1370 DebugTrace( 0, Dbg, " Vcb = %p\n", Vcb);
1371
1372 //
1373 // Verify that the Ea index has a legal value. Raise status
1374 // STATUS_NONEXISTENT_EA_ENTRY if illegal.
1375 //
1376
1378 || EaHandle > MAX_EA_HANDLE) {
1379
1380 DebugTrace(-1, Dbg, "FatReadEaSet: Illegal handle value\n", 0);
1382 }
1383
1384 //
1385 // Verify that the virtual Ea file is large enough for us to read
1386 // the EaOffet table for this index.
1387 //
1388
1389 EaOffsetVbo = sizeof( EA_FILE_HEADER ) + (((ULONGLONG)EaHandle >> 7) << 8);
1390
1391 //
1392 // Zero the Ea range structures.
1393 //
1394
1395 RtlZeroMemory( &EaHeaderRange, sizeof( EA_RANGE ));
1396 RtlZeroMemory( &EaOffsetRange, sizeof( EA_RANGE ));
1397
1398 //
1399 // Use a try statement to clean up on exit.
1400 //
1401
1402 _SEH2_TRY {
1403
1404 //
1405 // Pin down the EA file header.
1406 //
1407
1408 FatPinEaRange( IrpContext,
1409 Vcb->VirtualEaFile,
1410 Vcb->EaFcb,
1411 &EaHeaderRange,
1412 0,
1413 sizeof( EA_FILE_HEADER ),
1415
1416 EaHeader = (PEA_FILE_HEADER) EaHeaderRange.Data;
1417
1418 //
1419 // Pin down the Ea offset table for the particular index.
1420 //
1421
1422 FatPinEaRange( IrpContext,
1423 Vcb->VirtualEaFile,
1424 Vcb->EaFcb,
1425 &EaOffsetRange,
1426 EaOffsetVbo,
1427 sizeof( EA_OFF_TABLE ),
1429
1430 //
1431 // Check if the specifific handle is currently being used.
1432 //
1433
1434 EaOffsetCluster = *((PUSHORT) EaOffsetRange.Data
1435 + (EaHandle & (MAX_EA_OFFSET_INDEX - 1)));
1436
1437 if (EaOffsetCluster == UNUSED_EA_HANDLE) {
1438
1439 DebugTrace(0, Dbg, "FatReadEaSet: Ea handle is unused\n", 0);
1441 }
1442
1443 //
1444 // Compute the file offset for the Ea data.
1445 //
1446
1447 EaSetVbo = (EaHeader->EaBaseTable[EaHandle >> 7] + EaOffsetCluster)
1448 << Vcb->AllocationSupport.LogOfBytesPerCluster;
1449
1450 //
1451 // Unpin the file header and offset table.
1452 //
1453
1454 FatUnpinEaRange( IrpContext, &EaHeaderRange );
1455 FatUnpinEaRange( IrpContext, &EaOffsetRange );
1456
1457 //
1458 // Pin the ea set.
1459 //
1460
1461 FatPinEaRange( IrpContext,
1462 Vcb->VirtualEaFile,
1463 Vcb->EaFcb,
1464 EaSetRange,
1465 EaSetVbo,
1466 BytesPerCluster,
1468
1469 //
1470 // Verify that the Ea set is valid and belongs to this index.
1471 // Raise STATUS_DATA_ERROR if there is a data conflict.
1472 //
1473
1474 EaSet = (PEA_SET_HEADER) EaSetRange->Data;
1475
1476 if (EaSet->Signature != EA_SET_SIGNATURE
1477 || EaSet->OwnEaHandle != EaHandle ) {
1478
1479 DebugTrace(0, Dbg, "FatReadEaSet: Ea set header is corrupt\n", 0);
1480 FatRaiseStatus( IrpContext, STATUS_DATA_ERROR );
1481 }
1482
1483 //
1484 // At this point we have pinned a single cluster of Ea data. If
1485 // this represents the entire Ea data for the Ea index, we are
1486 // done. Otherwise we need to check on the entire size of
1487 // of the Ea set header and whether it is contained in the allocated
1488 // size of the Ea virtual file. At that point we can unpin
1489 // the partial Ea set header and repin the entire header.
1490 //
1491
1492 CbList = GetcbList( EaSet );
1493
1494 if (ReturnEntireSet
1495 && CbList > BytesPerCluster ) {
1496
1497 //
1498 // Round up to the cluster size.
1499 //
1500
1501 CbList = (CbList + EA_CBLIST_OFFSET + BytesPerCluster - 1)
1502 & ~(BytesPerCluster - 1);
1503
1504 FatUnpinEaRange( IrpContext, EaSetRange );
1505
1506 RtlZeroMemory( EaSetRange, sizeof( EA_RANGE ));
1507
1508 FatPinEaRange( IrpContext,
1509 Vcb->VirtualEaFile,
1510 Vcb->EaFcb,
1511 EaSetRange,
1512 EaSetVbo,
1513 CbList,
1515 }
1516
1517 } _SEH2_FINALLY {
1518
1520
1521 //
1522 // Unpin the Ea base and offset tables if locked down.
1523 //
1524
1525 FatUnpinEaRange( IrpContext, &EaHeaderRange );
1526 FatUnpinEaRange( IrpContext, &EaOffsetRange );
1527
1528 DebugTrace(-1, Dbg, "FatReadEaSet: Exit\n", 0);
1529 } _SEH2_END;
1530
1531 return;
1532}
#define EA_CBLIST_OFFSET
Definition: fat.h:749
#define UNUSED_EA_HANDLE
Definition: fat.h:748
#define MAX_EA_HANDLE
Definition: fat.h:747
#define MAX_EA_OFFSET_INDEX
Definition: fat.h:751
struct _EA_FILE_HEADER EA_FILE_HEADER
#define EA_SET_SIGNATURE
Definition: fat.h:626
USHORT EA_OFF_TABLE[128]
Definition: fat.h:652
EA_FILE_HEADER * PEA_FILE_HEADER
Definition: fat.h:650
#define MIN_EA_HANDLE
Definition: fat.h:746
VOID FatPinEaRange(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT VirtualEaFile, IN PFCB EaFcb, IN OUT PEA_RANGE EaRange, IN ULONG StartingVbo, IN ULONG Length, IN NTSTATUS ErrorStatus)
Definition: easup.c:3512
#define STATUS_NONEXISTENT_EA_ENTRY
Definition: ntstatus.h:317
#define STATUS_DATA_ERROR
Definition: ntstatus.h:298
USHORT EaBaseTable[240]
Definition: fat.h:647
PCHAR Data
Definition: fatstruc.h:1721
USHORT OwnEaHandle
Definition: fat.h:665
USHORT Signature
Definition: fat.h:664
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by _Requires_lock_held_(), FatCommonQueryEa(), FatCommonSetEa(), and FatReadEaSet().

◆ FatReadVolumeFile()

VOID FatReadVolumeFile ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN VBO  StartingVbo,
IN ULONG  ByteCount,
OUT PBCB Bcb,
OUT PVOID Buffer 
)

Definition at line 102 of file cachesup.c.

138{
140
141 PAGED_CODE();
142
143 //
144 // Check to see that all references are within the Bios Parameter Block
145 // or the fat(s). A special case is made when StartingVbo == 0 at
146 // mounting time since we do not know how big the fat is.
147 //
148
149 NT_ASSERT( ((StartingVbo == 0) || ((StartingVbo + ByteCount) <= (ULONG)
150 (FatRootDirectoryLbo( &Vcb->Bpb ) + PAGE_SIZE))));
151
152 DebugTrace(+1, Dbg, "FatReadVolumeFile\n", 0);
153 DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb);
154 DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo);
155 DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
156
157 //
158 // Call the Cache manager to attempt the transfer.
159 //
160
161 Vbo.QuadPart = StartingVbo;
162
163 if (!CcMapData( Vcb->VirtualVolumeFile,
164 &Vbo,
165 ByteCount,
166 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
167 Bcb,
168 Buffer )) {
169
170 NT_ASSERT( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
171
172 //
173 // Could not read the data without waiting (cache miss).
174 //
175
176 FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
177 }
178
179 DbgDoit( IrpContext->PinCount += 1 )
180
181 DebugTrace(-1, Dbg, "FatReadVolumeFile -> VOID, *BCB = %p\n", *Bcb);
182
183 return;
184}
return
Definition: dirsup.c:529
#define FatRootDirectoryLbo(B)
Definition: fat.h:445
#define DbgDoit(X)
Definition: fatdata.h:336
GLdouble n
Definition: glext.h:7729
GLfloat GLfloat p
Definition: glext.h:8902
BOOLEAN NTAPI CcMapData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *BcbResult, OUT PVOID *Buffer)
Definition: pinsup.c:694

Referenced by FatCheckDirtyBit(), FatExamineFatEntries(), and FatLookupFatEntry().

◆ FatReleaseVolumeFromClose()

VOID FatReleaseVolumeFromClose ( IN PVOID  Vcb)

◆ FatRemoveMcbEntry()

VOID FatRemoveMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN VBO  Vbo,
IN ULONG  SectorCount 
)

Definition at line 599 of file fsctrl.c.

605{
606 PAGED_CODE();
607
608 if ((SectorCount) && (SectorCount != 0xFFFFFFFF)) {
609
610 SectorCount--;
612 SectorCount++;
613 }
614
616
617#if DBG
618 _SEH2_TRY {
619#endif
620
622 (LONGLONG) Vbo,
624
625#if DBG
626 } _SEH2_EXCEPT(FatBugCheckExceptionFilter( _SEH2_GetExceptionInformation() )) {
627
628 NOTHING;
629 } _SEH2_END;
630#endif
631
632}
VOID NTAPI FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount)
Definition: largemcb.c:905

Referenced by _Requires_lock_held_(), FatCloseEaFile(), and FatTearDownAllocationSupport().

◆ FatRemoveNames()

VOID FatRemoveNames ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb 
)

Definition at line 222 of file splaysup.c.

244{
245 PDCB Parent;
246 PRTL_SPLAY_LINKS NewRoot;
247
248 PAGED_CODE();
249 UNREFERENCED_PARAMETER( IrpContext );
250
252
253 //
254 // We used to assert this condition, but it really isn't good. If
255 // someone rapidly renames a directory multiple times and we can't
256 // flush the lower fcbs fast enough (that didn't go away synch.)
257 // well, well hit some of them again.
258 //
259 // NT_ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_NAMES_IN_SPLAY_TREE ));
260 //
261
263
264 //
265 // Delete the node short name.
266 //
267
268 NewRoot = RtlDelete(&Fcb->ShortName.Links);
269
270 Parent->Specific.Dcb.RootOemNode = NewRoot;
271
272 //
273 // Now check for the presence of long name and delete it.
274 //
275
277
278 NewRoot = RtlDelete(&Fcb->LongName.Oem.Links);
279
280 Parent->Specific.Dcb.RootOemNode = NewRoot;
281
283
285 }
286
288
289 NewRoot = RtlDelete(&Fcb->LongName.Unicode.Links);
290
291 Parent->Specific.Dcb.RootUnicodeNode = NewRoot;
292
294
296 }
297
299 }
300
301 return;
302}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
RTL_SPLAY_LINKS Links
Definition: fatstruc.h:710
NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlDelete(_In_ PRTL_SPLAY_LINKS Links)

Referenced by _Requires_lock_held_(), FatDeleteFcb(), FatInsertName(), and FatSetRenameInfo().

◆ FatRepinBcb()

VOID FatRepinBcb ( IN PIRP_CONTEXT  IrpContext,
IN PBCB  Bcb 
)

Definition at line 1317 of file cachesup.c.

1340{
1341 PREPINNED_BCBS Repinned;
1342 ULONG i;
1343
1344 PAGED_CODE();
1345
1346 DebugTrace(+1, Dbg, "FatRepinBcb\n", 0 );
1347 DebugTrace( 0, Dbg, "IrpContext = %p\n", IrpContext );
1348 DebugTrace( 0, Dbg, "Bcb = %p\n", Bcb );
1349
1350 //
1351 // The algorithm is to search the list of repinned records until
1352 // we either find a match for the bcb or we find a null slot.
1353 //
1354
1355 Repinned = &IrpContext->Repinned;
1356
1357 while (TRUE) {
1358
1359 //
1360 // For every entry in the repinned record check if the bcb's
1361 // match or if the entry is null. If the bcb's match then
1362 // we've done because we've already repinned this bcb, if
1363 // the entry is null then we know, because it's densely packed,
1364 // that the bcb is not in the list so add it to the repinned
1365 // record and repin it.
1366 //
1367
1368 for (i = 0; i < REPINNED_BCBS_ARRAY_SIZE; i += 1) {
1369
1370 if (Repinned->Bcb[i] == Bcb) {
1371
1372 DebugTrace(-1, Dbg, "FatRepinBcb -> VOID\n", 0 );
1373 return;
1374 }
1375
1376 if (Repinned->Bcb[i] == NULL) {
1377
1378 Repinned->Bcb[i] = Bcb;
1379 CcRepinBcb( Bcb );
1380
1381 DebugTrace(-1, Dbg, "FatRepinBcb -> VOID\n", 0 );
1382 return;
1383 }
1384 }
1385
1386 //
1387 // We finished checking one repinned record so now locate the next
1388 // repinned record, If there isn't one then allocate and zero out
1389 // a new one.
1390 //
1391
1392 if (Repinned->Next == NULL) {
1393
1395 sizeof(REPINNED_BCBS),
1397
1398 RtlZeroMemory( Repinned->Next, sizeof(REPINNED_BCBS) );
1399 }
1400
1401 Repinned = Repinned->Next;
1402 }
1403}
#define TAG_REPINNED_BCB
Definition: nodetype.h:169
#define REPINNED_BCBS_ARRAY_SIZE
Definition: fatstruc.h:1464
struct _REPINNED_BCBS * Next
Definition: fatstruc.h:1472
PBCB Bcb[REPINNED_BCBS_ARRAY_SIZE]
Definition: fatstruc.h:1481

◆ 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
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
#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

◆ FatSetFileObject()

VOID FatSetFileObject ( IN PFILE_OBJECT FileObject  OPTIONAL,
IN TYPE_OF_OPEN  TypeOfOpen,
IN PVOID  VcbOrFcbOrDcb,
IN PCCB Ccb  OPTIONAL 
)

Definition at line 39 of file filobsup.c.

70{
71 PAGED_CODE();
72
73 DebugTrace(+1, Dbg, "FatSetFileObject, FileObject = %p\n", FileObject );
74
76
77
79
80 ||
81
83 (NodeType(VcbOrFcbOrDcb) == FAT_NTC_FCB) &&
84 (Ccb != NULL))
85
86 ||
87
88 ((TypeOfOpen == EaFile) &&
89 (NodeType(VcbOrFcbOrDcb) == FAT_NTC_FCB) &&
90 (Ccb == NULL))
91
92 ||
93
95 ((NodeType(VcbOrFcbOrDcb) == FAT_NTC_DCB) || (NodeType(VcbOrFcbOrDcb) == FAT_NTC_ROOT_DCB)) &&
96 (Ccb != NULL))
97
98 ||
99
101 (NodeType(VcbOrFcbOrDcb) == FAT_NTC_VCB) &&
102 (Ccb != NULL))
103
104 ||
105
107 (NodeType(VcbOrFcbOrDcb) == FAT_NTC_VCB) &&
108 (Ccb == NULL))
109
110 ||
111
113 ((NodeType(VcbOrFcbOrDcb) == FAT_NTC_DCB) || (NodeType(VcbOrFcbOrDcb) == FAT_NTC_ROOT_DCB)) &&
114 (Ccb == NULL))
115 );
116
117
119
120 //
121 // If we were given an Fcb, Dcb, or Vcb, we have some processing to do.
122 //
123
124 NT_ASSERT((Ccb == NULL) || (NodeType(Ccb) == FAT_NTC_CCB));
125
126 if ( VcbOrFcbOrDcb != NULL ) {
127
128 //
129 // Set the Vpb field in the file object, and if we were given an
130 // Fcb or Dcb move the field over to point to the nonpaged Fcb/Dcb
131 //
132
133 if (NodeType(VcbOrFcbOrDcb) == FAT_NTC_VCB) {
134
135 FileObject->Vpb = ((PVCB)VcbOrFcbOrDcb)->Vpb;
136
137 } else {
138
139 FileObject->Vpb = ((PFCB)VcbOrFcbOrDcb)->Vcb->Vpb;
140
141 //
142 // If this is a temporary file, note it in the FcbState
143 //
144
145 if (FlagOn(((PFCB)VcbOrFcbOrDcb)->FcbState, FCB_STATE_TEMPORARY)) {
146
148 }
149 }
150 }
151
152 NT_ASSERT((Ccb == NULL) || (NodeType(Ccb) == FAT_NTC_CCB));
153
154 //
155 // Now set the fscontext fields of the file object
156 //
157
159
160 FileObject->FsContext = VcbOrFcbOrDcb;
161 FileObject->FsContext2 = Ccb;
162 }
163
164 NT_ASSERT((Ccb == NULL) || (NodeType(Ccb) == FAT_NTC_CCB));
165
166 //
167 // And return to our caller
168 //
169
170 DebugTrace(-1, Dbg, "FatSetFileObject -> VOID\n", 0);
171
172 return;
173}
#define FCB_STATE_TEMPORARY
Definition: fatstruc.h:1198
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1791

◆ FatSetFullNameInFcb()

VOID FatSetFullNameInFcb ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PFCB  Fcb,
_In_ PUNICODE_STRING  FinalName 
)

Definition at line 6718 of file create.c.

6747{
6748 PAGED_CODE();
6749
6750 UNREFERENCED_PARAMETER( IrpContext );
6751
6753
6754 //
6755 // Prefer the ExactCaseLongName of the file for this operation, if set. In
6756 // this way we avoid building the fullname with a short filename. Several
6757 // operations assume this - the FinalNameLength in particular is the Lfn
6758 // (if existant) length, and we use this to crack the fullname in paths
6759 // such as the FsRtlNotify caller.
6760 //
6761 // If the caller specified a particular name and it is short, it is the
6762 // case that the long name was set up.
6763 //
6764
6766
6768 FinalName = &Fcb->ExactCaseLongName;
6769 }
6770
6771 //
6772 // Special case the root.
6773 //
6774
6776
6778 Fcb->FullFileName.MaximumLength = sizeof(WCHAR) + FinalName->Length;
6779
6783
6784 Fcb->FullFileName.Buffer[0] = L'\\';
6785
6787 &FinalName->Buffer[0],
6788 FinalName->Length );
6789
6790 } else {
6791
6793
6794 Prefix = &Fcb->ParentDcb->FullFileName;
6795
6796 //
6797 // It is possible our parent's full filename is not set. Simply fail
6798 // this attempt.
6799 //
6800
6801 if (Prefix->Buffer == NULL) {
6802
6803 return;
6804 }
6805
6807 Fcb->FullFileName.MaximumLength = Prefix->Length + sizeof(WCHAR) + FinalName->Length;
6808
6812
6814 &Prefix->Buffer[0],
6815 Prefix->Length );
6816
6817 Fcb->FullFileName.Buffer[Prefix->Length / sizeof(WCHAR)] = L'\\';
6818
6819 RtlCopyMemory( &Fcb->FullFileName.Buffer[(Prefix->Length / sizeof(WCHAR)) + 1],
6820 &FinalName->Buffer[0],
6821 FinalName->Length );
6822
6823 }
6824}
PAGED_CODE()
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1630

Referenced by FatSetRenameInfo().

◆ FatSetupAllocationSupport()

VOID FatSetupAllocationSupport ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 359 of file allocsup.c.

380{
381 ULONG BitIndex;
382 ULONG ClustersDescribableByFat;
383
384 PAGED_CODE();
385
386 DebugTrace(+1, Dbg, "FatSetupAllocationSupport\n", 0);
387 DebugTrace( 0, Dbg, " Vcb = %p\n", Vcb);
388
389 //
390 // Compute a number of fields for Vcb.AllocationSupport
391 //
392
393 Vcb->AllocationSupport.RootDirectoryLbo = FatRootDirectoryLbo( &Vcb->Bpb );
394 Vcb->AllocationSupport.RootDirectorySize = FatRootDirectorySize( &Vcb->Bpb );
395
396 Vcb->AllocationSupport.FileAreaLbo = FatFileAreaLbo( &Vcb->Bpb );
397
398 Vcb->AllocationSupport.NumberOfClusters = FatNumberOfClusters( &Vcb->Bpb );
399
400 Vcb->AllocationSupport.FatIndexBitSize = FatIndexBitSize( &Vcb->Bpb );
401
402 Vcb->AllocationSupport.LogOfBytesPerSector = FatLogOf(Vcb->Bpb.BytesPerSector);
403 Vcb->AllocationSupport.LogOfBytesPerCluster = FatLogOf(FatBytesPerCluster( &Vcb->Bpb ));
404 Vcb->AllocationSupport.NumberOfFreeClusters = 0;
405
406
407 //
408 // Deal with a bug in DOS 5 format, if the Fat is not big enough to
409 // describe all the clusters on the disk, reduce this number. We expect
410 // that fat32 volumes will not have this problem.
411 //
412 // Turns out this was not a good assumption. We have to do this always now.
413 //
414
415 ClustersDescribableByFat = ( ((FatIsFat32(Vcb)? Vcb->Bpb.LargeSectorsPerFat :
416 Vcb->Bpb.SectorsPerFat) *
417 Vcb->Bpb.BytesPerSector * 8)
418 / FatIndexBitSize(&Vcb->Bpb) ) - 2;
419
420 if (Vcb->AllocationSupport.NumberOfClusters > ClustersDescribableByFat) {
421
422 Vcb->AllocationSupport.NumberOfClusters = ClustersDescribableByFat;
423 }
424
425 //
426 // Extend the virtual volume file to include the Fat
427 //
428
429 {
431
434 FatBytesPerFat( &Vcb->Bpb ));
436
437 if ( Vcb->VirtualVolumeFile->PrivateCacheMap == NULL ) {
438
439 FatInitializeCacheMap( Vcb->VirtualVolumeFile,
440 &FileSizes,
441 TRUE,
443 Vcb );
444
445 } else {
446
447 CcSetFileSizes( Vcb->VirtualVolumeFile, &FileSizes );
448 }
449 }
450
451 _SEH2_TRY {
452
453 if (FatIsFat32(Vcb) &&
454 Vcb->AllocationSupport.NumberOfClusters > MAX_CLUSTER_BITMAP_SIZE) {
455
456 Vcb->NumberOfWindows = (Vcb->AllocationSupport.NumberOfClusters +
459
460 } else {
461
462 Vcb->NumberOfWindows = 1;
463 }
464
466 Vcb->NumberOfWindows * sizeof(FAT_WINDOW),
468
469 RtlInitializeBitMap( &Vcb->FreeClusterBitMap,
470 NULL,
471 0 );
472
473 //
474 // Chose a FAT window to begin operation in.
475 //
476
477 if (Vcb->NumberOfWindows > 1) {
478
479 //
480 // Read the fat and count up free clusters. We bias by the two reserved
481 // entries in the FAT.
482 //
483
484 FatExamineFatEntries( IrpContext, Vcb,
485 2,
486 Vcb->AllocationSupport.NumberOfClusters + 2 - 1,
487 TRUE,
488 NULL,
489 NULL);
490
491
492 //
493 // Pick a window to begin allocating from
494 //
495
496 Vcb->CurrentWindow = &Vcb->Windows[ FatSelectBestWindow( Vcb)];
497
498 } else {
499
500 Vcb->CurrentWindow = &Vcb->Windows[0];
501
502 //
503 // Carefully bias ourselves by the two reserved entries in the FAT.
504 //
505
506 Vcb->CurrentWindow->FirstCluster = 2;
507 Vcb->CurrentWindow->LastCluster = Vcb->AllocationSupport.NumberOfClusters + 2 - 1;
508 }
509
510 //
511 // Now transition to the FAT window we have chosen.
512 //
513
514 FatExamineFatEntries( IrpContext, Vcb,
515 0,
516 0,
517 FALSE,
518 Vcb->CurrentWindow,
519 NULL);
520
521 //
522 // Now set the ClusterHint to the first free bit in our favorite
523 // window (except the ClusterHint is off by two).
524 //
525
526 Vcb->ClusterHint =
527 (BitIndex = RtlFindClearBits( &Vcb->FreeClusterBitMap, 1, 0 )) != -1 ?
528 BitIndex + 2 : 2;
529
530 } _SEH2_FINALLY {
531
533
534 //
535 // If we hit an exception, back out.
536 //
537
539
540 FatTearDownAllocationSupport( IrpContext, Vcb );
541 }
542 } _SEH2_END;
543
544 return;
545}
#define FatNumberOfClusters(B)
Definition: fat.h:482
#define FatFileAreaLbo(B)
Definition: fat.h:458
#define FatBytesPerCluster(B)
Definition: fat.h:408
#define FatRootDirectorySize(B)
Definition: fat.h:427
#define TAG_FAT_WINDOW
Definition: nodetype.h:166
VOID FatExamineFatEntries(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN ULONG StartIndex OPTIONAL, IN ULONG EndIndex OPTIONAL, IN BOOLEAN SetupWindows, IN PFAT_WINDOW SwitchToWindow OPTIONAL, IN PULONG BitMapBuffer OPTIONAL)
Definition: allocsup.c:4720
INLINE ULONG FatSelectBestWindow(IN PVCB Vcb)
Definition: allocsup.c:279
UCHAR FatLogOf(IN ULONG Value)
Definition: allocsup.c:4655
VOID FatSetupAllocationSupport(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: allocsup.c:359
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
NTSYSAPI ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP, ULONG, ULONG)
LARGE_INTEGER FileSize
Definition: cctypes.h:16
LARGE_INTEGER ValidDataLength
Definition: cctypes.h:17
LARGE_INTEGER AllocationSize
Definition: cctypes.h:15
CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks
Definition: fatstruc.h:160

Referenced by FatSetupAllocationSupport().

◆ FatSingleAsync()

VOID FatSingleAsync ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN LBO  Lbo,
IN ULONG  ByteCount,
IN PIRP  Irp 
)

Definition at line 1990 of file deviosup.c.

2027{
2030#ifndef __REACTOS__
2031 BOOLEAN IsAWrite = FALSE;
2032#endif
2033
2034 PAGED_CODE();
2035
2036 DebugTrace(+1, Dbg, "FatSingleAsync\n", 0);
2037 DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
2038 DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
2039 DebugTrace( 0, Dbg, "Lbo = %08lx\n", Lbo);
2040 DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
2041 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
2042
2043 //
2044 // If this I/O originating during FatVerifyVolume, bypass the
2045 // verify logic.
2046 //
2047
2048 if (Vcb->VerifyThread == KeGetCurrentThread()) {
2049
2050 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
2051 }
2052
2053 //
2054 // Set up the completion routine address in our stack frame.
2055 //
2056
2058 FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ?
2061 IrpContext->FatIoContext,
2062 TRUE,
2063 TRUE,
2064 TRUE );
2065
2066 //
2067 // Setup the next IRP stack location in the associated Irp for the disk
2068 // driver beneath us.
2069 //
2070
2072
2073 //
2074 // Setup the Stack location to do a read from the disk driver.
2075 //
2076
2077 IrpSp->MajorFunction = IrpContext->MajorFunction;
2078 IrpSp->Parameters.Read.Length = ByteCount;
2079 IrpSp->Parameters.Read.ByteOffset.QuadPart = Lbo;
2080
2081#ifndef __REACTOS__
2082 IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
2083#endif
2084
2085 //
2086 // If this Irp is the result of a WriteThough operation,
2087 // tell the device to write it through.
2088 //
2089
2090 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH )) {
2091
2093 }
2094
2095 //
2096 // If this I/O requires override verify, bypass the verify logic.
2097 //
2098
2099 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
2100
2102 }
2103
2104 //
2105 // For async requests if we acquired locks, transition the lock owners to an
2106 // object, since when we return this thread could go away before request
2107 // completion, and the resource package may try to boost priority.
2108 //
2109
2110 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ) &&
2111 FlagOn( IrpContext->FatIoContext->Wait.Async.ResourceThreadId, 3 )) {
2112
2113 Context = IrpContext->FatIoContext;
2114
2115 if (Context->Wait.Async.Resource != NULL) {
2116
2117 ExSetResourceOwnerPointer( Context->Wait.Async.Resource,
2118 (PVOID)Context->Wait.Async.ResourceThreadId );
2119 }
2120
2121 if (Context->Wait.Async.Resource2 != NULL) {
2122
2123 ExSetResourceOwnerPointer( Context->Wait.Async.Resource2,
2124 (PVOID)Context->Wait.Async.ResourceThreadId );
2125 }
2126 }
2127
2128 //
2129 // Back up a copy of the IrpContext flags for later use in async completion.
2130 //
2131
2132 IrpContext->FatIoContext->IrpContextFlags = IrpContext->Flags;
2133
2134 //
2135 // Issue the read request
2136 //
2137
2138 DebugDoit( FatIoCallDriverCount += 1);
2139
2140 //
2141 // If IoCallDriver returns an error, it has completed the Irp
2142 // and the error will be caught by our completion routines
2143 // and dealt with as a normal IO error.
2144 //
2145
2146 (VOID)FatLowLevelReadWrite( IrpContext,
2147 Vcb->TargetDeviceObject,
2148 Irp,
2149 Vcb );
2150
2151 //
2152 // We just issued an IO to the storage stack, update the counters indicating so.
2153 //
2154
2156
2157 FatUpdateIOCountersPCW( IsAWrite, ByteCount );
2158 }
2159
2160 //
2161 // And return to our caller
2162 //
2163
2164 DebugTrace(-1, Dbg, "FatSingleAsync -> VOID\n", 0);
2165
2166 return;
2167}
IO_COMPLETION_ROUTINE FatSingleAsyncCompletionRoutine
Definition: deviosup.c:108
IO_COMPLETION_ROUTINE FatSingleSyncCompletionRoutine
Definition: deviosup.c:98

Referenced by _Requires_lock_held_().

◆ FatSpaceInName()

BOOLEAN FatSpaceInName ( IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  UnicodeName 
)

Definition at line 1003 of file namesup.c.

1024{
1025 ULONG i;
1026
1027 PAGED_CODE();
1028 UNREFERENCED_PARAMETER( IrpContext );
1029
1030 for (i=0; i < UnicodeName->Length/sizeof(WCHAR); i++) {
1031
1032 if (UnicodeName->Buffer[i] == L' ') {
1033 return TRUE;
1034 }
1035 }
1036
1037 return FALSE;
1038}

Referenced by FatSetRenameInfo().

◆ FatStringTo8dot3()

VOID FatStringTo8dot3 ( _In_ PIRP_CONTEXT  IrpContext,
_In_ OEM_STRING  InputString,
_Out_writes_bytes_(11) PFAT8DOT3  Output8dot3 
)

Definition at line 79 of file namesup.c.

105{
106 ULONG i;
107 ULONG j;
108
109 PAGED_CODE();
110
111 DebugTrace(+1, Dbg, "FatStringTo8dot3\n", 0);
112 DebugTrace( 0, Dbg, "InputString = %Z\n", &InputString);
113
114 NT_ASSERT( InputString.Length <= 12 );
115
116 //
117 // Make the output name all blanks
118 //
119
120 RtlFillMemory( Output8dot3, 11, UCHAR_SP );
121
122 //
123 // Copy over the first part of the file name. Stop when we get to
124 // the end of the input string or a dot.
125 //
126
127 for (i = 0;
128 (i < (ULONG)InputString.Length) && (InputString.Buffer[i] != '.') && (i < 11);
129 i += 1) {
130
131 (*Output8dot3)[i] = InputString.Buffer[i];
132 }
133
134 //
135 // Check if we need to process an extension
136 //
137
138 if (i < (ULONG)InputString.Length) {
139
140 //
141 // Make sure we have a dot and then skip over it.
142 //
143
144 NT_ASSERT( (InputString.Length - i) <= 4 );
145 NT_ASSERT( InputString.Buffer[i] == '.' );
146
147 i += 1;
148
149 //
150 // Copy over the extension. Stop when we get to the
151 // end of the input string.
152 //
153
154 for (j = 8; (i < (ULONG)InputString.Length); j += 1, i += 1) {
155
156 (*Output8dot3)[j] = InputString.Buffer[i];
157 }
158 }
159
160 //
161 // Before we return check if we should translate the first character
162 // from 0xe5 to 0x5.
163 //
164
165 if ((*Output8dot3)[0] == 0xe5) {
166
167 (*Output8dot3)[0] = FAT_DIRENT_REALLY_0E5;
168 }
169
170 DebugTrace(-1, Dbg, "FatStringTo8dot3 -> (VOID)\n", 0);
171
172 UNREFERENCED_PARAMETER( IrpContext );
173
174 return;
175}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250

Referenced by _Requires_lock_held_(), FatConstructDirent(), and FatSetRenameInfo().

◆ FatSyncUninitializeCacheMap()

VOID FatSyncUninitializeCacheMap ( IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  FileObject 
)

Definition at line 1812 of file cachesup.c.

1831{
1832 CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent;
1833 NTSTATUS WaitStatus;
1834
1835 UNREFERENCED_PARAMETER( IrpContext );
1836
1837 PAGED_CODE();
1838
1839 KeInitializeEvent( &UninitializeCompleteEvent.Event,
1841 FALSE);
1842
1844 &FatLargeZero,
1845 &UninitializeCompleteEvent );
1846
1847 //
1848 // Now wait for the cache manager to finish purging the file.
1849 // This will garentee that Mm gets the purge before we
1850 // delete the Vcb.
1851 //
1852
1853#ifdef _MSC_VER
1854#pragma prefast( suppress: 28931, "we use WaitStatus in the debug assert, in fre builds prefast complains it's unused" )
1855#endif
1856 WaitStatus = KeWaitForSingleObject( &UninitializeCompleteEvent.Event,
1857 Executive,
1858 KernelMode,
1859 FALSE,
1860 NULL);
1861
1862 NT_ASSERT(WaitStatus == STATUS_SUCCESS);
1863}
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

Referenced by _Requires_lock_held_(), and FatCloseEaFile().

◆ FatTearDownAllocationSupport()

VOID FatTearDownAllocationSupport ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 549 of file allocsup.c.

572{
573 DebugTrace(+1, Dbg, "FatTearDownAllocationSupport\n", 0);
574 DebugTrace( 0, Dbg, " Vcb = %p\n", Vcb);
575
576 PAGED_CODE();
577
578 //
579 // If there are FAT buckets, free them.
580 //
581
582 if ( Vcb->Windows != NULL ) {
583
584 ExFreePool( Vcb->Windows );
585 Vcb->Windows = NULL;
586 }
587
588 //
589 // Free the memory associated with the free cluster bitmap.
590 //
591
592 if ( Vcb->FreeClusterBitMap.Buffer != NULL ) {
593
594 ExFreePool( Vcb->FreeClusterBitMap.Buffer );
595
596 //
597 // NULL this field as an flag.
598 //
599
600 Vcb->FreeClusterBitMap.Buffer = NULL;
601 }
602
603 //
604 // And remove all the runs in the dirty fat Mcb
605 //
606
607 FatRemoveMcbEntry( Vcb, &Vcb->DirtyFatMcb, 0, 0xFFFFFFFF );
608
609 DebugTrace(-1, Dbg, "FatTearDownAllocationSupport -> (VOID)\n", 0);
610
611 UNREFERENCED_PARAMETER( IrpContext );
612
613 return;
614}

Referenced by FatDeleteVcb(), and FatSetupAllocationSupport().

◆ 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
#define FatSetVcbCondition(V, X)
Definition: fatprocs.h:1438

◆ FatToggleMediaEjectDisable()

NTSTATUS FatToggleMediaEjectDisable ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN BOOLEAN  PreventRemoval 
)

Definition at line 3495 of file deviosup.c.

3521{
3522 PIRP Irp;
3523 KIRQL SavedIrql;
3525 FAT_SYNC_CONTEXT SyncContext;
3526 PREVENT_MEDIA_REMOVAL Prevent;
3527
3528 UNREFERENCED_PARAMETER( IrpContext );
3529
3530 //
3531 // If PreventRemoval is the same as VCB_STATE_FLAG_REMOVAL_PREVENTED,
3532 // no-op this call, otherwise toggle the state of the flag.
3533 //
3534
3536
3537 if ((PreventRemoval ^
3539
3541
3542 return STATUS_SUCCESS;
3543
3544 } else {
3545
3547
3549 }
3550
3551 Prevent.PreventMediaRemoval = PreventRemoval;
3552
3554
3555 //
3556 // We build this IRP using a junk Iosb that will receive the final
3557 // completion status since we won't be around for it.
3558 //
3559 // We fill in the UserIosb manually below,
3560 // So passing NULL for the final parameter is ok in this special case.
3561 //
3562#ifdef _MSC_VER
3563#pragma warning(suppress: 6387)
3564#endif
3566 Vcb->TargetDeviceObject,
3567 &Prevent,
3568 sizeof(PREVENT_MEDIA_REMOVAL),
3569 NULL,
3570 0,
3571 FALSE,
3572 NULL,
3573 NULL );
3574
3575 if ( Irp != NULL ) {
3576
3577 //
3578 // Use our special completion routine which will remove the requirement that
3579 // the caller must be below APC level. All it tells us is that the Irp got
3580 // back, but will not tell us if it was succesful or not. We don't care,
3581 // and there is of course no fallback if the attempt to prevent removal
3582 // doesn't work for some mysterious reason.
3583 //
3584 // Normally, all IO is done at passive level. However, MM needs to be able
3585 // to issue IO with fast mutexes locked down, which raises us to APC. The
3586 // overlying IRP is set up to complete in yet another magical fashion even
3587 // though APCs are disabled, and any IRPage we do in these cases has to do
3588 // the same. Marking media dirty (and toggling eject state) is one.
3589 //
3590
3591 Irp->UserIosb = &Irp->IoStatus;
3592
3595 &SyncContext,
3596 TRUE,
3597 TRUE,
3598 TRUE );
3599
3600 Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
3601
3602 if (Status == STATUS_PENDING) {
3603
3604 (VOID) KeWaitForSingleObject( &SyncContext.Event,
3605 Executive,
3606 KernelMode,
3607 FALSE,
3608 NULL );
3609
3610 Status = SyncContext.Iosb.Status;
3611 }
3612
3613 return Status;
3614 }
3615
3617}
#define IOCTL_DISK_MEDIA_REMOVAL
Definition: cdrw_usr.h:176
IO_COMPLETION_ROUTINE FatSpecialSyncCompletionRoutine
Definition: deviosup.c:88
#define VCB_STATE_FLAG_REMOVAL_PREVENTED
Definition: fatstruc.h:571
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:152
IO_STATUS_BLOCK Iosb
Definition: deviosup.c:53
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:343

Referenced by _Requires_lock_held_(), and FatDeferredCleanVolume().

◆ FatTunnelFcbOrDcb()

VOID FatTunnelFcbOrDcb ( IN PFCB  FcbOrDcb,
IN PCCB Ccb  OPTIONAL 
)

Definition at line 652 of file dirsup.c.

675{
676 UNICODE_STRING ShortNameWithCase = {0};
677 UNICODE_STRING DownCaseSeg;
678 WCHAR ShortNameBuffer[8+1+3];
680 USHORT i;
681
682 PAGED_CODE();
683
684 DebugTrace(+1, Dbg, "FatTunnelFcbOrDcb\n", 0);
685
686 if (NodeType(FcbOrDcb) == FAT_NTC_DCB) {
687
688 //
689 // Directory deletion. Flush all entries from this directory in
690 // the cache for this volume
691 //
692
695
696 } else {
697
698 //
699 // Was a file, so throw it into the tunnel cache
700 //
701
702 //
703 // Get the short name into UNICODE
704 //
705
706 ShortNameWithCase.Length = 0;
707 ShortNameWithCase.MaximumLength = sizeof(ShortNameBuffer);
708 ShortNameWithCase.Buffer = ShortNameBuffer;
709
710#ifdef _MSC_VER
711#pragma prefast( suppress:28931, "needed for debug build" )
712#endif
713 Status = RtlOemStringToCountedUnicodeString( &ShortNameWithCase,
715 FALSE);
716
717 NT_ASSERT(ShortNameWithCase.Length != 0);
718
720
722
723 //
724 // Have to repair the case of the short name
725 //
726
727 for (i = 0; i < (ShortNameWithCase.Length/sizeof(WCHAR)) &&
728 ShortNameWithCase.Buffer[i] != L'.'; i++);
729
730 //
731 // Now pointing at the '.', or otherwise the end of name component
732 //
733
735
736 DownCaseSeg.Buffer = ShortNameWithCase.Buffer;
737 DownCaseSeg.MaximumLength = DownCaseSeg.Length = i*sizeof(WCHAR);
738
739 RtlDowncaseUnicodeString(&DownCaseSeg, &DownCaseSeg, FALSE);
740 }
741
742 i++;
743
744 //
745 // Now pointing at first wchar of the extension.
746 //
747
749
750 //
751 // It is not neccesarily the case that we can rely on the flag
752 // indicating that we really have an extension.
753 //
754
755 if ((i*sizeof(WCHAR)) < ShortNameWithCase.Length) {
756 DownCaseSeg.Buffer = &ShortNameWithCase.Buffer[i];
757 DownCaseSeg.MaximumLength = DownCaseSeg.Length = ShortNameWithCase.Length - i*sizeof(WCHAR);
758
759 RtlDowncaseUnicodeString(&DownCaseSeg, &DownCaseSeg, FALSE);
760 }
761 }
762 }
763
764 //
765 // ... and add it in
766 //
767
770 &ShortNameWithCase,
773 sizeof(LARGE_INTEGER),
775 }
776
777 DebugTrace(-1, Dbg, "FatTunnelFcbOrDcb -> (VOID)\n", 0);
778
779 return;
780}
#define FatDirectoryKey(FcbOrDcb)
Definition: fatprocs.h:850
#define CCB_FLAG_OPENED_BY_SHORTNAME
Definition: fatstruc.h:1296
NTSTATUS NTAPI RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCOEM_STRING OemSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1473
TUNNEL Tunnel
Definition: fatstruc.h:512
VOID NTAPI FsRtlAddToTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING ShortName, IN PUNICODE_STRING LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN PVOID Data)
Definition: tunnel.c:342
VOID NTAPI FsRtlDeleteKeyFromTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey)
Definition: tunnel.c:589

Referenced by _Requires_lock_held_(), and FatSetRenameInfo().

◆ FatUnicodeRestoreShortNameCase()

VOID FatUnicodeRestoreShortNameCase ( IN PUNICODE_STRING  ShortNameWithCase,
IN BOOLEAN  LowerCase8,
IN BOOLEAN  LowerCase3 
)

Definition at line 1041 of file namesup.c.

1064{
1065 USHORT i;
1066 UNICODE_STRING DownCaseSeg;
1067
1068 PAGED_CODE();
1069
1070 NT_ASSERT( ShortNameWithCase->Length <= 24 );
1071
1072 //
1073 // Have to repair the case of the short name
1074 //
1075
1076 for (i = 0; i < (ShortNameWithCase->Length/sizeof(WCHAR)) &&
1077 ShortNameWithCase->Buffer[i] != L'.'; i++);
1078
1079 //
1080 // Now pointing at the '.', or otherwise the end of name component
1081 //
1082
1083 if (LowerCase8) {
1084
1085 DownCaseSeg.Buffer = ShortNameWithCase->Buffer;
1086 DownCaseSeg.MaximumLength = DownCaseSeg.Length = i*sizeof(WCHAR);
1087
1088 RtlDowncaseUnicodeString(&DownCaseSeg, &DownCaseSeg, FALSE);
1089 }
1090
1091 i++;
1092
1093 //
1094 // Now pointing at first wchar of the extension.
1095 //
1096
1097 if (LowerCase3) {
1098
1099 //
1100 // It is not neccesarily the case that we can rely on the flag
1101 // indicating that we really have an extension.
1102 //
1103
1104 if ((i*sizeof(WCHAR)) < ShortNameWithCase->Length) {
1105 DownCaseSeg.Buffer = &ShortNameWithCase->Buffer[i];
1106 DownCaseSeg.MaximumLength = DownCaseSeg.Length = ShortNameWithCase->Length - i*sizeof(WCHAR);
1107
1108 RtlDowncaseUnicodeString(&DownCaseSeg, &DownCaseSeg, FALSE);
1109 }
1110 }
1111
1112}

◆ FatUnicodeToUpcaseOem()

VOID FatUnicodeToUpcaseOem ( IN PIRP_CONTEXT  IrpContext,
IN POEM_STRING  OemString,
IN PUNICODE_STRING  UnicodeString 
)

Definition at line 632 of file namesup.c.

662{
664
665 PAGED_CODE();
666
669 FALSE );
670
672
673 OemString->Buffer = NULL;
674 OemString->Length = 0;
675 OemString->MaximumLength = 0;
676
679 TRUE );
680 }
681
682 if (!NT_SUCCESS(Status)) {
683
685
686 OemString->Length = 0;
687
688 } else {
689
690 FatNormalizeAndRaiseStatus( IrpContext, Status );
691 }
692 }
693
694 return;
695}
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
*BytesInOemString PCHAR OemString
Definition: rtlfuncs.h:1560

Referenced by FatSetRenameInfo().

◆ FatUnlockVolumeInternal()

NTSTATUS FatUnlockVolumeInternal ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_OBJECT FileObject  OPTIONAL 
)

Definition at line 3601 of file fsctrl.c.

3630{
3631 KIRQL SavedIrql;
3633
3634 UNREFERENCED_PARAMETER( IrpContext );
3635
3636 IoAcquireVpbSpinLock( &SavedIrql );
3637
3638 if (FlagOn(Vcb->Vpb->Flags, VPB_LOCKED) && FileObject == Vcb->FileObjectWithVcbLocked) {
3639
3640 //
3641 // This one locked it, unlock the volume
3642 //
3643
3645 ClearFlag( Vcb->VcbState, VCB_STATE_FLAG_LOCKED );
3646 Vcb->FileObjectWithVcbLocked = NULL;
3647
3649 }
3650
3651 IoReleaseVpbSpinLock( SavedIrql );
3652
3653 return Status;
3654}
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
#define STATUS_NOT_LOCKED
Definition: ntstatus.h:279
#define VPB_DIRECT_WRITES_ALLOWED
Definition: iotypes.h:1812
#define VPB_LOCKED
Definition: iotypes.h:1808

Referenced by FatUnlockVolume().

◆ FatUnpinEaRange()

VOID FatUnpinEaRange ( IN PIRP_CONTEXT  IrpContext,
IN OUT PEA_RANGE  EaRange 
)

Definition at line 3782 of file easup.c.

3804{
3805 PBCB *NextBcb;
3806 ULONG BcbCount;
3807
3808 PAGED_CODE();
3809
3810 UNREFERENCED_PARAMETER( IrpContext );
3811
3812 //
3813 // If we allocated a auxilary buffer, deallocate it here.
3814 //
3815
3816 if (EaRange->AuxilaryBuffer == TRUE) {
3817
3818 ExFreePool( EaRange->Data );
3819 EaRange->AuxilaryBuffer = FALSE;
3820 }
3821
3822 //
3823 // Walk through the Bcb chain and unpin the data.
3824 //
3825
3826 if (EaRange->BcbChain != NULL) {
3827
3828 BcbCount = EaRange->BcbChainLength;
3829 NextBcb = EaRange->BcbChain;
3830
3831 while (BcbCount--) {
3832
3833 if (*NextBcb != NULL) {
3834
3835 CcUnpinData( *NextBcb );
3836 *NextBcb = NULL;
3837 }
3838
3839 NextBcb += 1;
3840 }
3841
3842 //
3843 // If we allocated a Bcb chain, deallocate it here.
3844 //
3845
3846 if (EaRange->BcbChain != &EaRange->BcbArray[0]) {
3847
3848 ExFreePool( EaRange->BcbChain );
3849 }
3850
3851 EaRange->BcbChain = NULL;
3852 }
3853
3854 return;
3855}

Referenced by _Requires_lock_held_(), FatCommonQueryEa(), FatCommonSetEa(), and FatReadEaSet().

◆ FatUnpinRepinnedBcbs()

VOID FatUnpinRepinnedBcbs ( IN PIRP_CONTEXT  IrpContext)

Definition at line 1407 of file cachesup.c.

1425{
1426 IO_STATUS_BLOCK RaiseIosb;
1427 PREPINNED_BCBS Repinned;
1428 BOOLEAN WriteThroughToDisk;
1430 BOOLEAN ForceVerify = FALSE;
1431 ULONG i;
1432 PFCB FcbOrDcb = NULL;
1433
1434 PAGED_CODE();
1435
1436 DebugTrace(+1, Dbg, "FatUnpinRepinnedBcbs\n", 0 );
1437 DebugTrace( 0, Dbg, "IrpContext = %p\n", IrpContext );
1438
1439 //
1440 // The algorithm for this procedure is to scan the entire list of
1441 // repinned records unpinning any repinned bcbs. We start off
1442 // with the first record in the irp context, and while there is a
1443 // record to scan we do the following loop.
1444 //
1445
1446 Repinned = &IrpContext->Repinned;
1447 RaiseIosb.Status = STATUS_SUCCESS;
1448
1449 //
1450 // WinSE bug #307418 "Occasional data corruption when
1451 // standby/resume while copying files to removable FAT
1452 // formatted media".
1453 // Extract main FCB pointer from the irp context - we
1454 // will need it later to detect new file creation operation.
1455 //
1456
1457 if (IrpContext->MajorFunction == IRP_MJ_CREATE &&
1458 IrpContext->OriginatingIrp != NULL) {
1460
1461 IrpSp = IoGetCurrentIrpStackLocation( IrpContext->OriginatingIrp );
1462
1463 if (IrpSp != NULL &&
1464 IrpSp->FileObject != NULL &&
1465 IrpSp->FileObject->FsContext != NULL) {
1466
1467 FcbOrDcb = IrpSp->FileObject->FsContext;
1468 }
1469 }
1470
1471 //
1472 // If the request is write through or the media is deferred flush,
1473 // unpin the bcb's write through.
1474 //
1475
1476 WriteThroughToDisk = (BOOLEAN) (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH) &&
1477 IrpContext->Vcb != NULL &&
1478 (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH) ||
1479 FlagOn(IrpContext->Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH)));
1480
1481 while (Repinned != NULL) {
1482
1483 //
1484 // For every non-null entry in the repinned record unpin the
1485 // repinned entry.
1486 //
1487 // If the this is removable media (therefore all requests write-
1488 // through) and the write fails, purge the cache so that we throw
1489 // away the modifications as we will be returning an error to the
1490 // user.
1491 //
1492
1493 for (i = 0; i < REPINNED_BCBS_ARRAY_SIZE; i += 1) {
1494
1495 if (Repinned->Bcb[i] != NULL) {
1496
1498
1499 if (WriteThroughToDisk &&
1500 FlagOn(IrpContext->Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH)) {
1501
1502 FileObject = CcGetFileObjectFromBcb( Repinned->Bcb[i] );
1503 }
1504
1505 CcUnpinRepinnedBcb( Repinned->Bcb[i],
1506 WriteThroughToDisk,
1507 &Iosb );
1508
1509 if (!NT_SUCCESS(Iosb.Status)) {
1510
1511 if (RaiseIosb.Status == STATUS_SUCCESS) {
1512
1513 RaiseIosb = Iosb;
1514 }
1515
1516 //
1517 // If this was a writethrough device, purge the cache,
1518 // except for Irp major codes that either don't handle
1519 // the error paths correctly or are simple victims like
1520 // cleanup.c.
1521 //
1522
1523 if (FileObject &&
1524 (IrpContext->MajorFunction != IRP_MJ_CLEANUP) &&
1525 (IrpContext->MajorFunction != IRP_MJ_FLUSH_BUFFERS) &&
1526 (IrpContext->MajorFunction != IRP_MJ_SET_INFORMATION)
1527
1528 &&
1529
1530 //
1531 // WinSE bug #307418 "Occasional data corruption when
1532 // standby/resume while copying files to removable FAT
1533 // formatted media".
1534 // Buffer unpinning for new file creation operation can
1535 // be interrupted by system syspend. As a result some BCBs
1536 // will be successfully written to the disk while others will
1537 // be kicked back with STATUS_VERIFY_REQUIRED. Since there is
1538 // is still a chance for the failed BCBs to reach the disk
1539 // after the volume verification we'll not purge them.
1540 // Instead FatCommonCreate() will unroll the file creation
1541 // changes for these pages.
1542 //
1543
1544 !(IrpContext->MajorFunction == IRP_MJ_CREATE &&
1545 Iosb.Status == STATUS_VERIFY_REQUIRED &&
1546 FcbOrDcb != NULL &&
1547 NodeType( FcbOrDcb ) == FAT_NTC_FCB)) {
1548
1549 //
1550 // The call to CcPurgeCacheSection() below will
1551 // purge the entire file from memory. It will also
1552 // block until all the file's BCB's are pinned.
1553 //
1554 // We end up in a deadlock situation of there
1555 // are any other pinned BCB's in this IRP context
1556 // so the first thing we do is search the list
1557 // for BCB's pinned in the same file and unpin
1558 // them.
1559 //
1560 // We are probably not going to lose data because
1561 // it's safe to assume that all flushes will
1562 // fail after the first one fails.
1563 //
1564
1565 ULONG j;
1566 ULONG k = i + 1;
1567 PREPINNED_BCBS RepinnedToPurge = Repinned;
1568
1569 while( RepinnedToPurge != NULL ) {
1570
1571 for (j = k; j < REPINNED_BCBS_ARRAY_SIZE; j++) {
1572
1573 if (RepinnedToPurge->Bcb[j] != NULL) {
1574
1575 if (CcGetFileObjectFromBcb( RepinnedToPurge->Bcb[j] ) == FileObject) {
1576
1577 CcUnpinRepinnedBcb( RepinnedToPurge->Bcb[j],
1578 FALSE,
1579 &Iosb );
1580
1581 RepinnedToPurge->Bcb[j] = NULL;
1582 }
1583 }
1584 }
1585
1586 RepinnedToPurge = RepinnedToPurge->Next;
1587 k = 0;
1588 }
1589
1590 CcPurgeCacheSection( FileObject->SectionObjectPointer,
1591 NULL,
1592 0,
1593 FALSE );
1594
1595 //
1596 // Force a verify operation here since who knows
1597 // what state things are in.
1598 //
1599
1600 ForceVerify = TRUE;
1601 }
1602 }
1603
1604 Repinned->Bcb[i] = NULL;
1605
1606 }
1607 }
1608
1609 //
1610 // Now find the next repinned record in the list, and possibly
1611 // delete the one we've just processed.
1612 //
1613
1614 if (Repinned != &IrpContext->Repinned) {
1615
1616 PREPINNED_BCBS Saved;
1617
1618 Saved = Repinned->Next;
1619 ExFreePool( Repinned );
1620 Repinned = Saved;
1621
1622 } else {
1623
1624 Repinned = Repinned->Next;
1625 IrpContext->Repinned.Next = NULL;
1626 }
1627 }
1628
1629 //
1630 // Now if we weren't completely successful in the our unpin
1631 // then raise the iosb we got
1632 //
1633
1634 if (!NT_SUCCESS(RaiseIosb.Status)) {
1635
1636 if (ForceVerify && FileObject) {
1637
1638 SetFlag(FileObject->DeviceObject->Flags, DO_VERIFY_VOLUME);
1639
1640 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1641 FileObject->DeviceObject );
1642 }
1643
1644 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_RAISE )) {
1645 if (IrpContext->OriginatingIrp) {
1646 IrpContext->OriginatingIrp->IoStatus = RaiseIosb;
1647 }
1648 FatNormalizeAndRaiseStatus( IrpContext, RaiseIosb.Status );
1649 }
1650 }
1651
1652 DebugTrace(-1, Dbg, "FatUnpinRepinnedBcbs -> VOID\n", 0 );
1653
1654 return;
1655}
#define IRP_CONTEXT_FLAG_DISABLE_RAISE
Definition: fatstruc.h:1573
#define VCB_STATE_FLAG_DEFERRED_FLUSH
Definition: fatstruc.h:568
PFILE_OBJECT NTAPI CcGetFileObjectFromBcb(PVOID Bcb)
Definition: fssup.c:625
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
int k
Definition: mpi.c:3369

Referenced by _Requires_lock_held_(), FatCommonSetEa(), FatCompleteRequest_Real(), FatDeferredCleanVolume(), FatSetFsLabelInfo(), and FatSetRenameInfo().

◆ FatVerifyOperationIsLegal()

VOID FatVerifyOperationIsLegal ( IN PIRP_CONTEXT  IrpContext)

Definition at line 1304 of file verfysup.c.

1326{
1327 PIRP Irp;
1329
1330 PAGED_CODE();
1331
1332 Irp = IrpContext->OriginatingIrp;
1333
1334 //
1335 // If the Irp is not present, then we got here via close.
1336 //
1337 //
1338
1339 if ( Irp == NULL ) {
1340
1341 return;
1342 }
1343
1345
1346 //
1347 // If there is not a file object, we cannot continue.
1348 //
1349
1350 if ( FileObject == NULL ) {
1351
1352 return;
1353 }
1354
1355 //
1356 // If the file object has already been cleaned up, and
1357 //
1358 // A) This request is a paging io read or write, or
1359 // B) This request is a close operation, or
1360 // C) This request is a set or query info call (for Lou)
1361 // D) This is an MDL complete
1362 //
1363 // let it pass, otherwise return STATUS_FILE_CLOSED.
1364 //
1365
1366 if ( FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE) ) {
1367
1369
1370 if ( (FlagOn(Irp->Flags, IRP_PAGING_IO)) ||
1374 ( ( (IrpSp->MajorFunction == IRP_MJ_READ) ||
1377
1378 NOTHING;
1379
1380 } else {
1381
1382 FatRaiseStatus( IrpContext, STATUS_FILE_CLOSED );
1383 }
1384 }
1385
1386 return;
1387}
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_PAGING_IO
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790

Referenced by _Requires_lock_held_().

◆ FatVerifyVcb()

VOID FatVerifyVcb ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 270 of file verfysup.c.

292{
293 BOOLEAN DevMarkedForVerify;
294
295 PAGED_CODE();
296
297 DebugTrace(+1, Dbg, "FatVerifyVcb, Vcb = %p\n", Vcb );
298
299 //
300 // If the verify volume flag in the device object is set
301 // this means the media has potentially changed.
302 //
303 // Note that we only force this ping for create operations.
304 // For others we take a sporting chance. If in the end we
305 // have to physically access the disk, the right thing will happen.
306 //
307
308 DevMarkedForVerify = BooleanFlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
309
310 //
311 // We ALWAYS force CREATE requests on unmounted volumes through the
312 // verify path. These requests could have been in limbo between
313 // IoCheckMountedVpb and us, when a verify/mount took place and caused
314 // a completely different fs/volume to be mounted. In this case the
315 // checks above may not have caught the condition, since we may already
316 // have verified (wrong volume) and decided that we have nothing to do.
317 // We want the requests to be re routed to the currently mounted volume,
318 // since they were directed at the 'drive', not our volume. So we take
319 // the verify path for synchronisation, and the request will eventually
320 // be bounced back to IO with STATUS_REPARSE by our verify handler.
321 //
322
323 if (!DevMarkedForVerify &&
324 (IrpContext->MajorFunction == IRP_MJ_CREATE) &&
325 (IrpContext->OriginatingIrp != NULL)) {
326
327 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->OriginatingIrp);
328
329 if ((IrpSp->FileObject->RelatedFileObject == NULL) &&
330 (Vcb->VcbCondition == VcbNotMounted)) {
331
332 DevMarkedForVerify = TRUE;
333 }
334 }
335
336 //
337 // Raise any error condition otherwise.
338 //
339
340 if (DevMarkedForVerify) {
341
342 DebugTrace(0, Dbg, "The Vcb needs to be verified\n", 0);
343
344 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
345 Vcb->Vpb->RealDevice );
346
348 }
349
350 //
351 // Check the operation is legal for current Vcb state.
352 //
353
354 FatQuickVerifyVcb( IrpContext, Vcb );
355
356 DebugTrace(-1, Dbg, "FatVerifyVcb -> VOID\n", 0);
357}
VOID FatQuickVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1662

Referenced by FatFlushFat(), FatIsVolumeDirty(), and FatIsVolumeMounted().

◆ FatVolumeUncleanCount()

ULONG FatVolumeUncleanCount ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

◆ FatWaitSync()

VOID FatWaitSync ( IN PIRP_CONTEXT  IrpContext)

Definition at line 2367 of file deviosup.c.

2386{
2387 PAGED_CODE();
2388
2389 DebugTrace(+1, Dbg, "FatWaitSync, Context = %p\n", IrpContext->FatIoContext );
2390
2391 KeWaitForSingleObject( &IrpContext->FatIoContext->Wait.SyncEvent,
2393
2394 KeClearEvent( &IrpContext->FatIoContext->Wait.SyncEvent );
2395
2396 DebugTrace(-1, Dbg, "FatWaitSync -> VOID\n", 0 );
2397}
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22

Referenced by _Requires_lock_held_(), and FatSingleNonAlignedSync().

◆ FatZeroData()

FINISHED FatZeroData ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_OBJECT  FileObject,
IN ULONG  StartingZero,
IN ULONG  ByteCount 
)

Definition at line 1659 of file cachesup.c.

1673{
1674#ifndef __REACTOS__
1675 LARGE_INTEGER ZeroStart = {0,0};
1676 LARGE_INTEGER BeyondZeroEnd = {0,0};
1677#else
1678 LARGE_INTEGER ZeroStart = {{0,0}};
1679 LARGE_INTEGER BeyondZeroEnd = {{0,0}};
1680#endif
1681
1683
1684 BOOLEAN Finished;
1685
1686 PAGED_CODE();
1687
1688 SectorSize = (ULONG)Vcb->Bpb.BytesPerSector;
1689
1690 ZeroStart.LowPart = (StartingZero + (SectorSize - 1)) & ~(SectorSize - 1);
1691
1692 //
1693 // Detect overflow if we were asked to zero in the last sector of the file,
1694 // which must be "zeroed" already (or we're in trouble).
1695 //
1696
1697 if (StartingZero != 0 && ZeroStart.LowPart == 0) {
1698
1699 return TRUE;
1700 }
1701
1702 //
1703 // Note that BeyondZeroEnd can take the value 4gb.
1704 //
1705
1706 BeyondZeroEnd.QuadPart = ((ULONGLONG) StartingZero + ByteCount + (SectorSize - 1))
1707 & (~((LONGLONG) SectorSize - 1));
1708
1709 //
1710 // If we were called to just zero part of a sector we are in trouble.
1711 //
1712
1713 if ( ZeroStart.QuadPart == BeyondZeroEnd.QuadPart ) {
1714
1715 return TRUE;
1716 }
1717
1718 Finished = CcZeroData( FileObject,
1719 &ZeroStart,
1720 &BeyondZeroEnd,
1721 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
1722
1723 return Finished;
1724}
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:414
_In_ ULONG SectorSize
Definition: halfuncs.h:291

Referenced by _Requires_lock_held_().

Variable Documentation

◆ AbsoluteClusterHint

IN PVCB IN ULONG AbsoluteClusterHint

Definition at line 344 of file fatprocs.h.

◆ AllLowerComponent

Definition at line 1308 of file fatprocs.h.

Referenced by FatEvaluateNameCase(), and FatSetRenameInfo().

◆ AllLowerExtension

Definition at line 1309 of file fatprocs.h.

Referenced by FatEvaluateNameCase(), and FatSetRenameInfo().

◆ Allocated

◆ AllocationSize

◆ Bcb

◆ Buffer

◆ ByteCount

IN PIRP IN PFCB IN ULONG IN ULONG ByteCount

Definition at line 309 of file fatprocs.h.

◆ ByteOffset

◆ Ccb

IN PFCB IN PCCB Ccb

Definition at line 726 of file fatprocs.h.

◆ CheckForReadOperation

◆ CompletionContext

Definition at line 1598 of file fatprocs.h.

◆ CreateFile

Definition at line 916 of file fatprocs.h.

◆ CreateLfn

◆ Dcb

IN PDCB Dcb

Definition at line 424 of file fatprocs.h.

◆ DeleteEa

Definition at line 717 of file fatprocs.h.

◆ Device

Definition at line 2030 of file fatprocs.h.

◆ DeviceObject

◆ Dirent

IN PVCB IN PDIRENT Dirent

Definition at line 729 of file fatprocs.h.

◆ DirentOffset

IN PDCB IN ULONG IN ULONG DirentOffset

Definition at line 790 of file fatprocs.h.

◆ DirentsNeeded

IN PDCB IN ULONG DirentsNeeded

Definition at line 699 of file fatprocs.h.

◆ EaBcb

IN PVCB IN ULONG IN PBCB EaBcb

Definition at line 915 of file fatprocs.h.

Referenced by _Requires_lock_held_(), FatCommonQueryEa(), and FatCommonSetEa().

◆ EaDirent

Definition at line 914 of file fatprocs.h.

Referenced by _Requires_lock_held_(), FatCommonQueryEa(), and FatCommonSetEa().

◆ EaHandle

Definition at line 897 of file fatprocs.h.

Referenced by FatCommonSetEa(), and FatReadEaSet().

◆ EaLength

◆ EaSetLength

IN PVCB IN ULONG EaSetLength

Definition at line 946 of file fatprocs.h.

◆ EaSetRange

◆ EndOnMax

Definition at line 311 of file fatprocs.h.

Referenced by _Requires_lock_held_().

◆ ExactMatchRequired

IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN ExactMatchRequired

Definition at line 346 of file fatprocs.h.

◆ ExceptionCode

IN PIRP IN NTSTATUS ExceptionCode

Definition at line 2934 of file fatprocs.h.

◆ ExclusiveFcb

Definition at line 917 of file fatprocs.h.

◆ ExclusiveLock

◆ FailImmediately

◆ FatCleanVolumeDpc

KDEFERRED_ROUTINE FatCleanVolumeDpc

Definition at line 1981 of file fatprocs.h.

Referenced by _Requires_lock_held_().

◆ FatEntry

◆ FatFspDispatch

WORKER_THREAD_ROUTINE FatFspDispatch

Definition at line 2380 of file fatprocs.h.

Referenced by FatAddToWorkque().

◆ FatFspMarkVolumeDirtyWithRecover

WORKER_THREAD_ROUTINE FatFspMarkVolumeDirtyWithRecover

Definition at line 2000 of file fatprocs.h.

Referenced by FatPagingFileErrorHandler().

◆ FatIndex

IN PVCB IN ULONG FatIndex

Definition at line 383 of file fatprocs.h.

Referenced by FatExamineFatEntries(), FatLookupFatEntry(), and FatVerifyLookupFatEntry().

◆ FatTime

◆ Fcb

IN PFCB Fcb

Definition at line 820 of file fatprocs.h.

◆ FcbOrDcb

◆ FileName

Definition at line 742 of file fatprocs.h.

◆ Filename

◆ FileObject

Definition at line 837 of file fatprocs.h.

◆ FileOffset

IN PLARGE_INTEGER FileOffset

Definition at line 2662 of file fatprocs.h.

◆ Flags

Definition at line 728 of file fatprocs.h.

◆ FlushType

IN PVCB IN FAT_FLUSH_TYPE FlushType

Definition at line 1081 of file fatprocs.h.

Referenced by _Requires_lock_held_(), CcFlushImageSection(), and MmFlushImageSection().

◆ Force

PVCB IN BOOLEAN Force

Definition at line 1803 of file fatprocs.h.

◆ FsDeviceObject

Definition at line 1676 of file fatprocs.h.

Referenced by _Requires_lock_held_().

◆ IoStatus

Definition at line 2667 of file fatprocs.h.

◆ Irp

Definition at line 589 of file fatprocs.h.

◆ Key

Definition at line 2712 of file fatprocs.h.

◆ Lbo

◆ Length

Definition at line 895 of file fatprocs.h.

◆ Lfn

Definition at line 753 of file fatprocs.h.

◆ LfnOffset

IN PDCB IN ULONG LfnOffset

Definition at line 789 of file fatprocs.h.

◆ LfnTmp

Definition at line 754 of file fatprocs.h.

◆ LockKey

◆ Mcb

Definition at line 347 of file fatprocs.h.

Referenced by _Requires_lock_held_(), bmap(), CdFindMcbEntry(), DosChangeMemoryOwner(), DosFreeMemory(), DosInitializeMemory(), DosInitializeUmb(), DosInitPsp(), DosLinkUmb(), DosResizeMemory(), DosUnlinkUmb(), DumpAllRuns(), Ext2AddBlockExtent(), Ext2AddMcbExtent(), Ext2AddMcbMetaExts(), Ext2AllocateFcb(), Ext2AllocateMcb(), Ext2BlockMap(), Ext2BuildExtents(), Ext2CheckFileAccess(), Ext2Cleanup(), Ext2CleanupAllMcbs(), Ext2CreateFile(), Ext2DeleteFile(), Ext2DeleteReparsePoint(), Ext2DoExtentExpand(), Ext2ExpandBlock(), Ext2ExpandExtent(), Ext2ExpandFile(), Ext2ExpandIndirect(), Ext2ExpandLast(), Ext2FastIoQueryBasicInfo(), Ext2FastIoQueryNetworkOpenInfo(), Ext2FirstUnusedMcb(), Ext2FollowLink(), Ext2FreeMcb(), Ext2GetBlock(), Ext2GetReparsePoint(), Ext2InitializeZone(), Ext2InodeType(), Ext2InsertMcb(), Ext2IsDirectoryEmpty(), Ext2IsFileRemovable(), Ext2LinkHeadMcb(), Ext2LinkTailMcb(), Ext2LookupBlockExtent(), Ext2LookupFile(), Ext2LookupMcbExtent(), Ext2MapExtent(), Ext2MapIndirect(), Ext2McbReaperThread(), Ext2NotifyReportChange(), Ext2OverwriteEa(), Ext2ProcessEntry(), Ext2QueryDirectory(), Ext2QueryEa(), Ext2QueryFileInformation(), Ext2ReadInode(), Ext2ReadSymlink(), Ext2ReleaseFcb(), Ext2RemoveBlockExtent(), Ext2RemoveEntry(), Ext2RemoveMcb(), Ext2RemoveMcbExtent(), Ext2RemoveMcbMetaExts(), Ext2SearchMcb(), Ext2SetDispositionInfo(), Ext2SetEa(), Ext2SetFileInformation(), Ext2SetFileType(), Ext2SetLinkInfo(), Ext2SetRenameInfo(), Ext2SetReparsePoint(), Ext2TruncateBlock(), Ext2TruncateExtent(), Ext2TruncateFile(), Ext2TruncateIndirect(), Ext2TruncateIndirectFast(), Ext2TruncateSymlink(), Ext2UnlinkFcb(), Ext2UnlinkMcb(), Ext2WriteInode(), Ext2WriteSymlink(), ext3_bread(), FatAddMcbEntry(), FatGetNextMcbEntry(), FatLookupLastMcbEntry(), FatLookupMcbEntry(), FatRemoveMcbEntry(), FsRtlAddBaseMcbEntry(), FsRtlAddLargeMcbEntry(), FsRtlAddMcbEntry(), FsRtlGetNextBaseMcbEntry(), FsRtlGetNextLargeMcbEntry(), FsRtlGetNextMcbEntry(), FsRtlInitializeBaseMcb(), FsRtlInitializeLargeMcb(), FsRtlInitializeMcb(), FsRtlLargeMcbTestsFastFat(), FsRtlLargeMcbTestsFastFat_2(), FsRtlLargeMcbTestsFastFat_3(), FsRtlLookupLargeMcbEntry(), FsRtlLookupLastBaseMcbEntry(), FsRtlLookupLastBaseMcbEntryAndIndex(), FsRtlLookupLastLargeMcbEntry(), FsRtlLookupLastLargeMcbEntryAndIndex_internal(), FsRtlLookupLastMcbEntry(), FsRtlLookupMcbEntry(), FsRtlNumberOfRunsInLargeMcb(), FsRtlNumberOfRunsInMcb(), FsRtlRemoveBaseMcbEntry(), FsRtlRemoveLargeMcbEntry(), FsRtlRemoveMcbEntry(), FsRtlResetBaseMcb(), FsRtlResetLargeMcb(), FsRtlSplitBaseMcb(), FsRtlSplitLargeMcb(), FsRtlTruncateLargeMcb(), FsRtlTruncateMcb(), FsRtlUninitializeBaseMcb(), FsRtlUninitializeLargeMcb(), FsRtlUninitializeMcb(), main(), McbMappingAllocate(), and ValidateMcb().

◆ NeedEaCount

IN PVCB IN PDIRENT OUT PULONG NeedEaCount

Definition at line 886 of file fatprocs.h.

◆ NoOpCheck

IN PVCB IN BOOLEAN NoOpCheck

Definition at line 1457 of file fatprocs.h.

Referenced by _Requires_lock_held_().

◆ NtTime

◆ OemName

◆ OffsetToStartSearchFrom

IN PDCB IN PCCB IN VBO OffsetToStartSearchFrom

Definition at line 727 of file fatprocs.h.

◆ OPTIONAL

Definition at line 312 of file fatprocs.h.

◆ Parent

IN PDCB Parent

Definition at line 1303 of file fatprocs.h.

◆ ParentDirectory

IN PDCB ParentDirectory

Definition at line 698 of file fatprocs.h.

Referenced by ObpLookupObjectName(), ObpQueryNameInfoSize(), and ObQueryNameString().

◆ ParentDirent

IN PDCB IN PDIRENT ParentDirent

Definition at line 708 of file fatprocs.h.

◆ Pin

Definition at line 427 of file fatprocs.h.

Referenced by AudioPositionPropertyHandler(), BdaMethodCreatePin(), BdaPropertyGetPinControl(), CaptureAvoidPipeStarvationWorker(), CaptureGateOnWorkItem(), CaptureInitializeUrbAndIrp(), CapturePinStateChange(), DECLARE_INTERFACE_(), DoDataIntersection(), FilterProcess(), GetFilterPinCount(), GetSysAudioDeviceCount(), GetSysAudioDevicePnpName(), HandleDataIntersection(), HandleNecessaryPropertyInstances(), HandlePhysicalConnection(), HandlePropertyInstances(), IKsFilter_AddPin(), IKsFilter_RemovePin(), IKsPin_Close(), IKsPin_DispatchCreateClock(), IKsPin_DispatchDeviceIoControl(), IKsPin_PinAllocatorFramingPropertyHandler(), IKsPin_PinDataFormatPropertyHandler(), IKsPin_PinMasterClock(), IKsPin_PinStatePropertyHandler(), InitCapturePin(), InitStreamPin(), IOAPICClear(), IOAPICClearPin(), KsGetPinFromIrp(), KspHandleDataIntersection(), KspHandleNecessaryPropertyInstances(), KspHandlePropertyInstances(), KsPinAcquireProcessingMutex(), KsPinAttachAndGate(), KsPinAttachOrGate(), KsPinDataIntersection(), KsPinGetAndGate(), KsPinGetFirstCloneStreamPointer(), KsPinGetLeadingEdgeStreamPointer(), KsPinGetNextSiblingPin(), KsPinGetParentFilter(), KsPinGetReferenceClockInterface(), KsPinRegisterFrameReturnCallback(), KsPinRegisterHandshakeCallback(), KsPinRegisterIrpCompletionCallback(), KsPinRegisterPowerCallbacks(), KsPinReleaseProcessingMutex(), KspPinPropertyHandler(), CKsInterfaceHandler::KsSetPin(), KsStreamPointerAdvanceOffsets(), KsStreamPointerClone(), KsStreamPointerDelete(), MMixerAddPinConnection(), MMixerGetAllUpOrDownstreamNodesFromPinIndex(), MMixerGetAllUpOrDownstreamPinsFromPinIndex(), MMixerGetFilterPinCount(), MMixerGetNextNodesFromPinIndex(), MMixerGetPhysicalConnection(), MMixerGetPinDataFlowAndCommunication(), MMixerGetPinName(), MMixerGetUpOrDownStreamPins(), MMixerHandleNodePinConnection(), MMixerHandleTopologyFilter(), PcCreatePinDispatch(), PinCaptureProcess(), PinClose(), PinCreate(), PinGetIrpFromReadyList(), PinIntersectHandler(), PinRenderProcess(), PinReset(), PinState(), RenderInitializeUrbAndIrp(), CKsProxy::SetPinState(), StartCaptureIsocTransfer(), SysAudioHandleProperty(), CMiniport::TestDataFormat(), CAC97MiniportTopology::TransPinDefToPinNr(), CAC97MiniportTopology::TransPinNrToPinDef(), UsbAudioCaptureComplete(), USBAudioPinCreate(), UsbAudioPinDataIntersect(), USBAudioPinProcess(), USBAudioPinSetDataFormat(), USBAudioPinSetDeviceState(), UsbAudioRenderComplete(), USBAudioSelectAudioStreamingInterface(), UsbAudioSetFormat(), and CMiniport::ValidateFormat().

◆ ProcessId

◆ RemainingMcb

Definition at line 366 of file fatprocs.h.

◆ RescanDir

IN PDCB IN ULONG IN BOOLEAN RescanDir

Definition at line 700 of file fatprocs.h.

◆ ReturnOnFailure

IN PFCB IN BOOLEAN ReturnOnFailure

Definition at line 772 of file fatprocs.h.

◆ Reversible

IN PBCB IN PVCB Vcb IN BOOLEAN Reversible

Definition at line 416 of file fatprocs.h.

Referenced by _Requires_lock_held_().

◆ Rounding

Definition at line 1915 of file fatprocs.h.

Referenced by _Success_().

◆ SecondMcb

Definition at line 375 of file fatprocs.h.

Referenced by FsRtlLargeMcbTestsExt2().

◆ ShortName

◆ SplitAtVbo

IN PVCB IN OUT PLARGE_MCB IN VBO SplitAtVbo

Definition at line 365 of file fatprocs.h.

◆ StartingVbo

IN PIRP IN PFCB IN ULONG StartingVbo

◆ Status

◆ StreamFlags

Definition at line 594 of file fatprocs.h.

Referenced by _Requires_lock_held_().

◆ TargetDcb

IN PDCB TargetDcb

Definition at line 788 of file fatprocs.h.

Referenced by Ext2SetLinkInfo(), Ext2SetRenameInfo(), and FatSetRenameInfo().

◆ TargetDeviceObject

◆ TenMsecs

Definition at line 1917 of file fatprocs.h.

Referenced by _Success_().

◆ TopLevel

◆ TypeOfOpen

IN PFCB IN PCCB IN TYPE_OF_OPEN TypeOfOpen

Definition at line 2415 of file fatprocs.h.

◆ UnicodeName

◆ UserByteCount

IN PIRP IN PFCB IN ULONG IN ULONG IN ULONG UserByteCount

Definition at line 593 of file fatprocs.h.

Referenced by _Requires_lock_held_().

◆ Vbo

◆ Vcb

IN PVCB Vcb

Definition at line 343 of file fatprocs.h.

Referenced by FatIsIoRangeValid().

◆ VolumeState

◆ Vpb

◆ Wait

Definition at line 1537 of file fatprocs.h.

◆ Zero

◆ ZeroOnDeallocate

IN PVCB IN PLARGE_MCB IN BOOLEAN ZeroOnDeallocate

Definition at line 356 of file fatprocs.h.