unit Fat32_1;
//----------------------------------------------------------------------------//
// ---> Only for P18 and P24 PIC's (stack too deep) <--- //
//----------------------------------------------------------------------------//
uses StrngUtils;
//interface
// -----------------------------------------------------------------------------
// --------------------- Routine to be defined externally ----------------------
// -----------------------------------------------------------------------------
function Fat32_Dev_Read_Sector (Sector: DWord; var Buffer: array[512] of byte): boolean; external; // returns true when successfull
function Fat32_Dev_Write_Sector(Sector: DWord; var Buffer: array[512] of byte): boolean; external; // returns true when successfull
function Fat32_Dev_Capacity_Sectors: DWord; external;
// -----------------------------------------------------------------------------
const LongFnLength = 255; // size of a long filename
type TLongFileName = string[LongFnLength];
TShortFileName = string[12]; // size of a short filename
TFat32DirItem =
record
FileName : TLongFileName; // longfilename if "LongFileNamePresent" is true, else "FileName" (short FileName)
ShortFileName : TShortFileName; // short filename
FileAttr : byte; // file attributes
FileSize : DWord; // FileSize in bytes
FindDirEntry : DWord; // for internal usage only
end;
// -------------------------------------------------------------------------------------------------
// ---- This variable contains the result of Fat32_FindFirst/Fat32_FindNext calls ----------
var Fat32_DirItem : TFat32DirItem;
// -------------------------------------------------------------------------------------------------
const // file attribute constants to be used in "Fat32_FindFirst", Fat32_FindNext" and "Fat32_FileExists"
faAnyFile = $00;
faReadOnly = $01; // bit 0 in the attributes byte
faHidden = $02; // bit 1
faSysFile = $04; // bit 2
faVolumeId = $08; // bit 3
faDirectory = $10; // bit 4
faArchive = $20; // bit 5
faFile = $40; // bit 6, not directory, not volumeId
faCreate = $80; // bit 7, special attribute to create files
// File attribute Characters for e.g. the directory files
Fat32_Attrs : string[6] = 'RHSVDA'; // be carefull: mirrored! ("R" is bit 0 in the attributes, "H" is bit 1 etc...)
// -----------------------------------------------------------------------------
// Basic Routines
// -----------------------------------------------------------------------------
function Fat32_Init: boolean;
// initialises the Fat32 filesystem, reads in the basic card/disk data (Fat boot record)
// returns true if success, false on failure
// IMPORTANT: ---> "mmc_Init" (or equivalent) must be done (with success) before this routine can be called! <---
function Fat32_QuickFormat(var VolumeLabel: string[11]): boolean;
// This routine deletes all files and directories and creates a new root directory.
// Returns true if Success, otherwise false
// Also re-inits the Fat32 system (call to Fat32_Init)
//------------------------------------------------------------------------------
// IMPORTANT: this routine only Quick -->RE<-- formats the card/disk.
// ---> It should have been initially formatted on a PC! <--- ,
// the MMC/SD/CF card or disk should already contain a valid Fat boot Record
//------------------------------------------------------------------------------
function Fat32_Format(var VolumeLabel: string[11]): boolean;
// This routines does the same as the Fat32_Quickformat" above , but the card does not
// have to be pre-formatted on a PC. The routine writes a new bootsector and a new FSInfo
// sector.
procedure Fat32_VolumeLabel(var _Label: string);
// Returns the Fat32 Volume Label in "_Label"
// "Fat32_Init" must have been executed with success before this procedure can be used
function Fat32_Assign(var LongFn: TLongFileName; file_cre_attr: byte): boolean;
// Opens a file with name "LongFn" and returns true on success.
// Only files can be opened, no directories, VolumeId's etc...
// The file is created (if not already existing) provided "file_cre_attr" contains "faCreate".
// The Filepointer (points to the next byte to be read or written) is set to zero.
procedure Fat32_Close;
// Closes the currently assigned file (flushes the databuffer etc...)
// !!! ---> Always to be called when finishing using a file, except
// when using a swapfile
// or "Fat32_Flush" was called after the last write action <---! !!!
procedure Fat32_Reset(var _Size: DWord);
// Resets the filepointer of the currently assigned file to zero (first byte of the file).
// Upon exit, "_Size" holds the filesize in bytes.
procedure Fat32_Append;
// Sets the filepointer of the currently assigned file to the next place after its last byte
procedure Fat32_Rewrite;
// Discards the content of the currently assigned file (as if it was newly created),
// sets its filesize and FilePointer to 0.
function Fat32_Rename(var OldName, NewName: TLongFileName): boolean;
// Renames the file named "OldName" to "NewName" in the current directory.
// Returns "true" if successful, else "false" (e.g. "OldName" does not exists or "NewName" already exists)
// Attention! !!! this function closes first the currently open file !!!
procedure Fat32_Flush;
// Writes the sectorbuffer of the currently assigned file to the card/disk (if necessary), and
// also writes the (changed) filesize to its directory entry (if necessary).
// Calling this function writes all info as if the file closes, but keeps the file open
// for further access.
procedure Fat32_Seek(Position: DWord);
// Sets the filepointer of the currently open file to "Position".
// If "Position" is outside the file, then it becomes the same as with "Append"
function Fat32_FilePointer: DWord;
// Returns the filepointer value of the currently open file
// The filepointer is the bytenumber in the file that will be read from or written to next.
function Fat32_EOF: boolean;
// Returns true on an end-of-file condition: the filepointer is outside the file
// During "appending" data EOF is always true.
function Fat32_Get_File_Size: DWord;
// Returns the FileSize in bytes of the currently assigned file
function Fat32_Get_File_Size_Sectors: DWord;
// Returns the FileSize of the currently assigned file in Sectors
procedure Fat32_Get_File_Date(var Year: word; var Month: byte; var Day: byte; var Hours: byte; var Mins: byte);
// Gets the "Creation" date and time of the currently assigned file
procedure Fat32_Set_File_Date(Year: word; Month: byte; Day: byte; Hours: byte; Mins: byte);
// Sets the "Creation" date and time of the currently assigned file
procedure Fat32_Get_File_Date_Modified(var Year: word; var Month: byte; var Day: byte; var Hours: byte; var Mins: byte);
// Gets the "Last Modified" date and time of the currently assigned file
procedure Fat32_Set_File_Date_Modified(Year: word; Month: byte; Day: byte; Hours: byte; Mins: byte);
// Sets the "Last Modified" date and time of the currently assigned file
function Fat32_GetAttr: byte;
// returns the attributes of the currently assigned file
procedure Fat32_SetAttr(Attr: byte);
// sets the attributes of the currently assigned file
procedure Fat32_ClearArchiveAttr;
// clears the archive attribute of the currently assigned file
procedure Fat32_SetArchiveAttr;
// Sets the archive attribute of the currently assigned file
procedure Fat32_Read(var _Data: byte);
// Reads 1 byte out of the currently assigned file into "_Data".
// On exit, the CurrentFilePointer points to the next byte in the file to be read
function Fat32_ReadBuffer(var Buffer: array[4096] of byte; DataLen: Word): word;
// Reads at most "DataLen" bytes out of the currently assigned file into "Buffer"
// Upon exit, the CurrentFilePointer points to the next byte in the file to be read
// Returns the actual number of bytes read (reading beyond EOF is not done)
procedure Fat32_Write(_Data: byte);
// Writes 1 byte ("_Data") to the currently assigned file.
// Upon exit, the CurrentFilePointer points to the next byte in the file to be written
procedure Fat32_Write_Const_Buffer(const _Data: ^byte; Len: word);
// writes "Len" bytes out of "_Data" (constant data) to the currently open file at position "CurrentFilePointer"
// Afterwards CurrentFilePointer points to the next byte in the file to be written
// Usage: Fat32_Write_Const_Buffer(@Constant, NrofConstantbytes);
procedure Fat32_WriteBuffer(var Buffer: array[4096] of byte; DataLen: Word);
// Writes "DataLen" bytes out of "Buffer" to the currently open file at position "CurrentFilePointer"
// Afterwards CurrentFilePointer points to the next byte in the file to be written
procedure Fat32_WriteText(var S: string[4095]);
// Writes string "S" to the currently open file at position "CurrentFilePointer",
// no CR LF written after the string
// Afterwards CurrentFilePointer points to the next byte in the file to be written
procedure Fat32_WriteLine(var S: string[4095]);
// Writes string "S" to the currently open file at position "CurrentFilePointer",
// CR LF additionally written after the string
// Afterwards CurrentFilePointer points to the next byte in the file to be written
procedure Fat32_Seek_Sector(Sector: DWord);
// Sets the filepointer of the currently open file to "Sector * BytesPerSector".
// If "Sector * BytesPerSector" is outside the file, then it becomes the same as with "Append"
procedure Fat32_Write_Sector(var Buffer: array[512] of byte);
// Writes 512 bytes out of "Buffer" to the currently open file at position "CurrentFilePointer"
// Afterwards "CurrentFilePointer" points to the next byte in the file to be written.
// Attention: "CurrentFilePointer" mod 512 must be zero (so, at a sector boundary) when "Fat32_Write_Sector" is called!!!!
function Fat32_Read_Sector(var Buffer: array[512] of byte): DWord;
// Reads one sector (if possible) out of the currently open file at position "CurrentFilePointer" to "Buffer"
// Returns the actual number of bytes read (0..512)
// Afterwards "CurrentFilePointer" points to the next byte in the file to be read.
// Attention: "CurrentFilePointer" mod 512 will be set to zero (so, at a sector boundary) when "Fat32_Read_Sector" is called!!!!
procedure Fat32_Append_Sector;
// Sets the filepointer of the currently assigned file to the next place after its last sector
function Fat32_Delete(var Mame: TLongFileName): boolean;
// Deletes file with "Name"
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!
procedure Fat32_Delete_Files;
// Deletes all "Files" in the current directory
// The directories in the current are not deleted
function Fat32_ChDir(var LongFn: TLongFileName): boolean;
// Changes directory to "LongFn" from within the current directory
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!
// "Prevdir" can be used afterwards to return to the original directory (the one before "ChDir")
function Fat32_ChDir_FP(var LongFn: TLongFileName): boolean;
// Changes directory to "LongFn"
// Multiple dirlevels allowed, e.g. "\Directory1\Directory2",
// but: the different parts of the path themselves can not be longer than 128 bytes!
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!
// "Prevdir" can be used afterwards to return to the original directory (the one before "ChDir_FP")
function Fat32_MkDir_ChDir_FP(var LongFn: TLongFileName): boolean;
// Changes directory to "LongFn" and meanwhile create all necessary directories in LonFn.
// Multiple dirlevels allowed, e.g. "\Directory1\Directory2",
// but: the different parts of the path themselves can not be longer than 128 bytes!
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!
// "Prevdir" can be used afterwards to return to the original directory (the one before "ChDir_FP")
procedure Fat32_PushDir;
// The current directory's start cluster is stored for "PopDir"
procedure Fat32_PopDir;
// The current directory is changed back to the directory wherein the last "PushDir" was executed
procedure Fat32_PrevDir;
// The current directory is changed back to the previously selected directory before the current one
function Fat32_MkDir(var LongFn: TLongFileName): boolean;
// Creates a directory inside the current one if it not already exists
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if success (the directory was created or existed already)
// Attention! !!! this function closes first the currently open file !!!
function Fat32_MkDir_ChDir(var LongFn: TLongFileName): boolean;
// Makes a directory and changes the current directory to it.
// (same as subsequent "MkDir" and "ChDir"
function Fat32_RmDir(var LongFn: TLongFileName): boolean;
// Deletes a directory within the current one.
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if success (the directory was removed or it did not exist already)
// Make sure the directory is empty (except for the '.' and '..' files), otherwise lost clusters will occur
// Attention! !!! this function closes first the currently open file !!!
function Fat32_RmDir_All(var Fn: string): boolean;
// Deletes directory "Fn" - and all of its files, including subdirectories and all of their files - from the current directory.
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if success (the directory was removed or it did not exist already)
// Attention! !!! this function closes first the currently open file !!!
function Fat32_Delete_All: boolean;
// Empties the current directory: all files and subdirs are removed.
// Returns true if success (the all flies and directories were removed or it did not exist already)
// Attention! !!! this function closes first the currently open file !!!
procedure Fat32_Curdir(var CurrentDir: TLongFileName);
// Returns the name of the current directory in "CurrentDir".
// Attention! !!! this function closes first the currently open file !!!
// Attention: the actual variable used as CurrentDir must be (at least) of type string[255]!!!
procedure Fat32_Curdir_FP(var CurrentDir: TLongFileName);
// Returns the full path of the current directory in "CurrentDir".
// Attention! !!! this function closes first the currently open file !!!
// Attention: the actual variable used as CurrentDir must be (at least) of type string[255]!!!
procedure Fat32_CleanDir;
// "Cleans" the current directory file: deletes the unused entries at the end, which
// makes it unnecessary to search through them when e.g. testing a file's existance.
// Enhances speed when creating new files, after other files have been deleted (direntries became free)
// Attention! !!! this function closes first the currently open file !!!
procedure Fat32_DefragDir;
// "Defragments" the current directory file: deletes the unused entries "holes" in the directory, which
// makes it unnecessary to search through them when e.g. testing a file's existance.
// Enhances speed when creating new files, after other files have been deleted (direntries became free)
// Does also a "CleanDir"
// Attention! !!! this function closes first the currently open file !!!
function Fat32_FindFirst(FileAttr: byte): boolean;
// Returns true if the routine finds the first file/directory (if any) and puts the result in "Fat32_DirItem".
// Only the current directory is searched.
// If no first file/directory present then the procedure returns false.
// To be called before "Fat32_FindNext" is used.
function Fat32_FindNext(FileAttr: byte): boolean;
// Returns true if the routine finds a next file/directory (if any) and puts the result in "Fat32_DirItem".
// Only the current directory is searched.
// If no next file/directory present then the procedure returns false.
// Not to be called without a previous call to "Fat32_FindFirst"
function Fat32_FindFirst_FN(var LongFN: TLongFileName; FAttr: byte): boolean;
// Same as "Fat32_FindFirst" but with filename ("LongFN") included in the search criteria.
// Allowed wildcard constructions in "LongFn":
// - "FileName.Ext" : Finds only the file/directory with the filename exactly equal to LongFn
// - "*.*" : Finds any file/directory (= same as "Fat32_FindFirst")
// - "File*.E*: : Finds all files/directories of which the filename starts with "File" and the
// extension starts with "E".
// Attention: The "*" can only be used to make the --> tail <-- of the filename or extension "don't care".
// - "FileN?me.E?t : Finds all files/directories with the same name as LongFn, except the positions holding "?"
// which are don't care. "?" only represents 1 character!
// If "LongFn" has no dot ('.') in it, only files/directories with no extension are found
function Fat32_FindNext_FN(var LongFN: TLongFileName; FAttr: byte): boolean;
// Same as "Fat32_FindNext" but with filename ("LongFN") included in the search criteria.
// Allowed wildcard constructions in "LongFn": see "Fat32_FindFirst_FN"
function Fat32_FileExists(var LongFn: TLongFileName; FAttr: byte): boolean;
// returns true if file with name "LongFn" and attribute "FAttr" exists
// No backslashes allowed in "LongFn" (no multiple dirlevels)
function Fat32_Get_Swap_File(NoSectors: dword; var filename : TLongFileName; Attr : byte) : Dword;
{ - This function is used to create a Fat32 file of fixed size (NoSectors sectors) on the MMC/SD media,
with consequtive sectors, making it possible to use direct sector read/write in the file without using the FAT32 filesystem any further.
- The function returns the number of the start sector for the newly created swap file, if there was enough free space
on the MMC/SD/CF card or disk to create file of required size, 0 otherwise.
- Attention!!! If a file with specified name already exists on the media, it will be emptied, and a attempt will be made to re-use its space on the card/disk.
- No need to "close" the file after it was created and written to with this function (the file is not open anyway from the filesystem's point of view).
- Afterwards the swap file can also be opened like a normal file with "Fat32_Assign".
}
// -----------------------------------------------------------------------------
// Additional Routines
// -----------------------------------------------------------------------------
procedure Fat32_MakeDirFile(var DirFileName: TLongFileName);
// Makes a text file which holds the directory info
// (e.g. names and sizes of files present) of the current directory
procedure Fat32_MakeDirFileHtm(var DirFileName: TLongFileName);
// Makes a html file which holds the directory info
// (e.g. names and sizes of files present) of the current directory
procedure Fat32_CopyFile(var SourceFileName: string; var DestinationFileName: string);
// Copies file with name "SourceFileName" to a file with name "DestinationFileName"
// Attention! !!! this function closes first the currently open files
function Fat32_FileCount(var Names: string[255]; Attr: byte): DWord;
// Count the number of files in the current directory of which the filename is in "Names"
// and the attributes comply with "Attr"
// "Names" is a comma separated list of ambiguous (wildcard) filesnames, like '*.txt, *.log, File*.*',
// for the allowed wildcard constructions in the filenames: see "Fat32_FindFirst_FN".
// "FAttr" is any of the filetypes defined in unit "Fat32.mpas"
//
// Attention:
// * upon exit "Names" is an empty string!
// * the separate untrimmed filenames in "names" should not be longer than 30 characters
function Fat32_TotalSpace: DWord;
// Gives the total space in bytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
// Only applicable with cards spaces <= 4 GB
function Fat32_FreeSpace: DWord;
// Gives the free space in bytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
// Only applicable with cards spaces <= 4 GB
function Fat32_UsedSpace: DWord;
// Gives the used space in bytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
// Only applicable with cards spaces <= 4 GB
function Fat32_TotalSpace_KB: DWord;
// Gives the total space in Kilobytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_FreeSpace_KB: DWord;
// Gives the free space in Kilobytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_UsedSpace_KB: DWord;
// Gives the used space in Kilobytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_TotalSpace_MB: DWord;
// Gives the total space in Megabytes (rounded down) on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_FreeSpace_MB: DWord;
// Gives the free space in Megabytes (rounded down) on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_UsedSpace_MB: DWord;
// Gives the used space in Megabytes (rounded down) on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_TotalSpace_GB: real;
// Gives the total space in Gigabytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_FreeSpace_GB: Real;
// Gives the free space in Gigabytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
function Fat32_UsedSpace_GB: Real;
// Gives the used space in Gigabytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
// -------------------------------------------------------------------------------------------------
implementation