mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 18:01:07 +00:00
{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
This commit is contained in:
parent
542a951d46
commit
91e657f782
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
90
reactos/include/reactos/libs/fullfat/ff_fatdef.h
Normal file
90
reactos/include/reactos/libs/fullfat/ff_fatdef.h
Normal file
|
@ -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 <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* 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
|
||||
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
1
reactos/lib/3rdparty/fullfat/ff_dir.c
vendored
1
reactos/lib/3rdparty/fullfat/ff_dir.c
vendored
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
2
reactos/lib/3rdparty/fullfat/ff_dir.h
vendored
2
reactos/lib/3rdparty/fullfat/ff_dir.h
vendored
|
@ -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"
|
||||
|
|
28
reactos/lib/3rdparty/fullfat/ff_fat.c
vendored
28
reactos/lib/3rdparty/fullfat/ff_fat.c
vendored
|
@ -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
|
52
reactos/lib/3rdparty/fullfat/ff_file.c
vendored
52
reactos/lib/3rdparty/fullfat/ff_file.c
vendored
|
@ -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;
|
||||
}
|
||||
|
|
4
reactos/lib/3rdparty/fullfat/ff_hash.c
vendored
4
reactos/lib/3rdparty/fullfat/ff_hash.c
vendored
|
@ -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;
|
||||
|
|
179
reactos/lib/3rdparty/fullfat/ff_ioman.c
vendored
179
reactos/lib/3rdparty/fullfat/ff_ioman.c
vendored
|
@ -42,8 +42,10 @@
|
|||
* Destroying a FullFAT IO object.
|
||||
**/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, <stdio.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!
|
||||
|
|
106
reactos/lib/3rdparty/fullfat/ff_memory.c
vendored
106
reactos/lib/3rdparty/fullfat/ff_memory.c
vendored
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue