ReactOS  0.4.15-dev-1068-g467feb9
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)
 
BOOLEAN FatSearchDirectoryBufferForFile (PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG EntryCount, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
 
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)
 
BOOLEAN FatOpenVolume (PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount)
 
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. More...
 
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)
 
const DEVVTBLFatMount (ULONG DeviceId)
 

Variables

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

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 FAT12
Definition: fat.h:167
#define FATX32
Definition: fat.h:171
#define FAT16
Definition: fat.h:168
#define FATX16
Definition: fat.h:170
#define FAT32
Definition: fat.h:169

Definition at line 26 of file fat.c.

◆ FAT_MAX_CACHE_SIZE

#define FAT_MAX_CACHE_SIZE   (256 * 1024)

Definition at line 37 of file fat.c.

◆ TAG_FAT_BUFFER

#define TAG_FAT_BUFFER   'BtaF'

Definition at line 34 of file fat.c.

◆ TAG_FAT_CACHE

#define TAG_FAT_CACHE   'HtaF'

Definition at line 35 of file fat.c.

◆ TAG_FAT_CHAIN

#define TAG_FAT_CHAIN   'CtaT'

Definition at line 31 of file fat.c.

◆ TAG_FAT_FILE

#define TAG_FAT_FILE   'FtaF'

Definition at line 32 of file fat.c.

◆ TAG_FAT_VOLUME

#define TAG_FAT_VOLUME   'VtaF'

Definition at line 33 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 419 of file fat.c.

420 {
421  PDIRECTORY_BUFFER DirectoryBuffer;
423 
424  TRACE("FatBufferDirectory() DirectoryStartCluster = %d RootDirectory = %s\n", DirectoryStartCluster, (RootDirectory ? "TRUE" : "FALSE"));
425 
426  /*
427  * For FAT32, the root directory is nothing special. We can treat it the same
428  * as a subdirectory.
429  */
430  if (RootDirectory && Volume->FatType == FAT32)
431  {
432  DirectoryStartCluster = Volume->RootDirStartCluster;
434  }
435 
436  /* Search the list for a match */
439  Entry = Entry->Flink)
440  {
441  DirectoryBuffer = CONTAINING_RECORD(Entry, DIRECTORY_BUFFER, Link);
442 
443  /* Check if it matches */
444  if ((DirectoryBuffer->Volume == Volume) &&
445  (DirectoryBuffer->DirectoryStartCluster == DirectoryStartCluster))
446  {
447  TRACE("Found cached buffer\n");
448  *DirectorySize = DirectoryBuffer->DirectorySize;
449  return DirectoryBuffer->Data;
450  }
451  }
452 
453  //
454  // Calculate the size of the directory
455  //
456  if (RootDirectory)
457  {
458  *DirectorySize = Volume->RootDirSectors * Volume->BytesPerSector;
459  }
460  else
461  {
462  *DirectorySize = FatCountClustersInChain(Volume, DirectoryStartCluster) * Volume->SectorsPerCluster * Volume->BytesPerSector;
463  }
464 
465  //
466  // Attempt to allocate memory for directory buffer
467  //
468  TRACE("Trying to allocate (DirectorySize) %d bytes.\n", *DirectorySize);
469  DirectoryBuffer = FrLdrTempAlloc(*DirectorySize + sizeof(DIRECTORY_BUFFER),
471 
472  if (DirectoryBuffer == NULL)
473  {
474  return NULL;
475  }
476 
477  //
478  // Now read directory contents into DirectoryBuffer
479  //
480  if (RootDirectory)
481  {
482  if (!FatReadVolumeSectors(Volume, Volume->RootDirSectorStart, Volume->RootDirSectors, DirectoryBuffer->Data))
483  {
484  FrLdrTempFree(DirectoryBuffer, TAG_FAT_BUFFER);
485  return NULL;
486  }
487  }
488  else
489  {
490  if (!FatReadClusterChain(Volume, DirectoryStartCluster, 0xFFFFFFFF, DirectoryBuffer->Data, NULL))
491  {
492  FrLdrTempFree(DirectoryBuffer, TAG_FAT_BUFFER);
493  return NULL;
494  }
495  }
496 
497  /* Enqueue it in the list */
498  DirectoryBuffer->Volume = Volume;
499  DirectoryBuffer->DirectoryStartCluster = DirectoryStartCluster;
500  DirectoryBuffer->DirectorySize = *DirectorySize;
501  InsertTailList(&DirectoryBufferListHead, &DirectoryBuffer->Link);
502 
503  return DirectoryBuffer->Data;
504 }
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
struct _Entry Entry
Definition: kefuncs.h:627
#define TAG_FAT_BUFFER
Definition: fat.c:34
#define InsertTailList(ListHead, Entry)
static BOOLEAN FatReadClusterChain(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 NumberOfClusters, PVOID Buffer, PUINT32 LastClusterNumber)
Definition: fat.c:1125
static int Link(const char **args)
Definition: vfdcmd.c:2414
PVOID Volume
Definition: fat.c:411
LIST_ENTRY Link
Definition: fat.c:410
#define FALSE
Definition: types.h:117
ULONG DirectorySize
Definition: fat.c:413
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG DirectoryStartCluster
Definition: fat.c:412
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
static ULONG FatCountClustersInChain(PFAT_VOLUME_INFO Volume, UINT32 StartCluster)
Definition: fat.c:1041
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: fat.c:1362
Definition: typedefs.h:119
UCHAR Data[]
Definition: fat.c:414
#define FAT32
Definition: fat.h:169
LIST_ENTRY DirectoryBufferListHead
Definition: fat.c:417
base of all file and directory entries
Definition: entries.h:82
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by FatLookupFile().

◆ FatClose()

ARC_STATUS FatClose ( ULONG  FileId)

Definition at line 1396 of file fat.c.

1397 {
1399 
1401 
1402  return ESUCCESS;
1403 }
Definition: arc.h:32
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
HANDLE FileHandle
Definition: stats.c:38
#define TAG_FAT_FILE
Definition: fat.c:32
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

◆ FatCountClustersInChain()

static ULONG FatCountClustersInChain ( PFAT_VOLUME_INFO  Volume,
UINT32  StartCluster 
)
static

Definition at line 1041 of file fat.c.

1042 {
1043  ULONG ClusterCount = 0;
1044 
1045  TRACE("FatCountClustersInChain() StartCluster = %d\n", StartCluster);
1046 
1047  while (1)
1048  {
1049  //
1050  // If end of chain then break out of our cluster counting loop
1051  //
1052  if (FAT_IS_END_CLUSTER(StartCluster))
1053  {
1054  break;
1055  }
1056 
1057  //
1058  // Increment count
1059  //
1060  ClusterCount++;
1061 
1062  //
1063  // Get next cluster
1064  //
1065  if (!FatGetFatEntry(Volume, StartCluster, &StartCluster))
1066  {
1067  return 0;
1068  }
1069  }
1070 
1071  TRACE("FatCountClustersInChain() ClusterCount = %d\n", ClusterCount);
1072 
1073  return ClusterCount;
1074 }
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
Definition: fat.c:951
#define FAT_IS_END_CLUSTER(clnumber)
Definition: fat.c:26
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int ULONG
Definition: retypes.h:1

Referenced by FatBufferDirectory().

◆ FatDetermineFatType()

ULONG FatDetermineFatType ( PFAT_BOOTSECTOR  FatBootSector,
ULONGLONG  PartitionSectorCount 
)

Definition at line 353 of file fat.c.

354 {
355  ULONG RootDirSectors;
356  ULONG DataSectorCount;
357  ULONG SectorsPerFat;
358  ULONG TotalSectors;
359  ULONG CountOfClusters;
360  PFAT32_BOOTSECTOR Fat32BootSector = (PFAT32_BOOTSECTOR)FatBootSector;
361  PFATX_BOOTSECTOR FatXBootSector = (PFATX_BOOTSECTOR)FatBootSector;
362 
363  if (0 == strncmp(FatXBootSector->FileSystemType, "FATX", 4))
364  {
365  CountOfClusters = (ULONG)(PartitionSectorCount / FatXBootSector->SectorsPerCluster);
366  if (CountOfClusters < 65525)
367  {
368  /* Volume is FATX16 */
369  return FATX16;
370  }
371  else
372  {
373  /* Volume is FAT32 */
374  return FATX32;
375  }
376  }
377  else
378  {
379  RootDirSectors = ((SWAPW(FatBootSector->RootDirEntries) * 32) + (SWAPW(FatBootSector->BytesPerSector) - 1)) / SWAPW(FatBootSector->BytesPerSector);
380  SectorsPerFat = SWAPW(FatBootSector->SectorsPerFat) ? SWAPW(FatBootSector->SectorsPerFat) : SWAPD(Fat32BootSector->SectorsPerFatBig);
381  TotalSectors = SWAPW(FatBootSector->TotalSectors) ? SWAPW(FatBootSector->TotalSectors) : SWAPD(FatBootSector->TotalSectorsBig);
382  DataSectorCount = TotalSectors - (SWAPW(FatBootSector->ReservedSectors) + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors);
383 
384 //mjl
385  if (FatBootSector->SectorsPerCluster == 0)
386  CountOfClusters = 0;
387  else
388  CountOfClusters = DataSectorCount / FatBootSector->SectorsPerCluster;
389 
390  if (CountOfClusters < 4085)
391  {
392  /* Volume is FAT12 */
393  return FAT12;
394  }
395  else if (CountOfClusters < 65525)
396  {
397  /* Volume is FAT16 */
398  return FAT16;
399  }
400  else
401  {
402  /* Volume is FAT32 */
403  return FAT32;
404  }
405  }
406 }
UCHAR SectorsPerCluster
Definition: bootsup.c:51
#define FAT12
Definition: fat.h:167
#define SWAPW(x)
Definition: bytesex.h:8
USHORT TotalSectors
Definition: bootsup.c:55
#define SWAPD(x)
Definition: bytesex.h:7
USHORT BytesPerSector
Definition: bootsup.c:50
ULONG PartitionSectorCount
Definition: partition.c:39
#define FATX32
Definition: fat.h:171
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
USHORT RootDirEntries
Definition: bootsup.c:54
USHORT ReservedSectors
Definition: bootsup.c:52
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
USHORT SectorsPerFat
Definition: bootsup.c:57
UCHAR NumberOfFats
Definition: bootsup.c:53
#define FAT16
Definition: fat.h:168
ULONG SectorsPerCluster
Definition: fat.h:92
#define FATX16
Definition: fat.h:170
#define FAT32
Definition: fat.h:169
unsigned int ULONG
Definition: retypes.h:1
CHAR FileSystemType[4]
Definition: fat.h:90
struct _FATX_BOOTSECTOR * PFATX_BOOTSECTOR

