ReactOS 0.4.15-dev-7788-g1ad9096
vfat.h File Reference
#include <ntifs.h>
#include <ntdddisk.h>
#include <dos.h>
#include <pseh/pseh2.h>
#include <section_attribs.h>
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for vfat.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _BootSector
 
struct  _BootSector32
 
struct  _BootSectorFatX
 
struct  _FsInfoSector
 
struct  _FATDirEntry
 
struct  _EAFileHeader
 
struct  _EASetHeader
 
struct  _EAHeader
 
struct  _FATXDirEntry
 
struct  _slot
 
union  _DIR_ENTRY
 
struct  FATINFO
 
struct  _HASHENTRY
 
struct  _VFAT_DISPATCH
 
struct  _STATISTICS
 
struct  DEVICE_EXTENSION
 
struct  VFAT_GLOBAL_DATA
 
struct  _VFATFCB
 
struct  _VFATCCB
 
struct  __DOSTIME
 
struct  __DOSDATE
 
struct  VFAT_IRP_CONTEXT
 
struct  _VFAT_DIRENTRY_CONTEXT
 
struct  _VFAT_MOVE_CONTEXT
 
struct  _VFAT_CLOSE_CONTEXT
 

Macros

#define USE_ROS_CC_AND_FS
 
#define ENABLE_SWAPOUT
 
#define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
 
#define ROUND_DOWN(n, align)    (((ULONG)n) & ~((align) - 1l))
 
#define ROUND_UP(n, align)    ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
 
#define ROUND_DOWN_64(n, align)    (((ULONGLONG)n) & ~((align) - 1LL))
 
#define ROUND_UP_64(n, align)    ROUND_DOWN_64(((ULONGLONG)n) + (align) - 1LL, (align))
 
#define FAT_DIRTY_BIT   0x01
 
#define FAT_EAFILE   "EA DATA. SF"
 
#define VFAT_CASE_LOWER_BASE   8
 
#define VFAT_CASE_LOWER_EXT   16
 
#define LONGNAME_MAX_LENGTH   256
 
#define ENTRY_DELETED(IsFatX, DirEntry)   (IsFatX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))
 
#define ENTRY_VOLUME(IsFatX, DirEntry)   (IsFatX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))
 
#define ENTRY_END(IsFatX, DirEntry)   (IsFatX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))
 
#define FAT_ENTRY_DELETED(DirEntry)   ((DirEntry)->Filename[0] == 0xe5)
 
#define FAT_ENTRY_END(DirEntry)   ((DirEntry)->Filename[0] == 0)
 
#define FAT_ENTRY_LONG(DirEntry)   (((DirEntry)->Attrib & 0x3f) == 0x0f)
 
#define FAT_ENTRY_VOLUME(DirEntry)   (((DirEntry)->Attrib & 0x1f) == 0x08)
 
#define FATX_ENTRY_DELETED(DirEntry)   ((DirEntry)->FilenameLength == 0xe5)
 
#define FATX_ENTRY_END(DirEntry)   ((DirEntry)->FilenameLength == 0xff)
 
#define FATX_ENTRY_LONG(DirEntry)   (FALSE)
 
#define FATX_ENTRY_VOLUME(DirEntry)   (((DirEntry)->Attrib & 0x1f) == 0x08)
 
#define FAT_ENTRIES_PER_PAGE   (PAGE_SIZE / sizeof (FAT_DIR_ENTRY))
 
#define FATX_ENTRIES_PER_PAGE   (PAGE_SIZE / sizeof (FATX_DIR_ENTRY))
 
#define BLOCKSIZE   512
 
#define FAT16   (1)
 
#define FAT12   (2)
 
#define FAT32   (3)
 
#define FATX16   (4)
 
#define FATX32   (5)
 
#define VCB_VOLUME_LOCKED   0x0001
 
#define VCB_DISMOUNT_PENDING   0x0002
 
#define VCB_IS_FATX   0x0004
 
#define VCB_IS_SYS_OR_HAS_PAGE   0x0008
 
#define VCB_IS_DIRTY   0x4000 /* Volume is dirty */
 
#define VCB_CLEAR_DIRTY   0x8000 /* Clean dirty flag at shutdown */
 
#define VCB_GOOD   0x0010 /* If not set, the VCB is improper for usage */
 
#define STATISTICS_SIZE_NO_PAD   (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS))
 
#define VFAT_BREAK_ON_CORRUPTION   1
 
#define FCB_CACHE_INITIALIZED   0x0001
 
#define FCB_DELETE_PENDING   0x0002
 
#define FCB_IS_FAT   0x0004
 
#define FCB_IS_PAGE_FILE   0x0008
 
#define FCB_IS_VOLUME   0x0010
 
#define FCB_IS_DIRTY   0x0020
 
#define FCB_DELAYED_CLOSE   0x0040
 
#define NODE_TYPE_FCB   ((CSHORT)0x0502)
 
#define CCB_DELETE_ON_CLOSE   0x0001
 
#define TAG_CCB   'CtaF'
 
#define TAG_FCB   'FtaF'
 
#define TAG_IRP   'ItaF'
 
#define TAG_CLOSE   'xtaF'
 
#define TAG_STATS   'VtaF'
 
#define TAG_BUFFER   'OtaF'
 
#define TAG_VPB   'vtaF'
 
#define TAG_NAME   'ntaF'
 
#define TAG_SEARCH   'LtaF'
 
#define TAG_DIRENT   'DtaF'
 
#define ENTRIES_PER_SECTOR   (BLOCKSIZE / sizeof(FATDirEntry))
 
#define IRPCONTEXT_CANWAIT   0x0001
 
#define IRPCONTEXT_COMPLETE   0x0002
 
#define IRPCONTEXT_QUEUE   0x0004
 
#define IRPCONTEXT_PENDINGRETURNED   0x0008
 
#define IRPCONTEXT_DEFERRED_WRITE   0x0010
 
#define vfatAddToStat(Vcb, Stat, Inc)
 

Typedefs

typedef struct _BootSector BootSector
 
typedef struct _EAFileHeader FAT_EA_FILE_HEADER
 
typedef struct _EAFileHeaderPFAT_EA_FILE_HEADER
 
typedef struct _EASetHeader FAT_EA_SET_HEADER
 
typedef struct _EASetHeaderPFAT_EA_SET_HEADER
 
typedef struct _EAHeader FAT_EA_HEADER
 
typedef struct _EAHeaderPFAT_EA_HEADER
 
typedef struct _FATDirEntry FAT_DIR_ENTRY
 
typedef struct _FATDirEntryPFAT_DIR_ENTRY
 
typedef struct _slot slot
 
typedef struct _FATXDirEntry FATX_DIR_ENTRY
 
typedef struct _FATXDirEntryPFATX_DIR_ENTRY
 
typedef union _DIR_ENTRY DIR_ENTRY
 
typedef union _DIR_ENTRYPDIR_ENTRY
 
typedef struct FATINFOPFATINFO
 
typedef struct _HASHENTRY HASHENTRY
 
typedef struct DEVICE_EXTENSIONPDEVICE_EXTENSION
 
typedef NTSTATUS(* PGET_NEXT_CLUSTER) (PDEVICE_EXTENSION, ULONG, PULONG)
 
typedef NTSTATUS(* PFIND_AND_MARK_AVAILABLE_CLUSTER) (PDEVICE_EXTENSION, PULONG)
 
typedef NTSTATUS(* PWRITE_CLUSTER) (PDEVICE_EXTENSION, ULONG, ULONG, PULONG)
 
typedef BOOLEAN(* PIS_DIRECTORY_EMPTY) (PDEVICE_EXTENSION, struct _VFATFCB *)
 
typedef NTSTATUS(* PADD_ENTRY) (PDEVICE_EXTENSION, PUNICODE_STRING, struct _VFATFCB **, struct _VFATFCB *, ULONG, UCHAR, struct _VFAT_MOVE_CONTEXT *)
 
typedef NTSTATUS(* PDEL_ENTRY) (PDEVICE_EXTENSION, struct _VFATFCB *, struct _VFAT_MOVE_CONTEXT *)
 
typedef NTSTATUS(* PGET_NEXT_DIR_ENTRY) (PVOID *, PVOID *, struct _VFATFCB *, struct _VFAT_DIRENTRY_CONTEXT *, BOOLEAN)
 
typedef NTSTATUS(* PGET_DIRTY_STATUS) (PDEVICE_EXTENSION, PBOOLEAN)
 
typedef NTSTATUS(* PSET_DIRTY_STATUS) (PDEVICE_EXTENSION, BOOLEAN)
 
typedef struct _VFAT_DISPATCH VFAT_DISPATCH
 
typedef struct _VFAT_DISPATCHPVFAT_DISPATCH
 
typedef struct _STATISTICS STATISTICS
 
typedef struct _STATISTICSPSTATISTICS
 
typedef struct DEVICE_EXTENSION DEVICE_EXTENSION
 
typedef struct DEVICE_EXTENSION VCB
 
typedef struct DEVICE_EXTENSIONPVCB
 
typedef struct VFAT_GLOBAL_DATAPVFAT_GLOBAL_DATA
 
typedef struct _VFATFCB VFATFCB
 
typedef struct _VFATFCBPVFATFCB
 
typedef struct _VFATCCB VFATCCB
 
typedef struct _VFATCCBPVFATCCB
 
typedef struct __DOSTIME DOSTIME
 
typedef struct __DOSTIMEPDOSTIME
 
typedef struct __DOSDATE DOSDATE
 
typedef struct __DOSDATEPDOSDATE
 
typedef struct VFAT_IRP_CONTEXTPVFAT_IRP_CONTEXT
 
typedef struct _VFAT_DIRENTRY_CONTEXT VFAT_DIRENTRY_CONTEXT
 
typedef struct _VFAT_DIRENTRY_CONTEXTPVFAT_DIRENTRY_CONTEXT
 
typedef struct _VFAT_MOVE_CONTEXT VFAT_MOVE_CONTEXT
 
typedef struct _VFAT_MOVE_CONTEXTPVFAT_MOVE_CONTEXT
 
typedef struct _VFAT_CLOSE_CONTEXT VFAT_CLOSE_CONTEXT
 
typedef struct _VFAT_CLOSE_CONTEXTPVFAT_CLOSE_CONTEXT
 

Functions

FORCEINLINE BOOLEAN VfatIsDirectoryEmpty (PDEVICE_EXTENSION DeviceExt, struct _VFATFCB *Fcb)
 
FORCEINLINE NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING NameU, struct _VFATFCB **Fcb, struct _VFATFCB *ParentFcb, ULONG RequestedOptions, UCHAR ReqAttr, struct _VFAT_MOVE_CONTEXT *MoveContext)
 
FORCEINLINE NTSTATUS VfatDelEntry (PDEVICE_EXTENSION DeviceExt, struct _VFATFCB *Fcb, struct _VFAT_MOVE_CONTEXT *MoveContext)
 
FORCEINLINE NTSTATUS VfatGetNextDirEntry (PDEVICE_EXTENSION DeviceExt, PVOID *pContext, PVOID *pPage, struct _VFATFCB *pDirFcb, struct _VFAT_DIRENTRY_CONTEXT *DirContext, BOOLEAN First)
 
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue (PVFAT_IRP_CONTEXT IrpContext)
 
FORCEINLINE BOOLEAN vfatFCBIsDirectory (PVFATFCB FCB)
 
FORCEINLINE BOOLEAN vfatFCBIsReadOnly (PVFATFCB FCB)
 
FORCEINLINE BOOLEAN vfatVolumeIsFatX (PDEVICE_EXTENSION DeviceExt)
 
FORCEINLINE VOID vfatReportChange (IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
 
NTSTATUS VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN PUCHAR Buffer, IN BOOLEAN Override)
 
NTSTATUS VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN ULONG BufferOffset, IN BOOLEAN Wait)
 
NTSTATUS VfatWriteDisk (IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
 
NTSTATUS VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN ULONG BufferOffset, IN BOOLEAN Wait)
 
NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, IN OUT PULONG pOutputBufferSize, IN BOOLEAN Override)
 
NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
 
NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Parent, PUNICODE_STRING FileToFindU, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First)
 
VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
 
NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext)
 
BOOLEAN FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime)
 
BOOLEAN FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, USHORT *pDosDate, USHORT *pDosTime)
 
ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pDirEntry)
 
NTSTATUS vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb)
 
NTSTATUS VfatUpdateEntry (IN PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
 
BOOLEAN vfatFindDirSpace (PDEVICE_EXTENSION DeviceExt, PVFATFCB pDirFcb, ULONG nbSlots, PULONG start)
 
NTSTATUS vfatRenameEntry (IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN BOOLEAN CaseChangeOnly)
 
NTSTATUS VfatMoveEntry (IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN PVFATFCB ParentFcb)
 
NTSTATUS VfatSetExtendedAttributes (PFILE_OBJECT FileObject, PVOID Ea, ULONG EaLength)
 
VOID VfatInitFastIoRoutines (PFAST_IO_DISPATCH FastIoDispatch)
 
BOOLEAN NTAPI VfatAcquireForLazyWrite (IN PVOID Context, IN BOOLEAN Wait)
 
VOID NTAPI VfatReleaseFromLazyWrite (IN PVOID Context)
 
NTSTATUS FAT12GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS FAT12FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
 
NTSTATUS FAT12WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
 
NTSTATUS FAT16GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS FAT16FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
 
NTSTATUS FAT16WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
 
NTSTATUS FAT32GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS FAT32FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
 
NTSTATUS FAT32WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
 
NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, BOOLEAN Extend)
 
ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt, ULONG Cluster)
 
NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS GetNextClusterExtend (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER Clusters)
 
NTSTATUS WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
 
NTSTATUS GetDirtyStatus (PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
 
NTSTATUS FAT16GetDirtyStatus (PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
 
NTSTATUS FAT32GetDirtyStatus (PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
 
NTSTATUS SetDirtyStatus (PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
 
NTSTATUS FAT16SetDirtyStatus (PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
 
NTSTATUS FAT32SetDirtyStatus (PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
 
NTSTATUS FAT32UpdateFreeClustersCount (PDEVICE_EXTENSION DeviceExt)
 
PVFATFCB vfatNewFCB (PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU)
 
NTSTATUS vfatSetFCBNewDirName (PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFATFCB ParentFcb)
 
NTSTATUS vfatUpdateFCB (PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB ParentFcb)
 
VOID vfatDestroyFCB (PVFATFCB pFCB)
 
VOID vfatDestroyCCB (PVFATCCB pCcb)
 
VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
 
VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
 
PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt, PUNICODE_STRING pFileNameU)
 
PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB)
 
PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB)
 
BOOLEAN vfatFCBIsRoot (PVFATFCB FCB)
 
NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
 
NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB, PVFATFCB parentFCB, PUNICODE_STRING FileToFindU, PVFATFCB *fileFCB)
 
NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
 
NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb, PVFATFCB directoryFCB, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB *fileFCB)
 
NTSTATUS VfatGetStandardInformation (PVFATFCB FCB, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength)
 
NTSTATUS VfatGetBasicInformation (PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
 
NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatSetAllocationSizeInformation (PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
 
NTSTATUS VfatFlush (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatFlushVolume (PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb)
 
NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS NTAPI DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI VfatBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
PVOID VfatGetUserBuffer (IN PIRP Irp, IN BOOLEAN Paging)
 
NTSTATUS VfatLockUserBuffer (IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
 
BOOLEAN VfatCheckForDismount (IN PDEVICE_EXTENSION DeviceExt, IN BOOLEAN Create)
 
VOID NTAPI VfatHandleDeferredWrite (IN PVOID IrpContext, IN PVOID Unused)
 
NTSTATUS VfatPnp (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT *pIrpContext)
 
NTSTATUS NextCluster (PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
 
NTSTATUS NTAPI VfatShutdown (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
VOID vfatSplitPathName (PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
 
BOOLEAN vfatIsLongIllegal (WCHAR c)
 
BOOLEAN IsDotOrDotDot (PCUNICODE_STRING Name)
 
NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext)
 
NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext)
 

Variables

PVFAT_GLOBAL_DATA VfatGlobalData
 
DRIVER_DISPATCH VfatBuildRequest
 
DRIVER_DISPATCH VfatShutdown
 

Macro Definition Documentation

◆ BLOCKSIZE

#define BLOCKSIZE   512

Definition at line 232 of file vfat.h.

◆ CCB_DELETE_ON_CLOSE

#define CCB_DELETE_ON_CLOSE   0x0001

Definition at line 534 of file vfat.h.

◆ ENABLE_SWAPOUT

#define ENABLE_SWAPOUT

Definition at line 16 of file vfat.h.

◆ ENTRIES_PER_SECTOR

#define ENTRIES_PER_SECTOR   (BLOCKSIZE / sizeof(FATDirEntry))

Definition at line 557 of file vfat.h.

◆ ENTRY_DELETED

#define ENTRY_DELETED (   IsFatX,
  DirEntry 
)    (IsFatX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))

Definition at line 205 of file vfat.h.

◆ ENTRY_END

#define ENTRY_END (   IsFatX,
  DirEntry 
)    (IsFatX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))

Definition at line 207 of file vfat.h.

◆ ENTRY_VOLUME

#define ENTRY_VOLUME (   IsFatX,
  DirEntry 
)    (IsFatX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))

Definition at line 206 of file vfat.h.

◆ FAT12

#define FAT12   (2)

Definition at line 235 of file vfat.h.

◆ FAT16

#define FAT16   (1)

Definition at line 234 of file vfat.h.

◆ FAT32

#define FAT32   (3)

Definition at line 236 of file vfat.h.

◆ FAT_DIRTY_BIT

#define FAT_DIRTY_BIT   0x01

Definition at line 85 of file vfat.h.

◆ FAT_EAFILE

#define FAT_EAFILE   "EA DATA. SF"

Definition at line 132 of file vfat.h.

◆ FAT_ENTRIES_PER_PAGE

#define FAT_ENTRIES_PER_PAGE   (PAGE_SIZE / sizeof (FAT_DIR_ENTRY))

Definition at line 219 of file vfat.h.

◆ FAT_ENTRY_DELETED

#define FAT_ENTRY_DELETED (   DirEntry)    ((DirEntry)->Filename[0] == 0xe5)

Definition at line 209 of file vfat.h.

◆ FAT_ENTRY_END

#define FAT_ENTRY_END (   DirEntry)    ((DirEntry)->Filename[0] == 0)

Definition at line 210 of file vfat.h.

◆ FAT_ENTRY_LONG

#define FAT_ENTRY_LONG (   DirEntry)    (((DirEntry)->Attrib & 0x3f) == 0x0f)

Definition at line 211 of file vfat.h.

◆ FAT_ENTRY_VOLUME

#define FAT_ENTRY_VOLUME (   DirEntry)    (((DirEntry)->Attrib & 0x1f) == 0x08)

Definition at line 212 of file vfat.h.

◆ FATX16

#define FATX16   (4)

Definition at line 237 of file vfat.h.

◆ FATX32

#define FATX32   (5)

Definition at line 238 of file vfat.h.

◆ FATX_ENTRIES_PER_PAGE

#define FATX_ENTRIES_PER_PAGE   (PAGE_SIZE / sizeof (FATX_DIR_ENTRY))

Definition at line 220 of file vfat.h.

◆ FATX_ENTRY_DELETED

#define FATX_ENTRY_DELETED (   DirEntry)    ((DirEntry)->FilenameLength == 0xe5)

Definition at line 214 of file vfat.h.

◆ FATX_ENTRY_END

#define FATX_ENTRY_END (   DirEntry)    ((DirEntry)->FilenameLength == 0xff)

Definition at line 215 of file vfat.h.

◆ FATX_ENTRY_LONG

#define FATX_ENTRY_LONG (   DirEntry)    (FALSE)

Definition at line 216 of file vfat.h.

◆ FATX_ENTRY_VOLUME

#define FATX_ENTRY_VOLUME (   DirEntry)    (((DirEntry)->Attrib & 0x1f) == 0x08)

Definition at line 217 of file vfat.h.

◆ FCB_CACHE_INITIALIZED

#define FCB_CACHE_INITIALIZED   0x0001

Definition at line 433 of file vfat.h.

◆ FCB_DELAYED_CLOSE

#define FCB_DELAYED_CLOSE   0x0040

Definition at line 439 of file vfat.h.

◆ FCB_DELETE_PENDING

#define FCB_DELETE_PENDING   0x0002

Definition at line 434 of file vfat.h.

◆ FCB_IS_DIRTY

#define FCB_IS_DIRTY   0x0020

Definition at line 438 of file vfat.h.

◆ FCB_IS_FAT

#define FCB_IS_FAT   0x0004

Definition at line 435 of file vfat.h.

◆ FCB_IS_PAGE_FILE

#define FCB_IS_PAGE_FILE   0x0008

Definition at line 436 of file vfat.h.

◆ FCB_IS_VOLUME

#define FCB_IS_VOLUME   0x0010

Definition at line 437 of file vfat.h.

◆ IRPCONTEXT_CANWAIT

#define IRPCONTEXT_CANWAIT   0x0001

Definition at line 575 of file vfat.h.

◆ IRPCONTEXT_COMPLETE

#define IRPCONTEXT_COMPLETE   0x0002

Definition at line 576 of file vfat.h.

◆ IRPCONTEXT_DEFERRED_WRITE

#define IRPCONTEXT_DEFERRED_WRITE   0x0010

Definition at line 579 of file vfat.h.

◆ IRPCONTEXT_PENDINGRETURNED

#define IRPCONTEXT_PENDINGRETURNED   0x0008

Definition at line 578 of file vfat.h.

◆ IRPCONTEXT_QUEUE

#define IRPCONTEXT_QUEUE   0x0004

Definition at line 577 of file vfat.h.

◆ LONGNAME_MAX_LENGTH

#define LONGNAME_MAX_LENGTH   256

Definition at line 203 of file vfat.h.

◆ NODE_TYPE_FCB

#define NODE_TYPE_FCB   ((CSHORT)0x0502)

Definition at line 445 of file vfat.h.

◆ ROUND_DOWN

#define ROUND_DOWN (   n,
  align 
)     (((ULONG)n) & ~((align) - 1l))

Definition at line 25 of file vfat.h.

◆ ROUND_DOWN_64

#define ROUND_DOWN_64 (   n,
  align 
)     (((ULONGLONG)n) & ~((align) - 1LL))

Definition at line 31 of file vfat.h.

◆ ROUND_UP

#define ROUND_UP (   n,
  align 
)     ROUND_DOWN(((ULONG)n) + (align) - 1, (align))

Definition at line 28 of file vfat.h.

◆ ROUND_UP_64

#define ROUND_UP_64 (   n,
  align 
)     ROUND_DOWN_64(((ULONGLONG)n) + (align) - 1LL, (align))

Definition at line 34 of file vfat.h.

◆ STATISTICS_SIZE_NO_PAD

#define STATISTICS_SIZE_NO_PAD   (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS))

Definition at line 304 of file vfat.h.

◆ TAG_BUFFER

#define TAG_BUFFER   'OtaF'

Definition at line 551 of file vfat.h.

◆ TAG_CCB

#define TAG_CCB   'CtaF'

Definition at line 546 of file vfat.h.

◆ TAG_CLOSE

#define TAG_CLOSE   'xtaF'

Definition at line 549 of file vfat.h.

◆ TAG_DIRENT

#define TAG_DIRENT   'DtaF'

Definition at line 555 of file vfat.h.

◆ TAG_FCB

#define TAG_FCB   'FtaF'

Definition at line 547 of file vfat.h.

◆ TAG_IRP

