18#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
19 (pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
41 FATOffset = CurrentCluster *
sizeof(
ULONG);
58 if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
59 CurrentCluster = 0xffffffff;
61 if (CurrentCluster == 0)
63 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
66 ASSERT(CurrentCluster != 0);
90 FATOffset = CurrentCluster * 2;
103 if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
104 CurrentCluster = 0xffffffff;
106 if (CurrentCluster == 0)
108 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
111 ASSERT(CurrentCluster != 0);
125 ULONG CurrentCluster,
148 if ((CurrentCluster % 2) == 0)
150 Entry = *CBlock & 0x0fff;
154 Entry = *CBlock >> 4;
188 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
190 StartCluster = DeviceExt->LastAvailableCluster;
192 for (
j = 0;
j < 2;
j++)
194 for (
i = StartCluster;
i < FatLength;)
212 while (Block < BlockEnd &&
i < FatLength)
216 DPRINT(
"Found available cluster 0x%x\n",
i);
217 DeviceExt->LastAvailableCluster = *Cluster =
i;
221 if (DeviceExt->AvailableClustersValid)
233 FatLength = StartCluster;
257 FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
259 StartCluster = DeviceExt->LastAvailableCluster;
267 DPRINT1(
"CcPinRead(Offset %x, Length %u) failed\n", (
ULONG)
Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
272 for (
j = 0;
j < 2;
j++)
274 for (
i = StartCluster;
i < FatLength;
i++)
279 Entry = *CBlock & 0xfff;
283 Entry = *CBlock >> 4;
288 DPRINT(
"Found available cluster 0x%x\n",
i);
289 DeviceExt->LastAvailableCluster = *Cluster =
i;
291 *CBlock = (*CBlock & 0xf000) | 0xfff;
293 *CBlock = (*CBlock & 0xf) | 0xfff0;
296 if (DeviceExt->AvailableClustersValid)
301 FatLength = StartCluster;
327 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
329 StartCluster = DeviceExt->LastAvailableCluster;
331 for (
j = 0;
j < 2;
j++)
333 for (
i = StartCluster;
i < FatLength;)
350 while (Block < BlockEnd &&
i < FatLength)
352 if ((*Block & 0x0fffffff) == 0)
354 DPRINT(
"Found available cluster 0x%x\n",
i);
355 DeviceExt->LastAvailableCluster = *Cluster =
i;
359 if (DeviceExt->AvailableClustersValid)
370 FatLength = StartCluster;
388 ULONG numberofclusters;
404 numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
406 for (
i = 2;
i < numberofclusters;
i++)
411 Entry = *CBlock & 0x0fff;
415 Entry = *CBlock >> 4;
423 DeviceExt->AvailableClusters = ulCount;
424 DeviceExt->AvailableClustersValid =
TRUE;
449 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
451 for (
i = 2;
i < FatLength; )
467 while (Block < BlockEnd &&
i < FatLength)
478 DeviceExt->AvailableClusters = ulCount;
479 DeviceExt->AvailableClustersValid =
TRUE;
504 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
506 for (
i = 2;
i < FatLength; )
523 while (Block < BlockEnd &&
i < FatLength)
525 if ((*Block & 0x0fffffff) == 0)
534 DeviceExt->AvailableClusters = ulCount;
535 DeviceExt->AvailableClustersValid =
TRUE;
547 if (!DeviceExt->AvailableClustersValid)
549 if (DeviceExt->FatInfo.FatType ==
FAT12)
551 else if (DeviceExt->FatInfo.FatType ==
FAT16 || DeviceExt->FatInfo.FatType ==
FATX16)
556 if (Clusters !=
NULL)
558 Clusters->
QuadPart = DeviceExt->AvailableClusters;
572 ULONG ClusterToWrite,
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)
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;
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);
623 ULONG ClusterToWrite,
635 FATOffset = ClusterToWrite * 2;
647 DPRINT(
"Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
650 *OldValue = *Cluster;
651 *Cluster = (
USHORT)NewValue;
663 ULONG ClusterToWrite,
676 FATOffset = (ClusterToWrite * 4);
688 DPRINT(
"Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
691 *OldValue = *Cluster & 0x0fffffff;
692 *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
707 ULONG ClusterToWrite,
714 Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
715 if (DeviceExt->AvailableClustersValid)
717 if (OldValue && NewValue == 0)
719 else if (OldValue == 0 && NewValue)
735 return DeviceExt->FatInfo.dataStart +
736 ((
ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
746 ULONG CurrentCluster,
751 DPRINT(
"GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
752 DeviceExt, CurrentCluster);
754 if (CurrentCluster == 0)
756 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
758 ASSERT(CurrentCluster != 0);
775 ULONG CurrentCluster,
781 DPRINT(
"GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
782 DeviceExt, CurrentCluster);
789 if (CurrentCluster == 0)
791 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
810 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
837 DPRINT(
"GetDirtyStatus(DeviceExt %p)\n", DeviceExt);
840 if (DeviceExt->FatInfo.FatType ==
FAT12)
842 *DirtyStatus =
FALSE;
851 Status = DeviceExt->GetDirtyStatus(DeviceExt, DirtyStatus);
864#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
873 Length = DeviceExt->FatInfo.BytesPerSector;
874#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
913#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
925 *DirtyStatus =
FALSE;
927#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
942#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
951 Length = DeviceExt->FatInfo.BytesPerSector;
952#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
991#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1001 *DirtyStatus =
TRUE;
1003 *DirtyStatus =
FALSE;
1005#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1023 DPRINT(
"SetDirtyStatus(DeviceExt %p, DirtyStatus %d)\n", DeviceExt, DirtyStatus);
1026 if (DeviceExt->FatInfo.FatType ==
FAT12)
1037 Status = DeviceExt->SetDirtyStatus(DeviceExt, DirtyStatus);
1050#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1059 Length = DeviceExt->FatInfo.BytesPerSector;
1060#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1095#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1108 Sector->
Res1 &= ~FAT_DIRTY_BIT;
1115#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1135#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1144 Length = DeviceExt->FatInfo.BytesPerSector;
1145#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1181#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1194 Sector->
Res4 &= ~FAT_DIRTY_BIT;
1201#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1220#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1227 if (!DeviceExt->AvailableClustersValid)
1233 Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector;
1234 Length = DeviceExt->FatInfo.BytesPerSector;
1235#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1271#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1282#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
#define InterlockedIncrement
#define InterlockedDecrement
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
#define NT_SUCCESS(StatCode)
NTSTATUS FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
static NTSTATUS FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
NTSTATUS GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
NTSTATUS FAT12FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
static NTSTATUS FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
NTSTATUS CountAvailableClusters(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER Clusters)
NTSTATUS FAT16SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
NTSTATUS FAT16GetDirtyStatus(PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
NTSTATUS SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
NTSTATUS FAT32GetDirtyStatus(PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
NTSTATUS FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
static NTSTATUS FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
NTSTATUS FAT32UpdateFreeClustersCount(PDEVICE_EXTENSION DeviceExt)
NTSTATUS FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
NTSTATUS FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
NTSTATUS GetNextClusterExtend(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
NTSTATUS FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
ULONGLONG ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster)
NTSTATUS FAT32SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
NTSTATUS FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
NTSTATUS FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
NTSTATUS GetDirtyStatus(PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
NTSTATUS FAT32FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
#define CACHEPAGESIZE(pDeviceExt)
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
#define ExAllocatePoolWithTag(hernya, size, tag)
#define ExAcquireResourceExclusiveLite(res, wait)
#define ExAcquireResourceSharedLite(res, wait)
#define ROUND_DOWN(n, align)
PVFAT_GLOBAL_DATA VfatGlobalData
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
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
#define EXCEPTION_EXECUTE_HANDLER
#define InterlockedCompareExchange
#define ExFreePoolWithTag(_P, _T)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
_In_ ULONG _In_ ULONG Offset
_In_ ULONG _In_ ULONG _In_ ULONG Length
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
VOID NTAPI CcUnpinData(IN PVOID Bcb)
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
BOOLEAN NTAPI CcMapData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *BcbResult, OUT PVOID *Buffer)
#define _SEH2_GetExceptionCode()
#define _SEH2_EXCEPT(...)
#define _SEH2_YIELD(__stmt)
base of all file and directory entries
unsigned short Signature1
unsigned long FSINFOSignature
unsigned long FreeCluster
unsigned long ExtBootSignature2
#define STATUS_INVALID_PARAMETER
#define STATUS_UNSUCCESSFUL
#define STATUS_DISK_CORRUPT_ERROR
#define STATUS_FILE_CORRUPT_ERROR
#define STATUS_INSUFFICIENT_RESOURCES
#define VFAT_BREAK_ON_CORRUPTION
NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize