ReactOS 0.4.15-dev-7924-g5949c20
fat.c File Reference
#include "vfat.h"
#include <debug.h>
Include dependency graph for fat.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define CACHEPAGESIZE(pDeviceExt)
 

Functions

NTSTATUS FAT32GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS FAT16GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS FAT12GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS FAT16FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
 
NTSTATUS FAT12FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
 
NTSTATUS FAT32FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
 
static NTSTATUS FAT12CountAvailableClusters (PDEVICE_EXTENSION DeviceExt)
 
static NTSTATUS FAT16CountAvailableClusters (PDEVICE_EXTENSION DeviceExt)
 
static NTSTATUS FAT32CountAvailableClusters (PDEVICE_EXTENSION DeviceExt)
 
NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER Clusters)
 
NTSTATUS FAT12WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
 
NTSTATUS FAT16WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
 
NTSTATUS FAT32WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue)
 
NTSTATUS WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
 
ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt, ULONG Cluster)
 
NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
NTSTATUS GetNextClusterExtend (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
 
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)
 

Macro Definition Documentation

◆ CACHEPAGESIZE

#define CACHEPAGESIZE (   pDeviceExt)
Value:
((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49

Definition at line 18 of file fat.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file fat.c.

Function Documentation

◆ ClusterToSector()

ULONGLONG ClusterToSector ( PDEVICE_EXTENSION  DeviceExt,
ULONG  Cluster 
)

Definition at line 731 of file fat.c.

734{
735 return DeviceExt->FatInfo.dataStart +
736 ((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
737
738}
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by VfatReadFileData(), and VfatWriteFileData().

◆ CountAvailableClusters()

NTSTATUS CountAvailableClusters ( PDEVICE_EXTENSION  DeviceExt,
PLARGE_INTEGER  Clusters 
)

Definition at line 541 of file fat.c.

544{
546 ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
547 if (!DeviceExt->AvailableClustersValid)
548 {
549 if (DeviceExt->FatInfo.FatType == FAT12)
551 else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
553 else
555 }
556 if (Clusters != NULL)
557 {
558 Clusters->QuadPart = DeviceExt->AvailableClusters;
559 }
560 ExReleaseResourceLite (&DeviceExt->FatResource);
561
562 return Status;
563}
LONG NTSTATUS
Definition: precomp.h:26
#define FATX16
Definition: fat.h:170
#define FAT12
Definition: fat.h:167
#define FAT16
Definition: fat.h:168
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
static NTSTATUS FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:490
static NTSTATUS FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:381
static NTSTATUS FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:435
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
Status
Definition: gdiplustypes.h:25
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_SUCCESS
Definition: shellext.h:65
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by FsdGetFsFullSizeInformation(), FsdGetFsSizeInformation(), and VfatMount().

◆ FAT12CountAvailableClusters()

static NTSTATUS FAT12CountAvailableClusters ( PDEVICE_EXTENSION  DeviceExt)
static

Definition at line 381 of file fat.c.

383{
384 ULONG Entry;
386 ULONG ulCount = 0;
387 ULONG i;
388 ULONG numberofclusters;
391 PUSHORT CBlock;
392
393 Offset.QuadPart = 0;
395 {
396 CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, MAP_WAIT, &Context, &BaseAddress);
397 }
399 {
401 }
402 _SEH2_END;
403
404 numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
405
406 for (i = 2; i < numberofclusters; i++)
407 {
408 CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
409 if ((i % 2) == 0)
410 {
411 Entry = *CBlock & 0x0fff;
412 }
413 else
414 {
415 Entry = *CBlock >> 4;
416 }
417
418 if (Entry == 0)
419 ulCount++;
420 }
421
423 DeviceExt->AvailableClusters = ulCount;
424 DeviceExt->AvailableClustersValid = TRUE;
425
426 return STATUS_SUCCESS;
427}
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
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
Definition: glfuncs.h:248
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define MAP_WAIT
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
BOOLEAN NTAPI CcMapData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *BcbResult, OUT PVOID *Buffer)
Definition: pinsup.c:694
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
base of all file and directory entries
Definition: entries.h:83
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59

Referenced by CountAvailableClusters().

◆ FAT12FindAndMarkAvailableCluster()

NTSTATUS FAT12FindAndMarkAvailableCluster ( PDEVICE_EXTENSION  DeviceExt,
PULONG  Cluster 
)

Definition at line 244 of file fat.c.

247{
248 ULONG FatLength;
249 ULONG StartCluster;
250 ULONG Entry;
251 PUSHORT CBlock;
252 ULONG i, j;
256
257 FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
258 *Cluster = 0;
259 StartCluster = DeviceExt->LastAvailableCluster;
260 Offset.QuadPart = 0;
262 {
263 CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, PIN_WAIT, &Context, &BaseAddress);
264 }
266 {
267 DPRINT1("CcPinRead(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
269 }
270 _SEH2_END;
271
272 for (j = 0; j < 2; j++)
273 {
274 for (i = StartCluster; i < FatLength; i++)
275 {
276 CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
277 if ((i % 2) == 0)
278 {
279 Entry = *CBlock & 0xfff;
280 }
281 else
282 {
283 Entry = *CBlock >> 4;
284 }
285
286 if (Entry == 0)
287 {
288 DPRINT("Found available cluster 0x%x\n", i);
289 DeviceExt->LastAvailableCluster = *Cluster = i;
290 if ((i % 2) == 0)
291 *CBlock = (*CBlock & 0xf000) | 0xfff;
292 else
293 *CBlock = (*CBlock & 0xf) | 0xfff0;
296 if (DeviceExt->AvailableClustersValid)
297 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
298 return STATUS_SUCCESS;
299 }
300 }
301 FatLength = StartCluster;
302 StartCluster = 2;
303 }
305 return STATUS_DISK_FULL;
306}
#define InterlockedDecrement
Definition: armddk.h:52
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
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
Definition: glfuncs.h:250
#define PIN_WAIT
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:802
#define DPRINT
Definition: sndvol32.h:71
int32_t * PLONG
Definition: typedefs.h:58
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155

Referenced by VfatMount().

◆ FAT12GetNextCluster()

NTSTATUS FAT12GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 123 of file fat.c.

127{
128 PUSHORT CBlock;
129 ULONG Entry;
133
134 *NextCluster = 0;
135
136 Offset.QuadPart = 0;
138 {
139 CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, MAP_WAIT, &Context, &BaseAddress);
140 }
142 {
144 }
145 _SEH2_END;
146
147 CBlock = (PUSHORT)((char*)BaseAddress + (CurrentCluster * 12) / 8);
148 if ((CurrentCluster % 2) == 0)
149 {
150 Entry = *CBlock & 0x0fff;
151 }
152 else
153 {
154 Entry = *CBlock >> 4;
155 }
156
157// DPRINT("Entry %x\n",Entry);
158 if (Entry >= 0xff8 && Entry <= 0xfff)
159 Entry = 0xffffffff;
160
161// DPRINT("Returning %x\n",Entry);
162 ASSERT(Entry != 0);
165// return Entry == 0xffffffff ? STATUS_END_OF_FILE : STATUS_SUCCESS;
166 return STATUS_SUCCESS;
167}
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:38
#define ASSERT(a)
Definition: mode.c:44

Referenced by VfatMount().

◆ FAT12WriteCluster()

NTSTATUS FAT12WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue,
PULONG  OldValue 
)