#define TAG_IRP   'ItaF'

Definition at line 548 of file vfat.h.

◆ TAG_NAME

#define TAG_NAME   'ntaF'

Definition at line 553 of file vfat.h.

◆ TAG_SEARCH

#define TAG_SEARCH   'LtaF'

Definition at line 554 of file vfat.h.

◆ TAG_STATS

#define TAG_STATS   'VtaF'

Definition at line 550 of file vfat.h.

◆ TAG_VPB

#define TAG_VPB   'vtaF'

Definition at line 552 of file vfat.h.

◆ USE_ROS_CC_AND_FS

#define USE_ROS_CC_AND_FS

Definition at line 15 of file vfat.h.

◆ VCB_CLEAR_DIRTY

#define VCB_CLEAR_DIRTY   0x8000 /* Clean dirty flag at shutdown */

Definition at line 245 of file vfat.h.

◆ VCB_DISMOUNT_PENDING

#define VCB_DISMOUNT_PENDING   0x0002

Definition at line 241 of file vfat.h.

◆ VCB_GOOD

#define VCB_GOOD   0x0010 /* If not set, the VCB is improper for usage */

Definition at line 247 of file vfat.h.

◆ VCB_IS_DIRTY

#define VCB_IS_DIRTY   0x4000 /* Volume is dirty */

Definition at line 244 of file vfat.h.

◆ VCB_IS_FATX

#define VCB_IS_FATX   0x0004

Definition at line 242 of file vfat.h.

◆ VCB_IS_SYS_OR_HAS_PAGE

#define VCB_IS_SYS_OR_HAS_PAGE   0x0008

Definition at line 243 of file vfat.h.

◆ VCB_VOLUME_LOCKED

#define VCB_VOLUME_LOCKED   0x0001

Definition at line 240 of file vfat.h.

◆ VFAT_BREAK_ON_CORRUPTION

#define VFAT_BREAK_ON_CORRUPTION   1

Definition at line 407 of file vfat.h.

◆ VFAT_CASE_LOWER_BASE

#define VFAT_CASE_LOWER_BASE   8

Definition at line 200 of file vfat.h.

◆ VFAT_CASE_LOWER_EXT

#define VFAT_CASE_LOWER_EXT   16

Definition at line 201 of file vfat.h.

◆ vfatAddToStat

#define vfatAddToStat (   Vcb,
  Stat,
  Inc 
)
Value:
{ \
Stats->Stat += Inc; \
}
#define Vcb
Definition: cdprocs.h:1415
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
ULONG NumberProcessors
Definition: vfat.h:414
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18

Definition at line 671 of file vfat.h.

◆ VOLUME_IS_NOT_CACHED_WORK_AROUND_IT

#define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT

Definition at line 22 of file vfat.h.

Typedef Documentation

◆ BootSector

Definition at line 108 of file vfat.h.

◆ DEVICE_EXTENSION

◆ DIR_ENTRY

typedef union _DIR_ENTRY DIR_ENTRY

Definition at line 230 of file vfat.h.

◆ DOSDATE

◆ DOSTIME

◆ FAT_DIR_ENTRY

Definition at line 167 of file vfat.h.

◆ FAT_EA_FILE_HEADER

Definition at line 134 of file vfat.h.

◆ FAT_EA_HEADER

Definition at line 156 of file vfat.h.

◆ FAT_EA_SET_HEADER

Definition at line 143 of file vfat.h.

◆ FATX_DIR_ENTRY

Definition at line 222 of file vfat.h.

◆ HASHENTRY

◆ PADD_ENTRY

Definition at line 290 of file vfat.h.

◆ PDEL_ENTRY

Definition at line 291 of file vfat.h.

◆ PDEVICE_EXTENSION

Definition at line 283 of file vfat.h.

◆ PDIR_ENTRY

typedef union _DIR_ENTRY * PDIR_ENTRY

Definition at line 230 of file vfat.h.

◆ PDOSDATE

◆ PDOSTIME

◆ PFAT_DIR_ENTRY

Definition at line 167 of file vfat.h.

◆ PFAT_EA_FILE_HEADER

Definition at line 134 of file vfat.h.

◆ PFAT_EA_HEADER

Definition at line 156 of file vfat.h.

◆ PFAT_EA_SET_HEADER

Definition at line 143 of file vfat.h.

◆ PFATINFO

typedef struct FATINFO * PFATINFO

◆ PFATX_DIR_ENTRY

Definition at line 222 of file vfat.h.

◆ PFIND_AND_MARK_AVAILABLE_CLUSTER

typedef NTSTATUS(* PFIND_AND_MARK_AVAILABLE_CLUSTER) (PDEVICE_EXTENSION, PULONG)

Definition at line 286 of file vfat.h.

◆ PGET_DIRTY_STATUS

typedef NTSTATUS(* PGET_DIRTY_STATUS) (PDEVICE_EXTENSION, PBOOLEAN)

Definition at line 293 of file vfat.h.

◆ PGET_NEXT_CLUSTER

typedef NTSTATUS(* PGET_NEXT_CLUSTER) (PDEVICE_EXTENSION, ULONG, PULONG)

Definition at line 285 of file vfat.h.

◆ PGET_NEXT_DIR_ENTRY

typedef NTSTATUS(* PGET_NEXT_DIR_ENTRY) (PVOID *, PVOID *, struct _VFATFCB *, struct _VFAT_DIRENTRY_CONTEXT *, BOOLEAN)

Definition at line 292 of file vfat.h.

◆ PIS_DIRECTORY_EMPTY

typedef BOOLEAN(* PIS_DIRECTORY_EMPTY) (PDEVICE_EXTENSION, struct _VFATFCB *)

Definition at line 289 of file vfat.h.

◆ PSET_DIRTY_STATUS

typedef NTSTATUS(* PSET_DIRTY_STATUS) (PDEVICE_EXTENSION, BOOLEAN)

Definition at line 294 of file vfat.h.

◆ PSTATISTICS

◆ PVCB

◆ PVFAT_CLOSE_CONTEXT

◆ PVFAT_DIRENTRY_CONTEXT

◆ PVFAT_DISPATCH

◆ PVFAT_GLOBAL_DATA

◆ PVFAT_IRP_CONTEXT

◆ PVFAT_MOVE_CONTEXT

◆ PVFATCCB

◆ PVFATFCB

◆ PWRITE_CLUSTER

typedef NTSTATUS(* PWRITE_CLUSTER) (PDEVICE_EXTENSION, ULONG, ULONG, PULONG)

Definition at line 287 of file vfat.h.

◆ slot

typedef struct _slot slot

Definition at line 196 of file vfat.h.

◆ STATISTICS

◆ VCB

◆ VFAT_CLOSE_CONTEXT

◆ VFAT_DIRENTRY_CONTEXT

◆ VFAT_DISPATCH

◆ VFAT_MOVE_CONTEXT

◆ VFATCCB

◆ VFATFCB

Function Documentation

◆ ClusterToSector()

ULONGLONG ClusterToSector ( PDEVICE_EXTENSION  DeviceExt,
ULONG  Cluster 
)

Definition at line 731 of file fat.c.

734{
735 return DeviceExt->FatInfo.dataStart +
736 ((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
737
738}
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by VfatReadFileData(), and VfatWriteFileData().

◆ CountAvailableClusters()

NTSTATUS CountAvailableClusters ( PDEVICE_EXTENSION  DeviceExt,
PLARGE_INTEGER  Clusters 
)

Definition at line 541 of file fat.c.

544{
546 ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
547 if (!DeviceExt->AvailableClustersValid)
548 {
549 if (DeviceExt->FatInfo.FatType == FAT12)
551 else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
553 else
555 }
556 if (Clusters != NULL)
557 {
558 Clusters->QuadPart = DeviceExt->AvailableClusters;
559 }
560 ExReleaseResourceLite (&DeviceExt->FatResource);
561
562 return Status;
563}
LONG NTSTATUS
Definition: precomp.h:26
#define FATX16
Definition: fat.h:170
#define FAT12
Definition: fat.h:167
#define FAT16
Definition: fat.h:168
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
static NTSTATUS FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:490
static NTSTATUS FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:381
static NTSTATUS FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:435
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
Status
Definition: gdiplustypes.h:25
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_SUCCESS
Definition: shellext.h:65
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by FsdGetFsFullSizeInformation(), FsdGetFsSizeInformation(), and VfatMount().

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( PDRIVER_OBJECT  DriverObject,
PUNICODE_STRING  RegistryPath 
)

Definition at line 16 of file battc.c.

18{
19 DPRINT("Battery class driver initialized\n");
20
21 return STATUS_SUCCESS;
22}
#define DPRINT
Definition: sndvol32.h:71

◆ FAT12FindAndMarkAvailableCluster()

NTSTATUS FAT12FindAndMarkAvailableCluster ( PDEVICE_EXTENSION  DeviceExt,
PULONG  Cluster 
)

Definition at line 244 of file fat.c.

247{
248 ULONG FatLength;
249 ULONG StartCluster;
250 ULONG Entry;
251 PUSHORT CBlock;
252 ULONG i, j;
256
257 FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
258 *Cluster = 0;
259 StartCluster = DeviceExt->LastAvailableCluster;
260 Offset.QuadPart = 0;
262 {
263 CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, PIN_WAIT, &Context, &BaseAddress);
264 }
266 {
267 DPRINT1("CcPinRead(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
269 }
270 _SEH2_END;
271
272 for (j = 0; j < 2; j++)
273 {
274 for (i = StartCluster; i < FatLength; i++)
275 {
276 CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
277 if ((i % 2) == 0)
278 {
279 Entry = *CBlock & 0xfff;
280 }
281 else
282 {
283 Entry = *CBlock >> 4;
284 }
285
286 if (Entry == 0)
287 {
288 DPRINT("Found available cluster 0x%x\n", i);
289 DeviceExt->LastAvailableCluster = *Cluster = i;
290 if ((i % 2) == 0)
291 *CBlock = (*CBlock & 0xf000) | 0xfff;
292 else
293 *CBlock = (*CBlock & 0xf) | 0xfff0;
296 if (DeviceExt->AvailableClustersValid)
297 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
298 return STATUS_SUCCESS;
299 }
300 }
301 FatLength = StartCluster;
302 StartCluster = 2;
303 }
305 return STATUS_DISK_FULL;
306}
#define InterlockedDecrement
Definition: armddk.h:52
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define PIN_WAIT
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_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
base of all file and directory entries
Definition: entries.h:83
uint16_t * PUSHORT
Definition: typedefs.h:56
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155

Referenced by VfatMount().

◆ FAT12GetNextCluster()

NTSTATUS FAT12GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 123 of file fat.c.

127{
128 PUSHORT CBlock;
129 ULONG Entry;
133
134 *NextCluster = 0;
135
136 Offset.QuadPart = 0;
138 {
139 CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, MAP_WAIT, &Context, &BaseAddress);
140 }
142 {
144 }
145 _SEH2_END;
146
147 CBlock = (PUSHORT)((char*)BaseAddress + (CurrentCluster * 12) / 8);
148 if ((CurrentCluster % 2) == 0)
149 {
150 Entry = *CBlock & 0x0fff;
151 }
152 else
153 {
154 Entry = *CBlock >> 4;
155 }
156
157// DPRINT("Entry %x\n",Entry);
158 if (Entry >= 0xff8 && Entry <= 0xfff)
159 Entry = 0xffffffff;
160
161// DPRINT("Returning %x\n",Entry);
162 ASSERT(Entry != 0);
165// return Entry == 0xffffffff ? STATUS_END_OF_FILE : STATUS_SUCCESS;
166 return STATUS_SUCCESS;
167}
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:38
#define ASSERT(a)
Definition: mode.c:44
#define MAP_WAIT
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 VfatMount().

◆ FAT12WriteCluster()

NTSTATUS FAT12WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue,
PULONG  OldValue 
)

Definition at line 570 of file fat.c.

575{
576 ULONG FATOffset;
577 PUCHAR CBlock;
581
582 Offset.QuadPart = 0;
584 {
585 CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, PIN_WAIT, &Context, &BaseAddress);
586 }
588 {
590 }
591 _SEH2_END;
592 CBlock = (PUCHAR)BaseAddress;
593
594 FATOffset = (ClusterToWrite * 12) / 8;
595 DPRINT("Writing 0x%x for 0x%x at 0x%x\n",
596 NewValue, ClusterToWrite, FATOffset);
597 if ((ClusterToWrite % 2) == 0)
598 {
599 *OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
600 CBlock[FATOffset] = (UCHAR)NewValue;
601 CBlock[FATOffset + 1] &= 0xf0;
602 CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
603 }
604 else
605 {
606 *OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
607 CBlock[FATOffset] &= 0x0f;
608 CBlock[FATOffset] |= (NewValue & 0xf) << 4;
609 CBlock[FATOffset + 1] = (UCHAR)(NewValue >> 4);
610 }
611 /* Write the changed FAT sector(s) to disk */
614 return STATUS_SUCCESS;
615}
unsigned char * PUCHAR
Definition: typedefs.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by VfatMount().

◆ FAT16FindAndMarkAvailableCluster()

NTSTATUS FAT16FindAndMarkAvailableCluster ( PDEVICE_EXTENSION  DeviceExt,
PULONG  Cluster 
)

Definition at line 173 of file fat.c.

176{
177 ULONG FatLength;
178 ULONG StartCluster;
179 ULONG i, j;
182 PVOID Context = 0;
184 PUSHORT Block;
185 PUSHORT BlockEnd;
186
187 ChunkSize = CACHEPAGESIZE(DeviceExt);
188 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
189 *Cluster = 0;
190 StartCluster = DeviceExt->LastAvailableCluster;
191
192 for (j = 0; j < 2; j++)
193 {
194 for (i = StartCluster; i < FatLength;)
195 {
196 Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
198 {
199 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
200 }
202 {
203 DPRINT1("CcPinRead(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
205 }
206 _SEH2_END;
207
208 Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
209 BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
210
211 /* Now process the whole block */
212 while (Block < BlockEnd && i < FatLength)
213 {
214 if (*Block == 0)
215 {
216 DPRINT("Found available cluster 0x%x\n", i);
217 DeviceExt->LastAvailableCluster = *Cluster = i;
218 *Block = 0xffff;
221 if (DeviceExt->AvailableClustersValid)
222 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
223 return STATUS_SUCCESS;
224 }
225
226 Block++;
227 i++;
228 }
229
231 }
232
233 FatLength = StartCluster;
234 StartCluster = 2;
235 }
236
237 return STATUS_DISK_FULL;
238}
#define CACHEPAGESIZE(pDeviceExt)
Definition: fat.c:18
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize
Definition: rtlfuncs.h:2277

Referenced by VfatMount().

◆ FAT16GetDirtyStatus()

NTSTATUS FAT16GetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
PBOOLEAN  DirtyStatus 
)

Definition at line 858 of file fat.c.

861{
864#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
866#else
868#endif
869 struct _BootSector * Sector;
870
871 /* We'll read the bootsector at 0 */
872 Offset.QuadPart = 0;
873 Length = DeviceExt->FatInfo.BytesPerSector;
874#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
875 /* Go through Cc for this */
877 {
878 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
879 }
881 {
883 }
884 _SEH2_END;
885#else
886 /* No Cc, do it the old way:
887 * - Allocate a big enough buffer
888 * - And read the disk
889 */
891 if (Sector == NULL)
892 {
893 *DirtyStatus = TRUE;
895 }
896
897 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
898 if (!NT_SUCCESS(Status))
899 {
900 *DirtyStatus = TRUE;
902 return Status;
903 }
904#endif
905
906 /* Make sure we have a boot sector...
907 * FIXME: This check is a bit lame and should be improved
908 */
909 if (Sector->Signatur1 != 0xaa55)
910 {
911 /* Set we are dirty so that we don't attempt anything */
912 *DirtyStatus = TRUE;
913#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
915#else
917#endif
919 }
920
921 /* Return the status of the dirty bit */
922 if (Sector->Res1 & FAT_DIRTY_BIT)
923 *DirtyStatus = TRUE;
924 else
925 *DirtyStatus = FALSE;
926
927#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
929#else
931#endif
932 return STATUS_SUCCESS;
933}
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short Signatur1
Definition: vfat.h:54
unsigned char Res1
Definition: vfat.h:50
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FAT_DIRTY_BIT
Definition: vfat.h:85
#define TAG_BUFFER
Definition: vfat.h:551
NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:70

Referenced by VfatMount().

◆ FAT16GetNextCluster()

NTSTATUS FAT16GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 77 of file fat.c.

81{
84 ULONG FATOffset;
88
89 ChunkSize = CACHEPAGESIZE(DeviceExt);
90 FATOffset = CurrentCluster * 2;
91 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
93 {
94 CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress);
95 }
97 {
99 }
100 _SEH2_END;
101
102 CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
103 if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
104 CurrentCluster = 0xffffffff;
105
106 if (CurrentCluster == 0)
107 {
108 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
111 ASSERT(CurrentCluster != 0);
112 }
113
115 *NextCluster = CurrentCluster;
116 return Status;
117}
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
ULONG Flags
Definition: vfat.h:413
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define VFAT_BREAK_ON_CORRUPTION
Definition: vfat.h:407

Referenced by VfatMount().

◆ FAT16SetDirtyStatus()

NTSTATUS FAT16SetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
BOOLEAN  DirtyStatus 
)

Definition at line 1044 of file fat.c.

1047{
1049 ULONG Length;
1050#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1052#else
1053 PVOID Context;
1054#endif
1055 struct _BootSector * Sector;
1056
1057 /* We'll read (and then write) the bootsector at 0 */
1058 Offset.QuadPart = 0;
1059 Length = DeviceExt->FatInfo.BytesPerSector;
1060#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1061 /* Go through Cc for this */
1062 _SEH2_TRY
1063 {
1064 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
1065 }
1067 {
1069 }
1070 _SEH2_END;
1071#else
1072 /* No Cc, do it the old way:
1073 * - Allocate a big enough buffer
1074 * - And read the disk
1075 */
1077 if (Sector == NULL)
1078 {
1080 }
1081
1082 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1083 if (!NT_SUCCESS(Status))
1084 {
1086 return Status;
1087 }
1088#endif
1089
1090 /* Make sure we have a boot sector...
1091 * FIXME: This check is a bit lame and should be improved
1092 */
1093 if (Sector->Signatur1 != 0xaa55)
1094 {
1095#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1097#else
1099#endif
1101 }
1102
1103 /* Modify the dirty bit status according
1104 * to caller needs
1105 */
1106 if (!DirtyStatus)
1107 {
1108 Sector->Res1 &= ~FAT_DIRTY_BIT;
1109 }
1110 else
1111 {
1112 Sector->Res1 |= FAT_DIRTY_BIT;
1113 }
1114
1115#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1116 /* Mark boot sector dirty so that it gets written to the disk */
1119 return STATUS_SUCCESS;
1120#else
1121 /* Write back the boot sector to the disk */
1122 Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1124 return Status;
1125#endif
1126}
NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:253

Referenced by VfatMount().

◆ FAT16WriteCluster()

NTSTATUS FAT16WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue,
PULONG  OldValue 
)

Definition at line 621 of file fat.c.

626{
628 ULONG FATOffset;
632 PUSHORT Cluster;
633
634 ChunkSize = CACHEPAGESIZE(DeviceExt);
635 FATOffset = ClusterToWrite * 2;
636 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
638 {
639 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
640 }
642 {
644 }
645 _SEH2_END;
646
647 DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
648 ClusterToWrite);
649 Cluster = ((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
650 *OldValue = *Cluster;
651 *Cluster = (USHORT)NewValue;
654 return STATUS_SUCCESS;
655}
unsigned short USHORT
Definition: pedump.c:61

Referenced by VfatMount().

◆ FAT32FindAndMarkAvailableCluster()

NTSTATUS FAT32FindAndMarkAvailableCluster ( PDEVICE_EXTENSION  DeviceExt,
PULONG  Cluster 
)

Definition at line 312 of file fat.c.

315{
316 ULONG FatLength;
317 ULONG StartCluster;
318 ULONG i, j;
323 PULONG Block;
324 PULONG BlockEnd;
325
326 ChunkSize = CACHEPAGESIZE(DeviceExt);
327 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
328 *Cluster = 0;
329 StartCluster = DeviceExt->LastAvailableCluster;
330
331 for (j = 0; j < 2; j++)
332 {
333 for (i = StartCluster; i < FatLength;)
334 {
335 Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
337 {
338 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
339 }
341 {
342 DPRINT1("CcPinRead(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
344 }
345 _SEH2_END;
346 Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
347 BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
348
349 /* Now process the whole block */
350 while (Block < BlockEnd && i < FatLength)
351 {
352 if ((*Block & 0x0fffffff) == 0)
353 {
354 DPRINT("Found available cluster 0x%x\n", i);
355 DeviceExt->LastAvailableCluster = *Cluster = i;
356 *Block = 0x0fffffff;
359 if (DeviceExt->AvailableClustersValid)
360 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
361 return STATUS_SUCCESS;
362 }
363
364 Block++;
365 i++;
366 }
367
369 }
370 FatLength = StartCluster;
371 StartCluster = 2;
372 }
373 return STATUS_DISK_FULL;
374}
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by VfatMount().

◆ FAT32GetDirtyStatus()

NTSTATUS FAT32GetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
PBOOLEAN  DirtyStatus 
)

Definition at line 936 of file fat.c.

939{
942#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
944#else
946#endif
947 struct _BootSector32 * Sector;
948
949 /* We'll read the bootsector at 0 */
950 Offset.QuadPart = 0;
951 Length = DeviceExt->FatInfo.BytesPerSector;
952#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
953 /* Go through Cc for this */
955 {
956 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
957 }
959 {
961 }
962 _SEH2_END;
963#else
964 /* No Cc, do it the old way:
965 * - Allocate a big enough buffer
966 * - And read the disk
967 */
969 if (Sector == NULL)
970 {
971 *DirtyStatus = TRUE;
973 }
974
975 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
976 if (!NT_SUCCESS(Status))
977 {
978 *DirtyStatus = TRUE;
980 return Status;
981 }
982#endif
983
984 /* Make sure we have a boot sector...
985 * FIXME: This check is a bit lame and should be improved
986 */
987 if (Sector->Signature1 != 0xaa55)
988 {
989 /* Set we are dirty so that we don't attempt anything */
990 *DirtyStatus = TRUE;
991#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
993#else
995#endif
997 }
998
999 /* Return the status of the dirty bit */
1000 if (Sector->Res4 & FAT_DIRTY_BIT)
1001 *DirtyStatus = TRUE;
1002 else
1003 *DirtyStatus = FALSE;
1004
1005#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1007#else
1009#endif
1010 return STATUS_SUCCESS;
1011}
unsigned short Signature1
Definition: vfat.h:82
unsigned char Res4
Definition: vfat.h:77

Referenced by VfatMount().

◆ FAT32GetNextCluster()

NTSTATUS FAT32GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 28 of file fat.c.

32{
35 ULONG FATOffset;
39
40 ChunkSize = CACHEPAGESIZE(DeviceExt);
41 FATOffset = CurrentCluster * sizeof(ULONG);
42 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
44 {
45 if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
46 {
49 }
50 }
52 {
54 }
56
57 CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
58 if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
59 CurrentCluster = 0xffffffff;
60
61 if (CurrentCluster == 0)
62 {
63 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
66 ASSERT(CurrentCluster != 0);
67 }
69 *NextCluster = CurrentCluster;
70 return Status;
71}
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by VfatMount().

◆ FAT32SetDirtyStatus()

NTSTATUS FAT32SetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
BOOLEAN  DirtyStatus 
)

