31 #define OVERFLOW_READ_THRESHHOLD 0xE00 46 if (FirstCluster == 1)
48 (*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
56 return GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster);
76 if (FirstCluster == 0)
78 DbgPrint(
"OffsetToCluster is called with FirstCluster = 0!\n");
82 if (FirstCluster == 1)
85 *Cluster = DeviceExt->FatInfo.rootStart +
FileOffset 86 / (DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.SectorsPerCluster;
91 CurrentCluster = FirstCluster;
94 for (
i = 0;
i <
FileOffset / DeviceExt->FatInfo.BytesPerCluster;
i++)
100 *Cluster = CurrentCluster;
104 for (
i = 0;
i <
FileOffset / DeviceExt->FatInfo.BytesPerCluster;
i++)
110 *Cluster = CurrentCluster;
127 ULONG CurrentCluster;
137 ULONG BytesPerSector;
138 ULONG BytesPerCluster;
146 ASSERT(DeviceExt->FatInfo.BytesPerCluster);
150 DPRINT(
"VfatReadFileData(DeviceExt %p, FileObject %p, " 151 "Length %u, ReadOffset 0x%I64x)\n", DeviceExt,
157 BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
158 BytesPerCluster = DeviceExt->FatInfo.BytesPerCluster;
167 ReadOffset.QuadPart += DeviceExt->FatInfo.FATStart * BytesPerSector;
200 if (FirstCluster == 1)
203 if (
ReadOffset.u.LowPart +
Length > DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector)
205 Length = DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector -
ReadOffset.u.LowPart;
207 ReadOffset.u.LowPart += DeviceExt->FatInfo.rootStart * BytesPerSector;
219 LastCluster =
Fcb->LastCluster;
220 LastOffset =
Fcb->LastOffset;
224 if (LastCluster > 0 &&
ReadOffset.u.LowPart >= LastOffset)
229 &CurrentCluster,
FALSE);
230 #ifdef DEBUG_VERIFY_OFFSET_CACHING 233 ULONG CorrectCluster;
236 &CorrectCluster,
FALSE);
237 if (CorrectCluster != CurrentCluster)
246 &CurrentCluster,
FALSE);
255 Fcb->LastCluster = CurrentCluster;
262 while (
Length > 0 && CurrentCluster != 0xffffffff)
264 StartCluster = CurrentCluster;
280 if (
Length - BytesDone > BytesPerCluster)
282 BytesDone += BytesPerCluster;
292 DPRINT(
"start %08x, next %08x, count %u\n",
293 StartCluster, CurrentCluster, ClusterCount);
296 Fcb->LastCluster = StartCluster + (ClusterCount - 1);
306 *LengthRead += BytesDone;
342 ULONG CurrentCluster;
348 ULONG BytesPerSector;
349 ULONG BytesPerCluster;
359 ASSERT(DeviceExt->FatInfo.BytesPerCluster);
364 BytesPerCluster = DeviceExt->FatInfo.BytesPerCluster;
365 BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
367 DPRINT(
"VfatWriteFileData(DeviceExt %p, FileObject %p, " 368 "Length %u, WriteOffset 0x%I64x), '%wZ'\n", DeviceExt,
390 WriteOffset.u.LowPart += DeviceExt->FatInfo.FATStart * BytesPerSector;
421 if (FirstCluster == 1)
425 WriteOffset.u.LowPart += DeviceExt->FatInfo.rootStart * BytesPerSector;
432 LastCluster =
Fcb->LastCluster;
433 LastOffset =
Fcb->LastOffset;
439 if (LastCluster > 0 &&
WriteOffset.u.LowPart >= LastOffset)
444 &CurrentCluster,
FALSE);
445 #ifdef DEBUG_VERIFY_OFFSET_CACHING 448 ULONG CorrectCluster;
451 &CorrectCluster,
FALSE);
452 if (CorrectCluster != CurrentCluster)
461 &CurrentCluster,
FALSE);
470 Fcb->LastCluster = CurrentCluster;
477 while (
Length > 0 && CurrentCluster != 0xffffffff)
479 StartCluster = CurrentCluster;
495 if (
Length - BytesDone > BytesPerCluster)
497 BytesDone += BytesPerCluster;
507 DPRINT(
"start %08x, next %08x, count %u\n",
508 StartCluster, CurrentCluster, ClusterCount);
511 Fcb->LastCluster = StartCluster + (ClusterCount - 1);
521 BufferOffset += BytesDone;
554 ULONG BytesPerSector;
557 BOOLEAN PagingIo, CanWait, IsVolume, NoCache;
567 BytesPerSector = IrpContext->
DeviceExt->FatInfo.BytesPerSector;
580 if (!PagingIo && !NoCache && !IsVolume)
677 DPRINT1(
"Performing posted read\n");
718 ULONG BytesPerSector;
719 BOOLEAN PagingIo, CanWait, IsVolume, NoCache;
723 DPRINT(
"VfatRead(IrpContext %p)\n", IrpContext);
734 DPRINT(
"VfatRead is called with the main device object.\n");
752 DPRINT(
"Read from page file, disk offset %I64x\n", IrpContext->
Stack->
Parameters.Read.ByteOffset.QuadPart);
761 BytesPerSector = IrpContext->
DeviceExt->FatInfo.BytesPerSector;
792 if (NoCache || PagingIo || IsVolume)
794 if (
ByteOffset.u.LowPart % BytesPerSector != 0 ||
Length % BytesPerSector != 0)
863 IrpContext->
FileObject->CurrentByteOffset.QuadPart =
886 ULONG BytesPerSector;
887 BOOLEAN PagingIo, CanWait, IsVolume, IsFAT, NoCache;
891 DPRINT(
"VfatWrite(IrpContext %p)\n", IrpContext);
902 DPRINT(
"VfatWrite is called with the main device object.\n");
921 DPRINT(
"Write to page file, disk offset %I64x\n", IrpContext->
Stack->
Parameters.Write.ByteOffset.QuadPart);
942 BytesPerSector = IrpContext->
DeviceExt->FatInfo.BytesPerSector;
950 if (IsFAT || IsVolume ||
961 if (PagingIo || NoCache || IsVolume)
963 if (
ByteOffset.u.LowPart % BytesPerSector != 0 ||
Length % BytesPerSector != 0)
1006 DPRINT1(
"Deferring write for Irp %p, context %p!\n", IrpContext->
Irp, IrpContext);
1009 *pIrpContext =
NULL;
1056 if (!CanWait && !IsVolume)
1067 if (!IsFAT && !IsVolume && !PagingIo &&
1090 if (!NoCache && !PagingIo && !IsVolume)
1168 if (!PagingIo && !IsFAT && !IsVolume)
1180 &SystemTime, &
Fcb->entry.FatX.UpdateDate,
1181 &
Fcb->entry.FatX.UpdateTime);
1182 Fcb->entry.FatX.AccessDate =
Fcb->entry.FatX.UpdateDate;
1183 Fcb->entry.FatX.AccessTime =
Fcb->entry.FatX.UpdateTime;
1188 &SystemTime, &
Fcb->entry.Fat.UpdateDate,
1189 &
Fcb->entry.Fat.UpdateTime);
1190 Fcb->entry.Fat.AccessDate =
Fcb->entry.Fat.UpdateDate;
1223 IrpContext->
FileObject->CurrentByteOffset.QuadPart =
#define KeQuerySystemTime(t)
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define IRPCONTEXT_DEFERRED_WRITE
#define ROUND_UP(n, align)
#define IRPCONTEXT_COMPLETE
PDEVICE_EXTENSION DeviceExt
IN BOOLEAN OUT PSTR Buffer
ULONG vfatDirEntryGetFirstCluster(PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
#define STATUS_INVALID_PARAMETER
#define BooleanFlagOn(F, SF)
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
VOID NTAPI FsRtlPostPagingFileStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
#define STATUS_INVALID_DEVICE_REQUEST
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define vfatAddToStat(Vcb, Stat, Inc)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
static NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext, ULONG Length, LARGE_INTEGER WriteOffset)
VOID NTAPI VfatStackOverflowRead(PVOID Context, IN PKEVENT Event)
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
#define STATUS_END_OF_FILE
#define FO_SYNCHRONOUS_IO
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
#define ROUND_UP_64(n, align)
#define IO_DISK_INCREMENT
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
VOID VfatPostRead(PVFAT_IRP_CONTEXT IrpContext, PERESOURCE Lock, BOOLEAN PagingIo)
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET ReadOffset
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
#define FILE_ACTION_MODIFIED
#define STATUS_INVALID_USER_BUFFER
_In_ PVOID _In_ ULONG Event
NTSTATUS VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN ULONG BufferOffset, IN BOOLEAN Wait)
#define EXCEPTION_EXECUTE_HANDLER
#define OVERFLOW_READ_THRESHHOLD
#define IRPCONTEXT_CANWAIT
PVOID VfatGetUserBuffer(IN PIRP Irp, IN BOOLEAN Paging)
#define FsRtlAreThereCurrentFileLocks(FL)
struct _LARGE_INTEGER::@2284 u
FSRTL_COMMON_FCB_HEADER RFCB
#define FILE_WRITE_TO_END_OF_FILE
static NTSTATUS VfatReadFileData(PVFAT_IRP_CONTEXT IrpContext, ULONG Length, LARGE_INTEGER ReadOffset, PULONG LengthRead)
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
PDEVICE_OBJECT DeviceObject
NTSTATUS GetNextClusterExtend(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
#define NT_SUCCESS(StatCode)
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
#define STATUS_UNSUCCESSFUL
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
#define InterlockedDecrement
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
NTSTATUS VfatCommonRead(PVFAT_IRP_CONTEXT IrpContext)
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
PVFAT_GLOBAL_DATA VfatGlobalData
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks
#define ROUND_DOWN(n, align)
NTSTATUS GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
#define KeInitializeEvent(pEvt, foo, foo2)
FORCEINLINE VOID vfatReportChange(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
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
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
NTSTATUS VfatRead(PVFAT_IRP_CONTEXT IrpContext)
_In_ PFCB _In_ LONGLONG FileOffset
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
PDEVICE_OBJECT DeviceObject
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
#define IoSkipCurrentIrpStackLocation(Irp)
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
#define STATUS_FILE_LOCK_CONFLICT
struct tagContext Context
VOID NTAPI VfatHandleDeferredWrite(IN PVOID IrpContext, IN PVOID Unused)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
ERESOURCE PagingIoResource
#define _SEH2_EXCEPT(...)
#define _SEH2_GetExceptionCode()
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
NTSTATUS VfatReadDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, ULONG BufferOffset, IN BOOLEAN Wait)
NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
NTSTATUS VfatWrite(PVFAT_IRP_CONTEXT *pIrpContext)
ULONGLONG ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster)
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)
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
NTSTATUS OffsetToCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, BOOLEAN Extend)