Definition at line 570 of file fat.c.

575{
576 ULONG FATOffset;
577 PUCHAR CBlock;
581
582 Offset.QuadPart = 0;
584 {
585 CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, PIN_WAIT, &Context, &BaseAddress);
586 }
588 {
590 }
591 _SEH2_END;
592 CBlock = (PUCHAR)BaseAddress;
593
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)
598 {
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;
603 }
604 else
605 {
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);
610 }
611 /* Write the changed FAT sector(s) to disk */
614 return STATUS_SUCCESS;
615}
unsigned char * PUCHAR
Definition: typedefs.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by VfatMount().

◆ FAT16CountAvailableClusters()

static NTSTATUS FAT16CountAvailableClusters ( PDEVICE_EXTENSION  DeviceExt)
static

Definition at line 435 of file fat.c.

437{
438 PUSHORT Block;
439 PUSHORT BlockEnd;
441 ULONG ulCount = 0;
442 ULONG i;
446 ULONG FatLength;
447
448 ChunkSize = CACHEPAGESIZE(DeviceExt);
449 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
450
451 for (i = 2; i < FatLength; )
452 {
453 Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
455 {
456 CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress);
457 }
459 {
461 }
462 _SEH2_END;
463 Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
464 BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
465
466 /* Now process the whole block */
467 while (Block < BlockEnd && i < FatLength)
468 {
469 if (*Block == 0)
470 ulCount++;
471 Block++;
472 i++;
473 }
474
476 }
477
478 DeviceExt->AvailableClusters = ulCount;
479 DeviceExt->AvailableClustersValid = TRUE;
480
481 return STATUS_SUCCESS;
482}
#define CACHEPAGESIZE(pDeviceExt)
Definition: fat.c:18
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize
Definition: rtlfuncs.h:2277