Referenced by FatOpenVolume().

◆ FatGetFatEntry()

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

Definition at line 951 of file fat.c.

952 {
953  UINT32 FatOffset, ThisFatSecNum, ThisFatEntOffset, fat;
955 
956  TRACE("FatGetFatEntry() Retrieving FAT entry for cluster %d.\n", Cluster);
957 
958  switch(Volume->FatType)
959  {
960  case FAT12:
961 
962  FatOffset = Cluster + (Cluster / 2);
963  ThisFatSecNum = FatOffset / Volume->BytesPerSector;
964  ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);
965 
966  TRACE("FatOffset: %d\n", FatOffset);
967  TRACE("ThisFatSecNum: %d\n", ThisFatSecNum);
968  TRACE("ThisFatEntOffset: %d\n", ThisFatEntOffset);
969 
970  // The cluster pointer can span within two sectors, but the FatGetFatSector function
971  // reads 4 sectors most times, except when we are at the edge of FAT cache
972  // and/or FAT region on the disk. For FAT12 the whole FAT would be cached so
973  // there will be no situation when the first sector is at the end of the cache
974  // and the next one is in the beginning
975 
976  ReadBuffer = FatGetFatSector(Volume, ThisFatSecNum);
977  if (!ReadBuffer)
978  {
979  return FALSE;
980  }
981 
982  fat = *((USHORT *) (ReadBuffer + ThisFatEntOffset));
983  fat = SWAPW(fat);
984  if (Cluster & 0x0001)
985  fat = fat >> 4; /* Cluster number is ODD */
986  else
987  fat = fat & 0x0FFF; /* Cluster number is EVEN */
988 
989  break;
990 
991  case FAT16:
992  case FATX16:
993 
994  FatOffset = (Cluster * 2);
995  ThisFatSecNum = FatOffset / Volume->BytesPerSector;
996  ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);
997 
998  ReadBuffer = FatGetFatSector(Volume, ThisFatSecNum);
999  if (!ReadBuffer)
1000  {
1001  return FALSE;
1002  }
1003 
1004  fat = *((USHORT *) (ReadBuffer + ThisFatEntOffset));
1005  fat = SWAPW(fat);
1006 
1007  break;
1008 
1009  case FAT32:
1010  case FATX32:
1011 
1012  FatOffset = (Cluster * 4);
1013  ThisFatSecNum = FatOffset / Volume->BytesPerSector;
1014  ThisFatEntOffset = (FatOffset % Volume->BytesPerSector);
1015 
1016  ReadBuffer = FatGetFatSector(Volume, ThisFatSecNum);
1017  if (!ReadBuffer)
1018  {
1019  return FALSE;
1020  }
1021 
1022  // Get the fat entry
1023  fat = (*((ULONG *) (ReadBuffer + ThisFatEntOffset))) & 0x0FFFFFFF;
1024  fat = SWAPD(fat);
1025 
1026  break;
1027 
1028  default:
1029  ERR("Unknown FAT type %d\n", Volume->FatType);
1030  return FALSE;
1031  }
1032 
1033  TRACE("FAT entry is 0x%x.\n", fat);
1034 
1035  *ClusterPointer = fat;
1036 
1037  return TRUE;
1038 }
#define FAT12
Definition: fat.h:167
#define SWAPW(x)
Definition: bytesex.h:8
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define SWAPD(x)
Definition: bytesex.h:7
static PUCHAR FatGetFatSector(PFAT_VOLUME_INFO Volume, UINT32 FatSectorNumber)
Reads 1-4 sectors from FAT using the cache.
Definition: fat.c:913
#define FALSE
Definition: types.h:117
unsigned int UINT32
#define FATX32
Definition: fat.h:171
#define TRACE(s)
Definition: solgame.cpp:4
#define FAT16
Definition: fat.h:168
#define ERR(fmt,...)
Definition: debug.h:110
unsigned short USHORT
Definition: pedump.c:61
#define FATX16
Definition: fat.h:170
#define FAT32
Definition: fat.h:169
unsigned int ULONG
Definition: retypes.h:1
static unsigned char * fat
Definition: mkdosfs.c:542

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 913 of file fat.c.

914 {
915  UINT32 SectorNumAbsolute = Volume->ActiveFatSectorStart + FatSectorNumber;
916  UINT32 CacheIndex = FatSectorNumber % Volume->FatCacheSize;
917 
918  ASSERT(FatSectorNumber < Volume->SectorsPerFat);
919 
920  // cache miss
921  if (Volume->FatCacheIndex[CacheIndex] != SectorNumAbsolute)
922  {
923  UINT32 SectorsToRead = min(Volume->FatCacheSize - CacheIndex, min(Volume->SectorsPerFat - SectorNumAbsolute, 4));
924  UINT8 i;
925 
926  if (!FatReadVolumeSectors(Volume, SectorNumAbsolute, SectorsToRead, &Volume->FatCache[CacheIndex * Volume->BytesPerSector]))
927  {
928  return NULL;
929  }
930 
931  for (i = 0; i < SectorsToRead; i++)
932  {
933  Volume->FatCacheIndex[CacheIndex + i] = SectorNumAbsolute + i;
934  }
935 
936  TRACE("FAT cache miss: read sector 0x%x from disk\n", SectorNumAbsolute);
937  }
938  else
939  {
940  TRACE("FAT cache hit: sector 0x%x present\n", SectorNumAbsolute);
941  }
942 
943  return &Volume->FatCache[CacheIndex * Volume->BytesPerSector];
944 }
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
unsigned int UINT32
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: fat.c:1362
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define min(a, b)
Definition: monoChain.cc:55
unsigned char UINT8

Referenced by FatGetFatEntry().

◆ FatGetFileInformation()

ARC_STATUS FatGetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)

Definition at line 1405 of file fat.c.

1406 {
1408 
1410  Information->EndingAddress.LowPart = FileHandle->FileSize;
1411  Information->CurrentAddress.LowPart = FileHandle->FilePointer;
1412 
1413  TRACE("FatGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
1414  FileId, Information->EndingAddress.LowPart, Information->CurrentAddress.LowPart);
1415 
1416  return ESUCCESS;
1417 }
Definition: arc.h:32
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
Iosb Information
Definition: create.c:4353
HANDLE FileHandle
Definition: stats.c:38
#define TRACE(s)
Definition: solgame.cpp:4
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ FatLookupFile()

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

Definition at line 774 of file fat.c.

775 {
776  UINT32 i;
777  ULONG NumberOfPathParts;
778  CHAR PathPart[261];
779  PVOID DirectoryBuffer;
780  ULONG DirectoryStartCluster = 0;
781  ULONG DirectorySize;
782  FAT_FILE_INFO FatFileInfo;
783 
784  TRACE("FatLookupFile() FileName = %s\n", FileName);
785 
786  RtlZeroMemory(FatFileInfoPointer, sizeof(FAT_FILE_INFO));
787 
788  //
789  // Figure out how many sub-directories we are nested in
790  //
791  NumberOfPathParts = FsGetNumPathParts(FileName);
792 
793  //
794  // Loop once for each part
795  //
796  for (i=0; i<NumberOfPathParts; i++)
797  {
798  //
799  // Get first path part
800  //
801  FsGetFirstNameFromPath(PathPart, FileName);
802 
803  //
804  // Advance to the next part of the path
805  //
806  for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
807  {
808  }
809  FileName++;
810 
811  //
812  // Buffer the directory contents
813  //
814  DirectoryBuffer = FatBufferDirectory(Volume, DirectoryStartCluster, &DirectorySize, (i == 0) );
815  if (DirectoryBuffer == NULL)
816  {
817  return ENOMEM;
818  }
819 
820  //
821  // Search for file name in directory
822  //
823  if (ISFATX(Volume->FatType))
824  {
825  if (!FatXSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo))
826  {
827  return ENOENT;
828  }
829  }
830  else
831  {
832  if (!FatSearchDirectoryBufferForFile(Volume, DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo))
833  {
834  return ENOENT;
835  }
836  }
837 
838  //
839  // If we have another sub-directory to go then
840  // grab the start cluster and free the fat chain array
841  //
842  if ((i+1) < NumberOfPathParts)
843  {
844  //
845  // Check if current entry is a directory
846  //
847  if (!(FatFileInfo.Attributes & ATTR_DIRECTORY))
848  {
849  return ENOTDIR;
850  }
851  DirectoryStartCluster = FatFileInfo.StartCluster;
852  }
853  }
854 
855  RtlCopyMemory(FatFileInfoPointer, &FatFileInfo, sizeof(FAT_FILE_INFO));
856 
857  return ESUCCESS;
858 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG *EntryCountPointer, BOOLEAN RootDirectory)
Definition: fat.c:419
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:356
Definition: arc.h:32
static BOOLEAN FatXSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
Definition: fat.c:711
char CHAR
Definition: xmlstorage.h:175
ULONG StartCluster
Definition: fat.h:154
#define ISFATX(FT)
Definition: fat.h:173
ULONG FsGetNumPathParts(PCSTR Path)
Definition: fs.c:328
Definition: arc.h:48
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
unsigned int UINT32
smooth NULL
Definition: ftsmooth.c:416
Definition: arc.h:50
#define TRACE(s)
Definition: solgame.cpp:4
#define ATTR_DIRECTORY
Definition: fat.h:163
Definition: arc.h:46
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR Attributes
Definition: fat.h:155
BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG EntryCount, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
Definition: fat.c:506

Referenced by FatOpen().

◆ FatMount()

const DEVVTBL* FatMount ( ULONG  DeviceId)

Definition at line 1552 of file fat.c.

1553 {
1555  UCHAR Buffer[512];
1558  PFATX_BOOTSECTOR BootSectorX = (PFATX_BOOTSECTOR)Buffer;
1561  ULONG Count;
1564 
1565  TRACE("Enter FatMount(%lu)\n", DeviceId);
1566 
1567  //
1568  // Allocate data for volume information
1569  //
1571  if (!Volume)
1572  return NULL;
1574 
1575  //
1576  // Read the BootSector
1577  //
1578  Position.QuadPart = 0;
1579  Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
1580  if (Status != ESUCCESS)
1581  {
1583  return NULL;
1584  }
1585  Status = ArcRead(DeviceId, Buffer, sizeof(Buffer), &Count);
1586  if (Status != ESUCCESS || Count != sizeof(Buffer))
1587  {
1589  return NULL;
1590  }
1591 
1592  //
1593  // Check if BootSector is valid. If no, return early
1594  //
1595  if (!RtlEqualMemory(BootSector->FileSystemType, "FAT12 ", 8) &&
1596  !RtlEqualMemory(BootSector->FileSystemType, "FAT16 ", 8) &&
1597  !RtlEqualMemory(BootSector32->FileSystemType, "FAT32 ", 8) &&
1598  !RtlEqualMemory(BootSectorX->FileSystemType, "FATX", 4))
1599  {
1601  return NULL;
1602  }
1603 
1604  //
1605  // Determine sector count
1606  //
1608  if (Status != ESUCCESS)
1609  {
1611  return NULL;
1612  }
1613  SectorCount.QuadPart = (FileInformation.EndingAddress.QuadPart - FileInformation.StartingAddress.QuadPart);
1614  SectorCount.QuadPart /= SECTOR_SIZE;
1615 
1616  //
1617  // Keep device id
1618  //
1619  Volume->DeviceId = DeviceId;
1620 
1621  //
1622  // Really open the volume
1623  //
1624  if (!FatOpenVolume(Volume, BootSector, SectorCount.QuadPart))
1625  {
1627  return NULL;
1628  }
1629 
1630  //
1631  // Remember FAT volume information
1632  //
1633  FatVolumes[DeviceId] = Volume;
1634 
1635  //
1636  // Return success
1637  //
1638  TRACE("FatMount(%lu) success\n", DeviceId);
1639  return &FatFuncTable;
1640 }
Definition: arc.h:32
static COORD Position
Definition: mouse.c:34
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
ULONG ARC_STATUS
Definition: arc.h:4
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define TRACE(s)
Definition: solgame.cpp:4
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
PFAT_VOLUME_INFO FatVolumes[MAX_FDS]
Definition: fat.c:58
#define TAG_FAT_VOLUME
Definition: fat.c:33
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:243
const DEVVTBL FatFuncTable
Definition: fat.c:1542
ULONG SectorCount
Definition: part_xbox.c:31
BOOLEAN FatOpenVolume(PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount)
Definition: fat.c:138
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:250
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define SECTOR_SIZE
Definition: fs.h:22
CHAR FileSystemType[4]
Definition: fat.h:90
struct _FATX_BOOTSECTOR * PFATX_BOOTSECTOR
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

◆ FatOpen()

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

Definition at line 1419 of file fat.c.

1420 {
1421  PFAT_VOLUME_INFO FatVolume;
1422  FAT_FILE_INFO TempFileInfo;
1424  ULONG DeviceId;
1427 
1428  if (OpenMode != OpenReadOnly && OpenMode != OpenDirectory)
1429  return EACCES;
1430 
1431  DeviceId = FsGetDeviceId(*FileId);
1432  FatVolume = FatVolumes[DeviceId];
1433 
1434  TRACE("FatOpen() FileName = %s\n", Path);
1435 
1436  RtlZeroMemory(&TempFileInfo, sizeof(TempFileInfo));
1437  Status = FatLookupFile(FatVolume, Path, &TempFileInfo);
1438  if (Status != ESUCCESS)
1439  return ENOENT;
1440 
1441  //
1442  // Check if caller opened what he expected (dir vs file)
1443  //
1444  IsDirectory = (TempFileInfo.Attributes & ATTR_DIRECTORY) != 0;
1445  if (IsDirectory && OpenMode != OpenDirectory)
1446  return EISDIR;
1447  else if (!IsDirectory && OpenMode != OpenReadOnly)
1448  return ENOTDIR;
1449 
1451  if (!FileHandle)
1452  return ENOMEM;
1453 
1454  RtlCopyMemory(FileHandle, &TempFileInfo, sizeof(FAT_FILE_INFO));
1455  FileHandle->Volume = FatVolume;
1456 
1457  FsSetDeviceSpecific(*FileId, FileHandle);
1458  return ESUCCESS;
1459 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
Definition: arc.h:48
HANDLE FileHandle
Definition: stats.c:38
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
unsigned char BOOLEAN
Definition: arc.h:50
#define TRACE(s)
Definition: solgame.cpp:4
PFAT_VOLUME_INFO FatVolumes[MAX_FDS]
Definition: fat.c:58
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
Definition: fs.c:409
Definition: arc.h:34
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
#define ATTR_DIRECTORY
Definition: fat.h:163
#define TAG_FAT_FILE
Definition: fat.c:32
PRTL_UNICODE_STRING_BUFFER Path
Definition: arc.h:46
Definition: arc.h:41
ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer)
Definition: fat.c:774
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:423
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR Attributes
Definition: fat.h:155

◆ FatOpenVolume()

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

Definition at line 138 of file fat.c.

139 {
140  char ErrMsg[80];
141  ULONG FatSize, i;
142  PFAT_BOOTSECTOR FatVolumeBootSector;
143  PFAT32_BOOTSECTOR Fat32VolumeBootSector;
144  PFATX_BOOTSECTOR FatXVolumeBootSector;
145 
146  TRACE("FatOpenVolume() DeviceId = %d\n", Volume->DeviceId);
147 
148  //
149  // Allocate the memory to hold the boot sector
150  //
151  FatVolumeBootSector = (PFAT_BOOTSECTOR)BootSector;
152  Fat32VolumeBootSector = (PFAT32_BOOTSECTOR)BootSector;
153  FatXVolumeBootSector = (PFATX_BOOTSECTOR)BootSector;
154 
155  // Get the FAT type
156  Volume->FatType = FatDetermineFatType(FatVolumeBootSector, PartitionSectorCount);
157 
158  // Dump boot sector (and swap it for big endian systems)
159  TRACE("Dumping boot sector:\n");
160  if (ISFATX(Volume->FatType))
161  {
162  FatSwapFatXBootSector(FatXVolumeBootSector);
163  TRACE("sizeof(FATX_BOOTSECTOR) = 0x%x.\n", sizeof(FATX_BOOTSECTOR));
164 
165  TRACE("FileSystemType: %c%c%c%c.\n", FatXVolumeBootSector->FileSystemType[0], FatXVolumeBootSector->FileSystemType[1], FatXVolumeBootSector->FileSystemType[2], FatXVolumeBootSector->FileSystemType[3]);
166  TRACE("VolumeSerialNumber: 0x%x\n", FatXVolumeBootSector->VolumeSerialNumber);
167  TRACE("SectorsPerCluster: %d\n", FatXVolumeBootSector->SectorsPerCluster);
168  TRACE("NumberOfFats: %d\n", FatXVolumeBootSector->NumberOfFats);
169  TRACE("Unknown: 0x%x\n", FatXVolumeBootSector->Unknown);
170 
171  TRACE("FatType %s\n", Volume->FatType == FATX16 ? "FATX16" : "FATX32");
172 
173  }
174  else if (Volume->FatType == FAT32)
175  {
176  FatSwapFat32BootSector(Fat32VolumeBootSector);
177  TRACE("sizeof(FAT32_BOOTSECTOR) = 0x%x.\n", sizeof(FAT32_BOOTSECTOR));
178 
179  TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", Fat32VolumeBootSector->JumpBoot[0], Fat32VolumeBootSector->JumpBoot[1], Fat32VolumeBootSector->JumpBoot[2]);
180  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]);
181  TRACE("BytesPerSector: %d\n", Fat32VolumeBootSector->BytesPerSector);
182  TRACE("SectorsPerCluster: %d\n", Fat32VolumeBootSector->SectorsPerCluster);
183  TRACE("ReservedSectors: %d\n", Fat32VolumeBootSector->ReservedSectors);
184  TRACE("NumberOfFats: %d\n", Fat32VolumeBootSector->NumberOfFats);
185  TRACE("RootDirEntries: %d\n", Fat32VolumeBootSector->RootDirEntries);
186  TRACE("TotalSectors: %d\n", Fat32VolumeBootSector->TotalSectors);
187  TRACE("MediaDescriptor: 0x%x\n", Fat32VolumeBootSector->MediaDescriptor);
188  TRACE("SectorsPerFat: %d\n", Fat32VolumeBootSector->SectorsPerFat);
189  TRACE("SectorsPerTrack: %d\n", Fat32VolumeBootSector->SectorsPerTrack);
190  TRACE("NumberOfHeads: %d\n", Fat32VolumeBootSector->NumberOfHeads);
191  TRACE("HiddenSectors: %d\n", Fat32VolumeBootSector->HiddenSectors);
192  TRACE("TotalSectorsBig: %d\n", Fat32VolumeBootSector->TotalSectorsBig);
193  TRACE("SectorsPerFatBig: %d\n", Fat32VolumeBootSector->SectorsPerFatBig);
194  TRACE("ExtendedFlags: 0x%x\n", Fat32VolumeBootSector->ExtendedFlags);
195  TRACE("FileSystemVersion: 0x%x\n", Fat32VolumeBootSector->FileSystemVersion);
196  TRACE("RootDirStartCluster: %d\n", Fat32VolumeBootSector->RootDirStartCluster);
197  TRACE("FsInfo: %d\n", Fat32VolumeBootSector->FsInfo);
198  TRACE("BackupBootSector: %d\n", Fat32VolumeBootSector->BackupBootSector);
199  TRACE("Reserved: 0x%x\n", Fat32VolumeBootSector->Reserved);
200  TRACE("DriveNumber: 0x%x\n", Fat32VolumeBootSector->DriveNumber);
201  TRACE("Reserved1: 0x%x\n", Fat32VolumeBootSector->Reserved1);
202  TRACE("BootSignature: 0x%x\n", Fat32VolumeBootSector->BootSignature);
203  TRACE("VolumeSerialNumber: 0x%x\n", Fat32VolumeBootSector->VolumeSerialNumber);
204  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]);
205  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]);
206  TRACE("BootSectorMagic: 0x%x\n", Fat32VolumeBootSector->BootSectorMagic);
207  }
208  else
209  {
210  FatSwapFatBootSector(FatVolumeBootSector);
211  TRACE("sizeof(FAT_BOOTSECTOR) = 0x%x.\n", sizeof(FAT_BOOTSECTOR));
212 
213  TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", FatVolumeBootSector->JumpBoot[0], FatVolumeBootSector->JumpBoot[1], FatVolumeBootSector->JumpBoot[2]);
214  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]);
215  TRACE("BytesPerSector: %d\n", FatVolumeBootSector->BytesPerSector);
216  TRACE("SectorsPerCluster: %d\n", FatVolumeBootSector->SectorsPerCluster);
217  TRACE("ReservedSectors: %d\n", FatVolumeBootSector->ReservedSectors);
218  TRACE("NumberOfFats: %d\n", FatVolumeBootSector->NumberOfFats);
219  TRACE("RootDirEntries: %d\n", FatVolumeBootSector->RootDirEntries);
220  TRACE("TotalSectors: %d\n", FatVolumeBootSector->TotalSectors);
221  TRACE("MediaDescriptor: 0x%x\n", FatVolumeBootSector->MediaDescriptor);
222  TRACE("SectorsPerFat: %d\n", FatVolumeBootSector->SectorsPerFat);
223  TRACE("SectorsPerTrack: %d\n", FatVolumeBootSector->SectorsPerTrack);
224  TRACE("NumberOfHeads: %d\n", FatVolumeBootSector->NumberOfHeads);
225  TRACE("HiddenSectors: %d\n", FatVolumeBootSector->HiddenSectors);
226  TRACE("TotalSectorsBig: %d\n", FatVolumeBootSector->TotalSectorsBig);
227  TRACE("DriveNumber: 0x%x\n", FatVolumeBootSector->DriveNumber);
228  TRACE("Reserved1: 0x%x\n", FatVolumeBootSector->Reserved1);
229  TRACE("BootSignature: 0x%x\n", FatVolumeBootSector->BootSignature);
230  TRACE("VolumeSerialNumber: 0x%x\n", FatVolumeBootSector->VolumeSerialNumber);
231  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]);
232  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]);
233  TRACE("BootSectorMagic: 0x%x\n", FatVolumeBootSector->BootSectorMagic);
234  }
235 
236  //
237  // Check the boot sector magic
238  //
239  if (! ISFATX(Volume->FatType) && FatVolumeBootSector->BootSectorMagic != 0xaa55)
240  {
241  sprintf(ErrMsg, "Invalid boot sector magic (expected 0xaa55 found 0x%x)",
242  FatVolumeBootSector->BootSectorMagic);
243  FileSystemError(ErrMsg);
244  return FALSE;
245  }
246 
247  //
248  // Check the FAT cluster size
249  // We do not support clusters bigger than 64k
250  //
251  if ((ISFATX(Volume->FatType) && 64 * 1024 < FatXVolumeBootSector->SectorsPerCluster * 512) ||
252  (! ISFATX(Volume->FatType) && 64 * 1024 < FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector))
253  {
254  FileSystemError("This file system has cluster sizes bigger than 64k.\nFreeLoader does not support this.");
255  return FALSE;
256  }
257 
258  //
259  // Get the sectors per FAT,
260  // root directory starting sector,
261  // and data sector start
262  //
263  if (ISFATX(Volume->FatType))
264  {
265  Volume->BytesPerSector = 512;
266  Volume->SectorsPerCluster = SWAPD(FatXVolumeBootSector->SectorsPerCluster);
267  Volume->FatSectorStart = (0x1000 / Volume->BytesPerSector);
268  Volume->ActiveFatSectorStart = Volume->FatSectorStart;
269  Volume->NumberOfFats = 1;
270  FatSize = (ULONG)(PartitionSectorCount / Volume->SectorsPerCluster *
271  (Volume->FatType == FATX16 ? 2 : 4));
272  Volume->SectorsPerFat = ROUND_UP(FatSize, 0x1000) / Volume->BytesPerSector;
273 
274  Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
275  Volume->RootDirSectors = FatXVolumeBootSector->SectorsPerCluster;
276 
277  Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors;
278  }
279  else if (Volume->FatType != FAT32)
280  {
281  Volume->BytesPerSector = FatVolumeBootSector->BytesPerSector;
282  Volume->SectorsPerCluster = FatVolumeBootSector->SectorsPerCluster;
283  Volume->FatSectorStart = FatVolumeBootSector->ReservedSectors;
284  Volume->ActiveFatSectorStart = Volume->FatSectorStart;
285  Volume->NumberOfFats = FatVolumeBootSector->NumberOfFats;
286  Volume->SectorsPerFat = FatVolumeBootSector->SectorsPerFat;
287 
288  Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
289  Volume->RootDirSectors = ((FatVolumeBootSector->RootDirEntries * 32) + (Volume->BytesPerSector - 1)) / Volume->BytesPerSector;
290 
291  Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors;
292  }
293  else
294  {
295  Volume->BytesPerSector = Fat32VolumeBootSector->BytesPerSector;
296  Volume->SectorsPerCluster = Fat32VolumeBootSector->SectorsPerCluster;
297  Volume->FatSectorStart = Fat32VolumeBootSector->ReservedSectors;
298  Volume->ActiveFatSectorStart = Volume->FatSectorStart +
299  ((Fat32VolumeBootSector->ExtendedFlags & 0x80) ? ((Fat32VolumeBootSector->ExtendedFlags & 0x0f) * Fat32VolumeBootSector->SectorsPerFatBig) : 0);
300  Volume->NumberOfFats = Fat32VolumeBootSector->NumberOfFats;
301  Volume->SectorsPerFat = Fat32VolumeBootSector->SectorsPerFatBig;
302 
303  Volume->RootDirStartCluster = Fat32VolumeBootSector->RootDirStartCluster;
304  Volume->DataSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat;
305 
306  //
307  // Check version
308  // we only work with version 0
309  //
310  if (Fat32VolumeBootSector->FileSystemVersion != 0)
311  {
312  FileSystemError("FreeLoader is too old to work with this FAT32 filesystem.\nPlease update FreeLoader.");
313  return FALSE;
314  }
315  }
316 
317  Volume->FatCacheSize = min(Volume->SectorsPerFat, FAT_MAX_CACHE_SIZE / Volume->BytesPerSector);
318  TRACE("FAT cache is %d sectors, %d bytes\n", Volume->FatCacheSize, Volume->FatCacheSize * Volume->BytesPerSector);
319 
320  Volume->FatCache = FrLdrTempAlloc(Volume->FatCacheSize * Volume->BytesPerSector, TAG_FAT_CACHE);
321  if (!Volume->FatCache)
322  {
323  FileSystemError("Cannot allocate memory for FAT cache");
324  return FALSE;
325  }
326 
327  Volume->FatCacheIndex = FrLdrTempAlloc(Volume->FatCacheSize * sizeof(*Volume->FatCacheIndex), TAG_FAT_VOLUME);
328  if (!Volume->FatCacheIndex)
329  {
330  FileSystemError("Cannot allocate memory for FAT cache index");
331  FrLdrTempFree(Volume->FatCache, TAG_FAT_CACHE);
332  return FALSE;
333  }
334 
335  // read the beginning of the FAT (or the whole one) to cache
336  if (!FatReadVolumeSectors(Volume, Volume->ActiveFatSectorStart, Volume->FatCacheSize, Volume->FatCache))
337  {
338  FileSystemError("Error when reading FAT cache");
339  FrLdrTempFree(Volume->FatCache, TAG_FAT_CACHE);
340  FrLdrTempFree(Volume->FatCacheIndex, TAG_FAT_VOLUME);
341  return FALSE;
342  }
343 
344  // fill the index with sector numbers
345  for (i = 0; i < Volume->FatCacheSize; i++)
346  {
347  Volume->FatCacheIndex[i] = Volume->ActiveFatSectorStart + i;
348  }
349 
350  return TRUE;
351 }
USHORT BytesPerSector
Definition: bootsup.c:79
UCHAR SectorsPerCluster
Definition: bootsup.c:51
VOID FatSwapFatXBootSector(PFATX_BOOTSECTOR Obj)
Definition: fat.c:95
#define FAT_MAX_CACHE_SIZE
Definition: fat.c:37
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
UCHAR SectorsPerCluster
Definition: bootsup.c:80
USHORT TotalSectors
Definition: bootsup.c:55
UCHAR Reserved1
Definition: bootsup.c:99
USHORT BootSectorMagic
Definition: bootsup.c:107
#define TRUE
Definition: types.h:120
UCHAR JumpBoot[3]
Definition: bootsup.c:77
#define ISFATX(FT)
Definition: fat.h:173
#define SWAPD(x)
Definition: bytesex.h:7
ULONG TotalSectorsBig
Definition: bootsup.c:90
ULONG VolumeSerialNumber
Definition: bootsup.c:101
USHORT BytesPerSector
Definition: bootsup.c:50
CHAR VolumeLabel[11]
Definition: bootsup.c:66
#define sprintf(buf, format,...)
Definition: sprintf.c:55
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
ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount)
Definition: fat.c:353
ULONG PartitionSectorCount
Definition: partition.c:39
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
ULONG SectorsPerFatBig
Definition: bootsup.c:91
USHORT RootDirEntries
Definition: bootsup.c:54
CHAR OemName[8]
Definition: bootsup.c:49
UCHAR JumpBoot[3]
Definition: bootsup.c:48
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
USHORT NumberOfHeads
Definition: bootsup.c:59
USHORT NumberOfFats
Definition: fat.h:93
#define TAG_FAT_CACHE
Definition: fat.c:35
CHAR FileSystemType[8]
Definition: bootsup.c:103
UCHAR BootSignature
Definition: bootsup.c:64
USHORT RootDirEntries
Definition: bootsup.c:83
VOID FatSwapFatBootSector(PFAT_BOOTSECTOR Obj)
Definition: fat.c:60
#define TRACE(s)
Definition: solgame.cpp:4
USHORT ReservedSectors
Definition: bootsup.c:52
USHORT ReservedSectors
Definition: bootsup.c:81
CHAR OemName[8]
Definition: bootsup.c:78
#define TAG_FAT_VOLUME
Definition: fat.c:33
UCHAR Reserved1
Definition: bootsup.c:63
USHORT SectorsPerFat
Definition: bootsup.c:57
UCHAR BootSignature
Definition: bootsup.c:100
USHORT BackupBootSector
Definition: bootsup.c:96
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: fat.c:1362
USHORT BootSectorMagic
Definition: bootsup.c:71
UCHAR NumberOfFats
Definition: bootsup.c:53
CHAR VolumeLabel[11]
Definition: bootsup.c:102
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
UCHAR DriveNumber
Definition: bootsup.c:98
USHORT TotalSectors
Definition: bootsup.c:84
USHORT SectorsPerTrack
Definition: bootsup.c:87
ULONG VolumeSerialNumber
Definition: bootsup.c:65
ULONG Unknown
Definition: fat.h:94
UCHAR MediaDescriptor
Definition: bootsup.c:85
USHORT SectorsPerTrack
Definition: bootsup.c:58
USHORT FileSystemVersion
Definition: bootsup.c:93
USHORT FsInfo
Definition: bootsup.c:95
VOID FatSwapFat32BootSector(PFAT32_BOOTSECTOR Obj)
Definition: fat.c:75
UCHAR MediaDescriptor
Definition: bootsup.c:56
CHAR FileSystemType[8]
Definition: bootsup.c:67
ULONG VolumeSerialNumber
Definition: fat.h:91
USHORT SectorsPerFat
Definition: bootsup.c:86
UCHAR NumberOfFats
Definition: bootsup.c:82
ULONG SectorsPerCluster
Definition: fat.h:92
#define FATX16
Definition: fat.h:170
#define min(a, b)
Definition: monoChain.cc:55
#define FAT32
Definition: fat.h:169
USHORT NumberOfHeads
Definition: bootsup.c:88
ULONG TotalSectorsBig
Definition: bootsup.c:61
ULONG HiddenSectors
Definition: bootsup.c:60
ULONG HiddenSectors
Definition: bootsup.c:89
unsigned int ULONG
Definition: retypes.h:1
UCHAR Reserved[12]
Definition: bootsup.c:97
CHAR FileSystemType[4]
Definition: fat.h:90
struct _FATX_BOOTSECTOR * PFATX_BOOTSECTOR
UCHAR DriveNumber
Definition: bootsup.c:62
ULONG RootDirStartCluster
Definition: bootsup.c:94
USHORT ExtendedFlags
Definition: bootsup.c:92
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by FatMount().

