From 91e657f78287f7faa36440143ef376a21e74a36c Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Sat, 2 Apr 2011 15:22:48 +0000 Subject: [PATCH] {FULLFAT] - Update FullFat to the latest stable release (1.0.5) - I'm awaiting a reply from James as to when 1.1.0 will be released as it have some nice improvements. svn path=/trunk/; revision=51227 --- .../include/reactos/libs/fullfat/ff_config.h | 15 +- reactos/include/reactos/libs/fullfat/ff_dir.h | 2 +- reactos/include/reactos/libs/fullfat/ff_fat.h | 2 +- .../include/reactos/libs/fullfat/ff_fatdef.h | 90 +++++++++ .../include/reactos/libs/fullfat/ff_ioman.h | 19 +- .../include/reactos/libs/fullfat/ff_memory.h | 118 +++++++++++- .../include/reactos/libs/fullfat/fullfat.h | 8 + reactos/lib/3rdparty/fullfat/ff_dir.c | 1 - reactos/lib/3rdparty/fullfat/ff_dir.h | 2 +- reactos/lib/3rdparty/fullfat/ff_fat.c | 28 ++- reactos/lib/3rdparty/fullfat/ff_file.c | 52 ++++- reactos/lib/3rdparty/fullfat/ff_hash.c | 4 +- reactos/lib/3rdparty/fullfat/ff_ioman.c | 179 ++++++++++++------ reactos/lib/3rdparty/fullfat/ff_memory.c | 106 ++++------- 14 files changed, 456 insertions(+), 170 deletions(-) create mode 100644 reactos/include/reactos/libs/fullfat/ff_fatdef.h diff --git a/reactos/include/reactos/libs/fullfat/ff_config.h b/reactos/include/reactos/libs/fullfat/ff_config.h index f81c79ac7c9..4588ef9c305 100644 --- a/reactos/include/reactos/libs/fullfat/ff_config.h +++ b/reactos/include/reactos/libs/fullfat/ff_config.h @@ -74,13 +74,24 @@ // within the same path. E.g. a copy \dir1\*.* \dir2\*.* command. // This command requires FF_MAX_PATH number of bytes of memory. (Defined below, default 2600). +//---------- BLKDEV USES SEMAPHORE +#define FF_BLKDEV_USES_SEM // When defined, each call to fnReadBlocks and fnWriteBlocks will be done while semaphore is locked + // See also ff_safety.c + // (HT addition) + #define FF_PATH_CACHE_DEPTH 2 // The Number of PATH's to Cache. //---------- DON'T USE MALLOC //#define FF_NO_MALLOC -//---------- DON'T +#define FF_MALLOC(aSize) malloc(aSize) +#define FF_FREE(apPtr) free(apPtr) + +//#define FF_INLINE_MEMORY_ACCESS + +//#define FF_INLINE static __forceinline // Keywords to inline functions (Windows) +#define FF_INLINE static inline // Standard for GCC //---------- Hash Table Support @@ -117,7 +128,7 @@ //---------- AUTOMATIC SETTINGS DO NOT EDIT -- These configure your options from above, and check sanity! #ifdef FF_LFN_SUPPORT -#define FF_MAX_FILENAME 260 +#define FF_MAX_FILENAME (129) #else #define FF_MAX_FILENAME 13 #endif diff --git a/reactos/include/reactos/libs/fullfat/ff_dir.h b/reactos/include/reactos/libs/fullfat/ff_dir.h index 7415eac06e6..41eb7278f8d 100644 --- a/reactos/include/reactos/libs/fullfat/ff_dir.h +++ b/reactos/include/reactos/libs/fullfat/ff_dir.h @@ -43,7 +43,7 @@ #include "ff_ioman.h" #include "ff_blk.h" #include "ff_fat.h" -#include "fat.h" +#include "ff_fatdef.h" #include "ff_memory.h" #include "ff_time.h" #include "ff_hash.h" diff --git a/reactos/include/reactos/libs/fullfat/ff_fat.h b/reactos/include/reactos/libs/fullfat/ff_fat.h index 2e6ff6702b9..8add6d0132e 100644 --- a/reactos/include/reactos/libs/fullfat/ff_fat.h +++ b/reactos/include/reactos/libs/fullfat/ff_fat.h @@ -39,7 +39,7 @@ #define _FF_FAT_H_ #include "ff_config.h" -#include "fat.h" +#include "ff_fatdef.h" #include "ff_ioman.h" #include "ff_blk.h" #include "ff_types.h" diff --git a/reactos/include/reactos/libs/fullfat/ff_fatdef.h b/reactos/include/reactos/libs/fullfat/ff_fatdef.h new file mode 100644 index 00000000000..7fd7c3c5f6f --- /dev/null +++ b/reactos/include/reactos/libs/fullfat/ff_fatdef.h @@ -0,0 +1,90 @@ +/***************************************************************************** + * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * + * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + * IMPORTANT NOTICE: * + * ================= * + * Alternative Licensing is available directly from the Copyright holder, * + * (James Walmsley). For more information consult LICENSING.TXT to obtain * + * a Commercial license. * + * * + * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * + * * + * Removing the above notice is illegal and will invalidate this license. * + ***************************************************************************** + * See http://worm.me.uk/fullfat for more information. * + * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * + *****************************************************************************/ +#ifndef _FF_FATDEF_H_ +#define _FF_FATDEF_H_ + +/* + This file defines offsets to various data for the FAT specification. +*/ + +// MBR / PBR Offsets + +#define FF_FAT_BYTES_PER_SECTOR 0x00B +#define FF_FAT_SECTORS_PER_CLUS 0x00D +#define FF_FAT_RESERVED_SECTORS 0x00E +#define FF_FAT_NUMBER_OF_FATS 0x010 +#define FF_FAT_ROOT_ENTRY_COUNT 0x011 +#define FF_FAT_16_TOTAL_SECTORS 0x013 +#define FF_FAT_32_TOTAL_SECTORS 0x020 +#define FF_FAT_16_SECTORS_PER_FAT 0x016 +#define FF_FAT_32_SECTORS_PER_FAT 0x024 +#define FF_FAT_ROOT_DIR_CLUSTER 0x02C + +#define FF_FAT_16_VOL_LABEL 0x02B +#define FF_FAT_32_VOL_LABEL 0x047 + +#define FF_FAT_PTBL 0x1BE +#define FF_FAT_PTBL_LBA 0x008 +#define FF_FAT_PTBL_ACTIVE 0x000 +#define FF_FAT_PTBL_ID 0x004 + +#define FF_FAT_MBR_SIGNATURE 0x1FE + +#define FF_FAT_DELETED 0xE5 + +// Directory Entry Offsets +#define FF_FAT_DIRENT_SHORTNAME 0x000 +#define FF_FAT_DIRENT_ATTRIB 0x00B +#define FF_FAT_DIRENT_CREATE_TIME 0x00E ///< Creation Time. +#define FF_FAT_DIRENT_CREATE_DATE 0x010 ///< Creation Date. +#define FF_FAT_DIRENT_LASTACC_DATE 0x012 ///< Date of Last Access. +#define FF_FAT_DIRENT_CLUS_HIGH 0x014 +#define FF_FAT_DIRENT_LASTMOD_TIME 0x016 ///< Time of Last modification. +#define FF_FAT_DIRENT_LASTMOD_DATE 0x018 ///< Date of Last modification. +#define FF_FAT_DIRENT_CLUS_LOW 0x01A +#define FF_FAT_DIRENT_FILESIZE 0x01C +#define FF_FAT_LFN_ORD 0x000 +#define FF_FAT_LFN_NAME_1 0x001 +#define FF_FAT_LFN_CHECKSUM 0x00D +#define FF_FAT_LFN_NAME_2 0x00E +#define FF_FAT_LFN_NAME_3 0x01C + +// Dirent Attributes +#define FF_FAT_ATTR_READONLY 0x01 +#define FF_FAT_ATTR_HIDDEN 0x02 +#define FF_FAT_ATTR_SYSTEM 0x04 +#define FF_FAT_ATTR_VOLID 0x08 +#define FF_FAT_ATTR_DIR 0x10 +#define FF_FAT_ATTR_ARCHIVE 0x20 +#define FF_FAT_ATTR_LFN 0x0F + +#endif + diff --git a/reactos/include/reactos/libs/fullfat/ff_ioman.h b/reactos/include/reactos/libs/fullfat/ff_ioman.h index 187ffa347f9..d59c10593cd 100644 --- a/reactos/include/reactos/libs/fullfat/ff_ioman.h +++ b/reactos/include/reactos/libs/fullfat/ff_ioman.h @@ -100,10 +100,10 @@ typedef struct { **/ typedef struct { FF_T_UINT32 Sector; ///< The LBA of the Cached sector. - FF_T_UINT8 Mode; ///< Read or Write mode. + FF_T_UINT32 LRU; ///< For the Least Recently Used algorithm. FF_T_UINT16 NumHandles; ///< Number of objects using this buffer. FF_T_UINT16 Persistance; ///< For the persistance algorithm. - FF_T_UINT32 LRU; ///< For the Least Recently Used algorithm. + FF_T_UINT8 Mode; ///< Read or Write mode. FF_T_BOOL Modified; ///< If the sector was modified since read. FF_T_BOOL Valid; ///< Initially FALSE. FF_T_UINT8 *pBuffer; ///< Pointer to the cache block. @@ -129,7 +129,7 @@ typedef struct { FF_T_UINT16 BlkSize; ///< Size of a Sector Block in bytes. FF_T_UINT8 BlkFactor; ///< Scale Factor for blocksizes above 512! //FF_T_INT8 Name[FF_MAX_PARTITION_NAME]; ///< Partition Identifier e.g. c: sd0: etc. - //FF_T_INT8 VolLabel[12]; ///< Volume Label of the partition. + FF_T_INT8 VolLabel[12]; ///< Volume Label of the partition. FF_T_UINT32 BeginLBA; ///< LBA start address of the partition. FF_T_UINT32 PartSize; ///< Size of Partition in number of sectors. FF_T_UINT32 FatBeginLBA; ///< LBA of the FAT tables. @@ -182,14 +182,15 @@ typedef struct { FF_BLK_DEVICE *pBlkDevice; ///< Pointer to a Block device description. FF_PARTITION *pPartition; ///< Pointer to a partition description. FF_BUFFER *pBuffers; ///< Pointer to the first buffer description. - FF_T_UINT32 LastReplaced; ///< Marks which sector was last replaced in the cache. - FF_T_UINT16 BlkSize; ///< The Block size that IOMAN is configured to. - FF_T_UINT8 *pCacheMem; ///< Pointer to a block of memory for the cache. - FF_T_UINT16 CacheSize; ///< Size of the cache in number of Sectors. - FF_T_UINT8 MemAllocation; ///< Bit-Mask identifying allocated pointers. - FF_T_UINT8 Locks; ///< Lock Flag for FAT & DIR Locking etc (This must be accessed via a semaphore). void *pSemaphore; ///< Pointer to a Semaphore object. (For buffer description modifications only!). void *FirstFile; ///< Pointer to the first File object. + FF_T_UINT8 *pCacheMem; ///< Pointer to a block of memory for the cache. + FF_T_UINT32 LastReplaced; ///< Marks which sector was last replaced in the cache. + FF_T_UINT16 BlkSize; ///< The Block size that IOMAN is configured to. + FF_T_UINT16 CacheSize; ///< Size of the cache in number of Sectors. + FF_T_UINT8 PreventFlush; ///< Flushing to disk only allowed when 0 + FF_T_UINT8 MemAllocation; ///< Bit-Mask identifying allocated pointers. + FF_T_UINT8 Locks; ///< Lock Flag for FAT & DIR Locking etc (This must be accessed via a semaphore). } FF_IOMAN; // Bit-Masks for Memory Allocation testing. diff --git a/reactos/include/reactos/libs/fullfat/ff_memory.h b/reactos/include/reactos/libs/fullfat/ff_memory.h index 1d4507c4a85..555a829210a 100644 --- a/reactos/include/reactos/libs/fullfat/ff_memory.h +++ b/reactos/include/reactos/libs/fullfat/ff_memory.h @@ -41,19 +41,119 @@ #include "ff_config.h" #include "ff_types.h" - +/* + HT changed type of aOffset to u32 +*/ //---------- PROTOTYPES -FF_T_UINT8 FF_getChar (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset); -FF_T_UINT16 FF_getShort (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset); -FF_T_UINT32 FF_getLong (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset); +#if defined(FF_LITTLE_ENDIAN) -void FF_putChar (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value); -void FF_putShort (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT16 Value); -void FF_putLong (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT32 Value); +typedef struct { + FF_T_UINT8 u8_0; + FF_T_UINT8 u8_1; +} FF_T_SHORT; -void *FF_Malloc(FF_T_UINT32 allocSize); -void FF_Free(void *pBuffer); +typedef struct { + FF_T_UINT8 u8_0; + FF_T_UINT8 u8_1; + FF_T_UINT8 u8_2; + FF_T_UINT8 u8_3; +} FF_T_LONG; + +#elif defined(FF_BIG_ENDIAN) + +typedef struct { + FF_T_UINT8 u8_1; + FF_T_UINT8 u8_0; +} FF_T_SHORT; + +typedef struct { + FF_T_UINT8 u8_3; + FF_T_UINT8 u8_2; + FF_T_UINT8 u8_1; + FF_T_UINT8 u8_0; +} FF_T_LONG; + +#else + +#error Little or Big Endian? + +#endif + +//! 16-bit union. +typedef union { + FF_T_UINT16 u16; + FF_T_SHORT bytes; +} FF_T_UN16; + +//! 32-bit union. +typedef union { + FF_T_UINT32 u32; + FF_T_LONG bytes; +} FF_T_UN32; + +/* HT inlined these functions: + */ + +#ifdef FF_INLINE_MEMORY_ACCESS + +FF_INLINE FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) +{ + return (FF_T_UINT8) (pBuffer[aOffset]); +} + +FF_INLINE FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) +{ + FF_T_UN16 u16; + pBuffer += aOffset; + u16.bytes.u8_1 = pBuffer[1]; + u16.bytes.u8_0 = pBuffer[0]; + return u16.u16; +} + +FF_INLINE FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) { + FF_T_UN32 u32; + pBuffer += aOffset; + u32.bytes.u8_3 = pBuffer[3]; + u32.bytes.u8_2 = pBuffer[2]; + u32.bytes.u8_1 = pBuffer[1]; + u32.bytes.u8_0 = pBuffer[0]; + return u32.u32; +} + +FF_INLINE void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value) { + pBuffer[aOffset] = Value; +} + +FF_INLINE void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT16 Value) { + FF_T_UN16 u16; + u16.u16 = Value; + pBuffer += aOffset; + pBuffer[0] = u16.bytes.u8_0; + pBuffer[1] = u16.bytes.u8_1; +} + +FF_INLINE void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT32 Value) { + FF_T_UN32 u32; + u32.u32 = Value; + pBuffer += aOffset; + pBuffer[0] = u32.bytes.u8_0; + pBuffer[1] = u32.bytes.u8_1; + pBuffer[2] = u32.bytes.u8_2; + pBuffer[3] = u32.bytes.u8_3; +} + +#else + +FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset); +FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset); +FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset); +void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value); +void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT16 Value); +void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT32 Value); + + +#endif #endif diff --git a/reactos/include/reactos/libs/fullfat/fullfat.h b/reactos/include/reactos/libs/fullfat/fullfat.h index dd8da071cf5..e4e8363e432 100644 --- a/reactos/include/reactos/libs/fullfat/fullfat.h +++ b/reactos/include/reactos/libs/fullfat/fullfat.h @@ -32,6 +32,10 @@ #ifndef _FULLFAT_H_ #define _FULLFAT_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "ff_config.h" #include "ff_ioman.h" #include "ff_fat.h" @@ -41,6 +45,10 @@ #include "ff_crc.h" #include "ff_hash.h" #include "ff_string.h" +//#include "ff_format.h" +#ifdef __cplusplus +} // extern "C" +#endif #endif diff --git a/reactos/lib/3rdparty/fullfat/ff_dir.c b/reactos/lib/3rdparty/fullfat/ff_dir.c index 6bba0b79020..f35d91c02e6 100644 --- a/reactos/lib/3rdparty/fullfat/ff_dir.c +++ b/reactos/lib/3rdparty/fullfat/ff_dir.c @@ -1769,4 +1769,3 @@ void FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 DirEntry) { }while(FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)) == FF_FAT_ATTR_LFN); } - diff --git a/reactos/lib/3rdparty/fullfat/ff_dir.h b/reactos/lib/3rdparty/fullfat/ff_dir.h index 7415eac06e6..41eb7278f8d 100644 --- a/reactos/lib/3rdparty/fullfat/ff_dir.h +++ b/reactos/lib/3rdparty/fullfat/ff_dir.h @@ -43,7 +43,7 @@ #include "ff_ioman.h" #include "ff_blk.h" #include "ff_fat.h" -#include "fat.h" +#include "ff_fatdef.h" #include "ff_memory.h" #include "ff_time.h" #include "ff_hash.h" diff --git a/reactos/lib/3rdparty/fullfat/ff_fat.c b/reactos/lib/3rdparty/fullfat/ff_fat.c index 1cbd420ffad..66769e56af7 100644 --- a/reactos/lib/3rdparty/fullfat/ff_fat.c +++ b/reactos/lib/3rdparty/fullfat/ff_fat.c @@ -136,13 +136,13 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) { FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize); - relClusterEntry = (FF_T_UINT16) (FatSectorEntry % pIoman->BlkSize); + relClusterEntry = (FF_T_UINT32) (FatSectorEntry % pIoman->BlkSize); FatSector = FF_getRealLBA(pIoman, FatSector); #ifdef FF_FAT12_SUPPORT if(pIoman->pPartition->Type == FF_T_FAT12) { - if(relClusterEntry == (pIoman->BlkSize - 1)) { + if(relClusterEntry == (FF_T_UINT32)(pIoman->BlkSize - 1)) { // Fat Entry SPANS a Sector! // First Buffer get the last Byte in buffer (first byte of our address)! pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); @@ -333,7 +333,7 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va FF_T_UINT32 FatSectorEntry; FF_T_UINT32 FatEntry; FF_T_UINT8 LBAadjust; - FF_T_UINT16 relClusterEntry; + FF_T_UINT32 relClusterEntry; #ifdef FF_FAT12_SUPPORT FF_T_UINT8 F12short[2]; // For FAT12 FAT Table Across sector boundary traversal. #endif @@ -350,13 +350,13 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize); - relClusterEntry = (FF_T_UINT16)(FatSectorEntry % pIoman->BlkSize); + relClusterEntry = (FF_T_UINT32)(FatSectorEntry % pIoman->BlkSize); FatSector = FF_getRealLBA(pIoman, FatSector); #ifdef FF_FAT12_SUPPORT if(pIoman->pPartition->Type == FF_T_FAT12) { - if(relClusterEntry == (FF_T_UINT16) (pIoman->BlkSize - 1)) { + if(relClusterEntry == (FF_T_UINT32)(pIoman->BlkSize - 1)) { // Fat Entry SPANS a Sector! // First Buffer get the last Byte in buffer (first byte of our address)! pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); @@ -497,6 +497,11 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) { for(i = FatSector; i < pIoman->pPartition->SectorsPerFAT; i++) { pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ); { + // HT addition: don't use non-existing clusters + if (nCluster >= pIoman->pPartition->NumClusters) { + FF_ReleaseBuffer(pIoman, pBuffer); + return 0; + } for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) { if(pIoman->pPartition->Type == FF_T_FAT32) { FatOffset = x * 4; @@ -612,6 +617,7 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_ FF_T_UINT32 fatEntry; FF_T_UINT32 currentCluster, chainLength = 0; FF_T_UINT32 iLen = 0; + FF_T_UINT32 lastFree = StartCluster; /* HT addition : reset LastFreeCluster */ fatEntry = StartCluster; @@ -622,9 +628,15 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_ do { fatEntry = FF_getFatEntry(pIoman, fatEntry); FF_putFatEntry(pIoman, currentCluster, 0x00000000); + if (lastFree > currentCluster) { + lastFree = currentCluster; + } currentCluster = fatEntry; iLen ++; }while(!FF_isEndOfChain(pIoman, fatEntry)); + if (pIoman->pPartition->LastFreeCluster > lastFree) { + pIoman->pPartition->LastFreeCluster = lastFree; + } FF_IncreaseFreeClusters(pIoman, iLen); } else { // Truncation - This is quite hard, because we can only do it backwards. @@ -694,7 +706,7 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) { } else { FatOffset = x * 2; FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; - FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, (FF_T_UINT16)FatSectorEntry); + FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FatSectorEntry); } if(FatEntry == 0x00000000) { FreeClusters += 1; @@ -706,7 +718,7 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) { FF_ReleaseBuffer(pIoman, pBuffer); } - return FreeClusters; + return FreeClusters <= pIoman->pPartition->NumClusters ? FreeClusters : pIoman->pPartition->NumClusters; } #ifdef FF_64_NUM_SUPPORT @@ -747,4 +759,4 @@ FF_T_UINT32 FF_GetFreeSize(FF_IOMAN *pIoman) { } return 0; } -#endif +#endif \ No newline at end of file diff --git a/reactos/lib/3rdparty/fullfat/ff_file.c b/reactos/lib/3rdparty/fullfat/ff_file.c index 7f982dc90d4..cd29e31562b 100644 --- a/reactos/lib/3rdparty/fullfat/ff_file.c +++ b/reactos/lib/3rdparty/fullfat/ff_file.c @@ -163,7 +163,7 @@ FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ER } return (FF_FILE *)NULL; } - pFile = FF_Malloc(sizeof(FF_FILE)); + pFile = FF_MALLOC(sizeof(FF_FILE)); if(!pFile) { if(pError) { *pError = FF_ERR_NOT_ENOUGH_MEMORY; @@ -222,7 +222,7 @@ FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ER if(Object.Attrib == FF_FAT_ATTR_DIR) { if(!(pFile->Mode & FF_MODE_DIR)) { // Not the object, File Not Found! - FF_Free(pFile); + FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_OBJECT_IS_A_DIR; } @@ -233,7 +233,7 @@ FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ER //---------- Ensure Read-Only files don't get opened for Writing. if((pFile->Mode & FF_MODE_WRITE) || (pFile->Mode & FF_MODE_APPEND)) { if((Object.Attrib & FF_FAT_ATTR_READONLY)) { - FF_Free(pFile); + FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_IS_READ_ONLY; } @@ -276,7 +276,7 @@ FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ER if(pFileChain->ObjectCluster == pFile->ObjectCluster) { // File is already open! DON'T ALLOW IT! FF_ReleaseSemaphore(pIoman->pSemaphore); - FF_Free(pFile); + FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_ALREADY_OPEN; } @@ -294,7 +294,7 @@ FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ER return pFile; }else { - FF_Free(pFile); + FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_NOT_FOUND; } @@ -305,7 +305,7 @@ FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ER *pError = FF_ERR_FILE_INVALID_PATH; } - FF_Free(pFile); + FF_FREE(pFile); return (FF_FILE *)NULL; } @@ -600,7 +600,14 @@ static FF_T_SINT32 FF_ReadClusters(FF_FILE *pFile, FF_T_UINT32 Count, FF_T_UINT8 do { if(pFile->pIoman->pBlkDevice->fnReadBlocks) { +#ifdef FF_BLKDEV_USES_SEM + FF_PendSemaphore(pFile->pIoman->pSemaphore); +#endif + // Called from FF_Read, sem not claimed RetVal = pFile->pIoman->pBlkDevice->fnReadBlocks(buffer, nItemLBA, Sectors, pFile->pIoman->pBlkDevice->pParam); +#ifdef FF_BLKDEV_USES_SEM + FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); +#endif if(RetVal == FF_ERR_DRIVER_BUSY) { FF_Yield(); FF_Sleep(FF_DRIVER_BUSY_SLEEP); @@ -703,7 +710,14 @@ static FF_T_SINT32 FF_WriteClusters(FF_FILE *pFile, FF_T_UINT32 Count, FF_T_UINT do { if(pFile->pIoman->pBlkDevice->fnWriteBlocks) { +#ifdef FF_BLKDEV_USES_SEM + FF_PendSemaphore(pFile->pIoman->pSemaphore); +#endif + // Called from FF_Write, sem not claimed RetVal = pFile->pIoman->pBlkDevice->fnWriteBlocks(buffer, nItemLBA, Sectors, pFile->pIoman->pBlkDevice->pParam); +#ifdef FF_BLKDEV_USES_SEM + FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); +#endif if(RetVal == FF_ERR_DRIVER_BUSY) { FF_Yield(); FF_Sleep(FF_DRIVER_BUSY_SLEEP); @@ -832,7 +846,13 @@ FF_T_SINT32 FF_Read(FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, do { if(pIoman->pBlkDevice->fnReadBlocks) { +#ifdef FF_BLKDEV_USES_SEM + FF_PendSemaphore(pFile->pIoman->pSemaphore); +#endif RetVal = pFile->pIoman->pBlkDevice->fnReadBlocks(buffer, nItemLBA, sSectors, pIoman->pBlkDevice->pParam); +#ifdef FF_BLKDEV_USES_SEM + FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); +#endif } if(RetVal == FF_ERR_DRIVER_BUSY) { FF_Yield(); @@ -887,7 +907,13 @@ FF_T_SINT32 FF_Read(FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, do { if(pIoman->pBlkDevice->fnReadBlocks) { +#ifdef FF_BLKDEV_USES_SEM + FF_PendSemaphore(pFile->pIoman->pSemaphore); +#endif RetVal = pFile->pIoman->pBlkDevice->fnReadBlocks(buffer, nItemLBA, sSectors, pIoman->pBlkDevice->pParam); +#ifdef FF_BLKDEV_USES_SEM + FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); +#endif } if(RetVal == FF_ERR_DRIVER_BUSY) { FF_Yield(); @@ -1116,7 +1142,13 @@ FF_T_SINT32 FF_Write(FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, do { if(pIoman->pBlkDevice->fnWriteBlocks) { +#ifdef FF_BLKDEV_USES_SEM + FF_PendSemaphore(pFile->pIoman->pSemaphore); +#endif RetVal = pFile->pIoman->pBlkDevice->fnWriteBlocks(buffer, nItemLBA, sSectors, pIoman->pBlkDevice->pParam); +#ifdef FF_BLKDEV_USES_SEM + FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); +#endif } if(RetVal == FF_ERR_DRIVER_BUSY) { FF_Yield(); @@ -1174,7 +1206,13 @@ FF_T_SINT32 FF_Write(FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, do { if(pIoman->pBlkDevice->fnWriteBlocks) { +#ifdef FF_BLKDEV_USES_SEM + FF_PendSemaphore(pFile->pIoman->pSemaphore); +#endif RetVal = pFile->pIoman->pBlkDevice->fnWriteBlocks(buffer, nItemLBA, sSectors, pIoman->pBlkDevice->pParam); +#ifdef FF_BLKDEV_USES_SEM + FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); +#endif } if(RetVal == FF_ERR_DRIVER_BUSY) { FF_Yield(); @@ -1405,7 +1443,7 @@ FF_ERROR FF_Close(FF_FILE *pFile) { FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); // If file written, flush to disk - FF_Free(pFile); + FF_FREE(pFile); // Simply free the pointer! return FF_ERR_NONE; } diff --git a/reactos/lib/3rdparty/fullfat/ff_hash.c b/reactos/lib/3rdparty/fullfat/ff_hash.c index 5bcaf4c66d2..4a07c81d37e 100644 --- a/reactos/lib/3rdparty/fullfat/ff_hash.c +++ b/reactos/lib/3rdparty/fullfat/ff_hash.c @@ -53,7 +53,7 @@ struct _FF_HASH_TABLE { * **/ FF_HASH_TABLE FF_CreateHashTable() { - FF_HASH_TABLE pHash = (FF_HASH_TABLE) FF_Malloc(sizeof(struct _FF_HASH_TABLE)); + FF_HASH_TABLE pHash = (FF_HASH_TABLE) FF_MALLOC(sizeof(struct _FF_HASH_TABLE)); if(pHash) { FF_ClearHashTable(pHash); @@ -110,7 +110,7 @@ FF_T_BOOL FF_isHashSet(FF_HASH_TABLE pHash, FF_T_UINT32 nHash) { FF_ERROR FF_DestroyHashTable(FF_HASH_TABLE pHash) { if(pHash) { - free(pHash); + FF_FREE(pHash); return FF_ERR_NONE; } return FF_ERR_NULL_POINTER; diff --git a/reactos/lib/3rdparty/fullfat/ff_ioman.c b/reactos/lib/3rdparty/fullfat/ff_ioman.c index c30126d3f28..60871f831a0 100644 --- a/reactos/lib/3rdparty/fullfat/ff_ioman.c +++ b/reactos/lib/3rdparty/fullfat/ff_ioman.c @@ -42,8 +42,10 @@ * Destroying a FullFAT IO object. **/ +#include + #include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, -#include "fat.h" +#include "ff_fatdef.h" extern FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman); extern FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman); @@ -89,7 +91,7 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl return NULL; // Memory Size not a multiple of BlkSize > 0 } - pIoman = (FF_IOMAN *) FF_Malloc(sizeof(FF_IOMAN)); + pIoman = (FF_IOMAN *) FF_MALLOC(sizeof(FF_IOMAN)); if(!pIoman) { // Ensure malloc() succeeded. if(pError) { @@ -98,62 +100,68 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl return NULL; } + memset (pIoman, '\0', sizeof(FF_IOMAN)); + // This is just a bit-mask, to use a byte to keep track of memory. // pIoman->MemAllocation = 0x00; // Unset all allocation identifiers. - pIoman->pBlkDevice = NULL; - pIoman->pBuffers = NULL; - pIoman->pCacheMem = NULL; - pIoman->pPartition = NULL; - pIoman->pSemaphore = NULL; - - pIoman->pPartition = (FF_PARTITION *) FF_Malloc(sizeof(FF_PARTITION)); - if(pIoman->pPartition) { // If succeeded, flag that allocation. - pIoman->MemAllocation |= FF_IOMAN_ALLOC_PART; - pIoman->pPartition->LastFreeCluster = 0; - pIoman->pPartition->PartitionMounted = FF_FALSE; // This should be checked by FF_Open(); -#ifdef FF_PATH_CACHE - pIoman->pPartition->PCIndex = 0; - for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { - pIoman->pPartition->PathCache[i].DirCluster = 0; - pIoman->pPartition->PathCache[i].Path[0] = '\0'; -#ifdef FF_HASH_TABLE_SUPPORT - pIoman->pPartition->PathCache[i].pHashTable = FF_CreateHashTable(); - pIoman->pPartition->PathCache[i].bHashed = FF_FALSE; -#endif + pIoman->pPartition = (FF_PARTITION *) FF_MALLOC(sizeof(FF_PARTITION)); + if(!pIoman->pPartition) { + if(pError) { + *pError = FF_ERR_NOT_ENOUGH_MEMORY; } + FF_DestroyIOMAN(pIoman); + return NULL; + } + memset (pIoman->pPartition, '\0', sizeof(FF_PARTITION)); + + pIoman->MemAllocation |= FF_IOMAN_ALLOC_PART; // If succeeded, flag that allocation. + pIoman->pPartition->LastFreeCluster = 0; + pIoman->pPartition->PartitionMounted = FF_FALSE; // This should be checked by FF_Open(); +#ifdef FF_PATH_CACHE + pIoman->pPartition->PCIndex = 0; + for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { + pIoman->pPartition->PathCache[i].DirCluster = 0; + pIoman->pPartition->PathCache[i].Path[0] = '\0'; +#ifdef FF_HASH_TABLE_SUPPORT + pIoman->pPartition->PathCache[i].pHashTable = FF_CreateHashTable(); + pIoman->pPartition->PathCache[i].bHashed = FF_FALSE; #endif - } else { + } +#endif + + pIoman->pBlkDevice = (FF_BLK_DEVICE *) FF_MALLOC(sizeof(FF_BLK_DEVICE)); + if(!pIoman->pBlkDevice) { // If succeeded, flag that allocation. + if(pError) { + *pError = FF_ERR_NOT_ENOUGH_MEMORY; + } FF_DestroyIOMAN(pIoman); return NULL; } + memset (pIoman->pBlkDevice, '\0', sizeof(FF_BLK_DEVICE)); + pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV; - pIoman->pBlkDevice = (FF_BLK_DEVICE *) FF_Malloc(sizeof(FF_BLK_DEVICE)); - if(pIoman->pBlkDevice) { // If succeeded, flag that allocation. - pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV; - - // Make sure all pointers are NULL - pIoman->pBlkDevice->fnReadBlocks = NULL; - pIoman->pBlkDevice->fnWriteBlocks = NULL; - pIoman->pBlkDevice->pParam = NULL; - - } else { - FF_DestroyIOMAN(pIoman); - return NULL; - } + // Make sure all pointers are NULL + pIoman->pBlkDevice->fnReadBlocks = NULL; + pIoman->pBlkDevice->fnWriteBlocks = NULL; + pIoman->pBlkDevice->pParam = NULL; // Organise the memory provided, or create our own! if(pCacheMem) { pIoman->pCacheMem = pCacheMem; }else { // No-Cache buffer provided (malloc) - pLong = (FF_T_UINT32 *) FF_Malloc(Size); + pLong = (FF_T_UINT32 *) FF_MALLOC(Size); pIoman->pCacheMem = (FF_T_UINT8 *) pLong; if(!pIoman->pCacheMem) { - pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS; + if(pError) { + *pError = FF_ERR_NOT_ENOUGH_MEMORY; + } FF_DestroyIOMAN(pIoman); return NULL; } + pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS; } + memset (pIoman->pCacheMem, '\0', Size); pIoman->BlkSize = BlkSize; pIoman->CacheSize = (FF_T_UINT16) (Size / BlkSize); @@ -163,14 +171,19 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl /* Malloc() memory for buffer objects. (FullFAT never refers to a buffer directly but uses buffer objects instead. Allows us to provide thread safety. */ - pIoman->pBuffers = (FF_BUFFER *) FF_Malloc(sizeof(FF_BUFFER) * pIoman->CacheSize); + pIoman->pBuffers = (FF_BUFFER *) FF_MALLOC(sizeof(FF_BUFFER) * pIoman->CacheSize); - if(pIoman->pBuffers) { - pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFDESCR; - FF_IOMAN_InitBufferDescriptors(pIoman); - } else { + if(!pIoman->pBuffers) { + if(pError) { + *pError = FF_ERR_NOT_ENOUGH_MEMORY; + } FF_DestroyIOMAN(pIoman); + return NULL; // HT added } + memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize); + + pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFDESCR; + FF_IOMAN_InitBufferDescriptors(pIoman); // Finally create a Semaphore for Buffer Description modifications. pIoman->pSemaphore = FF_CreateSemaphore(); @@ -196,22 +209,22 @@ FF_ERROR FF_DestroyIOMAN(FF_IOMAN *pIoman) { // Ensure pPartition pointer was allocated. if((pIoman->MemAllocation & FF_IOMAN_ALLOC_PART)) { - FF_Free(pIoman->pPartition); + FF_FREE(pIoman->pPartition); } // Ensure pBlkDevice pointer was allocated. if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BLKDEV)) { - FF_Free(pIoman->pBlkDevice); + FF_FREE(pIoman->pBlkDevice); } // Ensure pBuffers pointer was allocated. if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFDESCR)) { - FF_Free(pIoman->pBuffers); + FF_FREE(pIoman->pBuffers); } // Ensure pCacheMem pointer was allocated. if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFFERS)) { - FF_Free(pIoman->pCacheMem); + FF_FREE(pIoman->pCacheMem); } // Destroy any Semaphore that was created. @@ -220,7 +233,7 @@ FF_ERROR FF_DestroyIOMAN(FF_IOMAN *pIoman) { } // Finally free the FF_IOMAN object. - FF_Free(pIoman); + FF_FREE(pIoman); return FF_ERR_NONE; } @@ -236,15 +249,9 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman) { FF_T_UINT16 i; FF_BUFFER *pBuffer = pIoman->pBuffers; pIoman->LastReplaced = 0; + // HT : it is assmued that pBuffer was cleared by memset () for(i = 0; i < pIoman->CacheSize; i++) { - pBuffer->Mode = 0; - pBuffer->NumHandles = 0; - pBuffer->Persistance = 0; - pBuffer->LRU = 0; - pBuffer->Sector = 0; pBuffer->pBuffer = (FF_T_UINT8 *)((pIoman->pCacheMem) + (pIoman->BlkSize * i)); - pBuffer->Modified = FF_FALSE; - pBuffer->Valid = FF_FALSE; pBuffer++; } } @@ -273,12 +280,15 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman) { * @param Sector LBA address of the sector to fetch. * @param pBuffer Pointer to a byte-wise buffer to store the fetched data. * + * HT Note: will be called while semaphore claimed (by FF_GetBuffer) + * * @return FF_TRUE when valid, else FF_FALSE. **/ static FF_ERROR FF_IOMAN_FillBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 *pBuffer) { FF_T_SINT32 retVal = 0; if(pIoman->pBlkDevice->fnReadBlocks) { // Make sure we don't execute a NULL. do{ + // Called from FF_GetBuffer with semaphore claimed retVal = pIoman->pBlkDevice->fnReadBlocks(pBuffer, Sector, 1, pIoman->pBlkDevice->pParam); if(retVal == FF_ERR_DRIVER_BUSY) { FF_Sleep(FF_DRIVER_BUSY_SLEEP); @@ -306,9 +316,13 @@ static FF_ERROR FF_IOMAN_FillBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_U * @param Sector LBA address of the sector to fetch. * @param pBuffer Pointer to a byte-wise buffer to store the fetched data. * + * + * HT made it a globally accesible function to be used by new module ff_format.c + * Note that this function is called when semaphore is already locked + * * @return FF_TRUE when valid, else FF_FALSE. **/ -static FF_ERROR FF_IOMAN_FlushBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 *pBuffer) { +/* static */ FF_ERROR FF_IOMAN_FlushBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 *pBuffer) { FF_T_SINT32 retVal = 0; if(pIoman->pBlkDevice->fnWriteBlocks) { // Make sure we don't execute a NULL. do{ @@ -481,7 +495,7 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) { } } FF_ReleaseSemaphore(pIoman->pSemaphore); - FF_Yield(); + FF_Yield(); // Better to go asleep to give low-priority task a chance to release buffer(s) } return pBufMatch; // Return the Matched Buffer! @@ -500,7 +514,11 @@ void FF_ReleaseBuffer(FF_IOMAN *pIoman, FF_BUFFER *pBuffer) { // Protect description changes with a semaphore. FF_PendSemaphore(pIoman->pSemaphore); { - pBuffer->NumHandles--; + if (pBuffer->NumHandles) { + pBuffer->NumHandles--; + } else { + //printf ("FF_ReleaseBuffer: buffer not claimed\n"); + } } FF_ReleaseSemaphore(pIoman->pSemaphore); } @@ -630,6 +648,34 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) { return FF_ERR_IOMAN_NOT_FAT_FORMATTED; } + +static FF_T_SINT8 FF_PartitionCount (FF_T_UINT8 *pBuffer) +{ + FF_T_SINT8 count = 0; + FF_T_SINT8 part; + // Check PBR or MBR signature + if (FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0x55 && + FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0xAA ) { + // No MBR, but is it a PBR ? + if (FF_getChar(pBuffer, 0) == 0xEB && // PBR Byte 0 + FF_getChar(pBuffer, 2) == 0x90 && // PBR Byte 2 + (FF_getChar(pBuffer, 21) & 0xF0) == 0xF0) {// PBR Byte 21 : Media byte + return 1; // No MBR but PBR exist then only one partition + } + return 0; // No MBR and no PBR then no partition found + } + for (part = 0; part < 4; part++) { + FF_T_UINT8 active = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ACTIVE + (16 * part)); + FF_T_UINT8 part_id = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID + (16 * part)); + // The first sector must be a MBR, then check the partition entry in the MBR + if (active != 0x80 && (active != 0 || part_id == 0)) { + break; + } + count++; + } + return count; +} + /** * @public * @brief Mounts the Specified partition, the volume specified by the FF_IOMAN object provided. @@ -651,6 +697,7 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) { FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { FF_PARTITION *pPart; FF_BUFFER *pBuffer = 0; + int partCount; if(!pIoman) { return FF_ERR_NULL_POINTER; @@ -662,18 +709,27 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { pPart = pIoman->pPartition; + memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize); + memset (pIoman->pCacheMem, '\0', pIoman->BlkSize * pIoman->CacheSize); + + FF_IOMAN_InitBufferDescriptors(pIoman); + pIoman->FirstFile = 0; + pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ); if(!pBuffer) { return FF_ERR_DEVICE_DRIVER_FAILED; } + + partCount = FF_PartitionCount (pBuffer->pBuffer); + pPart->BlkSize = FF_getShort(pBuffer->pBuffer, FF_FAT_BYTES_PER_SECTOR); - if((pPart->BlkSize % 512) == 0 && pPart->BlkSize > 0) { + if (partCount == 0) { //(pPart->BlkSize % 512) == 0 && pPart->BlkSize > 0) { // Volume is not partitioned (MBR Found) pPart->BeginLBA = 0; } else { // Primary Partitions to deal with! - pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, (FF_T_UINT16)(FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber))); + pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber)); FF_ReleaseBuffer(pIoman, pBuffer); if(!pPart->BeginLBA) { @@ -690,6 +746,7 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { return FF_ERR_IOMAN_INVALID_FORMAT; } } + // Assume FAT16, then we'll adjust if its FAT32 pPart->ReservedSectors = FF_getShort(pBuffer->pBuffer, FF_FAT_RESERVED_SECTORS); pPart->FatBeginLBA = pPart->BeginLBA + pPart->ReservedSectors; @@ -709,6 +766,7 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { if(pPart->TotalSectors == 0) { pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); } + memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_32_VOL_LABEL, sizeof pPart->VolLabel); } else { // FAT16 pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT); pPart->TotalSectors = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_TOTAL_SECTORS); @@ -716,6 +774,7 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { if(pPart->TotalSectors == 0) { pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); } + memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_16_VOL_LABEL, sizeof pPart->VolLabel); } FF_ReleaseBuffer(pIoman, pBuffer); // Release the buffer finally! diff --git a/reactos/lib/3rdparty/fullfat/ff_memory.c b/reactos/lib/3rdparty/fullfat/ff_memory.c index cdbb2acf02d..2d6913d64d7 100644 --- a/reactos/lib/3rdparty/fullfat/ff_memory.c +++ b/reactos/lib/3rdparty/fullfat/ff_memory.c @@ -48,87 +48,55 @@ #include "ff_memory.h" #include "ff_config.h" -#ifdef FF_LITTLE_ENDIAN - -/** - * @public - * @brief 8 bit memory access routines. - **/ /* - These functions swap the byte-orders of shorts and longs. A getChar function is provided - incase there is a system that doesn't have byte-wise access to all memory. + * HT inlined these functions + * + * Not much left for the C-module + */ - These functions can be replaced with your own platform specific byte-order swapping routines - for more efficiency. - The provided functions should work on almost all platforms. -*/ -FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { - return (FF_T_UINT8) (pBuffer[offset]); +#ifndef FF_INLINE_MEMORY_ACCESS +FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) { + return (FF_T_UINT8) (pBuffer[aOffset]); } -FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { - return (FF_T_UINT16) (pBuffer[offset] & 0x00FF) | ((FF_T_UINT16) (pBuffer[offset+1] << 8) & 0xFF00); +FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) { + FF_T_UN16 u16; + pBuffer += aOffset; + u16.bytes.u8_1 = pBuffer[1]; + u16.bytes.u8_0 = pBuffer[0]; + return u16.u16; } -FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { - return (FF_T_UINT32) (pBuffer[offset] & 0x000000FF) | ((FF_T_UINT32) (pBuffer[offset+1] << 8) & 0x0000FF00) | ((FF_T_UINT32) (pBuffer[offset+2] << 16) & 0x00FF0000) | ((FF_T_UINT32) (pBuffer[offset+3] << 24) & 0xFF000000); +FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) { + FF_T_UN32 u32; + pBuffer += aOffset; + u32.bytes.u8_3 = pBuffer[3]; + u32.bytes.u8_2 = pBuffer[2]; + u32.bytes.u8_1 = pBuffer[1]; + u32.bytes.u8_0 = pBuffer[0]; + return u32.u32; } -void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value) { - pBuffer[offset] = Value; +void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value) { + pBuffer[aOffset] = Value; } -void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT16 Value) { - FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value; - pBuffer[offset] = Val[0]; - pBuffer[offset + 1] = Val[1]; +void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT16 Value) { + FF_T_UN16 u16; + u16.u16 = Value; + pBuffer += aOffset; + pBuffer[0] = u16.bytes.u8_0; + pBuffer[1] = u16.bytes.u8_1; } -void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT32 Value) { - FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value; - pBuffer[offset] = Val[0]; - pBuffer[offset + 1] = Val[1]; - pBuffer[offset + 2] = Val[2]; - pBuffer[offset + 3] = Val[3]; -} - -#endif - -#ifdef FF_BIG_ENDIAN -/* - These haven't been tested or checked. They should work in theory :) - Please contact james@worm.me.uk if they don't work, and also any fix. -*/ -FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { - return (FF_T_UINT8) (pBuffer[offset]); -} - -FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { - return (FF_T_UINT16) ((pBuffer[offset] & 0xFF00) << 8) | ((FF_T_UINT16) (pBuffer[offset+1]) & 0x00FF); -} - -FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { - return (FF_T_UINT32) ((pBuffer[offset] << 24) & 0xFF0000) | ((FF_T_UINT32) (pBuffer[offset+1] << 16) & 0x00FF0000) | ((FF_T_UINT32) (pBuffer[offset+2] << 8) & 0x0000FF00) | ((FF_T_UINT32) (pBuffer[offset+3]) & 0x000000FF); -} - -void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value) { - pBuffer[offset] = Value; -} - -void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT16 Value) { - FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value; - pBuffer[offset] = Val[1]; - pBuffer[offset + 1] = Val[0]; -} - -void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT32 Value) { - FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value; - pBuffer[offset] = Val[3]; - pBuffer[offset + 1] = Val[2]; - pBuffer[offset + 2] = Val[1]; - pBuffer[offset + 3] = Val[0]; +void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT32 Value) { + FF_T_UN32 u32; + u32.u32 = Value; + pBuffer += aOffset; + pBuffer[0] = u32.bytes.u8_0; + pBuffer[1] = u32.bytes.u8_1; + pBuffer[2] = u32.bytes.u8_2; + pBuffer[3] = u32.bytes.u8_3; } #endif - -