Definition at line 1129 of file fat.c.

1132{
1134 ULONG Length;
1135#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1137#else
1138 PVOID Context;
1139#endif
1140 struct _BootSector32 * Sector;
1141
1142 /* We'll read (and then write) the bootsector at 0 */
1143 Offset.QuadPart = 0;
1144 Length = DeviceExt->FatInfo.BytesPerSector;
1145#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1146 /* Go through Cc for this */
1147 _SEH2_TRY
1148 {
1149 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
1150 }
1152 {
1154 }
1155 _SEH2_END;
1156#else
1157 /* No Cc, do it the old way:
1158 * - Allocate a big enough buffer
1159 * - And read the disk
1160 */
1162 if (Sector == NULL)
1163 {
1165 }
1166
1167 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1168 if (!NT_SUCCESS(Status))
1169 {
1171 return Status;
1172 }
1173#endif
1174
1175 /* Make sure we have a boot sector...
1176 * FIXME: This check is a bit lame and should be improved
1177 */
1178 if (Sector->Signature1 != 0xaa55)
1179 {
1180 ASSERT(FALSE);
1181#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1183#else
1185#endif
1187 }
1188
1189 /* Modify the dirty bit status according
1190 * to caller needs
1191 */
1192 if (!DirtyStatus)
1193 {
1194 Sector->Res4 &= ~FAT_DIRTY_BIT;
1195 }
1196 else
1197 {
1198 Sector->Res4 |= FAT_DIRTY_BIT;
1199 }
1200
1201#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1202 /* Mark boot sector dirty so that it gets written to the disk */
1205 return STATUS_SUCCESS;
1206#else
1207 /* Write back the boot sector to the disk */
1208 Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1210 return Status;
1211#endif
1212}

Referenced by VfatMount().

◆ FAT32UpdateFreeClustersCount()

NTSTATUS FAT32UpdateFreeClustersCount ( PDEVICE_EXTENSION  DeviceExt)

Definition at line 1215 of file fat.c.

1217{
1219 ULONG Length;
1220#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1222#else
1223 PVOID Context;
1224#endif
1225 struct _FsInfoSector * Sector;
1226
1227 if (!DeviceExt->AvailableClustersValid)
1228 {
1230 }
1231
1232 /* We'll read (and then write) the fsinfo sector */
1233 Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector;
1234 Length = DeviceExt->FatInfo.BytesPerSector;
1235#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1236 /* Go through Cc for this */
1237 _SEH2_TRY
1238 {
1239 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
1240 }
1242 {
1244 }
1245 _SEH2_END;
1246#else
1247 /* No Cc, do it the old way:
1248 * - Allocate a big enough buffer
1249 * - And read the disk
1250 */
1252 if (Sector == NULL)
1253 {
1255 }
1256
1257 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1258 if (!NT_SUCCESS(Status))
1259 {
1261 return Status;
1262 }
1263#endif
1264
1265 /* Make sure we have a FSINFO sector */
1266 if (Sector->ExtBootSignature2 != 0x41615252 ||
1267 Sector->FSINFOSignature != 0x61417272 ||
1268 Sector->Signatur2 != 0xaa550000)
1269 {
1270 ASSERT(FALSE);
1271#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1273#else
1275#endif
1277 }
1278
1279 /* Update the free clusters count */
1280 Sector->FreeCluster = InterlockedCompareExchange((PLONG)&DeviceExt->AvailableClusters, 0, 0);
1281
1282#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1283 /* Mark FSINFO sector dirty so that it gets written to the disk */
1286 return STATUS_SUCCESS;
1287#else
1288 /* Write back the FSINFO sector to the disk */
1289 Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1291 return Status;
1292#endif
1293}
#define InterlockedCompareExchange
Definition: interlocked.h:104
unsigned long Signatur2
Definition: vfat.h:105
unsigned long FSINFOSignature
Definition: vfat.h:101
unsigned long FreeCluster
Definition: vfat.h:102
unsigned long ExtBootSignature2
Definition: vfat.h:99
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by FATAddEntry(), FATDelEntry(), and VfatSetAllocationSizeInformation().

◆ FAT32WriteCluster()

NTSTATUS FAT32WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue,
PULONG  OldValue 
)

Definition at line 661 of file fat.c.

666{
668 ULONG FATOffset;
672 PULONG Cluster;
673
674 ChunkSize = CACHEPAGESIZE(DeviceExt);
675
676 FATOffset = (ClusterToWrite * 4);
677 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
679 {
680 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
681 }
683 {
685 }
686 _SEH2_END;
687
688 DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
689 ClusterToWrite);
690 Cluster = ((PULONG)((char*)BaseAddress + (FATOffset % ChunkSize)));
691 *OldValue = *Cluster & 0x0fffffff;
692 *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
693
696
697 return STATUS_SUCCESS;
698}

Referenced by VfatMount().

◆ FindFile()

NTSTATUS FindFile ( PDEVICE_EXTENSION  DeviceExt,
PVFATFCB  Parent,
PUNICODE_STRING  FileToFindU,
PVFAT_DIRENTRY_CONTEXT  DirContext,
BOOLEAN  First 
)

Definition at line 83 of file create.c.

89{
90 PWCHAR PathNameBuffer;
91 USHORT PathNameBufferLength;
94 PVOID Page;
95 PVFATFCB rcFcb;
97 UNICODE_STRING PathNameU;
98 UNICODE_STRING FileToFindUpcase;
99 BOOLEAN WildCard;
100 BOOLEAN IsFatX = vfatVolumeIsFatX(DeviceExt);
101
102 DPRINT("FindFile(Parent %p, FileToFind '%wZ', DirIndex: %u)\n",
103 Parent, FileToFindU, DirContext->DirIndex);
104 DPRINT("FindFile: Path %wZ\n",&Parent->PathNameU);
105
106 PathNameBufferLength = LONGNAME_MAX_LENGTH * sizeof(WCHAR);
107 PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength + sizeof(WCHAR), TAG_NAME);
108 if (!PathNameBuffer)
109 {
111 }
112
113 PathNameU.Buffer = PathNameBuffer;
114 PathNameU.Length = 0;
115 PathNameU.MaximumLength = PathNameBufferLength;
116
117 DirContext->LongNameU.Length = 0;
118 DirContext->ShortNameU.Length = 0;
119
120 WildCard = FsRtlDoesNameContainWildCards(FileToFindU);
121
122 if (WildCard == FALSE)
123 {
124 /* if there is no '*?' in the search name, than look first for an existing fcb */
125 RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
126 if (!vfatFCBIsRoot(Parent))
127 {
128 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
129 PathNameU.Length += sizeof(WCHAR);
130 }
131 RtlAppendUnicodeStringToString(&PathNameU, FileToFindU);
132 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
133 rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
134 if (rcFcb)
135 {
136 ULONG startIndex = rcFcb->startIndex;
137 if (IsFatX && !vfatFCBIsRoot(Parent))
138 {
139 startIndex += 2;
140 }
141 if(startIndex >= DirContext->DirIndex)
142 {
143 RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
144 RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
145 RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
146 DirContext->StartIndex = rcFcb->startIndex;
147 DirContext->DirIndex = rcFcb->dirIndex;
148 DPRINT("FindFile: new Name %wZ, DirIndex %u (%u)\n",
149 &DirContext->LongNameU, DirContext->DirIndex, DirContext->StartIndex);
151 }
152 else
153 {
154 DPRINT("FCB not found for %wZ\n", &PathNameU);
156 }
157 vfatReleaseFCB(DeviceExt, rcFcb);
158 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
159 return Status;
160 }
161 }
162
163 /* FsRtlIsNameInExpression need the searched string to be upcase,
164 * even if IgnoreCase is specified */
165 Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFindU, TRUE);
166 if (!NT_SUCCESS(Status))
167 {
168 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
169 return Status;
170 }
171
172 while (TRUE)
173 {
175 First = FALSE;
177 {
178 break;
179 }
180 if (ENTRY_VOLUME(IsFatX, &DirContext->DirEntry))
181 {
183 continue;
184 }
185 if (DirContext->LongNameU.Length == 0 ||
186 DirContext->ShortNameU.Length == 0)
187 {
188 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
190 {
191 ASSERT(DirContext->LongNameU.Length != 0 &&
192 DirContext->ShortNameU.Length != 0);
193 }
195 continue;
196 }
197 if (WildCard)
198 {
199 Found = FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->LongNameU, TRUE, NULL) ||
200 FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->ShortNameU, TRUE, NULL);
201 }
202 else
203 {
204 Found = FsRtlAreNamesEqual(&DirContext->LongNameU, FileToFindU, TRUE, NULL) ||
205 FsRtlAreNamesEqual(&DirContext->ShortNameU, FileToFindU, TRUE, NULL);
206 }
207
208 if (Found)
209 {
210 if (WildCard)
211 {
212 RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
213 if (!vfatFCBIsRoot(Parent))
214 {
215 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
216 PathNameU.Length += sizeof(WCHAR);
217 }
218 RtlAppendUnicodeStringToString(&PathNameU, &DirContext->LongNameU);
219 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
220 rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
221 if (rcFcb != NULL)
222 {
223 RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
224 vfatReleaseFCB(DeviceExt, rcFcb);
225 }
226 }
227 DPRINT("%u\n", DirContext->LongNameU.Length);
228 DPRINT("FindFile: new Name %wZ, DirIndex %u\n",
229 &DirContext->LongNameU, DirContext->DirIndex);
230
231 if (Context)
232 {
234 }
235 RtlFreeUnicodeString(&FileToFindUpcase);
236 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
237 return STATUS_SUCCESS;
238 }
240 }
241
242 if (Context)
243 {
245 }
246
247 RtlFreeUnicodeString(&FileToFindUpcase);
248 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
249 return Status;
250}
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
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
return Found
Definition: dirsup.c:1270
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:425
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define L(x)
Definition: ntvdm.h:50
ULONG DirIndex
Definition: ntfs.h:533
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: vfat.h:448
ULONG dirIndex
Definition: vfat.h:502
UNICODE_STRING ShortNameU
Definition: vfat.h:466
ULONG startIndex
Definition: vfat.h:505
DIR_ENTRY entry
Definition: vfat.h:457
UNICODE_STRING LongNameU
Definition: vfat.h:463
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
Definition: vfat.h:225
#define ENTRY_VOLUME(IsFatX, DirEntry)
Definition: vfat.h:206
FORCEINLINE NTSTATUS VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt, PVOID *pContext, PVOID *pPage, struct _VFATFCB *pDirFcb, struct _VFAT_DIRENTRY_CONTEXT *DirContext, BOOLEAN First)
Definition: vfat.h:397
#define LONGNAME_MAX_LENGTH
Definition: vfat.h:203
#define TAG_NAME
Definition: vfat.h:553
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
PVFATFCB vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PUNICODE_STRING PathNameU)
Definition: fcb.c:594
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ FsdDosDateTimeToSystemTime()

BOOLEAN FsdDosDateTimeToSystemTime ( PDEVICE_EXTENSION  DeviceExt,
USHORT  DosDate,
USHORT  DosTime,
PLARGE_INTEGER  SystemTime 
)

Definition at line 21 of file dir.c.

26{
27 PDOSTIME pdtime = (PDOSTIME)&DosTime;
28 PDOSDATE pddate = (PDOSDATE)&DosDate;
30 LARGE_INTEGER LocalTime;
31
32 if (SystemTime == NULL)
33 return FALSE;
34
36 TimeFields.Second = pdtime->Second * 2;
37 TimeFields.Minute = pdtime->Minute;
38 TimeFields.Hour = pdtime->Hour;
39
40 TimeFields.Day = pddate->Day;
41 TimeFields.Month = pddate->Month;
42 TimeFields.Year = (CSHORT)(DeviceExt->BaseDateYear + pddate->Year);
43
44 RtlTimeFieldsToTime(&TimeFields, &LocalTime);
45 ExLocalTimeToSystemTime(&LocalTime, SystemTime);
46
47 return TRUE;
48}
struct _DOSTIME * PDOSTIME
struct _DOSDATE * PDOSDATE
BOOLEAN RtlTimeFieldsToTime(IN PTIME_FIELDS TimeFields, IN PLARGE_INTEGER Time)
#define ExLocalTimeToSystemTime(LocTime, SysTime)
Definition: env_spec_w32.h:738
static PTIME_FIELDS TimeFields
Definition: time.c:104
WORD Month
Definition: cabinet.c:42
WORD Year
Definition: cabinet.c:43
WORD Day
Definition: cabinet.c:41
WORD Second
Definition: cabinet.c:34
WORD Minute
Definition: cabinet.c:35
WORD Hour
Definition: cabinet.c:36
USHORT Milliseconds
Definition: env_spec_w32.h:717
short CSHORT
Definition: umtypes.h:127

Referenced by FsdGetFsVolumeInformation(), VfatGetBasicInformation(), VfatGetFileBothInformation(), VfatGetFileDirectoryInformation(), VfatGetFileFullDirectoryInformation(), and VfatGetNetworkOpenInformation().

◆ FsdSystemTimeToDosDateTime()

BOOLEAN FsdSystemTimeToDosDateTime ( PDEVICE_EXTENSION  DeviceExt,
PLARGE_INTEGER  SystemTime,
USHORT pDosDate,
USHORT pDosTime 
)

◆ GetDirtyStatus()

NTSTATUS GetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
PBOOLEAN  DirtyStatus 
)

Definition at line 831 of file fat.c.

834{
836
837 DPRINT("GetDirtyStatus(DeviceExt %p)\n", DeviceExt);
838
839 /* FAT12 has no dirty bit */
840 if (DeviceExt->FatInfo.FatType == FAT12)
841 {
842 *DirtyStatus = FALSE;
843 return STATUS_SUCCESS;
844 }
845
846 /* Not really in the FAT, but share the lock because
847 * we're really low-level and shouldn't happent that often
848 * And call the appropriate function
849 */
850 ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
851 Status = DeviceExt->GetDirtyStatus(DeviceExt, DirtyStatus);
852 ExReleaseResourceLite(&DeviceExt->FatResource);
853
854 return Status;
855}
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621

Referenced by VfatMount().

◆ GetNextCluster()

NTSTATUS GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 744 of file fat.c.

748{
750
751 DPRINT("GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
752 DeviceExt, CurrentCluster);
753
754 if (CurrentCluster == 0)
755 {
756 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
758 ASSERT(CurrentCluster != 0);
760 }
761
762 ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
763 Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
764 ExReleaseResourceLite(&DeviceExt->FatResource);
765
766 return Status;
767}

Referenced by FATDelEntry(), FATXDelEntry(), NextCluster(), and OffsetToCluster().

◆ GetNextClusterExtend()

NTSTATUS GetNextClusterExtend ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 773 of file fat.c.

777{
778 ULONG NewCluster;
780
781 DPRINT("GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
782 DeviceExt, CurrentCluster);
783
784 ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
785 /*
786 * If the file hasn't any clusters allocated then we need special
787 * handling
788 */
789 if (CurrentCluster == 0)
790 {
791 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
792 if (!NT_SUCCESS(Status))
793 {
794 ExReleaseResourceLite(&DeviceExt->FatResource);
795 return Status;
796 }
797
798 *NextCluster = NewCluster;
799 ExReleaseResourceLite(&DeviceExt->FatResource);
800 return STATUS_SUCCESS;
801 }
802
803 Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
804
805 if ((*NextCluster) == 0xFFFFFFFF)
806 {
807 /* We are after last existing cluster, we must add one to file */
808 /* Firstly, find the next available open allocation unit and
809 mark it as end of file */
810 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
811 if (!NT_SUCCESS(Status))
812 {
813 ExReleaseResourceLite(&DeviceExt->FatResource);
814 return Status;
815 }
816
817 /* Now, write the AU of the LastCluster with the value of the newly
818 found AU */
819 WriteCluster(DeviceExt, CurrentCluster, NewCluster);
820 *NextCluster = NewCluster;
821 }
822
823 ExReleaseResourceLite(&DeviceExt->FatResource);
824 return Status;
825}
NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
Definition: fat.c:705

Referenced by NextCluster(), and OffsetToCluster().

◆ IsDotOrDotDot()

BOOLEAN IsDotOrDotDot ( PCUNICODE_STRING  Name)

Definition at line 28 of file string.c.

29{
30 return ((Name->Length == sizeof(WCHAR) && Name->Buffer[0] == L'.') ||
31 (Name->Length == 2 * sizeof(WCHAR) && Name->Buffer[0] == L'.' && Name->Buffer[1] == L'.'));
32}

Referenced by VfatCreateFile(), VfatOpenFile(), VfatSetDispositionInformation(), and VfatSetRenameInformation().

◆ NextCluster()

NTSTATUS NextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  FirstCluster,
PULONG  CurrentCluster,
BOOLEAN  Extend 
)

Definition at line 38 of file rw.c.

43{
44 if (FirstCluster == 1)
45 {
46 (*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
47 return STATUS_SUCCESS;
48 }
49 else
50 {
51 if (Extend)
52 return GetNextClusterExtend(DeviceExt, (*CurrentCluster), CurrentCluster);
53 else
54 return GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster);
55 }
56}
VOID NTAPI Extend(VOID)
Definition: extend.c:14
NTSTATUS GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
Definition: fat.c:744
NTSTATUS GetNextClusterExtend(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
Definition: fat.c:773

Referenced by FAT12GetNextCluster(), FAT16GetNextCluster(), FAT32GetNextCluster(), FATAddEntry(), FATDelEntry(), FATXDelEntry(), GetNextCluster(), GetNextClusterExtend(), VfatGetRetrievalPointers(), vfatInitFCBFromDirEntry(), vfatMakeRootFCB(), VfatReadFileData(), VfatSetAllocationSizeInformation(), and VfatWriteFileData().

◆ OffsetToCluster()

NTSTATUS OffsetToCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  FirstCluster,
ULONG  FileOffset,
PULONG  Cluster,
BOOLEAN  Extend 
)

Definition at line 59 of file rw.c.

65{
66 ULONG CurrentCluster;
67 ULONG i;
69/*
70 DPRINT("OffsetToCluster(DeviceExt %x, Fcb %x, FirstCluster %x,"
71 " FileOffset %x, Cluster %x, Extend %d)\n", DeviceExt,
72 Fcb, FirstCluster, FileOffset, Cluster, Extend);
73*/
74 if (FirstCluster == 0)
75 {
76 DbgPrint("OffsetToCluster is called with FirstCluster = 0!\n");
78 }
79
80 if (FirstCluster == 1)
81 {
82 /* root of FAT16 or FAT12 */
83 *Cluster = DeviceExt->FatInfo.rootStart + FileOffset
84 / (DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.SectorsPerCluster;
85 return STATUS_SUCCESS;
86 }
87 else
88 {
89 CurrentCluster = FirstCluster;
90 if (Extend)
91 {
92 for (i = 0; i < FileOffset / DeviceExt->FatInfo.BytesPerCluster; i++)
93 {
94 Status = GetNextClusterExtend (DeviceExt, CurrentCluster, &CurrentCluster);
95 if (!NT_SUCCESS(Status))
96 return Status;
97 }
98 *Cluster = CurrentCluster;
99 }
100 else
101 {
102 for (i = 0; i < FileOffset / DeviceExt->FatInfo.BytesPerCluster; i++)
103 {
104 Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster);
105 if (!NT_SUCCESS(Status))
106 return Status;
107 }
108 *Cluster = CurrentCluster;
109 }
110 return STATUS_SUCCESS;
111 }
112}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define DbgPrint
Definition: hal.h:12

Referenced by VfatGetRetrievalPointers(), VfatReadFileData(), VfatSetAllocationSizeInformation(), and VfatWriteFileData().

◆ SetDirtyStatus()

NTSTATUS SetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
BOOLEAN  DirtyStatus 
)

Definition at line 1017 of file fat.c.

1020{
1022
1023 DPRINT("SetDirtyStatus(DeviceExt %p, DirtyStatus %d)\n", DeviceExt, DirtyStatus);
1024
1025 /* FAT12 has no dirty bit */
1026 if (DeviceExt->FatInfo.FatType == FAT12)
1027 {
1028 return STATUS_SUCCESS;
1029 }
1030
1031 /* Not really in the FAT, but share the lock because
1032 * we're really low-level and shouldn't happent that often
1033 * And call the appropriate function
1034 * Acquire exclusive because we will modify ondisk value
1035 */
1036 ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
1037 Status = DeviceExt->SetDirtyStatus(DeviceExt, DirtyStatus);
1038 ExReleaseResourceLite(&DeviceExt->FatResource);
1039
1040 return Status;
1041}

Referenced by VfatDismountVolume(), VfatLockOrUnlockVolume(), VfatMarkVolumeDirty(), VfatMount(), and VfatShutdown().

◆ vfat8Dot3ToString()

VOID vfat8Dot3ToString ( PFAT_DIR_ENTRY  pEntry,
PUNICODE_STRING  NameU 
)

Definition at line 19 of file create.c.

22{
23 OEM_STRING StringA;
25 CHAR cString[12];
26
27 RtlCopyMemory(cString, pEntry->ShortName, 11);
28 cString[11] = 0;
29 if (cString[0] == 0x05)
30 {
31 cString[0] = 0xe5;
32 }
33
34 StringA.Buffer = cString;
35 for (StringA.Length = 0;
36 StringA.Length < 8 && StringA.Buffer[StringA.Length] != ' ';
37 StringA.Length++);
38 StringA.MaximumLength = StringA.Length;
39
40 RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
41
43 {
44 RtlDowncaseUnicodeString(NameU, NameU, FALSE);
45 }
46
47 if (cString[8] != ' ')
48 {
49 Length = NameU->Length;
50 NameU->Buffer += Length / sizeof(WCHAR);
52 {
53 Length += sizeof(WCHAR);
54 NameU->Buffer[0] = L'.';
55 NameU->Buffer++;
56 }
57 NameU->Length = 0;
58 NameU->MaximumLength -= Length;
59
60 StringA.Buffer = &cString[8];
61 for (StringA.Length = 0;
62 StringA.Length < 3 && StringA.Buffer[StringA.Length] != ' ';
63 StringA.Length++);
64 StringA.MaximumLength = StringA.Length;
65 RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
67 {
68 RtlDowncaseUnicodeString(NameU, NameU, FALSE);
69 }
70 NameU->Buffer -= Length / sizeof(WCHAR);
71 NameU->Length += Length;
72 NameU->MaximumLength += Length;
73 }
74
75 NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
76 DPRINT("'%wZ'\n", NameU);
77}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
NTSYSAPI NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN)
NTSYSAPI NTSTATUS NTAPI RtlOemStringToUnicodeString(PUNICODE_STRING DestinationString, PCOEM_STRING SourceString, BOOLEAN AllocateDestinationString)
STRING OEM_STRING
Definition: umtypes.h:203
#define VFAT_CASE_LOWER_EXT
Definition: vfat.h:201
#define FAT_ENTRY_VOLUME(DirEntry)
Definition: vfat.h:212
#define VFAT_CASE_LOWER_BASE
Definition: vfat.h:200
char CHAR
Definition: xmlstorage.h:175

Referenced by FATGetNextDirEntry(), and ReadVolumeLabel().

◆ VfatAcquireForLazyWrite()

BOOLEAN NTAPI VfatAcquireForLazyWrite ( IN PVOID  Context,
IN BOOLEAN  Wait 
)

Definition at line 723 of file fastio.c.

726{
728 ASSERT(Fcb);
729 DPRINT("VfatAcquireForLazyWrite(): Fcb %p\n", Fcb);
730
732 {
733 DPRINT("VfatAcquireForLazyWrite(): ExReleaseResourceLite failed.\n");
734 return FALSE;
735 }
736 return TRUE;
737}
_In_ PFCB Fcb
Definition: cdprocs.h:159
ERESOURCE MainResource
Definition: ntfs.h:528
struct _VFATFCB * PVFATFCB
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

Referenced by DriverEntry().

◆ VfatAddEntry()

FORCEINLINE NTSTATUS VfatAddEntry ( PDEVICE_EXTENSION  DeviceExt,
PUNICODE_STRING  NameU,
struct _VFATFCB **  Fcb,
struct _VFATFCB ParentFcb,
ULONG  RequestedOptions,
UCHAR  ReqAttr,
struct _VFAT_MOVE_CONTEXT MoveContext 
)

Definition at line 375 of file vfat.h.

382{
383 return DeviceExt->Dispatch.AddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext);
384}
_In_ PFCB ParentFcb
Definition: cdprocs.h:736

Referenced by VfatCreateFile(), and VfatMoveEntry().

◆ vfatAttachFCBToFileObject()

NTSTATUS vfatAttachFCBToFileObject ( PDEVICE_EXTENSION  vcb,
PVFATFCB  fcb,
PFILE_OBJECT  fileObject 
)

Definition at line 754 of file fcb.c.

758{
759 PVFATCCB newCCB;
760
761#ifdef KDBG
762 if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
763 {
764 DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
765 }
766#endif
767
768 newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
769 if (newCCB == NULL)
770 {
772 }
773 RtlZeroMemory(newCCB, sizeof (VFATCCB));
774
775 fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
776 fileObject->FsContext = fcb;
777 fileObject->FsContext2 = newCCB;
778 fileObject->Vpb = vcb->IoVPB;
779 DPRINT("file open: fcb:%p PathName:%wZ\n", fcb, &fcb->PathNameU);
780
781#ifdef KDBG
782 fcb->Flags &= ~FCB_CLEANED_UP;
783 fcb->Flags &= ~FCB_CLOSED;
784#endif
785
786 return STATUS_SUCCESS;
787}
struct _fcb fcb
Definition: btrfs_drv.h:1364
NPAGED_LOOKASIDE_LIST CcbLookasideList
Definition: vfat.h:418
Definition: vfat.h:537
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by VfatCreateFile(), VfatMount(), and VfatOpenFile().

◆ VfatBlockDeviceIoControl()

NTSTATUS VfatBlockDeviceIoControl ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  CtlCode,
IN PVOID  InputBuffer,
IN ULONG  InputBufferSize,
IN OUT PVOID  OutputBuffer,
IN OUT PULONG  pOutputBufferSize,
IN BOOLEAN  Override 
)

Definition at line 430 of file blockdev.c.

438{
441 PIRP Irp;
444
445 DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
446 "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
447 "OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
448 InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
449 OutputBufferSize ? *OutputBufferSize : 0);
450
451again:
453
454 DPRINT("Building device I/O control request ...\n");
458 InputBufferSize,
460 (OutputBufferSize) ? *OutputBufferSize : 0,
461 FALSE,
462 &Event,
463 &IoStatus);
464 if (Irp == NULL)
465 {
466 DPRINT("IoBuildDeviceIoControlRequest failed\n");
468 }
469
470 if (Override)
471 {
474 }
475
476 DPRINT("Calling IO Driver... with irp %p\n", Irp);
478
479 DPRINT("Waiting for IO Operation for %p\n", Irp);
480 if (Status == STATUS_PENDING)
481 {
482 DPRINT("Operation pending\n");
484 DPRINT("Getting IO Status... for %p\n", Irp);
485
486 Status = IoStatus.Status;
487 }
488
490 {
492
493 DPRINT1("Media change detected!\n");
494
495 /* Find the device to verify and reset the thread field to empty value again. */
499 FALSE);
500
501 if (NT_SUCCESS(Status))
502 {
503 DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
504 goto again;
505 }
506 }
507
508 if (OutputBufferSize)
509 {
510 *OutputBufferSize = IoStatus.Information;
511 }
512
513 DPRINT("Returning Status %x\n", Status);
514
515 return Status;
516}
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1409
_In_ PIRP Irp
Definition: csq.h:116
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
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
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:336
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:877
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_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
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
@ Suspended
Definition: ketypes.h:420

Referenced by VfatHasFileSystem(), VfatOpenFile(), and VfatVerify().

◆ VfatBuildRequest()

NTSTATUS NTAPI VfatBuildRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

◆ VfatCheckForDismount()

BOOLEAN VfatCheckForDismount ( IN PDEVICE_EXTENSION  DeviceExt,
IN BOOLEAN  Create 
)

Definition at line 495 of file misc.c.

498{
500 ULONG UnCleanCount;
501 PVPB Vpb;
503
504 DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Force);
505
506 /* If the VCB is OK (not under uninitialization) and we don't force dismount, do nothing */
507 if (BooleanFlagOn(DeviceExt->Flags, VCB_GOOD) && !Force)
508 {
509 return FALSE;
510 }
511
512 /*
513 * NOTE: In their *CheckForDismount() function, our 3rd-party FS drivers
514 * as well as MS' fastfat, perform a comparison check of the current VCB's
515 * VPB ReferenceCount with some sort of "dangling"/"residual" open count,
516 * depending on whether or not we are in IRP_MJ_CREATE.
517 * It seems to be related to the fact that the volume root directory as
518 * well as auxiliary data stream(s) are still opened, and only these are
519 * allowed to be opened at that moment. After analysis it appears that for
520 * the ReactOS' vfatfs, this number is equal to "2".
521 */
522 UnCleanCount = 2;
523
524 /* Lock VPB */
526
527 /* Reference it and check if a create is being done */
528 Vpb = DeviceExt->IoVPB;
529 DPRINT("Vpb->ReferenceCount = %d\n", Vpb->ReferenceCount);
530 if (Vpb->ReferenceCount != UnCleanCount || DeviceExt->OpenHandleCount != 0)
531 {
532 /* If we force-unmount, copy the VPB to our local own to prepare later dismount */
533 if (Force && Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
534 {
535 RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
536 DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
537 DeviceExt->SpareVPB->Size = sizeof(VPB);
538 DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
539 DeviceExt->SpareVPB->DeviceObject = NULL;
540 DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING;
541 DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
542 DeviceExt->SpareVPB = NULL;
543 DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
544
545 /* We are uninitializing, the VCB cannot be used anymore */
546 ClearFlag(DeviceExt->Flags, VCB_GOOD);
547 }
548
549 /* Don't do anything for now */
550 Delete = FALSE;
551 }
552 else
553 {
554 /* Otherwise, delete the volume */
555 Delete = TRUE;
556
557 /* Swap the VPB with our local own */
558 if (Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
559 {
560 RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
561 DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
562 DeviceExt->SpareVPB->Size = sizeof(VPB);
563 DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
564 DeviceExt->SpareVPB->DeviceObject = NULL;
565 DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING;
566 DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
567 DeviceExt->SpareVPB = NULL;
568 DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
569
570 /* We are uninitializing, the VCB cannot be used anymore */
571 ClearFlag(DeviceExt->Flags, VCB_GOOD);
572 }
573
574 /*
575 * We defer setting the VPB's DeviceObject to NULL for later because
576 * we want to handle the closing of the internal opened meta-files.
577 */
578
579 /* Clear the mounted and locked flags in the VPB */
581 }
582
583 /* Release lock and return status */
585
586 /* If we were to delete, delete volume */
587 if (Delete)
588 {
589 LARGE_INTEGER Zero = {{0,0}};
591
592 /* We are uninitializing, the VCB cannot be used anymore */
593 ClearFlag(DeviceExt->Flags, VCB_GOOD);
594
595 /* Invalidate and close the internal opened meta-files */
596 if (DeviceExt->RootFcb)
597 {
598 Fcb = DeviceExt->RootFcb;
600 &Zero,
601 NULL);
603 DeviceExt->RootFcb = NULL;
605 }
606 if (DeviceExt->VolumeFcb)
607 {
608 Fcb = DeviceExt->VolumeFcb;
609#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
611 &Zero,
612 NULL);
614#endif
615 DeviceExt->VolumeFcb = NULL;
617 }
618 if (DeviceExt->FATFileObject)
619 {
620 Fcb = DeviceExt->FATFileObject->FsContext;
621 CcUninitializeCacheMap(DeviceExt->FATFileObject,
622 &Zero,
623 NULL);
624 DeviceExt->FATFileObject->FsContext = NULL;
625 ObDereferenceObject(DeviceExt->FATFileObject);
626 DeviceExt->FATFileObject = NULL;
628 }
629
630 ASSERT(DeviceExt->OverflowQueueCount == 0);
631 ASSERT(IsListEmpty(&DeviceExt->OverflowQueue));
632 ASSERT(DeviceExt->PostedRequestCount == 0);
633
634 /*
635 * Now that the closing of the internal opened meta-files has been
636 * handled, we can now set the VPB's DeviceObject to NULL.
637 */
638 Vpb->DeviceObject = NULL;
639
640 /* If we have a local VPB, we'll have to delete it
641 * but we won't dismount us - something went bad before
642 */
643 if (DeviceExt->SpareVPB)
644 {
645 ExFreePool(DeviceExt->SpareVPB);
646 }
647 /* Otherwise, delete any of the available VPB if its reference count is zero */
648 else if (DeviceExt->IoVPB->ReferenceCount == 0)
649 {
650 ExFreePool(DeviceExt->IoVPB);
651 }
652
653 /* Remove the volume from the list */
655 RemoveEntryList(&DeviceExt->VolumeListEntry);
657
658 /* Uninitialize the notify synchronization object */
659 FsRtlNotifyUninitializeSync(&DeviceExt->NotifySync);
660
661 /* Release resources */
662 ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS);
663 ExDeleteResourceLite(&DeviceExt->DirResource);
664 ExDeleteResourceLite(&DeviceExt->FatResource);
665
666 /* Dismount our device if possible */
667 ObDereferenceObject(DeviceExt->StorageDevice);
668 IoDeleteDevice(DeviceExt->VolumeDevice);
669 }
670
671 return Delete;
672}
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1417
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:418
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1668
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
ERESOURCE VolumeListLock
Definition: vfat.h:415
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PVPB Vpb
Definition: cdstruc.h:511
Definition: iotypes.h:189
#define TAG_STATS
Definition: vfat.h:550
#define VCB_GOOD
Definition: vfat.h:247
VOID vfatDestroyFCB(PVFATFCB pFCB)
Definition: fcb.c:268
#define VPB_MOUNTED
Definition: iotypes.h:1807
#define IO_TYPE_VPB
#define VPB_PERSISTENT
Definition: iotypes.h:1809
struct _VPB VPB
#define VPB_LOCKED
Definition: iotypes.h:1808
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by VfatCleanupFile(), VfatCloseFile(), and VfatShutdown().

◆ VfatCleanup()

NTSTATUS VfatCleanup ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 176 of file cleanup.c.

178{
180
181 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
182
183 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
184 {
185 IrpContext->Irp->IoStatus.Information = 0;
186 return STATUS_SUCCESS;
187 }
188
190 Deleted = VfatCleanupFile(IrpContext);
192
193 IrpContext->Irp->IoStatus.Information = 0;
194 return STATUS_SUCCESS;
195}
static BOOLEAN VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
Definition: cleanup.c:24
@ Deleted
Definition: kstypes.h:187
ERESOURCE DirResource
Definition: ntfs.h:103
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
IO_STATUS_BLOCK IoStatus

Referenced by VfatDispatchRequest().

◆ VfatClose()

NTSTATUS VfatClose ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 212 of file close.c.

214{
216
217 DPRINT("VfatClose(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
218
219 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
220 {
221 DPRINT("Closing file system\n");
222 IrpContext->Irp->IoStatus.Information = 0;
223 return STATUS_SUCCESS;
224 }
226 {
227 return VfatMarkIrpContextForQueue(IrpContext);
228 }
229
230 Status = VfatCloseFile(IrpContext->DeviceExt, IrpContext->FileObject);
232
233 IrpContext->Irp->IoStatus.Information = 0;
234
235 return Status;
236}
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:474
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:159
ULONG Flags
Definition: vfat.h:586
PFILE_OBJECT FileObject
Definition: vfat.h:591
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
Definition: vfat.h:625

Referenced by VfatDispatchRequest().

◆ VfatCloseFile()

NTSTATUS VfatCloseFile ( PDEVICE_EXTENSION  DeviceExt,
PFILE_OBJECT  FileObject 
)

Definition at line 159 of file close.c.

162{
163 PVFATFCB pFcb;
164 PVFATCCB pCcb;
165 BOOLEAN IsVolume;
167
168 DPRINT("VfatCloseFile(DeviceExt %p, FileObject %p)\n",
169 DeviceExt, FileObject);
170
171 /* FIXME : update entry in directory? */
172 pCcb = (PVFATCCB) (FileObject->FsContext2);
173 pFcb = (PVFATFCB) (FileObject->FsContext);
174
175 if (pFcb == NULL)
176 {
177 return STATUS_SUCCESS;
178 }
179
180 IsVolume = BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME);
181
182 if (pCcb)
183 {
184 vfatDestroyCCB(pCcb);
185 }
186
187 /* If we have to close immediately, or if delaying failed, close */
190 {
191 VfatCommonCloseFile(DeviceExt, pFcb);
192 }
193
194 FileObject->FsContext2 = NULL;
195 FileObject->FsContext = NULL;
196 FileObject->SectionObjectPointer = NULL;
197
198#ifdef ENABLE_SWAPOUT
199 if (IsVolume && DeviceExt->OpenHandleCount == 0)
200 {
201 VfatCheckForDismount(DeviceExt, FALSE);
202 }
203#endif
204
205 return Status;
206}
#define FCB_IS_VOLUME
Definition: ntfs.h:510
NTSTATUS VfatPostCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:115
VOID VfatCommonCloseFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
Definition: close.c:19
BOOLEAN VfatCheckForDismount(IN PDEVICE_EXTENSION DeviceExt, IN BOOLEAN Force)
Definition: misc.c:495
BOOLEAN ShutdownStarted
Definition: vfat.h:428
ULONG Flags
Definition: vfat.h:496
#define FCB_DELAYED_CLOSE
Definition: vfat.h:439
struct _VFATCCB * PVFATCCB
VOID vfatDestroyCCB(PVFATCCB pCcb)
Definition: fcb.c:257
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

Referenced by VfatClose(), VfatCreateFile(), and vfatPrepareTargetForRename().

◆ VfatCreate()

NTSTATUS VfatCreate ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 1070 of file create.c.

1072{
1074
1075 ASSERT(IrpContext);
1076
1077 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
1078 {
1079 /* DeviceObject represents FileSystem instead of logical volume */
1080 DPRINT ("FsdCreate called with file system\n");
1081 IrpContext->Irp->IoStatus.Information = FILE_OPENED;
1082 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1083
1084 return STATUS_SUCCESS;
1085 }
1086
1087 IrpContext->Irp->IoStatus.Information = 0;
1089 Status = VfatCreateFile(IrpContext->DeviceObject, IrpContext->Irp);
1091
1092 if (NT_SUCCESS(Status))
1093 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1094
1095 return Status;
1096}
static NTSTATUS VfatCreateFile(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: create.c:404
#define FILE_OPENED
Definition: nt_native.h:769
CCHAR PriorityBoost
Definition: vfat.h:594
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

Referenced by VfatDispatchRequest().

◆ VfatDelEntry()

FORCEINLINE NTSTATUS VfatDelEntry ( PDEVICE_EXTENSION  DeviceExt,
struct _VFATFCB Fcb,
struct _VFAT_MOVE_CONTEXT MoveContext 
)

Definition at line 388 of file vfat.h.

391{
392 return DeviceExt->Dispatch.DelEntry(DeviceExt, Fcb, MoveContext);
393}

Referenced by VfatCleanupFile(), VfatMoveEntry(), and vfatPrepareTargetForRename().

◆ vfatDestroyCCB()

VOID vfatDestroyCCB ( PVFATCCB  pCcb)

Definition at line 257 of file fcb.c.

259{
260 if (pCcb->SearchPattern.Buffer)
261 {
263 }
264 ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb);
265}
UNICODE_STRING SearchPattern
Definition: vfat.h:543
#define TAG_SEARCH
Definition: vfat.h:554

Referenced by VfatCloseFile(), and VfatMount().

◆ vfatDestroyFCB()

VOID vfatDestroyFCB ( PVFATFCB  pFCB)

Definition at line 268 of file fcb.c.

270{
271#ifdef KDBG
272 if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
273 {
274 DPRINT1("Destroying: %p (%wZ) %d\n", pFCB, &pFCB->PathNameU, pFCB->RefCount);
275 }
276#endif
277
279
280 if (!vfatFCBIsRoot(pFCB) &&
282 {
284 }
289 ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
290}
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
NPAGED_LOOKASIDE_LIST FcbLookasideList
Definition: vfat.h:417
FILE_LOCK FileLock
Definition: vfat.h:520
LIST_ENTRY ParentListEntry
Definition: vfat.h:487
ERESOURCE PagingIoResource
Definition: vfat.h:453
UNICODE_STRING PathNameU
Definition: vfat.h:472
PWCHAR PathNameBuffer
Definition: vfat.h:475
LIST_ENTRY ParentListHead
Definition: vfat.h:493
ERESOURCE MainResource
Definition: vfat.h:452
LONG RefCount
Definition: vfat.h:481
#define FCB_IS_FAT
Definition: vfat.h:435

Referenced by VfatCheckForDismount(), VfatDismountVolume(), VfatMount(), and vfatReleaseFCB().

◆ VfatDirectoryControl()

NTSTATUS VfatDirectoryControl ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 727 of file dir.c.

729{
731
732 IrpContext->Irp->IoStatus.Information = 0;
733
734 switch (IrpContext->MinorFunction)
735 {
737 Status = DoQuery (IrpContext);
738 break;
739
741 Status = VfatNotifyChangeDirectory(IrpContext);
742 break;
743
744 default:
745 /* Error */
746 DPRINT("Unexpected minor function %x in VFAT driver\n",
747 IrpContext->MinorFunction);
749 break;
750 }
751
753 {
754 return VfatMarkIrpContextForQueue(IrpContext);
755 }
756
757 return Status;
758}
#define IRPCONTEXT_COMPLETE
Definition: ntfs.h:475
NTSTATUS VfatNotifyChangeDirectory(PVFAT_IRP_CONTEXT IrpContext)
Definition: dir.c:697
static NTSTATUS DoQuery(PVFAT_IRP_CONTEXT IrpContext)
Definition: dir.c:474
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
UCHAR MinorFunction
Definition: vfat.h:590
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by VfatDispatchRequest().

◆ vfatDirEntryGetFirstCluster()

ULONG vfatDirEntryGetFirstCluster ( PDEVICE_EXTENSION  pDeviceExt,
PDIR_ENTRY  pDirEntry 
)

Definition at line 18 of file direntry.c.

21{
22 ULONG cluster;
23
24 if (pDeviceExt->FatInfo.FatType == FAT32)
25 {
26 cluster = pFatDirEntry->Fat.FirstCluster |
27 (pFatDirEntry->Fat.FirstClusterHigh << 16);
28 }
29 else if (vfatVolumeIsFatX(pDeviceExt))
30 {
31 cluster = pFatDirEntry->FatX.FirstCluster;
32 }
33 else
34 {
35 cluster = pFatDirEntry->Fat.FirstCluster;
36 }
37
38 return cluster;
39}
#define FAT32
Definition: fat.h:169

Referenced by FATDelEntry(), FATXDelEntry(), VfatGetInternalInformation(), VfatGetRetrievalPointers(), vfatInitFCBFromDirEntry(), VfatReadFileData(), VfatSetAllocationSizeInformation(), VfatWrite(), and VfatWriteFileData().

◆ vfatDirFindFile()

NTSTATUS vfatDirFindFile ( PDEVICE_EXTENSION  pVCB,
PVFATFCB  parentFCB,
PUNICODE_STRING  FileToFindU,
PVFATFCB fileFCB 
)

Definition at line 790 of file fcb.c.

795{
798 PVOID Page = NULL;
801 /* This buffer must have a size of 260 characters, because
802 vfatMakeFCBFromDirEntry can copy 20 name entries with 13 characters. */
803 WCHAR LongNameBuffer[260];
804 WCHAR ShortNameBuffer[13];
805 BOOLEAN FoundLong = FALSE;
806 BOOLEAN FoundShort = FALSE;
807 BOOLEAN IsFatX = vfatVolumeIsFatX(pDeviceExt);
808
809 ASSERT(pDeviceExt);
810 ASSERT(pDirectoryFCB);
811 ASSERT(FileToFindU);
812
813 DPRINT("vfatDirFindFile(VCB:%p, dirFCB:%p, File:%wZ)\n",
814 pDeviceExt, pDirectoryFCB, FileToFindU);
815 DPRINT("Dir Path:%wZ\n", &pDirectoryFCB->PathNameU);
816
818 DirContext.LongNameU.Buffer = LongNameBuffer;
819 DirContext.LongNameU.Length = 0;
820 DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
821 DirContext.ShortNameU.Buffer = ShortNameBuffer;
822 DirContext.ShortNameU.Length = 0;
823 DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
824 DirContext.DeviceExt = pDeviceExt;
825
826 while (TRUE)
827 {
828 status = VfatGetNextDirEntry(pDeviceExt,
829 &Context,
830 &Page,
831 pDirectoryFCB,
832 &DirContext,
833 First);
834 First = FALSE;
836 {
838 }
839 if (!NT_SUCCESS(status))
840 {
841 return status;
842 }
843
844 DPRINT(" Index:%u longName:%wZ\n",
845 DirContext.DirIndex, &DirContext.LongNameU);
846
847 if (!ENTRY_VOLUME(IsFatX, &DirContext.DirEntry))
848 {
849 if (DirContext.LongNameU.Length == 0 ||
850 DirContext.ShortNameU.Length == 0)
851 {
852 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
854 {
855 ASSERT(DirContext.LongNameU.Length != 0 &&
856 DirContext.ShortNameU.Length != 0);
857 }
859 continue;
860 }
861 FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);
862 if (FoundLong == FALSE)
863 {
864 FoundShort = RtlEqualUnicodeString(FileToFindU, &DirContext.ShortNameU, TRUE);
865 }
866 if (FoundLong || FoundShort)
867 {
868 status = vfatMakeFCBFromDirEntry(pDeviceExt,
869 pDirectoryFCB,
870 &DirContext,
871 pFoundFCB);
873 return status;
874 }
875 }
877 }
878
880}
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
Definition: ps.c:97
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb, PVFATFCB directoryFCB, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB *fileFCB)
Definition: fcb.c:725

Referenced by vfatGetFCBForFile().

◆ vfatFCBInitializeCacheFromVolume()

NTSTATUS vfatFCBInitializeCacheFromVolume ( PVCB  vcb,
PVFATFCB  fcb 
)

Definition at line 22 of file dirwr.c.

25{
26 PFILE_OBJECT fileObject;
27 PVFATCCB newCCB;
29 BOOLEAN Acquired;
30
31 /* Don't re-initialize if already done */
33 {
34 return STATUS_SUCCESS;
35 }
36
38 ASSERT(fcb->FileObject == NULL);
39
40 Acquired = FALSE;
41 if (!ExIsResourceAcquiredExclusive(&vcb->DirResource))
42 {
43 ExAcquireResourceExclusiveLite(&vcb->DirResource, TRUE);
44 Acquired = TRUE;
45 }
46
47 fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
48 if (fileObject == NULL)
49 {
51 goto Quit;
52 }
53
54#ifdef KDBG
55 if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
56 {
57 DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
58 }
59#endif
60
61 newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
62 if (newCCB == NULL)
63 {
65 ObDereferenceObject(fileObject);
66 goto Quit;
67 }
68 RtlZeroMemory(newCCB, sizeof (VFATCCB));
69
70 fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
71 fileObject->FsContext = fcb;
72 fileObject->FsContext2 = newCCB;
73 fileObject->Vpb = vcb->IoVPB;
74 fcb->FileObject = fileObject;
75
77 {
78 CcInitializeCacheMap(fileObject,
79 (PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
80 TRUE,
82 fcb);
83 }
85 {
87 fcb->FileObject = NULL;
88 ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, newCCB);
89 ObDereferenceObject(fileObject);
90 if (Acquired)
91 {
92 ExReleaseResourceLite(&vcb->DirResource);
93 }
94 return status;
95 }
97
98 vfatGrabFCB(vcb, fcb);
101
102Quit:
103 if (Acquired)
104 {
105 ExReleaseResourceLite(&vcb->DirResource);
106 }
107
108 return status;
109}
#define FCB_CACHE_INITIALIZED
Definition: ntfs.h:508
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3187
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks
Definition: vfat.h:422
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:301
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by FATAddEntry(), FATDelEntry(), FATGetNextDirEntry(), FATIsDirectoryEmpty(), FATXDelEntry(), FATXGetNextDirEntry(), FATXIsDirectoryEmpty(), FsdSetFsLabelInformation(), vfatFindDirSpace(), vfatMakeRootFCB(), vfatRenameEntry(), and VfatUpdateEntry().

◆ vfatFCBIsDirectory()

◆ vfatFCBIsReadOnly()

FORCEINLINE BOOLEAN vfatFCBIsReadOnly ( PVFATFCB  FCB)

Definition at line 644 of file vfat.h.

645{
646 return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_READONLY);
647}
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702

Referenced by VfatOpenFile(), vfatPrepareTargetForRename(), and VfatSetDispositionInformation().

◆ vfatFCBIsRoot()

BOOLEAN vfatFCBIsRoot ( PVFATFCB  FCB)

◆ VfatFileSystemControl()

NTSTATUS VfatFileSystemControl ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 1378 of file fsctl.c.

1380{
1382
1383 DPRINT("VfatFileSystemControl(IrpContext %p)\n", IrpContext);
1384
1385 ASSERT(IrpContext);
1386 ASSERT(IrpContext->Irp);
1387 ASSERT(IrpContext->Stack);
1388
1389 IrpContext->Irp->IoStatus.Information = 0;
1390
1391 switch (IrpContext->MinorFunction)
1392 {
1393 case IRP_MN_KERNEL_CALL:
1395 switch(IrpContext->Stack->Parameters.DeviceIoControl.IoControlCode)
1396 {
1398 Status = VfatGetVolumeBitmap(IrpContext);
1399 break;
1400
1402 Status = VfatGetRetrievalPointers(IrpContext);
1403 break;
1404
1405 case FSCTL_MOVE_FILE:
1406 Status = VfatMoveFile(IrpContext);
1407 break;
1408
1410 Status = VfatIsVolumeDirty(IrpContext);
1411 break;
1412
1414 Status = VfatMarkVolumeDirty(IrpContext);
1415 break;
1416
1417 case FSCTL_LOCK_VOLUME:
1418 Status = VfatLockOrUnlockVolume(IrpContext, TRUE);
1419 break;
1420
1422 Status = VfatLockOrUnlockVolume(IrpContext, FALSE);
1423 break;
1424
1426 Status = VfatDismountVolume(IrpContext);
1427 break;
1428
1430 Status = VfatGetStatistics(IrpContext);
1431 break;
1432
1433 default:
1435 }
1436 break;
1437
1439 Status = VfatMount(IrpContext);
1440 break;
1441
1443 DPRINT("VFATFS: IRP_MN_VERIFY_VOLUME\n");
1444 Status = VfatVerify(IrpContext);
1445 break;
1446
1447 default:
1448 DPRINT("VFAT FSC: MinorFunction %u\n", IrpContext->MinorFunction);
1450 break;
1451 }
1452
1453 return Status;
1454}
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_MARK_VOLUME_DIRTY
Definition: nt_native.h:838
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_FILESYSTEM_GET_STATISTICS
Definition: nt_native.h:850
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define FSCTL_IS_VOLUME_DIRTY
Definition: winioctl.h:714
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:95
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:94
#define FSCTL_MOVE_FILE
Definition: winioctl.h:96
PIO_STACK_LOCATION Stack
Definition: vfat.h:588
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static NTSTATUS VfatDismountVolume(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1256
static NTSTATUS VfatGetVolumeBitmap(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:923
static NTSTATUS VfatMount(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:508
static NTSTATUS VfatGetRetrievalPointers(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:933
static NTSTATUS VfatMoveFile(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1027
static NTSTATUS VfatIsVolumeDirty(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1036
static NTSTATUS VfatLockOrUnlockVolume(PVFAT_IRP_CONTEXT IrpContext, BOOLEAN Lock)
Definition: fsctl.c:1085
static NTSTATUS VfatGetStatistics(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1336
static NTSTATUS VfatMarkVolumeDirty(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1064
static NTSTATUS VfatVerify(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:829
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
#define IRP_MN_KERNEL_CALL
Definition: iotypes.h:4408
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404

Referenced by VfatDispatchRequest().

◆ vfatFindDirSpace()

BOOLEAN vfatFindDirSpace ( PDEVICE_EXTENSION  DeviceExt,
PVFATFCB  pDirFcb,
ULONG  nbSlots,
PULONG  start 
)

◆ VfatFlush()

NTSTATUS VfatFlush ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 149 of file flush.c.

151{
154
155 /* This request is not allowed on the main device object. */
156 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
157 {
158 IrpContext->Irp->IoStatus.Information = 0;
160 }
161
162 Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
163 ASSERT(Fcb);
164
166 {
168 Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
170 }
171 else
172 {
174 Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
176 }
177
178 IrpContext->Irp->IoStatus.Information = 0;
179 return Status;
180}
ULONG Flags
Definition: ntfs.h:536
NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb)
Definition: flush.c:51
static NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
Definition: flush.c:20

Referenced by VfatDispatchRequest().

◆ VfatFlushVolume()

NTSTATUS VfatFlushVolume ( PDEVICE_EXTENSION  DeviceExt,
PVFATFCB  VolumeFcb 
)

Definition at line 51 of file flush.c.

54{
55 PLIST_ENTRY ListEntry;
57 NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
58 PIRP Irp;
61
62 DPRINT("VfatFlushVolume(DeviceExt %p, VolumeFcb %p)\n", DeviceExt, VolumeFcb);
63
64 ASSERT(VolumeFcb == DeviceExt->VolumeFcb);
65
66 ListEntry = DeviceExt->FcbListHead.Flink;
67 while (ListEntry != &DeviceExt->FcbListHead)
68 {
69 Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
70 ListEntry = ListEntry->Flink;
72 {
74 Status = VfatFlushFile(DeviceExt, Fcb);
76 if (!NT_SUCCESS(Status))
77 {
78 DPRINT1("VfatFlushFile failed, status = %x\n", Status);
79 ReturnStatus = Status;
80 }
81 }
82 /* FIXME: Stop flushing if this is a removable media and the media was removed */
83 }
84
85 ListEntry = DeviceExt->FcbListHead.Flink;
86 while (ListEntry != &DeviceExt->FcbListHead)
87 {
88 Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
89 ListEntry = ListEntry->Flink;
91 {
93 Status = VfatFlushFile(DeviceExt, Fcb);
95 if (!NT_SUCCESS(Status))
96 {
97 DPRINT1("VfatFlushFile failed, status = %x\n", Status);
98 ReturnStatus = Status;
99 }
100 }
101 /* FIXME: Stop flushing if this is a removable media and the media was removed */
102 }
103
104 Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
105
106 ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
107 Status = VfatFlushFile(DeviceExt, Fcb);
108 ExReleaseResourceLite(&DeviceExt->FatResource);
109
110 /* Prepare an IRP to flush device buffers */
112 DeviceExt->StorageDevice,
113 NULL, 0, NULL, &Event,
115 if (Irp != NULL)
116 {
118
119 Status = IoCallDriver(DeviceExt->StorageDevice, Irp);
120 if (Status == STATUS_PENDING)
121 {
124 }
125
126 /* Ignore device not supporting flush operation */
128 {
129 DPRINT1("Flush not supported, ignored\n");
131
132 }
133 }
134 else
135 {
137 }
138
139 if (!NT_SUCCESS(Status))
140 {
141 DPRINT1("VfatFlushFile failed, status = %x\n", Status);
142 ReturnStatus = Status;
143 }
144
145 return ReturnStatus;
146}
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define IRP_MJ_FLUSH_BUFFERS
@ Executive
Definition: ketypes.h:415

Referenced by VfatDismountVolume(), VfatFlush(), VfatLockOrUnlockVolume(), and VfatShutdown().

◆ VfatGetBasicInformation()

NTSTATUS VfatGetBasicInformation ( PFILE_OBJECT  FileObject,
PVFATFCB  FCB,
PDEVICE_EXTENSION  DeviceExt,
PFILE_BASIC_INFORMATION  BasicInfo,
PULONG  BufferLength 
)

Definition at line 280 of file finfo.c.

286{
288
289 DPRINT("VfatGetBasicInformation()\n");
290
293
294 RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
295
296 if (vfatVolumeIsFatX(DeviceExt))
297 {
299 FCB->entry.FatX.CreationDate,
300 FCB->entry.FatX.CreationTime,
301 &BasicInfo->CreationTime);
303 FCB->entry.FatX.AccessDate,
304 FCB->entry.FatX.AccessTime,
305 &BasicInfo->LastAccessTime);
307 FCB->entry.FatX.UpdateDate,
308 FCB->entry.FatX.UpdateTime,
309 &BasicInfo->LastWriteTime);
310 BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
311 }
312 else
313 {
315 FCB->entry.Fat.CreationDate,
316 FCB->entry.Fat.CreationTime,
317 &BasicInfo->CreationTime);
319 FCB->entry.Fat.AccessDate,
320 0,
321 &BasicInfo->LastAccessTime);
323 FCB->entry.Fat.UpdateDate,
324 FCB->entry.Fat.UpdateTime,
325 &BasicInfo->LastWriteTime);
326 BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
327 }
328
329 BasicInfo->FileAttributes = *FCB->Attributes & 0x3f;
330 /* Synthesize FILE_ATTRIBUTE_NORMAL */
331 if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
336 {
337 DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
339 }
340 DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes);
341
343 return STATUS_SUCCESS;
344}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
BOOLEAN FsdDosDateTimeToSystemTime(PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime)
Definition: dir.c:21
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
LONGLONG CreationTime
Definition: cdstruc.h:1030
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771

Referenced by VfatFastIoQueryBasicInfo(), VfatGetAllInformation(), and VfatQueryInformation().

◆ vfatGetFCBForFile()

NTSTATUS vfatGetFCBForFile ( PDEVICE_EXTENSION  pVCB,
PVFATFCB pParentFCB,
PVFATFCB pFCB,
PUNICODE_STRING  pFileNameU 
)

Definition at line 883 of file fcb.c.

888{
890 PVFATFCB FCB = NULL;
891 PVFATFCB parentFCB;
892 UNICODE_STRING NameU;
893 UNICODE_STRING RootNameU = RTL_CONSTANT_STRING(L"\\");
894 UNICODE_STRING FileNameU;
895 WCHAR NameBuffer[260];
896 PWCHAR curr, prev, last;
898
899 DPRINT("vfatGetFCBForFile (%p,%p,%p,%wZ)\n",
900 pVCB, pParentFCB, pFCB, pFileNameU);
901
902 RtlInitEmptyUnicodeString(&FileNameU, NameBuffer, sizeof(NameBuffer));
903
904 parentFCB = *pParentFCB;
905
906 if (parentFCB == NULL)
907 {
908 /* Passed-in name is the full name */
909 RtlCopyUnicodeString(&FileNameU, pFileNameU);
910
911 // Trivial case, open of the root directory on volume
912 if (RtlEqualUnicodeString(&FileNameU, &RootNameU, FALSE))
913 {
914 DPRINT("returning root FCB\n");
915
916 FCB = vfatOpenRootFCB(pVCB);
917 *pFCB = FCB;
918 *pParentFCB = NULL;
919
921 }
922
923 /* Check for an existing FCB */
924 FCB = vfatGrabFCBFromTable(pVCB, &FileNameU);
925 if (FCB)
926 {
927 *pFCB = FCB;
928 *pParentFCB = FCB->parentFcb;
929 vfatGrabFCB(pVCB, *pParentFCB);
930 return STATUS_SUCCESS;
931 }
932
933 last = curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
934 while (*curr != L'\\' && curr > FileNameU.Buffer)
935 {
936 curr--;
937 }
938
939 if (curr > FileNameU.Buffer)
940 {
941 NameU.Buffer = FileNameU.Buffer;
942 NameU.MaximumLength = NameU.Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
943 FCB = vfatGrabFCBFromTable(pVCB, &NameU);
944 if (FCB)
945 {
946 Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
947 if (Length != FCB->PathNameU.Length)
948 {
949 if (FileNameU.Length + FCB->PathNameU.Length - Length > FileNameU.MaximumLength)
950 {
951 vfatReleaseFCB(pVCB, FCB);
953 }
954 RtlMoveMemory(FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR),
955 curr, FileNameU.Length - Length);
956 FileNameU.Length += (USHORT)(FCB->PathNameU.Length - Length);
957 curr = FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
958 last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
959 }
960 RtlCopyMemory(FileNameU.Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
961 }
962 }
963 else
964 {
965 FCB = NULL;
966 }
967
968 if (FCB == NULL)
969 {
970 FCB = vfatOpenRootFCB(pVCB);
971 curr = FileNameU.Buffer;
972 }
973
974 parentFCB = NULL;
975 prev = curr;
976 }
977 else
978 {
979 /* Make absolute path */
980 RtlCopyUnicodeString(&FileNameU, &parentFCB->PathNameU);
981 curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
982 if (*curr != L'\\')
983 {
984 RtlAppendUnicodeToString(&FileNameU, L"\\");
985 curr++;
986 }
987 ASSERT(*curr == L'\\');
988 RtlAppendUnicodeStringToString(&FileNameU, pFileNameU);
989
990 FCB = parentFCB;
991 parentFCB = NULL;
992 prev = curr;
993 last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
994 }
995
996 while (curr <= last)
997 {
998 if (parentFCB)
999 {
1000 vfatReleaseFCB(pVCB, parentFCB);
1001 parentFCB = NULL;
1002 }
1003 // fail if element in FCB is not a directory
1004 if (!vfatFCBIsDirectory(FCB))
1005 {
1006 DPRINT ("Element in requested path is not a directory\n");
1007
1008 vfatReleaseFCB(pVCB, FCB);
1009 FCB = NULL;
1010 *pParentFCB = NULL;
1011 *pFCB = NULL;
1012
1014 }
1015 parentFCB = FCB;
1016 if (prev < curr)
1017 {
1018 Length = (curr - prev) * sizeof(WCHAR);
1019 if (Length != parentFCB->LongNameU.Length)
1020 {
1021 if (FileNameU.Length + parentFCB->LongNameU.Length - Length > FileNameU.MaximumLength)
1022 {
1023 vfatReleaseFCB(pVCB, parentFCB);
1024 *pParentFCB = NULL;
1025 *pFCB = NULL;
1027 }
1028 RtlMoveMemory(prev + parentFCB->LongNameU.Length / sizeof(WCHAR), curr,
1029 FileNameU.Length - (curr - FileNameU.Buffer) * sizeof(WCHAR));
1030 FileNameU.Length += (USHORT)(parentFCB->LongNameU.Length - Length);
1031 curr = prev + parentFCB->LongNameU.Length / sizeof(WCHAR);
1032 last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
1033 }
1034 RtlCopyMemory(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
1035 }
1036 curr++;
1037 prev = curr;
1038 while (*curr != L'\\' && curr <= last)
1039 {
1040 curr++;
1041 }
1042 NameU.Buffer = FileNameU.Buffer;
1043 NameU.Length = (curr - NameU.Buffer) * sizeof(WCHAR);
1044 NameU.MaximumLength = FileNameU.MaximumLength;
1045 DPRINT("%wZ\n", &NameU);
1046 FCB = vfatGrabFCBFromTable(pVCB, &NameU);
1047 if (FCB == NULL)
1048 {
1049 NameU.Buffer = prev;
1050 NameU.MaximumLength = NameU.Length = (curr - prev) * sizeof(WCHAR);
1051 status = vfatDirFindFile(pVCB, parentFCB, &NameU, &FCB);
1053 {
1054 *pFCB = NULL;
1055 if (curr > last)
1056 {
1057 *pParentFCB = parentFCB;
1059 }
1060 else
1061 {
1062 vfatReleaseFCB(pVCB, parentFCB);
1063 *pParentFCB = NULL;
1065 }
1066 }
1067 else if (!NT_SUCCESS(status))
1068 {
1069 vfatReleaseFCB(pVCB, parentFCB);
1070 *pParentFCB = NULL;
1071 *pFCB = NULL;
1072
1073 return status;
1074 }
1075 }
1076 }
1077
1078 *pParentFCB = parentFCB;
1079 *pFCB = FCB;
1080
1081 return STATUS_SUCCESS;
1082}
struct _FCB FCB
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
static UINT UINT last
Definition: font.c:45
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
PVFATFCB vfatOpenRootFCB(PDEVICE_EXTENSION pVCB)
Definition: fcb.c:708
NTSTATUS vfatDirFindFile(PDEVICE_EXTENSION pDeviceExt, PVFATFCB pDirectoryFCB, PUNICODE_STRING FileToFindU, PVFATFCB *pFoundFCB)
Definition: fcb.c:790

Referenced by VfatCreateFile(), VfatOpenFile(), and vfatPrepareTargetForRename().

◆ VfatGetNextDirEntry()

FORCEINLINE NTSTATUS VfatGetNextDirEntry ( PDEVICE_EXTENSION  DeviceExt,
PVOID pContext,
PVOID pPage,
struct _VFATFCB pDirFcb,
struct _VFAT_DIRENTRY_CONTEXT DirContext,
BOOLEAN  First 
)

Definition at line 397 of file vfat.h.

403{
404 return DeviceExt->Dispatch.GetNextDirEntry(pContext, pPage, pDirFcb, DirContext, First);
405}

Referenced by FindFile(), and vfatDirFindFile().

◆ VfatGetStandardInformation()

NTSTATUS VfatGetStandardInformation ( PVFATFCB  FCB,
PFILE_STANDARD_INFORMATION  StandardInfo,
PULONG  BufferLength 
)

Definition at line 73 of file finfo.c.

77{
80
81 /* PRECONDITION */
82 ASSERT(StandardInfo != NULL);
83 ASSERT(FCB != NULL);
84
86 {
87 StandardInfo->AllocationSize.QuadPart = 0;
88 StandardInfo->EndOfFile.QuadPart = 0;
89 StandardInfo->Directory = TRUE;
90 }
91 else
92 {
93 StandardInfo->AllocationSize = FCB->RFCB.AllocationSize;
94 StandardInfo->EndOfFile = FCB->RFCB.FileSize;
95 StandardInfo->Directory = FALSE;
96 }
97 StandardInfo->NumberOfLinks = 1;
99
101 return STATUS_SUCCESS;
102}
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:517
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755

Referenced by VfatFastIoQueryStandardInfo(), VfatGetAllInformation(), and VfatQueryInformation().

◆ VfatGetUserBuffer()

PVOID VfatGetUserBuffer ( IN PIRP  Irp,
IN BOOLEAN  Paging 
)

Definition at line 443 of file misc.c.

446{
447 ASSERT(Irp);
448
449 if (Irp->MdlAddress)
450 {
452 }
453 else
454 {
455 return Irp->UserBuffer;
456 }
457}
@ NormalPagePriority
Definition: imports.h:56
@ HighPagePriority
Definition: imports.h:57
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

Referenced by DoQuery(), VfatCommonRead(), and VfatWrite().

◆ vfatGrabFCB()

VOID vfatGrabFCB ( PDEVICE_EXTENSION  pVCB,
PVFATFCB  pFCB 
)

Definition at line 301 of file fcb.c.

314{
315#ifdef KDBG
316 if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
317 {
318 DPRINT1("Inc ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func);
319 }
320#else
321 DPRINT("Grabbing FCB at %p: %wZ, refCount:%d\n",
322 pFCB, &pFCB->PathNameU, pFCB->RefCount);
323#endif
324
325 ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource));
326
328 ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
329 ASSERT(pFCB->RefCount > 0);
330 ++pFCB->RefCount;
331}
Definition: File.h:16
void(* Func)(int)
Definition: ncftp.h:79
ULONG OpenHandleCount
Definition: vfat.h:511

Referenced by vfatAddFCBToTable(), VfatCreateFile(), vfatFCBInitializeCacheFromVolume(), vfatGetFCBForFile(), vfatGrabFCBFromTable(), VfatOpenFile(), and VfatSetRenameInformation().

◆ vfatGrabFCBFromTable()

PVFATFCB vfatGrabFCBFromTable ( PDEVICE_EXTENSION  pDeviceExt,
PUNICODE_STRING  pFileNameU 
)

Definition at line 594 of file fcb.c.

597{
598 PVFATFCB rcFCB;
599 ULONG Hash;
600 UNICODE_STRING DirNameU;
601 UNICODE_STRING FileNameU;
602 PUNICODE_STRING FcbNameU;
603
605
606 DPRINT("'%wZ'\n", PathNameU);
607
608 ASSERT(PathNameU->Length >= sizeof(WCHAR) && PathNameU->Buffer[0] == L'\\');
609 Hash = vfatNameHash(0, PathNameU);
610
611 entry = pVCB->FcbHashTable[Hash % pVCB->HashTableSize];
612 if (entry)
613 {
614 vfatSplitPathName(PathNameU, &DirNameU, &FileNameU);
615 }
616
617 while (entry)
618 {
619 if (entry->Hash == Hash)
620 {
621 rcFCB = entry->self;
622 DPRINT("'%wZ' '%wZ'\n", &DirNameU, &rcFCB->DirNameU);
623 if (RtlEqualUnicodeString(&DirNameU, &rcFCB->DirNameU, TRUE))
624 {
625 if (rcFCB->Hash.Hash == Hash)
626 {
627 FcbNameU = &rcFCB->LongNameU;
628 }
629 else
630 {
631 FcbNameU = &rcFCB->ShortNameU;
632 }
633 /* compare the file name */
634 DPRINT("'%wZ' '%wZ'\n", &FileNameU, FcbNameU);
635 if (RtlEqualUnicodeString(&FileNameU, FcbNameU, TRUE))
636 {
637 vfatGrabFCB(pVCB, rcFCB);
638 return rcFCB;
639 }
640 }
641 }
642 entry = entry->next;
643 }
644 return NULL;
645}
static int Hash(const char *)
Definition: reader.c:2257
uint32_t entry
Definition: isohybrid.c:63
ULONG Hash
Definition: vfat.h:277
HASHENTRY Hash
Definition: vfat.h:514
UNICODE_STRING DirNameU
Definition: vfat.h:469
static ULONG vfatNameHash(ULONG hash, PUNICODE_STRING NameU)
Definition: fcb.c:32
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:54

Referenced by FindFile(), vfatGetFCBForFile(), and vfatOpenRootFCB().

◆ VfatHandleDeferredWrite()

VOID NTAPI VfatHandleDeferredWrite ( IN PVOID  IrpContext,
IN PVOID  Unused 
)

Definition at line 220 of file misc.c.

223{
225}
static NTSTATUS VfatDispatchRequest(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:104

Referenced by VfatWrite().

◆ VfatInitFastIoRoutines()

VOID VfatInitFastIoRoutines ( PFAST_IO_DISPATCH  FastIoDispatch)

Definition at line 753 of file fastio.c.

755{
784}
FAST_IO_DISPATCH FastIoDispatch
Definition: fastio.c:20
static FAST_IO_WRITE_COMPRESSED VfatFastIoWriteCompressed
Definition: fastio.c:562
static FAST_IO_ACQUIRE_FILE VfatAcquireFileForNtCreateSection
Definition: fastio.c:353
static FAST_IO_READ VfatFastIoRead
Definition: fastio.c:44
static FAST_IO_MDL_WRITE_COMPLETE VfatMdlWriteComplete
Definition: fastio.c:508
static FAST_IO_MDL_WRITE_COMPLETE_COMPRESSED VfatMdlWriteCompleteCompressed
Definition: fastio.c:614
static FAST_IO_CHECK_IF_POSSIBLE VfatFastIoCheckIfPossible
Definition: fastio.c:14
static FAST_IO_QUERY_STANDARD_INFO VfatFastIoQueryStandardInfo
Definition: fastio.c:161
static FAST_IO_RELEASE_FILE VfatReleaseFileForNtCreateSection
Definition: fastio.c:365
static FAST_IO_ACQUIRE_FOR_CCFLUSH VfatAcquireForCcFlush
Definition: fastio.c:673
static FAST_IO_UNLOCK_ALL_BY_KEY VfatFastIoUnlockAllByKey
Definition: fastio.c:299
static FAST_IO_MDL_READ_COMPLETE_COMPRESSED VfatMdlReadCompleteCompressed
Definition: fastio.c:595
static FAST_IO_ACQUIRE_FOR_MOD_WRITE VfatAcquireForModWrite
Definition: fastio.c:414
static FAST_IO_DETACH_DEVICE VfatFastIoDetachDevice
Definition: fastio.c:377
static FAST_IO_MDL_READ VfatMdlRead
Definition: fastio.c:435
static FAST_IO_UNLOCK_SINGLE VfatFastIoUnlockSingle
Definition: fastio.c:251
static FAST_IO_DEVICE_CONTROL VfatFastIoDeviceControl
Definition: fastio.c:322
static FAST_IO_QUERY_BASIC_INFO VfatFastIoQueryBasicInfo
Definition: fastio.c:102
static FAST_IO_QUERY_OPEN VfatFastIoQueryOpen
Definition: fastio.c:635
static FAST_IO_MDL_READ_COMPLETE VfatMdlReadComplete
Definition: fastio.c:462
static FAST_IO_WRITE VfatFastIoWrite
Definition: fastio.c:73
static FAST_IO_RELEASE_FOR_CCFLUSH VfatReleaseForCcFlush
Definition: fastio.c:697
static FAST_IO_UNLOCK_ALL VfatFastIoUnlockAll
Definition: fastio.c:278
static FAST_IO_LOCK VfatFastIoLock
Definition: fastio.c:220
static FAST_IO_READ_COMPRESSED VfatFastIoReadCompressed
Definition: fastio.c:529
static FAST_IO_PREPARE_MDL_WRITE VfatPrepareMdlWrite
Definition: fastio.c:481
static FAST_IO_QUERY_NETWORK_OPEN_INFO VfatFastIoQueryNetworkOpenInfo
Definition: fastio.c:391
static FAST_IO_RELEASE_FOR_MOD_WRITE VfatReleaseForModWrite
Definition: fastio.c:654
PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite
Definition: iotypes.h:1748
PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo
Definition: iotypes.h:1738
PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey
Definition: iotypes.h:1742
PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush
Definition: iotypes.h:1760
PFAST_IO_MDL_READ_COMPLETE MdlReadComplete
Definition: iotypes.h:1750
PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED MdlWriteCompleteCompressed
Definition: iotypes.h:1756
PFAST_IO_MDL_READ MdlRead
Definition: iotypes.h:1749
PFAST_IO_WRITE FastIoWrite
Definition: iotypes.h:1736
PFAST_IO_UNLOCK_ALL FastIoUnlockAll
Definition: iotypes.h:1741
PFAST_IO_QUERY_NETWORK_OPEN_INFO FastIoQueryNetworkOpenInfo
Definition: iotypes.h:1747
PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush
Definition: iotypes.h:1759
PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete
Definition: iotypes.h:1752
ULONG SizeOfFastIoDispatch
Definition: iotypes.h:1733
PFAST_IO_DEVICE_CONTROL FastIoDeviceControl
Definition: iotypes.h:1743
PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection
Definition: iotypes.h:1744
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1735
PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo
Definition: iotypes.h:1737
PFAST_IO_LOCK FastIoLock
Definition: iotypes.h:1739
PFAST_IO_WRITE_COMPRESSED FastIoWriteCompressed
Definition: iotypes.h:1754
PFAST_IO_MDL_READ_COMPLETE_COMPRESSED MdlReadCompleteCompressed
Definition: iotypes.h:1755
PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle
Definition: iotypes.h:1740
PFAST_IO_READ_COMPRESSED FastIoReadCompressed
Definition: iotypes.h:1753
PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection
Definition: iotypes.h:1745
PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite
Definition: iotypes.h:1751
PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite
Definition: iotypes.h:1758
PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible
Definition: iotypes.h:1734
PFAST_IO_QUERY_OPEN FastIoQueryOpen
Definition: iotypes.h:1757
PFAST_IO_DETACH_DEVICE FastIoDetachDevice
Definition: iotypes.h:1746
struct _FAST_IO_DISPATCH FAST_IO_DISPATCH

Referenced by DriverEntry().

◆ VfatIsDirectoryEmpty()

FORCEINLINE BOOLEAN VfatIsDirectoryEmpty ( PDEVICE_EXTENSION  DeviceExt,
struct _VFATFCB Fcb 
)

Definition at line 367 of file vfat.h.

369{
370 return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb);
371}

Referenced by VfatCleanupFile(), and VfatSetDispositionInformation().

◆ vfatIsLongIllegal()

BOOLEAN vfatIsLongIllegal ( WCHAR  c)

Definition at line 21 of file string.c.

23{
24 return wcschr(long_illegals, c) ? TRUE : FALSE;
25}
#define wcschr
Definition: compat.h:17
const WCHAR * long_illegals
Definition: string.c:18
const GLubyte * c
Definition: glext.h:8905

Referenced by VfatCreateFile().

◆ VfatLockUserBuffer()

NTSTATUS VfatLockUserBuffer ( IN PIRP  Irp,
IN ULONG  Length,
IN LOCK_OPERATION  Operation 
)

Definition at line 460 of file misc.c.

464{
465 ASSERT(Irp);
466
467 if (Irp->MdlAddress)
468 {
469 return STATUS_SUCCESS;
470 }
471
472 IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
473
474 if (!Irp->MdlAddress)
475 {
477 }
478
480 {
481 MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
482 }
484 {
485 IoFreeMdl(Irp->MdlAddress);
486 Irp->MdlAddress = NULL;
488 }
489 _SEH2_END;
490
491 return STATUS_SUCCESS;
492}
FP_OP Operation
Definition: fpcontrol.c:150
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931

Referenced by DoQuery(), VfatCommonRead(), VfatRead(), and VfatWrite().

◆ vfatMakeFCBFromDirEntry()

NTSTATUS vfatMakeFCBFromDirEntry ( PVCB  vcb,
PVFATFCB  directoryFCB,
PVFAT_DIRENTRY_CONTEXT  DirContext,
PVFATFCB fileFCB 
)

Definition at line 725 of file fcb.c.

730{
731 PVFATFCB rcFCB;
732 UNICODE_STRING NameU;
734
735 Status = vfatMakeFullName(directoryFCB, &DirContext->LongNameU, &DirContext->ShortNameU, &NameU);
736 if (!NT_SUCCESS(Status))
737 {
738 return Status;
739 }
740
741 rcFCB = vfatNewFCB(vcb, &NameU);
742 vfatInitFCBFromDirEntry(vcb, directoryFCB, rcFCB, DirContext);
743
744 rcFCB->RefCount = 1;
745 InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
746 vfatAddFCBToTable(vcb, rcFCB);
747 *fileFCB = rcFCB;
748
750 return STATUS_SUCCESS;
751}
#define TAG_FCB
Definition: nodetype.h:152
#define InsertTailList(ListHead, Entry)
static NTSTATUS vfatMakeFullName(PVFATFCB directoryFCB, PUNICODE_STRING LongNameU, PUNICODE_STRING ShortNameU, PUNICODE_STRING NameU)
Definition: fcb.c:210
static VOID vfatInitFCBFromDirEntry(PDEVICE_EXTENSION Vcb, PVFATFCB ParentFcb, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext)
Definition: fcb.c:428
PVFATFCB vfatNewFCB(PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:128
static VOID vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:400

Referenced by FATAddEntry(), FATXAddEntry(), and vfatDirFindFile().

◆ vfatMakeRootFCB()

PVFATFCB vfatMakeRootFCB ( PDEVICE_EXTENSION  pVCB)

Definition at line 648 of file fcb.c.

650{
652 ULONG FirstCluster, CurrentCluster, Size = 0;
655
656 ASSERT(pVCB->RootFcb == NULL);
657
658 FCB = vfatNewFCB(pVCB, &NameU);
659 if (vfatVolumeIsFatX(pVCB))
660 {
661 memset(FCB->entry.FatX.Filename, ' ', 42);
662 FCB->entry.FatX.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
663 FCB->entry.FatX.Attrib = FILE_ATTRIBUTE_DIRECTORY;
664 FCB->entry.FatX.FirstCluster = 1;
665 Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
666 }
667 else
668 {
669 memset(FCB->entry.Fat.ShortName, ' ', 11);
670 FCB->entry.Fat.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
671 FCB->entry.Fat.Attrib = FILE_ATTRIBUTE_DIRECTORY;
672 if (pVCB->FatInfo.FatType == FAT32)
673 {
674 CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
675 FCB->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
676 FCB->entry.Fat.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
677
678 while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
679 {
680 Size += pVCB->FatInfo.BytesPerCluster;
681 Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
682 }
683 }
684 else
685 {
686 FCB->entry.Fat.FirstCluster = 1;
687 Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
688 }
689 }
690 FCB->ShortHash.Hash = FCB->Hash.Hash;
691 FCB->RefCount = 2;
692 FCB->dirIndex = 0;
697
699 vfatAddFCBToTable(pVCB, FCB);
700
701 /* Cache it */
702 pVCB->RootFcb = FCB;
703
704 return FCB;
705}
NTSTATUS vfatFCBInitializeCacheFromVolume(PVCB vcb, PVFATFCB fcb)
Definition: dirwr.c:22
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240
#define memset(x, y, z)
Definition: compat.h:39
LONG RefCount
Definition: ntfs.h:535
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1115
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by vfatOpenRootFCB().

◆ VfatMarkIrpContextForQueue()

FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 625 of file vfat.h.

626{
627 PULONG Flags = &IrpContext->Flags;
628
629 *Flags &= ~IRPCONTEXT_COMPLETE;
631
632 return STATUS_PENDING;
633}
#define IRPCONTEXT_QUEUE
Definition: vfat.h:577
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by VfatClose(), VfatDirectoryControl(), VfatQueryInformation(), VfatQueryVolumeInformation(), VfatRead(), VfatSetInformation(), VfatSetVolumeInformation(), and VfatWrite().

◆ VfatMoveEntry()

NTSTATUS VfatMoveEntry ( IN PDEVICE_EXTENSION  DeviceExt,
IN PVFATFCB  pFcb,
IN PUNICODE_STRING  FileName,
IN PVFATFCB  ParentFcb 
)

Definition at line 1122 of file dirwr.c.

1127{
1129 PVFATFCB OldParent;
1130 VFAT_MOVE_CONTEXT MoveContext;
1131
1132 DPRINT("VfatMoveEntry(%p, %p, %wZ, %p)\n", DeviceExt, pFcb, FileName, ParentFcb);
1133
1134 /* Delete old entry while keeping data */
1135 Status = VfatDelEntry(DeviceExt, pFcb, &MoveContext);
1136 if (!NT_SUCCESS(Status))
1137 {
1138 return Status;
1139 }
1140
1141 OldParent = pFcb->parentFcb;
1142 CcFlushCache(&OldParent->SectionObjectPointers, NULL, 0, NULL);
1143 MoveContext.InPlace = (OldParent == ParentFcb);
1144
1145 /* Add our new entry with our cluster */
1146 Status = VfatAddEntry(DeviceExt,
1147 FileName,
1148 &pFcb,
1149 ParentFcb,
1151 *pFcb->Attributes,
1152 &MoveContext);
1153
1154 CcFlushCache(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, NULL);
1155
1156 return Status;
1157}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
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
struct _VFATFCB * parentFcb
Definition: vfat.h:490
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: vfat.h:451
BOOLEAN InPlace
Definition: vfat.h:613
FORCEINLINE NTSTATUS VfatAddEntry(PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING NameU, struct _VFATFCB **Fcb, struct _VFATFCB *ParentFcb, ULONG RequestedOptions, UCHAR ReqAttr, struct _VFAT_MOVE_CONTEXT *MoveContext)
Definition: vfat.h:375
FORCEINLINE NTSTATUS VfatDelEntry(PDEVICE_EXTENSION DeviceExt, struct _VFATFCB *Fcb, struct _VFAT_MOVE_CONTEXT *MoveContext)
Definition: vfat.h:388

Referenced by vfatRenameEntry(), and VfatSetRenameInformation().

◆ vfatNewFCB()

PVFATFCB vfatNewFCB ( PDEVICE_EXTENSION  pVCB,
PUNICODE_STRING  pFileNameU 
)

Definition at line 128 of file fcb.c.

131{
132 PVFATFCB rcFCB;
133
134 DPRINT("'%wZ'\n", pFileNameU);
135
136 rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList);
137 if (rcFCB == NULL)
138 {
139 return NULL;
140 }
141 RtlZeroMemory(rcFCB, sizeof(VFATFCB));
142 vfatInitFcb(rcFCB, pFileNameU);
143 if (vfatVolumeIsFatX(pVCB))
144 rcFCB->Attributes = &rcFCB->entry.FatX.Attrib;
145 else
146 rcFCB->Attributes = &rcFCB->entry.Fat.Attrib;
147 rcFCB->Hash.Hash = vfatNameHash(0, &rcFCB->PathNameU);
148 rcFCB->Hash.self = rcFCB;
149 rcFCB->ShortHash.self = rcFCB;
154 rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
155 rcFCB->RFCB.Resource = &rcFCB->MainResource;
158
159 return rcFCB;
160}
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1262
unsigned char Attrib
Definition: vfat.h:117
unsigned char Attrib
Definition: vfat.h:172
struct _VFATFCB * self
Definition: vfat.h:278
FAST_MUTEX LastMutex
Definition: vfat.h:527
FSRTL_COMMON_FCB_HEADER RFCB
Definition: vfat.h:450
PUCHAR Attributes
Definition: vfat.h:460
HASHENTRY ShortHash
Definition: vfat.h:517
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
FATX_DIR_ENTRY FatX
Definition: vfat.h:227
static VOID vfatInitFcb(PVFATFCB Fcb, PUNICODE_STRING NameU)
Definition: fcb.c:83
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

Referenced by vfatMakeFCBFromDirEntry(), vfatMakeRootFCB(), and VfatMount().

◆ vfatOpenRootFCB()

PVFATFCB vfatOpenRootFCB ( PDEVICE_EXTENSION  pVCB)

Definition at line 708 of file fcb.c.

710{
713
714 FCB = vfatGrabFCBFromTable(pVCB, &NameU);
715 if (FCB == NULL)
716 {
717 FCB = vfatMakeRootFCB(pVCB);
718 }
719 ASSERT(FCB == pVCB->RootFcb);
720
721 return FCB;
722}
PVFATFCB vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
Definition: fcb.c:648

Referenced by FsdSetFsLabelInformation(), ReadVolumeLabel(), and vfatGetFCBForFile().

◆ VfatPnp()

NTSTATUS VfatPnp ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 18 of file pnp.c.

20{
21 PVCB Vcb = NULL;
23
24 /* PRECONDITION */
25 ASSERT(IrpContext);
26
27 switch (IrpContext->Stack->MinorFunction)
28 {
34 break;
35
36 default:
38 Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;
39 IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
40 Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp);
41 }
42
43 return Status;
44}
struct _VCB * PVCB
Definition: fatstruc.h:557
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
Definition: cdstruc.h:498
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_QUERY_REMOVE_DEVICE

