ReactOS 0.4.16-dev-1946-g52006dd
fat.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for fat.c:

Go to the source code of this file.

Classes

struct  _FAT_VOLUME_INFO
 
struct  _DIRECTORY_BUFFER
 

Macros

#define FAT_IS_END_CLUSTER(clnumber)
 
#define TAG_FAT_CHAIN   'CtaT'
 
#define TAG_FAT_FILE   'FtaF'
 
#define TAG_FAT_VOLUME   'VtaF'
 
#define TAG_FAT_BUFFER   'BtaF'
 
#define TAG_FAT_CACHE   'HtaF'
 
#define FAT_MAX_CACHE_SIZE   (256 * 1024)
 

Typedefs

typedef struct _FAT_VOLUME_INFO FAT_VOLUME_INFO
 
typedef struct _DIRECTORY_BUFFER DIRECTORY_BUFFER
 
typedef struct _DIRECTORY_BUFFERPDIRECTORY_BUFFER
 

Functions

 DBG_DEFAULT_CHANNEL (FILESYSTEM)
 
ULONG FatDetermineFatType (PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount)
 
PVOID FatBufferDirectory (PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG *EntryCountPointer, BOOLEAN RootDirectory)
 
ARC_STATUS FatLookupFile (PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer)
 
void FatParseShortFileName (PCHAR Buffer, PDIRENTRY DirEntry)
 
