20 #define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \ 21 (pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE) 43 FATOffset = CurrentCluster *
sizeof(
ULONG);
60 if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
61 CurrentCluster = 0xffffffff;
63 if (CurrentCluster == 0)
65 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
68 ASSERT(CurrentCluster != 0);
92 FATOffset = CurrentCluster * 2;
105 if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
106 CurrentCluster = 0xffffffff;
108 if (CurrentCluster == 0)
110 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
113 ASSERT(CurrentCluster != 0);
127 ULONG CurrentCluster,
150 if ((CurrentCluster % 2) == 0)
152 Entry = *CBlock & 0x0fff;
156 Entry = *CBlock >> 4;
190 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
192 StartCluster = DeviceExt->LastAvailableCluster;
194 for (
j = 0;
j < 2;
j++)
196 for (
i = StartCluster;
i < FatLength;)
214 while (Block < BlockEnd &&
i < FatLength)
218 DPRINT(
"Found available cluster 0x%x\n",
i);
219 DeviceExt->LastAvailableCluster = *Cluster =
i;
223 if (DeviceExt->AvailableClustersValid)
235 FatLength = StartCluster;
259 FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
261 StartCluster = DeviceExt->LastAvailableCluster;
269 DPRINT1(
"CcPinRead(Offset %x, Length %u) failed\n", (
ULONG)
Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
274 for (
j = 0;
j < 2;
j++)
276 for (
i = StartCluster;
i < FatLength;
i++)
281 Entry = *CBlock & 0xfff;
285 Entry = *CBlock >> 4;
290 DPRINT(
"Found available cluster 0x%x\n",
i);
291 DeviceExt->LastAvailableCluster = *Cluster =
i;
293 *CBlock = (*CBlock & 0xf000) | 0xfff;
295 *CBlock = (*CBlock & 0xf) | 0xfff0;
298 if (DeviceExt->AvailableClustersValid)
303 FatLength = StartCluster;
329 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
331 StartCluster = DeviceExt->LastAvailableCluster;
333 for (
j = 0;
j < 2;
j++)
335 for (
i = StartCluster;
i < FatLength;)
352 while (Block < BlockEnd &&
i < FatLength)
354 if ((*Block & 0x0fffffff) == 0)
356 DPRINT(
"Found available cluster 0x%x\n",
i);
357 DeviceExt->LastAvailableCluster = *Cluster =
i;
361 if (DeviceExt->AvailableClustersValid)
372 FatLength = StartCluster;
390 ULONG numberofclusters;
406 numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
408 for (
i = 2;
i < numberofclusters;
i++)
413 Entry = *CBlock & 0x0fff;
417 Entry = *CBlock >> 4;
425 DeviceExt->AvailableClusters = ulCount;
426 DeviceExt->AvailableClustersValid =
TRUE;
451 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
453 for (
i = 2;
i < FatLength; )
469 while (Block < BlockEnd &&
i < FatLength)
480 DeviceExt->AvailableClusters = ulCount;
481 DeviceExt->AvailableClustersValid =
TRUE;
506 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
508 for (
i = 2;
i < FatLength; )
525 while (Block < BlockEnd &&
i < FatLength)
527 if ((*Block & 0x0fffffff) == 0)
536 DeviceExt->AvailableClusters = ulCount;
537 DeviceExt->AvailableClustersValid =
TRUE;
549 if (!DeviceExt->AvailableClustersValid)
551 if (DeviceExt->FatInfo.FatType ==
FAT12)
553 else if (DeviceExt->FatInfo.FatType ==
FAT16 || DeviceExt->FatInfo.FatType ==
FATX16)
558 if (Clusters !=
NULL)
560 Clusters->
QuadPart = DeviceExt->AvailableClusters;
574 ULONG ClusterToWrite,
596 FATOffset = (ClusterToWrite * 12) / 8;
597 DPRINT(
"Writing 0x%x for 0x%x at 0x%x\n",
598 NewValue, ClusterToWrite, FATOffset);
599 if ((ClusterToWrite % 2) == 0)
601 *OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
602 CBlock[FATOffset] = (
UCHAR)NewValue;
603 CBlock[FATOffset + 1] &= 0xf0;
604 CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
608 *OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
609 CBlock[FATOffset] &= 0x0f;
610 CBlock[FATOffset] |= (NewValue & 0xf) << 4;
611 CBlock[FATOffset + 1] = (
UCHAR)(NewValue >> 4);
625 ULONG ClusterToWrite,
637 FATOffset = ClusterToWrite * 2;
649 DPRINT(
"Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
652 *OldValue = *Cluster;
653 *Cluster = (
USHORT)NewValue;
665 ULONG ClusterToWrite,
678 FATOffset = (ClusterToWrite * 4);
690 DPRINT(
"Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
693 *OldValue = *Cluster & 0x0fffffff;
694 *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
709 ULONG ClusterToWrite,
716 Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
717 if (DeviceExt->AvailableClustersValid)
719 if (OldValue && NewValue == 0)
721 else if (OldValue == 0 && NewValue)
737 return DeviceExt->FatInfo.dataStart +
738 ((
ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
748 ULONG CurrentCluster,
753 DPRINT(
"GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
754 DeviceExt, CurrentCluster);
756 if (CurrentCluster == 0)
758 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
760 ASSERT(CurrentCluster != 0);
777 ULONG CurrentCluster,
783 DPRINT(
"GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
784 DeviceExt, CurrentCluster);
791 if (CurrentCluster == 0)
793 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
812 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
839 DPRINT(
"GetDirtyStatus(DeviceExt %p)\n", DeviceExt);
842 if (DeviceExt->FatInfo.FatType ==
FAT12)
844 *DirtyStatus =
FALSE;
853 Status = DeviceExt->GetDirtyStatus(DeviceExt, DirtyStatus);
866 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 875 Length = DeviceExt->FatInfo.BytesPerSector;
876 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 911 if (Sector->Signatur1 != 0xaa55)
915 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 927 *DirtyStatus =
FALSE;
929 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 944 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 953 Length = DeviceExt->FatInfo.BytesPerSector;
954 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 989 if (Sector->Signature1 != 0xaa55)
993 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1003 *DirtyStatus =
TRUE;
1005 *DirtyStatus =
FALSE;
1007 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1025 DPRINT(
"SetDirtyStatus(DeviceExt %p, DirtyStatus %d)\n", DeviceExt, DirtyStatus);
1028 if (DeviceExt->FatInfo.FatType ==
FAT12)
1039 Status = DeviceExt->SetDirtyStatus(DeviceExt, DirtyStatus);
1052 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1061 Length = DeviceExt->FatInfo.BytesPerSector;
1062 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1095 if (Sector->Signatur1 != 0xaa55)
1097 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1117 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1137 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1146 Length = DeviceExt->FatInfo.BytesPerSector;
1147 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1180 if (Sector->Signature1 != 0xaa55)
1183 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1203 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1222 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1229 if (!DeviceExt->AvailableClustersValid)
1235 Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector;
1236 Length = DeviceExt->FatInfo.BytesPerSector;
1237 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1268 if (Sector->ExtBootSignature2 != 0x41615252 ||
1269 Sector->FSINFOSignature != 0x61417272 ||
1270 Sector->Signatur2 != 0xaa550000)
1273 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1284 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT NTSTATUS FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
NTSTATUS CountAvailableClusters(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER Clusters)
#define STATUS_INSUFFICIENT_RESOURCES
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define STATUS_INVALID_PARAMETER
NTSTATUS FAT16GetDirtyStatus(PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
NTSTATUS FAT32UpdateFreeClustersCount(PDEVICE_EXTENSION DeviceExt)
NTSTATUS FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
VOID NTAPI CcUnpinData(IN PVOID Bcb)
#define InterlockedCompareExchange
NTSTATUS FAT32SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
NTSTATUS FAT32FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
#define STATUS_FILE_CORRUPT_ERROR
NTSTATUS GetDirtyStatus(PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize
static NTSTATUS FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
NTSTATUS FAT12FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
NTSTATUS FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
NTSTATUS FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
NTSTATUS FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
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
BOOLEAN NTAPI CcMapData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *BcbResult, OUT PVOID *Buffer)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
NTSTATUS GetNextClusterExtend(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
#define NT_SUCCESS(StatCode)
#define EXCEPTION_EXECUTE_HANDLER
static NTSTATUS FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
static NTSTATUS FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
#define STATUS_UNSUCCESSFUL
#define ExAllocatePoolWithTag(hernya, size, tag)
#define InterlockedDecrement
_In_ ULONG _In_ ULONG Offset
#define VFAT_BREAK_ON_CORRUPTION
PVFAT_GLOBAL_DATA VfatGlobalData
#define ROUND_DOWN(n, align)
NTSTATUS FAT32GetDirtyStatus(PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
NTSTATUS GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
#define InterlockedIncrement
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
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
#define CACHEPAGESIZE(pDeviceExt)
NTSTATUS FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
struct tagContext Context
#define STATUS_DISK_CORRUPT_ERROR
NTSTATUS FAT16SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
NTSTATUS FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
#define _SEH2_EXCEPT(...)
#define _SEH2_GetExceptionCode()
#define _SEH2_YIELD(__stmt)
NTSTATUS SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
#define ExFreePoolWithTag(_P, _T)
ULONGLONG ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster)
base of all file and directory entries