Referenced by VfatDispatchRequest().

◆ VfatQueryInformation()

NTSTATUS VfatQueryInformation ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 1434 of file finfo.c.

1436{
1438 PVFATFCB FCB;
1439
1441 PVOID SystemBuffer;
1443
1444 /* PRECONDITION */
1445 ASSERT(IrpContext);
1446
1447 /* INITIALIZATION */
1448 FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
1449 FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1450
1451 DPRINT("VfatQueryInformation is called for '%s'\n",
1453
1454 if (FCB == NULL)
1455 {
1456 DPRINT1("IRP_MJ_QUERY_INFORMATION without FCB!\n");
1457 IrpContext->Irp->IoStatus.Information = 0;
1459 }
1460
1461 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1462 BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
1463
1465 {
1467 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1468 {
1469 return VfatMarkIrpContextForQueue(IrpContext);
1470 }
1471 }
1472
1473 switch (FileInformationClass)
1474 {
1477 SystemBuffer,
1478 &BufferLength);
1479 break;
1480
1483 FCB,
1484 IrpContext->DeviceExt,
1485 SystemBuffer,
1486 &BufferLength);
1487 break;
1488
1491 FCB,
1492 IrpContext->DeviceExt,
1493 SystemBuffer,
1494 &BufferLength);
1495 break;
1496
1499 FCB,
1500 IrpContext->DeviceExt,
1501 SystemBuffer,
1502 &BufferLength);
1503 break;
1504
1507 IrpContext->DeviceExt,
1508 SystemBuffer,
1509 &BufferLength);
1510 break;
1511
1514 IrpContext->DeviceExt,
1515 SystemBuffer,
1516 &BufferLength);
1517 break;
1518
1519 case FileAllInformation:
1521 FCB,
1522 IrpContext->DeviceExt,
1523 SystemBuffer,
1524 &BufferLength);
1525 break;
1526
1527 case FileEaInformation:
1529 FCB,
1530 IrpContext->DeviceExt,
1531 SystemBuffer,
1532 &BufferLength);
1533 break;
1534
1537 break;
1538
1539 default:
1541 }
1542
1544 {
1546 }
1547
1549 IrpContext->Irp->IoStatus.Information =
1550 IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
1551 else
1552 IrpContext->Irp->IoStatus.Information = 0;
1553
1554 return Status;
1555}
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileMaximumInformation
Definition: from_kernel.h:112
@ FileAllInformation
Definition: from_kernel.h:79
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileEaInformation
Definition: from_kernel.h:68
@ FileAlternateNameInformation
Definition: from_kernel.h:82
@ FileNameInformation
Definition: from_kernel.h:70
@ FileNetworkOpenInformation
Definition: from_kernel.h:95
@ FileBasicInformation
Definition: from_kernel.h:65
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
#define FileStandardInformation
Definition: propsheet.cpp:61
#define FCB_IS_PAGE_FILE
Definition: vfat.h:436
static NTSTATUS VfatGetInternalInformation(PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_INTERNAL_INFORMATION InternalInfo, PULONG BufferLength)
Definition: finfo.c:1015
NTSTATUS VfatGetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
Definition: finfo.c:280
static NTSTATUS VfatGetNetworkOpenInformation(PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_NETWORK_OPEN_INFORMATION NetworkInfo, PULONG BufferLength)
Definition: finfo.c:1039
static NTSTATUS VfatGetPositionInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_POSITION_INFORMATION PositionInfo, PULONG BufferLength)
Definition: finfo.c:123
static NTSTATUS VfatGetAllInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_ALL_INFORMATION Info, PULONG BufferLength)
Definition: finfo.c:1142
static NTSTATUS VfatGetNameInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_NAME_INFORMATION NameInfo, PULONG BufferLength)
Definition: finfo.c:970
static NTSTATUS VfatGetEaInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_EA_INFORMATION Info, PULONG BufferLength)
Definition: finfo.c:1114
NTSTATUS VfatGetStandardInformation(PVFATFCB FCB, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength)
Definition: finfo.c:73
const char * FileInformationClassNames[]
Definition: finfo.c:21

Referenced by VfatDispatchRequest().

◆ VfatQueryVolumeInformation()

NTSTATUS VfatQueryVolumeInformation ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 431 of file volume.c.

433{
436 PVOID SystemBuffer;
438
439 /* PRECONDITION */
440 ASSERT(IrpContext);
441
442 DPRINT("VfatQueryVolumeInformation(IrpContext %p)\n", IrpContext);
443
446 {
447 DPRINT1("DirResource failed!\n");
448 return VfatMarkIrpContextForQueue(IrpContext);
449 }
450
451 /* INITIALIZATION */
452 FsInformationClass = IrpContext->Stack->Parameters.QueryVolume.FsInformationClass;
453 BufferLength = IrpContext->Stack->Parameters.QueryVolume.Length;
454 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
455
456 DPRINT("FsInformationClass %d\n", FsInformationClass);
457 DPRINT("SystemBuffer %p\n", SystemBuffer);
458
459 RtlZeroMemory(SystemBuffer, BufferLength);
460
461 switch (FsInformationClass)
462 {
465 SystemBuffer,
466 &BufferLength);
467 break;
468
471 SystemBuffer,
472 &BufferLength);
473 break;
474
476 RC = FsdGetFsSizeInformation(IrpContext->DeviceObject,
477 SystemBuffer,
478 &BufferLength);
479 break;
480
483 SystemBuffer,
484 &BufferLength);
485 break;
486
489 SystemBuffer,
490 &BufferLength);
491 break;
492
493 default:
495 }
496
498
499 IrpContext->Irp->IoStatus.Information =
500 IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength;
501
502 return RC;
503}
static NTSTATUS FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_SIZE_INFORMATION FsSizeInfo, PULONG BufferLength)
Definition: volume.c:145
static NTSTATUS FsdGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt, PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, PULONG BufferLength)
Definition: volume.c:86
static NTSTATUS FsdGetFsFullSizeInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_FULL_SIZE_INFORMATION FsSizeInfo, PULONG BufferLength)
Definition: volume.c:201
static NTSTATUS FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, PULONG BufferLength)
Definition: volume.c:20
static NTSTATUS FsdGetFsDeviceInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_DEVICE_INFORMATION FsDeviceInfo, PULONG BufferLength)
Definition: volume.c:175
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FS_INFORMATION_CLASS FsInformationClass
Definition: fltkernel.h:1330
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
enum _FSINFOCLASS FS_INFORMATION_CLASS
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423

Referenced by VfatDispatchRequest().

◆ VfatRead()

NTSTATUS VfatRead ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 708 of file rw.c.