◆ FatParseShortFileName()

void FatParseShortFileName ( PCHAR  Buffer,
PDIRENTRY  DirEntry 
)

Definition at line 866 of file fat.c.

867 {
868  ULONG Idx;
869 
870  Idx = 0;
871  RtlZeroMemory(Buffer, 13);
872 
873  //
874  // Fixup first character
875  //
876  if (DirEntry->FileName[0] == 0x05)
877  {
878  DirEntry->FileName[0] = 0xE5;
879  }
880 
881  //
882  // Get the file name
883  //
884  while (Idx < 8)
885  {
886  if (DirEntry->FileName[Idx] == ' ')
887  {
888  break;
889  }
890 
891  Buffer[Idx] = DirEntry->FileName[Idx];
892  Idx++;
893  }
894 
895  //
896  // Get extension
897  //
898  if ((DirEntry->FileName[8] != ' '))
899  {
900  Buffer[Idx++] = '.';
901  Buffer[Idx++] = (DirEntry->FileName[8] == ' ') ? '\0' : DirEntry->FileName[8];
902  Buffer[Idx++] = (DirEntry->FileName[9] == ' ') ? '\0' : DirEntry->FileName[9];
903  Buffer[Idx++] = (DirEntry->FileName[10] == ' ') ? '\0' : DirEntry->FileName[10];
904  }
905 
906  //TRACE("FatParseShortFileName() ShortName = %s\n", Buffer);
907 }
Definition: bufpool.h:45
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by FatSearchDirectoryBufferForFile().

◆ FatRead()

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

Definition at line 1461 of file fat.c.

1462 {
1464  BOOLEAN Success;
1465 
1466  //
1467  // Call old read method
1468  //
1470 
1471  //
1472  // Check for success
1473  //
1474  if (Success)
1475  return ESUCCESS;
1476  else
1477  return EIO;
1478 }
Definition: arc.h:32
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
HANDLE FileHandle
Definition: stats.c:38
unsigned char BOOLEAN
Definition: bufpool.h:45
Definition: arc.h:40
static BOOLEAN FatReadFile(PFAT_FILE_INFO FatFileInfo, ULONG BytesToRead, ULONG *BytesRead, PVOID Buffer)
Definition: fat.c:1196

◆ FatReadAdjacentClusters()

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

Definition at line 1077 of file fat.c.

1084 {
1085  UINT32 NextClusterNumber;
1086  UINT32 ClustersToRead = 1;
1087  UINT32 PrevClusterNumber = StartClusterNumber;
1088  UINT32 ClusterStartSector = ((PrevClusterNumber - 2) * Volume->SectorsPerCluster) + Volume->DataSectorStart;
1089 
1090  *ClustersRead = 0;
1091  *LastClusterNumber = 0;
1092 
1093  if (!FatGetFatEntry(Volume, StartClusterNumber, &NextClusterNumber))
1094  {
1095  return FALSE;
1096  }
1097 
1098  // getting the number of adjacent clusters
1099  while (!FAT_IS_END_CLUSTER(NextClusterNumber) && ClustersToRead < MaxClusters && (NextClusterNumber == PrevClusterNumber + 1))
1100  {
1101  ClustersToRead++;
1102  PrevClusterNumber = NextClusterNumber;
1103  if (!FatGetFatEntry(Volume, PrevClusterNumber, &NextClusterNumber))
1104  {
1105  return FALSE;
1106  }
1107  }
1108 
1109  if (!FatReadVolumeSectors(Volume, ClusterStartSector, ClustersToRead * Volume->SectorsPerCluster, Buffer))
1110  {
1111  return FALSE;
1112  }
1113 
1114  *ClustersRead = ClustersToRead;
1115  *LastClusterNumber = NextClusterNumber;
1116 
1117  return !FAT_IS_END_CLUSTER(NextClusterNumber) && ClustersToRead < MaxClusters;
1118 }
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
Definition: fat.c:951
#define FAT_IS_END_CLUSTER(clnumber)
Definition: fat.c:26
#define FALSE
Definition: types.h:117
unsigned int UINT32
Definition: bufpool.h:45
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: fat.c:1362

Referenced by FatReadClusterChain().

◆ FatReadClusterChain()

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

Definition at line 1125 of file fat.c.

1126 {
1127  UINT32 ClustersRead, NextClusterNumber, ClustersLeft = NumberOfClusters;
1128 
1129  TRACE("FatReadClusterChain() StartClusterNumber = %d NumberOfClusters = %d Buffer = 0x%x\n", StartClusterNumber, NumberOfClusters, Buffer);
1130 
1131  ASSERT(NumberOfClusters > 0);
1132 
1133  while (FatReadAdjacentClusters(Volume, StartClusterNumber, ClustersLeft, Buffer, &ClustersRead, &NextClusterNumber))
1134  {
1135  ClustersLeft -= ClustersRead;
1136  Buffer = (PVOID)((ULONG_PTR)Buffer + (ClustersRead * Volume->SectorsPerCluster * Volume->BytesPerSector));
1137  StartClusterNumber = NextClusterNumber;
1138  }
1139 
1140  if (LastClusterNumber)
1141  {
1142  *LastClusterNumber = NextClusterNumber;
1143  }
1144 
1145  return (ClustersRead > 0);
1146 }
static BOOLEAN FatReadAdjacentClusters(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 MaxClusters, PVOID Buffer, PUINT32 ClustersRead, PUINT32 LastClusterNumber)
Definition: fat.c:1077
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned int UINT32
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
#define TRACE(s)
Definition: solgame.cpp:4
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by FatBufferDirectory(), and FatReadFile().

◆ FatReadFile()

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

Definition at line 1196 of file fat.c.