Referenced by CountAvailableClusters().

◆ FAT16FindAndMarkAvailableCluster()

NTSTATUS FAT16FindAndMarkAvailableCluster ( PDEVICE_EXTENSION  DeviceExt,
PULONG  Cluster 
)

Definition at line 173 of file fat.c.

176{
177 ULONG FatLength;
178 ULONG StartCluster;
179 ULONG i, j;
182 PVOID Context = 0;
184 PUSHORT Block;
185 PUSHORT BlockEnd;
186
187 ChunkSize = CACHEPAGESIZE(DeviceExt);
188 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
189 *Cluster = 0;
190 StartCluster = DeviceExt->LastAvailableCluster;
191
192 for (j = 0; j < 2; j++)
193 {
194 for (i = StartCluster; i < FatLength;)
195 {
196 Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
198 {
199 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
200 }
202 {
203 DPRINT1("CcPinRead(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
205 }
206 _SEH2_END;
207
208 Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
209 BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
210
211 /* Now process the whole block */
212 while (Block < BlockEnd && i < FatLength)
213 {
214 if (*Block == 0)
215 {
216 DPRINT("Found available cluster 0x%x\n", i);
217 DeviceExt->LastAvailableCluster = *Cluster = i;
218 *Block = 0xffff;
221 if (DeviceExt->AvailableClustersValid)
222 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
223 return STATUS_SUCCESS;
224 }
225
226 Block++;
227 i++;
228 }
229
231 }
232
233 FatLength = StartCluster;
234 StartCluster = 2;
235 }
236
237 return STATUS_DISK_FULL;
238}

Referenced by VfatMount().

◆ FAT16GetDirtyStatus()

NTSTATUS FAT16GetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
PBOOLEAN  DirtyStatus 
)

Definition at line 858 of file fat.c.

