#include <ntifs.h>
#include <ntdddisk.h>
#include <dos.h>
+#include <pseh/pseh2.h>
+#include <section_attribs.h>
+#ifdef KDBG
+#include <ndk/kdfuncs.h>
+#include <reactos/kdros.h>
+#endif
+
#define USE_ROS_CC_AND_FS
+#define ENABLE_SWAPOUT
+
+/* FIXME: because volume is not cached, we have to perform direct IOs
+ * The day this is fixed, just comment out that line, and check
+ * it still works (and delete old code ;-))
+ */
+#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))
+
#include <pshpack1.h>
struct _BootSector
{
unsigned short Signature1; // 510
};
+#define FAT_DIRTY_BIT 0x01
+
struct _BootSectorFatX
{
unsigned char SysType[4]; // 0
#define LONGNAME_MAX_LENGTH 256 // max length for a long filename
-#define ENTRY_DELETED(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))
-#define ENTRY_VOLUME(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))
-#define ENTRY_END(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))
+#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 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 */
+/* VCB condition state */
+#define VCB_GOOD 0x0010 /* If not set, the VCB is improper for usage */
typedef struct
{
ULONG VolumeID;
+ CHAR VolumeLabel[11];
ULONG FATStart;
ULONG FATCount;
ULONG FATSectors;
ULONG FatType;
ULONG Sectors;
BOOLEAN FixedMedia;
+ ULONG FSInfoSector;
} FATINFO, *PFATINFO;
struct _VFATFCB;
struct _VFAT_DIRENTRY_CONTEXT;
+struct _VFAT_MOVE_CONTEXT;
+struct _VFAT_CLOSE_CONTEXT;
typedef struct _HASHENTRY
{
}
HASHENTRY;
-#define FCB_HASH_TABLE_SIZE 65536
-
typedef struct DEVICE_EXTENSION *PDEVICE_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
+{
+ PIS_DIRECTORY_EMPTY IsDirectoryEmpty;
+ PADD_ENTRY AddEntry;
+ PDEL_ENTRY DelEntry;
+ PGET_NEXT_DIR_ENTRY GetNextDirEntry;
+} VFAT_DISPATCH, *PVFAT_DISPATCH;
+
+#define STATISTICS_SIZE_NO_PAD (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS))
+typedef struct _STATISTICS {
+ FILESYSTEM_STATISTICS Base;
+ FAT_STATISTICS Fat;
+ UCHAR Pad[((STATISTICS_SIZE_NO_PAD + 0x3f) & ~0x3f) - STATISTICS_SIZE_NO_PAD];
+} STATISTICS, *PSTATISTICS;
typedef struct DEVICE_EXTENSION
{
ULONG HashTableSize;
struct _HASHENTRY **FcbHashTable;
+ PDEVICE_OBJECT VolumeDevice;
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT FATFileObject;
FATINFO FatInfo;
BOOLEAN AvailableClustersValid;
ULONG Flags;
struct _VFATFCB *VolumeFcb;
+ struct _VFATFCB *RootFcb;
+ PSTATISTICS Statistics;
/* Pointers to functions for manipulating FAT. */
PGET_NEXT_CLUSTER GetNextCluster;
PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
PWRITE_CLUSTER WriteCluster;
- ULONG CleanShutBitMask;
-
- /* Pointers to functions for manipulating directory entries. */
- PGET_NEXT_DIR_ENTRY GetNextDirEntry;
+ PGET_DIRTY_STATUS GetDirtyStatus;
+ PSET_DIRTY_STATUS SetDirtyStatus;
ULONG BaseDateYear;
/* Notifications */
LIST_ENTRY NotifyList;
PNOTIFY_SYNC NotifySync;
+
+ /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE */
+ ULONG OpenHandleCount;
+
+ /* VPBs for dismount */
+ PVPB IoVPB;
+ PVPB SpareVPB;
+
+ /* Pointers to functions for manipulating directory entries. */
+ VFAT_DISPATCH Dispatch;
} DEVICE_EXTENSION, VCB, *PVCB;
+FORCEINLINE
+BOOLEAN
+VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
+ struct _VFATFCB* Fcb)
+{
+ return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, 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)
+{
+ return DeviceExt->Dispatch.AddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext);
+}
+
+FORCEINLINE
+NTSTATUS
+VfatDelEntry(PDEVICE_EXTENSION DeviceExt,
+ struct _VFATFCB* Fcb,
+ struct _VFAT_MOVE_CONTEXT* MoveContext)
+{
+ return DeviceExt->Dispatch.DelEntry(DeviceExt, Fcb, MoveContext);
+}
+
+FORCEINLINE
+NTSTATUS
+VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt,
+ PVOID *pContext,
+ PVOID *pPage,
+ struct _VFATFCB* pDirFcb,
+ struct _VFAT_DIRENTRY_CONTEXT* DirContext,
+ BOOLEAN First)
+{
+ return DeviceExt->Dispatch.GetNextDirEntry(pContext, pPage, pDirFcb, DirContext, First);
+}
+
+#define VFAT_BREAK_ON_CORRUPTION 1
+
typedef struct
{
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
ULONG Flags;
+ ULONG NumberProcessors;
ERESOURCE VolumeListLock;
LIST_ENTRY VolumeListHead;
NPAGED_LOOKASIDE_LIST FcbLookasideList;
NPAGED_LOOKASIDE_LIST CcbLookasideList;
NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
+ PAGED_LOOKASIDE_LIST CloseContextLookasideList;
FAST_IO_DISPATCH FastIoDispatch;
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
+ FAST_MUTEX CloseMutex;
+ ULONG CloseCount;
+ LIST_ENTRY CloseListHead;
+ BOOLEAN CloseWorkerRunning;
+ PIO_WORKITEM CloseWorkItem;
+ BOOLEAN ShutdownStarted;
} VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
extern PVFAT_GLOBAL_DATA VfatGlobalData;
#define FCB_IS_PAGE_FILE 0x0008
#define FCB_IS_VOLUME 0x0010
#define FCB_IS_DIRTY 0x0020
-#define FCB_IS_FATX_ENTRY 0x0040
+#define FCB_DELAYED_CLOSE 0x0040
+#ifdef KDBG
+#define FCB_CLEANED_UP 0x0080
+#define FCB_CLOSED 0x0100
+#endif
+
+#define NODE_TYPE_FCB ((CSHORT)0x0502)
typedef struct _VFATFCB
{
/* List of FCB's for this volume */
LIST_ENTRY FcbListEntry;
+ /* List of FCB's for the parent */
+ LIST_ENTRY ParentListEntry;
+
/* pointer to the parent fcb */
struct _VFATFCB *parentFcb;
+ /* List for the children */
+ LIST_ENTRY ParentListHead;
+
/* Flags for the fcb */
ULONG Flags;
FILE_LOCK FileLock;
/*
- * Optimalization: caching of last read/write cluster+offset pair. Can't
+ * Optimization: caching of last read/write cluster+offset pair. Can't
* be in VFATCCB because it must be reset everytime the allocated clusters
* change.
*/
FAST_MUTEX LastMutex;
ULONG LastCluster;
ULONG LastOffset;
+
+ struct _VFAT_CLOSE_CONTEXT * CloseContext;
} VFATFCB, *PVFATFCB;
+#define CCB_DELETE_ON_CLOSE 0x0001
+
typedef struct _VFATCCB
{
LARGE_INTEGER CurrentByteOffset;
+ ULONG Flags;
/* for DirectoryControl */
ULONG Entry;
/* for DirectoryControl */
UNICODE_STRING SearchPattern;
} VFATCCB, *PVFATCCB;
-#define TAG_CCB 'BCCV'
-#define TAG_FCB 'BCFV'
-#define TAG_IRP 'PRIV'
-#define TAG_VFAT 'TAFV'
+#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))
}
DOSDATE, *PDOSDATE;
-#define IRPCONTEXT_CANWAIT 0x0001
-#define IRPCONTEXT_PENDINGRETURNED 0x0002
+#define IRPCONTEXT_CANWAIT 0x0001
+#define IRPCONTEXT_COMPLETE 0x0002
+#define IRPCONTEXT_QUEUE 0x0004
+#define IRPCONTEXT_PENDINGRETURNED 0x0008
+#define IRPCONTEXT_DEFERRED_WRITE 0x0010
typedef struct
{
PFILE_OBJECT FileObject;
ULONG RefCount;
KEVENT Event;
+ CCHAR PriorityBoost;
} VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
typedef struct _VFAT_DIRENTRY_CONTEXT
DIR_ENTRY DirEntry;
UNICODE_STRING LongNameU;
UNICODE_STRING ShortNameU;
+ PDEVICE_EXTENSION DeviceExt;
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
+typedef struct _VFAT_MOVE_CONTEXT
+{
+ ULONG FirstCluster;
+ ULONG FileSize;
+ USHORT CreationDate;
+ USHORT CreationTime;
+ BOOLEAN InPlace;
+} VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
+
+typedef struct _VFAT_CLOSE_CONTEXT
+{
+ PDEVICE_EXTENSION Vcb;
+ PVFATFCB Fcb;
+ LIST_ENTRY CloseListEntry;
+} VFAT_CLOSE_CONTEXT, *PVFAT_CLOSE_CONTEXT;
+
+FORCEINLINE
+NTSTATUS
+VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
+{
+ PULONG Flags = &IrpContext->Flags;
+
+ *Flags &= ~IRPCONTEXT_COMPLETE;
+ *Flags |= IRPCONTEXT_QUEUE;
+
+ return STATUS_PENDING;
+}
+
+FORCEINLINE
+BOOLEAN
+vfatFCBIsDirectory(PVFATFCB FCB)
+{
+ return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_DIRECTORY);
+}
+
+FORCEINLINE
+BOOLEAN
+vfatFCBIsReadOnly(PVFATFCB FCB)
+{
+ return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_READONLY);
+}
+
+FORCEINLINE
+BOOLEAN
+vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
+{
+ return BooleanFlagOn(DeviceExt->Flags, VCB_IS_FATX);
+}
+
+FORCEINLINE
+VOID
+vfatReportChange(
+ IN PDEVICE_EXTENSION DeviceExt,
+ IN PVFATFCB Fcb,
+ IN ULONG FilterMatch,
+ IN ULONG Action)
+{
+ FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
+ &(DeviceExt->NotifyList),
+ (PSTRING)&Fcb->PathNameU,
+ Fcb->PathNameU.Length - Fcb->LongNameU.Length,
+ NULL, NULL, FilterMatch, Action, NULL);
+}
+
+#define vfatAddToStat(Vcb, Stat, Inc) \
+{ \
+ PSTATISTICS Stats = &(Vcb)->Statistics[KeGetCurrentProcessorNumber() % VfatGlobalData->NumberProcessors]; \
+ Stats->Stat += Inc; \
+}
/* blockdev.c */
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,
PFAT_DIR_ENTRY pEntry,
PUNICODE_STRING NameU);
-NTSTATUS
-ReadVolumeLabel(
- PDEVICE_EXTENSION DeviceExt,
- PVPB Vpb);
-
/* dir.c */
NTSTATUS
PDEVICE_EXTENSION pDeviceExt,
PDIR_ENTRY pDirEntry);
-BOOLEAN
-VfatIsDirectoryEmpty(
- PVFATFCB Fcb);
-
-NTSTATUS
-FATGetNextDirEntry(
- PVOID *pContext,
- PVOID *pPage,
- IN PVFATFCB pDirFcb,
- IN PVFAT_DIRENTRY_CONTEXT DirContext,
- BOOLEAN First);
-
-NTSTATUS
-FATXGetNextDirEntry(
- PVOID *pContext,
- PVOID *pPage,
- IN PVFATFCB pDirFcb,
- IN PVFAT_DIRENTRY_CONTEXT DirContext,
- BOOLEAN First);
-
/* dirwr.c */
NTSTATUS
-VfatAddEntry(
- PDEVICE_EXTENSION DeviceExt,
- PUNICODE_STRING PathNameU,
- PVFATFCB* Fcb,
- PVFATFCB ParentFcb,
- ULONG RequestedOptions,
- UCHAR ReqAttr);
+vfatFCBInitializeCacheFromVolume(
+ PVCB vcb,
+ PVFATFCB fcb);
NTSTATUS
VfatUpdateEntry(
+ IN PDEVICE_EXTENSION DeviceExt,
PVFATFCB pFcb);
-NTSTATUS
-VfatDelEntry(
- PDEVICE_EXTENSION,
- PVFATFCB);
-
BOOLEAN
vfatFindDirSpace(
PDEVICE_EXTENSION DeviceExt,
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);
+
/* ea.h */
NTSTATUS
/* fastio.c */
+INIT_FUNCTION
VOID
VfatInitFastIoRoutines(
PFAST_IO_DISPATCH FastIoDispatch);
VfatReleaseFromLazyWrite(
IN PVOID Context);
-BOOLEAN
-NTAPI
-VfatAcquireForReadAhead(
- IN PVOID Context,
- IN BOOLEAN Wait);
-
-VOID
-NTAPI
-VfatReleaseFromReadAhead(
- IN PVOID Context);
-
/* fat.c */
NTSTATUS
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);
+
/* fcb.c */
PVFATFCB
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);
PVFATCCB pCcb);
VOID
+#ifndef KDBG
vfatGrabFCB(
+#else
+_vfatGrabFCB(
+#endif
PDEVICE_EXTENSION pVCB,
- PVFATFCB pFCB);
+ PVFATFCB pFCB
+#ifdef KDBG
+ ,
+ PCSTR File,
+ ULONG Line,
+ PCSTR Func
+#endif
+ );
VOID
+#ifndef KDBG
vfatReleaseFCB(
+#else
+_vfatReleaseFCB(
+#endif
PDEVICE_EXTENSION pVCB,
- PVFATFCB pFCB);
-
-VOID
-vfatAddFCBToTable(
- PDEVICE_EXTENSION pVCB,
- PVFATFCB pFCB);
+ PVFATFCB pFCB
+#ifdef KDBG
+ ,
+ PCSTR File,
+ ULONG Line,
+ PCSTR Func
+#endif
+ );
+
+#ifdef KDBG
+#define vfatGrabFCB(v, f) _vfatGrabFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
+#define vfatReleaseFCB(v, f) _vfatReleaseFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
+#endif
PVFATFCB
vfatGrabFCBFromTable(
/* finfo.c */
+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);
/* iface.c */
+INIT_FUNCTION
NTSTATUS
NTAPI
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
+#ifdef KDBG
+/* kdbg.c */
+KDBG_CLI_ROUTINE vfatKdbgHandler;
+#endif
/* misc.c */
-NTSTATUS
-VfatQueueRequest(
- PVFAT_IRP_CONTEXT IrpContext);
-
-PVFAT_IRP_CONTEXT
-VfatAllocateIrpContext(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-
-VOID
-VfatFreeIrpContext(
- PVFAT_IRP_CONTEXT IrpContext);
-
DRIVER_DISPATCH
VfatBuildRequest;
PVOID
VfatGetUserBuffer(
- IN PIRP);
+ IN PIRP Irp,
+ IN BOOLEAN Paging);
NTSTATUS
VfatLockUserBuffer(
- IN PIRP,
- IN ULONG,
- IN LOCK_OPERATION);
+ IN PIRP Irp,
+ IN ULONG Length,
+ IN LOCK_OPERATION Operation);
+
+BOOLEAN
+VfatCheckForDismount(
+ IN PDEVICE_EXTENSION DeviceExt,
+ IN BOOLEAN Create);
+
+VOID
+vfatReportChange(
+ IN PDEVICE_EXTENSION DeviceExt,
+ IN PVFATFCB Fcb,
+ IN ULONG FilterMatch,
+ IN ULONG Action);
+
+VOID
+NTAPI
+VfatHandleDeferredWrite(
+ IN PVOID IrpContext,
+ IN PVOID Unused);
/* pnp.c */
vfatIsLongIllegal(
WCHAR c);
-BOOLEAN
-wstrcmpjoki(
- PWSTR s1,
- PWSTR s2);
-
/* volume.c */
NTSTATUS