1197 {
1198  PFAT_VOLUME_INFO Volume = FatFileInfo->Volume;
1199  UINT32 NextClusterNumber, BytesPerCluster;
1200 
1201  TRACE("FatReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead, Buffer);
1202 
1203  if (BytesRead != NULL)
1204  {
1205  *BytesRead = 0;
1206  }
1207 
1208  //
1209  // If the user is trying to read past the end of
1210  // the file then return success with BytesRead == 0.
1211  //
1212  if (FatFileInfo->FilePointer >= FatFileInfo->FileSize)
1213  {
1214  return TRUE;
1215  }
1216 
1217  //
1218  // If the user is trying to read more than there is to read
1219  // then adjust the amount to read.
1220  //
1221  if ((FatFileInfo->FilePointer + BytesToRead) > FatFileInfo->FileSize)
1222  {
1223  BytesToRead = (FatFileInfo->FileSize - FatFileInfo->FilePointer);
1224  }
1225 
1226  //
1227  // Ok, now we have to perform at most 3 calculations
1228  // I'll draw you a picture (using nifty ASCII art):
1229  //
1230  // CurrentFilePointer -+
1231  // |
1232  // +----------------+
1233  // |
1234  // +-----------+-----------+-----------+-----------+
1235  // | Cluster 1 | Cluster 2 | Cluster 3 | Cluster 4 |
1236  // +-----------+-----------+-----------+-----------+
1237  // | |
1238  // +---------------+--------------------+
1239  // |
1240  // BytesToRead -------+
1241  //
1242  // 1 - The first calculation (and read) will align
1243  // the file pointer with the next cluster.
1244  // boundary (if we are supposed to read that much)
1245  // 2 - The next calculation (and read) will read
1246  // in all the full clusters that the requested
1247  // amount of data would cover (in this case
1248  // clusters 2 & 3).
1249  // 3 - The last calculation (and read) would read
1250  // in the remainder of the data requested out of
1251  // the last cluster.
1252  //
1253 
1254  BytesPerCluster = Volume->SectorsPerCluster * Volume->BytesPerSector;
1255 
1256  //
1257  // Only do the first read if we
1258  // aren't aligned on a cluster boundary
1259  //
1260  if (FatFileInfo->FilePointer % BytesPerCluster)
1261  {
1262  //
1263  // Do the math for our first read
1264  //
1265  UINT32 OffsetInCluster = FatFileInfo->FilePointer % BytesPerCluster;
1266  UINT32 LengthInCluster = min(BytesToRead, BytesPerCluster - OffsetInCluster);
1267 
1268  ASSERT(LengthInCluster <= BytesPerCluster && LengthInCluster > 0);
1269 
1270  //
1271  // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
1272  //
1273  if (!FatReadPartialCluster(Volume, FatFileInfo->CurrentCluster, OffsetInCluster, LengthInCluster, Buffer))
1274  {
1275  return FALSE;
1276  }
1277  if (BytesRead != NULL)
1278  {
1279  *BytesRead += LengthInCluster;
1280  }
1281  BytesToRead -= LengthInCluster;
1282  FatFileInfo->FilePointer += LengthInCluster;
1283  Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInCluster);
1284 
1285  // get the next cluster if needed
1286  if ((LengthInCluster + OffsetInCluster) == BytesPerCluster)
1287  {
1288  if (!FatGetFatEntry(Volume, FatFileInfo->CurrentCluster, &NextClusterNumber))
1289  {
1290  return FALSE;
1291  }
1292 
1293  FatFileInfo->CurrentCluster = NextClusterNumber;
1294  TRACE("FatReadFile() FatFileInfo->CurrentCluster = 0x%x\n", FatFileInfo->CurrentCluster);
1295  }
1296  }
1297 
1298  //
1299  // Do the math for our second read (if any data left)
1300  //
1301  if (BytesToRead > 0)
1302  {
1303  //
1304  // Determine how many full clusters we need to read
1305  //
1306  UINT32 NumberOfClusters = BytesToRead / BytesPerCluster;
1307 
1308  TRACE("Going to read: %u clusters\n", NumberOfClusters);
1309 
1310  if (NumberOfClusters > 0)
1311  {
1312  UINT32 BytesReadHere = NumberOfClusters * BytesPerCluster;
1313 
1314  ASSERT(!FAT_IS_END_CLUSTER(FatFileInfo->CurrentCluster));
1315 
1316  if (!FatReadClusterChain(Volume, FatFileInfo->CurrentCluster, NumberOfClusters, Buffer, &NextClusterNumber))
1317  {
1318  return FALSE;
1319  }
1320 
1321  if (BytesRead != NULL)
1322  {
1323  *BytesRead += BytesReadHere;
1324  }
1325  BytesToRead -= BytesReadHere;
1326  Buffer = (PVOID)((ULONG_PTR)Buffer + BytesReadHere);
1327 
1328  ASSERT(!FAT_IS_END_CLUSTER(NextClusterNumber) || BytesToRead == 0);
1329 
1330  FatFileInfo->FilePointer += BytesReadHere;
1331  FatFileInfo->CurrentCluster = NextClusterNumber;
1332  TRACE("FatReadFile() FatFileInfo->CurrentCluster = 0x%x\n", FatFileInfo->CurrentCluster);
1333  }
1334  }
1335 
1336  //
1337  // Do the math for our third read (if any data left)
1338  //
1339  if (BytesToRead > 0)
1340  {
1341  ASSERT(!FAT_IS_END_CLUSTER(FatFileInfo->CurrentCluster));
1342 
1343  //
1344  // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
1345  //
1346  if (!FatReadPartialCluster(Volume, FatFileInfo->CurrentCluster, 0, BytesToRead, Buffer))
1347  {
1348  return FALSE;
1349  }
1350  if (BytesRead != NULL)
1351  {
1352  *BytesRead += BytesToRead;
1353  }
1354  FatFileInfo->FilePointer += BytesToRead;
1355  BytesToRead -= BytesToRead;
1356  Buffer = (PVOID)((ULONG_PTR)Buffer + BytesToRead);
1357  }
1358 
1359  return TRUE;
1360 }
#define TRUE
Definition: types.h:120
PFAT_VOLUME_INFO Volume
Definition: fat.h:150
static BOOLEAN FatReadClusterChain(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 NumberOfClusters, PVOID Buffer, PUINT32 LastClusterNumber)
Definition: fat.c:1125
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
Definition: fat.c:951
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FAT_IS_END_CLUSTER(clnumber)
Definition: fat.c:26
#define FALSE
Definition: types.h:117
unsigned int UINT32
ULONG FilePointer
Definition: fat.h:152
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
#define TRACE(s)
Definition: solgame.cpp:4
ULONG CurrentCluster
Definition: fat.h:153
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG FileSize
Definition: fat.h:151
#define min(a, b)
Definition: monoChain.cc:55
BOOLEAN FatReadPartialCluster(PFAT_VOLUME_INFO Volume, ULONG ClusterNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
Definition: fat.c:1152
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

Referenced by FatRead().

◆ FatReadPartialCluster()

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

Definition at line 1152 of file fat.c.

1153 {
1154  ULONG ClusterStartSector;
1155  ULONG SectorOffset, ReadSize, SectorCount;
1157  BOOLEAN Success = FALSE;
1158 
1159  //TRACE("FatReadPartialCluster() ClusterNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", ClusterNumber, StartingOffset, Length, Buffer);
1160 
1161  ClusterStartSector = ((ClusterNumber - 2) * Volume->SectorsPerCluster) + Volume->DataSectorStart;
1162 
1163  // This is the offset of the data in sectors
1164  SectorOffset = (StartingOffset / Volume->BytesPerSector);
1165  StartingOffset %= Volume->BytesPerSector;
1166 
1167  // Calculate how many sectors we need to read
1168  SectorCount = (StartingOffset + Length + Volume->BytesPerSector - 1) / Volume->BytesPerSector;
1169 
1170  // Calculate rounded up read size
1171  ReadSize = SectorCount * Volume->BytesPerSector;
1172 
1174  if (!ReadBuffer)
1175  {
1176  return FALSE;
1177  }
1178 
1179  if (FatReadVolumeSectors(Volume, ClusterStartSector + SectorOffset, SectorCount, ReadBuffer))
1180  {
1182  Success = TRUE;
1183  }
1184 
1186 
1187  return Success;
1188 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:290
#define TAG_FAT_BUFFER
Definition: fat.c:34
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define FALSE
Definition: types.h:117
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
#define SectorOffset(L)
Definition: cdprocs.h:1622
unsigned char BOOLEAN
Definition: bufpool.h:45
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: fat.c:1362
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG SectorCount
Definition: part_xbox.c:31
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by FatReadFile().

◆ FatReadVolumeSectors()

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

Definition at line 1362 of file fat.c.

1363 {
1365  ULONG Count;
1367 
1368  //TRACE("FatReadVolumeSectors(): SectorNumber %d, SectorCount %d, Buffer %p\n",
1369  // SectorNumber, SectorCount, Buffer);
1370 
1371  //
1372  // Seek to right position
1373  //
1374  Position.QuadPart = (ULONGLONG)SectorNumber * 512;
1375  Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
1376  if (Status != ESUCCESS)
1377  {
1378  TRACE("FatReadVolumeSectors() Failed to seek\n");
1379  return FALSE;
1380  }
1381 
1382  //
1383  // Read data
1384  //
1385  Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * 512, &Count);
1386  if (Status != ESUCCESS || Count != SectorCount * 512)
1387  {
1388  TRACE("FatReadVolumeSectors() Failed to read\n");
1389  return FALSE;
1390  }
1391 
1392  // Return success
1393  return TRUE;
1394 }
Definition: arc.h:32
#define TRUE
Definition: types.h:120
static COORD Position
Definition: mouse.c:34
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
ULONG ARC_STATUS
Definition: arc.h:4
#define FALSE
Definition: types.h:117
Definition: bufpool.h:45
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t ULONGLONG
Definition: typedefs.h:67
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
Status
Definition: gdiplustypes.h:24
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:243
ULONG SectorCount
Definition: part_xbox.c:31
unsigned int ULONG
Definition: retypes.h:1

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

◆ FatSearchDirectoryBufferForFile()

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

Definition at line 506 of file fat.c.

507 {
508  ULONG EntryCount;
509  ULONG CurrentEntry;
510  CHAR LfnNameBuffer[265];
511  CHAR ShortNameBuffer[20];
512  ULONG StartCluster;
513  DIRENTRY OurDirEntry;
514  LFN_DIRENTRY OurLfnDirEntry;
515  PDIRENTRY DirEntry = &OurDirEntry;
516  PLFN_DIRENTRY LfnDirEntry = &OurLfnDirEntry;
517 
518  EntryCount = DirectorySize / sizeof(DIRENTRY);
519 
520  TRACE("FatSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName);
521 
522  RtlZeroMemory(ShortNameBuffer, 13 * sizeof(CHAR));
523  RtlZeroMemory(LfnNameBuffer, 261 * sizeof(CHAR));
524 
525  for (CurrentEntry=0; CurrentEntry<EntryCount; CurrentEntry++, DirectoryBuffer = ((PDIRENTRY)DirectoryBuffer)+1)
526  {
527  OurLfnDirEntry = *((PLFN_DIRENTRY) DirectoryBuffer);
528  FatSwapLFNDirEntry(LfnDirEntry);
529  OurDirEntry = *((PDIRENTRY) DirectoryBuffer);
531 
532  //TRACE("Dumping directory entry %d:\n", CurrentEntry);
533  //DbgDumpBuffer(DPRINT_FILESYSTEM, DirEntry, sizeof(DIRENTRY));
534 
535  //
536  // Check if this is the last file in the directory
537  // If DirEntry[0] == 0x00 then that means all the
538  // entries after this one are unused. If this is the
539  // last entry then we didn't find the file in this directory.
540  //
541  if (DirEntry->FileName[0] == '\0')
542  {
543  return FALSE;
544  }
545 
546  //
547  // Check if this is a deleted entry or not
548  //
549  if (DirEntry->FileName[0] == '\xE5')
550  {
551  RtlZeroMemory(ShortNameBuffer, 13 * sizeof(CHAR));
552  RtlZeroMemory(LfnNameBuffer, 261 * sizeof(CHAR));
553  continue;
554  }
555 
556  //
557  // Check if this is a LFN entry
558  // If so it needs special handling
559  //
560  if (DirEntry->Attr == ATTR_LONG_NAME)
561  {
562  //
563  // Check to see if this is a deleted LFN entry, if so continue
564  //
565  if (LfnDirEntry->SequenceNumber & 0x80)
566  {
567  continue;
568  }
569 
570  //
571  // Mask off high two bits of sequence number
572  // and make the sequence number zero-based
573  //
574  LfnDirEntry->SequenceNumber &= 0x3F;
575  LfnDirEntry->SequenceNumber--;
576 
577  //
578  // Get all 13 LFN entry characters
579  //
580  if (LfnDirEntry->Name0_4[0] != 0xFFFF)
581  {
582  LfnNameBuffer[0 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[0];
583  }
584  if (LfnDirEntry->Name0_4[1] != 0xFFFF)
585  {
586  LfnNameBuffer[1 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[1];
587  }
588  if (LfnDirEntry->Name0_4[2] != 0xFFFF)
589  {
590  LfnNameBuffer[2 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[2];
591  }
592  if (LfnDirEntry->Name0_4[3] != 0xFFFF)
593  {
594  LfnNameBuffer[3 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[3];
595  }
596  if (LfnDirEntry->Name0_4[4] != 0xFFFF)
597  {
598  LfnNameBuffer[4 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name0_4[4];
599  }
600  if (LfnDirEntry->Name5_10[0] != 0xFFFF)
601  {
602  LfnNameBuffer[5 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[0];
603  }
604  if (LfnDirEntry->Name5_10[1] != 0xFFFF)
605  {
606  LfnNameBuffer[6 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[1];
607  }
608  if (LfnDirEntry->Name5_10[2] != 0xFFFF)
609  {
610  LfnNameBuffer[7 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[2];
611  }
612  if (LfnDirEntry->Name5_10[3] != 0xFFFF)
613  {
614  LfnNameBuffer[8 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[3];
615  }
616  if (LfnDirEntry->Name5_10[4] != 0xFFFF)
617  {
618  LfnNameBuffer[9 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[4];
619  }
620  if (LfnDirEntry->Name5_10[5] != 0xFFFF)
621  {
622  LfnNameBuffer[10 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name5_10[5];
623  }
624  if (LfnDirEntry->Name11_12[0] != 0xFFFF)
625  {
626  LfnNameBuffer[11 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name11_12[0];
627  }
628  if (LfnDirEntry->Name11_12[1] != 0xFFFF)
629  {
630  LfnNameBuffer[12 + (LfnDirEntry->SequenceNumber * 13)] = (UCHAR)LfnDirEntry->Name11_12[1];
631  }
632 
633  //TRACE("Dumping long name buffer:\n");
634  //DbgDumpBuffer(DPRINT_FILESYSTEM, LfnNameBuffer, 260);
635 
636  continue;
637  }
638 
639  //
640  // Check for the volume label attribute
641  // and skip over this entry if found
642  //
643  if (DirEntry->Attr & ATTR_VOLUMENAME)
644  {
645  RtlZeroMemory(ShortNameBuffer, 13 * sizeof(UCHAR));
646  RtlZeroMemory(LfnNameBuffer, 261 * sizeof(UCHAR));
647  continue;
648  }
649 
650  //
651  // If we get here then we've found a short file name
652  // entry and LfnNameBuffer contains the long file
653  // name or zeroes. All we have to do now is see if the
654  // file name matches either the short or long file name
655  // and fill in the FAT_FILE_INFO structure if it does
656  // or zero our buffers and continue looking.
657  //
658 
659  //
660  // Get short file name
661  //
662  FatParseShortFileName(ShortNameBuffer, DirEntry);
663 
664  //TRACE("Entry: %d LFN = %s\n", CurrentEntry, LfnNameBuffer);
665  //TRACE("Entry: %d DOS name = %s\n", CurrentEntry, ShortNameBuffer);
666 
667  //
668  // See if the file name matches either the short or long name
669  //
670  if (((strlen(FileName) == strlen(LfnNameBuffer)) && (_stricmp(FileName, LfnNameBuffer) == 0)) ||
671  ((strlen(FileName) == strlen(ShortNameBuffer)) && (_stricmp(FileName, ShortNameBuffer) == 0))) {
672  //
673  // We found the entry, now fill in the FAT_FILE_INFO struct
674  //
675  FatFileInfoPointer->Attributes = DirEntry->Attr;
676  FatFileInfoPointer->FileSize = DirEntry->Size;
677  FatFileInfoPointer->FilePointer = 0;
678  StartCluster = ((ULONG)DirEntry->ClusterHigh << 16) + DirEntry->ClusterLow;
679  FatFileInfoPointer->CurrentCluster = StartCluster;
680  FatFileInfoPointer->StartCluster = StartCluster;
681 
682  TRACE("MSDOS Directory Entry:\n");
683  TRACE("FileName[11] = %c%c%c%c%c%c%c%c%c%c%c\n", DirEntry->FileName[0], DirEntry->FileName[1], DirEntry->FileName[2], DirEntry->FileName[3], DirEntry->FileName[4], DirEntry->FileName[5], DirEntry->FileName[6], DirEntry->FileName[7], DirEntry->FileName[8], DirEntry->FileName[9], DirEntry->FileName[10]);
684  TRACE("Attr = 0x%x\n", DirEntry->Attr);
685  TRACE("ReservedNT = 0x%x\n", DirEntry->ReservedNT);
686  TRACE("TimeInTenths = %d\n", DirEntry->TimeInTenths);
687  TRACE("CreateTime = %d\n", DirEntry->CreateTime);
688  TRACE("CreateDate = %d\n", DirEntry->CreateDate);
689  TRACE("LastAccessDate = %d\n", DirEntry->LastAccessDate);
690  TRACE("ClusterHigh = 0x%x\n", DirEntry->ClusterHigh);
691  TRACE("Time = %d\n", DirEntry->Time);
692  TRACE("Date = %d\n", DirEntry->Date);
693  TRACE("ClusterLow = 0x%x\n", DirEntry->ClusterLow);
694  TRACE("Size = %d\n", DirEntry->Size);
695  TRACE("StartCluster = 0x%x\n", StartCluster);
696 
697  return TRUE;
698  }
699 
700  //
701  // Nope, no match - zero buffers and continue looking
702  //
703  RtlZeroMemory(ShortNameBuffer, 13 * sizeof(UCHAR));
704  RtlZeroMemory(LfnNameBuffer, 261 * sizeof(UCHAR));
705  continue;
706  }
707 
708  return FALSE;
709 }
struct DIRENTRY * PDIRENTRY
UCHAR SequenceNumber
Definition: fat.h:120
VOID FatSwapDirEntry(PDIRENTRY Obj)
Definition: fat.c:102
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
ULONG StartCluster
Definition: fat.h:154
#define ATTR_LONG_NAME
Definition: fat.h:165
#define _stricmp
Definition: cat.c:22
#define ATTR_VOLUMENAME
Definition: fat.h:162
struct LFN_DIRENTRY * PLFN_DIRENTRY
#define FALSE
Definition: types.h:117
ULONG FilePointer
Definition: fat.h:152
struct tagDIRENTRY DIRENTRY
WCHAR Name5_10[6]
Definition: fat.h:125
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR Name0_4[5]
Definition: fat.h:121
ULONG CurrentCluster
Definition: fat.h:153
unsigned char UCHAR
Definition: xmlstorage.h:181
void FatParseShortFileName(PCHAR Buffer, PDIRENTRY DirEntry)
Definition: fat.c:866
Definition: fat.h:102
ULONG FileSize
Definition: fat.h:151
VOID FatSwapLFNDirEntry(PLFN_DIRENTRY Obj)
Definition: fat.c:114
WCHAR Name11_12[2]
Definition: fat.h:127
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR Attributes
Definition: fat.h:155

Referenced by FatLookupFile().

◆ FatSeek()

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

Definition at line 1480 of file fat.c.

1481 {
1484  LARGE_INTEGER NewPosition = *Position;
1485 
1486  switch (SeekMode)
1487  {
1488  case SeekAbsolute:
1489  break;
1490  case SeekRelative:
1491  NewPosition.QuadPart += (ULONGLONG)FileHandle->FilePointer;
1492  break;
1493  default:
1494  ASSERT(FALSE);
1495  return EINVAL;
1496  }
1497 
1498  if (NewPosition.HighPart != 0)
1499  return EINVAL;
1500  if (NewPosition.LowPart >= FileHandle->FileSize)
1501  return EINVAL;
1502 
1503  TRACE("FatSeek() NewPosition = %u, OldPointer = %u, SeekMode = %d\n", NewPosition.LowPart, FileHandle->FilePointer, SeekMode);
1504 
1505  {
1506  UINT32 OldClusterIdx = FileHandle->FilePointer / (Volume->SectorsPerCluster * Volume->BytesPerSector);
1507  UINT32 NewClusterIdx = NewPosition.LowPart / (Volume->SectorsPerCluster * Volume->BytesPerSector);
1508 
1509  TRACE("FatSeek() OldClusterIdx: %u, NewClusterIdx: %u\n", OldClusterIdx, NewClusterIdx);
1510 
1511  if (NewClusterIdx != OldClusterIdx)
1512  {
1513  UINT32 CurrentClusterIdx, ClusterNumber;
1514 
1515  if (NewClusterIdx > OldClusterIdx)
1516  {
1517  CurrentClusterIdx = OldClusterIdx;
1518  ClusterNumber = FileHandle->CurrentCluster;
1519  }
1520  else
1521  {
1522  CurrentClusterIdx = 0;
1523  ClusterNumber = FileHandle->StartCluster;
1524  }
1525 
1526  for (; CurrentClusterIdx < NewClusterIdx; CurrentClusterIdx++)
1527  {
1528  if (!FatGetFatEntry(Volume, ClusterNumber, &ClusterNumber))
1529  {
1530  return EIO;
1531  }
1532  }
1533  FileHandle->CurrentCluster = ClusterNumber;
1534  }
1535  }
1536 
1537  FileHandle->FilePointer = NewPosition.LowPart;
1538 
1539  return ESUCCESS;
1540 }
Definition: arc.h:32
Definition: arc.h:39
static COORD Position
Definition: mouse.c:34
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
Definition: fat.c:951
HANDLE FileHandle
Definition: stats.c:38
#define FALSE
Definition: types.h:117
unsigned int UINT32
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t ULONGLONG
Definition: typedefs.h:67
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG LowPart
Definition: typedefs.h:106
Definition: arc.h:40
LONGLONG QuadPart
Definition: typedefs.h:114

◆ FatSwapDirEntry()

VOID FatSwapDirEntry ( PDIRENTRY  Obj)

Definition at line 102 of file fat.c.

103 {
104  SW(Obj, CreateTime);
105  SW(Obj, CreateDate);
106  SW(Obj, LastAccessDate);
107  SW(Obj, ClusterHigh);
108  SW(Obj, Time);
109  SW(Obj, Date);
110  SW(Obj, ClusterLow);
111  SD(Obj, Size);
112 }
#define SD(Object, Field)
Definition: bytesex.h:10
#define SW(Object, Field)
Definition: bytesex.h:11
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
static PLARGE_INTEGER Time
Definition: time.c:105

Referenced by FatSearchDirectoryBufferForFile().

◆ FatSwapFat32BootSector()

VOID FatSwapFat32BootSector ( PFAT32_BOOTSECTOR  Obj)

Definition at line 75 of file fat.c.

76 {
77  SW(Obj, BytesPerSector);
78  SW(Obj, ReservedSectors);
79  SW(Obj, RootDirEntries);
80  SW(Obj, TotalSectors);
81  SW(Obj, SectorsPerFat);
83  SD(Obj, HiddenSectors);
84  SD(Obj, TotalSectorsBig);
85  SD(Obj, SectorsPerFatBig);
86  SW(Obj, ExtendedFlags);
87  SW(Obj, FileSystemVersion);
88  SD(Obj, RootDirStartCluster);
89  SW(Obj, FsInfo);
91  SD(Obj, VolumeSerialNumber);
92  SW(Obj, BootSectorMagic);
93 }
#define SD(Object, Field)
Definition: bytesex.h:10
#define SW(Object, Field)
Definition: bytesex.h:11
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
Definition: iofuncs.h:2066
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
Definition: install.c:61

Referenced by FatOpenVolume().

◆ FatSwapFatBootSector()

VOID FatSwapFatBootSector ( PFAT_BOOTSECTOR  Obj)

Definition at line 60 of file fat.c.

61 {
62  SW(Obj, BytesPerSector);
63  SW(Obj, ReservedSectors);
64  SW(Obj, RootDirEntries);
65  SW(Obj, TotalSectors);
66  SW(Obj, SectorsPerFat);
69  SD(Obj, HiddenSectors);
70  SD(Obj, TotalSectorsBig);
71  SD(Obj, VolumeSerialNumber);
72  SW(Obj, BootSectorMagic);
73 }
#define SD(Object, Field)
Definition: bytesex.h:10
#define SW(Object, Field)
Definition: bytesex.h:11
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
Definition: iofuncs.h:2066
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2066

Referenced by FatOpenVolume().

◆ FatSwapFatXBootSector()

VOID FatSwapFatXBootSector ( PFATX_BOOTSECTOR  Obj)

Definition at line 95 of file fat.c.

96 {
97  SD(Obj, VolumeSerialNumber);
98  SD(Obj, SectorsPerCluster);
99  SW(Obj, NumberOfFats);
100 }
#define SD(Object, Field)
Definition: bytesex.h:10
#define SW(Object, Field)
Definition: bytesex.h:11

Referenced by FatOpenVolume().

◆ FatSwapFatXDirEntry()

VOID FatSwapFatXDirEntry ( PFATX_DIRENTRY  Obj)

Definition at line 126 of file fat.c.

127 {
128  SD(Obj, StartCluster);
129  SD(Obj, Size);
130  SW(Obj, Time);
131  SW(Obj, Date);
132  SW(Obj, CreateTime);
133  SW(Obj, CreateDate);
134  SW(Obj, LastAccessTime);
135  SW(Obj, LastAccessDate);
136 }
#define SD(Object, Field)
Definition: bytesex.h:10
#define SW(Object, Field)
Definition: bytesex.h:11
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
static PLARGE_INTEGER Time
Definition: time.c:105

Referenced by FatXSearchDirectoryBufferForFile().

◆ FatSwapLFNDirEntry()

VOID FatSwapLFNDirEntry ( PLFN_DIRENTRY  Obj)

Definition at line 114 of file fat.c.

115 {
116  int i;
117  SW(Obj, StartCluster);
118  for(i = 0; i < 5; i++)
119  Obj->Name0_4[i] = SWAPW(Obj->Name0_4[i]);
120  for(i = 0; i < 6; i++)
121  Obj->Name5_10[i] = SWAPW(Obj->Name5_10[i]);
122  for(i = 0; i < 2; i++)
123  Obj->Name11_12[i] = SWAPW(Obj->Name11_12[i]);
124 }
#define SWAPW(x)
Definition: bytesex.h:8
#define SW(Object, Field)
Definition: bytesex.h:11
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

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 711 of file fat.c.

712 {
713  ULONG EntryCount;
714  ULONG CurrentEntry;
716  FATX_DIRENTRY OurDirEntry;
717  PFATX_DIRENTRY DirEntry = &OurDirEntry;
718 
719  EntryCount = DirectorySize / sizeof(FATX_DIRENTRY);
720 
721  TRACE("FatXSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName);
722 
724 
725  for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++, DirectoryBuffer = ((PFATX_DIRENTRY)DirectoryBuffer)+1)
726  {
727  OurDirEntry = *(PFATX_DIRENTRY) DirectoryBuffer;
728  FatSwapFatXDirEntry(&OurDirEntry);
729  if (0xff == DirEntry->FileNameSize)
730  {
731  break;
732  }
733  if (0xe5 == DirEntry->FileNameSize)
734  {
735  continue;
736  }
737  if (FileNameLen == DirEntry->FileNameSize &&
738  0 == _strnicmp(FileName, DirEntry->FileName, FileNameLen))
739  {
740  /*
741  * We found the entry, now fill in the FAT_FILE_INFO struct
742  */
743  FatFileInfoPointer->Attributes = DirEntry->Attr;
744  FatFileInfoPointer->FileSize = DirEntry->Size;
745  FatFileInfoPointer->FilePointer = 0;
746  FatFileInfoPointer->CurrentCluster = DirEntry->StartCluster;
747  FatFileInfoPointer->StartCluster = DirEntry->StartCluster;
748 
749  TRACE("FATX Directory Entry:\n");
750  TRACE("FileNameSize = %d\n", DirEntry->FileNameSize);
751  TRACE("Attr = 0x%x\n", DirEntry->Attr);
752  TRACE("StartCluster = 0x%x\n", DirEntry->StartCluster);
753  TRACE("Size = %d\n", DirEntry->Size);
754  TRACE("Time = %d\n", DirEntry->Time);
755  TRACE("Date = %d\n", DirEntry->Date);
756  TRACE("CreateTime = %d\n", DirEntry->CreateTime);
757  TRACE("CreateDate = %d\n", DirEntry->CreateDate);
758  TRACE("LastAccessTime = %d\n", DirEntry->LastAccessTime);
759  TRACE("LastAccessDate = %d\n", DirEntry->LastAccessDate);
760 
761  return TRUE;
762  }
763  }
764 
765  return FALSE;
766 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
ULONG StartCluster
Definition: fat.h:154
VOID FatSwapFatXDirEntry(PFATX_DIRENTRY Obj)
Definition: fat.c:126
struct FATX_DIRENTRY * PFATX_DIRENTRY
#define FALSE
Definition: types.h:117
ULONG FilePointer
Definition: fat.h:152
#define TRACE(s)
Definition: solgame.cpp:4
Dirent FileNameLen
Definition: dirsup.c:506
ULONG CurrentCluster
Definition: fat.h:153
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG FileSize
Definition: fat.h:151
unsigned int ULONG
Definition: retypes.h:1
UCHAR Attributes
Definition: fat.h:155

Referenced by FatLookupFile().

Variable Documentation

◆ DirectoryBufferListHead

LIST_ENTRY DirectoryBufferListHead = {&DirectoryBufferListHead, &DirectoryBufferListHead}

Definition at line 417 of file fat.c.

Referenced by FatBufferDirectory().

◆ FatFuncTable

const DEVVTBL FatFuncTable
Initial value:
=
{
L"fastfat",
}
ARC_STATUS FatGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fat.c:1405
ARC_STATUS FatRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fat.c:1461
static const WCHAR L[]
Definition: oid.c:1250
ARC_STATUS FatOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fat.c:1419
ARC_STATUS FatSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fat.c:1480
ARC_STATUS FatClose(ULONG FileId)
Definition: fat.c:1396

Definition at line 1542 of file fat.c.

Referenced by FatMount().

◆ FatVolumes

Definition at line 58 of file fat.c.

Referenced by FatMount(), and FatOpen().