861{
864#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
866#else
868#endif
869 struct _BootSector * Sector;
870
871 /* We'll read the bootsector at 0 */
872 Offset.QuadPart = 0;
873 Length = DeviceExt->FatInfo.BytesPerSector;
874#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
875 /* Go through Cc for this */
877 {
878 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
879 }
881 {
883 }
884 _SEH2_END;
885#else
886 /* No Cc, do it the old way:
887 * - Allocate a big enough buffer
888 * - And read the disk
889 */
891 if (Sector == NULL)
892 {
893 *DirtyStatus = TRUE;
895 }
896
897 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
898 if (!NT_SUCCESS(Status))
899 {
900 *DirtyStatus = TRUE;
902 return Status;
903 }
904#endif
905
906 /* Make sure we have a boot sector...
907 * FIXME: This check is a bit lame and should be improved
908 */
909 if (Sector->Signatur1 != 0xaa55)
910 {
911 /* Set we are dirty so that we don't attempt anything */
912 *DirtyStatus = TRUE;
913#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
915#else
917#endif
919 }
920
921 /* Return the status of the dirty bit */
922 if (Sector->Res1 & FAT_DIRTY_BIT)
923 *DirtyStatus = TRUE;
924 else
925 *DirtyStatus = FALSE;
926
927#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
929#else
931#endif
932 return STATUS_SUCCESS;
933}
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short Signatur1
Definition: vfat.h:54
unsigned char Res1
Definition: vfat.h:50
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FAT_DIRTY_BIT
Definition: vfat.h:85
#define TAG_BUFFER
Definition: vfat.h:551
NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:70

Referenced by VfatMount().

◆ FAT16GetNextCluster()

NTSTATUS FAT16GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 77 of file fat.c.

81{
84 ULONG FATOffset;
88
89 ChunkSize = CACHEPAGESIZE(DeviceExt);
90 FATOffset = CurrentCluster * 2;
91 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
93 {
94 CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress);
95 }
97 {
99 }
100 _SEH2_END;
101
102 CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
103 if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
104 CurrentCluster = 0xffffffff;
105
106 if (CurrentCluster == 0)
107 {
108 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
111 ASSERT(CurrentCluster != 0);
112 }
113
115 *NextCluster = CurrentCluster;
116 return Status;
117}
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
ULONG Flags
Definition: vfat.h:413
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define VFAT_BREAK_ON_CORRUPTION
Definition: vfat.h:407

Referenced by VfatMount().

◆ FAT16SetDirtyStatus()

NTSTATUS FAT16SetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
BOOLEAN  DirtyStatus 
)

Definition at line 1044 of file fat.c.

1047{
1049 ULONG Length;
1050#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1052#else
1053 PVOID Context;
1054#endif
1055 struct _BootSector * Sector;
1056
1057 /* We'll read (and then write) the bootsector at 0 */
1058 Offset.QuadPart = 0;
1059 Length = DeviceExt->FatInfo.BytesPerSector;
1060#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1061 /* Go through Cc for this */
1062 _SEH2_TRY
1063 {
1064 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
1065 }
1067 {
1069 }
1070 _SEH2_END;
1071#else
1072 /* No Cc, do it the old way:
1073 * - Allocate a big enough buffer
1074 * - And read the disk
1075 */
1077 if (Sector == NULL)
1078 {
1080 }
1081
1082 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1083 if (!NT_SUCCESS(Status))
1084 {
1086 return Status;
1087 }
1088#endif
1089
1090 /* Make sure we have a boot sector...
1091 * FIXME: This check is a bit lame and should be improved
1092 */
1093 if (Sector->Signatur1 != 0xaa55)
1094 {
1095#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1097#else
1099#endif
1101 }
1102
1103 /* Modify the dirty bit status according
1104 * to caller needs
1105 */
1106 if (!DirtyStatus)
1107 {
1108 Sector->Res1 &= ~FAT_DIRTY_BIT;
1109 }
1110 else
1111 {
1112 Sector->Res1 |= FAT_DIRTY_BIT;
1113 }
1114
1115#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1116 /* Mark boot sector dirty so that it gets written to the disk */
1119 return STATUS_SUCCESS;
1120#else
1121 /* Write back the boot sector to the disk */
1122 Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1124 return Status;
1125#endif
1126}
NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:253

Referenced by VfatMount().

◆ FAT16WriteCluster()

NTSTATUS FAT16WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue,
PULONG  OldValue 
)

Definition at line 621 of file fat.c.

