mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 18:01:07 +00:00
[FULLFAT]
- Update FullFat to the latest SVN code on James' recommendation. - This release has many advantages over the previous, including full UTF-8 and UTF-16 support and the ability to modify attributes and timestamps. All of which are important for ros. - It currently has a few warnings (in both gcc and msc), so I've had to turn allow warnings on. svn path=/trunk/; revision=51229
This commit is contained in:
parent
888f3912cb
commit
271454653d
|
@ -34,108 +34,138 @@
|
|||
Here you can change the configuration of FullFAT as appropriate to your
|
||||
platform.
|
||||
*/
|
||||
|
||||
//---------- ENDIANESS
|
||||
#define FF_LITTLE_ENDIAN // Choosing the Byte-order of your system is important.
|
||||
//#define FF_BIG_ENDIAN // You may be able to provide better Byte-order swapping routines to FullFAT.
|
||||
// See ff_memory.c for more information.
|
||||
#define FF_LITTLE_ENDIAN // Choosing the Byte-order of your system is important.
|
||||
//#define FF_BIG_ENDIAN // You may be able to provide better Byte-order swapping routines to FullFAT.
|
||||
// See ff_memory.c for more information.
|
||||
|
||||
|
||||
//---------- LFN (Long File-name) SUPPORT
|
||||
#define FF_LFN_SUPPORT // Comment this out if you don't want to worry about Patent Issues.
|
||||
// FullFAT works great with LFNs and without. You choose, its your project!
|
||||
#define FF_LFN_SUPPORT // Comment this out if you don't want to worry about Patent Issues.
|
||||
// FullFAT works great with LFNs and without. You choose, its your project!
|
||||
|
||||
//---------- LEGAL LFNS
|
||||
//#define FF_LEGAL_LFNS // Enabling this define causes FullFAT to not infringe on any of Microsoft's patents when making LFN names.
|
||||
// To do this, it will only create LFNs and no shortnames. Microsofts patents are only relevent when mapping
|
||||
// a shortname to a long name. This is the same way that Linux gets around the FAT legal issues:
|
||||
// see http://lkml.org/lkml/2009/6/26/314
|
||||
//
|
||||
// Enabling this may break compatibility with devices that cannot read LFN filenames.
|
||||
// Enabling this option causes no compatibility issues when reading any media.
|
||||
|
||||
//---------- TIME SUPPORT
|
||||
#define FF_TIME_SUPPORT // Should FullFAT use time stamping. Only if you have provided the relevant time drivers in ff_time.c
|
||||
// Note, by default ff_time.c is set-up for the Windows Demonstration. Please see ff_time.c to disable.
|
||||
|
||||
//---------- FILE SPACE ALLOCATION PERFORMANCE
|
||||
// Uncomment the prefered method. (Can only choose a single method).
|
||||
#define FF_ALLOC_DEFAULT // Only allocate as much as is needed. (Provides good performance, without wasting space).
|
||||
//#define FF_ALLOC_DOUBLE // Doubles the size of a file each time allocation is required. (When high-performance writing is required).
|
||||
|
||||
//---------- Use Native STDIO.h
|
||||
//#define FF_USE_NATIVE_STDIO // Makes FullFAT conform to values provided by your native STDIO.h file.
|
||||
|
||||
//---------- FREE SPACE CALCULATION
|
||||
//#define FF_MOUNT_FIND_FREE // Uncomment this option to check for Freespace on a volume mount. (Performance Penalty while mounting).
|
||||
// If not done in the mount, it will be done on the first call to FF_GetFreeSize() function.
|
||||
|
||||
//---------- PATH CACHE
|
||||
#define FF_PATH_CACHE // Enables a simply Path Caching mechanism that increases performance of repeated operations
|
||||
// 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_INCLUDE_SHORT_NAME // HT addition, in 'FF_DIRENT', beside FileName, ShortName will be filled as well
|
||||
// Useful for debugging, but also some situations its useful to know both.
|
||||
//---------- SHORTNAMES CAN USE THE CASE BITS
|
||||
#define FF_SHORTNAME_CASE // Works for XP+ e.g. short.TXT or SHORT.txt.
|
||||
|
||||
|
||||
#define FF_PATH_CACHE_DEPTH 2 // The Number of PATH's to Cache.
|
||||
//---------- UNICODE SUPPORT
|
||||
//#define FF_UNICODE_SUPPORT // If this is defined, then all of FullFAT's API's will expect to receive UTF-16 formatted strings.
|
||||
// FF_FindFirst() and FF_FindNext() will also return Filenames in UTF-16 format.
|
||||
// NOTE: This option may cause FullFAT to not "Clean-compile" when using GCC. This is because
|
||||
// pedantically GCC refuses to accept C99 library functions, unless the -std=c99 flag is used.
|
||||
// To use UNICODE (UTF-16, or UTF-32 depending on the size of wchar_t) you must have a C99 compliant
|
||||
// compiler and library.
|
||||
|
||||
//---------- DON'T USE MALLOC
|
||||
//#define FF_NO_MALLOC
|
||||
//#define FF_UNICODE_UTF8_SUPPORT // If this is defined, then all of FullFAT's API's will expect to receive UTF-8 formatted strings.
|
||||
// FF_FindFirst() and FF_FindNext() will also return Filenames in UTF-8 format.
|
||||
|
||||
#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
|
||||
//#define FF_HASH_TABLE_SUPPORT // Enable HASH to speed up file creation.
|
||||
#ifdef FF_HASH_TABLE_SUPPORT
|
||||
#define FF_HASH_FUNCTION CRC16
|
||||
//#define FF_HASH_FUNCTION CRC8
|
||||
#endif
|
||||
// Note the 2 UNICODE options are mutually exclusive. Only one can be enabled.
|
||||
|
||||
// Ensure that dirents are big enough to hold the maximum UTF-8 sequence.
|
||||
|
||||
|
||||
//---------- FAT12 SUPPORT
|
||||
#define FF_FAT12_SUPPORT // Enable FAT12 Suppport. You can reduce the code-size by commenting this out.
|
||||
// If you don't need FAT12 support, why have it. FAT12 is more complex to process,
|
||||
// therefore savings can be made by not having it.
|
||||
#define FF_FAT12_SUPPORT // Enable FAT12 Suppport. You can reduce the code-size by commenting this out.
|
||||
// If you don't need FAT12 support, why have it. FAT12 is more complex to process,
|
||||
// therefore savings can be made by not having it.
|
||||
|
||||
|
||||
//---------- TIME SUPPORT
|
||||
#define FF_TIME_SUPPORT // Should FullFAT use time stamping. Only if you have provided the relevant time drivers in ff_time.c
|
||||
// Note, by default ff_time.c is set-up for the Windows Demonstration. Please see ff_time.c to disable.
|
||||
|
||||
|
||||
//---------- FILE SPACE ALLOCATION PERFORMANCE
|
||||
// Uncomment the prefered method. (Can only choose a single method).
|
||||
#define FF_ALLOC_DEFAULT // Only allocate as much as is needed. (Provides good performance, without wasting space).
|
||||
//#define FF_ALLOC_DOUBLE // Doubles the size of a file each time allocation is required. (When high-performance writing is required).
|
||||
|
||||
|
||||
//---------- Use Native STDIO.h
|
||||
//#define FF_USE_NATIVE_STDIO // Makes FullFAT conform to values provided by your native STDIO.h file.
|
||||
|
||||
|
||||
//---------- FREE SPACE CALCULATION
|
||||
//#define FF_MOUNT_FIND_FREE // Uncomment this option to check for Freespace on a volume mount. (Performance Penalty while mounting).
|
||||
// If not done in the mount, it will be done on the first call to FF_GetFreeSize() function.
|
||||
|
||||
|
||||
//---------- FIND API WILD-CARD SUPPORT
|
||||
#define FF_FINDAPI_ALLOW_WILDCARDS // Defined to enable Wild-cards in the API. Disabling this, makes the API consistent with 1.0.x series.
|
||||
|
||||
#define FF_WILDCARD_CASE_INSENSITIVE // Alter the case insensitivity of the Wild-card checking behaviour.
|
||||
|
||||
|
||||
//---------- PATH CACHE ----------
|
||||
#define FF_PATH_CACHE // Enables a simply Path Caching mechanism that increases performance of repeated operations
|
||||
// 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).
|
||||
|
||||
#define FF_PATH_CACHE_DEPTH 5 // The Number of PATH's to Cache. (Memory Requirement ~= FF_PATH_CACHE_DEPTH * FF_MAX_PATH).
|
||||
|
||||
|
||||
//---------- HASH CACHE // Speed up File-creation with a HASH table. Provides up to 20x performance boost.
|
||||
//#define FF_HASH_CACHE // Enable HASH to speed up file creation.
|
||||
#define FF_HASH_CACHE_DEPTH 10 // Number of Directories to be Hashed. (For CRC16 memory is 8KB * DEPTH)
|
||||
#define FF_HASH_FUNCTION CRC16 // Choose a 16-bit hash.
|
||||
//#define FF_HASH_FUNCTION CRC8 // Choose an 8-bit hash.
|
||||
|
||||
|
||||
//---------- 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) - Thanks to Hein Tibosch
|
||||
|
||||
|
||||
//---------- MALLOC
|
||||
// These should map on to platform specific memory allocators.
|
||||
#define FF_MALLOC(aSize) malloc(aSize)
|
||||
#define FF_FREE(apPtr) free(apPtr)
|
||||
|
||||
|
||||
//---------- IN-LINE FUNCTIONS
|
||||
//---------- INLINE KeyWord // Define FF_INLINE as your compiler's inline keyword. This is placed before the type qualifier.
|
||||
#define FF_INLINE static __forceinline // Keywords to inline functions (Windows)
|
||||
//#define FF_INLINE static inline // Standard for GCC
|
||||
|
||||
//---------- Inline Memory Independence Routines for better performance, but bigger codesize.
|
||||
//#define FF_INLINE_MEMORY_ACCESS
|
||||
//---------- Inline Block Calculation Routines for slightly better performance in critical sections.
|
||||
//#define FF_INLINE_BLOCK_CALCULATIONS
|
||||
|
||||
|
||||
//---------- 64-Bit Number Support
|
||||
#define FF_64_NUM_SUPPORT // This helps to give information about the FreeSpace and VolumeSize of a partition or volume.
|
||||
// If you cannot support 64-bit integers, then FullFAT still works, its just that the functions:
|
||||
// FF_GetFreeSize() and FF_GetVolumeSize() don't make sense when reporting sizes > 4GB.
|
||||
#define FF_64_NUM_SUPPORT // This helps to give information about the FreeSpace and VolumeSize of a partition or volume.
|
||||
// If you cannot support 64-bit integers, then FullFAT still works, its just that the functions:
|
||||
// FF_GetFreeSize() and FF_GetVolumeSize() don't make sense when reporting sizes > 4GB.
|
||||
|
||||
//---------- Driver Sleep Time // How long FullFAT should sleep the thread for in ms, if FF_ERR_DRIVER_BUSY is recieved.
|
||||
#define FF_DRIVER_BUSY_SLEEP 20
|
||||
|
||||
//---------- Debugging Features
|
||||
#define FF_DEBUG // Enable the Error Code string functions. const FF_T_INT8 *FF_GetErrMessage( FF_T_SINT32 iErrorCode);
|
||||
// Uncommenting this just stops FullFAT error strings being compiled.
|
||||
//---------- Driver Sleep Time
|
||||
#define FF_DRIVER_BUSY_SLEEP 20 // How long FullFAT should sleep the thread for in ms, if FF_ERR_DRIVER_BUSY is recieved.
|
||||
|
||||
//---------- Actively Determine if partition is FAT
|
||||
#define FF_FAT_CHECK // This is experimental, so if FullFAT won't mount your volume, comment this out
|
||||
// Also report the problem to james@worm.me.uk
|
||||
|
||||
//---------- DEBUGGING FEATURES (HELPFUL ERROR MESSAGES)
|
||||
#define FF_DEBUG // Enable the Error Code string functions. const FF_T_INT8 *FF_GetErrMessage( FF_T_SINT32 iErrorCode);
|
||||
// Uncommenting this just stops FullFAT error strings being compiled.
|
||||
// Further calls to FF_GetErrMessage() are safe, and simply returns a pointer to a NULL string. ("").
|
||||
// This should be disabled to reduce code-size dramatically.
|
||||
|
||||
|
||||
//---------- AUTOMATIC SETTINGS DO NOT EDIT -- These configure your options from above, and check sanity!
|
||||
|
||||
#ifdef FF_LFN_SUPPORT
|
||||
#define FF_MAX_FILENAME (129)
|
||||
#define FF_MAX_FILENAME (260)
|
||||
#else
|
||||
#define FF_MAX_FILENAME 13
|
||||
#define FF_MAX_FILENAME (13)
|
||||
#endif
|
||||
|
||||
#ifdef FF_USE_NATIVE_STDIO
|
||||
#ifdef MAX_PATH
|
||||
#define FF_MAX_PATH MAX_PATH
|
||||
#elif PATH_MAX
|
||||
#define FF_MAX_PATH PATH_MAX
|
||||
#else
|
||||
#define FF_MAX_PATH 2600
|
||||
#endif
|
||||
|
@ -155,6 +185,16 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
#ifdef FF_UNICODE_UTF8_SUPPORT
|
||||
#error FullFAT Invalid ff_config.h file: Must choose a single UNICODE support option. FF_UNICODE_SUPPORT for UTF-16, FF_UNICODE_UTF8_SUPPORT for UTF-8.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FF_FAT_CHECK // FF_FAT_CHECK is now forced.
|
||||
#define FF_FAT_CHECK
|
||||
#endif
|
||||
|
||||
#ifndef FF_LITTLE_ENDIAN
|
||||
#ifndef FF_BIG_ENDIAN
|
||||
#error FullFAT Invalid ff_config.h file: An ENDIANESS must be defined for your platform. See ff_config.h file.
|
||||
|
@ -167,16 +207,18 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FF_HASH_TABLE_SUPPORT
|
||||
#ifdef FF_HASH_CACHE
|
||||
|
||||
#if FF_HASH_FUNCTION == CRC16
|
||||
#define FF_HASH_TABLE_SIZE 8192
|
||||
#elif FF_HASH_FUNCTION == CRC8
|
||||
#define FF_HASH_TABLE_SIZE 32
|
||||
#else
|
||||
#error Invalid Hashing function selected. CRC16 or CRC8!
|
||||
#error FullFAT Invalid ff_config.h file: Invalid Hashing function selected. CRC16 or CRC8!
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//---------- END-OF-CONFIGURATION
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
FF_T_UINT8 FF_GetCRC8 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength);
|
||||
FF_T_UINT16 FF_GetCRC16 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength);
|
||||
FF_T_UINT32 FF_GetCRC32 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -52,54 +52,118 @@
|
|||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
FF_T_INT8 FileName[FF_MAX_FILENAME];
|
||||
FF_T_UINT8 Attrib;
|
||||
FF_T_UINT32 ulChainLength;
|
||||
FF_T_UINT32 ulDirCluster;
|
||||
FF_T_UINT32 ulCurrentClusterLCN;
|
||||
FF_T_UINT32 ulCurrentClusterNum;
|
||||
FF_T_UINT32 ulCurrentEntry;
|
||||
FF_BUFFER *pBuffer;
|
||||
} FF_FETCH_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
FF_T_UINT32 Filesize;
|
||||
FF_T_UINT32 ObjectCluster;
|
||||
|
||||
|
||||
// Book Keeping
|
||||
FF_T_UINT32 CurrentCluster;
|
||||
FF_T_UINT32 AddrCurrentCluster;
|
||||
FF_T_UINT32 DirCluster;
|
||||
FF_T_UINT16 CurrentItem;
|
||||
// End Book Keeping
|
||||
|
||||
#ifdef FF_TIME_SUPPORT
|
||||
FF_SYSTEMTIME CreateTime; ///< Date and Time Created.
|
||||
FF_SYSTEMTIME ModifiedTime; ///< Date and Time Modified.
|
||||
FF_SYSTEMTIME AccessedTime; ///< Date of Last Access.
|
||||
#endif
|
||||
|
||||
//---- Book Keeping for FF_Find Functions
|
||||
FF_T_UINT16 CurrentItem;
|
||||
FF_T_UINT32 DirCluster;
|
||||
FF_T_UINT32 CurrentCluster;
|
||||
FF_T_UINT32 AddrCurrentCluster;
|
||||
//FF_T_UINT8 NumLFNs;
|
||||
#ifdef FF_FINDAPI_ALLOW_WILDCARDS
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_WCHAR szWildCard[FF_MAX_FILENAME];
|
||||
#else
|
||||
FF_T_INT8 szWildCard[FF_MAX_FILENAME];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_WCHAR FileName[FF_MAX_FILENAME];
|
||||
#else
|
||||
FF_T_INT8 FileName[FF_MAX_FILENAME];
|
||||
#endif
|
||||
|
||||
#if defined(FF_LFN_SUPPORT) && defined(FF_INCLUDE_SHORT_NAME)
|
||||
FF_T_INT8 ShortName[13];
|
||||
#endif
|
||||
FF_T_UINT8 Attrib;
|
||||
FF_FETCH_CONTEXT FetchContext;
|
||||
} FF_DIRENT;
|
||||
|
||||
FF_ERROR FF_GetEntry (FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_PutEntry (FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_FindEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_DIRENT *pDirent, FF_T_BOOL LFNs);
|
||||
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path);
|
||||
FF_ERROR FF_FindNext (FF_IOMAN *pIoman, FF_DIRENT *pDirent);
|
||||
void FF_PopulateShortDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer);
|
||||
FF_T_SINT8 FF_PopulateLongDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry);
|
||||
FF_T_SINT8 FF_FetchEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
|
||||
FF_T_SINT8 FF_PushEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
|
||||
FF_T_BOOL FF_isEndOfDir (FF_T_UINT8 *EntryBuffer);
|
||||
FF_T_SINT8 FF_FindNextInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_UINT32 FF_FindEntryInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_CreateShortName(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName);
|
||||
|
||||
void FF_lockDIR (FF_IOMAN *pIoman);
|
||||
void FF_unlockDIR (FF_IOMAN *pIoman);
|
||||
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent);
|
||||
FF_ERROR FF_MkDir(FF_IOMAN *pIoman, const FF_T_INT8 *Path);
|
||||
FF_T_SINT8 FF_CreateDirent(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_ExtendDirectory(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
FF_T_UINT32 FF_FindDir(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen);
|
||||
|
||||
|
||||
FF_T_BOOL FF_CheckDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
FF_T_BOOL FF_DirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
FF_ERROR FF_AddDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
void FF_SetDirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
// PUBLIC API
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_WCHAR *path);
|
||||
FF_ERROR FF_MkDir (FF_IOMAN *pIoman, const FF_T_WCHAR *Path);
|
||||
#else
|
||||
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path);
|
||||
FF_ERROR FF_MkDir (FF_IOMAN *pIoman, const FF_T_INT8 *Path);
|
||||
#endif
|
||||
|
||||
void FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 DirEntry);
|
||||
FF_ERROR FF_FindNext (FF_IOMAN *pIoman, FF_DIRENT *pDirent);
|
||||
|
||||
|
||||
// INTERNAL API
|
||||
FF_ERROR FF_GetEntry (FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_ERROR FF_PutEntry (FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_FindEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_DIRENT *pDirent, FF_T_BOOL LFNs);
|
||||
|
||||
void FF_PopulateShortDirent (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer);
|
||||
FF_ERROR FF_PopulateLongDirent (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT16 nEntry, FF_FETCH_CONTEXT *pFetchContext);
|
||||
|
||||
FF_ERROR FF_InitEntryFetch (FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_FETCH_CONTEXT *pContext);
|
||||
FF_ERROR FF_FetchEntryWithContext (FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer);
|
||||
FF_ERROR FF_PushEntryWithContext (FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer);
|
||||
void FF_CleanupEntryFetch (FF_IOMAN *pIoman, FF_FETCH_CONTEXT *pContext);
|
||||
|
||||
FF_T_SINT8 FF_PushEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer, void *pParam);
|
||||
FF_T_BOOL FF_isEndOfDir (FF_T_UINT8 *EntryBuffer);
|
||||
FF_ERROR FF_FindNextInDir (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_FETCH_CONTEXT *pFetchContext);
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_UINT32 FF_FindEntryInDir (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_WCHAR *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
FF_T_SINT8 FF_CreateShortName (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *ShortName, FF_T_WCHAR *LongName);
|
||||
#else
|
||||
FF_T_UINT32 FF_FindEntryInDir (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
FF_T_SINT8 FF_CreateShortName (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName);
|
||||
#endif
|
||||
|
||||
|
||||
void FF_lockDIR (FF_IOMAN *pIoman);
|
||||
void FF_unlockDIR (FF_IOMAN *pIoman);
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *FileName, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
#else
|
||||
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
#endif
|
||||
|
||||
FF_ERROR FF_CreateDirent (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_ERROR FF_ExtendDirectory (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_UINT32 FF_FindDir (FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT16 pathLen, FF_ERROR *pError);
|
||||
#else
|
||||
FF_T_UINT32 FF_FindDir (FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen, FF_ERROR *pError);
|
||||
#endif
|
||||
|
||||
#ifdef FF_HASH_CACHE
|
||||
FF_T_BOOL FF_CheckDirentHash (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
FF_T_BOOL FF_DirHashed (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
FF_ERROR FF_AddDirentHash (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
FF_ERROR FF_HashDir (FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster);
|
||||
#endif
|
||||
|
||||
FF_ERROR FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT16 usDirEntry, FF_FETCH_CONTEXT *pContext);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -40,53 +40,111 @@
|
|||
#include "ff_config.h"
|
||||
#include "ff_types.h"
|
||||
|
||||
/**
|
||||
Error codes are 32-bit numbers, and consist of three items:
|
||||
8Bits 8bits 16bits
|
||||
........ ........ ........ ........
|
||||
[ModuleID][FunctionID][-- ERROR CODE --]
|
||||
|
||||
**/
|
||||
|
||||
#define FF_GETERROR(x) (x & 0x0000FFFF)
|
||||
|
||||
#define FF_MODULE_SHIFT 24
|
||||
#define FF_FUNCTION_SHIFT 16
|
||||
|
||||
//----- FullFAT Module Identifiers
|
||||
#define FF_MODULE_IOMAN (1 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_DIR (2 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_FILE (3 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_FAT (4 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_CRC (5 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_FORMAT (6 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_HASH (7 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_MEMORY (8 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_STRING (9 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_UNICODE (10 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_SAFETY (11 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_TIME (12 << FF_MODULE_SHIFT)
|
||||
#define FF_MODULE_DRIVER (13 << FF_MODULE_SHIFT) // We can mark underlying platform error codes with this.
|
||||
|
||||
//----- FullFAT Function Identifiers (In Modular Order)
|
||||
//----- FF_IOMAN - The FullFAT I/O Manager.
|
||||
#define FF_CREATEIOMAN (1 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_DESTROYIOMAN (2 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_REGISTERBLKDEVICE (3 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_UNREGISTERBLKDEVICE (4 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_MOUNTPARTITION (5 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_UNMOUNTPARTITION (6 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_FLUSHCACHE (7 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_GETPARTITIONBLOCKSIZE (8 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_BLOCKREAD (9 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
#define FF_BLOCKWRITE (10 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
|
||||
|
||||
//----- FF_DIR - The FullFAT directory handling routines.
|
||||
// -- COMPLETE THESE ERROR CODES TOMORROW :P
|
||||
|
||||
|
||||
/* FullFAT defines different Error-Code spaces for each module. This ensures
|
||||
that all error codes remain unique, and their meaning can be quickly identified.
|
||||
*/
|
||||
// Global Error Codes
|
||||
#define FF_ERR_NONE 0 ///< No Error
|
||||
#define FF_ERR_NULL_POINTER -2 ///< pIoman was NULL.
|
||||
#define FF_ERR_NOT_ENOUGH_MEMORY -3 ///< malloc() failed! - Could not allocate handle memory.
|
||||
#define FF_ERR_DEVICE_DRIVER_FAILED -4 ///< The Block Device driver reported a FATAL error, cannot continue.
|
||||
#define FF_ERR_NONE 0 ///< No Error
|
||||
//#define FF_ERR_GENERIC 1 ///< BAD NEVER USE THIS!
|
||||
#define FF_ERR_NULL_POINTER 2 ///< pIoman was NULL.
|
||||
#define FF_ERR_NOT_ENOUGH_MEMORY 3 ///< malloc() failed! - Could not allocate handle memory.
|
||||
#define FF_ERR_DEVICE_DRIVER_FAILED 4 ///< The Block Device driver reported a FATAL error, cannot continue.
|
||||
|
||||
|
||||
// IOMAN Error Codes
|
||||
#define FF_ERR_IOMAN_BAD_BLKSIZE -11 ///< The provided blocksize was not a multiple of 512.
|
||||
#define FF_ERR_IOMAN_BAD_MEMSIZE -12 ///< The memory size was not a multiple of the blocksize.
|
||||
#define FF_ERR_IOMAN_DEV_ALREADY_REGD -13 ///< Device was already registered. Use FF_UnRegister() to re-use this IOMAN with another device.
|
||||
#define FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION -14 ///< A mountable partition could not be found on the device.
|
||||
#define FF_ERR_IOMAN_INVALID_FORMAT -15 ///< The
|
||||
#define FF_ERR_IOMAN_INVALID_PARTITION_NUM -16 ///< The partition number provided was out of range.
|
||||
#define FF_ERR_IOMAN_NOT_FAT_FORMATTED -17 ///< The partition did not look like a FAT partition.
|
||||
#define FF_ERR_IOMAN_DEV_INVALID_BLKSIZE -18 ///< IOMAN object BlkSize is not compatible with the blocksize of this device driver.
|
||||
#define FF_ERR_IOMAN_PARTITION_MOUNTED -19 ///< Device is in use by an actively mounted partition. Unmount the partition first.
|
||||
#define FF_ERR_IOMAN_ACTIVE_HANDLES -20 ///< The partition cannot be unmounted until all active file handles are closed. (There may also be active handles on the cache).
|
||||
#define FF_ERR_IOMAN_BAD_BLKSIZE 11 ///< The provided blocksize was not a multiple of 512.
|
||||
#define FF_ERR_IOMAN_BAD_MEMSIZE 12 ///< The memory size was not a multiple of the blocksize.
|
||||
#define FF_ERR_IOMAN_DEV_ALREADY_REGD 13 ///< Device was already registered. Use FF_UnRegister() to re-use this IOMAN with another device.
|
||||
#define FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION 14 ///< A mountable partition could not be found on the device.
|
||||
#define FF_ERR_IOMAN_INVALID_FORMAT 15 ///< The
|
||||
#define FF_ERR_IOMAN_INVALID_PARTITION_NUM 16 ///< The partition number provided was out of range.
|
||||
#define FF_ERR_IOMAN_NOT_FAT_FORMATTED 17 ///< The partition did not look like a FAT partition.
|
||||
#define FF_ERR_IOMAN_DEV_INVALID_BLKSIZE 18 ///< IOMAN object BlkSize is not compatible with the blocksize of this device driver.
|
||||
#define FF_ERR_IOMAN_PARTITION_MOUNTED 19 ///< Device is in use by an actively mounted partition. Unmount the partition first.
|
||||
#define FF_ERR_IOMAN_ACTIVE_HANDLES 20 ///< The partition cannot be unmounted until all active file handles are closed. (There may also be active handles on the cache).
|
||||
#define FF_ERR_IOMAN_GPT_HEADER_CORRUPT 21 ///< The GPT partition table appears to be corrupt, refusing to mount.
|
||||
#define FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE 22
|
||||
#define FF_ERR_IOMAN_OUT_OF_BOUNDS_READ 23
|
||||
#define FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE 24
|
||||
|
||||
|
||||
// File Error Codes -30 +
|
||||
#define FF_ERR_FILE_ALREADY_OPEN -30 ///< File is in use.
|
||||
#define FF_ERR_FILE_NOT_FOUND -31 ///< File was not found.
|
||||
#define FF_ERR_FILE_OBJECT_IS_A_DIR -32 ///< Tried to FF_Open() a Directory.
|
||||
#define FF_ERR_FILE_IS_READ_ONLY -33 ///< Tried to FF_Open() a file marked read only.
|
||||
#define FF_ERR_FILE_INVALID_PATH -34 ///< The path of the file was not found.
|
||||
#define FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE -35
|
||||
#define FF_ERR_FILE_NOT_OPENED_IN_READ_MODE -36
|
||||
#define FF_ERR_FILE_EXTEND_FAILED -37 ///< Could not extend the file.
|
||||
#define FF_ERR_FILE_DESTINATION_EXISTS -38
|
||||
#define FF_ERR_FILE_SOURCE_NOT_FOUND -39
|
||||
#define FF_ERR_FILE_DIR_NOT_FOUND -40
|
||||
#define FF_ERR_FILE_COULD_NOT_CREATE_DIRENT -41
|
||||
// File Error Codes 30 +
|
||||
#define FF_ERR_FILE_ALREADY_OPEN 30 ///< File is in use.
|
||||
#define FF_ERR_FILE_NOT_FOUND 31 ///< File was not found.
|
||||
#define FF_ERR_FILE_OBJECT_IS_A_DIR 32 ///< Tried to FF_Open() a Directory.
|
||||
#define FF_ERR_FILE_IS_READ_ONLY 33 ///< Tried to FF_Open() a file marked read only.
|
||||
#define FF_ERR_FILE_INVALID_PATH 34 ///< The path of the file was not found.
|
||||
#define FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE 35
|
||||
#define FF_ERR_FILE_NOT_OPENED_IN_READ_MODE 36
|
||||
#define FF_ERR_FILE_EXTEND_FAILED 37 ///< Could not extend the file.
|
||||
#define FF_ERR_FILE_DESTINATION_EXISTS 38
|
||||
#define FF_ERR_FILE_SOURCE_NOT_FOUND 39
|
||||
#define FF_ERR_FILE_DIR_NOT_FOUND 40
|
||||
#define FF_ERR_FILE_COULD_NOT_CREATE_DIRENT 41
|
||||
|
||||
// Directory Error Codes -50 +
|
||||
#define FF_ERR_DIR_OBJECT_EXISTS -50 ///< A file or folder of the same name already exists in the current directory.
|
||||
#define FF_ERR_DIR_DIRECTORY_FULL -51 ///< No more items could be added to the directory.
|
||||
#define FF_ERR_DIR_END_OF_DIR -52 ///
|
||||
#define FF_ERR_DIR_NOT_EMPTY -53 ///< Cannot delete a directory that contains files or folders.
|
||||
#define FF_ERR_DIR_INVALID_PATH -54 ///< Could not find the directory specified by the path.
|
||||
#define FF_ERR_DIR_CANT_EXTEND_ROOT_DIR -55 ///< Can't extend the root dir.
|
||||
// Directory Error Codes 50 +
|
||||
#define FF_ERR_DIR_OBJECT_EXISTS 50 ///< A file or folder of the same name already exists in the current directory.
|
||||
#define FF_ERR_DIR_DIRECTORY_FULL 51 ///< No more items could be added to the directory.
|
||||
#define FF_ERR_DIR_END_OF_DIR 52 ///
|
||||
#define FF_ERR_DIR_NOT_EMPTY 53 ///< Cannot delete a directory that contains files or folders.
|
||||
#define FF_ERR_DIR_INVALID_PATH 54 ///< Could not find the directory specified by the path.
|
||||
#define FF_ERR_DIR_CANT_EXTEND_ROOT_DIR 55 ///< Can't extend the root dir.
|
||||
#define FF_ERR_DIR_EXTEND_FAILED 56 ///< Not enough space to extend the directory.
|
||||
#define FF_ERR_DIR_NAME_TOO_LONG 57 ///< Name exceeds the number of allowed charachters for a filename.
|
||||
|
||||
// Fat Error Codes -70 +
|
||||
#define FF_ERR_FAT_NO_FREE_CLUSTERS -70 ///< No more free space is available on the disk.
|
||||
// Fat Error Codes 70 +
|
||||
#define FF_ERR_FAT_NO_FREE_CLUSTERS 70 ///< No more free space is available on the disk.
|
||||
|
||||
// UNICODE Error Codes 100 +
|
||||
#define FF_ERR_UNICODE_INVALID_CODE 100 ///< An invalid Unicode charachter was provided!
|
||||
#define FF_ERR_UNICODE_DEST_TOO_SMALL 101 ///< Not enough space in the UTF-16 buffer to encode the entire sequence as UTF-16.
|
||||
#define FF_ERR_UNICODE_INVALID_SEQUENCE 102 ///< An invalid UTF-16 sequence was encountered.
|
||||
#define FF_ERR_UNICODE_CONVERSION_EXCEEDED 103 ///< Filename exceeds MAX long-filename length when converted to UTF-16.
|
||||
|
||||
#ifdef FF_DEBUG
|
||||
const FF_T_INT8 *FF_GetErrMessage(FF_ERROR iErrorCode);
|
||||
|
|
|
@ -52,24 +52,23 @@
|
|||
FF_T_UINT32 FF_getRealLBA (FF_IOMAN *pIoman, FF_T_UINT32 LBA);
|
||||
FF_T_UINT32 FF_Cluster2LBA (FF_IOMAN *pIoman, FF_T_UINT32 Cluster);
|
||||
FF_T_UINT32 FF_LBA2Cluster (FF_IOMAN *pIoman, FF_T_UINT32 Address);
|
||||
FF_T_SINT32 FF_getFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster);
|
||||
FF_T_UINT32 FF_getFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_ERROR *pError);
|
||||
FF_ERROR FF_putFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value);
|
||||
FF_T_BOOL FF_isEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 fatEntry);
|
||||
FF_T_SINT8 FF_putFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value);
|
||||
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
|
||||
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman, FF_ERROR *pError);
|
||||
FF_T_UINT32 FF_ExtendClusterChain (FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT32 Count);
|
||||
FF_T_SINT8 FF_UnlinkClusterChain (FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count);
|
||||
FF_T_UINT32 FF_TraverseFAT (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count);
|
||||
FF_T_UINT32 FF_CreateClusterChain (FF_IOMAN *pIoman);
|
||||
FF_T_UINT32 FF_GetChainLength (FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain);
|
||||
FF_T_UINT32 FF_FindEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 Start);
|
||||
FF_T_SINT8 FF_ClearCluster (FF_IOMAN *pIoman, FF_T_UINT32 nCluster);
|
||||
FF_ERROR FF_UnlinkClusterChain (FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count);
|
||||
FF_T_UINT32 FF_TraverseFAT (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count, FF_ERROR *pError);
|
||||
FF_T_UINT32 FF_CreateClusterChain (FF_IOMAN *pIoman, FF_ERROR *pError);
|
||||
FF_T_UINT32 FF_GetChainLength (FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain, FF_ERROR *pError);
|
||||
FF_T_UINT32 FF_FindEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_ERROR *pError);
|
||||
FF_ERROR FF_ClearCluster (FF_IOMAN *pIoman, FF_T_UINT32 nCluster);
|
||||
#ifdef FF_64_NUM_SUPPORT
|
||||
FF_T_UINT64 FF_GetFreeSize (FF_IOMAN *pIoman);
|
||||
FF_T_UINT64 FF_GetFreeSize (FF_IOMAN *pIoman, FF_ERROR *pError);
|
||||
#else
|
||||
FF_T_UINT32 FF_GetFreeSize (FF_IOMAN *pIoman);
|
||||
FF_T_UINT32 FF_GetFreeSize (FF_IOMAN *pIoman, FF_ERROR *pError);
|
||||
#endif
|
||||
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
|
||||
FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman);
|
||||
FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman, FF_ERROR *pError); // WARNING: If this protoype changes, it must be updated in ff_ioman.c also!
|
||||
void FF_lockFAT (FF_IOMAN *pIoman);
|
||||
void FF_unlockFAT (FF_IOMAN *pIoman);
|
||||
|
||||
|
|
|
@ -86,5 +86,20 @@
|
|||
#define FF_FAT_ATTR_ARCHIVE 0x20
|
||||
#define FF_FAT_ATTR_LFN 0x0F
|
||||
|
||||
/**
|
||||
* -- Hein_Tibosch additions for mixed case in shortnames --
|
||||
*
|
||||
* Specifically, bit 4 means lowercase extension and bit 3 lowercase basename,
|
||||
* which allows for combinations such as "example.TXT" or "HELLO.txt" but not "Mixed.txt"
|
||||
*/
|
||||
|
||||
#define FF_FAT_CASE_OFFS 0x0C ///< After NT/XP : 2 case bits
|
||||
#define FF_FAT_CASE_ATTR_BASE 0x08
|
||||
#define FF_FAT_CASE_ATTR_EXT 0x10
|
||||
|
||||
#if defined(FF_LFN_SUPPORT) && defined(FF_INCLUDE_SHORT_NAME)
|
||||
#define FF_FAT_ATTR_IS_LFN 0x40 ///< artificial attribute, for debugging only
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -75,19 +75,29 @@ typedef struct _FF_FILE {
|
|||
//---------- PROTOTYPES
|
||||
// PUBLIC (Interfaces):
|
||||
|
||||
FF_FILE *FF_Open (FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ERROR *pError);
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT8 Mode, FF_ERROR *pError);
|
||||
FF_T_BOOL FF_isDirEmpty (FF_IOMAN *pIoman, const FF_T_WCHAR *Path);
|
||||
FF_ERROR FF_RmFile (FF_IOMAN *pIoman, const FF_T_WCHAR *path);
|
||||
FF_ERROR FF_RmDir (FF_IOMAN *pIoman, const FF_T_WCHAR *path);
|
||||
FF_ERROR FF_Move (FF_IOMAN *pIoman, const FF_T_WCHAR *szSourceFile, const FF_T_WCHAR *szDestinationFile);
|
||||
#else
|
||||
FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ERROR *pError);
|
||||
FF_T_BOOL FF_isDirEmpty (FF_IOMAN *pIoman, const FF_T_INT8 *Path);
|
||||
FF_ERROR FF_RmFile (FF_IOMAN *pIoman, const FF_T_INT8 *path);
|
||||
FF_ERROR FF_RmDir (FF_IOMAN *pIoman, const FF_T_INT8 *path);
|
||||
FF_ERROR FF_Move (FF_IOMAN *pIoman, const FF_T_INT8 *szSourceFile, const FF_T_INT8 *szDestinationFile);
|
||||
#endif
|
||||
FF_ERROR FF_Close (FF_FILE *pFile);
|
||||
FF_T_SINT32 FF_GetC (FF_FILE *pFile);
|
||||
FF_T_SINT32 FF_GetLine (FF_FILE *pFile, FF_T_INT8 *szLine, FF_T_UINT32 ulLimit);
|
||||
FF_T_SINT32 FF_Read (FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer);
|
||||
FF_T_SINT32 FF_Write (FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer);
|
||||
FF_T_BOOL FF_isEOF (FF_FILE *pFile);
|
||||
FF_ERROR FF_Seek (FF_FILE *pFile, FF_T_SINT32 Offset, FF_T_INT8 Origin);
|
||||
FF_T_SINT32 FF_PutC (FF_FILE *pFile, FF_T_UINT8 Value);
|
||||
FF_T_UINT32 FF_Tell (FF_FILE *pFile);
|
||||
FF_ERROR FF_RmFile (FF_IOMAN *pIoman, const FF_T_INT8 *path);
|
||||
FF_ERROR FF_RmDir (FF_IOMAN *pIoman, const FF_T_INT8 *path);
|
||||
FF_T_BOOL FF_isDirEmpty (FF_IOMAN *pIoman, const FF_T_INT8 *Path);
|
||||
FF_ERROR FF_Move (FF_IOMAN *pIoman, const FF_T_INT8 *szSourceFile, const FF_T_INT8 *szDestinationFile);
|
||||
|
||||
FF_T_UINT8 FF_GetModeBits (FF_T_INT8 *Mode);
|
||||
|
||||
// Private :
|
||||
|
|
47
reactos/include/reactos/libs/fullfat/ff_format.h
Normal file
47
reactos/include/reactos/libs/fullfat/ff_format.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*****************************************************************************
|
||||
* 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. *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ff_format.c
|
||||
* @author James Walmsley
|
||||
* @ingroup FORMAT
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
#ifndef _FF_FORMAT_H_
|
||||
#define _FF_FORMAT_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -87,8 +87,8 @@ typedef FF_T_SINT32 (*FF_READ_BLOCKS) (FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAd
|
|||
* @brief Describes the block device driver interface to FullFAT.
|
||||
**/
|
||||
typedef struct {
|
||||
FF_WRITE_BLOCKS fnWriteBlocks; ///< Function Pointer, to write a block(s) from a block device.
|
||||
FF_READ_BLOCKS fnReadBlocks; ///< Function Pointer, to read a block(s) from a block device.
|
||||
FF_WRITE_BLOCKS fnpWriteBlocks; ///< Function Pointer, to write a block(s) from a block device.
|
||||
FF_READ_BLOCKS fnpReadBlocks; ///< Function Pointer, to read a block(s) from a block device.
|
||||
FF_T_UINT16 devBlkSize; ///< Block size that the driver deals with.
|
||||
void *pParam; ///< Pointer to some parameters e.g. for a Low-Level Driver Handle
|
||||
} FF_BLK_DEVICE;
|
||||
|
@ -110,14 +110,23 @@ typedef struct {
|
|||
} FF_BUFFER;
|
||||
|
||||
typedef struct {
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_WCHAR Path[FF_MAX_PATH];
|
||||
#else
|
||||
FF_T_INT8 Path[FF_MAX_PATH];
|
||||
FF_T_UINT32 DirCluster;
|
||||
#ifdef FF_HASH_TABLE_SUPPORT
|
||||
FF_HASH_TABLE pHashTable;
|
||||
FF_T_BOOL bHashed;
|
||||
#endif
|
||||
FF_T_UINT32 DirCluster;
|
||||
} FF_PATHCACHE;
|
||||
|
||||
#ifdef FF_HASH_CACHE
|
||||
typedef struct {
|
||||
FF_T_UINT32 ulDirCluster; ///< The Starting Cluster of the dir that the hash represents.
|
||||
FF_HASH_TABLE pHashTable; ///< Pointer to the Hash Table object.
|
||||
FF_T_UINT32 ulNumHandles; ///< Number of active Handles using this hash table.
|
||||
FF_T_UINT32 ulMisses; ///< Number of times this Hash Table was missed, (i.e. how redundant it is).
|
||||
} FF_HASHCACHE;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @brief FullFAT identifies a partition with the following data.
|
||||
|
@ -183,6 +192,9 @@ typedef struct {
|
|||
FF_PARTITION *pPartition; ///< Pointer to a partition description.
|
||||
FF_BUFFER *pBuffers; ///< Pointer to the first buffer description.
|
||||
void *pSemaphore; ///< Pointer to a Semaphore object. (For buffer description modifications only!).
|
||||
#ifdef FF_BLKDEV_USES_SEM
|
||||
void *pBlkDevSemaphore; ///< Semaphore to guarantee Atomic access to the underlying block device, if required.
|
||||
#endif
|
||||
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.
|
||||
|
@ -191,6 +203,9 @@ typedef struct {
|
|||
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).
|
||||
#ifdef FF_HASH_CACHE
|
||||
FF_HASHCACHE HashCache[FF_HASH_CACHE_DEPTH];
|
||||
#endif
|
||||
} FF_IOMAN;
|
||||
|
||||
// Bit-Masks for Memory Allocation testing.
|
||||
|
@ -220,6 +235,8 @@ FF_T_UINT32 FF_GetVolumeSize(FF_IOMAN *pIoman);
|
|||
#endif
|
||||
|
||||
// PUBLIC (To FullFAT Only):
|
||||
FF_T_SINT32 FF_BlockRead (FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer);
|
||||
FF_T_SINT32 FF_BlockWrite (FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer);
|
||||
FF_ERROR FF_IncreaseFreeClusters (FF_IOMAN *pIoman, FF_T_UINT32 Count);
|
||||
FF_ERROR FF_DecreaseFreeClusters (FF_IOMAN *pIoman, FF_T_UINT32 Count);
|
||||
FF_BUFFER *FF_GetBuffer (FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode);
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef struct {
|
|||
|
||||
#else
|
||||
|
||||
#error Little or Big Endian?
|
||||
#error Little or Big Endian? - Please set an endianess in ff_config.h
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -44,11 +44,37 @@
|
|||
#define _FF_STRING_H_
|
||||
|
||||
#include "ff_types.h"
|
||||
#include "ff_config.h"
|
||||
#include <string.h>
|
||||
|
||||
void FF_tolower (FF_T_INT8 *string, FF_T_UINT32 strLen);
|
||||
void FF_toupper (FF_T_INT8 *string, FF_T_UINT32 strLen);
|
||||
FF_T_BOOL FF_strmatch (const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len);
|
||||
FF_T_INT8 *FF_strtok (const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length);
|
||||
FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString);
|
||||
#ifdef WIN32
|
||||
#define stricmp stricmp
|
||||
#define FF_stricmp stricmp
|
||||
#else
|
||||
#define strcasecmp strcasecmp
|
||||
#define FF_stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
void FF_tolower (FF_T_WCHAR *string, FF_T_UINT32 strLen);
|
||||
void FF_toupper (FF_T_WCHAR *string, FF_T_UINT32 strLen);
|
||||
FF_T_BOOL FF_strmatch (const FF_T_WCHAR *str1, const FF_T_WCHAR *str2, FF_T_UINT16 len);
|
||||
FF_T_WCHAR *FF_strtok (const FF_T_WCHAR *string, FF_T_WCHAR *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length);
|
||||
FF_T_BOOL FF_wildcompare (const FF_T_WCHAR *pszWildCard, const FF_T_WCHAR *pszString);
|
||||
|
||||
// ASCII to UTF16 and UTF16 to ASCII routines. -- These are lossy routines, and are only for converting ASCII to UTF-16
|
||||
// and the equivalent back to ASCII. Do not use them for international text.
|
||||
void FF_cstrtowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource);
|
||||
void FF_wcstocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource);
|
||||
void FF_cstrntowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource, FF_T_UINT32 len);
|
||||
void FF_wcsntocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource, FF_T_UINT32 len);
|
||||
|
||||
#else
|
||||
void FF_tolower (FF_T_INT8 *string, FF_T_UINT32 strLen);
|
||||
void FF_toupper (FF_T_INT8 *string, FF_T_UINT32 strLen);
|
||||
FF_T_BOOL FF_strmatch (const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len);
|
||||
FF_T_INT8 *FF_strtok (const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length);
|
||||
FF_T_BOOL FF_wildcompare (const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,11 @@ typedef long FF_T_INT32; ///< 32 bit default integer.
|
|||
typedef unsigned long FF_T_UINT32; ///< 32 bit unsigned integer.
|
||||
typedef signed long FF_T_SINT32; ///< 32 bit signed integer.
|
||||
|
||||
//---------------- Platform Integer Sizes
|
||||
typedef int FF_T_INT;
|
||||
typedef unsigned int FF_T_UINT;
|
||||
typedef signed int FF_T_SINT;
|
||||
|
||||
#ifdef FF_64_NUM_SUPPORT
|
||||
//---------------- 64 BIT INTEGERS // If you cannot define these, then make sure you see ff_config.h
|
||||
typedef long long FF_T_INT64; // about 64-bit number support.
|
||||
|
@ -70,5 +75,9 @@ typedef signed long long FF_T_SINT64; // > 4GB in bytes if you cannot support 64
|
|||
#endif
|
||||
|
||||
typedef FF_T_SINT32 FF_ERROR; ///< A special error code type to ease some inconsistencies in Error reporting.
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
#include <wchar.h>
|
||||
typedef wchar_t FF_T_WCHAR; ///< Unicode UTF-16 Charachter type, for FullFAT when UNICODE is enabled.
|
||||
#endif
|
||||
|
||||
#endif // end of include guard
|
||||
|
|
60
reactos/include/reactos/libs/fullfat/ff_unicode.h
Normal file
60
reactos/include/reactos/libs/fullfat/ff_unicode.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*****************************************************************************
|
||||
* 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. *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ff_unicode.c
|
||||
* @author James Walmsley
|
||||
* @ingroup UNICODE
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef _FF_UNICODE_H_
|
||||
#define _FF_UNICODE_H_
|
||||
|
||||
#include "ff_config.h"
|
||||
#include "ff_types.h"
|
||||
#include "ff_error.h"
|
||||
|
||||
// UTF8 / UTF16 Transformation Functions
|
||||
|
||||
FF_T_UINT FF_GetUtf16SequenceLen (FF_T_UINT16 usLeadChar);
|
||||
FF_T_SINT32 FF_Utf8ctoUtf16c (FF_T_UINT16 *utf16Dest, const FF_T_UINT8 *utf8Source, FF_T_UINT32 ulSize);
|
||||
FF_T_SINT32 FF_Utf16ctoUtf8c (FF_T_UINT8 *utf8Dest, const FF_T_UINT16 *utf16Source, FF_T_UINT32 ulSize);
|
||||
|
||||
// UTF16 / UTF32 Transformation Functions
|
||||
|
||||
FF_T_SINT32 FF_Utf16ctoUtf32c(FF_T_UINT32 *utf32Dest, const FF_T_UINT16 *utf16Source);
|
||||
FF_T_SINT32 FF_Utf32ctoUtf16c(FF_T_UINT16 *utf16Dest, FF_T_UINT32 utf32char, FF_T_UINT32 ulSize);
|
||||
|
||||
// String transformations
|
||||
FF_T_SINT32 FF_Utf32stoUtf8s(FF_T_UINT8 *Utf8String, FF_T_UINT32 *Utf32String);
|
||||
|
||||
#endif
|
|
@ -45,6 +45,7 @@ extern "C" {
|
|||
#include "ff_crc.h"
|
||||
#include "ff_hash.h"
|
||||
#include "ff_string.h"
|
||||
#include "ff_unicode.h"
|
||||
//#include "ff_format.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
73
reactos/lib/3rdparty/fullfat/ff_crc.c
vendored
73
reactos/lib/3rdparty/fullfat/ff_crc.c
vendored
|
@ -41,7 +41,68 @@
|
|||
|
||||
#include "ff_crc.h"
|
||||
|
||||
static const FF_T_UINT8 CRC16_Low[256] =
|
||||
|
||||
static const FF_T_UINT32 crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
|
||||
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
|
||||
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
|
||||
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
||||
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
|
||||
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
|
||||
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
|
||||
0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
|
||||
0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
|
||||
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
|
||||
0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
||||
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
|
||||
0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
|
||||
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
||||
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
|
||||
0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
|
||||
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
||||
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
|
||||
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
|
||||
0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
|
||||
0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
|
||||
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
||||
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
|
||||
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
|
||||
0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
||||
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
|
||||
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
|
||||
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
FF_T_UINT32 FF_GetCRC32(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) {
|
||||
|
||||
register FF_T_UINT32 crc = 0xFFFFFFFF;
|
||||
|
||||
while(stLength--) {
|
||||
crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc^*pbyData++) & 0x000000FF];
|
||||
}
|
||||
|
||||
return (crc ^ 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const FF_T_UINT8 crc16_table_low[256] =
|
||||
{
|
||||
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
|
||||
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
|
||||
|
@ -77,7 +138,7 @@ static const FF_T_UINT8 CRC16_Low[256] =
|
|||
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
|
||||
};
|
||||
|
||||
static const FF_T_UINT8 CRC16_High[256] =
|
||||
static const FF_T_UINT8 crc16_table_high[256] =
|
||||
{
|
||||
0x000, 0x0c0, 0x0c1, 0x001, 0x0c3, 0x003, 0x002, 0x0c2,
|
||||
0x0c6, 0x006, 0x007, 0x0c7, 0x005, 0x0c5, 0x0c4, 0x004,
|
||||
|
@ -130,15 +191,15 @@ FF_T_UINT16 FF_GetCRC16(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) {
|
|||
|
||||
while (stLength--) {
|
||||
bTableValue = (FF_T_UINT8)((wCRC & 0x00FF) ^ *pbyData++);
|
||||
wCRC = (FF_T_UINT16)(((CRC16_High[bTableValue]) << 8)
|
||||
+ (CRC16_Low[bTableValue] ^ ((wCRC >> 8) & 0x00FF)));
|
||||
wCRC = (FF_T_UINT16)(((crc16_table_high[bTableValue]) << 8)
|
||||
+ (crc16_table_low[bTableValue] ^ ((wCRC >> 8) & 0x00FF)));
|
||||
}
|
||||
|
||||
return wCRC;
|
||||
}
|
||||
|
||||
|
||||
static const FF_T_UINT8 byCRCLookUpTable[256] =
|
||||
static const FF_T_UINT8 crc8_table[256] =
|
||||
{
|
||||
0, 94, 188, 226, 97, 63, 221, 131,
|
||||
194, 156, 126, 32, 163, 253, 31, 65,
|
||||
|
@ -188,7 +249,7 @@ FF_T_UINT8 FF_GetCRC8(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) {
|
|||
FF_T_UINT8 byCRC = 0, byData;
|
||||
while (stLength--) {
|
||||
byData = *pbyData++;
|
||||
byCRC = byCRCLookUpTable[(byCRC ^ byData)];
|
||||
byCRC = crc8_table[(byCRC ^ byData)];
|
||||
}
|
||||
return byCRC;
|
||||
}
|
||||
|
|
2460
reactos/lib/3rdparty/fullfat/ff_dir.c
vendored
2460
reactos/lib/3rdparty/fullfat/ff_dir.c
vendored
File diff suppressed because it is too large
Load diff
134
reactos/lib/3rdparty/fullfat/ff_dir.h
vendored
134
reactos/lib/3rdparty/fullfat/ff_dir.h
vendored
|
@ -52,54 +52,118 @@
|
|||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
FF_T_INT8 FileName[FF_MAX_FILENAME];
|
||||
FF_T_UINT8 Attrib;
|
||||
FF_T_UINT32 ulChainLength;
|
||||
FF_T_UINT32 ulDirCluster;
|
||||
FF_T_UINT32 ulCurrentClusterLCN;
|
||||
FF_T_UINT32 ulCurrentClusterNum;
|
||||
FF_T_UINT32 ulCurrentEntry;
|
||||
FF_BUFFER *pBuffer;
|
||||
} FF_FETCH_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
FF_T_UINT32 Filesize;
|
||||
FF_T_UINT32 ObjectCluster;
|
||||
|
||||
|
||||
// Book Keeping
|
||||
FF_T_UINT32 CurrentCluster;
|
||||
FF_T_UINT32 AddrCurrentCluster;
|
||||
FF_T_UINT32 DirCluster;
|
||||
FF_T_UINT16 CurrentItem;
|
||||
// End Book Keeping
|
||||
|
||||
#ifdef FF_TIME_SUPPORT
|
||||
FF_SYSTEMTIME CreateTime; ///< Date and Time Created.
|
||||
FF_SYSTEMTIME ModifiedTime; ///< Date and Time Modified.
|
||||
FF_SYSTEMTIME AccessedTime; ///< Date of Last Access.
|
||||
#endif
|
||||
|
||||
//---- Book Keeping for FF_Find Functions
|
||||
FF_T_UINT16 CurrentItem;
|
||||
FF_T_UINT32 DirCluster;
|
||||
FF_T_UINT32 CurrentCluster;
|
||||
FF_T_UINT32 AddrCurrentCluster;
|
||||
//FF_T_UINT8 NumLFNs;
|
||||
#ifdef FF_FINDAPI_ALLOW_WILDCARDS
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_WCHAR szWildCard[FF_MAX_FILENAME];
|
||||
#else
|
||||
FF_T_INT8 szWildCard[FF_MAX_FILENAME];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_WCHAR FileName[FF_MAX_FILENAME];
|
||||
#else
|
||||
FF_T_INT8 FileName[FF_MAX_FILENAME];
|
||||
#endif
|
||||
|
||||
#if defined(FF_LFN_SUPPORT) && defined(FF_INCLUDE_SHORT_NAME)
|
||||
FF_T_INT8 ShortName[13];
|
||||
#endif
|
||||
FF_T_UINT8 Attrib;
|
||||
FF_FETCH_CONTEXT FetchContext;
|
||||
} FF_DIRENT;
|
||||
|
||||
FF_ERROR FF_GetEntry (FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_PutEntry (FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_FindEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_DIRENT *pDirent, FF_T_BOOL LFNs);
|
||||
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path);
|
||||
FF_ERROR FF_FindNext (FF_IOMAN *pIoman, FF_DIRENT *pDirent);
|
||||
void FF_PopulateShortDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer);
|
||||
FF_T_SINT8 FF_PopulateLongDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry);
|
||||
FF_T_SINT8 FF_FetchEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
|
||||
FF_T_SINT8 FF_PushEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
|
||||
FF_T_BOOL FF_isEndOfDir (FF_T_UINT8 *EntryBuffer);
|
||||
FF_T_SINT8 FF_FindNextInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_UINT32 FF_FindEntryInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_CreateShortName(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName);
|
||||
|
||||
void FF_lockDIR (FF_IOMAN *pIoman);
|
||||
void FF_unlockDIR (FF_IOMAN *pIoman);
|
||||
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent);
|
||||
FF_ERROR FF_MkDir(FF_IOMAN *pIoman, const FF_T_INT8 *Path);
|
||||
FF_T_SINT8 FF_CreateDirent(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_ExtendDirectory(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
FF_T_UINT32 FF_FindDir(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen);
|
||||
|
||||
|
||||
FF_T_BOOL FF_CheckDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
FF_T_BOOL FF_DirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
FF_ERROR FF_AddDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
void FF_SetDirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
// PUBLIC API
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_WCHAR *path);
|
||||
FF_ERROR FF_MkDir (FF_IOMAN *pIoman, const FF_T_WCHAR *Path);
|
||||
#else
|
||||
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path);
|
||||
FF_ERROR FF_MkDir (FF_IOMAN *pIoman, const FF_T_INT8 *Path);
|
||||
#endif
|
||||
|
||||
void FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 DirEntry);
|
||||
FF_ERROR FF_FindNext (FF_IOMAN *pIoman, FF_DIRENT *pDirent);
|
||||
|
||||
|
||||
// INTERNAL API
|
||||
FF_ERROR FF_GetEntry (FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_ERROR FF_PutEntry (FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_T_SINT8 FF_FindEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_DIRENT *pDirent, FF_T_BOOL LFNs);
|
||||
|
||||
void FF_PopulateShortDirent (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer);
|
||||
FF_ERROR FF_PopulateLongDirent (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT16 nEntry, FF_FETCH_CONTEXT *pFetchContext);
|
||||
|
||||
FF_ERROR FF_InitEntryFetch (FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_FETCH_CONTEXT *pContext);
|
||||
FF_ERROR FF_FetchEntryWithContext (FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer);
|
||||
FF_ERROR FF_PushEntryWithContext (FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer);
|
||||
void FF_CleanupEntryFetch (FF_IOMAN *pIoman, FF_FETCH_CONTEXT *pContext);
|
||||
|
||||
FF_T_SINT8 FF_PushEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer, void *pParam);
|
||||
FF_T_BOOL FF_isEndOfDir (FF_T_UINT8 *EntryBuffer);
|
||||
FF_ERROR FF_FindNextInDir (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_FETCH_CONTEXT *pFetchContext);
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_UINT32 FF_FindEntryInDir (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_WCHAR *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
FF_T_SINT8 FF_CreateShortName (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *ShortName, FF_T_WCHAR *LongName);
|
||||
#else
|
||||
FF_T_UINT32 FF_FindEntryInDir (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
FF_T_SINT8 FF_CreateShortName (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName);
|
||||
#endif
|
||||
|
||||
|
||||
void FF_lockDIR (FF_IOMAN *pIoman);
|
||||
void FF_unlockDIR (FF_IOMAN *pIoman);
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *FileName, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
#else
|
||||
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent, FF_ERROR *pError);
|
||||
#endif
|
||||
|
||||
FF_ERROR FF_CreateDirent (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
|
||||
FF_ERROR FF_ExtendDirectory (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_UINT32 FF_FindDir (FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT16 pathLen, FF_ERROR *pError);
|
||||
#else
|
||||
FF_T_UINT32 FF_FindDir (FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen, FF_ERROR *pError);
|
||||
#endif
|
||||
|
||||
#ifdef FF_HASH_CACHE
|
||||
FF_T_BOOL FF_CheckDirentHash (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
FF_T_BOOL FF_DirHashed (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
|
||||
FF_ERROR FF_AddDirentHash (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
|
||||
FF_ERROR FF_HashDir (FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster);
|
||||
#endif
|
||||
|
||||
FF_ERROR FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT16 usDirEntry, FF_FETCH_CONTEXT *pContext);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
6
reactos/lib/3rdparty/fullfat/ff_error.c
vendored
6
reactos/lib/3rdparty/fullfat/ff_error.c
vendored
|
@ -56,7 +56,7 @@ const struct _FFERRTAB
|
|||
{"Not enough memory (malloc() returned NULL).", FF_ERR_NOT_ENOUGH_MEMORY},
|
||||
{"Device Driver returned a FATAL error!.", FF_ERR_DEVICE_DRIVER_FAILED},
|
||||
{"The blocksize is not 512 multiple.", FF_ERR_IOMAN_BAD_BLKSIZE},
|
||||
{"The provided memory size, is not a multiple of the blocksize.", FF_ERR_IOMAN_BAD_MEMSIZE},
|
||||
{"The memory size, is not a multiple of the blocksize. (Atleast 2 Blocks).", FF_ERR_IOMAN_BAD_MEMSIZE},
|
||||
{"Device is already registered, use FF_UnregisterBlkDevice() first.", FF_ERR_IOMAN_DEV_ALREADY_REGD},
|
||||
{"No mountable partition was found on the specified device.", FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION},
|
||||
{"The format of the MBR was unrecognised.", FF_ERR_IOMAN_INVALID_FORMAT},
|
||||
|
@ -65,6 +65,7 @@ const struct _FFERRTAB
|
|||
{"Cannot register device. (BlkSize not a multiple of 512).", FF_ERR_IOMAN_DEV_INVALID_BLKSIZE},
|
||||
{"Cannot unregister device, a partition is still mounted.", FF_ERR_IOMAN_PARTITION_MOUNTED},
|
||||
{"Cannot unmount the partition while there are active FILE handles.", FF_ERR_IOMAN_ACTIVE_HANDLES},
|
||||
{"The GPT partition header appears to be corrupt, refusing to mount.", FF_ERR_IOMAN_GPT_HEADER_CORRUPT},
|
||||
{"Cannot open the file, file already in use.", FF_ERR_FILE_ALREADY_OPEN},
|
||||
{"The specified file could not be found.", FF_ERR_FILE_NOT_FOUND},
|
||||
{"Cannot open a Directory.", FF_ERR_FILE_OBJECT_IS_A_DIR},
|
||||
|
@ -84,6 +85,9 @@ const struct _FFERRTAB
|
|||
{"Source file was not found.", FF_ERR_FILE_SOURCE_NOT_FOUND},
|
||||
{"Destination path (dir) was not found.", FF_ERR_FILE_DIR_NOT_FOUND},
|
||||
{"Failed to create the directory Entry.", FF_ERR_FILE_COULD_NOT_CREATE_DIRENT},
|
||||
{"Not enough free disk space to complete the disk transaction.", FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE},
|
||||
{"Attempted to Read a sector out of bounds.", FF_ERR_IOMAN_OUT_OF_BOUNDS_READ},
|
||||
{"Attempted to Write a sector out of bounds.", FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
168
reactos/lib/3rdparty/fullfat/ff_fat.c
vendored
168
reactos/lib/3rdparty/fullfat/ff_fat.c
vendored
|
@ -110,7 +110,7 @@ FF_T_UINT32 FF_LBA2Cluster(FF_IOMAN *pIoman, FF_T_UINT32 Address) {
|
|||
/**
|
||||
* @private
|
||||
**/
|
||||
FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
||||
FF_T_UINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_ERROR *pError) {
|
||||
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_T_UINT32 FatOffset;
|
||||
|
@ -148,7 +148,8 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
|||
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ);
|
||||
{
|
||||
if(!pBuffer) {
|
||||
return FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
return 0;
|
||||
}
|
||||
F12short[0] = FF_getChar(pBuffer->pBuffer, (FF_T_UINT16)(pIoman->BlkSize - 1));
|
||||
}
|
||||
|
@ -157,7 +158,8 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
|||
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust + 1, FF_MODE_READ);
|
||||
{
|
||||
if(!pBuffer) {
|
||||
return FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
return 0;
|
||||
}
|
||||
F12short[1] = FF_getChar(pBuffer->pBuffer, 0);
|
||||
}
|
||||
|
@ -176,7 +178,8 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
|||
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ);
|
||||
{
|
||||
if(!pBuffer) {
|
||||
return FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(pIoman->pPartition->Type) {
|
||||
|
@ -208,11 +211,10 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
|||
return (FF_T_SINT32) FatEntry;
|
||||
}
|
||||
|
||||
FF_T_SINT8 FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
||||
FF_ERROR FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_T_UINT16 i;
|
||||
FF_T_UINT32 BaseLBA;
|
||||
FF_T_SINT8 RetVal = 0;
|
||||
|
||||
BaseLBA = FF_Cluster2LBA(pIoman, nCluster);
|
||||
BaseLBA = FF_getRealLBA(pIoman, BaseLBA);
|
||||
|
@ -220,16 +222,15 @@ FF_T_SINT8 FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
|||
for(i = 0; i < pIoman->pPartition->SectorsPerCluster; i++) {
|
||||
pBuffer = FF_GetBuffer(pIoman, BaseLBA++, FF_MODE_WRITE);
|
||||
{
|
||||
if(pBuffer) {
|
||||
memset(pBuffer->pBuffer, 0x00, 512);
|
||||
} else {
|
||||
RetVal = FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
if(!pBuffer) {
|
||||
return FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
}
|
||||
memset(pBuffer->pBuffer, 0x00, 512);
|
||||
}
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
}
|
||||
|
||||
return RetVal;
|
||||
return FF_ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,17 +241,19 @@ FF_T_SINT8 FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
|
|||
* @param Start Cluster address of the first cluster in the chain.
|
||||
* @param Count Number of Cluster in the chain,
|
||||
*
|
||||
* @return FF_TRUE if it is an end of chain, otherwise FF_FALSE.
|
||||
*
|
||||
*
|
||||
**/
|
||||
FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count) {
|
||||
FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count, FF_ERROR *pError) {
|
||||
|
||||
FF_T_UINT32 i;
|
||||
FF_T_UINT32 fatEntry = Start, currentCluster = Start;
|
||||
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
for(i = 0; i < Count; i++) {
|
||||
fatEntry = FF_getFatEntry(pIoman, currentCluster);
|
||||
if(fatEntry == (FF_T_UINT32) FF_ERR_DEVICE_DRIVER_FAILED) {
|
||||
fatEntry = FF_getFatEntry(pIoman, currentCluster, pError);
|
||||
if(*pError) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -264,13 +267,14 @@ FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Coun
|
|||
return fatEntry;
|
||||
}
|
||||
|
||||
FF_T_UINT32 FF_FindEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 Start) {
|
||||
FF_T_UINT32 FF_FindEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_ERROR *pError) {
|
||||
|
||||
FF_T_UINT32 fatEntry = Start, currentCluster = Start;
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
while(!FF_isEndOfChain(pIoman, fatEntry)) {
|
||||
fatEntry = FF_getFatEntry(pIoman, currentCluster);
|
||||
if(fatEntry == (FF_T_UINT32) FF_ERR_DEVICE_DRIVER_FAILED) {
|
||||
fatEntry = FF_getFatEntry(pIoman, currentCluster, pError);
|
||||
if(*pError) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -325,7 +329,7 @@ FF_T_BOOL FF_isEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 fatEntry) {
|
|||
* @param nCluster Cluster Number to be modified.
|
||||
* @param Value The Value to store.
|
||||
**/
|
||||
FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value) {
|
||||
FF_ERROR FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value) {
|
||||
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_T_UINT32 FatOffset;
|
||||
|
@ -439,7 +443,7 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va
|
|||
}
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
|
||||
return 0;
|
||||
return FF_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -454,12 +458,17 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va
|
|||
* @return 0 on error.
|
||||
**/
|
||||
#ifdef FF_FAT12_SUPPORT
|
||||
FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman) {
|
||||
static FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman, FF_ERROR *pError) {
|
||||
FF_T_UINT32 nCluster;
|
||||
FF_T_UINT32 fatEntry;
|
||||
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
for(nCluster = pIoman->pPartition->LastFreeCluster; nCluster < pIoman->pPartition->NumClusters; nCluster++) {
|
||||
fatEntry = FF_getFatEntry(pIoman, nCluster);
|
||||
fatEntry = FF_getFatEntry(pIoman, nCluster, pError);
|
||||
if(*pError) {
|
||||
return 0;
|
||||
}
|
||||
if(fatEntry == 0x00000000) {
|
||||
pIoman->pPartition->LastFreeCluster = nCluster;
|
||||
return nCluster;
|
||||
|
@ -469,7 +478,7 @@ FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman) {
|
|||
}
|
||||
#endif
|
||||
|
||||
FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
|
||||
FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman, FF_ERROR *pError) {
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_T_UINT32 i, x, nCluster = pIoman->pPartition->LastFreeCluster;
|
||||
FF_T_UINT32 FatOffset;
|
||||
|
@ -478,9 +487,11 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
|
|||
FF_T_UINT32 EntriesPerSector;
|
||||
FF_T_UINT32 FatEntry = 1;
|
||||
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
#ifdef FF_FAT12_SUPPORT
|
||||
if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated!
|
||||
return FF_FindFreeClusterOLD(pIoman);
|
||||
return FF_FindFreeClusterOLD(pIoman, pError);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -491,15 +502,20 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
|
|||
EntriesPerSector = pIoman->BlkSize / 2;
|
||||
FatOffset = nCluster * 2;
|
||||
}
|
||||
|
||||
// HT addition: don't use non-existing clusters
|
||||
if (nCluster >= pIoman->pPartition->NumClusters) {
|
||||
*pError = FF_ERR_FAT_NO_FREE_CLUSTERS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
FatSector = (FatOffset / pIoman->pPartition->BlkSize);
|
||||
|
||||
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);
|
||||
if(!pBuffer) {
|
||||
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
return 0;
|
||||
}
|
||||
for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) {
|
||||
|
@ -533,24 +549,54 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
|
|||
* @private
|
||||
* @brief Create's a Cluster Chain
|
||||
**/
|
||||
FF_T_UINT32 FF_CreateClusterChain(FF_IOMAN *pIoman) {
|
||||
FF_T_UINT32 FF_CreateClusterChain(FF_IOMAN *pIoman, FF_ERROR *pError) {
|
||||
FF_T_UINT32 iStartCluster;
|
||||
FF_ERROR Error;
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
FF_lockFAT(pIoman);
|
||||
{
|
||||
iStartCluster = FF_FindFreeCluster(pIoman);
|
||||
FF_putFatEntry(pIoman, iStartCluster, 0xFFFFFFFF); // Mark the cluster as EOC
|
||||
iStartCluster = FF_FindFreeCluster(pIoman, &Error);
|
||||
if(Error) {
|
||||
*pError = Error;
|
||||
FF_unlockFAT(pIoman);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(iStartCluster) {
|
||||
Error = FF_putFatEntry(pIoman, iStartCluster, 0xFFFFFFFF); // Mark the cluster as End-Of-Chain
|
||||
if(Error) {
|
||||
*pError = Error;
|
||||
FF_unlockFAT(pIoman);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
FF_unlockFAT(pIoman);
|
||||
|
||||
if(iStartCluster) {
|
||||
Error = FF_DecreaseFreeClusters(pIoman, 1);
|
||||
if(Error) {
|
||||
*pError = Error;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return iStartCluster;
|
||||
}
|
||||
|
||||
FF_T_UINT32 FF_GetChainLength(FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain) {
|
||||
FF_T_UINT32 FF_GetChainLength(FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain, FF_ERROR *pError) {
|
||||
FF_T_UINT32 iLength = 0;
|
||||
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
FF_lockFAT(pIoman);
|
||||
{
|
||||
while(!FF_isEndOfChain(pIoman, pa_nStartCluster)) {
|
||||
pa_nStartCluster = FF_getFatEntry(pIoman, pa_nStartCluster);
|
||||
pa_nStartCluster = FF_getFatEntry(pIoman, pa_nStartCluster, pError);
|
||||
if(*pError) {
|
||||
return 0;
|
||||
}
|
||||
iLength++;
|
||||
}
|
||||
if(piEndOfChain) {
|
||||
|
@ -612,12 +658,13 @@ FF_T_UINT32 FF_ExtendClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF
|
|||
* @return -1 If the device driver failed to provide access.
|
||||
*
|
||||
**/
|
||||
FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count) {
|
||||
FF_ERROR FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count) {
|
||||
|
||||
FF_T_UINT32 fatEntry;
|
||||
FF_T_UINT32 currentCluster, chainLength = 0;
|
||||
FF_T_UINT32 iLen = 0;
|
||||
FF_T_UINT32 lastFree = StartCluster; /* HT addition : reset LastFreeCluster */
|
||||
FF_ERROR Error;
|
||||
|
||||
fatEntry = StartCluster;
|
||||
|
||||
|
@ -626,8 +673,15 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_
|
|||
currentCluster = StartCluster;
|
||||
fatEntry = currentCluster;
|
||||
do {
|
||||
fatEntry = FF_getFatEntry(pIoman, fatEntry);
|
||||
FF_putFatEntry(pIoman, currentCluster, 0x00000000);
|
||||
fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error);
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
Error = FF_putFatEntry(pIoman, currentCluster, 0x00000000);
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
|
||||
if (lastFree > currentCluster) {
|
||||
lastFree = currentCluster;
|
||||
}
|
||||
|
@ -637,11 +691,17 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_
|
|||
if (pIoman->pPartition->LastFreeCluster > lastFree) {
|
||||
pIoman->pPartition->LastFreeCluster = lastFree;
|
||||
}
|
||||
FF_IncreaseFreeClusters(pIoman, iLen);
|
||||
Error = FF_IncreaseFreeClusters(pIoman, iLen);
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
} else {
|
||||
// Truncation - This is quite hard, because we can only do it backwards.
|
||||
do {
|
||||
fatEntry = FF_getFatEntry(pIoman, fatEntry);
|
||||
fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error);
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
chainLength++;
|
||||
}while(!FF_isEndOfChain(pIoman, fatEntry));
|
||||
}
|
||||
|
@ -650,14 +710,19 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_
|
|||
}
|
||||
|
||||
#ifdef FF_FAT12_SUPPORT
|
||||
FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman) {
|
||||
FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman, FF_ERROR *pError) {
|
||||
FF_T_UINT32 i;
|
||||
FF_T_UINT32 TotalClusters = pIoman->pPartition->DataSectors / pIoman->pPartition->SectorsPerCluster;
|
||||
FF_T_UINT32 FatEntry;
|
||||
FF_T_UINT32 FreeClusters = 0;
|
||||
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
for(i = 0; i < TotalClusters; i++) {
|
||||
FatEntry = FF_getFatEntry(pIoman, i);
|
||||
FatEntry = FF_getFatEntry(pIoman, i, pError);
|
||||
if(*pError) {
|
||||
return 0;
|
||||
}
|
||||
if(!FatEntry) {
|
||||
FreeClusters++;
|
||||
}
|
||||
|
@ -668,7 +733,7 @@ FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman) {
|
|||
#endif
|
||||
|
||||
|
||||
FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
|
||||
FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman, FF_ERROR *pError) {
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_T_UINT32 i, x, nCluster = 0;
|
||||
FF_T_UINT32 FatOffset;
|
||||
|
@ -678,9 +743,14 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
|
|||
FF_T_UINT32 FatEntry = 1;
|
||||
FF_T_UINT32 FreeClusters = 0;
|
||||
|
||||
*pError = FF_ERR_NONE;
|
||||
|
||||
#ifdef FF_FAT12_SUPPORT
|
||||
if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated!
|
||||
return FF_CountFreeClustersOLD(pIoman);
|
||||
FreeClusters = FF_CountFreeClustersOLD(pIoman, pError);
|
||||
if(*pError) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -697,6 +767,10 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
|
|||
for(i = 0; i < pIoman->pPartition->SectorsPerFAT; i++) {
|
||||
pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ);
|
||||
{
|
||||
if(!pBuffer) {
|
||||
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
return 0;
|
||||
}
|
||||
for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) {
|
||||
if(pIoman->pPartition->Type == FF_T_FAT32) {
|
||||
FatOffset = x * 4;
|
||||
|
@ -722,15 +796,23 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
|
|||
}
|
||||
|
||||
#ifdef FF_64_NUM_SUPPORT
|
||||
FF_T_UINT64 FF_GetFreeSize(FF_IOMAN *pIoman) {
|
||||
FF_T_UINT64 FF_GetFreeSize(FF_IOMAN *pIoman, FF_ERROR *pError) {
|
||||
FF_T_UINT32 FreeClusters;
|
||||
FF_T_UINT64 FreeSize;
|
||||
FF_ERROR Error;
|
||||
|
||||
if(pIoman) {
|
||||
FF_lockFAT(pIoman);
|
||||
{
|
||||
if(!pIoman->pPartition->FreeClusterCount) {
|
||||
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman);
|
||||
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error);
|
||||
if(Error) {
|
||||
if(pError) {
|
||||
*pError = Error;
|
||||
}
|
||||
FF_unlockFAT(pIoman);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
FreeClusters = pIoman->pPartition->FreeClusterCount;
|
||||
}
|
||||
|
|
716
reactos/lib/3rdparty/fullfat/ff_file.c
vendored
716
reactos/lib/3rdparty/fullfat/ff_file.c
vendored
File diff suppressed because it is too large
Load diff
132
reactos/lib/3rdparty/fullfat/ff_format.c
vendored
Normal file
132
reactos/lib/3rdparty/fullfat/ff_format.c
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*****************************************************************************
|
||||
* 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. *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ff_format.c
|
||||
* @author James Walmsley
|
||||
* @ingroup FORMAT
|
||||
*
|
||||
* @defgroup FORMAT Independent FAT Formatter
|
||||
* @brief Provides an interface to format a partition with FAT.
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
#include "ff_format.h"
|
||||
#include "ff_types.h"
|
||||
#include "ff_ioman.h"
|
||||
#include "ff_fatdef.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
FF_ERROR FF_FormatPartition(FF_IOMAN *pIoman, FF_T_UINT32 ulPartitionNumber, FF_T_UINT32 ulClusterSize) {
|
||||
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_T_UINT8 ucPartitionType;
|
||||
FF_T_SINT8 scPartitionCount;
|
||||
|
||||
FF_T_UINT32 /*ulPartitionBeginLBA, ulPartitionLength,*/ ulPnum;
|
||||
|
||||
FF_ERROR Error = FF_ERR_NONE;
|
||||
|
||||
ulClusterSize = 0;
|
||||
|
||||
// Get Partition Metrics, and pass on to FF_Format() function
|
||||
|
||||
pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ);
|
||||
{
|
||||
if(!pBuffer) {
|
||||
return FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
}
|
||||
|
||||
scPartitionCount = FF_PartitionCount(pBuffer->pBuffer);
|
||||
|
||||
ucPartitionType = FF_getChar(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID);
|
||||
|
||||
if(ucPartitionType == 0xEE) {
|
||||
// Handle Extended Partitions
|
||||
ulPnum = 0;
|
||||
} else {
|
||||
if(ulPartitionNumber > (FF_T_UINT32) scPartitionCount) {
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
|
||||
}
|
||||
ulPnum = ulPartitionNumber;
|
||||
}
|
||||
|
||||
}
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
|
||||
|
||||
|
||||
return Error;
|
||||
|
||||
}
|
||||
|
||||
FF_ERROR FF_Format(FF_IOMAN *pIoman, FF_T_UINT32 ulStartLBA, FF_T_UINT32 ulEndLBA, FF_T_UINT32 ulClusterSize) {
|
||||
FF_T_UINT32 ulTotalSectors;
|
||||
FF_T_UINT32 ulTotalClusters;
|
||||
|
||||
ulTotalSectors = ulEndLBA - ulStartLBA;
|
||||
ulTotalClusters = ulTotalSectors / (ulClusterSize / pIoman->BlkSize);
|
||||
|
||||
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
4
reactos/lib/3rdparty/fullfat/ff_hash.c
vendored
4
reactos/lib/3rdparty/fullfat/ff_hash.c
vendored
|
@ -43,9 +43,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef FF_HASH_TABLE_SUPPORT
|
||||
#ifdef FF_HASH_CACHE
|
||||
struct _FF_HASH_TABLE {
|
||||
FF_T_UINT8 bitTable[FF_HASH_TABLE_SIZE];
|
||||
FF_T_UINT8 bitTable[FF_HASH_TABLE_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
462
reactos/lib/3rdparty/fullfat/ff_ioman.c
vendored
462
reactos/lib/3rdparty/fullfat/ff_ioman.c
vendored
|
@ -46,9 +46,10 @@
|
|||
|
||||
#include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, <stdio.h>
|
||||
#include "ff_fatdef.h"
|
||||
#include "ff_crc.h"
|
||||
|
||||
extern FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
|
||||
extern FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman);
|
||||
//extern FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
|
||||
extern FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman, FF_ERROR *pError);
|
||||
|
||||
static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman);
|
||||
|
||||
|
@ -57,7 +58,7 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman);
|
|||
* @brief Creates an FF_IOMAN object, to initialise FullFAT
|
||||
*
|
||||
* @param pCacheMem Pointer to a buffer for the cache. (NULL if ok to Malloc).
|
||||
* @param Size The size of the provided buffer, or size of the cache to be created.
|
||||
* @param Size The size of the provided buffer, or size of the cache to be created. (Must be atleast 2 * BlkSize). Always a multiple of BlkSize.
|
||||
* @param BlkSize The block size of devices to be attached. If in doubt use 512.
|
||||
* @param pError Pointer to a signed byte for error checking. Can be NULL if not required.
|
||||
* @param pError To be checked when a NULL pointer is returned.
|
||||
|
@ -77,16 +78,16 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
*pError = FF_ERR_NONE;
|
||||
}
|
||||
|
||||
if((BlkSize % 512) != 0 || Size == 0) {
|
||||
if((BlkSize % 512) != 0 || BlkSize == 0) {
|
||||
if(pError) {
|
||||
*pError = FF_ERR_IOMAN_BAD_BLKSIZE;
|
||||
*pError = FF_ERR_IOMAN_BAD_BLKSIZE | FF_CREATEIOMAN;
|
||||
}
|
||||
return NULL; // BlkSize Size not a multiple of 512 > 0
|
||||
}
|
||||
|
||||
if((Size % BlkSize) != 0 || Size == 0) {
|
||||
if((Size % BlkSize) != 0 || Size == 0 || Size == BlkSize) { // Size must now be atleast 2 * BlkSize (or a deadlock will occur).
|
||||
if(pError) {
|
||||
*pError = FF_ERR_IOMAN_BAD_MEMSIZE;
|
||||
*pError = FF_ERR_IOMAN_BAD_MEMSIZE | FF_CREATEIOMAN;
|
||||
}
|
||||
return NULL; // Memory Size not a multiple of BlkSize > 0
|
||||
}
|
||||
|
@ -95,7 +96,7 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
|
||||
if(!pIoman) { // Ensure malloc() succeeded.
|
||||
if(pError) {
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY;
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -107,7 +108,7 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
pIoman->pPartition = (FF_PARTITION *) FF_MALLOC(sizeof(FF_PARTITION));
|
||||
if(!pIoman->pPartition) {
|
||||
if(pError) {
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY;
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
|
||||
}
|
||||
FF_DestroyIOMAN(pIoman);
|
||||
return NULL;
|
||||
|
@ -122,17 +123,25 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
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
|
||||
/*#ifdef FF_HASH_TABLE_SUPPORT
|
||||
pIoman->pPartition->PathCache[i].pHashTable = FF_CreateHashTable();
|
||||
pIoman->pPartition->PathCache[i].bHashed = FF_FALSE;
|
||||
#endif*/
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FF_HASH_CACHE
|
||||
for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) {
|
||||
pIoman->HashCache[i].pHashTable = FF_CreateHashTable();
|
||||
pIoman->HashCache[i].ulDirCluster = 0;
|
||||
pIoman->HashCache[i].ulMisses = 100;
|
||||
}
|
||||
#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;
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
|
||||
}
|
||||
FF_DestroyIOMAN(pIoman);
|
||||
return NULL;
|
||||
|
@ -141,8 +150,8 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV;
|
||||
|
||||
// Make sure all pointers are NULL
|
||||
pIoman->pBlkDevice->fnReadBlocks = NULL;
|
||||
pIoman->pBlkDevice->fnWriteBlocks = NULL;
|
||||
pIoman->pBlkDevice->fnpReadBlocks = NULL;
|
||||
pIoman->pBlkDevice->fnpWriteBlocks = NULL;
|
||||
pIoman->pBlkDevice->pParam = NULL;
|
||||
|
||||
// Organise the memory provided, or create our own!
|
||||
|
@ -153,7 +162,7 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
pIoman->pCacheMem = (FF_T_UINT8 *) pLong;
|
||||
if(!pIoman->pCacheMem) {
|
||||
if(pError) {
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY;
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
|
||||
}
|
||||
FF_DestroyIOMAN(pIoman);
|
||||
return NULL;
|
||||
|
@ -175,7 +184,7 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
|
||||
if(!pIoman->pBuffers) {
|
||||
if(pError) {
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY;
|
||||
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
|
||||
}
|
||||
FF_DestroyIOMAN(pIoman);
|
||||
return NULL; // HT added
|
||||
|
@ -188,6 +197,10 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
// Finally create a Semaphore for Buffer Description modifications.
|
||||
pIoman->pSemaphore = FF_CreateSemaphore();
|
||||
|
||||
#ifdef FF_BLKDEV_USES_SEM
|
||||
pIoman->pBlkDevSemaphore = FF_CreateSemaphore();
|
||||
#endif
|
||||
|
||||
return pIoman; // Sucess, return the created object.
|
||||
}
|
||||
|
||||
|
@ -202,9 +215,13 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
|
|||
**/
|
||||
FF_ERROR FF_DestroyIOMAN(FF_IOMAN *pIoman) {
|
||||
|
||||
#ifdef FF_HASH_CACHE
|
||||
FF_T_UINT32 i;
|
||||
#endif
|
||||
|
||||
// Ensure no NULL pointer was provided.
|
||||
if(!pIoman) {
|
||||
return FF_ERR_NULL_POINTER;
|
||||
return FF_ERR_NULL_POINTER | FF_DESTROYIOMAN;
|
||||
}
|
||||
|
||||
// Ensure pPartition pointer was allocated.
|
||||
|
@ -231,6 +248,18 @@ FF_ERROR FF_DestroyIOMAN(FF_IOMAN *pIoman) {
|
|||
if(pIoman->pSemaphore) {
|
||||
FF_DestroySemaphore(pIoman->pSemaphore);
|
||||
}
|
||||
#ifdef FF_BLKDEV_USES_SEM
|
||||
if(pIoman->pBlkDevSemaphore) {
|
||||
FF_DestroySemaphore(pIoman->pBlkDevSemaphore);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Destroy HashCache
|
||||
#ifdef FF_HASH_CACHE
|
||||
for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) {
|
||||
FF_DestroyHashTable(pIoman->HashCache[i].pHashTable);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Finally free the FF_IOMAN object.
|
||||
FF_FREE(pIoman);
|
||||
|
@ -256,94 +285,6 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @brief Tests the Mode for validity.
|
||||
*
|
||||
* @param Mode Mode of buffer to check.
|
||||
*
|
||||
* @return FF_TRUE when valid, else FF_FALSE.
|
||||
**/
|
||||
/*static FF_T_BOOL FF_IOMAN_ModeValid(FF_T_UINT8 Mode) {
|
||||
if(Mode == FF_MODE_READ || Mode == FF_MODE_WRITE) {
|
||||
return FF_TRUE;
|
||||
}
|
||||
return FF_FALSE;
|
||||
}*/
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @brief Fills a buffer with the appropriate sector via the device driver.
|
||||
*
|
||||
* @param pIoman FF_IOMAN object.
|
||||
* @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);
|
||||
}
|
||||
} while(retVal == FF_ERR_DRIVER_BUSY);
|
||||
if(retVal < 0) {
|
||||
return -1; // FF_ERR_DRIVER_FATAL_ERROR was returned Fail!
|
||||
} else {
|
||||
if(retVal == 1) {
|
||||
return 0; // 1 Block was sucessfully read.
|
||||
} else {
|
||||
return -1; // 0 Blocks we're read, Error!
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; // error no device diver registered.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @brief Flushes a buffer to the device driver.
|
||||
*
|
||||
* @param pIoman FF_IOMAN object.
|
||||
* @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) {
|
||||
FF_T_SINT32 retVal = 0;
|
||||
if(pIoman->pBlkDevice->fnWriteBlocks) { // Make sure we don't execute a NULL.
|
||||
do{
|
||||
retVal = pIoman->pBlkDevice->fnWriteBlocks(pBuffer, Sector, 1, pIoman->pBlkDevice->pParam);
|
||||
if(retVal == FF_ERR_DRIVER_BUSY) {
|
||||
FF_Sleep(FF_DRIVER_BUSY_SLEEP);
|
||||
}
|
||||
} while(retVal == FF_ERR_DRIVER_BUSY);
|
||||
if(retVal < 0) {
|
||||
return -1; // FF_ERR_DRIVER_FATAL_ERROR was returned Fail!
|
||||
} else {
|
||||
if(retVal == 1) {
|
||||
return FF_ERR_NONE; // 1 Block was sucessfully written.
|
||||
} else {
|
||||
return -1; // 0 Blocks we're written, Error!
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; // error no device diver registered.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
|
@ -358,7 +299,7 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
|
|||
FF_T_UINT16 i,x;
|
||||
|
||||
if(!pIoman) {
|
||||
return FF_ERR_NULL_POINTER;
|
||||
return FF_ERR_NULL_POINTER | FF_FLUSHCACHE;
|
||||
}
|
||||
|
||||
FF_PendSemaphore(pIoman->pSemaphore);
|
||||
|
@ -366,7 +307,7 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
|
|||
for(i = 0; i < pIoman->CacheSize; i++) {
|
||||
if((pIoman->pBuffers + i)->NumHandles == 0 && (pIoman->pBuffers + i)->Modified == FF_TRUE) {
|
||||
|
||||
FF_IOMAN_FlushBuffer(pIoman, (pIoman->pBuffers + i)->Sector, (pIoman->pBuffers + i)->pBuffer);
|
||||
FF_BlockWrite(pIoman, (pIoman->pBuffers + i)->Sector, 1, (pIoman->pBuffers + i)->pBuffer);
|
||||
|
||||
// Buffer has now been flushed, mark it as a read buffer and unmodified.
|
||||
(pIoman->pBuffers + i)->Mode = FF_MODE_READ;
|
||||
|
@ -389,13 +330,6 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
|
|||
return FF_ERR_NONE;
|
||||
}
|
||||
|
||||
/*static FF_T_BOOL FF_isFATSector(FF_IOMAN *pIoman, FF_T_UINT32 Sector) {
|
||||
if(Sector >= pIoman->pPartition->FatBeginLBA && Sector < (pIoman->pPartition->FatBeginLBA + pIoman->pPartition->ReservedSectors)) {
|
||||
return FF_TRUE;
|
||||
}
|
||||
return FF_FALSE;
|
||||
}*/
|
||||
|
||||
FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_BUFFER *pBufLRU = NULL;
|
||||
|
@ -407,35 +341,13 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
|
|||
while(!pBufMatch) {
|
||||
FF_PendSemaphore(pIoman->pSemaphore);
|
||||
{
|
||||
for(i = 0; i < pIoman->CacheSize; i++) {
|
||||
pBuffer = pIoman->pBuffers;
|
||||
// HT if a perfect match has priority, find that first
|
||||
for(i = 0; i < pIoman->CacheSize; i++, pBuffer++) {
|
||||
pBuffer = (pIoman->pBuffers + i);
|
||||
if(pBuffer->Sector == Sector && pBuffer->Valid == FF_TRUE) {
|
||||
pBufMatch = pBuffer;
|
||||
} else {
|
||||
if(pBuffer->NumHandles == 0) {
|
||||
pBuffer->LRU += 1;
|
||||
|
||||
if(!pBufLRU) {
|
||||
pBufLRU = pBuffer;
|
||||
}
|
||||
if(!pBufLHITS) {
|
||||
pBufLHITS = pBuffer;
|
||||
}
|
||||
|
||||
if(pBuffer->LRU >= pBufLRU->LRU) {
|
||||
if(pBuffer->LRU == pBufLRU->LRU) {
|
||||
if(pBuffer->Persistance > pBufLRU->Persistance) {
|
||||
pBufLRU = pBuffer;
|
||||
}
|
||||
} else {
|
||||
pBufLRU = pBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
if(pBuffer->Persistance < pBufLHITS->Persistance) {
|
||||
pBufLHITS = pBuffer;
|
||||
}
|
||||
}
|
||||
break; // Why look further if you found a perfect match?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,11 +380,38 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
|
|||
pBufMatch = NULL; // Sector is already in use, keep yielding until its available!
|
||||
|
||||
} else {
|
||||
// Choose a suitable buffer!
|
||||
pBuffer = pIoman->pBuffers;
|
||||
for(i = 0; i < pIoman->CacheSize; i++, pBuffer++) {
|
||||
if(pBuffer->NumHandles == 0) {
|
||||
pBuffer->LRU += 1;
|
||||
|
||||
if(!pBufLRU) {
|
||||
pBufLRU = pBuffer;
|
||||
}
|
||||
if(!pBufLHITS) {
|
||||
pBufLHITS = pBuffer;
|
||||
}
|
||||
|
||||
if(pBuffer->LRU >= pBufLRU->LRU) {
|
||||
if(pBuffer->LRU == pBufLRU->LRU) {
|
||||
if(pBuffer->Persistance > pBufLRU->Persistance) {
|
||||
pBufLRU = pBuffer;
|
||||
}
|
||||
} else {
|
||||
pBufLRU = pBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
if(pBuffer->Persistance < pBufLHITS->Persistance) {
|
||||
pBufLHITS = pBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pBufLRU) {
|
||||
// Process the suitable candidate.
|
||||
if(pBufLRU->Modified == FF_TRUE) {
|
||||
FF_IOMAN_FlushBuffer(pIoman, pBufLRU->Sector, pBufLRU->pBuffer);
|
||||
FF_BlockWrite(pIoman, pBufLRU->Sector, 1, pBufLRU->pBuffer);
|
||||
}
|
||||
pBufLRU->Mode = Mode;
|
||||
pBufLRU->Persistance = 1;
|
||||
|
@ -486,7 +425,7 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
|
|||
pBufLRU->Modified = FF_FALSE;
|
||||
}
|
||||
|
||||
FF_IOMAN_FillBuffer(pIoman, Sector, pBufLRU->pBuffer);
|
||||
FF_BlockRead(pIoman, Sector, 1, pBufLRU->pBuffer);
|
||||
pBufLRU->Valid = FF_TRUE;
|
||||
FF_ReleaseSemaphore(pIoman->pSemaphore);
|
||||
return pBufLRU;
|
||||
|
@ -540,39 +479,94 @@ void FF_ReleaseBuffer(FF_IOMAN *pIoman, FF_BUFFER *pBuffer) {
|
|||
**/
|
||||
FF_ERROR FF_RegisterBlkDevice(FF_IOMAN *pIoman, FF_T_UINT16 BlkSize, FF_WRITE_BLOCKS fnWriteBlocks, FF_READ_BLOCKS fnReadBlocks, void *pParam) {
|
||||
if(!pIoman) { // We can't do anything without an IOMAN object.
|
||||
return FF_ERR_NULL_POINTER;
|
||||
return FF_ERR_NULL_POINTER | FF_REGISTERBLKDEVICE;
|
||||
}
|
||||
|
||||
if((BlkSize % 512) != 0 || BlkSize == 0) {
|
||||
return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0
|
||||
return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE | FF_REGISTERBLKDEVICE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0
|
||||
}
|
||||
|
||||
if((BlkSize % pIoman->BlkSize) != 0 || BlkSize == 0) {
|
||||
return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0
|
||||
return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE | FF_REGISTERBLKDEVICE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0
|
||||
}
|
||||
|
||||
// Ensure that a device cannot be re-registered "mid-flight"
|
||||
// Doing so would corrupt the context of FullFAT
|
||||
if(pIoman->pBlkDevice->fnReadBlocks) {
|
||||
return FF_ERR_IOMAN_DEV_ALREADY_REGD;
|
||||
if(pIoman->pBlkDevice->fnpReadBlocks) {
|
||||
return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
|
||||
}
|
||||
if(pIoman->pBlkDevice->fnWriteBlocks) {
|
||||
return FF_ERR_IOMAN_DEV_ALREADY_REGD;
|
||||
if(pIoman->pBlkDevice->fnpWriteBlocks) {
|
||||
return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
|
||||
}
|
||||
if(pIoman->pBlkDevice->pParam) {
|
||||
return FF_ERR_IOMAN_DEV_ALREADY_REGD;
|
||||
return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
|
||||
}
|
||||
|
||||
// Here we shall just set the values.
|
||||
// FullFAT checks before using any of these values.
|
||||
pIoman->pBlkDevice->devBlkSize = BlkSize;
|
||||
pIoman->pBlkDevice->fnReadBlocks = fnReadBlocks;
|
||||
pIoman->pBlkDevice->fnWriteBlocks = fnWriteBlocks;
|
||||
pIoman->pBlkDevice->fnpReadBlocks = fnReadBlocks;
|
||||
pIoman->pBlkDevice->fnpWriteBlocks = fnWriteBlocks;
|
||||
pIoman->pBlkDevice->pParam = pParam;
|
||||
|
||||
return FF_ERR_NONE; // Success
|
||||
}
|
||||
|
||||
/*
|
||||
New Interface for FullFAT to read blocks.
|
||||
*/
|
||||
|
||||
FF_T_SINT32 FF_BlockRead(FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer) {
|
||||
FF_T_SINT32 slRetVal = 0;
|
||||
|
||||
if(pIoman->pPartition->TotalSectors) {
|
||||
if((ulSectorLBA + ulNumSectors) > (pIoman->pPartition->TotalSectors + pIoman->pPartition->BeginLBA)) {
|
||||
return -(FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_BLOCKREAD);
|
||||
}
|
||||
}
|
||||
|
||||
if(pIoman->pBlkDevice->fnpReadBlocks) { // Make sure we don't execute a NULL.
|
||||
#ifdef FF_BLKDEV_USES_SEM
|
||||
FF_PendSemaphore(pIoman->pBlkDevSemaphore);
|
||||
#endif
|
||||
slRetVal = pIoman->pBlkDevice->fnpReadBlocks(pBuffer, ulSectorLBA, ulNumSectors, pIoman->pBlkDevice->pParam);
|
||||
#ifdef FF_BLKDEV_USES_SEM
|
||||
FF_ReleaseSemaphore(pIoman->pBlkDevSemaphore);
|
||||
#endif
|
||||
if(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY) {
|
||||
FF_Sleep(FF_DRIVER_BUSY_SLEEP);
|
||||
}
|
||||
} while(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY);
|
||||
|
||||
return slRetVal;
|
||||
}
|
||||
|
||||
FF_T_SINT32 FF_BlockWrite(FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer) {
|
||||
FF_T_SINT32 slRetVal = 0;
|
||||
|
||||
if(pIoman->pPartition->TotalSectors) {
|
||||
if((ulSectorLBA + ulNumSectors) > (pIoman->pPartition->TotalSectors + pIoman->pPartition->BeginLBA)) {
|
||||
return -(FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_BLOCKWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
if(pIoman->pBlkDevice->fnpWriteBlocks) { // Make sure we don't execute a NULL.
|
||||
#ifdef FF_BLKDEV_USES_SEM
|
||||
FF_PendSemaphore(pIoman->pBlkDevSemaphore);
|
||||
#endif
|
||||
slRetVal = pIoman->pBlkDevice->fnpWriteBlocks(pBuffer, ulSectorLBA, ulNumSectors, pIoman->pBlkDevice->pParam);
|
||||
#ifdef FF_BLKDEV_USES_SEM
|
||||
FF_ReleaseSemaphore(pIoman->pBlkDevSemaphore);
|
||||
#endif
|
||||
if(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY) {
|
||||
FF_Sleep(FF_DRIVER_BUSY_SLEEP);
|
||||
}
|
||||
} while(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY);
|
||||
|
||||
return slRetVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
**/
|
||||
|
@ -638,7 +632,7 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) {
|
|||
testLong = FF_getLong(pBuffer->pBuffer, 0x0000);
|
||||
}
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
if((testLong & 0x0FFFFFF8) != 0x0FFFFFF8) {
|
||||
if((testLong & 0x0FFFFFF8) != 0x0FFFFFF8 && (testLong & 0x0FFFFFF8) != 0x0FFFFFF0) {
|
||||
return FF_ERR_IOMAN_NOT_FAT_FORMATTED;
|
||||
}
|
||||
#endif
|
||||
|
@ -676,6 +670,91 @@ static FF_T_SINT8 FF_PartitionCount (FF_T_UINT8 *pBuffer)
|
|||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
Mount GPT Partition Tables
|
||||
*/
|
||||
|
||||
#define FF_GPT_HEAD_ENTRY_SIZE 0x54
|
||||
#define FF_GPT_HEAD_TOTAL_ENTRIES 0x50
|
||||
#define FF_GPT_HEAD_PART_ENTRY_LBA 0x48
|
||||
#define FF_GPT_ENTRY_FIRST_SECTOR_LBA 0x20
|
||||
#define FF_GPT_HEAD_CRC 0x10
|
||||
#define FF_GPT_HEAD_LENGTH 0x0C
|
||||
|
||||
static FF_ERROR FF_GetEfiPartitionEntry(FF_IOMAN *pIoman, FF_T_UINT32 ulPartitionNumber) {
|
||||
// Continuing on from FF_MountPartition() pPartition->BeginLBA should be the sector of the GPT Header
|
||||
FF_BUFFER *pBuffer;
|
||||
FF_PARTITION *pPart = pIoman->pPartition;
|
||||
|
||||
FF_T_UINT32 ulBeginGPT;
|
||||
FF_T_UINT32 ulEntrySector;
|
||||
FF_T_UINT32 ulSectorOffset;
|
||||
FF_T_UINT32 ulTotalPartitionEntries;
|
||||
FF_T_UINT32 ulPartitionEntrySize;
|
||||
FF_T_UINT32 ulGPTHeadCRC, ulGPTCrcCheck, ulGPTHeadLength;
|
||||
|
||||
if(ulPartitionNumber >= 128) {
|
||||
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
|
||||
}
|
||||
|
||||
pBuffer = FF_GetBuffer(pIoman, pPart->BeginLBA, FF_MODE_READ);
|
||||
{
|
||||
if(!pBuffer) {
|
||||
return FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
}
|
||||
|
||||
// Verify this is an EFI header
|
||||
if(memcmp(pBuffer->pBuffer, "EFI PART", 8) != 0) {
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
return FF_ERR_IOMAN_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
ulBeginGPT = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_PART_ENTRY_LBA);
|
||||
ulTotalPartitionEntries = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_TOTAL_ENTRIES);
|
||||
ulPartitionEntrySize = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_ENTRY_SIZE);
|
||||
ulGPTHeadCRC = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC);
|
||||
ulGPTHeadLength = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_LENGTH);
|
||||
|
||||
// Calculate Head CRC
|
||||
|
||||
// Blank CRC field
|
||||
FF_putLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC, 0x00000000);
|
||||
|
||||
// Calculate CRC
|
||||
ulGPTCrcCheck = FF_GetCRC32(pBuffer->pBuffer, ulGPTHeadLength);
|
||||
|
||||
// Restore The CRC field
|
||||
FF_putLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC, ulGPTHeadCRC);
|
||||
}
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
|
||||
// Check CRC
|
||||
if(ulGPTHeadCRC != ulGPTCrcCheck) {
|
||||
return FF_ERR_IOMAN_GPT_HEADER_CORRUPT;
|
||||
}
|
||||
|
||||
// Calculate Sector Containing the Partition Entry we want to use.
|
||||
|
||||
ulEntrySector = ((ulPartitionNumber * ulPartitionEntrySize) / pIoman->BlkSize) + ulBeginGPT;
|
||||
ulSectorOffset = (ulPartitionNumber % (pIoman->BlkSize / ulPartitionEntrySize)) * ulPartitionEntrySize;
|
||||
|
||||
pBuffer = FF_GetBuffer(pIoman, ulEntrySector, FF_MODE_READ);
|
||||
{
|
||||
if(!pBuffer) {
|
||||
return FF_ERR_DEVICE_DRIVER_FAILED;
|
||||
}
|
||||
|
||||
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, ulSectorOffset + FF_GPT_ENTRY_FIRST_SECTOR_LBA);
|
||||
}
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
|
||||
if(!pPart->BeginLBA) {
|
||||
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
|
||||
}
|
||||
|
||||
return FF_ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @brief Mounts the Specified partition, the volume specified by the FF_IOMAN object provided.
|
||||
|
@ -697,15 +776,19 @@ static FF_T_SINT8 FF_PartitionCount (FF_T_UINT8 *pBuffer)
|
|||
FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) {
|
||||
FF_PARTITION *pPart;
|
||||
FF_BUFFER *pBuffer = 0;
|
||||
FF_ERROR Error;
|
||||
|
||||
FF_T_UINT8 ucPartitionType;
|
||||
|
||||
int partCount;
|
||||
|
||||
if(!pIoman) {
|
||||
return FF_ERR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(PartitionNumber > 3) {
|
||||
/*if(PartitionNumber > 3) {
|
||||
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
|
||||
}
|
||||
}*/
|
||||
|
||||
pPart = pIoman->pPartition;
|
||||
|
||||
|
@ -728,10 +811,32 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) {
|
|||
// Volume is not partitioned (MBR Found)
|
||||
pPart->BeginLBA = 0;
|
||||
} else {
|
||||
// Primary Partitions to deal with!
|
||||
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber));
|
||||
|
||||
ucPartitionType = FF_getChar(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID); // Ensure its not an EFI partition!
|
||||
|
||||
if(ucPartitionType != 0xEE) {
|
||||
|
||||
if(PartitionNumber > 3) {
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
|
||||
}
|
||||
|
||||
// Primary Partitions to deal with!
|
||||
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber));
|
||||
}
|
||||
|
||||
FF_ReleaseBuffer(pIoman, pBuffer);
|
||||
|
||||
if(ucPartitionType == 0xEE) {
|
||||
|
||||
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA);
|
||||
Error = FF_GetEfiPartitionEntry(pIoman, PartitionNumber);
|
||||
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
}
|
||||
|
||||
if(!pPart->BeginLBA) {
|
||||
return FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION;
|
||||
}
|
||||
|
@ -778,13 +883,25 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) {
|
|||
}
|
||||
|
||||
FF_ReleaseBuffer(pIoman, pBuffer); // Release the buffer finally!
|
||||
|
||||
if(!pPart->BlkSize) {
|
||||
return FF_ERR_IOMAN_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
pPart->RootDirSectors = ((FF_getShort(pBuffer->pBuffer, FF_FAT_ROOT_ENTRY_COUNT) * 32) + pPart->BlkSize - 1) / pPart->BlkSize;
|
||||
pPart->FirstDataSector = pPart->ClusterBeginLBA + pPart->RootDirSectors;
|
||||
pPart->DataSectors = pPart->TotalSectors - (pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT) + pPart->RootDirSectors);
|
||||
|
||||
if(!pPart->SectorsPerCluster) {
|
||||
return FF_ERR_IOMAN_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
pPart->NumClusters = pPart->DataSectors / pPart->SectorsPerCluster;
|
||||
|
||||
if(FF_DetermineFatType(pIoman)) {
|
||||
return FF_ERR_IOMAN_NOT_FAT_FORMATTED;
|
||||
Error = FF_DetermineFatType(pIoman);
|
||||
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
|
||||
#ifdef FF_MOUNT_FIND_FREE
|
||||
|
@ -820,8 +937,8 @@ FF_ERROR FF_UnregisterBlkDevice(FF_IOMAN *pIoman) {
|
|||
{
|
||||
if(pIoman->pPartition->PartitionMounted == FF_FALSE) {
|
||||
pIoman->pBlkDevice->devBlkSize = 0;
|
||||
pIoman->pBlkDevice->fnReadBlocks = NULL;
|
||||
pIoman->pBlkDevice->fnWriteBlocks = NULL;
|
||||
pIoman->pBlkDevice->fnpReadBlocks = NULL;
|
||||
pIoman->pBlkDevice->fnpWriteBlocks = NULL;
|
||||
pIoman->pBlkDevice->pParam = NULL;
|
||||
} else {
|
||||
RetVal = FF_ERR_IOMAN_PARTITION_MOUNTED;
|
||||
|
@ -876,7 +993,11 @@ FF_ERROR FF_UnmountPartition(FF_IOMAN *pIoman) {
|
|||
{
|
||||
if(!FF_ActiveHandles(pIoman)) {
|
||||
if(pIoman->FirstFile == NULL) {
|
||||
// Release Semaphore to call this function!
|
||||
FF_ReleaseSemaphore(pIoman->pSemaphore);
|
||||
FF_FlushCache(pIoman); // Flush any unwritten sectors to disk.
|
||||
// Reclaim Semaphore
|
||||
FF_PendSemaphore(pIoman->pSemaphore);
|
||||
pIoman->pPartition->PartitionMounted = FF_FALSE;
|
||||
} else {
|
||||
RetVal = FF_ERR_IOMAN_ACTIVE_HANDLES;
|
||||
|
@ -893,12 +1014,17 @@ FF_ERROR FF_UnmountPartition(FF_IOMAN *pIoman) {
|
|||
|
||||
FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) {
|
||||
|
||||
FF_ERROR Error;
|
||||
//FF_PendSemaphore(pIoman->pSemaphore);
|
||||
//{
|
||||
if(!pIoman->pPartition->FreeClusterCount) {
|
||||
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman);
|
||||
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error);
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
} else {
|
||||
pIoman->pPartition->FreeClusterCount += Count;
|
||||
}
|
||||
pIoman->pPartition->FreeClusterCount += Count;
|
||||
//}
|
||||
//FF_ReleaseSemaphore(pIoman->pSemaphore);
|
||||
|
||||
|
@ -907,12 +1033,18 @@ FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) {
|
|||
|
||||
FF_ERROR FF_DecreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) {
|
||||
|
||||
FF_ERROR Error;
|
||||
|
||||
//FF_lockFAT(pIoman);
|
||||
//{
|
||||
if(!pIoman->pPartition->FreeClusterCount) {
|
||||
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman);
|
||||
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error);
|
||||
if(Error) {
|
||||
return Error;
|
||||
}
|
||||
} else {
|
||||
pIoman->pPartition->FreeClusterCount -= Count;
|
||||
}
|
||||
pIoman->pPartition->FreeClusterCount -= Count;
|
||||
//}
|
||||
//FF_unlockFAT(pIoman);
|
||||
|
||||
|
|
274
reactos/lib/3rdparty/fullfat/ff_string.c
vendored
274
reactos/lib/3rdparty/fullfat/ff_string.c
vendored
|
@ -42,27 +42,57 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "ff_string.h"
|
||||
#include "ff_error.h"
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These will eventually be moved into a platform independent string
|
||||
* library. Which will be optional. (To allow the use of system specific versions).
|
||||
*/
|
||||
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
|
||||
void FF_cstrntowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource, FF_T_UINT32 len) {
|
||||
while(*szpSource && len--) {
|
||||
*wcsDest++ = *szpSource++;
|
||||
}
|
||||
*wcsDest = '\0';
|
||||
}
|
||||
|
||||
void FF_cstrtowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource) {
|
||||
while(*szpSource) {
|
||||
*wcsDest++ = (FF_T_WCHAR) *szpSource++;
|
||||
}
|
||||
*wcsDest = '\0';
|
||||
}
|
||||
|
||||
void FF_wcstocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource) {
|
||||
while(*wcsSource) {
|
||||
*szpDest++ = (FF_T_INT8) *wcsSource++;
|
||||
}
|
||||
*szpDest = '\0';
|
||||
}
|
||||
|
||||
void FF_wcsntocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource, FF_T_UINT32 len) {
|
||||
while(*wcsSource && len--) {
|
||||
*szpDest++ = (FF_T_INT8) *wcsSource++;
|
||||
}
|
||||
*szpDest = '\0';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @brief Converts an ASCII string to lowercase.
|
||||
**/
|
||||
void FF_tolower(FF_T_INT8 *string, FF_T_UINT32 strLen) {
|
||||
FF_T_UINT32 i;
|
||||
for(i = 0; i < strLen; i++) {
|
||||
if(string[i] >= 'A' && string[i] <= 'Z')
|
||||
string[i] += 32;
|
||||
if(string[i] == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FF_UNICODE_SUPPORT
|
||||
/**
|
||||
* @private
|
||||
* @brief Converts an ASCII string to uppercase.
|
||||
|
@ -76,6 +106,32 @@ void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
void FF_tolower(FF_T_INT8 *string, FF_T_UINT32 strLen) {
|
||||
FF_T_UINT32 i;
|
||||
for(i = 0; i < strLen; i++) {
|
||||
if(string[i] >= 'A' && string[i] <= 'Z')
|
||||
string[i] += 32;
|
||||
if(string[i] == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
void FF_toupper(FF_T_WCHAR *string, FF_T_UINT32 strLen) {
|
||||
FF_T_UINT32 i;
|
||||
for(i = 0; i < strLen; i++) {
|
||||
string[i] = towupper(string[i]);
|
||||
}
|
||||
}
|
||||
void FF_tolower(FF_T_WCHAR *string, FF_T_UINT32 strLen) {
|
||||
FF_T_UINT32 i;
|
||||
for(i = 0; i < strLen; i++) {
|
||||
string[i] = towlower(string[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -84,6 +140,8 @@ void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) {
|
|||
* otherwise FF_FALSE is returned.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef FF_UNICODE_SUPPORT
|
||||
FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len) {
|
||||
register FF_T_UINT16 i;
|
||||
register FF_T_INT8 char1, char2;
|
||||
|
@ -112,12 +170,38 @@ FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16
|
|||
|
||||
return FF_TRUE;
|
||||
}
|
||||
#else
|
||||
|
||||
FF_T_BOOL FF_strmatch(const FF_T_WCHAR *str1, const FF_T_WCHAR *str2, FF_T_UINT16 len) {
|
||||
register FF_T_UINT16 i;
|
||||
register FF_T_WCHAR char1, char2;
|
||||
|
||||
if(!len) {
|
||||
if(wcslen(str1) != wcslen(str2)) {
|
||||
return FF_FALSE;
|
||||
}
|
||||
len = (FF_T_UINT16) wcslen(str1);
|
||||
}
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
char1 = towlower(str1[i]);
|
||||
char2 = towlower(str2[i]);
|
||||
if(char1 != char2) {
|
||||
return FF_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return FF_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @brief A re-entrant Strtok function. No documentation is provided :P
|
||||
* Use at your own risk. (This is for FullFAT's use only).
|
||||
**/
|
||||
|
||||
#ifndef FF_UNICODE_SUPPORT
|
||||
FF_T_INT8 *FF_strtok(const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) {
|
||||
FF_T_UINT16 strLen = Length;
|
||||
FF_T_UINT16 i,y, tokenStart, tokenEnd = 0;
|
||||
|
@ -153,20 +237,80 @@ FF_T_INT8 *FF_strtok(const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tok
|
|||
}
|
||||
tokenEnd = i;
|
||||
}
|
||||
|
||||
memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart));
|
||||
token[tokenEnd - tokenStart] = '\0';
|
||||
if((tokenEnd - tokenStart) < FF_MAX_FILENAME) {
|
||||
memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart));
|
||||
token[tokenEnd - tokenStart] = '\0';
|
||||
} else {
|
||||
memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME));
|
||||
token[FF_MAX_FILENAME-1] = '\0';
|
||||
}
|
||||
//token[tokenEnd - tokenStart] = '\0';
|
||||
*tokenNumber += 1;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
#else
|
||||
FF_T_WCHAR *FF_strtok(const FF_T_WCHAR *string, FF_T_WCHAR *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) {
|
||||
FF_T_UINT16 strLen = Length;
|
||||
FF_T_UINT16 i,y, tokenStart, tokenEnd = 0;
|
||||
|
||||
FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
|
||||
/* Check to see if the string contains the wild card */
|
||||
i = 0;
|
||||
y = 0;
|
||||
|
||||
if(string[i] == '\\' || string[i] == '/') {
|
||||
i++;
|
||||
}
|
||||
|
||||
tokenStart = i;
|
||||
|
||||
while(i < strLen) {
|
||||
if(string[i] == '\\' || string[i] == '/') {
|
||||
y++;
|
||||
if(y == *tokenNumber) {
|
||||
tokenStart = (FF_T_UINT16)(i + 1);
|
||||
}
|
||||
if(y == (*tokenNumber + 1)) {
|
||||
tokenEnd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if(!tokenEnd) {
|
||||
if(*last == FF_TRUE) {
|
||||
return NULL;
|
||||
} else {
|
||||
*last = FF_TRUE;
|
||||
}
|
||||
tokenEnd = i;
|
||||
}
|
||||
if((tokenEnd - tokenStart) < FF_MAX_FILENAME) {
|
||||
memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart) * sizeof(FF_T_WCHAR));
|
||||
token[tokenEnd - tokenStart] = '\0';
|
||||
} else {
|
||||
memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME) * sizeof(FF_T_WCHAR));
|
||||
token[FF_MAX_FILENAME-1] = '\0';
|
||||
}
|
||||
//token[tokenEnd - tokenStart] = '\0';
|
||||
*tokenNumber += 1;
|
||||
|
||||
return token;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
A Wild-Card Comparator Library function, Provided by Adam Fullerton.
|
||||
This can be extended or altered to improve or advance wildCard matching
|
||||
of the FF_FindFirst() and FF_FindNext() API's.
|
||||
*/
|
||||
#ifdef FF_FINDAPI_ALLOW_WILDCARDS
|
||||
/*FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
|
||||
// Check to see if the string contains the wild card
|
||||
if (!memchr(pszWildCard, '*', strlen(pszWildCard)))
|
||||
{
|
||||
/* if it does not then do a straight string compare */
|
||||
// if it does not then do a straight string compare
|
||||
if (strcmp(pszWildCard, pszString))
|
||||
{
|
||||
return FF_FALSE;
|
||||
|
@ -177,20 +321,20 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
|
|||
while ((*pszWildCard)
|
||||
&& (*pszString))
|
||||
{
|
||||
/* Test for the wild card */
|
||||
// Test for the wild card
|
||||
if (*pszWildCard == '*')
|
||||
{
|
||||
/* Eat more than one */
|
||||
// Eat more than one
|
||||
while (*pszWildCard == '*')
|
||||
{
|
||||
pszWildCard++;
|
||||
}
|
||||
/* If there are more chars in the string */
|
||||
// If there are more chars in the string
|
||||
if (*pszWildCard)
|
||||
{
|
||||
/* Search for the next char */
|
||||
// Search for the next char
|
||||
pszString = memchr(pszString, (int)*pszWildCard, strlen(pszString));
|
||||
/* if it does not exist then the strings don't match */
|
||||
// if it does not exist then the strings don't match
|
||||
if (!pszString)
|
||||
{
|
||||
return FF_FALSE;
|
||||
|
@ -201,7 +345,7 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
|
|||
{
|
||||
if (*pszWildCard)
|
||||
{
|
||||
/* continue */
|
||||
// continue
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -212,17 +356,17 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Fail if they don't match */
|
||||
// Fail if they don't match
|
||||
if (*pszWildCard != *pszString)
|
||||
{
|
||||
return FF_FALSE;
|
||||
}
|
||||
}
|
||||
/* Bump both pointers */
|
||||
// Bump both pointers
|
||||
pszWildCard++;
|
||||
pszString++;
|
||||
}
|
||||
/* fail if different lengths */
|
||||
// fail if different lengths
|
||||
if (*pszWildCard != *pszString)
|
||||
{
|
||||
return FF_FALSE;
|
||||
|
@ -230,5 +374,83 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
|
|||
}
|
||||
|
||||
return FF_TRUE;
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
This is a better Wild-card compare function, that works perfectly, and is much more efficient.
|
||||
This function was contributed by one of our commercial customers.
|
||||
*/
|
||||
#ifdef FF_UNICODE_SUPPORT
|
||||
FF_T_BOOL FF_wildcompare(const FF_T_WCHAR *pszWildCard, const FF_T_WCHAR *pszString) {
|
||||
register const FF_T_WCHAR *pszWc = NULL;
|
||||
register const FF_T_WCHAR *pszStr = NULL; // Encourage the string pointers to be placed in memory.
|
||||
do {
|
||||
if ( *pszWildCard == '*' ) {
|
||||
while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s
|
||||
pszWc = (pszWildCard - 1);
|
||||
pszStr = pszString;
|
||||
}
|
||||
if (*pszWildCard == '?' && !*pszString) {
|
||||
return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded.
|
||||
}
|
||||
#ifdef FF_WILDCARD_CASE_INSENSITIVE
|
||||
if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) {
|
||||
#else
|
||||
if (*pszWildCard != '?' && *pszWildCard != *pszString) {
|
||||
#endif
|
||||
if (pszWc == NULL) {
|
||||
return FF_FALSE;
|
||||
}
|
||||
pszWildCard = pszWc;
|
||||
pszString = pszStr++;
|
||||
}
|
||||
} while ( *pszWildCard++ && *pszString++ );
|
||||
|
||||
while(*pszWildCard == '*') {
|
||||
pszWildCard++;
|
||||
}
|
||||
|
||||
if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated)
|
||||
return FF_TRUE; // Therefore this must be a match.
|
||||
}
|
||||
|
||||
return FF_FALSE; // If not, then return FF_FALSE!
|
||||
}
|
||||
#else
|
||||
FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
|
||||
register const FF_T_INT8 *pszWc = NULL;
|
||||
register const FF_T_INT8 *pszStr = NULL; // Encourage the string pointers to be placed in memory.
|
||||
do {
|
||||
if ( *pszWildCard == '*' ) {
|
||||
while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s
|
||||
pszWc = (pszWildCard - 1);
|
||||
pszStr = pszString;
|
||||
}
|
||||
if (*pszWildCard == '?' && !*pszString) {
|
||||
return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded.
|
||||
}
|
||||
#ifdef FF_WILDCARD_CASE_INSENSITIVE
|
||||
if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) {
|
||||
#else
|
||||
if (*pszWildCard != '?' && *pszWildCard != *pszString) {
|
||||
#endif
|
||||
if (pszWc == NULL) {
|
||||
return FF_FALSE;
|
||||
}
|
||||
pszWildCard = pszWc;
|
||||
pszString = pszStr++;
|
||||
}
|
||||
} while ( *pszWildCard++ && *pszString++ );
|
||||
|
||||
while(*pszWildCard == '*') {
|
||||
pszWildCard++;
|
||||
}
|
||||
|
||||
if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated)
|
||||
return FF_TRUE; // Therefore this must be a match.
|
||||
}
|
||||
|
||||
return FF_FALSE; // If not, then return FF_FALSE!
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
294
reactos/lib/3rdparty/fullfat/ff_unicode.c
vendored
Normal file
294
reactos/lib/3rdparty/fullfat/ff_unicode.c
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*****************************************************************************
|
||||
* 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. *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ff_unicode.c
|
||||
* @author James Walmsley
|
||||
* @ingroup UNICODE
|
||||
*
|
||||
* @defgroup UNICODE FullFAT UNICODE Library
|
||||
* @brief Portable UNICODE Transformation Library for FullFAT
|
||||
*
|
||||
**/
|
||||
|
||||
#include "ff_unicode.h"
|
||||
#include "string.h"
|
||||
|
||||
// UTF-8 Routines
|
||||
|
||||
/*
|
||||
UCS-4 range (hex.) UTF-8 octet sequence (binary)
|
||||
0000 0000-0000 007F 0xxxxxxx
|
||||
0000 0080-0000 07FF 110xxxxx 10xxxxxx
|
||||
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
|
||||
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
|
||||
*/
|
||||
|
||||
FF_T_UINT FF_GetUtf16SequenceLen(FF_T_UINT16 usLeadChar) {
|
||||
if((usLeadChar & 0xFC00) == 0xD800) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the number of UTF-8 units read.
|
||||
Will not exceed ulSize UTF-16 units. (ulSize * 2 bytes).
|
||||
*/
|
||||
/*
|
||||
UCS-4 range (hex.) UTF-8 octet sequence (binary)
|
||||
0000 0000-0000 007F 0xxxxxxx
|
||||
0000 0080-0000 07FF 110xxxxx 10xxxxxx
|
||||
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
|
||||
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
|
||||
*/
|
||||
FF_T_SINT32 FF_Utf8ctoUtf16c(FF_T_UINT16 *utf16Dest, const FF_T_UINT8 *utf8Source, FF_T_UINT32 ulSize) {
|
||||
FF_T_UINT32 ulUtf32char;
|
||||
FF_T_UINT16 utf16Source = 0;
|
||||
register FF_T_INT uiSequenceNumber = 0;
|
||||
|
||||
while((*utf8Source & (0x80 >> (uiSequenceNumber)))) { // Count number of set bits before a zero.
|
||||
uiSequenceNumber++;
|
||||
}
|
||||
|
||||
if(!uiSequenceNumber) {
|
||||
uiSequenceNumber++;
|
||||
}
|
||||
|
||||
if(!ulSize) {
|
||||
return FF_ERR_UNICODE_DEST_TOO_SMALL;
|
||||
}
|
||||
|
||||
switch(uiSequenceNumber) {
|
||||
case 1:
|
||||
utf16Source = (FF_T_UINT16) *utf8Source;
|
||||
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
|
||||
//bobtntfullfat *utf16Dest = (FF_T_UINT16) *utf8Source;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
utf16Source =(FF_T_UINT16) ((*utf8Source & 0x1F) << 6) | ((*(utf8Source + 1) & 0x3F));
|
||||
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
|
||||
//bobtntfullfat *utf16Dest = (FF_T_UINT16) ((*utf8Source & 0x1F) << 6) | ((*(utf8Source + 1) & 0x3F));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
utf16Source =(FF_T_UINT16) ((*utf8Source & 0x0F) << 12) | ((*(utf8Source + 1) & 0x3F) << 6) | ((*(utf8Source + 2) & 0x3F));
|
||||
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
|
||||
//bobtntfullfat *utf16Dest = (FF_T_UINT16) ((*utf8Source & 0x0F) << 12) | ((*(utf8Source + 1) & 0x3F) << 6) | ((*(utf8Source + 2) & 0x3F));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Convert to UTF-32 and then into UTF-16
|
||||
if(ulSize < 2) {
|
||||
return FF_ERR_UNICODE_DEST_TOO_SMALL;
|
||||
}
|
||||
ulUtf32char = (FF_T_UINT16) ((*utf8Source & 0x0F) << 18) | ((*(utf8Source + 1) & 0x3F) << 12) | ((*(utf8Source + 2) & 0x3F) << 6) | ((*(utf8Source + 3) & 0x3F));
|
||||
|
||||
utf16Source = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800;
|
||||
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
|
||||
utf16Source = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00;
|
||||
memcpy(utf16Dest+1,&utf16Source,sizeof(FF_T_UINT16));
|
||||
//bobtntfullfat *(utf16Dest + 0) = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800;
|
||||
//bobtntfullfat *(utf16Dest + 1) = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return uiSequenceNumber;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns the number of UTF-8 units required to encode the UTF-16 sequence.
|
||||
Will not exceed ulSize UTF-8 units. (ulSize * 1 bytes).
|
||||
*/
|
||||
FF_T_SINT32 FF_Utf16ctoUtf8c(FF_T_UINT8 *utf8Dest, const FF_T_UINT16 *utf16Source, FF_T_UINT32 ulSize) {
|
||||
FF_T_UINT32 ulUtf32char;
|
||||
FF_T_UINT16 ulUtf16char;
|
||||
|
||||
if(!ulSize) {
|
||||
return FF_ERR_UNICODE_DEST_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(&ulUtf16char, utf16Source, sizeof(FF_T_UINT16));
|
||||
if((/*bobtntfullfat *utf16Source*/ulUtf16char & 0xF800) == 0xD800) { // A surrogate sequence was encountered. Must transform to UTF32 first.
|
||||
ulUtf32char = ((FF_T_UINT32) (ulUtf16char & 0x003FF) << 10) + 0x10000;
|
||||
//bobtntfullfat ulUtf32char = ((FF_T_UINT32) (*(utf16Source + 0) & 0x003FF) << 10) + 0x10000;
|
||||
|
||||
memcpy(&ulUtf16char, utf16Source + 1, sizeof(FF_T_UINT16));
|
||||
if((/*bobtntfullfat *(utf16Source + 1)*/ulUtf16char & 0xFC00) != 0xDC00) {
|
||||
return FF_ERR_UNICODE_INVALID_SEQUENCE; // Invalid UTF-16 sequence.
|
||||
}
|
||||
ulUtf32char |= ((FF_T_UINT32) (/*bobtntfullfat *(utf16Source + 1)*/ulUtf16char & 0x003FF));
|
||||
|
||||
} else {
|
||||
ulUtf32char = (FF_T_UINT32) /*bobtntfullfat *utf16Source*/ulUtf16char;
|
||||
}
|
||||
|
||||
// Now convert to the UTF-8 sequence.
|
||||
if(ulUtf32char < 0x00000080) { // Single byte UTF-8 sequence.
|
||||
*(utf8Dest + 0) = (FF_T_UINT8) ulUtf32char;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(ulUtf32char < 0x00000800) { // Double byte UTF-8 sequence.
|
||||
if(ulSize < 2) {
|
||||
return FF_ERR_UNICODE_DEST_TOO_SMALL;
|
||||
}
|
||||
*(utf8Dest + 0) = (FF_T_UINT8) (0xC0 | ((ulUtf32char >> 6) & 0x1F));
|
||||
*(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0) & 0x3F));
|
||||
return 2;
|
||||
}
|
||||
|
||||
if(ulUtf32char < 0x00010000) { // Triple byte UTF-8 sequence.
|
||||
if(ulSize < 3) {
|
||||
return FF_ERR_UNICODE_DEST_TOO_SMALL;
|
||||
}
|
||||
*(utf8Dest + 0) = (FF_T_UINT8) (0xE0 | ((ulUtf32char >> 12) & 0x0F));
|
||||
*(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 6 ) & 0x3F));
|
||||
*(utf8Dest + 2) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0 ) & 0x3F));
|
||||
return 3;
|
||||
}
|
||||
|
||||
if(ulUtf32char < 0x00200000) { // Quadruple byte UTF-8 sequence.
|
||||
if(ulSize < 4) {
|
||||
return FF_ERR_UNICODE_DEST_TOO_SMALL;
|
||||
}
|
||||
*(utf8Dest + 0) = (FF_T_UINT8) (0xF0 | ((ulUtf32char >> 18) & 0x07));
|
||||
*(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 12) & 0x3F));
|
||||
*(utf8Dest + 2) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 6 ) & 0x3F));
|
||||
*(utf8Dest + 3) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0 ) & 0x3F));
|
||||
return 4;
|
||||
}
|
||||
|
||||
return FF_ERR_UNICODE_INVALID_CODE; // Invalid Charachter
|
||||
}
|
||||
|
||||
|
||||
// UTF-16 Support Functions
|
||||
|
||||
// Converts a UTF-32 Charachter into its equivalent UTF-16 sequence.
|
||||
FF_T_SINT32 FF_Utf32ctoUtf16c(FF_T_UINT16 *utf16Dest, FF_T_UINT32 utf32char, FF_T_UINT32 ulSize) {
|
||||
|
||||
// Check that its a valid UTF-32 wide-char!
|
||||
|
||||
if(utf32char >= 0xD800 && utf32char <= 0xDFFF) { // This range is not a valid Unicode code point.
|
||||
return FF_ERR_UNICODE_INVALID_CODE; // Invalid charachter.
|
||||
}
|
||||
|
||||
if(utf32char < 0x10000) {
|
||||
*utf16Dest = (FF_T_UINT16) utf32char; // Simple conversion! Char comes within UTF-16 space (without surrogates).
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(ulSize < 2) {
|
||||
return FF_ERR_UNICODE_DEST_TOO_SMALL; // Not enough UTF-16 units to record this charachter.
|
||||
}
|
||||
|
||||
if(utf32char < 0x00200000) {
|
||||
// Conversion to a UTF-16 Surrogate pair!
|
||||
//valueImage = utf32char - 0x10000;
|
||||
|
||||
*(utf16Dest + 0) = (FF_T_UINT16) (((utf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800;
|
||||
*(utf16Dest + 1) = (FF_T_UINT16) (((utf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00;
|
||||
|
||||
return 2; // Surrogate pair encoded value.
|
||||
}
|
||||
|
||||
return FF_ERR_UNICODE_INVALID_CODE; // Invalid Charachter
|
||||
}
|
||||
|
||||
// Converts a UTF-16 sequence into its equivalent UTF-32 code point.
|
||||
FF_T_SINT32 FF_Utf16ctoUtf32c(FF_T_UINT32 *utf32Dest, const FF_T_UINT16 *utf16Source) {
|
||||
|
||||
if((*utf16Source & 0xFC00) != 0xD800) { // Not a surrogate sequence.
|
||||
*utf32Dest = (FF_T_UINT32) *utf16Source;
|
||||
return 1; // A single UTF-16 item was used to represent the charachter.
|
||||
}
|
||||
|
||||
*utf32Dest = ((FF_T_UINT32) (*(utf16Source + 0) & 0x003FF) << 10) + 0x10000;
|
||||
|
||||
if((*(utf16Source + 1) & 0xFC00) != 0xDC00) {
|
||||
return FF_ERR_UNICODE_INVALID_SEQUENCE; // Invalid UTF-16 sequence.
|
||||
}
|
||||
*utf32Dest |= ((FF_T_UINT32) (*(utf16Source + 1) & 0x003FF));
|
||||
return 2; // 2 utf-16 units make up the Unicode code-point.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns the total number of UTF-16 items required to represent
|
||||
the provided UTF-32 string in UTF-16 form.
|
||||
*/
|
||||
/*
|
||||
FF_T_UINT FF_Utf32GetUtf16Len(const FF_T_UINT32 *utf32String) {
|
||||
FF_T_UINT utf16len = 0;
|
||||
|
||||
while(*utf32String) {
|
||||
if(*utf32String++ <= 0xFFFF) {
|
||||
utf16len++;
|
||||
} else {
|
||||
utf16len += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return utf16len;
|
||||
}*/
|
||||
|
||||
|
||||
// String conversions
|
||||
|
||||
FF_T_SINT32 FF_Utf32stoUtf8s(FF_T_UINT8 *Utf8String, FF_T_UINT32 *Utf32String) {
|
||||
int i = 0,y = 0;
|
||||
|
||||
FF_T_UINT16 utf16buffer[2];
|
||||
|
||||
while(Utf32String[i]) {
|
||||
// Convert to a UTF16 char.
|
||||
FF_Utf32ctoUtf16c(utf16buffer, Utf32String[i], 2);
|
||||
// Now convert the UTF16 to UTF8 sequence.
|
||||
y += FF_Utf16ctoUtf8c(&Utf8String[y], utf16buffer, 4);
|
||||
i++;
|
||||
}
|
||||
|
||||
Utf8String[y] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
4
reactos/lib/3rdparty/fullfat/fullfat.rbuild
vendored
4
reactos/lib/3rdparty/fullfat/fullfat.rbuild
vendored
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
||||
<module name="fullfat" type="staticlibrary">
|
||||
<module name="fullfat" type="staticlibrary" allowwarnings="true" >
|
||||
<include base="ReactOS">include/reactos/libs/fullfat</include>
|
||||
<define name="__NTDRIVER__" />
|
||||
|
||||
|
@ -10,10 +10,12 @@
|
|||
<file>ff_error.c</file>
|
||||
<file>ff_fat.c</file>
|
||||
<file>ff_file.c</file>
|
||||
<file>ff_format.c</file>
|
||||
<file>ff_hash.c</file>
|
||||
<file>ff_ioman.c</file>
|
||||
<file>ff_memory.c</file>
|
||||
<file>ff_safety.c</file>
|
||||
<file>ff_string.c</file>
|
||||
<file>ff_time.c</file>
|
||||
<file>ff_unicode.c</file>
|
||||
</module>
|
||||
|
|
Loading…
Reference in a new issue