static BOOLEAN FatGetFatEntry (PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
 
static ULONG FatCountClustersInChain (PFAT_VOLUME_INFO Volume, UINT32 StartCluster)
 
static BOOLEAN FatReadClusterChain (PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 NumberOfClusters, PVOID Buffer, PUINT32 LastClusterNumber)
 
BOOLEAN FatReadPartialCluster (PFAT_VOLUME_INFO Volume, ULONG ClusterNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
 
BOOLEAN FatReadVolumeSectors (PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 
VOID FatSwapFatBootSector (PFAT_BOOTSECTOR Obj)
 
VOID FatSwapFat32BootSector (PFAT32_BOOTSECTOR Obj)
 
VOID FatSwapFatXBootSector (PFATX_BOOTSECTOR Obj)
 
VOID FatSwapDirEntry (PDIRENTRY Obj)
 
VOID FatSwapLFNDirEntry (PLFN_DIRENTRY Obj)
 
VOID FatSwapFatXDirEntry (PFATX_DIRENTRY Obj)
 
FORCEINLINE ULONG FatNumberOfClusters (_In_ PFAT_VOLUME_INFO Volume)
 Returns the number of clusters of the data area of the FAT volume. This value is computed by taking the total sectors on the disk, subtracting up to the first file area sector, then dividing by the sectors per cluster count.
 
BOOLEAN FatOpenVolume (PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount)
 
static BOOLEAN FatSearchDirectoryBufferForFile (PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
 
static BOOLEAN FatXSearchDirectoryBufferForFile (PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
 
static PUCHAR FatGetFatSector (PFAT_VOLUME_INFO Volume, UINT32 FatSectorNumber)
 Reads 1-4 sectors from FAT using the cache.
 
static BOOLEAN FatReadAdjacentClusters (PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 MaxClusters, PVOID Buffer, PUINT32 ClustersRead, PUINT32 LastClusterNumber)
 
static BOOLEAN FatReadFile (PFAT_FILE_INFO FatFileInfo, ULONG BytesToRead, ULONG *BytesRead, PVOID Buffer)
 
ARC_STATUS FatClose (ULONG FileId)
 
ARC_STATUS FatGetFileInformation (ULONG FileId, FILEINFORMATION *Information)
 
ARC_STATUS FatOpen (CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
 
ARC_STATUS FatRead (ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
 
ARC_STATUS FatSeek (ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
 
ULONGLONG FatGetVolumeSize (_In_ ULONG DeviceId)
 Returns the size of the FAT volume laid on the storage media device opened via DeviceId.
 
const DEVVTBLFatMount (ULONG DeviceId)
 

Variables

PFAT_VOLUME_INFO FatVolumes [MAX_FDS]
 
LIST_ENTRY DirectoryBufferListHead = {&DirectoryBufferListHead, &DirectoryBufferListHead}
 
const DEVVTBL FatFuncTable
 
const DEVVTBL FatXFuncTable
 

Macro Definition Documentation

◆ FAT_IS_END_CLUSTER

#define FAT_IS_END_CLUSTER (   clnumber)
Value:
(((Volume->FatType == FAT12) && (clnumber >= 0xff8)) || \
((Volume->FatType == FAT16 || Volume->FatType == FATX16) && (clnumber >= 0xfff8)) || \
((Volume->FatType == FAT32 || Volume->FatType == FATX32) && (clnumber >= 0x0ffffff8)))
#define FAT32
Definition: fat.h:157
#define FATX16
Definition: fat.h:158
#define FATX32
Definition: fat.h:159
#define FAT12
Definition: fat.h:155
#define FAT16
Definition: fat.h:156
UNICODE_STRING Volume
Definition: fltkernel.h:1172

Definition at line 25 of file fat.c.

◆ FAT_MAX_CACHE_SIZE

#define FAT_MAX_CACHE_SIZE   (256 * 1024)

Definition at line 36 of file fat.c.

◆ TAG_FAT_BUFFER

#define TAG_FAT_BUFFER   'BtaF'

Definition at line 33 of file fat.c.

◆ TAG_FAT_CACHE

#define TAG_FAT_CACHE   'HtaF'

Definition at line 34 of file fat.c.

◆ TAG_FAT_CHAIN

#define TAG_FAT_CHAIN   'CtaT'

Definition at line 30 of file fat.c.

◆ TAG_FAT_FILE

#define TAG_FAT_FILE   'FtaF'

Definition at line 31 of file fat.c.

◆ TAG_FAT_VOLUME

#define TAG_FAT_VOLUME   'VtaF'

Definition at line 32 of file fat.c.

Typedef Documentation

◆ DIRECTORY_BUFFER

◆ FAT_VOLUME_INFO

◆ PDIRECTORY_BUFFER

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( FILESYSTEM  )

◆ FatBufferDirectory()

PVOID FatBufferDirectory ( PFAT_VOLUME_INFO  Volume,
ULONG  DirectoryStartCluster,
ULONG EntryCountPointer,
BOOLEAN  RootDirectory 
)

Definition at line 462 of file fat.c.

463{
464 PDIRECTORY_BUFFER DirectoryBuffer;
466
467 TRACE("FatBufferDirectory() DirectoryStartCluster = %d RootDirectory = %s\n", DirectoryStartCluster, (RootDirectory ? "TRUE" : "FALSE"));
468
469 /*
470 * For FAT32, the root directory is nothing special. We can treat it the same
471 * as a subdirectory.
472 */
473 if (RootDirectory && Volume->FatType == FAT32)
474 {
475 DirectoryStartCluster = Volume->RootDirStartCluster;
477 }
478
479 /* Search the list for a match */
482 Entry = Entry->Flink)
483 {
484 DirectoryBuffer = CONTAINING_RECORD(Entry, DIRECTORY_BUFFER, Link);
485
486 /* Check if it matches */
487 if ((DirectoryBuffer->Volume == Volume) &&
488 (DirectoryBuffer->DirectoryStartCluster == DirectoryStartCluster))
489 {
490 TRACE("Found cached buffer\n");
491 *DirectorySize = DirectoryBuffer->DirectorySize;
492 return DirectoryBuffer->Data;
493 }
494 }
495
496 //
497 // Calculate the size of the directory
498 //
499 if (RootDirectory)
500 {
501 *DirectorySize = Volume->RootDirSectors * Volume->BytesPerSector;
502 }
503 else
504 {
505 *DirectorySize = FatCountClustersInChain(Volume, DirectoryStartCluster) * Volume->SectorsPerCluster * Volume->BytesPerSector;
506 }
507
508 //
509 // Attempt to allocate memory for directory buffer
510 //
511 TRACE("Trying to allocate (DirectorySize) %d bytes.\n", *DirectorySize);
512 DirectoryBuffer = FrLdrTempAlloc(*DirectorySize + sizeof(DIRECTORY_BUFFER),
514
515 if (DirectoryBuffer == NULL)
516 {
517 return NULL;
518 }
519
520 //
521 // Now read directory contents into DirectoryBuffer
522 //
523 if (RootDirectory)
524 {
525 if (!FatReadVolumeSectors(Volume, Volume->RootDirSectorStart, Volume->RootDirSectors, DirectoryBuffer->Data))
526 {
527 FrLdrTempFree(DirectoryBuffer, TAG_FAT_BUFFER);
528 return NULL;
529 }
530 }
531 else
532 {
533 if (!FatReadClusterChain(Volume, DirectoryStartCluster, 0xFFFFFFFF, DirectoryBuffer->Data, NULL))
534 {
535 FrLdrTempFree(DirectoryBuffer, TAG_FAT_BUFFER);
536 return NULL;
537 }
538 }
539
540 /* Enqueue it in the list */
541 DirectoryBuffer->Volume = Volume;
542 DirectoryBuffer->DirectoryStartCluster = DirectoryStartCluster;
543 DirectoryBuffer->DirectorySize = *DirectorySize;
544 InsertTailList(&DirectoryBufferListHead, &DirectoryBuffer->Link);
545
546 return DirectoryBuffer->Data;
547}
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: heap.c:553
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
static BOOLEAN FatReadClusterChain(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 NumberOfClusters, PVOID Buffer, PUINT32 LastClusterNumber)
Definition: fat.c:1192
static ULONG FatCountClustersInChain(PFAT_VOLUME_INFO Volume, UINT32 StartCluster)
Definition: fat.c:1108
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: fat.c:1427
#define TAG_FAT_BUFFER
Definition: fat.c:33
LIST_ENTRY DirectoryBufferListHead
Definition: fat.c:460
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define InsertTailList(ListHead, Entry)
#define TRACE(s)
Definition: solgame.cpp:4
base of all file and directory entries
Definition: entries.h:83
LIST_ENTRY Link
Definition: fat.c:453
PVOID Volume
Definition: fat.c:454
ULONG DirectorySize
Definition: fat.c:456
ULONG DirectoryStartCluster
Definition: fat.c:455
UCHAR Data[]
Definition: fat.c:457
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static int Link(const char **args)
Definition: vfdcmd.c:2414

Referenced by FatLookupFile().

◆ FatClose()

ARC_STATUS FatClose ( ULONG  FileId)

Definition at line 1461 of file fat.c.

1462{
1464
1466
1467 return ESUCCESS;
1468}
PVOID FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:709
#define TAG_FAT_FILE
Definition: fat.c:31
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ ESUCCESS
Definition: arc.h:32

◆ FatCountClustersInChain()

static ULONG FatCountClustersInChain ( PFAT_VOLUME_INFO  Volume,
UINT32  StartCluster 
)
static

Definition at line 1108 of file fat.c.

1109{
1110 ULONG ClusterCount = 0;
1111
1112 TRACE("FatCountClustersInChain() StartCluster = %d\n", StartCluster);
1113
1114 while (1)
1115 {
1116 //
1117 // If end of chain then break out of our cluster counting loop
1118 //
1119 if (FAT_IS_END_CLUSTER(StartCluster))
1120 {
1121 break;
1122 }
1123
1124 //
1125 // Increment count
1126 //
1127 ClusterCount++;
1128
1129 //
1130 // Get next cluster
1131 //
1132 if (!FatGetFatEntry(Volume, StartCluster, &StartCluster))
1133 {
1134 return 0;
1135 }
1136 }
1137
1138 TRACE("FatCountClustersInChain() ClusterCount = %d\n", ClusterCount);
1139
1140 return ClusterCount;
1141}
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
Definition: fat.c:1018
#define FAT_IS_END_CLUSTER(clnumber)
Definition: fat.c:25
uint32_t ULONG
Definition: typedefs.h:59

Referenced by FatBufferDirectory().

◆ FatDetermineFatType()

ULONG FatDetermineFatType ( PFAT_BOOTSECTOR  FatBootSector,
ULONGLONG  PartitionSectorCount 
)

Definition at line 396 of file fat.c.

397{
398 ULONG RootDirSectors;
399 ULONG DataSectorCount;
400 ULONG SectorsPerFat;
401 ULONG TotalSectors;
402 ULONG CountOfClusters;
403 PFAT32_BOOTSECTOR Fat32BootSector = (PFAT32_BOOTSECTOR)FatBootSector;
404 PFATX_BOOTSECTOR FatXBootSector = (PFATX_BOOTSECTOR)FatBootSector;
405
406 if (0 == strncmp(FatXBootSector->FileSystemType, "FATX", 4))
407 {
408 CountOfClusters = (ULONG)(PartitionSectorCount / FatXBootSector->SectorsPerCluster);
409 if (CountOfClusters < 65525)
410 {
411 /* Volume is FATX16 */
412 return FATX16;
413 }
414 else
415 {
416 /* Volume is FAT32 */
417 return FATX32;
418 }
419 }
420 else
421 {
422 RootDirSectors = ((SWAPW(FatBootSector->RootDirEntries) * 32) + (SWAPW(FatBootSector->BytesPerSector) - 1)) / SWAPW(FatBootSector->BytesPerSector);
423 SectorsPerFat = SWAPW(FatBootSector->SectorsPerFat) ? SWAPW(FatBootSector->SectorsPerFat) : SWAPD(Fat32BootSector->SectorsPerFatBig);
424 TotalSectors = SWAPW(FatBootSector->TotalSectors) ? SWAPW(FatBootSector->TotalSectors) : SWAPD(FatBootSector->TotalSectorsBig);
425 DataSectorCount = TotalSectors - (SWAPW(FatBootSector->ReservedSectors) + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors);
426
427//mjl
428 if (FatBootSector->SectorsPerCluster == 0)
429 CountOfClusters = 0;
430 else
431 CountOfClusters = DataSectorCount / FatBootSector->SectorsPerCluster;
432
433 if (CountOfClusters < 4085)
434 {
435 /* Volume is FAT12 */
436 return FAT12;
437 }
438 else if (CountOfClusters < 65525)
439 {
440 /* Volume is FAT16 */
441 return FAT16;
442 }
443 else
444 {
445 /* Volume is FAT32 */
446 return FAT32;
447 }
448 }
449}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
ULONG PartitionSectorCount
Definition: partition.c:39
struct _FATX_BOOTSECTOR * PFATX_BOOTSECTOR
#define SWAPD(x)
Definition: bytesex.h:7
#define SWAPW(x)
Definition: bytesex.h:8
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
ULONG SectorsPerCluster
Definition: fat.h:92
CHAR FileSystemType[4]
Definition: fat.h:90
USHORT TotalSectors
Definition: fsutil.c:45
UCHAR NumberOfFats
Definition: fsutil.c:43
USHORT SectorsPerFat
Definition: fsutil.c:47
USHORT ReservedSectors
Definition: fsutil.c:42
USHORT BytesPerSector
Definition: fsutil.c:40
USHORT RootDirEntries
Definition: fsutil.c:44
UCHAR SectorsPerCluster
Definition: fsutil.c:41

Referenced by FatOpenVolume().

◆ FatGetFatEntry()

static BOOLEAN FatGetFatEntry ( PFAT_VOLUME_INFO  Volume,
UINT32  Cluster,
PUINT32  ClusterPointer 
)
static

Definition at line 1018 of file fat.c.

1019{
1020 UINT32 FatOffset, ThisFatSecNum, ThisFatEntOffset, fat;
1022
1023 TRACE("FatGetFatEntry() Retrieving FAT entry for cluster %d.\n", Cluster);
1024
1025 switch(Volume->FatType)
1026 {
1027 case FAT12:
1028
1029 FatOffset = Cluster + (Cluster / 2);
1030 ThisFatSecNum = FatOffset / Volume->BytesPerSector;
1031 ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);
1032
1033 TRACE("FatOffset: %d\n", FatOffset);
1034 TRACE("ThisFatSecNum: %d\n", ThisFatSecNum);
1035 TRACE("ThisFatEntOffset: %d\n", ThisFatEntOffset);
1036
1037 // The cluster pointer can span within two sectors, but the FatGetFatSector function
1038 // reads 4 sectors most times, except when we are at the edge of FAT cache
1039 // and/or FAT region on the disk. For FAT12 the whole FAT would be cached so
1040 // there will be no situation when the first sector is at the end of the cache
1041 // and the next one is in the beginning
1042
1043 ReadBuffer = FatGetFatSector(Volume, ThisFatSecNum);
1044 if (!ReadBuffer)
1045 {
1046 return FALSE;
1047 }
1048
1049 fat = *((USHORT *) (ReadBuffer + ThisFatEntOffset));
1050 fat = SWAPW(fat);
1051 if (Cluster & 0x0001)
1052 fat = fat >> 4; /* Cluster number is ODD */
1053 else
1054 fat = fat & 0x0FFF; /* Cluster number is EVEN */
1055
1056 break;
1057
1058 case FAT16:
1059 case FATX16:
1060
1061 FatOffset = (Cluster * 2);
1062 ThisFatSecNum = FatOffset / Volume->BytesPerSector;
1063 ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);
1064
1065 ReadBuffer = FatGetFatSector(Volume, ThisFatSecNum);
1066 if (!ReadBuffer)
1067 {
1068 return FALSE;
1069 }
1070
1071 fat = *((USHORT *) (ReadBuffer + ThisFatEntOffset));
1072 fat = SWAPW(fat);
1073
1074 break;
1075
1076 case FAT32:
1077 case FATX32:
1078
1079 FatOffset = (Cluster * 4);
1080 ThisFatSecNum = FatOffset / Volume->BytesPerSector;
1081 ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);
1082
1083 ReadBuffer = FatGetFatSector(Volume, ThisFatSecNum);
1084 if (!ReadBuffer)
1085 {
1086 return FALSE;
1087 }
1088
1089 // Get the fat entry
1090 fat = (*((ULONG *) (ReadBuffer + ThisFatEntOffset))) & 0x0FFFFFFF;
1091 fat = SWAPD(fat);
1092
1093 break;
1094
1095 default:
1096 ERR("Unknown FAT type %d\n", Volume->FatType);
1097 return FALSE;
1098 }
1099
1100 TRACE("FAT entry is 0x%x.\n", fat);
1101
1102 *ClusterPointer = fat;
1103
1104 return TRUE;
1105}
unsigned int UINT32
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define ERR(fmt,...)
Definition: precomp.h:57
static PUCHAR FatGetFatSector(PFAT_VOLUME_INFO Volume, UINT32 FatSectorNumber)
Reads 1-4 sectors from FAT using the cache.
Definition: fat.c:980
#define TRUE
Definition: types.h:120
static unsigned char * fat
Definition: mkdosfs.c:542
unsigned short USHORT
Definition: pedump.c:61
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by FatCountClustersInChain(), FatReadAdjacentClusters(), FatReadFile(), and FatSeek().

◆ FatGetFatSector()

static PUCHAR FatGetFatSector ( PFAT_VOLUME_INFO  Volume,
UINT32  FatSectorNumber 
)
static

Reads 1-4 sectors from FAT using the cache.

Definition at line 980 of file fat.c.

981{
982 UINT32 SectorNumAbsolute = Volume->ActiveFatSectorStart + FatSectorNumber;
983 UINT32 CacheIndex = FatSectorNumber % Volume->FatCacheSize;
984
985 ASSERT(FatSectorNumber < Volume->SectorsPerFat);
986
987 // cache miss
988 if (Volume->FatCacheIndex[CacheIndex] != SectorNumAbsolute)
989 {
990 UINT32 SectorsToRead = min(Volume->FatCacheSize - CacheIndex, min(Volume->SectorsPerFat - SectorNumAbsolute, 4));
991 UINT8 i;
992
993 if (!FatReadVolumeSectors(Volume, SectorNumAbsolute, SectorsToRead, &Volume->FatCache[CacheIndex * Volume->BytesPerSector]))
994 {
995 return NULL;
996 }
997
998 for (i = 0; i < SectorsToRead; i++)
999 {
1000 Volume->FatCacheIndex[CacheIndex + i] = SectorNumAbsolute + i;
1001 }
1002
1003 TRACE("FAT cache miss: read sector 0x%x from disk\n", SectorNumAbsolute);
1004 }
1005 else
1006 {
1007 TRACE("FAT cache hit: sector 0x%x present\n", SectorNumAbsolute);
1008 }
1009
1010 return &Volume->FatCache[CacheIndex * Volume->BytesPerSector];
1011}
unsigned char UINT8
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 ASSERT(a)
Definition: mode.c:44
#define min(a, b)
Definition: monoChain.cc:55

Referenced by FatGetFatEntry().

◆ FatGetFileInformation()

ARC_STATUS FatGetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)

Definition at line 1470 of file fat.c.

1471{
1473
1475 Information->EndingAddress.LowPart = FileHandle->FileSize;
1476 Information->CurrentAddress.LowPart = FileHandle->FilePointer;
1477
1478 /* Set the ARC file attributes */
1479 Information->Attributes = FileHandle->Attributes;
1480
1481 /* Copy the file name, perhaps truncated, and NUL-terminated */
1482 Information->FileNameLength = min(FileHandle->FileNameLength, sizeof(Information->FileName) - 1);
1483 RtlCopyMemory(Information->FileName, FileHandle->FileName, Information->FileNameLength);
1484 Information->FileName[Information->FileNameLength] = ANSI_NULL;
1485
1486 TRACE("FatGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
1487 FileId, Information->EndingAddress.LowPart, Information->CurrentAddress.LowPart);
1488
1489 return ESUCCESS;
1490}
#define ANSI_NULL
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

◆ FatGetVolumeSize()

ULONGLONG FatGetVolumeSize ( _In_ ULONG  DeviceId)

Returns the size of the FAT volume laid on the storage media device opened via DeviceId.

Definition at line 1616 of file fat.c.

1618{
1620 ASSERT(Volume);
1621 return (ULONGLONG)Volume->TotalSectors * Volume->BytesPerSector;
1622}
PFAT_VOLUME_INFO FatVolumes[MAX_FDS]
Definition: fat.c:59
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by FsGetVolumeSize().

◆ FatLookupFile()

ARC_STATUS FatLookupFile ( PFAT_VOLUME_INFO  Volume,
PCSTR  FileName,
PFAT_FILE_INFO  FatFileInfoPointer 
)

Definition at line 818 of file fat.c.

819{
820 ULONG NumberOfPathParts;
821 ULONG i;
822 CHAR PathPart[261];
823 PVOID DirectoryBuffer;
824 ULONG DirectoryStartCluster = 0;
825 ULONG DirectorySize;
826 FAT_FILE_INFO FatFileInfo;
827
828 TRACE("FatLookupFile() FileName = %s\n", FileName);
829
830 RtlZeroMemory(FatFileInfoPointer, sizeof(FAT_FILE_INFO));
831
832 /* Skip leading path separator, if any */
833 if (*FileName == '\\' || *FileName == '/')
834 ++FileName;
835 PathPart[0] = ANSI_NULL;
836
837 //
838 // Figure out how many sub-directories we are nested in
839 //
840 NumberOfPathParts = FsGetNumPathParts(FileName);
841
842 //
843 // Loop once for each part
844 //
845 for (i=0; i<NumberOfPathParts; i++)
846 {
847 //
848 // Get first path part
849 //
851
852 //
853 // Advance to the next part of the path
854 //
855 for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
856 {
857 }
858 FileName++;
859
860 //
861 // Buffer the directory contents
862 //
863 DirectoryBuffer = FatBufferDirectory(Volume, DirectoryStartCluster, &DirectorySize, (i == 0) );
864 if (DirectoryBuffer == NULL)
865 {
866 return ENOMEM;
867 }
868
869 //
870 // Search for file name in directory
871 //
872 if (ISFATX(Volume->FatType))
873 {
874 if (!FatXSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo))
875 {
876 return ENOENT;
877 }
878 }
879 else
880 {
881 if (!FatSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo))
882 {
883 return ENOENT;
884 }
885 }
886
887 //
888 // If we have another sub-directory to go then
889 // grab the start cluster and free the fat chain array
890 //
891 if ((i+1) < NumberOfPathParts)
892 {
893 //
894 // Check if current entry is a directory
895 //
896 if (!(FatFileInfo.Attributes & FAT_ATTR_DIRECTORY))
897 {
898 return ENOTDIR;
899 }
900 DirectoryStartCluster = FatFileInfo.StartCluster;
901 }
902 }
903
904 RtlCopyMemory(FatFileInfoPointer, &FatFileInfo, sizeof(FatFileInfo));
905
906 /* Re-map the attributes to ARC file attributes */
907 FatFileInfoPointer->Attributes = 0;
908 if (FatFileInfo.Attributes & FAT_ATTR_READONLY)
909 FatFileInfoPointer->Attributes |= ReadOnlyFile;
910 if (FatFileInfo.Attributes & FAT_ATTR_HIDDEN)
911 FatFileInfoPointer->Attributes |= HiddenFile;
912 if (FatFileInfo.Attributes & FAT_ATTR_SYSTEM)
913 FatFileInfoPointer->Attributes |= SystemFile;
914 if (FatFileInfo.Attributes & FAT_ATTR_ARCHIVE)
915 FatFileInfoPointer->Attributes |= ArchiveFile;
916 if (FatFileInfo.Attributes & FAT_ATTR_DIRECTORY)
917 FatFileInfoPointer->Attributes |= DirectoryFile;
918
919 /* Copy the file name, perhaps truncated */
920 FatFileInfoPointer->FileNameLength = (ULONG)strlen(PathPart);
921 FatFileInfoPointer->FileNameLength = min(FatFileInfoPointer->FileNameLength, sizeof(FatFileInfoPointer->FileName) - 1);
922 RtlCopyMemory(FatFileInfoPointer->FileName, PathPart, FatFileInfoPointer->FileNameLength);
923
924 return ESUCCESS;
925}
#define ENOENT
Definition: acclib.h:79
#define ENOMEM
Definition: acclib.h:84
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define FAT_ATTR_SYSTEM
Definition: fat.h:149
#define FAT_ATTR_READONLY
Definition: fat.h:147
#define FAT_ATTR_HIDDEN
Definition: fat.h:148
#define FAT_ATTR_ARCHIVE
Definition: fat.h:152
#define FAT_ATTR_DIRECTORY
Definition: fat.h:151
#define ISFATX(FT)
Definition: fat.h:161
ULONG FsGetNumPathParts(PCSTR Path)
Definition: fs.c:617
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:645
static BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
Definition: fat.c:549
PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG *EntryCountPointer, BOOLEAN RootDirectory)
Definition: fat.c:462
static BOOLEAN FatXSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
Definition: fat.c:755
#define ENOTDIR
Definition: errno.h:26
@ DirectoryFile
Definition: fatprocs.h:1047
struct _FileName FileName
Definition: fatprocs.h:897
@ ReadOnlyFile
Definition: arc.h:78
@ ArchiveFile
Definition: arc.h:81
@ SystemFile
Definition: arc.h:80
@ HiddenFile
Definition: arc.h:79
ULONG FileNameLength
Definition: fat.h:172
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)]
Definition: fat.h:174
UCHAR Attributes
Definition: fat.h:173
ULONG StartCluster
Definition: fat.h:171
char CHAR
Definition: xmlstorage.h:175

Referenced by FatOpen().

◆ FatMount()

const DEVVTBL * FatMount ( ULONG  DeviceId)

Definition at line 1645 of file fat.c.

1646{
1654 ULONG Count;
1657
1658 TRACE("Enter FatMount(%lu)\n", DeviceId);
1659
1660 //
1661 // Allocate data for volume information
1662 //
1664 if (!Volume)
1665 return NULL;
1667
1668 //
1669 // Read the BootSector
1670 //
1671 Position.QuadPart = 0;
1672 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
1673 if (Status != ESUCCESS)
1674 {
1676 return NULL;
1677 }
1678 Status = ArcRead(DeviceId, Buffer, sizeof(Buffer), &Count);
1679 if (Status != ESUCCESS || Count != sizeof(Buffer))
1680 {
1682 return NULL;
1683 }
1684
1685 //
1686 // Check if BootSector is valid. If no, return early
1687 //
1688 if (!RtlEqualMemory(BootSector->FileSystemType, "FAT12 ", 8) &&
1689 !RtlEqualMemory(BootSector->FileSystemType, "FAT16 ", 8) &&
1690 !RtlEqualMemory(BootSector32->FileSystemType, "FAT32 ", 8) &&
1691 !RtlEqualMemory(BootSectorX->FileSystemType, "FATX", 4))
1692 {
1694 return NULL;
1695 }
1696
1697 //
1698 // Determine sector count
1699 //
1701 if (Status != ESUCCESS)
1702 {
1704 return NULL;
1705 }
1706 SectorCount.QuadPart = (FileInformation.EndingAddress.QuadPart - FileInformation.StartingAddress.QuadPart);
1707 SectorCount.QuadPart /= SECTOR_SIZE;
1708
1709 //
1710 // Keep device id
1711 //
1712 Volume->DeviceId = DeviceId;
1713
1714 //
1715 // Really open the volume
1716 //
1717 if (!FatOpenVolume(Volume, BootSector, SectorCount.QuadPart))
1718 {
1720 return NULL;
1721 }
1722
1723 //
1724 // Remember FAT volume information
1725 //
1726 FatVolumes[DeviceId] = Volume;
1727
1728 //
1729 // Return success
1730 //
1731 TRACE("FatMount(%lu) success\n", DeviceId);
1732 return (ISFATX(Volume->FatType) ? &FatXFuncTable : &FatFuncTable);
1733}
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:462
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:455
#define SECTOR_SIZE
Definition: fs.h:22
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:448
#define TAG_FAT_VOLUME
Definition: fat.c:32
const DEVVTBL FatXFuncTable
Definition: fat.c:1635
BOOLEAN FatOpenVolume(PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount)
Definition: fat.c:160
const DEVVTBL FatFuncTable
Definition: fat.c:1625
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:25
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
int Count
Definition: noreturn.cpp:7
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
ULONG SectorCount
Definition: part_xbox.c:31
ULONG ARC_STATUS
Definition: arc.h:4
@ SeekAbsolute
Definition: arc.h:59
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
static COORD Position
Definition: mouse.c:34
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ FatNumberOfClusters()

FORCEINLINE ULONG FatNumberOfClusters ( _In_ PFAT_VOLUME_INFO  Volume)

Returns the number of clusters of the data area of the FAT volume. This value is computed by taking the total sectors on the disk, subtracting up to the first file area sector, then dividing by the sectors per cluster count.

Note
Relies on the FAT_VOLUME_INFO fields already computed by FatOpenVolume().
See also
https://github.com/reactos/reactos/blob/435482912c6dc0aaa4371e37b7336b2b1291e65f/drivers/filesystems/fastfat/fat.h#L460 https://github.com/reactos/reactos/blob/435482912c6dc0aaa4371e37b7336b2b1291e65f/drivers/filesystems/vfatfs/fsctl.c#L24

Definition at line 154 of file fat.c.

156{
157 return ((Volume->TotalSectors - Volume->DataSectorStart) / Volume->SectorsPerCluster);
158}

◆ FatOpen()

ARC_STATUS FatOpen ( CHAR Path,
OPENMODE  OpenMode,
ULONG FileId 
)

Definition at line 1492 of file fat.c.

1493{
1494 PFAT_VOLUME_INFO FatVolume;
1495 FAT_FILE_INFO TempFileInfo;
1497 ULONG DeviceId;
1500
1501 if (OpenMode != OpenReadOnly && OpenMode != OpenDirectory)
1502 return EACCES;
1503
1504 DeviceId = FsGetDeviceId(*FileId);
1505 FatVolume = FatVolumes[DeviceId];
1506
1507 TRACE("FatOpen() FileName = %s\n", Path);
1508
1509 RtlZeroMemory(&TempFileInfo, sizeof(TempFileInfo));
1510 Status = FatLookupFile(FatVolume, Path, &TempFileInfo);
1511 if (Status != ESUCCESS)
1512 return ENOENT;
1513
1514 //
1515 // Check if caller opened what he expected (dir vs file)
1516 //
1517 IsDirectory = !!(TempFileInfo.Attributes & DirectoryFile);
1518 if (IsDirectory && OpenMode != OpenDirectory)
1519 return EISDIR;
1520 else if (!IsDirectory && OpenMode != OpenReadOnly)
1521 return ENOTDIR;
1522
1524 if (!FileHandle)
1525 return ENOMEM;
1526
1527 RtlCopyMemory(FileHandle, &TempFileInfo, sizeof(FAT_FILE_INFO));
1528 FileHandle->Volume = FatVolume;
1529
1531 return ESUCCESS;
1532}
unsigned char BOOLEAN
PRTL_UNICODE_STRING_BUFFER Path
#define EACCES
Definition: acclib.h:85
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
Definition: fs.c:702
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:716
ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer)
Definition: fat.c:818
#define EISDIR
Definition: errno.h:27
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
@ OpenDirectory
Definition: arc.h:72
@ OpenReadOnly
Definition: arc.h:65
PVOID Volume
Definition: fltmgrint.h:141

◆ FatOpenVolume()

BOOLEAN FatOpenVolume ( PFAT_VOLUME_INFO  Volume,
PFAT_BOOTSECTOR  BootSector,
ULONGLONG  PartitionSectorCount 
)

Definition at line 160 of file fat.c.

161{
162 char ErrMsg[80];
163 ULONG FatSize, i;
164 PFAT_BOOTSECTOR FatVolumeBootSector;
165 PFAT32_BOOTSECTOR Fat32VolumeBootSector;
166 PFATX_BOOTSECTOR FatXVolumeBootSector;
167
168 TRACE("FatOpenVolume() DeviceId = %d\n", Volume->DeviceId);
169
170 //
171 // Allocate the memory to hold the boot sector
172 //
173 FatVolumeBootSector = (PFAT_BOOTSECTOR)BootSector;
174 Fat32VolumeBootSector = (PFAT32_BOOTSECTOR)BootSector;
175 FatXVolumeBootSector = (PFATX_BOOTSECTOR)BootSector;
176
177 // Get the FAT type
178 Volume->FatType = FatDetermineFatType(FatVolumeBootSector, PartitionSectorCount);
179
180 // Dump boot sector (and swap it for big endian systems)
181 TRACE("Dumping boot sector:\n");
182 if (ISFATX(Volume->FatType))
183 {
184 FatSwapFatXBootSector(FatXVolumeBootSector);
185 TRACE("sizeof(FATX_BOOTSECTOR) = 0x%x.\n", sizeof(FATX_BOOTSECTOR));
186
187 TRACE("FileSystemType: %c%c%c%c.\n", FatXVolumeBootSector->FileSystemType[0], FatXVolumeBootSector->FileSystemType[1], FatXVolumeBootSector->FileSystemType[2], FatXVolumeBootSector->FileSystemType[3]);
188 TRACE("VolumeSerialNumber: 0x%x\n", FatXVolumeBootSector->VolumeSerialNumber);
189 TRACE("SectorsPerCluster: %d\n", FatXVolumeBootSector->SectorsPerCluster);
190 TRACE("NumberOfFats: %d\n", FatXVolumeBootSector->NumberOfFats);
191 TRACE("Unknown: 0x%x\n", FatXVolumeBootSector->Unknown);
192
193 TRACE("FatType %s\n", Volume->FatType == FATX16 ? "FATX16" : "FATX32");
194
195 }
196 else if (Volume->FatType == FAT32)
197 {
198 FatSwapFat32BootSector(Fat32VolumeBootSector);
199 TRACE("sizeof(FAT32_BOOTSECTOR) = 0x%x.\n", sizeof(FAT32_BOOTSECTOR));
200
201 TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", Fat32VolumeBootSector->JumpBoot[0], Fat32VolumeBootSector->JumpBoot[1], Fat32VolumeBootSector->JumpBoot[2]);
202 TRACE("OemName: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->OemName[0], Fat32VolumeBootSector->OemName[1], Fat32VolumeBootSector->OemName[2], Fat32VolumeBootSector->OemName[3], Fat32VolumeBootSector->OemName[4], Fat32VolumeBootSector->OemName[5], Fat32VolumeBootSector->OemName[6], Fat32VolumeBootSector->OemName[7]);
203 TRACE("BytesPerSector: %d\n", Fat32VolumeBootSector->BytesPerSector);
204 TRACE("SectorsPerCluster: %d\n", Fat32VolumeBootSector->SectorsPerCluster);
205 TRACE("ReservedSectors: %d\n", Fat32VolumeBootSector->ReservedSectors);
206 TRACE("NumberOfFats: %d\n", Fat32VolumeBootSector->NumberOfFats);
207 TRACE("RootDirEntries: %d\n", Fat32VolumeBootSector->RootDirEntries);
208 TRACE("TotalSectors: %d\n", Fat32VolumeBootSector->TotalSectors);
209 TRACE("MediaDescriptor: 0x%x\n", Fat32VolumeBootSector->MediaDescriptor);
210 TRACE("SectorsPerFat: %d\n", Fat32VolumeBootSector->SectorsPerFat);
211 TRACE("SectorsPerTrack: %d\n", Fat32VolumeBootSector->SectorsPerTrack);
212 TRACE("NumberOfHeads: %d\n", Fat32VolumeBootSector->NumberOfHeads);
213 TRACE("HiddenSectors: %d\n", Fat32VolumeBootSector->HiddenSectors);
214 TRACE("TotalSectorsBig: %d\n", Fat32VolumeBootSector->TotalSectorsBig);
215 TRACE("SectorsPerFatBig: %d\n", Fat32VolumeBootSector->SectorsPerFatBig);
216 TRACE("ExtendedFlags: 0x%x\n", Fat32VolumeBootSector->ExtendedFlags);
217 TRACE("FileSystemVersion: 0x%x\n", Fat32VolumeBootSector->FileSystemVersion);
218 TRACE("RootDirStartCluster: %d\n", Fat32VolumeBootSector->RootDirStartCluster);
219 TRACE("FsInfo: %d\n", Fat32VolumeBootSector->FsInfo);
220 TRACE("BackupBootSector: %d\n", Fat32VolumeBootSector->BackupBootSector);
221 TRACE("Reserved: 0x%x\n", Fat32VolumeBootSector->Reserved);
222 TRACE("DriveNumber: 0x%x\n", Fat32VolumeBootSector->DriveNumber);
223 TRACE("Reserved1: 0x%x\n", Fat32VolumeBootSector->Reserved1);
224 TRACE("BootSignature: 0x%x\n", Fat32VolumeBootSector->BootSignature);
225 TRACE("VolumeSerialNumber: 0x%x\n", Fat32VolumeBootSector->VolumeSerialNumber);
226 TRACE("VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->VolumeLabel[0], Fat32VolumeBootSector->VolumeLabel[1], Fat32VolumeBootSector->VolumeLabel[2], Fat32VolumeBootSector->VolumeLabel[3], Fat32VolumeBootSector->VolumeLabel[4], Fat32VolumeBootSector->VolumeLabel[5], Fat32VolumeBootSector->VolumeLabel[6], Fat32VolumeBootSector->VolumeLabel[7], Fat32VolumeBootSector->VolumeLabel[8], Fat32VolumeBootSector->VolumeLabel[9], Fat32VolumeBootSector->VolumeLabel[10]);
227 TRACE("FileSystemType: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->FileSystemType[0], Fat32VolumeBootSector->FileSystemType[1], Fat32VolumeBootSector->FileSystemType[2], Fat32VolumeBootSector->FileSystemType[3], Fat32VolumeBootSector->FileSystemType[4], Fat32VolumeBootSector->FileSystemType[5], Fat32VolumeBootSector->FileSystemType[6], Fat32VolumeBootSector->FileSystemType[7]);
228 TRACE("BootSectorMagic: 0x%x\n", Fat32VolumeBootSector->BootSectorMagic);
229 }
230 else
231 {
232 FatSwapFatBootSector(FatVolumeBootSector);
233 TRACE("sizeof(FAT_BOOTSECTOR) = 0x%x.\n", sizeof(FAT_BOOTSECTOR));
234
235 TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", FatVolumeBootSector->JumpBoot[0], FatVolumeBootSector->JumpBoot[1], FatVolumeBootSector->JumpBoot[2]);
236 TRACE("OemName: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->OemName[0], FatVolumeBootSector->OemName[1], FatVolumeBootSector->OemName[2], FatVolumeBootSector->OemName[3], FatVolumeBootSector->OemName[4], FatVolumeBootSector->OemName[5], FatVolumeBootSector->OemName[6], FatVolumeBootSector->OemName[7]);
237 TRACE("BytesPerSector: %d\n", FatVolumeBootSector->BytesPerSector);
238 TRACE("SectorsPerCluster: %d\n", FatVolumeBootSector->SectorsPerCluster);
239 TRACE("ReservedSectors: %d\n", FatVolumeBootSector->ReservedSectors);
240 TRACE("NumberOfFats: %d\n", FatVolumeBootSector->NumberOfFats);
241 TRACE("RootDirEntries: %d\n", FatVolumeBootSector->RootDirEntries);
242 TRACE("TotalSectors: %d\n", FatVolumeBootSector->TotalSectors);
243 TRACE("MediaDescriptor: 0x%x\n", FatVolumeBootSector->MediaDescriptor);
244 TRACE("SectorsPerFat: %d\n", FatVolumeBootSector->SectorsPerFat);
245 TRACE("SectorsPerTrack: %d\n", FatVolumeBootSector->SectorsPerTrack);
246 TRACE("NumberOfHeads: %d\n", FatVolumeBootSector->NumberOfHeads);
247 TRACE("HiddenSectors: %d\n", FatVolumeBootSector->HiddenSectors);
248 TRACE("TotalSectorsBig: %d\n", FatVolumeBootSector->TotalSectorsBig);
249 TRACE("DriveNumber: 0x%x\n", FatVolumeBootSector->DriveNumber);
250 TRACE("Reserved1: 0x%x\n", FatVolumeBootSector->Reserved1);
251 TRACE("BootSignature: 0x%x\n", FatVolumeBootSector->BootSignature);
252 TRACE("VolumeSerialNumber: 0x%x\n", FatVolumeBootSector->VolumeSerialNumber);
253 TRACE("VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", FatVolumeBootSector->VolumeLabel[0], FatVolumeBootSector->VolumeLabel[1], FatVolumeBootSector->VolumeLabel[2], FatVolumeBootSector->VolumeLabel[3], FatVolumeBootSector->VolumeLabel[4], FatVolumeBootSector->VolumeLabel[5], FatVolumeBootSector->VolumeLabel[6], FatVolumeBootSector->VolumeLabel[7], FatVolumeBootSector->VolumeLabel[8], FatVolumeBootSector->VolumeLabel[9], FatVolumeBootSector->VolumeLabel[10]);
254 TRACE("FileSystemType: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->FileSystemType[0], FatVolumeBootSector->FileSystemType[1], FatVolumeBootSector->FileSystemType[2], FatVolumeBootSector->FileSystemType[3], FatVolumeBootSector->FileSystemType[4], FatVolumeBootSector->FileSystemType[5], FatVolumeBootSector->FileSystemType[6], FatVolumeBootSector->FileSystemType[7]);
255 TRACE("BootSectorMagic: 0x%x\n", FatVolumeBootSector->BootSectorMagic);
256 }
257
258 //
259 // Check the boot sector magic
260 //
261 if (! ISFATX(Volume->FatType) && FatVolumeBootSector->BootSectorMagic != 0xaa55)
262 {
263 sprintf(ErrMsg, "Invalid boot sector magic (expected 0xaa55 found 0x%x)",
264 FatVolumeBootSector->BootSectorMagic);
266 return FALSE;
267 }
268
269 //
270 // Check the FAT cluster size
271 // We do not support clusters bigger than 64k
272 //
273 if ((ISFATX(Volume->FatType) && 64 * 1024 < FatXVolumeBootSector->SectorsPerCluster * 512) ||
274 (! ISFATX(Volume->FatType) && 64 * 1024 < FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector))
275 {
276 FileSystemError("This file system has cluster sizes bigger than 64k.\nFreeLoader does not support this.");
277 return FALSE;
278 }
279
280 if (ISFATX(Volume->FatType))
281 {
282 Volume->TotalSectors = PartitionSectorCount;
283 }
284 else
285 {
286 /*
287 * After DOS 4.0, at least one of TotalSectors or TotalSectorsBig will be zero.
288 * In DOS version 3.2 or before, both of these might contain some value,
289 * because, before 3.2, there was no TotalSectorsBig entry. Thus some disks
290 * might have an unexpected value in the field, and we will use TotalSectorsBig
291 * only if TotalSectors equals zero.
292 */
293 C_ASSERT(FIELD_OFFSET(FAT_BOOTSECTOR, TotalSectors) ==
294 FIELD_OFFSET(FAT32_BOOTSECTOR, TotalSectors));
295 C_ASSERT(FIELD_OFFSET(FAT_BOOTSECTOR, TotalSectorsBig) ==
296 FIELD_OFFSET(FAT32_BOOTSECTOR, TotalSectorsBig));
297 Volume->TotalSectors = (FatVolumeBootSector->TotalSectors ? FatVolumeBootSector->TotalSectors
298 : FatVolumeBootSector->TotalSectorsBig);
299 }
300
301 /* Get the sectors per FAT, root directory sector start, and data sector start */
302 if (ISFATX(Volume->FatType))
303 {
304 Volume->BytesPerSector = SECTOR_SIZE;
305 Volume->SectorsPerCluster = SWAPD(FatXVolumeBootSector->SectorsPerCluster);
306 Volume->FatSectorStart = 4096 / Volume->BytesPerSector;
307 Volume->ActiveFatSectorStart = Volume->FatSectorStart;
308 Volume->NumberOfFats = 1; // FatXVolumeBootSector->NumberOfFats;
309 FatSize = (ULONG)(PartitionSectorCount / Volume->SectorsPerCluster *
310 (Volume->FatType == FATX16 ? 2 : 4));
311 Volume->SectorsPerFat = ROUND_UP(FatSize, 4096) / Volume->BytesPerSector;
312
313 Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
314 Volume->RootDirSectors = FatXVolumeBootSector->SectorsPerCluster;
315
316 Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors;
317 }
318 else if (Volume->FatType != FAT32)
319 {
320 Volume->BytesPerSector = FatVolumeBootSector->BytesPerSector;
321 Volume->SectorsPerCluster = FatVolumeBootSector->SectorsPerCluster;
322 Volume->FatSectorStart = FatVolumeBootSector->ReservedSectors;
323 Volume->ActiveFatSectorStart = Volume->FatSectorStart;
324 Volume->NumberOfFats = FatVolumeBootSector->NumberOfFats;
325 Volume->SectorsPerFat = FatVolumeBootSector->SectorsPerFat;
326
327 Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
328 Volume->RootDirSectors = ((FatVolumeBootSector->RootDirEntries * 32) + (Volume->BytesPerSector - 1)) / Volume->BytesPerSector;
329 // Volume->RootDirSectors = (FatVolumeBootSector->RootDirEntries * sizeof(DIRENT) / Volume->BytesPerSector);
330
331 Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors;
332 }
333 else
334 {
335 Volume->BytesPerSector = Fat32VolumeBootSector->BytesPerSector;
336 Volume->SectorsPerCluster = Fat32VolumeBootSector->SectorsPerCluster;
337 Volume->FatSectorStart = Fat32VolumeBootSector->ReservedSectors;
338 Volume->ActiveFatSectorStart =
339 Volume->FatSectorStart + ((Fat32VolumeBootSector->ExtendedFlags & 0x80) ?
340 ((Fat32VolumeBootSector->ExtendedFlags & 0x0f) * Fat32VolumeBootSector->SectorsPerFatBig) : 0);
341 Volume->NumberOfFats = Fat32VolumeBootSector->NumberOfFats;
342 Volume->SectorsPerFat = Fat32VolumeBootSector->SectorsPerFatBig;
343 // Volume->SectorsPerFat = (Fat32VolumeBootSector->SectorsPerFat ? Fat32VolumeBootSector->SectorsPerFat : Fat32VolumeBootSector->SectorsPerFatBig);
344
345 Volume->RootDirStartCluster = Fat32VolumeBootSector->RootDirStartCluster;
346 Volume->DataSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
347
348 //
349 // Check version
350 // we only work with version 0
351 //
352 if (Fat32VolumeBootSector->FileSystemVersion != 0)
353 {
354 FileSystemError("FreeLoader is too old to work with this FAT32 filesystem.\nPlease update FreeLoader.");
355 return FALSE;
356 }
357 }
358 // Volume->NumberOfClusters = FatNumberOfClusters(Volume);
359
360 Volume->FatCacheSize = min(Volume->SectorsPerFat, FAT_MAX_CACHE_SIZE / Volume->BytesPerSector);
361 TRACE("FAT cache is %d sectors, %d bytes\n", Volume->FatCacheSize, Volume->FatCacheSize * Volume->BytesPerSector);
362
363 Volume->FatCache = FrLdrTempAlloc(Volume->FatCacheSize * Volume->BytesPerSector, TAG_FAT_CACHE);
364 if (!Volume->FatCache)
365 {
366 FileSystemError("Cannot allocate memory for FAT cache");
367 return FALSE;
368 }
369
370 Volume->FatCacheIndex = FrLdrTempAlloc(Volume->FatCacheSize * sizeof(*Volume->FatCacheIndex), TAG_FAT_VOLUME);
371 if (!Volume->FatCacheIndex)
372 {
373 FileSystemError("Cannot allocate memory for FAT cache index");
375 return FALSE;
376 }
377
378 // read the beginning of the FAT (or the whole one) to cache
379 if (!FatReadVolumeSectors(Volume, Volume->ActiveFatSectorStart, Volume->FatCacheSize, Volume->FatCache))
380 {
381 FileSystemError("Error when reading FAT cache");
383 FrLdrTempFree(Volume->FatCacheIndex, TAG_FAT_VOLUME);
384 return FALSE;
385 }
386
387 // fill the index with sector numbers
388 for (i = 0; i < Volume->FatCacheSize; i++)
389 {
390 Volume->FatCacheIndex[i] = Volume->ActiveFatSectorStart + i;
391 }
392
393 return TRUE;
394}
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:471
VOID FatSwapFatBootSector(PFAT_BOOTSECTOR Obj)
Definition: fat.c:61
VOID FatSwapFat32BootSector(PFAT32_BOOTSECTOR Obj)
Definition: fat.c:76
#define TAG_FAT_CACHE
Definition: fat.c:34
VOID FatSwapFatXBootSector(PFATX_BOOTSECTOR Obj)
Definition: fat.c:96
ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount)
Definition: fat.c:396
#define FAT_MAX_CACHE_SIZE
Definition: fat.c:36
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define C_ASSERT(e)
Definition: intsafe.h:73
static int ErrMsg(int Error)
Definition: lnktool.cpp:123
#define sprintf
Definition: sprintf.c:45
USHORT BootSectorMagic
Definition: fsutil.c:98
CHAR FileSystemType[8]
Definition: fsutil.c:94
UCHAR Reserved[12]
Definition: fsutil.c:88
UCHAR MediaDescriptor
Definition: fsutil.c:76
ULONG HiddenSectors
Definition: fsutil.c:80
UCHAR NumberOfFats
Definition: fsutil.c:73
ULONG VolumeSerialNumber
Definition: fsutil.c:92
CHAR VolumeLabel[11]
Definition: fsutil.c:93
USHORT ExtendedFlags
Definition: fsutil.c:83
ULONG SectorsPerFatBig
Definition: fsutil.c:82
UCHAR JumpBoot[3]
Definition: fsutil.c:68
CHAR OemName[8]
Definition: fsutil.c:69
USHORT NumberOfHeads
Definition: fsutil.c:79
USHORT ReservedSectors
Definition: fsutil.c:72
USHORT RootDirEntries
Definition: fsutil.c:74
USHORT FsInfo
Definition: fsutil.c:86
USHORT BytesPerSector
Definition: fsutil.c:70
USHORT FileSystemVersion
Definition: fsutil.c:84
ULONG TotalSectorsBig
Definition: fsutil.c:81
UCHAR BootSignature
Definition: fsutil.c:91
ULONG RootDirStartCluster
Definition: fsutil.c:85
UCHAR DriveNumber
Definition: fsutil.c:89
UCHAR SectorsPerCluster
Definition: fsutil.c:71
USHORT SectorsPerFat
Definition: fsutil.c:77
USHORT SectorsPerTrack
Definition: fsutil.c:78
UCHAR Reserved1
Definition: fsutil.c:90
USHORT BackupBootSector
Definition: fsutil.c:87
USHORT TotalSectors
Definition: fsutil.c:75
ULONG VolumeSerialNumber
Definition: fat.h:91
ULONG Unknown
Definition: fat.h:94
USHORT NumberOfFats
Definition: fat.h:93
ULONG TotalSectorsBig
Definition: fsutil.c:51
UCHAR JumpBoot[3]
Definition: fsutil.c:38
USHORT SectorsPerTrack
Definition: fsutil.c:48
CHAR VolumeLabel[11]
Definition: fsutil.c:56
USHORT NumberOfHeads
Definition: fsutil.c:49
CHAR OemName[8]
Definition: fsutil.c:39
ULONG HiddenSectors
Definition: fsutil.c:50
CHAR FileSystemType[8]
Definition: fsutil.c:57
ULONG VolumeSerialNumber
Definition: fsutil.c:55
UCHAR MediaDescriptor
Definition: fsutil.c:46
USHORT BootSectorMagic
Definition: fsutil.c:61
UCHAR Reserved1
Definition: fsutil.c:53
UCHAR DriveNumber
Definition: fsutil.c:52
UCHAR BootSignature
Definition: fsutil.c:54
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by FatMount().

◆ FatParseShortFileName()

void FatParseShortFileName ( PCHAR  Buffer,
PDIRENTRY  DirEntry 
)

Definition at line 933 of file fat.c.

934{
935 ULONG Idx;
936
937 Idx = 0;
939
940 //
941 // Fixup first character
942 //
943 if (DirEntry->FileName[0] == 0x05)
944 {
945 DirEntry->FileName[0] = 0xE5;
946 }
947
948 //
949 // Get the file name
950 //
951 while (Idx < 8)
952 {
953 if (DirEntry->FileName[Idx] == ' ')
954 {
955 break;
956 }
957
958 Buffer[Idx] = DirEntry->FileName[Idx];
959 Idx++;
960 }
961
962 //
963 // Get extension
964 //
965 if ((DirEntry->FileName[8] != ' '))
966 {
967 Buffer[Idx++] = '.';
968 Buffer[Idx++] = (DirEntry->FileName[8] == ' ') ? '\0' : DirEntry->FileName[8];
969 Buffer[Idx++] = (DirEntry->FileName[9] == ' ') ? '\0' : DirEntry->FileName[9];
970 Buffer[Idx++] = (DirEntry->FileName[10] == ' ') ? '\0' : DirEntry->FileName[10];
971 }
972
973 //TRACE("FatParseShortFileName() ShortName = %s\n", Buffer);
974}

Referenced by FatSearchDirectoryBufferForFile().

◆ FatRead()

ARC_STATUS FatRead ( ULONG  FileId,
VOID Buffer,
ULONG  N,
ULONG Count 
)

Definition at line 1534 of file fat.c.

1535{
1538
1539 /* Call old read method */
1541 if (Success)
1542 return ESUCCESS;
1543 else
1544 return EIO;
1545}
#define N
Definition: crc32.c:57
#define EIO
Definition: acclib.h:81
static BOOLEAN FatReadFile(PFAT_FILE_INFO FatFileInfo, ULONG BytesToRead, ULONG *BytesRead, PVOID Buffer)
Definition: fat.c:1263
@ Success
Definition: eventcreate.c:712

◆ FatReadAdjacentClusters()

static BOOLEAN FatReadAdjacentClusters ( PFAT_VOLUME_INFO  Volume,
UINT32  StartClusterNumber,
UINT32  MaxClusters,
PVOID  Buffer,
PUINT32  ClustersRead,
PUINT32  LastClusterNumber 
)
static

Definition at line 1144 of file fat.c.

1151{
1152 UINT32 NextClusterNumber;
1153 UINT32 ClustersToRead = 1;
1154 UINT32 PrevClusterNumber = StartClusterNumber;
1155 UINT32 ClusterStartSector = ((PrevClusterNumber - 2) * Volume->SectorsPerCluster) + Volume->DataSectorStart;
1156
1157 *ClustersRead = 0;
1158 *LastClusterNumber = 0;
1159
1160 if (!FatGetFatEntry(Volume, StartClusterNumber, &NextClusterNumber))
1161 {
1162 return FALSE;
1163 }
1164
1165 // getting the number of adjacent clusters
1166 while (!FAT_IS_END_CLUSTER(NextClusterNumber) && ClustersToRead < MaxClusters && (NextClusterNumber == PrevClusterNumber + 1))
1167 {
1168 ClustersToRead++;
1169 PrevClusterNumber = NextClusterNumber;
1170 if (!FatGetFatEntry(Volume, PrevClusterNumber, &NextClusterNumber))
1171 {
1172 return FALSE;
1173 }
1174 }
1175
1176 if (!FatReadVolumeSectors(Volume, ClusterStartSector, ClustersToRead * Volume->SectorsPerCluster, Buffer))
1177 {
1178 return FALSE;
1179 }
1180
1181 *ClustersRead = ClustersToRead;
1182 *LastClusterNumber = NextClusterNumber;
1183
1184 return !FAT_IS_END_CLUSTER(NextClusterNumber) && ClustersToRead < MaxClusters;
1185}

Referenced by FatReadClusterChain().

◆ FatReadClusterChain()

static BOOLEAN FatReadClusterChain ( PFAT_VOLUME_INFO  Volume,
UINT32  StartClusterNumber,
UINT32  NumberOfClusters,
PVOID  Buffer,
PUINT32  LastClusterNumber 
)
static

Definition at line 1192 of file fat.c.

1193{
1194 UINT32 ClustersRead, NextClusterNumber, ClustersLeft = NumberOfClusters;
1195
1196 TRACE("FatReadClusterChain() StartClusterNumber = %d NumberOfClusters = %d Buffer = 0x%x\n", StartClusterNumber, NumberOfClusters, Buffer);
1197
1198 ASSERT(NumberOfClusters > 0);
1199
1200 while (FatReadAdjacentClusters(Volume, StartClusterNumber, ClustersLeft, Buffer, &ClustersRead, &NextClusterNumber))
1201 {
1202 ClustersLeft -= ClustersRead;
1203 Buffer = (PVOID)((ULONG_PTR)Buffer + (ClustersRead * Volume->SectorsPerCluster * Volume->BytesPerSector));
1204 StartClusterNumber = NextClusterNumber;
1205 }
1206
1207 if (LastClusterNumber)
1208 {
1209 *LastClusterNumber = NextClusterNumber;
1210 }
1211
1212 return (ClustersRead > 0);
1213}
static BOOLEAN FatReadAdjacentClusters(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 MaxClusters, PVOID Buffer, PUINT32 ClustersRead, PUINT32 LastClusterNumber)
Definition: fat.c:1144
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by FatBufferDirectory(), and FatReadFile().

◆ FatReadFile()

static BOOLEAN FatReadFile ( PFAT_FILE_INFO  FatFileInfo,
ULONG  BytesToRead,
ULONG BytesRead,
PVOID  Buffer 
)
static

Definition at line 1263 of file fat.c.

1264{
1265 PFAT_VOLUME_INFO Volume = FatFileInfo->Volume;
1266 UINT32 NextClusterNumber, BytesPerCluster;
1267
1268 TRACE("FatReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead, Buffer);
1269
1270 if (BytesRead != NULL)
1271 {
1272 *BytesRead = 0;
1273 }
1274
1275 //
1276 // If the user is trying to read past the end of
1277 // the file then return success with BytesRead == 0.
1278 //
1279 if (FatFileInfo->FilePointer >= FatFileInfo->FileSize)
1280 {
1281 return TRUE;
1282 }
1283
1284 //
1285 // If the user is trying to read more than there is to read
1286 // then adjust the amount to read.
1287 //
1288 if ((FatFileInfo->FilePointer + BytesToRead) > FatFileInfo->FileSize)
1289 {
1290 BytesToRead = (FatFileInfo->FileSize - FatFileInfo->FilePointer);
1291 }
1292
1293 //
1294 // Ok, now we have to perform at most 3 calculations
1295 // I'll draw you a picture (using nifty ASCII art):
1296 //
1297 // CurrentFilePointer -+
1298 // |
1299 // +----------------+
1300 // |
1301 // +-----------+-----------+-----------+-----------+
1302 // | Cluster 1 | Cluster 2 | Cluster 3 | Cluster 4 |
1303 // +-----------+-----------+-----------+-----------+
1304 // | |
1305 // +---------------+--------------------+
1306 // |
1307 // BytesToRead -------+
1308 //
1309 // 1 - The first calculation (and read) will align
1310 // the file pointer with the next cluster.
1311 // boundary (if we are supposed to read that much)
1312 // 2 - The next calculation (and read) will read
1313 // in all the full clusters that the requested
1314 // amount of data would cover (in this case
1315 // clusters 2 & 3).
1316 // 3 - The last calculation (and read) would read
1317 // in the remainder of the data requested out of
1318 // the last cluster.
1319 //
1320
1321 BytesPerCluster = Volume->SectorsPerCluster * Volume->BytesPerSector;
1322
1323 //
1324 // Only do the first read if we
1325 // aren't aligned on a cluster boundary
1326 //
1327 if (FatFileInfo->FilePointer % BytesPerCluster)
1328 {
1329 //
1330 // Do the math for our first read
1331 //
1332 UINT32 OffsetInCluster = FatFileInfo->FilePointer % BytesPerCluster;
1333 UINT32 LengthInCluster = min(BytesToRead, BytesPerCluster - OffsetInCluster);
1334
1335 ASSERT(LengthInCluster <= BytesPerCluster && LengthInCluster > 0);
1336
1337 //
1338 // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
1339 //
1340 if (!FatReadPartialCluster(Volume, FatFileInfo->CurrentCluster, OffsetInCluster, LengthInCluster, Buffer))
1341 {
1342 return FALSE;
1343 }
1344 if (BytesRead != NULL)
1345 {
1346 *BytesRead += LengthInCluster;
1347 }
1348 BytesToRead -= LengthInCluster;
1349 FatFileInfo->FilePointer += LengthInCluster;
1350 Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInCluster);
1351
1352 // get the next cluster if needed
1353 if ((LengthInCluster + OffsetInCluster) == BytesPerCluster)
1354 {
1355 if (!FatGetFatEntry(Volume, FatFileInfo->CurrentCluster, &NextClusterNumber))
1356 {
1357 return FALSE;
1358 }
1359
1360 FatFileInfo->CurrentCluster = NextClusterNumber;
1361 TRACE("FatReadFile() FatFileInfo->CurrentCluster = 0x%x\n", FatFileInfo->CurrentCluster);
1362 }
1363 }
1364
1365 //
1366 // Do the math for our second read (if any data left)
1367 //
1368 if (BytesToRead > 0)
1369 {
1370 //
1371 // Determine how many full clusters we need to read
1372 //
1373 UINT32 NumberOfClusters = BytesToRead / BytesPerCluster;
1374
1375 TRACE("Going to read: %u clusters\n", NumberOfClusters);
1376
1377 if (NumberOfClusters > 0)
1378 {
1379 UINT32 BytesReadHere = NumberOfClusters * BytesPerCluster;
1380
1382
1383 if (!FatReadClusterChain(Volume, FatFileInfo->CurrentCluster, NumberOfClusters, Buffer, &NextClusterNumber))
1384 {
1385 return FALSE;
1386 }
1387
1388 if (BytesRead != NULL)
1389 {
1390 *BytesRead += BytesReadHere;
1391 }
1392 BytesToRead -= BytesReadHere;
1393 Buffer = (PVOID)((ULONG_PTR)Buffer + BytesReadHere);
1394
1395 ASSERT(!FAT_IS_END_CLUSTER(NextClusterNumber) || BytesToRead == 0);
1396
1397 FatFileInfo->FilePointer += BytesReadHere;
1398 FatFileInfo->CurrentCluster = NextClusterNumber;
1399 TRACE("FatReadFile() FatFileInfo->CurrentCluster = 0x%x\n", FatFileInfo->CurrentCluster);
1400 }
1401 }
1402
1403 //
1404 // Do the math for our third read (if any data left)
1405 //
1406 if (BytesToRead > 0)
1407 {
1409
1410 //
1411 // Now do the read and update BytesRead & FilePointer
1412 //
1413 if (!FatReadPartialCluster(Volume, FatFileInfo->CurrentCluster, 0, BytesToRead, Buffer))
1414 {
1415 return FALSE;
1416 }
1417 if (BytesRead != NULL)
1418 {
1419 *BytesRead += BytesToRead;
1420 }
1421 FatFileInfo->FilePointer += BytesToRead;
1422 }
1423
1424 return TRUE;
1425}
BOOLEAN FatReadPartialCluster(PFAT_VOLUME_INFO Volume, ULONG ClusterNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
Definition: fat.c:1219
ULONG FileSize
Definition: fat.h:168
PFAT_VOLUME_INFO Volume
Definition: fat.h:167
ULONG FilePointer
Definition: fat.h:169
ULONG CurrentCluster
Definition: fat.h:170
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870

Referenced by FatRead().

◆ FatReadPartialCluster()

BOOLEAN FatReadPartialCluster ( PFAT_VOLUME_INFO  Volume,
ULONG  ClusterNumber,
ULONG  StartingOffset,
ULONG  Length,
PVOID  Buffer 
)

Definition at line 1219 of file fat.c.

1220{
1221 ULONG ClusterStartSector;
1222 ULONG SectorOffset, ReadSize, SectorCount;
1225
1226 //TRACE("FatReadPartialCluster() ClusterNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", ClusterNumber, StartingOffset, Length, Buffer);
1227
1228 ClusterStartSector = ((ClusterNumber - 2) * Volume->SectorsPerCluster) + Volume->DataSectorStart;
1229
1230 // This is the offset of the data in sectors
1231 SectorOffset = (StartingOffset / Volume->BytesPerSector);
1232 StartingOffset %= Volume->BytesPerSector;
1233
1234 // Calculate how many sectors we need to read
1235 SectorCount = (StartingOffset + Length + Volume->BytesPerSector - 1) / Volume->BytesPerSector;
1236
1237 // Calculate rounded up read size
1238 ReadSize = SectorCount * Volume->BytesPerSector;
1239
1241 if (!ReadBuffer)
1242 {
1243 return FALSE;
1244 }
1245
1246 if (FatReadVolumeSectors(Volume, ClusterStartSector + SectorOffset, SectorCount, ReadBuffer))
1247 {
1249 Success = TRUE;
1250 }
1251
1253
1254 return Success;
1255}
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
#define SectorOffset(L)
Definition: cdprocs.h:1622
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

Referenced by FatReadFile().

◆ FatReadVolumeSectors()

BOOLEAN FatReadVolumeSectors ( PFAT_VOLUME_INFO  Volume,
ULONG  SectorNumber,
ULONG  SectorCount,
PVOID  Buffer 
)

Definition at line 1427 of file fat.c.

1428{
1430 ULONG Count;
1432
1433 //TRACE("FatReadVolumeSectors(): SectorNumber %d, SectorCount %d, Buffer %p\n",
1434 // SectorNumber, SectorCount, Buffer);
1435
1436 //
1437 // Seek to right position
1438 //
1439 Position.QuadPart = (ULONGLONG)SectorNumber * Volume->BytesPerSector;
1440 Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
1441 if (Status != ESUCCESS)
1442 {
1443 TRACE("FatReadVolumeSectors() Failed to seek\n");
1444 return FALSE;
1445 }
1446
1447 //
1448 // Read data
1449 //
1450 Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * Volume->BytesPerSector, &Count);
1451 if (Status != ESUCCESS || Count != SectorCount * Volume->BytesPerSector)
1452 {
1453 TRACE("FatReadVolumeSectors() Failed to read\n");
1454 return FALSE;
1455 }
1456
1457 // Return success
1458 return TRUE;
1459}

Referenced by FatBufferDirectory(), FatGetFatSector(), FatOpenVolume(), FatReadAdjacentClusters(), and FatReadPartialCluster().

◆ FatSearchDirectoryBufferForFile()

static BOOLEAN FatSearchDirectoryBufferForFile ( PFAT_VOLUME_INFO  Volume,
PVOID  DirectoryBuffer,
ULONG  DirectorySize,
PCHAR  FileName,
PFAT_FILE_INFO  FatFileInfoPointer 
)
static

Definition at line 549 of file fat.c.

550{
551 ULONG EntryCount;
552 ULONG CurrentEntry;
553 CHAR LfnNameBuffer[265];
554 CHAR ShortNameBuffer[20];
555 ULONG StartCluster;
556 DIRENTRY OurDirEntry;
557 LFN_DIRENTRY OurLfnDirEntry;
558 PDIRENTRY DirEntry = &OurDirEntry;
559 PLFN_DIRENTRY LfnDirEntry = &OurLfnDirEntry;
560
561 EntryCount = DirectorySize / sizeof(DIRENTRY);
562
563 TRACE("FatSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName);
564
565 RtlZeroMemory(ShortNameBuffer, 13 * sizeof(CHAR));
566 RtlZeroMemory(LfnNameBuffer, 261 * sizeof(CHAR));
567
568 for (CurrentEntry=0; CurrentEntry<EntryCount; CurrentEntry++, DirectoryBuffer = ((PDIRENTRY)DirectoryBuffer)+1)
569 {
570 OurLfnDirEntry = *((PLFN_DIRENTRY) DirectoryBuffer);
571 FatSwapLFNDirEntry(LfnDirEntry);
572 OurDirEntry = *((PDIRENTRY) DirectoryBuffer);
574
575 //TRACE("Dumping directory entry %d:\n", CurrentEntry);
576 //DbgDumpBuffer(DPRINT_FILESYSTEM, DirEntry, sizeof(DIRENTRY));
577
578 //
579 // Check if this is the last file in the directory
580 // If DirEntry[0] == 0x00 then that means all the
581 // entries after this one are unused. If this is the
582 // last entry then we didn't find the file in this directory.
583 //
584 if (DirEntry->FileName[0] == '\0')
585 {
586 return FALSE;
587 }
588
589 //
590 // Check if this is a deleted entry or not
591 //
592 if (DirEntry->FileName[0] == '\xE5')
593 {
594 RtlZeroMemory(ShortNameBuffer, 13 * sizeof(CHAR));
595 RtlZeroMemory(LfnNameBuffer, 261 * sizeof(CHAR));
596 continue;
597 }
598
599 //
600 // Check if this is a LFN entry
601 // If so it needs special handling
602 //
603 if (DirEntry->Attr == FAT_ATTR_LONG_NAME)
604 {
605 //
606 // Check to see if this is a deleted LFN entry, if so continue
607 //
608 if (LfnDirEntry->SequenceNumber & 0x80)
609 {
610 continue;
611 }
612
613 //
614 // Mask off high two bits of sequence number
615 // and make the sequence number zero-based
616 //
617 LfnDirEntry->SequenceNumber &= 0x3F;
618 LfnDirEntry->SequenceNumber--;
619
620 //
621 // Get all 13 LFN entry characters
622 //
623 if (LfnDirEntry->Name0_4[0] != 0xFFFF)
624 {
625 LfnNameBuffer[0 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[0];
626 }
627 if (LfnDirEntry->Name0_4[1] != 0xFFFF)
628 {
629 LfnNameBuffer[1 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[1];
630 }
631 if (LfnDirEntry->Name0_4[2] != 0xFFFF)
632 {
633 LfnNameBuffer[2 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[2];
634 }
635 if (LfnDirEntry->Name0_4[3] != 0xFFFF)
636 {
637 LfnNameBuffer[3 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[3];
638 }
639 if (LfnDirEntry->Name0_4[4] != 0xFFFF)
640 {
641 LfnNameBuffer[4 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[4];
642 }
643 if (LfnDirEntry->Name5_10[0] != 0xFFFF)
644 {
645 LfnNameBuffer[5 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[0];
646 }
647 if (LfnDirEntry->Name5_10[1] != 0xFFFF)
648 {
649 LfnNameBuffer[6 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[1];
650 }
651 if (LfnDirEntry->Name5_10[2] != 0xFFFF)
652 {
653 LfnNameBuffer[7 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[2];
654 }
655 if (LfnDirEntry->Name5_10[3] != 0xFFFF)
656 {
657 LfnNameBuffer[8 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[3];
658 }
659 if (LfnDirEntry->Name5_10[4] != 0xFFFF)
660 {
661 LfnNameBuffer[9 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[4];
662 }
663 if (LfnDirEntry->Name5_10[5] != 0xFFFF)
664 {
665 LfnNameBuffer[10 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[5];
666 }
667 if (LfnDirEntry->Name11_12[0] != 0xFFFF)
668 {
669 LfnNameBuffer[11 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name11_12[0];
670 }
671 if (LfnDirEntry->Name11_12[1] != 0xFFFF)
672 {
673 LfnNameBuffer[12 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name11_12[1];
674 }
675
676 //TRACE("Dumping long name buffer:\n");
677 //DbgDumpBuffer(DPRINT_FILESYSTEM, LfnNameBuffer, 260);
678
679 continue;
680 }
681
682 //
683 // Check for the volume label attribute
684 // and skip over this entry if found
685 //
686 if (DirEntry->Attr & FAT_ATTR_VOLUMENAME)
687 {
688 RtlZeroMemory(ShortNameBuffer, 13 * sizeof(UCHAR));
689 RtlZeroMemory(LfnNameBuffer, 261 * sizeof(UCHAR));
690 continue;
691 }
692
693 //
694 // If we get here then we've found a short file name
695 // entry and LfnNameBuffer contains the long file
696 // name or zeroes. All we have to do now is see if the
697 // file name matches either the short or long file name
698 // and fill in the FAT_FILE_INFO structure if it does
699 // or zero our buffers and continue looking.
700 //
701
702 //
703 // Get short file name
704 //
705 FatParseShortFileName(ShortNameBuffer, DirEntry);
706
707 //TRACE("Entry: %d LFN = %s\n", CurrentEntry, LfnNameBuffer);
708 //TRACE("Entry: %d DOS name = %s\n", CurrentEntry, ShortNameBuffer);
709
710 //
711 // See if the file name matches either the short or long name
712 //
713 if ((_stricmp(FileName, LfnNameBuffer) == 0) || (_stricmp(FileName, ShortNameBuffer) == 0))
714 {
715 //
716 // We found the entry, now fill in the FAT_FILE_INFO struct
717 //
718 FatFileInfoPointer->Attributes = DirEntry->Attr;
719 FatFileInfoPointer->FileSize = DirEntry->Size;
720 FatFileInfoPointer->FilePointer = 0;
721 StartCluster = ((ULONG)DirEntry->ClusterHigh << 16) + DirEntry->ClusterLow;
722 FatFileInfoPointer->CurrentCluster = StartCluster;
723 FatFileInfoPointer->StartCluster = StartCluster;
724
725 TRACE("MSDOS Directory Entry:\n");
726 TRACE("FileName[11] = %c%c%c%c%c%c%c%c%c%c%c\n",
727 DirEntry->FileName[0], DirEntry->FileName[1], DirEntry->FileName[2], DirEntry->FileName[3], DirEntry->FileName[4],
728 DirEntry->FileName[5], DirEntry->FileName[6], DirEntry->FileName[7], DirEntry->FileName[8], DirEntry->FileName[9], DirEntry->FileName[10]);
729 TRACE("Attr = 0x%x\n", DirEntry->Attr);
730 TRACE("ReservedNT = 0x%x\n", DirEntry->ReservedNT);
731 TRACE("TimeInTenths = %d\n", DirEntry->TimeInTenths);
732 TRACE("CreateTime = %d\n", DirEntry->CreateTime);
733 TRACE("CreateDate = %d\n", DirEntry->CreateDate);
734 TRACE("LastAccessDate = %d\n", DirEntry->LastAccessDate);
735 TRACE("ClusterHigh = 0x%x\n", DirEntry->ClusterHigh);
736 TRACE("Time = %d\n", DirEntry->Time);
737 TRACE("Date = %d\n", DirEntry->Date);
738 TRACE("ClusterLow = 0x%x\n", DirEntry->ClusterLow);
739 TRACE("Size = %d\n", DirEntry->Size);
740 TRACE("StartCluster = 0x%x\n", StartCluster);
741
742 return TRUE;
743 }
744
745 //
746 // Nope, no match - zero buffers and continue looking
747 //
748 RtlZeroMemory(ShortNameBuffer, 13 * sizeof(UCHAR));
749 RtlZeroMemory(LfnNameBuffer, 261 * sizeof(UCHAR));
750 }
751
752 return FALSE;
753}
#define FAT_ATTR_LONG_NAME
Definition: fat.h:153
struct DIRENTRY * PDIRENTRY
#define FAT_ATTR_VOLUMENAME
Definition: fat.h:150
struct LFN_DIRENTRY * PLFN_DIRENTRY
VOID FatSwapDirEntry(PDIRENTRY Obj)
Definition: fat.c:103
VOID FatSwapLFNDirEntry(PLFN_DIRENTRY Obj)
Definition: fat.c:115
void FatParseShortFileName(PCHAR Buffer, PDIRENTRY DirEntry)
Definition: fat.c:933
#define _stricmp
Definition: cat.c:22
Definition: fat.h:103
WCHAR Name11_12[2]
Definition: fat.h:127
UCHAR SequenceNumber
Definition: fat.h:120
WCHAR Name5_10[6]
Definition: fat.h:125
WCHAR Name0_4[5]
Definition: fat.h:121

Referenced by FatLookupFile().

◆ FatSeek()

ARC_STATUS FatSeek ( ULONG  FileId,
LARGE_INTEGER Position,
SEEKMODE  SeekMode 
)

Definition at line 1547 of file fat.c.

1548{
1551 LARGE_INTEGER NewPosition = *Position;
1552
1553 switch (SeekMode)
1554 {
1555 case SeekAbsolute:
1556 break;
1557 case SeekRelative:
1558 NewPosition.QuadPart += (ULONGLONG)FileHandle->FilePointer;
1559 break;
1560 default:
1561 ASSERT(FALSE);
1562 return EINVAL;
1563 }
1564
1565 if (NewPosition.HighPart != 0)
1566 return EINVAL;
1567 if (NewPosition.LowPart >= FileHandle->FileSize)
1568 return EINVAL;
1569
1570 TRACE("FatSeek() NewPosition = %u, OldPointer = %u, SeekMode = %d\n", NewPosition.LowPart, FileHandle->FilePointer, SeekMode);
1571
1572 {
1573 UINT32 OldClusterIdx = FileHandle->FilePointer / (Volume->SectorsPerCluster * Volume->BytesPerSector);
1574 UINT32 NewClusterIdx = NewPosition.LowPart / (Volume->SectorsPerCluster * Volume->BytesPerSector);
1575
1576 TRACE("FatSeek() OldClusterIdx: %u, NewClusterIdx: %u\n", OldClusterIdx, NewClusterIdx);
1577
1578 if (NewClusterIdx != OldClusterIdx)
1579 {
1580 UINT32 CurrentClusterIdx, ClusterNumber;
1581
1582 if (NewClusterIdx > OldClusterIdx)
1583 {
1584 CurrentClusterIdx = OldClusterIdx;
1585 ClusterNumber = FileHandle->CurrentCluster;
1586 }
1587 else
1588 {
1589 CurrentClusterIdx = 0;
1590 ClusterNumber = FileHandle->StartCluster;
1591 }
1592
1593 for (; CurrentClusterIdx < NewClusterIdx; CurrentClusterIdx++)
1594 {
1595 if (!FatGetFatEntry(Volume, ClusterNumber, &ClusterNumber))
1596 {
1597 return EIO;
1598 }
1599 }
1600 FileHandle->CurrentCluster = ClusterNumber;
1601 }
1602 }
1603
1604 FileHandle->FilePointer = NewPosition.LowPart;
1605
1606 return ESUCCESS;
1607}
#define EINVAL
Definition: acclib.h:90
@ SeekRelative
Definition: arc.h:60
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

◆ FatSwapDirEntry()

VOID FatSwapDirEntry ( PDIRENTRY  Obj)

Definition at line 103 of file fat.c.

104{
105 SW(Obj, CreateTime);
106 SW(Obj, CreateDate);
107 SW(Obj, LastAccessDate);
108 SW(Obj, ClusterHigh);
109 SW(Obj, Time);
110 SW(Obj, Date);
111 SW(Obj, ClusterLow);
112 SD(Obj, Size);
113}
#define SW(Object, Field)
Definition: bytesex.h:11
#define SD(Object, Field)
Definition: bytesex.h:10
static PLARGE_INTEGER Time
Definition: time.c:105
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by FatSearchDirectoryBufferForFile().

◆ FatSwapFat32BootSector()

VOID FatSwapFat32BootSector ( PFAT32_BOOTSECTOR  Obj)

Definition at line 76 of file fat.c.

77{
78 SW(Obj, BytesPerSector);
79 SW(Obj, ReservedSectors);
80 SW(Obj, RootDirEntries);
81 SW(Obj, TotalSectors);
82 SW(Obj, SectorsPerFat);
84 SD(Obj, HiddenSectors);
85 SD(Obj, TotalSectorsBig);
86 SD(Obj, SectorsPerFatBig);
87 SW(Obj, ExtendedFlags);
88 SW(Obj, FileSystemVersion);
89 SD(Obj, RootDirStartCluster);
90 SW(Obj, FsInfo);
92 SD(Obj, VolumeSerialNumber);
93 SW(Obj, BootSectorMagic);
94}
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
Definition: install.c:61
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
Definition: iofuncs.h:2072

Referenced by FatOpenVolume().

◆ FatSwapFatBootSector()

VOID FatSwapFatBootSector ( PFAT_BOOTSECTOR  Obj)

Definition at line 61 of file fat.c.

62{
63 SW(Obj, BytesPerSector);
64 SW(Obj, ReservedSectors);
65 SW(Obj, RootDirEntries);
66 SW(Obj, TotalSectors);
67 SW(Obj, SectorsPerFat);
70 SD(Obj, HiddenSectors);
71 SD(Obj, TotalSectorsBig);
72 SD(Obj, VolumeSerialNumber);
73 SW(Obj, BootSectorMagic);
74}
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2071

Referenced by FatOpenVolume().

◆ FatSwapFatXBootSector()

VOID FatSwapFatXBootSector ( PFATX_BOOTSECTOR  Obj)

Definition at line 96 of file fat.c.

97{
98 SD(Obj, VolumeSerialNumber);
99 SD(Obj, SectorsPerCluster);
100 SW(Obj, NumberOfFats);
101}

Referenced by FatOpenVolume().

◆ FatSwapFatXDirEntry()

VOID FatSwapFatXDirEntry ( PFATX_DIRENTRY  Obj)

Definition at line 127 of file fat.c.

128{
129 SD(Obj, StartCluster);
130 SD(Obj, Size);
131 SW(Obj, Time);
132 SW(Obj, Date);
133 SW(Obj, CreateTime);
134 SW(Obj, CreateDate);
135 SW(Obj, LastAccessTime);
136 SW(Obj, LastAccessDate);
137}

Referenced by FatXSearchDirectoryBufferForFile().

◆ FatSwapLFNDirEntry()

VOID FatSwapLFNDirEntry ( PLFN_DIRENTRY  Obj)

Definition at line 115 of file fat.c.

116{
117 int i;
118 SW(Obj, StartCluster);
119 for(i = 0; i < 5; i++)
120 Obj->Name0_4[i] = SWAPW(Obj->Name0_4[i]);
121 for(i = 0; i < 6; i++)
122 Obj->Name5_10[i] = SWAPW(Obj->Name5_10[i]);
123 for(i = 0; i < 2; i++)
124 Obj->Name11_12[i] = SWAPW(Obj->Name11_12[i]);
125}

Referenced by FatSearchDirectoryBufferForFile().

◆ FatXSearchDirectoryBufferForFile()

static BOOLEAN FatXSearchDirectoryBufferForFile ( PFAT_VOLUME_INFO  Volume,
PVOID  DirectoryBuffer,
ULONG  DirectorySize,
PCHAR  FileName,
PFAT_FILE_INFO  FatFileInfoPointer 
)
static

Definition at line 755 of file fat.c.

756{
757 ULONG EntryCount;
758 ULONG CurrentEntry;
760 FATX_DIRENTRY OurDirEntry;
761 PFATX_DIRENTRY DirEntry = &OurDirEntry;
762
763 EntryCount = DirectorySize / sizeof(FATX_DIRENTRY);
764
765 TRACE("FatXSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName);
766
768
769 for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++, DirectoryBuffer = ((PFATX_DIRENTRY)DirectoryBuffer)+1)
770 {
771 OurDirEntry = *(PFATX_DIRENTRY) DirectoryBuffer;
772 FatSwapFatXDirEntry(&OurDirEntry);
773 if (0xff == DirEntry->FileNameSize)
774 {
775 break;
776 }
777 if (0xe5 == DirEntry->FileNameSize)
778 {
779 continue;
780 }
781 if ((FileNameLen == DirEntry->FileNameSize) &&
782 (_strnicmp(FileName, DirEntry->FileName, FileNameLen) == 0))
783 {
784 /*
785 * We found the entry, now fill in the FAT_FILE_INFO struct
786 */
787 FatFileInfoPointer->Attributes = DirEntry->Attr;
788 FatFileInfoPointer->FileSize = DirEntry->Size;
789 FatFileInfoPointer->FilePointer = 0;
790 FatFileInfoPointer->CurrentCluster = DirEntry->StartCluster;
791 FatFileInfoPointer->StartCluster = DirEntry->StartCluster;
792
793 TRACE("FATX Directory Entry:\n");
794 TRACE("FileNameSize = %d\n", DirEntry->FileNameSize);
795 TRACE("Attr = 0x%x\n", DirEntry->Attr);
796 TRACE("StartCluster = 0x%x\n", DirEntry->StartCluster);
797 TRACE("Size = %d\n", DirEntry->Size);
798 TRACE("Time = %d\n", DirEntry->Time);
799 TRACE("Date = %d\n", DirEntry->Date);
800 TRACE("CreateTime = %d\n", DirEntry->CreateTime);
801 TRACE("CreateDate = %d\n", DirEntry->CreateDate);
802 TRACE("LastAccessTime = %d\n", DirEntry->LastAccessTime);
803 TRACE("LastAccessDate = %d\n", DirEntry->LastAccessDate);
804
805 return TRUE;
806 }
807 }
808
809 return FALSE;
810}
struct FATX_DIRENTRY * PFATX_DIRENTRY
VOID FatSwapFatXDirEntry(PFATX_DIRENTRY Obj)
Definition: fat.c:127
Dirent FileNameLen
Definition: dirsup.c:506
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by FatLookupFile().

Variable Documentation

◆ DirectoryBufferListHead

LIST_ENTRY DirectoryBufferListHead = {&DirectoryBufferListHead, &DirectoryBufferListHead}

Definition at line 460 of file fat.c.

Referenced by FatBufferDirectory().

◆ FatFuncTable

const DEVVTBL FatFuncTable
Initial value:
=
{
L"fastfat",
}
ARC_STATUS FatOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fat.c:1492
ARC_STATUS FatSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fat.c:1547
ARC_STATUS FatRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fat.c:1534
ARC_STATUS FatGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fat.c:1470
ARC_STATUS FatClose(ULONG FileId)
Definition: fat.c:1461
#define L(x)
Definition: resources.c:13

Definition at line 1625 of file fat.c.

Referenced by FatMount().

◆ FatVolumes

Definition at line 59 of file fat.c.

Referenced by FatGetVolumeSize(), FatMount(), and FatOpen().

◆ FatXFuncTable

const DEVVTBL FatXFuncTable
Initial value:

Definition at line 1635 of file fat.c.

Referenced by FatMount().