626{
628 ULONG FATOffset;
632 PUSHORT Cluster;
633
634 ChunkSize = CACHEPAGESIZE(DeviceExt);
635 FATOffset = ClusterToWrite * 2;
636 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
638 {
639 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
640 }
642 {
644 }
645 _SEH2_END;
646
647 DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
648 ClusterToWrite);
649 Cluster = ((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
650 *OldValue = *Cluster;
651 *Cluster = (USHORT)NewValue;
654 return STATUS_SUCCESS;
655}
unsigned short USHORT
Definition: pedump.c:61

Referenced by VfatMount().

◆ FAT32CountAvailableClusters()

static NTSTATUS FAT32CountAvailableClusters ( PDEVICE_EXTENSION  DeviceExt)
static

Definition at line 490 of file fat.c.

492{
493 PULONG Block;
494 PULONG BlockEnd;
496 ULONG ulCount = 0;
497 ULONG i;
501 ULONG FatLength;
502
503 ChunkSize = CACHEPAGESIZE(DeviceExt);
504 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
505
506 for (i = 2; i < FatLength; )
507 {
508 Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
510 {
511 CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress);
512 }
514 {
515 DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
517 }
518 _SEH2_END;
519 Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
520 BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
521
522 /* Now process the whole block */
523 while (Block < BlockEnd && i < FatLength)
524 {
525 if ((*Block & 0x0fffffff) == 0)
526 ulCount++;
527 Block++;
528 i++;
529 }
530
532 }
533
534 DeviceExt->AvailableClusters = ulCount;
535 DeviceExt->AvailableClustersValid = TRUE;
536
537 return STATUS_SUCCESS;
538}
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by CountAvailableClusters().

◆ FAT32FindAndMarkAvailableCluster()

NTSTATUS FAT32FindAndMarkAvailableCluster ( PDEVICE_EXTENSION  DeviceExt,
PULONG  Cluster 
)

Definition at line 312 of file fat.c.

315{
316 ULONG FatLength;
317 ULONG StartCluster;
318 ULONG i, j;
323 PULONG Block;
324 PULONG BlockEnd;
325
326 ChunkSize = CACHEPAGESIZE(DeviceExt);
327 FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
328 *Cluster = 0;
329 StartCluster = DeviceExt->LastAvailableCluster;
330
331 for (j = 0; j < 2; j++)
332 {
333 for (i = StartCluster; i < FatLength;)
334 {
335 Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
337 {
338 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
339 }
341 {
342 DPRINT1("CcPinRead(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
344 }
345 _SEH2_END;
346 Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
347 BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
348
349 /* Now process the whole block */
350 while (Block < BlockEnd && i < FatLength)
351 {
352 if ((*Block & 0x0fffffff) == 0)
353 {
354 DPRINT("Found available cluster 0x%x\n", i);
355 DeviceExt->LastAvailableCluster = *Cluster = i;
356 *Block = 0x0fffffff;
359 if (DeviceExt->AvailableClustersValid)
360 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
361 return STATUS_SUCCESS;
362 }
363
364 Block++;
365 i++;
366 }
367
369 }
370 FatLength = StartCluster;
371 StartCluster = 2;
372 }
373 return STATUS_DISK_FULL;
374}

Referenced by VfatMount().

◆ FAT32GetDirtyStatus()

NTSTATUS FAT32GetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
PBOOLEAN  DirtyStatus 
)

Definition at line 936 of file fat.c.