710{
713 ULONG Length = 0;
716 ULONG BytesPerSector;
717 BOOLEAN PagingIo, CanWait, IsVolume, NoCache;
718
719 ASSERT(IrpContext);
720
721 DPRINT("VfatRead(IrpContext %p)\n", IrpContext);
722
723 ASSERT(IrpContext->DeviceObject);
724
725 PagingIo = BooleanFlagOn(IrpContext->Irp->Flags, IRP_PAGING_IO);
726 CanWait = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT);
727 NoCache = BooleanFlagOn(IrpContext->Irp->Flags, IRP_NOCACHE);
728
729 // This request is not allowed on the main device object
730 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
731 {
732 DPRINT("VfatRead is called with the main device object.\n");
734 goto ByeBye;
735 }
736
737 ASSERT(IrpContext->DeviceExt);
738 ASSERT(IrpContext->FileObject);
739 Fcb = IrpContext->FileObject->FsContext;
740 ASSERT(Fcb);
741
742 IsVolume = BooleanFlagOn(Fcb->Flags, FCB_IS_VOLUME);
743
745 {
746 PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
747 IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
749 IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
750 DPRINT("Read from page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart);
751 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
752 return Status;
753 }
754
755 DPRINT("<%wZ>\n", &Fcb->PathNameU);
756
757 ByteOffset = IrpContext->Stack->Parameters.Read.ByteOffset;
758 Length = IrpContext->Stack->Parameters.Read.Length;
759 BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
760
761 /* fail if file is a directory and no paged read */
762 if (vfatFCBIsDirectory(Fcb) && !PagingIo)
763 {
765 goto ByeBye;
766 }
767
768 DPRINT("'%wZ', Offset: %u, Length %u\n", &Fcb->PathNameU, ByteOffset.u.LowPart, Length);
769
770 if (ByteOffset.u.HighPart && !IsVolume)
771 {
773 goto ByeBye;
774 }
775
776 if (Length == 0)
777 {
778 IrpContext->Irp->IoStatus.Information = 0;
780 goto ByeBye;
781 }
782
783 if (ByteOffset.QuadPart >= Fcb->RFCB.FileSize.QuadPart)
784 {
785 IrpContext->Irp->IoStatus.Information = 0;
787 goto ByeBye;
788 }
789
790 if (NoCache || PagingIo || IsVolume)
791 {
792 if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
793 {
794 DPRINT("%u %u\n", ByteOffset.u.LowPart, Length);
795 // non cached read must be sector aligned
797 goto ByeBye;
798 }
799 }
800
801 if (IsVolume)
802 {
803 Resource = &IrpContext->DeviceExt->DirResource;
804 }
805 else if (PagingIo)
806 {
808 }
809 else
810 {
812 }
813
814 /* Are we out of stack for the rest of the operation? */
815 if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD)
816 {
817 /* Lock the buffer */
819 if (!NT_SUCCESS(Status))
820 {
821 return Status;
822 }
823
824 /* And post the read to the overflow thread */
825 VfatPostRead(IrpContext, Resource, PagingIo);
826
827 /* Return the appropriate status */
828 return IrpContext->Irp->IoStatus.Status;
829 }
830
832 {
833 Resource = NULL;
835 goto ByeBye;
836 }
837
838 Status = VfatCommonRead(IrpContext);
839
840ByeBye:
841 if (Resource)
842 {
844 }
845
846 if (Status == STATUS_PENDING)
847 {
849 if (NT_SUCCESS(Status))
850 {
852 }
853 }
854 else
855 {
856 IrpContext->Irp->IoStatus.Status = Status;
857 if (BooleanFlagOn(IrpContext->FileObject->Flags, FO_SYNCHRONOUS_IO) &&
858 !PagingIo &&
860 {
861 IrpContext->FileObject->CurrentByteOffset.QuadPart =
862 ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;
863 }
864
865 if (NT_SUCCESS(Status))
866 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
867 }
868 DPRINT("%x\n", Status);
869 return Status;
870}
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: misc.c:460
VOID VfatPostRead(PVFAT_IRP_CONTEXT IrpContext, PERESOURCE Lock, BOOLEAN PagingIo)
Definition: rw.c:682
#define OVERFLOW_READ_THRESHHOLD
Definition: rw.c:29
NTSTATUS VfatCommonRead(PVFAT_IRP_CONTEXT IrpContext)
Definition: rw.c:545
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
#define STATUS_END_OF_FILE
Definition: shellext.h:67
PDEVICE_OBJECT StorageDevice
Definition: ntfs.h:110
FATINFO FatInfo
Definition: vfat.h:324
Definition: vfat.h:250
ULONG dataStart
Definition: vfat.h:258
ULONG BytesPerSector
Definition: vfat.h:261
ERESOURCE PagingIoResource
Definition: ntfs.h:527
#define IRP_PAGING_IO
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_NOCACHE
@ IoWriteAccess
Definition: ketypes.h:864

Referenced by VfatDispatchRequest().

◆ VfatReadDisk()

NTSTATUS VfatReadDisk ( IN PDEVICE_OBJECT  pDeviceObject,
IN PLARGE_INTEGER  ReadOffset,
IN ULONG  ReadLength,
IN PUCHAR  Buffer,
IN BOOLEAN  Override 
)

◆ VfatReadDiskPartial()

NTSTATUS VfatReadDiskPartial ( IN PVFAT_IRP_CONTEXT  IrpContext,
IN PLARGE_INTEGER  ReadOffset,
IN ULONG  ReadLength,
IN ULONG  BufferOffset,
IN BOOLEAN  Wait 
)

◆ vfatReleaseFCB()

VOID vfatReleaseFCB ( PDEVICE_EXTENSION  pVCB,
PVFATFCB  pFCB 
)

Definition at line 335 of file fcb.c.

348{
349 PVFATFCB tmpFcb;
350
351#ifdef KDBG
352 if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
353 {
354 DPRINT1("Dec ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func);
355 }
356#else
357 DPRINT("Releasing FCB at %p: %wZ, refCount:%d\n",
358 pFCB, &pFCB->PathNameU, pFCB->RefCount);
359#endif
360
361 ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource));
362
363 while (pFCB)
364 {
365 ULONG RefCount;
366
368 ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
369 ASSERT(pFCB->RefCount > 0);
370 RefCount = --pFCB->RefCount;
371
372 if (RefCount == 1 && BooleanFlagOn(pFCB->Flags, FCB_CACHE_INITIALIZED))
373 {
374 PFILE_OBJECT tmpFileObject;
375 tmpFileObject = pFCB->FileObject;
376
377 pFCB->FileObject = NULL;
378 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
380 ObDereferenceObject(tmpFileObject);
381 }
382
383 if (RefCount == 0)
384 {
385 ASSERT(pFCB->OpenHandleCount == 0);
386 tmpFcb = pFCB->parentFcb;
387 vfatDelFCBFromTable(pVCB, pFCB);
388 vfatDestroyFCB(pFCB);
389 }
390 else
391 {
392 tmpFcb = NULL;
393 }
394 pFCB = tmpFcb;
395 }
396}
PFILE_OBJECT FileObject
Definition: vfat.h:499
static VOID vfatDelFCBFromTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:164

Referenced by FindFile(), FsdSetFsLabelInformation(), ReadVolumeLabel(), VfatCommonCloseFile(), VfatCreateFile(), vfatGetFCBForFile(), VfatOpenFile(), vfatPrepareTargetForRename(), vfatSetFCBNewDirName(), VfatSetRenameInformation(), and vfatUpdateFCB().

◆ VfatReleaseFromLazyWrite()

VOID NTAPI VfatReleaseFromLazyWrite ( IN PVOID  Context)

Definition at line 741 of file fastio.c.

743{
745 ASSERT(Fcb);
746 DPRINT("VfatReleaseFromLazyWrite(): Fcb %p\n", Fcb);
747
749}

Referenced by DriverEntry().

◆ vfatRenameEntry()

NTSTATUS vfatRenameEntry ( IN PDEVICE_EXTENSION  DeviceExt,
IN PVFATFCB  pFcb,
IN PUNICODE_STRING  FileName,
IN BOOLEAN  CaseChangeOnly 
)

Definition at line 178 of file dirwr.c.

183{
184 OEM_STRING NameA;
185 ULONG StartIndex;
188 PFATX_DIR_ENTRY pDirEntry;
190
191 DPRINT("vfatRenameEntry(%p, %p, %wZ, %d)\n", DeviceExt, pFcb, FileName, CaseChangeOnly);
192
193 Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
194 if (!NT_SUCCESS(Status))
195 {
196 return Status;
197 }
198
199 if (vfatVolumeIsFatX(DeviceExt))
200 {
202
203 /* Open associated dir entry */
204 StartIndex = pFcb->startIndex;
205 Offset.u.HighPart = 0;
206 Offset.u.LowPart = (StartIndex * sizeof(FATX_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
208 {
209 CcPinRead(pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, PIN_WAIT, &Context, (PVOID*)&pDirEntry);
210 }
212 {
213 DPRINT1("CcPinRead(Offset %x:%x, Length %d) failed\n", Offset.u.HighPart, Offset.u.LowPart, PAGE_SIZE);
215 }
216 _SEH2_END;
217
218 pDirEntry = &pDirEntry[StartIndex % (PAGE_SIZE / sizeof(FATX_DIR_ENTRY))];
219
220 /* Set file name */
221 NameA.Buffer = (PCHAR)pDirEntry->Filename;
222 NameA.Length = 0;
223 NameA.MaximumLength = 42;
225 pDirEntry->FilenameLength = (unsigned char)NameA.Length;
226
227 /* Update FCB */
228 DirContext.DeviceExt = DeviceExt;
229 DirContext.ShortNameU.Length = 0;
230 DirContext.ShortNameU.MaximumLength = 0;
231 DirContext.ShortNameU.Buffer = NULL;
232 DirContext.LongNameU = *FileName;
233 DirContext.DirEntry.FatX = *pDirEntry;
234
237
238 Status = vfatUpdateFCB(DeviceExt, pFcb, &DirContext, pFcb->parentFcb);
239 if (NT_SUCCESS(Status))
240 {
241 CcFlushCache(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, NULL);
242 }
243
244 return Status;
245 }
246 else
247 {
248 /* This we cannot handle properly, move file - would likely need love */
249 return VfatMoveEntry(DeviceExt, pFcb, FileName, pFcb->parentFcb);
250 }
251}
NTSTATUS VfatMoveEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN PVFATFCB ParentFcb)
Definition: dirwr.c:1122
unsigned char
Definition: typeof.h:29
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PCHAR
Definition: match.c:90
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned char Filename[42]
Definition: vfat.h:173
unsigned char FilenameLength
Definition: vfat.h:171
struct _FATXDirEntry FATX_DIR_ENTRY
Definition: vfat.h:222
NTSTATUS vfatUpdateFCB(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB ParentFcb)
Definition: fcb.c:539

Referenced by VfatSetRenameInformation().

◆ vfatReportChange()

VOID vfatReportChange ( IN PDEVICE_EXTENSION  DeviceExt,
IN PVFATFCB  Fcb,
IN ULONG  FilterMatch,
IN ULONG  Action 
)

Definition at line 658 of file vfat.h.

663{
664 FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
665 &(DeviceExt->NotifyList),
666 (PSTRING)&Fcb->PathNameU,
667 Fcb->PathNameU.Length - Fcb->LongNameU.Length,
669}
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG FilterMatch
Definition: fsrtlfuncs.h:743
VOID NTAPI FsRtlNotifyFullReportChange(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext)
Definition: notify.c:1552
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510

Referenced by VfatCleanupFile(), VfatCreateFile(), VfatSetAllocationSizeInformation(), VfatSetBasicInformation(), VfatSetRenameInformation(), and VfatWrite().

◆ VfatSetAllocationSizeInformation()

NTSTATUS VfatSetAllocationSizeInformation ( PFILE_OBJECT  FileObject,
PVFATFCB  Fcb,
PDEVICE_EXTENSION  DeviceExt,
PLARGE_INTEGER  AllocationSize 
)

Definition at line 1211 of file finfo.c.

1216{
1217 ULONG OldSize;
1218 ULONG Cluster, FirstCluster;
1220
1221 ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
1222 ULONG NewSize = AllocationSize->u.LowPart;
1223 ULONG NCluster;
1224 BOOLEAN AllocSizeChanged = FALSE, IsFatX = vfatVolumeIsFatX(DeviceExt);
1225
1226 DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n",
1227 &Fcb->PathNameU, AllocationSize->HighPart, AllocationSize->LowPart);
1228
1229 if (IsFatX)
1230 OldSize = Fcb->entry.FatX.FileSize;
1231 else
1232 OldSize = Fcb->entry.Fat.FileSize;
1233
1234 if (AllocationSize->u.HighPart > 0)
1235 {
1237 }
1238
1239 if (OldSize == NewSize)
1240 {
1241 return STATUS_SUCCESS;
1242 }
1243
1244 FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry);
1245
1246 if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
1247 {
1248 AllocSizeChanged = TRUE;
1249 if (FirstCluster == 0)
1250 {
1251 Fcb->LastCluster = Fcb->LastOffset = 0;
1252 Status = NextCluster(DeviceExt, FirstCluster, &FirstCluster, TRUE);
1253 if (!NT_SUCCESS(Status))
1254 {
1255 DPRINT1("NextCluster failed. Status = %x\n", Status);
1256 return Status;
1257 }
1258
1259 if (FirstCluster == 0xffffffff)
1260 {
1261 return STATUS_DISK_FULL;
1262 }
1263
1264 Status = OffsetToCluster(DeviceExt, FirstCluster,
1266 &NCluster, TRUE);
1267 if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1268 {
1269 /* disk is full */
1270 NCluster = Cluster = FirstCluster;
1272 while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1273 {
1274 Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1275 WriteCluster(DeviceExt, Cluster, 0);
1276 Cluster = NCluster;
1277 }
1278 return STATUS_DISK_FULL;
1279 }
1280
1281 if (IsFatX)
1282 {
1283 Fcb->entry.FatX.FirstCluster = FirstCluster;
1284 }
1285 else
1286 {
1287 if (DeviceExt->FatInfo.FatType == FAT32)
1288 {
1289 Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1290 Fcb->entry.Fat.FirstClusterHigh = FirstCluster >> 16;
1291 }
1292 else
1293 {
1294 ASSERT((FirstCluster >> 16) == 0);
1295 Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1296 }
1297 }
1298 }
1299 else
1300 {
1301 if (Fcb->LastCluster > 0)
1302 {
1303 if (Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize == Fcb->LastOffset)
1304 {
1305 Cluster = Fcb->LastCluster;
1307 }
1308 else
1309 {
1310 Status = OffsetToCluster(DeviceExt, Fcb->LastCluster,
1311 Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize - Fcb->LastOffset,
1312 &Cluster, FALSE);
1313 }
1314 }
1315 else
1316 {
1317 Status = OffsetToCluster(DeviceExt, FirstCluster,
1318 Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
1319 &Cluster, FALSE);
1320 }
1321
1322 if (!NT_SUCCESS(Status))
1323 {
1324 return Status;
1325 }
1326
1327 Fcb->LastCluster = Cluster;
1328 Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;
1329
1330 /* FIXME: Check status */
1331 /* Cluster points now to the last cluster within the chain */
1332 Status = OffsetToCluster(DeviceExt, Cluster,
1333 ROUND_DOWN(NewSize - 1, ClusterSize) - Fcb->LastOffset,
1334 &NCluster, TRUE);
1335 if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1336 {
1337 /* disk is full */
1338 NCluster = Cluster;
1339 Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1340 WriteCluster(DeviceExt, Cluster, 0xffffffff);
1341 Cluster = NCluster;
1342 while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1343 {
1344 Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1345 WriteCluster(DeviceExt, Cluster, 0);
1346 Cluster = NCluster;
1347 }
1348 return STATUS_DISK_FULL;
1349 }
1350 }
1352 }
1353 else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
1354 {
1355 DPRINT("Check for the ability to set file size\n");
1356 if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
1358 {
1359 DPRINT("Couldn't set file size!\n");
1361 }
1362 DPRINT("Can set file size\n");
1363
1364 AllocSizeChanged = TRUE;
1365 /* FIXME: Use the cached cluster/offset better way. */
1366 Fcb->LastCluster = Fcb->LastOffset = 0;
1368 if (NewSize > 0)
1369 {
1370 Status = OffsetToCluster(DeviceExt, FirstCluster,
1372 &Cluster, FALSE);
1373
1374 NCluster = Cluster;
1375 Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1376 WriteCluster(DeviceExt, Cluster, 0xffffffff);
1377 Cluster = NCluster;
1378 }
1379 else
1380 {
1381 if (IsFatX)
1382 {
1383 Fcb->entry.FatX.FirstCluster = 0;
1384 }
1385 else
1386 {
1387 if (DeviceExt->FatInfo.FatType == FAT32)
1388 {
1389 Fcb->entry.Fat.FirstCluster = 0;
1390 Fcb->entry.Fat.FirstClusterHigh = 0;
1391 }
1392 else
1393 {
1394 Fcb->entry.Fat.FirstCluster = 0;
1395 }
1396 }
1397
1398 NCluster = Cluster = FirstCluster;
1400 }
1401
1402 while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
1403 {
1404 Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1405 WriteCluster(DeviceExt, Cluster, 0);
1406 Cluster = NCluster;
1407 }
1408
1409 if (DeviceExt->FatInfo.FatType == FAT32)
1410 {
1412 }
1413 }
1414 else
1415 {
1417 }
1418
1419 /* Update the on-disk directory entry */
1421 if (AllocSizeChanged)
1422 {
1423 VfatUpdateEntry(DeviceExt, Fcb);
1424
1426 }
1427 return STATUS_SUCCESS;
1428}
DWORD ClusterSize
Definition: format.c:67
ULONG vfatDirEntryGetFirstCluster(PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
Definition: direntry.c:18
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:115
NTSTATUS FAT32UpdateFreeClustersCount(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:1215
NTSTATUS OffsetToCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, BOOLEAN Extend)
Definition: rw.c:59
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:322
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4255
struct _LARGE_INTEGER::@2290 u
#define FCB_IS_DIRTY
Definition: vfat.h:438
FORCEINLINE VOID vfatReportChange(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
Definition: vfat.h:658
static VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, ULONG ClusterSize, BOOLEAN IsFatX)
Definition: finfo.c:1182
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_ACTION_MODIFIED

Referenced by VfatCreateFile(), vfatFindDirSpace(), VfatSetInformation(), and VfatWrite().

◆ VfatSetExtendedAttributes()

NTSTATUS VfatSetExtendedAttributes ( PFILE_OBJECT  FileObject,
PVOID  Ea,
ULONG  EaLength 
)

Definition at line 18 of file ea.c.

22{
26
28}
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:878
#define STATUS_EAS_NOT_SUPPORTED
Definition: ntstatus.h:315

Referenced by VfatCreateFile().

◆ vfatSetFCBNewDirName()

NTSTATUS vfatSetFCBNewDirName ( PDEVICE_EXTENSION  pVCB,
PVFATFCB  Fcb,
PVFATFCB  ParentFcb 
)

Definition at line 492 of file fcb.c.

496{
498 UNICODE_STRING NewNameU;
499
500 /* Get full path name */
501 Status = vfatMakeFullName(ParentFcb, &Fcb->LongNameU, &Fcb->ShortNameU, &NewNameU);
502 if (!NT_SUCCESS(Status))
503 {
504 return Status;
505 }
506
507 /* Delete old name */
508 if (Fcb->PathNameBuffer)
509 {
510 ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
511 }
512 Fcb->PathNameU = NewNameU;
513
514 /* Delete from table */
516
517 /* Split it properly */
518 Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
519 Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
520 vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
521 Fcb->Hash.Hash = vfatNameHash(0, &Fcb->PathNameU);
522 if (vfatVolumeIsFatX(pVCB))
523 {
524 Fcb->ShortHash.Hash = Fcb->Hash.Hash;
525 }
526 else
527 {
528 Fcb->ShortHash.Hash = vfatNameHash(0, &Fcb->DirNameU);
529 Fcb->ShortHash.Hash = vfatNameHash(Fcb->ShortHash.Hash, &Fcb->ShortNameU);
530 }
531
532 vfatAddFCBToTable(pVCB, Fcb);
534
535 return STATUS_SUCCESS;
536}

Referenced by VfatRenameChildFCB().

◆ VfatSetInformation()

NTSTATUS VfatSetInformation ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 1561 of file finfo.c.

1563{
1565 PVFATFCB FCB;
1567 PVOID SystemBuffer;
1568 BOOLEAN LockDir;
1569
1570 /* PRECONDITION */
1571 ASSERT(IrpContext);
1572
1573 DPRINT("VfatSetInformation(IrpContext %p)\n", IrpContext);
1574
1575 /* INITIALIZATION */
1577 IrpContext->Stack->Parameters.SetFile.FileInformationClass;
1578 FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1579 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1580
1581 DPRINT("VfatSetInformation is called for '%s'\n",
1583
1584 DPRINT("FileInformationClass %d\n", FileInformationClass);
1585 DPRINT("SystemBuffer %p\n", SystemBuffer);
1586
1587 if (FCB == NULL)
1588 {
1589 DPRINT1("IRP_MJ_SET_INFORMATION without FCB!\n");
1590 IrpContext->Irp->IoStatus.Information = 0;
1592 }
1593
1594 /* Special: We should call MmCanFileBeTruncated here to determine if changing
1595 the file size would be allowed. If not, we bail with the right error.
1596 We must do this before acquiring the lock. */
1598 {
1599 DPRINT("Check for the ability to set file size\n");
1600 if (!MmCanFileBeTruncated(IrpContext->FileObject->SectionObjectPointer,
1601 (PLARGE_INTEGER)SystemBuffer))
1602 {
1603 DPRINT("Couldn't set file size!\n");
1604 IrpContext->Irp->IoStatus.Information = 0;
1606 }
1607 DPRINT("Can set file size\n");
1608 }
1609
1610 LockDir = FALSE;
1613 {
1614 LockDir = TRUE;
1615 }
1616
1617 if (LockDir)
1618 {
1620 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1621 {
1622 return VfatMarkIrpContextForQueue(IrpContext);
1623 }
1624 }
1625
1627 {
1629 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1630 {
1631 if (LockDir)
1632 {
1634 }
1635
1636 return VfatMarkIrpContextForQueue(IrpContext);
1637 }
1638 }
1639
1640 switch (FileInformationClass)
1641 {
1644 SystemBuffer);
1645 break;
1646
1649 FCB,
1650 IrpContext->DeviceExt,
1651 SystemBuffer);
1652 break;
1653
1657 FCB,
1658 IrpContext->DeviceExt,
1659 (PLARGE_INTEGER)SystemBuffer);
1660 break;
1661
1664 FCB,
1665 IrpContext->DeviceExt,
1666 SystemBuffer);
1667 break;
1668
1671 FCB,
1672 IrpContext->DeviceExt,
1673 SystemBuffer,
1674 IrpContext->Stack->Parameters.SetFile.FileObject);
1675 break;
1676
1677 default:
1679 }
1680
1682 {
1684 }
1685
1686 if (LockDir)
1687 {
1689 }
1690
1691 IrpContext->Irp->IoStatus.Information = 0;
1692 return Status;
1693}
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileDispositionInformation
Definition: from_kernel.h:74
static NTSTATUS VfatSetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo)
Definition: finfo.c:151
static NTSTATUS VfatSetRenameInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_RENAME_INFORMATION RenameInfo, PFILE_OBJECT TargetFileObject)
Definition: finfo.c:558
static NTSTATUS VfatSetDispositionInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_DISPOSITION_INFORMATION DispositionInfo)
Definition: finfo.c:349
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
Definition: finfo.c:1211
static NTSTATUS VfatSetPositionInformation(PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION PositionInfo)
Definition: finfo.c:106

