20 #define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \ 21 (pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE) 43 FATOffset = CurrentCluster *
sizeof(
ULONG);
56 if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
57 CurrentCluster = 0xffffffff;
59 if (CurrentCluster == 0)
61 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
64 ASSERT(CurrentCluster != 0);
88 FATOffset = CurrentCluster * 2;
101 if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
102 CurrentCluster = 0xffffffff;
104 if (CurrentCluster == 0)
106 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
109 ASSERT(CurrentCluster != 0);
123 ULONG CurrentCluster,
146 if ((CurrentCluster % 2) == 0)
148 Entry = *CBlock & 0x0fff;
152 Entry = *CBlock >> 4;
186 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
188 StartCluster = DeviceExt->LastAvailableCluster;
190 for (
j = 0;
j < 2;
j++)
192 for (
i = StartCluster;
i < FatLength;)
210 while (Block < BlockEnd &&
i < FatLength)
214 DPRINT(
"Found available cluster 0x%x\n",
i);
215 DeviceExt->LastAvailableCluster = *Cluster =
i;
219 if (DeviceExt->AvailableClustersValid)
231 FatLength = StartCluster;
255 FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
257 StartCluster = DeviceExt->LastAvailableCluster;
265 DPRINT1(
"CcPinRead(Offset %x, Length %u) failed\n", (
ULONG)
Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
270 for (
j = 0;
j < 2;
j++)
272 for (
i = StartCluster;
i < FatLength;
i++)
277 Entry = *CBlock & 0xfff;
281 Entry = *CBlock >> 4;
286 DPRINT(
"Found available cluster 0x%x\n",
i);
287 DeviceExt->LastAvailableCluster = *Cluster =
i;
289 *CBlock = (*CBlock & 0xf000) | 0xfff;
291 *CBlock = (*CBlock & 0xf) | 0xfff0;
294 if (DeviceExt->AvailableClustersValid)
299 FatLength = StartCluster;
325 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
327 StartCluster = DeviceExt->LastAvailableCluster;
329 for (
j = 0;
j < 2;
j++)
331 for (
i = StartCluster;
i < FatLength;)
348 while (Block < BlockEnd &&
i < FatLength)
350 if ((*Block & 0x0fffffff) == 0)
352 DPRINT(
"Found available cluster 0x%x\n",
i);
353 DeviceExt->LastAvailableCluster = *Cluster =
i;
357 if (DeviceExt->AvailableClustersValid)
368 FatLength = StartCluster;
386 ULONG numberofclusters;
402 numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
404 for (
i = 2;
i < numberofclusters;
i++)
409 Entry = *CBlock & 0x0fff;
413 Entry = *CBlock >> 4;
421 DeviceExt->AvailableClusters = ulCount;
422 DeviceExt->AvailableClustersValid =
TRUE;
447 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
449 for (
i = 2;
i < FatLength; )
465 while (Block < BlockEnd &&
i < FatLength)
476 DeviceExt->AvailableClusters = ulCount;
477 DeviceExt->AvailableClustersValid =
TRUE;
502 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
504 for (
i = 2;
i < FatLength; )
521 while (Block < BlockEnd &&
i < FatLength)
523 if ((*Block & 0x0fffffff) == 0)
532 DeviceExt->AvailableClusters = ulCount;
533 DeviceExt->AvailableClustersValid =
TRUE;
545 if (!DeviceExt->AvailableClustersValid)
547 if (DeviceExt->FatInfo.FatType ==
FAT12)
549 else if (DeviceExt->FatInfo.FatType ==
FAT16 || DeviceExt->FatInfo.FatType ==
FATX16)
554 if (Clusters !=
NULL)
556 Clusters->
QuadPart = DeviceExt->AvailableClusters;
570 ULONG ClusterToWrite,
592 FATOffset = (ClusterToWrite * 12) / 8;
593 DPRINT(
"Writing 0x%x for 0x%x at 0x%x\n",
594 NewValue, ClusterToWrite, FATOffset);
595 if ((ClusterToWrite % 2) == 0)
597 *OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
598 CBlock[FATOffset] = (
UCHAR)NewValue;
599 CBlock[FATOffset + 1] &= 0xf0;
600 CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
604 *OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
605 CBlock[FATOffset] &= 0x0f;
606 CBlock[FATOffset] |= (NewValue & 0xf) << 4;
607 CBlock[FATOffset + 1] = (
UCHAR)(NewValue >> 4);
621 ULONG ClusterToWrite,
633 FATOffset = ClusterToWrite * 2;
645 DPRINT(
"Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
648 *OldValue = *Cluster;
649 *Cluster = (
USHORT)NewValue;
661 ULONG ClusterToWrite,
674 FATOffset = (ClusterToWrite * 4);
686 DPRINT(
"Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
689 *OldValue = *Cluster & 0x0fffffff;
690 *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
705 ULONG ClusterToWrite,
712 Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
713 if (DeviceExt->AvailableClustersValid)
715 if (OldValue && NewValue == 0)
717 else if (OldValue == 0 && NewValue)
733 return DeviceExt->FatInfo.dataStart +
734 ((
ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
744 ULONG CurrentCluster,
749 DPRINT(
"GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
750 DeviceExt, CurrentCluster);
752 if (CurrentCluster == 0)
754 DPRINT1(
"WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
756 ASSERT(CurrentCluster != 0);
773 ULONG CurrentCluster,
779 DPRINT(
"GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
780 DeviceExt, CurrentCluster);
787 if (CurrentCluster == 0)
789 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
808 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
835 DPRINT(
"GetDirtyStatus(DeviceExt %p)\n", DeviceExt);
838 if (DeviceExt->FatInfo.FatType ==
FAT12)
840 *DirtyStatus =
FALSE;
849 Status = DeviceExt->GetDirtyStatus(DeviceExt, DirtyStatus);
862 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 871 Length = DeviceExt->FatInfo.BytesPerSector;
872 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 907 if (Sector->Signatur1 != 0xaa55)
911 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 923 *DirtyStatus =
FALSE;
925 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 940 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 949 Length = DeviceExt->FatInfo.BytesPerSector;
950 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 985 if (Sector->Signature1 != 0xaa55)
989 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1001 *DirtyStatus =
FALSE;
1003 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1021 DPRINT(
"SetDirtyStatus(DeviceExt %p, DirtyStatus %d)\n", DeviceExt, DirtyStatus);
1024 if (DeviceExt->FatInfo.FatType ==
FAT12)
1035 Status = DeviceExt->SetDirtyStatus(DeviceExt, DirtyStatus);
1048 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1057 Length = DeviceExt->FatInfo.BytesPerSector;
1058 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1091 if (Sector->Signatur1 != 0xaa55)
1093 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1113 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1133 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1142 Length = DeviceExt->FatInfo.BytesPerSector;
1143 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1176 if (Sector->Signature1 != 0xaa55)
1179 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1199 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1218 #ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1225 if (!DeviceExt->AvailableClustersValid)
1231 Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector;
1232 Length = DeviceExt->FatInfo.BytesPerSector;
1233 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1264 if (Sector->ExtBootSignature2 != 0x41615252 ||
1265 Sector->FSINFOSignature != 0x61417272 ||
1266 Sector->Signatur2 != 0xaa550000)
1269 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT 1280 #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
#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)
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
#define STATUS_FILE_CORRUPT_ERROR
NTSTATUS GetDirtyStatus(PDEVICE_EXTENSION DeviceExt, PBOOLEAN DirtyStatus)
_In_ ULONG _In_ ULONG Offset
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize
static NTSTATUS FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
#define EXCEPTION_EXECUTE_HANDLER
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 _SEH2_YIELD(STMT_)
#define NT_SUCCESS(StatCode)
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)
_In_ ULONG _In_ ULONG _In_ ULONG Length
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)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
#define InterlockedDecrement
#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
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
#define CACHEPAGESIZE(pDeviceExt)
NTSTATUS FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
#define STATUS_DISK_CORRUPT_ERROR
struct tagContext Context
NTSTATUS FAT16SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
NTSTATUS FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
#define _SEH2_EXCEPT(...)
#define ExFreePoolWithTag(_P, _T)
#define _SEH2_GetExceptionCode()
NTSTATUS SetDirtyStatus(PDEVICE_EXTENSION DeviceExt, BOOLEAN DirtyStatus)
ULONGLONG ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster)
base of all file and directory entries