939{
942#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
944#else
946#endif
947 struct _BootSector32 * Sector;
948
949 /* We'll read the bootsector at 0 */
950 Offset.QuadPart = 0;
951 Length = DeviceExt->FatInfo.BytesPerSector;
952#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
953 /* Go through Cc for this */
955 {
956 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
957 }
959 {
961 }
962 _SEH2_END;
963#else
964 /* No Cc, do it the old way:
965 * - Allocate a big enough buffer
966 * - And read the disk
967 */
969 if (Sector == NULL)
970 {
971 *DirtyStatus = TRUE;
973 }
974
975 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
976 if (!NT_SUCCESS(Status))
977 {
978 *DirtyStatus = TRUE;
980 return Status;
981 }
982#endif
983
984 /* Make sure we have a boot sector...
985 * FIXME: This check is a bit lame and should be improved
986 */
987 if (Sector->Signature1 != 0xaa55)
988 {
989 /* Set we are dirty so that we don't attempt anything */
990 *DirtyStatus = TRUE;
991#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
993#else
995#endif
997 }
998
999 /* Return the status of the dirty bit */
1000 if (Sector->Res4 & FAT_DIRTY_BIT)
1001 *DirtyStatus = TRUE;
1002 else
1003 *DirtyStatus = FALSE;
1004
1005#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1007#else
1009#endif
1010 return STATUS_SUCCESS;
1011}
unsigned short Signature1
Definition: vfat.h:82
unsigned char Res4
Definition: vfat.h:77

Referenced by VfatMount().

◆ FAT32GetNextCluster()

NTSTATUS FAT32GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 28 of file fat.c.

32{
35 ULONG FATOffset;
39
40 ChunkSize = CACHEPAGESIZE(DeviceExt);
41 FATOffset = CurrentCluster * sizeof(ULONG);
42 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
44 {
45 if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
46 {
49 }
50 }
52 {
54 }
56
57 CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
58 if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
59 CurrentCluster = 0xffffffff;
60
61 if (CurrentCluster == 0)
62 {
63 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
66 ASSERT(CurrentCluster != 0);
67 }
69 *NextCluster = CurrentCluster;
70 return Status;
71}
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by VfatMount().

◆ FAT32SetDirtyStatus()

NTSTATUS FAT32SetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
BOOLEAN  DirtyStatus 
)

Definition at line 1129 of file fat.c.

1132{
1134 ULONG Length;
1135#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1137#else
1138 PVOID Context;
1139#endif
1140 struct _BootSector32 * Sector;
1141
1142 /* We'll read (and then write) the bootsector at 0 */
1143 Offset.QuadPart = 0;
1144 Length = DeviceExt->FatInfo.BytesPerSector;
1145#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1146 /* Go through Cc for this */
1147 _SEH2_TRY
1148 {
1149 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
1150 }
1152 {
1154 }
1155 _SEH2_END;
1156#else
1157 /* No Cc, do it the old way:
1158 * - Allocate a big enough buffer
1159 * - And read the disk
1160 */
1162 if (Sector == NULL)
1163 {
1165 }
1166
1167 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1168 if (!NT_SUCCESS(Status))
1169 {
1171 return Status;
1172 }
1173#endif
1174
1175 /* Make sure we have a boot sector...
1176 * FIXME: This check is a bit lame and should be improved
1177 */
1178 if (Sector->Signature1 != 0xaa55)
1179 {
1180 ASSERT(FALSE);
1181#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1183#else
1185#endif
1187 }
1188
1189 /* Modify the dirty bit status according
1190 * to caller needs
1191 */
1192 if (!DirtyStatus)
1193 {
1194 Sector->Res4 &= ~FAT_DIRTY_BIT;
1195 }
1196 else
1197 {
1198 Sector->Res4 |= FAT_DIRTY_BIT;
1199 }
1200
1201#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1202 /* Mark boot sector dirty so that it gets written to the disk */
1205 return STATUS_SUCCESS;
1206#else
1207 /* Write back the boot sector to the disk */
1208 Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1210 return Status;
1211#endif
1212}

Referenced by VfatMount().

◆ FAT32UpdateFreeClustersCount()

NTSTATUS FAT32UpdateFreeClustersCount ( PDEVICE_EXTENSION  DeviceExt)

Definition at line 1215 of file fat.c.