Referenced by VfatDispatchRequest().

◆ VfatSetVolumeInformation()

NTSTATUS VfatSetVolumeInformation ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 510 of file volume.c.

512{
515 PVOID SystemBuffer;
517 PIO_STACK_LOCATION Stack = IrpContext->Stack;
518
519 /* PRECONDITION */
520 ASSERT(IrpContext);
521
522 DPRINT("VfatSetVolumeInformation(IrpContext %p)\n", IrpContext);
523
526 {
527 return VfatMarkIrpContextForQueue(IrpContext);
528 }
529
530 FsInformationClass = Stack->Parameters.SetVolume.FsInformationClass;
531 BufferLength = Stack->Parameters.SetVolume.Length;
532 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
533
534 DPRINT("FsInformationClass %d\n", FsInformationClass);
535 DPRINT("BufferLength %u\n", BufferLength);
536 DPRINT("SystemBuffer %p\n", SystemBuffer);
537
538 switch (FsInformationClass)
539 {
542 SystemBuffer);
543 break;
544
545 default:
547 }
548
550 IrpContext->Irp->IoStatus.Information = 0;
551
552 return Status;
553}
static NTSTATUS FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_LABEL_INFORMATION FsLabelInfo)
Definition: volume.c:232
@ FileFsLabelInformation
Definition: from_kernel.h:220

Referenced by VfatDispatchRequest().

◆ VfatShutdown()

NTSTATUS NTAPI VfatShutdown ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 50 of file shutdown.c.

53{
55 PLIST_ENTRY ListEntry;
56 PDEVICE_EXTENSION DeviceExt;
57
58 DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);
59
61
62 /* FIXME: block new mount requests */
64
66 {
67 Irp->IoStatus.Status = STATUS_SUCCESS;
70 while (ListEntry != &VfatGlobalData->VolumeListHead)
71 {
72 DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
73 ListEntry = ListEntry->Flink;
74
75 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
76
77 /* Flush volume & files */
78 Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
79
80 /* We're performing a clean shutdown */
81 if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) &&
82 BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY))
83 {
84 /* Drop the dirty bit */
85 if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE)))
86 DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
87 }
88
89 if (NT_SUCCESS(Status))
90 {
91 Status = VfatDiskShutDown(DeviceExt);
92 if (!NT_SUCCESS(Status))
93 {
94 DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
95 }
96 }
97 else
98 {
99 DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
100 }
101 ExReleaseResourceLite(&DeviceExt->DirResource);
102
103 /* Unmount the logical volume */
104#ifdef ENABLE_SWAPOUT
105 VfatCheckForDismount(DeviceExt, FALSE);
106#endif
107
108 if (!NT_SUCCESS(Status))
109 Irp->IoStatus.Status = Status;
110 }
112
113 /* FIXME: Free all global acquired resources */
114
115 Status = Irp->IoStatus.Status;
116 }
117 else
118 {
119 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
121 }
122
123 Irp->IoStatus.Information = 0;
125
127
128 return Status;
129}
NTSTATUS SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
Definition: fat.c:1017
static NTSTATUS VfatDiskShutDown(PVCB Vcb)
Definition: shutdown.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define IoCompleteRequest
Definition: irp.c:1240
LIST_ENTRY VolumeListHead
Definition: vfat.h:416
#define VCB_CLEAR_DIRTY
Definition: vfat.h:245
#define VCB_IS_DIRTY
Definition: vfat.h:244
#define IO_NO_INCREMENT
Definition: iotypes.h:598

◆ vfatSplitPathName()

VOID vfatSplitPathName ( PUNICODE_STRING  PathNameU,
PUNICODE_STRING  DirNameU,
PUNICODE_STRING  FileNameU 
)

Definition at line 54 of file fcb.c.

58{
60 USHORT Length = 0;
61 pName = PathNameU->Buffer + PathNameU->Length / sizeof(WCHAR) - 1;
62 while (*pName != L'\\' && pName >= PathNameU->Buffer)
63 {
64 pName--;
65 Length++;
66 }
67 ASSERT(*pName == L'\\' || pName < PathNameU->Buffer);
68 if (FileNameU)
69 {
70 FileNameU->Buffer = pName + 1;
71 FileNameU->Length = FileNameU->MaximumLength = Length * sizeof(WCHAR);
72 }
73 if (DirNameU)
74 {
75 DirNameU->Buffer = PathNameU->Buffer;
76 DirNameU->Length = (pName + 1 - PathNameU->Buffer) * sizeof(WCHAR);
77 DirNameU->MaximumLength = DirNameU->Length;
78 }
79}
Definition: bufpool.h:45
static LPSTR pName
Definition: security.c:75

Referenced by VfatCreateFile(), vfatGrabFCBFromTable(), vfatInitFcb(), vfatSetFCBNewDirName(), VfatSetRenameInformation(), and vfatUpdateFCB().

◆ VfatUpdateEntry()

NTSTATUS VfatUpdateEntry ( IN PDEVICE_EXTENSION  DeviceExt,
PVFATFCB  pFcb 
)

◆ vfatUpdateFCB()

NTSTATUS vfatUpdateFCB ( PDEVICE_EXTENSION  pVCB,
PVFATFCB  Fcb,
PVFAT_DIRENTRY_CONTEXT  DirContext,
PVFATFCB  ParentFcb 
)

Definition at line 539 of file fcb.c.

544{
546 PVFATFCB OldParent;
547
548 DPRINT("vfatUpdateFCB(%p, %p, %p, %p)\n", pVCB, Fcb, DirContext, ParentFcb);
549
550 /* Get full path name */
551 Status = vfatMakeFullName(ParentFcb, &DirContext->LongNameU, &DirContext->ShortNameU, &Fcb->PathNameU);
552 if (!NT_SUCCESS(Status))
553 {
554 return Status;
555 }
556
557 /* Delete old name */
558 if (Fcb->PathNameBuffer)
559 {
560 ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
561 }
562
563 /* Delete from table */
565
566 /* Split it properly */
567 Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
568 Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
569 vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
570
571 /* Save old parent */
572 OldParent = Fcb->parentFcb;
573 RemoveEntryList(&Fcb->ParentListEntry);
574
575 /* Reinit FCB */
577
579 {
581 }
582 InsertTailList(&ParentFcb->ParentListHead, &Fcb->ParentListEntry);
583 vfatAddFCBToTable(pVCB, Fcb);
584
585 /* If we moved across directories, dereference our old parent
586 * We also dereference in case we're just renaming since AddFCBToTable references it
587 */
588 vfatReleaseFCB(pVCB, OldParent);
589
590 return STATUS_SUCCESS;
591}
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:518

Referenced by FATAddEntry(), FATXAddEntry(), and vfatRenameEntry().

◆ vfatVolumeIsFatX()

◆ VfatWrite()

NTSTATUS VfatWrite ( PVFAT_IRP_CONTEXT pIrpContext)

CanWait

Definition at line 873 of file rw.c.

875{
876 PVFAT_IRP_CONTEXT IrpContext = *pIrpContext;
880 LARGE_INTEGER OldFileSize;
882 ULONG Length = 0;
884 ULONG BytesPerSector;
885 BOOLEAN PagingIo, CanWait, IsVolume, IsFAT, NoCache;
886
887 ASSERT(IrpContext);
888
889 DPRINT("VfatWrite(IrpContext %p)\n", IrpContext);
890
891 ASSERT(IrpContext->DeviceObject);
892
893 PagingIo = BooleanFlagOn(IrpContext->Irp->Flags, IRP_PAGING_IO);
894 CanWait = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT);
895 NoCache = BooleanFlagOn(IrpContext->Irp->Flags, IRP_NOCACHE);
896
897 // This request is not allowed on the main device object
898 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
899 {
900 DPRINT("VfatWrite is called with the main device object.\n");
902 goto ByeBye;
903 }
904
905 ASSERT(IrpContext->DeviceExt);
906 ASSERT(IrpContext->FileObject);
907 Fcb = IrpContext->FileObject->FsContext;
908 ASSERT(Fcb);
909
910 IsVolume = BooleanFlagOn(Fcb->Flags, FCB_IS_VOLUME);
912
914 {
915 PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
916 IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
918 IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
919 DPRINT("Write to page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart);
920 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
921 return Status;
922 }
923
924 DPRINT("<%wZ>\n", &Fcb->PathNameU);
925
926 /* fail if file is a directory and no paged read */
927 if (vfatFCBIsDirectory(Fcb) && !PagingIo)
928 {
930 goto ByeBye;
931 }
932
933 ByteOffset = IrpContext->Stack->Parameters.Write.ByteOffset;
934 if (ByteOffset.u.LowPart == FILE_WRITE_TO_END_OF_FILE &&
935 ByteOffset.u.HighPart == -1)
936 {
937 ByteOffset.QuadPart = Fcb->RFCB.FileSize.QuadPart;
938 }
939 Length = IrpContext->Stack->Parameters.Write.Length;
940 BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
941
942 if (ByteOffset.u.HighPart && !IsVolume)
943 {
945 goto ByeBye;
946 }
947
948 if (IsFAT || IsVolume ||
949 vfatDirEntryGetFirstCluster(IrpContext->DeviceExt, &Fcb->entry) == 1)
950 {
951 if (ByteOffset.QuadPart + Length > Fcb->RFCB.FileSize.QuadPart)
952 {
953 // we can't extend the FAT, the volume or the root on FAT12/FAT16
955 goto ByeBye;
956 }
957 }
958
959 if (PagingIo || NoCache || IsVolume)
960 {
961 if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
962 {
963 // non cached write must be sector aligned
965 goto ByeBye;
966 }
967 }
968
969 OldFileSize = Fcb->RFCB.FileSize;
970
971 if (Length == 0)
972 {
973 /* Update last write time */
974 IrpContext->Irp->IoStatus.Information = 0;
976 goto Metadata;
977 }
978
979 if (PagingIo)
980 {
981 if (ByteOffset.u.LowPart + Length > Fcb->RFCB.AllocationSize.u.LowPart)
982 {
984 goto ByeBye;
985 }
986
987 if (ByteOffset.u.LowPart + Length > ROUND_UP(Fcb->RFCB.AllocationSize.u.LowPart, BytesPerSector))
988 {
989 Length = ROUND_UP(Fcb->RFCB.FileSize.u.LowPart, BytesPerSector) - ByteOffset.u.LowPart;
990 }
991 }
992
993 if (!NoCache && !CcCanIWrite(IrpContext->FileObject, Length, CanWait,
995 {
996 BOOLEAN Retrying;
997
998 Retrying = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_DEFERRED_WRITE);
1000
1001 IoMarkIrpPending(IrpContext->Irp);
1003
1004 DPRINT1("Deferring write for Irp %p, context %p!\n", IrpContext->Irp, IrpContext);
1006 IrpContext, NULL, Length, Retrying);
1007 *pIrpContext = NULL;
1008
1009 return Status;
1010 }
1011
1012 if (IsVolume)
1013 {
1014 Resource = &IrpContext->DeviceExt->DirResource;
1015 }
1016 else if (PagingIo)
1017 {
1019 }
1020 else
1021 {
1023 }
1024
1025 if (PagingIo)
1026 {
1028 {
1029 Resource = NULL;
1031 goto ByeBye;
1032 }
1033 }
1034 else
1035 {
1037 {
1038 Resource = NULL;
1040 goto ByeBye;
1041 }
1042 }
1043
1044 if (!PagingIo &&
1046 {
1047 if (!FsRtlCheckLockForWriteAccess(&Fcb->FileLock, IrpContext->Irp))
1048 {
1050 goto ByeBye;
1051 }
1052 }
1053
1054 if (!CanWait && !IsVolume)
1055 {
1056 if (ByteOffset.u.LowPart + Length > Fcb->RFCB.AllocationSize.u.LowPart)
1057 {
1059 goto ByeBye;
1060 }
1061 }
1062
1063 Buffer = VfatGetUserBuffer(IrpContext->Irp, PagingIo);
1064
1065 if (!IsFAT && !IsVolume && !PagingIo &&
1066 ByteOffset.u.LowPart + Length > Fcb->RFCB.FileSize.u.LowPart)
1067 {
1069
1070 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, CanWait))
1071 {
1073 goto ByeBye;
1074 }
1075
1076 AllocationSize.QuadPart = ByteOffset.u.LowPart + Length;
1078 IrpContext->DeviceExt, &AllocationSize);
1079
1081
1082 if (!NT_SUCCESS (Status))
1083 {
1084 goto ByeBye;
1085 }
1086 }
1087
1088 if (!NoCache && !PagingIo && !IsVolume)
1089 {
1090 // cached write
1091
1092 vfatAddToStat(IrpContext->DeviceExt, Base.UserFileWrites, 1);
1093 vfatAddToStat(IrpContext->DeviceExt, Base.UserFileWriteBytes, Length);
1094
1095 _SEH2_TRY
1096 {
1097 if (IrpContext->FileObject->PrivateCacheMap == NULL)
1098 {
1099 CcInitializeCacheMap(IrpContext->FileObject,
1101 FALSE,
1103 Fcb);
1104 }
1105
1106 if (ByteOffset.QuadPart > OldFileSize.QuadPart)
1107 {
1108 CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE);
1109 }
1110
1111 if (CcCopyWrite(IrpContext->FileObject,
1112 &ByteOffset,
1113 Length,
1114 TRUE /*CanWait*/,
1115 Buffer))
1116 {
1117 IrpContext->Irp->IoStatus.Information = Length;
1119 }
1120 else
1121 {
1122 ASSERT(FALSE );
1124 }
1125 }
1127 {
1129 }
1130 _SEH2_END;
1131 }
1132 else
1133 {
1134 // non cached write
1136 if (!NT_SUCCESS(Status))
1137 {
1139 goto ByeBye;
1140 }
1141
1142 if (ByteOffset.QuadPart > OldFileSize.QuadPart)
1143 {
1144 CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE);
1145 }
1146
1147 if (!IsVolume)
1148 {
1149 vfatAddToStat(IrpContext->DeviceExt, Fat.NonCachedWrites, 1);
1150 vfatAddToStat(IrpContext->DeviceExt, Fat.NonCachedWriteBytes, Length);
1151 }
1152 else
1153 {
1154 vfatAddToStat(IrpContext->DeviceExt, Base.MetaDataWrites, 1);
1155 vfatAddToStat(IrpContext->DeviceExt, Base.MetaDataWriteBytes, Length);
1156 }
1157
1158 Status = VfatWriteFileData(IrpContext, Length, ByteOffset);
1159 if (NT_SUCCESS(Status))
1160 {
1161 IrpContext->Irp->IoStatus.Information = Length;
1162 }
1163 }
1164
1165Metadata:
1166 if (!PagingIo && !IsFAT && !IsVolume)
1167 {
1169 {
1170 LARGE_INTEGER SystemTime;
1171 ULONG Filter;
1172
1173 // set dates and times
1174 KeQuerySystemTime (&SystemTime);
1175 if (vfatVolumeIsFatX(IrpContext->DeviceExt))
1176 {
1178 &SystemTime, &Fcb->entry.FatX.UpdateDate,
1179 &Fcb->entry.FatX.UpdateTime);
1180 Fcb->entry.FatX.AccessDate = Fcb->entry.FatX.UpdateDate;
1181 Fcb->entry.FatX.AccessTime = Fcb->entry.FatX.UpdateTime;
1182 }
1183 else
1184 {
1186 &SystemTime, &Fcb->entry.Fat.UpdateDate,
1187 &Fcb->entry.Fat.UpdateTime);
1188 Fcb->entry.Fat.AccessDate = Fcb->entry.Fat.UpdateDate;
1189 }
1190 /* set date and times to dirty */
1192
1193 /* Time to notify the OS */
1195 if (ByteOffset.QuadPart != OldFileSize.QuadPart) Filter |= FILE_NOTIFY_CHANGE_SIZE;
1196
1198 }
1199 }
1200
1201ByeBye:
1202 if (Resource)
1203 {
1205 }
1206
1207 if (Status == STATUS_PENDING)
1208 {
1210 if (NT_SUCCESS(Status))
1211 {
1212 Status = VfatMarkIrpContextForQueue(IrpContext);
1213 }
1214 }
1215 else
1216 {
1217 IrpContext->Irp->IoStatus.Status = Status;
1218 if (BooleanFlagOn(IrpContext->FileObject->Flags, FO_SYNCHRONOUS_IO) &&
1219 !PagingIo && NT_SUCCESS(Status))
1220 {
1221 IrpContext->FileObject->CurrentByteOffset.QuadPart =
1222 ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;
1223 }
1224
1225 if (NT_SUCCESS(Status))
1226 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1227 }
1228 DPRINT("%x\n", Status);
1229 return Status;
1230}
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:52
VOID NTAPI VfatHandleDeferredWrite(IN PVOID IrpContext, IN PVOID Unused)
Definition: misc.c:220
PVOID VfatGetUserBuffer(IN PIRP Irp, IN BOOLEAN Paging)
Definition: misc.c:443
static NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext, ULONG Length, LARGE_INTEGER WriteOffset)
Definition: rw.c:331
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define FILE_WRITE_TO_END_OF_FILE
Definition: ext2fs.h:278
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:710
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
#define FsRtlAreThereCurrentFileLocks(FL)
Definition: fsrtlfuncs.h:1584
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:414
IoMarkIrpPending(Irp)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
VOID NTAPI CcDeferWrite(IN PFILE_OBJECT FileObject, IN PCC_POST_DEFERRED_WRITE PostRoutine, IN PVOID Context1, IN PVOID Context2, IN ULONG BytesToWrite, IN BOOLEAN Retrying)
Definition: copysup.c:225
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
FILE_LOCK FileLock
Definition: fatstruc.h:1071
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define IRPCONTEXT_DEFERRED_WRITE
Definition: vfat.h:579
#define vfatAddToStat(Vcb, Stat, Inc)
Definition: vfat.h:671
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FILE_NOTIFY_CHANGE_LAST_WRITE
@ IoReadAccess
Definition: ketypes.h:863

Referenced by VfatDispatchRequest().

◆ VfatWriteDisk()

NTSTATUS VfatWriteDisk ( IN PDEVICE_OBJECT  pDeviceObject,
IN PLARGE_INTEGER  WriteOffset,
IN ULONG  WriteLength,
IN OUT PUCHAR  Buffer,
IN BOOLEAN  Override 
)

Definition at line 253 of file blockdev.c.

259{
261 PIRP Irp;
265
266again:
268
269 DPRINT("VfatWriteDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
271
272 DPRINT ("Building synchronous FSD Request...\n");
275 Buffer,
278 &Event,
279 &IoStatus);
280 if (Irp == NULL)
281 {
282 DPRINT("IoBuildSynchronousFsdRequest failed\n");
283 return STATUS_UNSUCCESSFUL;
284 }
285
286 if (Override)
287 {
290 }
291
292 DPRINT("Calling IO Driver... with irp %p\n", Irp);
294
295 DPRINT("Waiting for IO Operation for %p\n", Irp);
296 if (Status == STATUS_PENDING)
297 {
298 DPRINT("Operation pending\n");
300 DPRINT("Getting IO Status... for %p\n", Irp);
301 Status = IoStatus.Status;
302 }
303
305 {
307
308 DPRINT1 ("Media change detected!\n");
309
310 /* Find the device to verify and reset the thread field to empty value again. */
314 FALSE);
315 if (NT_SUCCESS(Status))
316 {
317 DPRINT1("Volume verification successful; Reissuing write request\n");
318 goto again;
319 }
320 }
321
322 if (!NT_SUCCESS(Status))
323 {
324 DPRINT("IO failed!!! VfatWriteDisk : Error code: %x\n", Status);
325 DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
327 return Status;
328 }
329 DPRINT("Block request succeeded for %p\n", Irp);
330 return STATUS_SUCCESS;
331}
ULONG WriteLength
Definition: CcPinRead_drv.c:40
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4679
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
Definition: wdfusb.h:1921

Referenced by FAT16SetDirtyStatus(), FAT32SetDirtyStatus(), and FAT32UpdateFreeClustersCount().

◆ VfatWriteDiskPartial()

NTSTATUS VfatWriteDiskPartial ( IN PVFAT_IRP_CONTEXT  IrpContext,
IN PLARGE_INTEGER  WriteOffset,
IN ULONG  WriteLength,
IN ULONG  BufferOffset,
IN BOOLEAN  Wait 
)

Definition at line 334 of file blockdev.c.

340{
341 PIRP Irp;
342 PIO_STACK_LOCATION StackPtr;
345
346 DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
347 IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
348
349 Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
350
351again:
352 DPRINT("Building asynchronous FSD Request...\n");
353 Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
354 if (Irp == NULL)
355 {
356 DPRINT("IoAllocateIrp failed\n");
357 return STATUS_UNSUCCESSFUL;
358 }
359
360 Irp->UserIosb = NULL;
361 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
362
363 StackPtr = IoGetNextIrpStackLocation(Irp);
364 StackPtr->MajorFunction = IRP_MJ_WRITE;
365 StackPtr->MinorFunction = 0;
366 StackPtr->Flags = 0;
367 StackPtr->Control = 0;
368 StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
369 StackPtr->FileObject = NULL;
370 StackPtr->CompletionRoutine = NULL;
371 StackPtr->Parameters.Read.Length = WriteLength;
372 StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
373
375 {
376 DPRINT("IoAllocateMdl failed\n");
377 IoFreeIrp(Irp);
378 return STATUS_UNSUCCESSFUL;
379 }
380
381 IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
382
385 IrpContext,
386 TRUE,
387 TRUE,
388 TRUE);
389
390 if (Wait)
391 {
392 KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
393 IrpContext->RefCount = 1;
394 }
395 else
396 {
397 InterlockedIncrement((PLONG)&IrpContext->RefCount);
398 }
399
400 DPRINT("Calling IO Driver...\n");
401 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
402 if (Wait && Status == STATUS_PENDING)
403 {
404 KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
405 Status = IrpContext->Irp->IoStatus.Status;
406 }
407
409 {
411
412 DPRINT1("Media change detected!\n");
413
414 /* Find the device to verify and reset the thread field to empty value again. */
418 FALSE);
419 if (NT_SUCCESS(Status))
420 {
421 DPRINT1("Volume verification successful; Reissuing write request\n");
422 goto again;
423 }
424 }
425
426 return Status;
427}
#define InterlockedIncrement
Definition: armddk.h:53
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: iotypes.h:3314
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion
Definition: blockdev.c:17
#define MmGetMdlVirtualAddress(_Mdl)

Referenced by VfatWriteFileData().

◆ WriteCluster()

NTSTATUS WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue 
)

Definition at line 705 of file fat.c.

709{
711 ULONG OldValue;
712
713 ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
714 Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
715 if (DeviceExt->AvailableClustersValid)
716 {
717 if (OldValue && NewValue == 0)
718 InterlockedIncrement((PLONG)&DeviceExt->AvailableClusters);
719 else if (OldValue == 0 && NewValue)
720 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
721 }
722 ExReleaseResourceLite(&DeviceExt->FatResource);
723 return Status;
724}

Referenced by FATDelEntry(), FATXDelEntry(), GetNextClusterExtend(), and VfatSetAllocationSizeInformation().

Variable Documentation

◆ VfatBuildRequest

DRIVER_DISPATCH VfatBuildRequest

Definition at line 1147 of file vfat.h.

Referenced by DriverEntry().

◆ VfatGlobalData

◆ VfatShutdown

DRIVER_DISPATCH VfatShutdown

Definition at line 1210 of file vfat.h.

Referenced by DriverEntry().