1217{
1219 ULONG Length;
1220#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1222#else
1223 PVOID Context;
1224#endif
1225 struct _FsInfoSector * Sector;
1226
1227 if (!DeviceExt->AvailableClustersValid)
1228 {
1230 }
1231
1232 /* We'll read (and then write) the fsinfo sector */
1233 Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector;
1234 Length = DeviceExt->FatInfo.BytesPerSector;
1235#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1236 /* Go through Cc for this */
1237 _SEH2_TRY
1238 {
1239 CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
1240 }
1242 {
1244 }
1245 _SEH2_END;
1246#else
1247 /* No Cc, do it the old way:
1248 * - Allocate a big enough buffer
1249 * - And read the disk
1250 */
1252 if (Sector == NULL)
1253 {
1255 }
1256
1257 Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1258 if (!NT_SUCCESS(Status))
1259 {
1261 return Status;
1262 }
1263#endif
1264
1265 /* Make sure we have a FSINFO sector */
1266 if (Sector->ExtBootSignature2 != 0x41615252 ||
1267 Sector->FSINFOSignature != 0x61417272 ||
1268 Sector->Signatur2 != 0xaa550000)
1269 {
1270 ASSERT(FALSE);
1271#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1273#else
1275#endif
1277 }
1278
1279 /* Update the free clusters count */
1280 Sector->FreeCluster = InterlockedCompareExchange((PLONG)&DeviceExt->AvailableClusters, 0, 0);
1281
1282#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
1283 /* Mark FSINFO sector dirty so that it gets written to the disk */
1286 return STATUS_SUCCESS;
1287#else
1288 /* Write back the FSINFO sector to the disk */
1289 Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
1291 return Status;
1292#endif
1293}
#define InterlockedCompareExchange
Definition: interlocked.h:104
unsigned long Signatur2
Definition: vfat.h:105
unsigned long FSINFOSignature
Definition: vfat.h:101
unsigned long FreeCluster
Definition: vfat.h:102
unsigned long ExtBootSignature2
Definition: vfat.h:99
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by FATAddEntry(), FATDelEntry(), and VfatSetAllocationSizeInformation().

◆ FAT32WriteCluster()

NTSTATUS FAT32WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue,
PULONG  OldValue 
)

Definition at line 661 of file fat.c.

666{
668 ULONG FATOffset;
672 PULONG Cluster;
673
674 ChunkSize = CACHEPAGESIZE(DeviceExt);
675
676 FATOffset = (ClusterToWrite * 4);
677 Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
679 {
680 CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, PIN_WAIT, &Context, &BaseAddress);
681 }
683 {
685 }
686 _SEH2_END;
687
688 DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
689 ClusterToWrite);
690 Cluster = ((PULONG)((char*)BaseAddress + (FATOffset % ChunkSize)));
691 *OldValue = *Cluster & 0x0fffffff;
692 *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
693
696
697 return STATUS_SUCCESS;
698}

Referenced by VfatMount().

◆ GetDirtyStatus()

NTSTATUS GetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
PBOOLEAN  DirtyStatus 
)

Definition at line 831 of file fat.c.

834{
836
837 DPRINT("GetDirtyStatus(DeviceExt %p)\n", DeviceExt);
838
839 /* FAT12 has no dirty bit */
840 if (DeviceExt->FatInfo.FatType == FAT12)
841 {
842 *DirtyStatus = FALSE;
843 return STATUS_SUCCESS;
844 }
845
846 /* Not really in the FAT, but share the lock because
847 * we're really low-level and shouldn't happent that often
848 * And call the appropriate function
849 */
850 ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
851 Status = DeviceExt->GetDirtyStatus(DeviceExt, DirtyStatus);
852 ExReleaseResourceLite(&DeviceExt->FatResource);
853
854 return Status;
855}
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621

Referenced by VfatMount().

◆ GetNextCluster()

NTSTATUS GetNextCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 744 of file fat.c.

748{
750
751 DPRINT("GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
752 DeviceExt, CurrentCluster);
753
754 if (CurrentCluster == 0)
755 {
756 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
758 ASSERT(CurrentCluster != 0);
760 }
761
762 ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
763 Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
764 ExReleaseResourceLite(&DeviceExt->FatResource);
765
766 return Status;
767}

Referenced by FATDelEntry(), FATXDelEntry(), NextCluster(), and OffsetToCluster().

◆ GetNextClusterExtend()

NTSTATUS GetNextClusterExtend ( PDEVICE_EXTENSION  DeviceExt,
ULONG  CurrentCluster,
PULONG  NextCluster 
)

Definition at line 773 of file fat.c.

777{
778 ULONG NewCluster;
780
781 DPRINT("GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
782 DeviceExt, CurrentCluster);
783
784 ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
785 /*
786 * If the file hasn't any clusters allocated then we need special
787 * handling
788 */
789 if (CurrentCluster == 0)
790 {
791 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
792 if (!NT_SUCCESS(Status))
793 {
794 ExReleaseResourceLite(&DeviceExt->FatResource);
795 return Status;
796 }
797
798 *NextCluster = NewCluster;
799 ExReleaseResourceLite(&DeviceExt->FatResource);
800 return STATUS_SUCCESS;
801 }
802
803 Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
804
805 if ((*NextCluster) == 0xFFFFFFFF)
806 {
807 /* We are after last existing cluster, we must add one to file */
808 /* Firstly, find the next available open allocation unit and
809 mark it as end of file */
810 Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
811 if (!NT_SUCCESS(Status))
812 {
813 ExReleaseResourceLite(&DeviceExt->FatResource);
814 return Status;
815 }
816
817 /* Now, write the AU of the LastCluster with the value of the newly
818 found AU */
819 WriteCluster(DeviceExt, CurrentCluster, NewCluster);
820 *NextCluster = NewCluster;
821 }
822
823 ExReleaseResourceLite(&DeviceExt->FatResource);
824 return Status;
825}
NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
Definition: fat.c:705

Referenced by NextCluster(), and OffsetToCluster().

◆ SetDirtyStatus()

NTSTATUS SetDirtyStatus ( PDEVICE_EXTENSION  DeviceExt,
BOOLEAN  DirtyStatus 
)

Definition at line 1017 of file fat.c.

1020{
1022
1023 DPRINT("SetDirtyStatus(DeviceExt %p, DirtyStatus %d)\n", DeviceExt, DirtyStatus);
1024
1025 /* FAT12 has no dirty bit */
1026 if (DeviceExt->FatInfo.FatType == FAT12)
1027 {
1028 return STATUS_SUCCESS;
1029 }
1030
1031 /* Not really in the FAT, but share the lock because
1032 * we're really low-level and shouldn't happent that often
1033 * And call the appropriate function
1034 * Acquire exclusive because we will modify ondisk value
1035 */
1036 ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
1037 Status = DeviceExt->SetDirtyStatus(DeviceExt, DirtyStatus);
1038 ExReleaseResourceLite(&DeviceExt->FatResource);
1039
1040 return Status;
1041}

Referenced by VfatDismountVolume(), VfatLockOrUnlockVolume(), VfatMarkVolumeDirty(), VfatMount(), and VfatShutdown().

◆ WriteCluster()

NTSTATUS WriteCluster ( PDEVICE_EXTENSION  DeviceExt,
ULONG  ClusterToWrite,
ULONG  NewValue 
)

Definition at line 705 of file fat.c.

709{
711 ULONG OldValue;
712
713 ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
714 Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
715 if (DeviceExt->AvailableClustersValid)
716 {
717 if (OldValue && NewValue == 0)
718 InterlockedIncrement((PLONG)&DeviceExt->AvailableClusters);
719 else if (OldValue == 0 && NewValue)
720 InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
721 }
722 ExReleaseResourceLite(&DeviceExt->FatResource);
723 return Status;
724}
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by FATDelEntry(), FATXDelEntry(), GetNextClusterExtend(), and VfatSetAllocationSizeInformation().