mirror of
https://github.com/peteratebs/rtfsprorelease.git
synced 2025-06-19 01:05:39 -04:00
1771 lines
77 KiB
C
1771 lines
77 KiB
C
/*****************************************************************************
|
||
*Filename: RTFSTYPES.H - RTFS common function types
|
||
*
|
||
*
|
||
* EBS - RTFS (Real Time File Manager)
|
||
*
|
||
* Copyright EBS, 2007
|
||
* All rights reserved.
|
||
* This code may not be redistributed in source or linkable object form
|
||
* without the consent of its author.
|
||
*
|
||
*
|
||
* Description:
|
||
*
|
||
*
|
||
*
|
||
*
|
||
****************************************************************************/
|
||
|
||
#ifndef __RTFSTYPES__
|
||
#define __RTFSTYPES__ 1
|
||
|
||
/* llword type used for ProPlus feature set, all arithmetic on files sizes and file offsets uses the llword type.
|
||
Unlike in the basic exFAT package which USES 64 bit arithmetic macros, some ProPlus arithmetic is performed
|
||
using C operators (+,- == etc) and require native 64 bit support if exFAT is enabled */
|
||
/* This ProPlus union is included in the RTFS Finode structure */
|
||
typedef union _llword {
|
||
dword val32; /* File size */
|
||
#if (INCLUDE_EXFATORFAT64)
|
||
ddword val64; /* File size */
|
||
#endif
|
||
} llword;
|
||
|
||
/* Structure for run length encoding cluster chains, currently used by
|
||
ProPlus only but will be used in Pro */
|
||
typedef struct region_fragment {
|
||
dword start_location;
|
||
dword end_location;
|
||
struct region_fragment *pnext;
|
||
} REGION_FRAGMENT;
|
||
/* Give the size of an individual fragment in clusters */
|
||
#define PC_FRAGMENT_SIZE_CLUSTERS(PF) ((PF)->end_location - (PF)->start_location + 1)
|
||
|
||
/* ProPlus extensions to RTFS Finode structure */
|
||
typedef struct finode_extended {
|
||
REGION_FRAGMENT *plast_fragment;
|
||
REGION_FRAGMENT *pfirst_fragment;
|
||
llword alloced_size_bytes;
|
||
dword alloced_size_clusters;
|
||
dword clusters_to_process;
|
||
dword last_processed_cluster;
|
||
dword clusters_to_delete;
|
||
dword last_deleted_cluster;
|
||
REGION_FRAGMENT *ptofree_fragment; /* fragments to in the FAT on flush */
|
||
} FINODE_EXTENDED;
|
||
|
||
/* This ProPlus union is included in the RTFS Finode structure */
|
||
typedef union finode_extension {
|
||
FINODE_EXTENDED *x;
|
||
} FINODE_EXTENSION;
|
||
|
||
/* This union is used as a device for declaring or allocating all extended finode structures in the same pool.
|
||
the FINODE_EXTENDED and FINODE_META64 are basically the same size and so decaring them together simplified
|
||
startup configuration procedures */
|
||
typedef union finode_extension_memory {
|
||
union finode_extension_memory *pnext_freelist;
|
||
FINODE_EXTENDED x;
|
||
} FINODE_EXTENSION_MEMORY;
|
||
|
||
/* ProPlus extensions to RTFS File structure */
|
||
#if (INCLUDE_CIRCULAR_FILES)
|
||
typedef struct remap_record
|
||
{
|
||
ddword remap_fpoff_start_ddw; /* byte offset to fp offset of region */
|
||
ddword remap_fpoff_end_ddw; /* byte length of fp remap region */
|
||
ddword remap_linear_offset_ddw; /* raw offset to data in linear file */
|
||
struct pc_file *premapfile;
|
||
struct remap_record *pnext;
|
||
} REMAP_RECORD;
|
||
#endif
|
||
|
||
/* Date stamping buffer */
|
||
typedef struct datestr {
|
||
unsigned short date;
|
||
unsigned short time;
|
||
} DATESTR;
|
||
|
||
/* This ProPlus structure is included in the RTFS file structure */
|
||
typedef struct pc_file_proplus {
|
||
struct finode * ffinode; /* Info for getting at the inode for file access */
|
||
struct pc_file *asy_file_pnext;
|
||
#define AF_CONTIGUOUS_MODE_FORCE 0x02
|
||
word allocflags; /* For Files special allocation instructions */
|
||
dword allocation_policy;
|
||
dword allocation_hint;
|
||
dword async_file_segment64;
|
||
dword segment_size;
|
||
llword file_pointer;
|
||
llword region_byte_base;
|
||
dword region_block_base;
|
||
REGION_FRAGMENT *pcurrent_fragment;
|
||
dword min_alloc_bytes;
|
||
#if (INCLUDE_TRANSACTION_FILES)
|
||
byte *transaction_buffer;
|
||
dword current_transaction_cluster;
|
||
dword current_transaction_blockno;
|
||
#endif
|
||
#if (INCLUDE_CIRCULAR_FILES)
|
||
ddword circular_file_size_ddw;
|
||
ddword circular_file_base_ddw;
|
||
ddword circular_max_offset_ddw;
|
||
int sibling_fd;
|
||
struct pc_file *psibling;
|
||
REMAP_RECORD *remapped_regions;
|
||
REMAP_RECORD *remap_freelist;
|
||
#endif
|
||
} PC_FILE_PROPLUS;
|
||
|
||
/* ProPlus extensions to RTFS drive structure */
|
||
/* These ProPlus structures are included in the RTFS file structure */
|
||
|
||
/* Constants used for logging IO region accesses and forcing IO errors
|
||
Only needed for test - Some tests monitor the IO operations that
|
||
occuring and force read or write error during specific IO operations
|
||
to ensure that the system responds properly
|
||
For now this methodolgy is used only to test the journaling system
|
||
*/
|
||
#define RTFS_DEBUG_IO_J_NOT_USED 0
|
||
#define RTFS_DEBUG_IO_J_ROOT_WRITE 1
|
||
#define RTFS_DEBUG_IO_J_INDEX_OPEN 2
|
||
#define RTFS_DEBUG_IO_J_INDEX_FLUSH 3
|
||
#define RTFS_DEBUG_IO_J_INDEX_CLOSE 4
|
||
#define RTFS_DEBUG_IO_J_INDEX_CLOSE_EMPTY 5
|
||
#define RTFS_DEBUG_IO_J_REMAP_WRITE 6
|
||
#define RTFS_DEBUG_IO_J_REMAP_READ 7
|
||
#define RTFS_DEBUG_IO_J_ROOT_READ 8
|
||
#define RTFS_DEBUG_IO_J_RESTORE_READ 9
|
||
#define RTFS_DEBUG_IO_J_RESTORE_START 10
|
||
#define RTFS_DEBUG_IO_J_RESTORE_END 11
|
||
#define RTFS_DEBUG_IO_J_INDEX_READ 12
|
||
#define RTFS_DEBUG_IO_J_RESTORE_INFO_WRITE 13
|
||
#define RTFS_DEBUG_IO_J_RESTORE_FAT_WRITE 14
|
||
#define RTFS_DEBUG_IO_J_RESTORE_BLOCK_WRITE 15
|
||
#define RTFS_DEBUG_IO_J_RANGES 16
|
||
|
||
#if (INCLUDE_DEBUG_TEST_CODE)
|
||
typedef struct io_runtime_stats {
|
||
dword blocks_transferred[RTFS_DEBUG_IO_J_RANGES];
|
||
int force_io_error_on_type;
|
||
dword force_io_error_when;
|
||
int io_errors_forced;
|
||
dword force_io_error_now;
|
||
} IO_RUNTIME_STATS;
|
||
#endif
|
||
|
||
/* values for drive_async_state */
|
||
#define DRV_ASYNC_IDLE 0
|
||
#define DRV_ASYNC_MOUNT 1
|
||
#define DRV_ASYNC_RESTORE 2
|
||
#define DRV_ASYNC_FATFLUSH 3
|
||
#define DRV_ASYNC_JOURNALFLUSH 4
|
||
#define DRV_ASYNC_FILES 5
|
||
#define DRV_ASYNC_DONE_MOUNT 101
|
||
#define DRV_ASYNC_DONE_RESTORE 102
|
||
#define DRV_ASYNC_DONE_FATFLUSH 103
|
||
#define DRV_ASYNC_DONE_JOURNALFLUSH 104
|
||
#define DRV_ASYNC_DONE_FILES 105
|
||
|
||
|
||
/* removed typedef struct drive_configure { */
|
||
|
||
|
||
|
||
#if (INCLUDE_VFAT||INCLUDE_EXFAT)
|
||
/* Trag lfn segments. segblock[0] is the block that contains beginning of the
|
||
file name. segindex is the segment in that block where the beginning is
|
||
stored. If the lfn spans > 1 block the next block # is in segblock[2] */
|
||
typedef struct segdesc {
|
||
int nsegs; /* # segs in the lfn */
|
||
int segindex;
|
||
dword segblock[3];
|
||
byte ncksum; /* checksum of the associated DOSINODE */
|
||
byte fill[3]; /* nice */
|
||
} SEGDESC;
|
||
|
||
#define LFNRECORD SEGDESC
|
||
#endif
|
||
|
||
|
||
|
||
#if (INCLUDE_EXFAT)
|
||
/* exfat Format control structure */
|
||
|
||
typedef struct rtfsexfatparms {
|
||
ddword MediaLengthSectors;
|
||
dword BytesPerSector;
|
||
dword SectorsPerCluster;
|
||
int ExtendedBootCodeCountSectors;
|
||
byte *ExtendedBootCodeData;
|
||
BOOLEAN ScrubVolume; /* If true erase or zero the section of media to contain the volume formatting */
|
||
dword BadSectorCount;
|
||
dword *BadSectorList;
|
||
|
||
ddword MediaLengthBytes;
|
||
dword BoundaryUnit;
|
||
dword FirstClusterOfUpCaseTable;
|
||
dword FirstClusterOfBam;
|
||
dword UpCaseSizeClusters;
|
||
dword BamSizeClusters;
|
||
ddword BamSizeBytes;
|
||
dword ReservedSectors;
|
||
|
||
|
||
|
||
byte JumpBoot[3]; /* EBh, 76h, 90h */
|
||
byte FileSystemName[8]; /* <20>EXFAT <20> */
|
||
ddword PartitionOffset;
|
||
ddword VolumeLength;
|
||
dword FatOffset;
|
||
dword FatLength;
|
||
dword ClusterHeapOffset;
|
||
dword ClusterCount;
|
||
dword FirstClusterOfRootDirectory;
|
||
dword VolumeSerialNumber;
|
||
byte FileSystemRevision[2];
|
||
word VolumeFlags;
|
||
byte BytesPerSectorShift;
|
||
byte SectorsPerClusterShift;
|
||
byte NumberOfFats;
|
||
byte DriveSelect; /* 80h */
|
||
byte PercentInUse;
|
||
// byte 7 Reserved All 00h
|
||
byte BootCode[390];
|
||
byte BootSignature[2];
|
||
|
||
|
||
} RTFSEXFATFMTPARMS;
|
||
|
||
|
||
/* exfat FINODE structure extensions */
|
||
typedef struct exfatfinodext {
|
||
word SetChecksum;
|
||
word FileAttributes;
|
||
// dword CreateTimeStamp;
|
||
// dword LastModifiedTimeStamp;
|
||
// dword LastAccessedTimeStamp;
|
||
byte Create10msIncrement;
|
||
byte LastModified10msIncrement;
|
||
byte CreateUtcOffset;
|
||
byte LastModifiedUtcOffset;
|
||
byte LastAccessedUtcOffset;
|
||
byte GeneralSecondaryFlags;
|
||
byte SecondaryCount;
|
||
byte NameLen;
|
||
word NameHash;
|
||
} EXFATFINODEEXT;
|
||
#endif
|
||
|
||
|
||
/* This ProPlus union is included in the RTFS Finode structure */
|
||
typedef union finode_size {
|
||
dword fsize; /* File size */
|
||
#if (INCLUDE_EXFATORFAT64)
|
||
ddword fsize64; /* File size */
|
||
#endif
|
||
} FINODE_SIZE;
|
||
|
||
|
||
typedef struct finode {
|
||
byte fname[8];
|
||
byte fext[3];
|
||
byte fattribute; /* File attributes */
|
||
byte reservednt;
|
||
byte create10msincrement;
|
||
word ctime; /* time & date create */
|
||
word cdate;
|
||
word atime; /* time & date modified */
|
||
word adate;
|
||
word fclusterhi; /* This is where fat32 stores file location */
|
||
word ftime; /* time & date lastmodified */
|
||
word fdate;
|
||
word fcluster; /* Cluster for data file */
|
||
FINODE_SIZE fsizeu;
|
||
int opencount;
|
||
/* If the finode is an open file the following flags control the sharing.
|
||
they are maintained by po__open */
|
||
#ifdef OF_WRITE
|
||
/* The watcom Windows include files define OF_WRITE too */
|
||
#undef OF_WRITE
|
||
#endif
|
||
#define OF_WRITE 0x01 /* File is open for write by someone */
|
||
#define OF_WRITEEXCLUSIVE 0x02 /* File is open for write by someone
|
||
they wish exclusive write access */
|
||
#define OF_EXCLUSIVE 0x04 /* File is open with exclusive access not
|
||
sharing write or read */
|
||
#define OF_BUFFERED 0x10 /* Non block alligned data is buffered */
|
||
#if (INCLUDE_RTFS_PROPLUS) /* ProPlus specific open flags */
|
||
#define OF_TRANSACTION 0x80 /* Opened as a transaction file */
|
||
#endif
|
||
dword openflags; /* For Files. Track how files have it open */
|
||
struct blkbuff *pfile_buffer; /* If the file is opened in buffered
|
||
mode this is the last buffered
|
||
item */
|
||
struct ddrive *my_drive;
|
||
dword my_block;
|
||
int my_index;
|
||
struct finode *pnext;
|
||
struct finode *pprev;
|
||
BOOLEAN is_free; /* True if on the free list */
|
||
#if (INCLUDE_VFAT)
|
||
LFNRECORD s; /* Defined as SEGDESC for VFAT */
|
||
#endif
|
||
|
||
/* Flags tell if buffer associted with the finode or the directory entry needs flush */
|
||
#define FIOP_BUFFER_DIRTY 0x01
|
||
#define FIOP_NEEDS_FLUSH 0x02
|
||
|
||
/* The following flags are proplus only */
|
||
#define FIOP_ASYNC_FLUSH 0x04
|
||
#define FIOP_ASYNC_UNLINK 0x08
|
||
#define FIOP_ASYNC_OPEN 0x10
|
||
#define FIOP_ASYNC_CLOSE 0x20
|
||
#define FIOP_ASYNC_ALL_OPS (FIOP_ASYNC_CLOSE|FIOP_ASYNC_FLUSH|FIOP_ASYNC_UNLINK|FIOP_ASYNC_OPEN)
|
||
|
||
#define FIOP_LOAD_AS_NEEDED 0x40
|
||
|
||
dword operating_flags; /* For Files. Track how files have it open */
|
||
REGION_FRAGMENT *pbasic_fragment;
|
||
|
||
#if (INCLUDE_EXFAT) /* exfat FINODE structure extensions */
|
||
EXFATFINODEEXT exfatinode;
|
||
#endif
|
||
|
||
#if (INCLUDE_RTFS_PROPLUS) /* ProPlus FINODE structure extensions */
|
||
dword extended_attribute_dstart;
|
||
FINODE_EXTENSION e; /* finode extension */
|
||
#endif
|
||
} FINODE;
|
||
|
||
|
||
#define PCDELETE (byte) 0xE5 /* MS-DOS file deleted char */
|
||
#define PCDELETEESCAPE (byte) 0xFF /* Escape character rmode
|
||
passes to pc_ino2dos to really
|
||
delete a directory entry */
|
||
#define FAT_EOF_RVAL 0xffffffff /* Symbolic constant. if returned from clnext
|
||
means end of chain */
|
||
#define LARGEST_DWORD 0xffffffff /* Use when we want MAX dword */
|
||
|
||
typedef struct pcmbuff {
|
||
dword first_blockno;
|
||
int block_count; /* up to 32 */
|
||
int dirty_count; /* 0 if no blocks need flush, othe4rwise count of dirty blocks */
|
||
int dirty_block_offset; /* Offset to last block marked dirty (if dirty_count is 1, this is it */
|
||
dword dirty_bitmap; /* Bitmap of offsets of all dirty blocks (max is 32 */
|
||
byte *pdata;
|
||
} PCMBUFF;
|
||
|
||
typedef struct fatbuff {
|
||
struct fatbuff *pnext;
|
||
struct fatbuff *pprev;
|
||
struct fatbuff *pnext_hash; /* All hash table entries start one of these */
|
||
struct fatbuff *pprev_hash;
|
||
dword lru_counter;
|
||
PCMBUFF fat_data_buff;
|
||
} FATBUFF;
|
||
|
||
/* Fat buffer context */
|
||
typedef struct fatbuffcntxt {
|
||
// Suggest supporting on ProPlus
|
||
dword stat_primary_cache_hits;
|
||
dword stat_secondary_cache_hits;
|
||
dword stat_secondary_cache_loads;
|
||
dword stat_secondary_cache_swaps;
|
||
|
||
// Suggest supporting on ProPlus, point to drive.du values
|
||
struct fatbuff *pfat_buffers; /* address of buffer pool */
|
||
struct fatbuff *pcommitted_buffers; /* uses pnext/pprev */
|
||
struct fatbuff *pfree_buffers; /* uses pnext */
|
||
dword fat_buffer_page_size_sectors; /* Set during context setup */
|
||
dword fat_buffer_page_mask;
|
||
int hash_size;
|
||
dword hash_mask;
|
||
dword lru_counter;
|
||
int num_dirty;
|
||
#define FAT_HASH_SIZE 32
|
||
FATBUFF *fat_blk_hash_tbl_core[FAT_HASH_SIZE];
|
||
dword primary_sectormap_core[FAT_HASH_SIZE];
|
||
FATBUFF *primary_buffmap_core[FAT_HASH_SIZE];
|
||
FATBUFF **fat_blk_hash_tbl; /* ProPlus points to fat_blk_hash_tbl_core Pro passed in */
|
||
/* Merged primary mapping scheme uses block cache instead of pointers */
|
||
dword *primary_mapped_sectors;
|
||
FATBUFF **primary_mapped_buffers;
|
||
} FATBUFFCNTXT;
|
||
|
||
/* Dos Directory Entry Memory Image of Disk Entry */
|
||
|
||
|
||
|
||
typedef struct dosinode {
|
||
byte fname[8];
|
||
byte fext[3];
|
||
byte fattribute; /* File attributes */
|
||
byte reservednt;
|
||
byte create10msincrement;
|
||
word ctime; /* time & date create */
|
||
word cdate;
|
||
word adate; /* Date last modified */
|
||
word fclusterhi; /* This is where fat32 stores file location */
|
||
word ftime; /* time & date lastmodified */
|
||
word fdate;
|
||
word fcluster; /* Cluster for data file */
|
||
dword fsize; /* File size */
|
||
} DOSINODE;
|
||
|
||
|
||
|
||
|
||
/* contain location information for a directory */
|
||
typedef struct dirblk {
|
||
dword my_frstblock; /* First block in this directory */
|
||
dword my_block; /* Current block number */
|
||
#if (INCLUDE_EXFAT) /* Exfat dirblk extensions */
|
||
dword my_exNOFATCHAINfirstcluster; /* ExFat - if non-zero we are scanning a contiguous region with no FAT chain */
|
||
dword my_exNOFATCHAINlastcluster; /* ExFat - if non-zero we are scanning a contiguous region with no FAT chain */
|
||
#endif
|
||
int my_index; /* dirent number in my block */
|
||
} DIRBLK;
|
||
|
||
/* Block buffer */
|
||
typedef struct blkbuff {
|
||
struct blkbuff *pnext; /* Used to navigate free and populated lists */
|
||
struct blkbuff *pprev; /* the populated list is double linked. */
|
||
/* Free list is not */
|
||
struct blkbuff *pnext2; /* Each hash table entry starts a chain of these */
|
||
#define DIRBLOCK_FREE 0
|
||
#define DIRBLOCK_ALLOCATED 1
|
||
#define DIRBLOCK_UNCOMMITTED 2
|
||
int block_state;
|
||
int use_count;
|
||
struct ddrive *pdrive; /* Used during IO */
|
||
struct ddrive *pdrive_owner; /* Used to distinguish scratch allocation from common pool or device */
|
||
dword blockno;
|
||
dword data_size_bytes; /* Size of the data at pointer */
|
||
byte *data;
|
||
} BLKBUFF;
|
||
|
||
/* Block buffer context */
|
||
typedef struct blkbuffcntxt {
|
||
dword stat_cache_hits;
|
||
dword stat_cache_misses;
|
||
struct blkbuff *ppopulated_blocks; /* uses pnext/pprev */
|
||
struct blkbuff *pfree_blocks; /* uses pnext */
|
||
struct blkbuff *assigned_free_buffers;
|
||
#if (INCLUDE_DEBUG_LEAK_CHECKING)
|
||
struct blkbuff *pscratch_blocks; /* uses pnext */
|
||
#endif
|
||
int num_blocks;
|
||
int num_free;
|
||
int scratch_alloc_count;
|
||
int low_water;
|
||
int num_alloc_failures;
|
||
#define BLOCK_HASHSIZE 16
|
||
#define BLOCK_HASHMASK 0xf
|
||
struct blkbuff *blk_hash_tbl[BLOCK_HASHSIZE]; /* uses pnext2 */
|
||
} BLKBUFFCNTXT;
|
||
|
||
|
||
|
||
|
||
#define DRVOP_MOUNT_VALID 0x1 /* True if mounted */
|
||
#define DRVOP_MOUNT_ABORT 0x2 /* True if error handler requests abort */
|
||
#define DRVOP_FAT_IS_DIRTY 0x4 /* True if fat needs flush */
|
||
/* The states below are for ProPlus only */
|
||
#define DRVOP_FS_NEEDS_FLUSH 0x8 /* True if journal needs flush */
|
||
#define DRVOP_FS_NEEDS_RESTORE 0x10/* True if FAT volume needs restore */
|
||
#define DRVOP_ASYNC_FFLUSH 0x20
|
||
#define DRVOP_ASYNC_JFLUSH 0x40
|
||
#define DRVOP_ASYNC_JRESTORE 0x80
|
||
#define DRVOP_FS_CLEAR_ON_MOUNT 0x100 /* fs_api_enable() called with a request to clear the journal. It is cleared when journaling resumes */
|
||
#define DRVOP_FS_START_ON_MOUNT 0x200 /* fs_api_enable() called enable journaling on the next mount regardless of callback policy */
|
||
#define DRVOP_FS_DISABLE_ON_MOUNT 0x400 /* fs_api_disable() was called disable autorestore and journaling on the next mount regardless of callback policy */
|
||
#define DRVOP_BAM_IS_DIRTY 0x800 /* EXFAT True if BAM needs flush */
|
||
|
||
|
||
#if (INCLUDE_EXFAT) /* exfat drive structure extensions */
|
||
typedef struct exfatddrive {
|
||
byte JumpBoot[3]; /* (BP 0 to 2) */
|
||
byte FileSystemName[8]; /* (BP 3 to 10) */
|
||
/* byte MustBeZero[53]; (BP 11 to 63) */
|
||
ddword PartitionOffset; /* (BP 64 to 71) */
|
||
ddword VolumeLength; /* (BP 72 to 79) */
|
||
dword FatOffset; /* (BP 80 to 83) */
|
||
dword FatLength; /* (BP 84 to 87) */
|
||
dword ClusterHeapOffset; /* (BP 88 to 91) */
|
||
dword ClusterCount; /* (BP 92 to 95) */
|
||
dword FirstClusterOfRootDirectory; /* (BP 96 to 99) */
|
||
dword VolumeSerialNumber; /* (BP 100 to 103) */
|
||
word FileSystemRevision; /* (BP 104 and 105) */
|
||
word VolumeFlags; /* (BP 106 and 107) */
|
||
byte BytesPerSectorShift; /* (BP 108) */
|
||
byte SectorsPerClusterShift; /* (BP 109) */
|
||
byte NumberOfFats; /* (BP 110) */
|
||
byte DriveSelect; /* (BP 111) */
|
||
byte PercentInUse; /* (BP 112) */
|
||
/*
|
||
byte Reserved[7]; (BP 113 to 119)
|
||
byte BootCode[390]; (BP 120 to 509)
|
||
*/
|
||
byte BootSignature[2]; /* (BP 510 and 511) */
|
||
|
||
/* === Calculated and retrieved exfat information. */
|
||
word PrimaryFlagsOfBitMap[2]; /* Two possible bit maps so 2 values of each */
|
||
dword FirstClusterOfBitMap[2];
|
||
dword SizeOfBitMap[2];
|
||
dword FirstClusterOfUpCase;
|
||
dword SizeOfUpcase;
|
||
dword TableChecksum;
|
||
/* Maximum unicode value to be upcased (128 for Mandatory else 65536 */
|
||
word UpCaseMaxTranskey;
|
||
|
||
/* Raw configuration values returned from RTFS_CBS_GETEXFATBUFFERS
|
||
Released by RTFS_CBS_RELEASEEXFATBUFFERS */
|
||
int BitMapBufferPageSizeSectors;
|
||
dword BitMapBufferSizeSectors;
|
||
void *BitMapBufferControlCore;
|
||
void *BitMapBufferCore;
|
||
void *UpCaseBufferCore;
|
||
|
||
/* Use a FATBUFFER structure and a modified version of FAT buffering
|
||
code to manage the bit allocation map */
|
||
FATBUFFCNTXT bambuffcntxt;
|
||
dword volume_label_sector; /* Location of the volume entry in the root directory or zero. */
|
||
int volume_label_index; /* index into volume_label_sector */
|
||
} EXFATDDRIVE;
|
||
|
||
#endif
|
||
|
||
|
||
typedef struct ddrive_info {
|
||
dword drive_operating_flags;
|
||
dword volume_serialno; /* Volume serial number block 0 */
|
||
byte volume_label[24]; /* Volume entry from block 0 11 ascii bytes for fat 22 unicode characters for exFat */
|
||
int bytespcluster; /* */
|
||
dword byte_into_cl_mask; /* And this with file pointer to get the
|
||
byte offset into the cluster */
|
||
int fasize; /* Nibbles per fat entry. (3,4 or 8) */
|
||
dword rootblock; /* First block of root dir */
|
||
dword firstclblock; /* First block of cluster area */
|
||
dword maxfindex; /* Last element in the fat - fat32*/
|
||
dword fatblock; /* First block in fat */
|
||
int secproot; /* blocks in root dir */
|
||
dword bootaddr;
|
||
byte oemname[9];
|
||
int bytespsector; /* Multiple of 512 usually is 512 */
|
||
dword bytemasksec; /* Mask to get byte offset (bytespsector-1) */
|
||
int log2_bytespsec; /* Log of bytes per sector */
|
||
int inopblock; /* 16 for 512 sector size */
|
||
int blockspsec; /*1 for 512 sector size, 2 for 1024 sector size, 8 for 4096 */
|
||
|
||
#if (INCLUDE_EXFATORFAT64) /* exfat FINODE structure extensions */
|
||
dword secpalloc; /* Sectors per cluster */
|
||
#else
|
||
byte secpalloc; /* Sectors per cluster */
|
||
#endif
|
||
int log2_secpalloc; /* Log of sectors per cluster */
|
||
int log2_bytespalloc; /* Log of bytes per cluster */
|
||
|
||
int clpfblock32; /* Cluster indeces in a FAT block for FAT32 (128, 256, 512 etc */
|
||
dword cl32maskblock; /* Mask to get cluster index offset (clpfblock32-1) */
|
||
int clpfblock16; /* Cluster indeces in a FAT block for FAT32 (256, 512, 1204 etc */
|
||
dword cl16maskblock; /* Mask to get cluster index offset (clpfblock16-1) */
|
||
|
||
word secreserved; /* Reserved sectors before the FAT */
|
||
byte numfats; /* Number of FATS on the disk */
|
||
word numroot; /* Maximum # of root dir entries */
|
||
dword numsecs; /* Total # sectors on the disk */
|
||
byte mediadesc; /* Media descriptor byte */
|
||
dword secpfat; /* Size of each fat */
|
||
word secptrk; /* sectors per track */
|
||
word numhead; /* number of heads */
|
||
dword numhide; /* # hidden sectors */
|
||
dword free_contig_base; /* Guess of where file data would most ProPlus does not use*/
|
||
dword free_contig_pointer;/* Efficiently stored ProPlus does not use*/
|
||
dword known_free_clusters;/* free clusters on the disk */
|
||
word infosec; /* Only used for fat32 */
|
||
dword partition_base; /* Start of the partition */
|
||
dword partition_size; /* Size of the partition */
|
||
int partition_type; /* Partition type */
|
||
#define SETISEXFAT(P) P->drive_info.isExfat = 1
|
||
#define ISEXFAT(P) P->drive_info.isExfat
|
||
#define ISEXFATORFAT64(P) P->drive_info.isExfat
|
||
int isExfat;
|
||
} DDRIVE_INFO;
|
||
|
||
|
||
typedef struct drive_info {
|
||
/* The following fields are always updated by pc_diskio_info */
|
||
BOOLEAN free_manager_enabled;
|
||
BOOLEAN is_exfat;
|
||
dword drive_opencounter;
|
||
dword sector_size;
|
||
dword erase_block_size; /* sectors per erase block, zero if no erase blocks */
|
||
dword cluster_size;
|
||
dword total_clusters;
|
||
dword free_clusters;
|
||
dword fat_entry_size;
|
||
dword region_buffers_total;
|
||
dword region_buffers_free;
|
||
dword region_buffers_low_water;
|
||
dword drive_operating_policy;
|
||
/* The following field is updated by pc_diskio_stats when extended is specified */
|
||
dword free_fragments;
|
||
} DRIVE_INFO;
|
||
|
||
typedef struct drive_runtime_stats {
|
||
dword async_steps;
|
||
|
||
dword fat_reads;
|
||
dword fat_blocks_read;
|
||
dword fat_writes;
|
||
dword fat_blocks_written;
|
||
dword fat_buffer_swaps;
|
||
|
||
dword dir_buff_hits;
|
||
dword dir_buff_reads;
|
||
dword dir_buff_writes;
|
||
dword dir_direct_reads;
|
||
dword dir_direct_blocks_read;
|
||
dword dir_direct_writes;
|
||
dword dir_direct_blocks_written;
|
||
|
||
dword file_buff_hits;
|
||
dword file_buff_reads;
|
||
dword file_buff_writes;
|
||
dword file_direct_reads;
|
||
dword file_direct_blocks_read;
|
||
dword file_direct_writes;
|
||
dword file_direct_blocks_written;
|
||
} DRIVE_RUNTIME_STATS;
|
||
|
||
/* This structure is included in the RTFS drive structure for Pro and ProPlus
|
||
fields required for ProPlus only are conditionally included */
|
||
typedef struct ddrive_state {
|
||
struct blkbuff *allocated_user_buffer;
|
||
struct blkbuffcntxt *pbuffcntxt;
|
||
#if (INCLUDE_RTFS_FREEMANAGER)
|
||
/* freelist context */
|
||
dword free_ctxt_slot_size;
|
||
dword free_ctxt_cluster_shifter;
|
||
REGION_FRAGMENT *free_ctxt_hash_tbl[RTFS_FREE_MANAGER_HASHSIZE];
|
||
#endif
|
||
#if (INCLUDE_FAILSAFE_RUNTIME)
|
||
void *failsafe_context; /* Failsafe context block if enabled */
|
||
#endif
|
||
|
||
#if (INCLUDE_ASYNC_FATLOAD) /* ProPlus drive_state extensions */
|
||
BOOLEAN fat_scan_complete;
|
||
#endif
|
||
#if (INCLUDE_RTFS_PROPLUS||INCLUDE_ASYNC_FATLOAD) /* ProPlus drive_state extensions */
|
||
dword drv_async_current_cluster;
|
||
dword drv_async_current_fatblock;
|
||
dword drv_async_region_start;
|
||
dword drv_async_region_length;
|
||
#endif
|
||
#if (INCLUDE_RTFS_PROPLUS) /* ProPlus drive_state extensions */
|
||
int drive_async_state;
|
||
struct pc_file *asy_file_pfirst; /* list of currently active async files */
|
||
#endif
|
||
} DDRIVE_STATE;
|
||
|
||
#if (INCLUDE_RTFS_FREEMANAGER)
|
||
#define CHECK_FREEMG_OPEN(PDR) (PDR->drive_state.free_ctxt_cluster_shifter != 0)
|
||
#define CHECK_FREEMG_CLOSED(PDR) (PDR->drive_state.free_ctxt_cluster_shifter == 0)
|
||
#else
|
||
int free_manager_disabled(int);
|
||
#define CHECK_FREEMG_OPEN(PDR) free_manager_disabled(0) /* Call routines that return 0 so compilers do not complain */
|
||
#define CHECK_FREEMG_CLOSED(PDR) free_manager_disabled(1)
|
||
#endif
|
||
|
||
/* This structure is included in the RTFS drive structure and contains drive configuration
|
||
values passed through pc_diskio_configure.
|
||
For ProPlus additional fields are conditionally included */
|
||
|
||
typedef struct driveusercontext {
|
||
#if (INCLUDE_FAILSAFE_CODE)
|
||
/* Failsafe context provided to pc_diskio_configure */
|
||
void *user_failsafe_context;
|
||
#endif
|
||
/* Fat buffer context provided to pc_diskio_configure */
|
||
dword user_num_fat_buffers;
|
||
struct fatbuff *fat_buffer_structures; /* address of buffer pool */
|
||
int fat_buffer_pagesize;
|
||
byte *user_fat_buffer_data; /* address of buffer pool */
|
||
|
||
/* Current user buffer, same as assigned_user_buffer unless overriddedn by a call to pc_efilio_setbuff */
|
||
dword drive_operating_policy; /* by user */
|
||
#if (INCLUDE_RTFS_PROPLUS) /* ProPlus drive_user context extensions */
|
||
#if (INCLUDE_DEBUG_TEST_CODE)
|
||
IO_RUNTIME_STATS iostats;
|
||
#endif
|
||
#endif /* ProPlus drive_state extensions */
|
||
} DRIVEUSERCONTEXT;
|
||
|
||
typedef struct rtfsfmtparmsex {
|
||
BOOLEAN scrub_volume; /* If true erase or zero the section of media to contain the volume formatting */
|
||
/* Fixed format parameters. If bits_per_cluster is set to a non-zero value then numroot, numfats, and secpalloc must
|
||
also be provided. Rtfs will not calculate these parameters and instead use these values. Rtfs does not check the values
|
||
for correctness, porper values must be provided */
|
||
unsigned char bits_per_cluster; /* 12, 16, 32 == FAT12, FAT16, FAT32 */
|
||
unsigned short numroot; /* # of root dir entries (normally 512 for FAT12, FAT16, must be 0 for FAT32*/
|
||
unsigned char numfats; /* Number of FATS on the disk, Must be 2 if using Failsafe */
|
||
unsigned char secpalloc; /* Sectors per cluster */
|
||
unsigned short secreserved; /* # of root reserved sectors. usually 32 for FAT32, 1 for not FAT32 */
|
||
|
||
} RTFSFMTPARMSEX;
|
||
|
||
|
||
/* Parameter block for formatting: Used by format.c */
|
||
typedef struct fmtparms {
|
||
unsigned char oemname[9]; /* Only first 8 bytes are used */
|
||
unsigned char secpalloc; /* Sectors per cluster */
|
||
unsigned short secreserved; /* Reserved sectors before the FAT */
|
||
unsigned char nibs_per_entry; /* 3, 4, 8 == FAT12, FAT16, FAT32 */
|
||
unsigned char numfats; /* Number of FATS on the disk */
|
||
dword secpfat; /* Sectors per fat */
|
||
dword numhide; /* Hidden sectors */
|
||
unsigned short numroot; /* Maximum # of root dir entries */
|
||
unsigned char mediadesc; /* Media descriptor byte */
|
||
unsigned short secptrk; /* sectors per track */
|
||
unsigned short numhead; /* number of heads */
|
||
unsigned short numcyl; /* number of cylinders */
|
||
dword total_sectors; /* Total number of sectors (secptrk*numhead*numcyl) before any truncation */
|
||
unsigned char physical_drive_no;
|
||
dword binary_volume_label;
|
||
unsigned char text_volume_label[12];
|
||
unsigned char file_sys_type[12];
|
||
unsigned long bytes_per_sector;
|
||
/* Additional extended format parameters */
|
||
BOOLEAN scrub_volume; /* If true erase or zero the media before formatting */
|
||
unsigned char fixed_bits_per_cluster; /* 12, 16, 32 == FAT12, FAT16, FAT32 */
|
||
unsigned short fixed_numroot; /* Maximum # of root dir entries */
|
||
unsigned char fixed_numfats; /* Number of FATS on the disk */
|
||
unsigned char fixed_secpalloc; /* Sectors per cluster */
|
||
unsigned short fixed_secreserved; /* Reserved sectors before the FAT */
|
||
} FMTPARMS;
|
||
|
||
struct mbr_entry_specification {
|
||
dword partition_start;
|
||
dword partition_size;
|
||
byte partition_type;
|
||
byte partition_boot; /* 0x80 for bootable */
|
||
};
|
||
struct mbr_specification {
|
||
int device_mbr_count;
|
||
dword mbr_sector_location;
|
||
struct mbr_entry_specification entry_specifications[4];
|
||
};
|
||
|
||
|
||
/* Structure passed to BLK_DEV_volume_mount_parms, to retrieve mount instructions and buffers */
|
||
typedef struct rtfsdevi_volume_mount_parms
|
||
{
|
||
BOOLEAN dynamically_allocated;
|
||
|
||
dword drive_operating_policy; /* drive operating policy, see Rtfs manual */
|
||
dword n_sector_buffers; /* Total number of sector sized buffers (used for director buffers and scratch sectors */
|
||
dword n_fat_buffers; /* Total number of FAT buffers */
|
||
dword fat_buffer_page_size_sectors; /* Number of sectors per FAT buffer */
|
||
|
||
dword n_file_buffers; /* Total number of file buffers */
|
||
dword file_buffer_size_sectors; /* file buffer size in sectors */
|
||
|
||
|
||
/* Memory returned values */
|
||
/* Note: Rtfs never references blkbuff_memory or fatbuff_memory, they are provided for the bllk_dev layer so it
|
||
may allocate and release multiple control structures in single calls */
|
||
void *blkbuff_memory; /* 1 element must be sizeof(BLKBUFF)(sizeof(BLKBUFF)=40) * (n_sector_buffers) bytes wide */
|
||
void *filebuff_memory; /* 1 element must be sizeof(BLKBUFF)(sizeof(BLKBUFF)=40) * (n_file_buffers) bytes wide */
|
||
void *fatbuff_memory; /* 1 element must be sizeof(FATBUFF)(sizeof(FATBUFF)=40) * n_fat_buffers) bytes wide */
|
||
|
||
byte *sector_buffer_base; /* Unaligned sector buffer heap, returns from malloc */
|
||
byte *file_buffer_base; /* Unaligned file buffer heap, returns from malloc */
|
||
byte *fat_buffer_base; /* Unaligned fat buffer heap, returns from malloc */
|
||
|
||
|
||
void *sector_buffer_memory; /* n_sector_buffers elements (must be a linked list, each element sector_size bytes wide */
|
||
void *file_buffer_memory; /* n_file_buffers elements (must be a linked list, each element file_buffer_size_sectors * sector_size bytes wide */
|
||
void *fat_buffer_memory; /* n_fat_buffers elements (must be a linked list, each element fat_buffer_page_size_sectors * sector_size bytes wide */
|
||
|
||
#if (INCLUDE_FAILSAFE_CODE)
|
||
dword fsrestore_buffer_size_sectors;/* Failsafe restore buffer size in sectors */
|
||
dword fsjournal_n_blockmaps; /* number of Failsafe sector remap records provided.
|
||
Determines the number of outstanding remapped sectors permitted */
|
||
dword fsindex_buffer_size_sectors; /* Failsafe index buffer size in sectors */
|
||
void *fsfailsafe_context_memory; /* Failsafe context block */
|
||
void *fsrestore_buffer_memory; /* 1 element must be (fsrestore_buffer_size_sectors * sector_size) bytes */
|
||
void *fsjournal_blockmap_memory; /* 1 element must be (fsjournal_n_blockmaps * sizeof(FSBLOCKMAP)) bytes. sizeof(FSBLOCKMAP) equals 16 */
|
||
void *fsindex_buffer_memory; /* 1 element must be sector_size bytes */
|
||
byte *failsafe_buffer_base;
|
||
byte *failsafe_indexbuffer_base;
|
||
#endif
|
||
|
||
} RTFS_DEVI_VOLUME_MOUNT_PARMS;
|
||
|
||
|
||
/* Structure passed from the blk_dev layer to RTFS_DEVI_device_mount() when new media comes on line */
|
||
typedef struct rtfs_devi_media_parms
|
||
{
|
||
void *devhandle; /* Handle Rtfs will pass to device_io() and other functions. devhandle is opaque to rtfs */
|
||
#define DEVICE_REMOVE_EVENT 0x01
|
||
dword mount_flags;
|
||
dword access_semaphore; /* Access semaphore for the device. */
|
||
dword media_size_sectors; /* Total number of addressable sectors on the media */
|
||
dword numheads; /* cylinder, head, sector representation of the media. */
|
||
dword numcyl; /* Note: must be valid FAT HCN values. max cyl = 1023, max heads == 255, max sectors = 63 */
|
||
dword secptrk;
|
||
dword sector_size_bytes; /* Sector size in bytes: 512, 2048, etc */
|
||
dword eraseblock_size_sectors; /* Sectors per erase block. Set to zero for media without erase blocks */
|
||
int is_write_protect; /* Set to one if the media is write protected */
|
||
byte *device_sector_buffer_base;
|
||
void *device_sector_buffer;
|
||
dword device_sector_buffer_size;
|
||
|
||
int unit_number; /* which instance of this device */
|
||
int device_type; /* Used by blk dev driver layer. device mount sets it, volume mount may use it to configure buffering */
|
||
|
||
int (*device_io)(void *devhandle, void * pdrive, dword sector, void *buffer, dword count, BOOLEAN reading);
|
||
int (*device_erase)(void *devhandle, void *pdrive, dword start_sector, dword nsectors);
|
||
int (*device_ioctl)(void *devhandle, void *pdrive, int opcode, int iArgs, void *vargs);
|
||
int (*device_configure_media)(struct rtfs_media_insert_args *pmedia_parms, struct rtfs_media_resource_reply *media_config_block, int sector_buffer_required);
|
||
int (*device_configure_volume)(struct rtfs_volume_resource_request *prequest_block, struct rtfs_volume_resource_reply *preply_block);
|
||
} RTFS_DEVI_MEDIA_PARMS;
|
||
|
||
/* A placeholder vector must be provided by the device driver if it registers a function to poll for device changes. */
|
||
typedef struct rtfs_devi_poll_request_vector {
|
||
struct rtfs_devi_poll_request_vector *pnext;
|
||
void (*poll_device_ready)(void);
|
||
} RTFS_DEVI_POLL_REQUEST_VECTOR;
|
||
|
||
|
||
typedef struct ddrive {
|
||
struct ddrive *pnext_free; /* Free list */
|
||
int drive_opencounter; /* Value of global opencounter when we mounted */
|
||
int driveno; /* Driveno. Set when open succeeds */
|
||
DDRIVE_INFO drive_info;
|
||
DDRIVE_STATE drive_state;
|
||
#if (INCLUDE_DEBUG_RUNTIME_STATS)
|
||
DRIVE_RUNTIME_STATS drive_rtstats;
|
||
#endif
|
||
/* These buffers are used for parsing arguments to API calls.
|
||
they are large, so rather then use the stack we allocate
|
||
scratch buffers for the duration of the API call that needs then */
|
||
byte *pathname_buffer;
|
||
byte *filename_buffer;
|
||
BLKBUFF *pathname_blkbuff;
|
||
BLKBUFF *filename_blkbuff;
|
||
|
||
/* Beyond this is initialized at run time and must not be cleared by ertfs */
|
||
DRIVEUSERCONTEXT du;
|
||
|
||
FATBUFFCNTXT fatcontext; /* Controls fat cache */
|
||
|
||
/*
|
||
DRIVE_FLAGS_PARTITIONED YES. Used but set unconditionally. could be eliminated.
|
||
DRIVE_FLAGS_PCMCIA ONLY In PCMCIA segments which are disabled.
|
||
DRIVE_FLAGS_PCMCIA_ATA Not used
|
||
DRIVE_FLAGS_FAILSAFE Not used
|
||
DRIVE_FLAGS_VALID YES - Usage between device dirivers and common code is different. should be 2.
|
||
DRIVE_FLAGS_REMOVABLE Not used by v1.1 core code. needs to be removed where it is sert. used by 1.0 drivers
|
||
DRIVE_FLAGS_INSERTED Not used by v1.1 core code. needs to be removed where it is sert. used by 1.0 drivers
|
||
DRIVE_FLAGS_FORMAT Not used by v1.1 core code. Used by 1.0 drivers.
|
||
DRIVE_FLAGS_CDFS Only used in IDE driver should remove
|
||
DRIVE_FLAGS_RDONLY Not used
|
||
DRIVE_FLAGS_FILEIO Used
|
||
*/
|
||
|
||
/* user init is required for the following elements required */
|
||
/* Flags - These must be set by the pc_ertfs_init */
|
||
#define DRIVE_FLAGS_PARTITIONED 0x0002 /* Partitioned device */
|
||
#define DRIVE_FLAGS_PCMCIA 0x0004 /* Pcmcia device */
|
||
#define DRIVE_FLAGS_PCMCIA_ATA 0x0008
|
||
#define DRIVE_FLAGS_FAILSAFE 0x0800 /* Automatically initialize Pro Only
|
||
failsafe operations for
|
||
the device. */
|
||
/* Flags - These must be set by the warmstrt IOCTL call to the driver */
|
||
/* VALID is set by the device driver as a result of a successful call to
|
||
the device ioctl call DEVCTL_WARMSTART. If the driver does not set this
|
||
flag then it i assumed that the driver probe or init sequence failed */
|
||
#define DRIVE_FLAGS_VALID 0x0001 /* Flags have been set */
|
||
#define DRIVE_FLAGS_REMOVABLE 0x0040 /* Device is removable */
|
||
#define DRIVE_FLAGS_INSERTED 0x0080 /* Device drivers use to
|
||
remember states */
|
||
#define DRIVE_FLAGS_FORMAT 0x0100 /* If set by the driver then
|
||
rtfs_init must format
|
||
the device before it
|
||
is usable. */
|
||
#define DRIVE_FLAGS_CDFS 0x0200
|
||
#define DRIVE_FLAGS_RDONLY 0x0400 /* Device is read only */
|
||
#define DRIVE_FLAGS_FILEIO 0x0020 /* Set by RTFS when the current
|
||
block transfer is file io */
|
||
/* only used by the driver */
|
||
dword drive_flags; /* Note: the upper byte is reserved
|
||
for private use by device drivers */
|
||
/* Note: look for redundancy in mount parms and legacy methods */
|
||
RTFS_DEVI_MEDIA_PARMS *pmedia_info; /* Each mount drive structure on a devices points to media info provided by the blk device driver */
|
||
RTFS_DEVI_VOLUME_MOUNT_PARMS mount_parms;
|
||
BLKBUFFCNTXT _buffctxt;
|
||
BLKBUFF *file_buffer_freelist;
|
||
dword dyn_partition_base;
|
||
dword dyn_partition_size;
|
||
byte dyn_partition_type;
|
||
int controller_number;
|
||
int logical_unit_number;
|
||
int partition_number;
|
||
#if (INCLUDE_EXFAT) /* Include eXfat drive extension in drive structure */
|
||
EXFATDDRIVE exfatextension;
|
||
#endif
|
||
|
||
#if (INCLUDE_V_1_0_DEVICES == 1)
|
||
int pcmcia_slot_number;
|
||
int pcmcia_controller_number;
|
||
byte pcmcia_cfg_opt_value;
|
||
dword register_file_address;
|
||
int interrupt_number; /* note -1 is polled for IDE */
|
||
/* These two routines are attached to device driver specific routines */
|
||
BOOLEAN (*dev_table_drive_io)(int driveno, dword sector, void *buffer, word count, BOOLEAN readin);
|
||
int (*dev_table_perform_device_ioctl)(int driveno, int opcode, void * arg);
|
||
#endif
|
||
} DDRIVE;
|
||
|
||
/* Drive configure options for ProPlus */
|
||
#define DRVPOL_DISABLE_AUTOFLUSH 0x01
|
||
#define DRVPOL_DISABLE_AUTOFAILSAFE 0x02
|
||
#define DRVPOL_DISABLE_FREEMANAGER 0x04
|
||
#define DRVPOL_ASYNC_FATFLUSH 0x08
|
||
#define DRVPOL_ASYNC_JOURNALFLUSH 0x10
|
||
#define DRVPOL_ASYNC_RESTORE 0x20
|
||
#define DRVPOL_NAND_SPACE_OPTIMIZE 0x40
|
||
#define DRVPOL_NAND_SPACE_RECOVER 0x80
|
||
#define DRVPOL_DISABLE_AUTOMOUNT 0x100 /* Used for testing. If it is set the automount feature is disabled and the application layer performs the mount */
|
||
|
||
|
||
#define DRVPOL_ALL_VALID_PRO_OPTIONS (DRVPOL_DISABLE_FREEMANAGER|DRVPOL_NAND_SPACE_OPTIMIZE|DRVPOL_NAND_SPACE_RECOVER|DRVPOL_DISABLE_AUTOMOUNT|DRVPOL_DISABLE_AUTOFAILSAFE)
|
||
|
||
#if (INCLUDE_RTFS_PROPLUS)
|
||
/* ProPlus support all options */
|
||
#define DRVPOL_ALL_VALID_USER_OPTIONS (DRVPOL_ALL_VALID_PRO_OPTIONS|DRVPOL_DISABLE_AUTOFLUSH|DRVPOL_ASYNC_FATFLUSH|DRVPOL_ASYNC_JOURNALFLUSH|DRVPOL_ASYNC_RESTORE)
|
||
#else
|
||
/* No drive options supported basic */
|
||
#define DRVPOL_ALL_VALID_USER_OPTIONS DRVPOL_ALL_VALID_PRO_OPTIONS
|
||
#endif
|
||
|
||
|
||
/* Object used to find a dirent on a disk and its parent's */
|
||
typedef struct drobj {
|
||
struct ddrive *pdrive;
|
||
struct finode *finode;
|
||
DIRBLK blkinfo;
|
||
BOOLEAN isroot; /* True if this is the root */
|
||
BOOLEAN is_free; /* True if on the free list */
|
||
BLKBUFF *pblkbuff;
|
||
} DROBJ;
|
||
/* Internal file representation */
|
||
|
||
/* RTFS Pro Internal file representation, included in PC_FILE structure
|
||
If ProPlus is enabled an additional structure is included */
|
||
typedef union pc_file_basic {
|
||
dword file_pointer; /* Current file pointer */
|
||
#if (INCLUDE_MATH64) /* ddword type, ProPlus only */
|
||
ddword file_pointer64; /* Current file pointer */
|
||
#endif
|
||
} PC_FILE_BASIC;
|
||
|
||
union file_control {
|
||
PC_FILE_BASIC basic;
|
||
#if (INCLUDE_RTFS_PROPLUS) /* ProPlus file structure extensions */
|
||
PC_FILE_PROPLUS plus;
|
||
#endif
|
||
};
|
||
|
||
typedef struct pc_file {
|
||
BOOLEAN is_free; /* If TRUE this FILE may be used (see pc_memry.c) */
|
||
int my_fd; /* Accessed through this file descriptor */
|
||
DROBJ * pobj; /* Info for getting at the inode */
|
||
word flag; /* Acces flags from po_open(). */
|
||
union file_control fc;
|
||
} PC_FILE;
|
||
|
||
|
||
/* INTERNAL !! */
|
||
/* Structure to contain block 0 image from the disk */
|
||
struct pcblk0 {
|
||
byte jump; /* Should be E9 or EB on formatted disk */
|
||
int fasize; /* Nibbles per fat entry if determined from bpb. (3,4 or 8) 0 if could not be determined */
|
||
byte oemname[9];
|
||
word bytspsector; /* Must be 512 for this implementation */
|
||
byte secpalloc; /* Sectors per cluster */
|
||
word secreserved; /* Reserved sectors before the FAT */
|
||
byte numfats; /* Number of FATS on the disk */
|
||
word numroot; /* Maximum # of root dir entries */
|
||
word numsecs; /* Total # sectors on the disk */
|
||
byte mediadesc; /* Media descriptor byte */
|
||
word secpfat; /* Size of each fat */
|
||
word secptrk; /* sectors per track */
|
||
word numhead; /* number of heads */
|
||
word numhide; /* # hidden sectors High word if DOS4 */
|
||
word numhide2; /* # hidden sectors Low word if DOS 4 */
|
||
dword numsecs2; /* # secs if numhid+numsec > 32M (4.0) */
|
||
dword secpfat2; /* Size of FAT in sectors (fat32 only) */
|
||
byte physdrv; /* Physical Drive No. (4.0) */
|
||
byte xtbootsig; /* Extended signt 29H if 4.0 stuf valid */
|
||
dword volid; /* Unique number per volume (4.0) */
|
||
byte vollabel[11]; /* Volume label (4.0) */
|
||
word flags; /* Defined below (fat32 only) */
|
||
#define NOFATMIRROR 0x0080
|
||
#define ACTIVEFAT 0x000F
|
||
word fs_version; /* Version of fat32 used (fat32 only) */
|
||
dword rootbegin; /* Location of 1st cluster in root dir(fat32 only) */
|
||
word infosec; /* Location of information sector (fat32 only) */
|
||
word backup; /* Location of backup boot sector (fat32 only) */
|
||
dword free_alloc; /* Free clusters on drive (-1 if unknown) (fat32 only) */
|
||
dword next_alloc; /* Most recently allocated cluster (fat32 only) */
|
||
};
|
||
|
||
#define CS_CHARSET_NOT_UNICODE 0
|
||
#define CS_CHARSET_UNICODE 1
|
||
#define WHICH_CHARSET CS_CHARSET_NOT_UNICODE
|
||
|
||
#define CS_OP_CP_CHR(TO,FR,CS) rtfs_cs_char_copy((TO),(FR), CS)
|
||
#define CS_OP_INC_PTR(P,CS) P = rtfs_cs_increment((P), CS)
|
||
#define CS_OP_CMP_CHAR(P1, P2,CS) rtfs_cs_compare((P1), (P2), CS)
|
||
#define CS_OP_CMP_CHAR_NC(P1, P2,CS) rtfs_cs_compare_nc((P1), (P2), CS)
|
||
#define CS_OP_ASCII_INDEX(P,C,CS) rtfs_cs_ascii_index(P,C, CS)
|
||
#define CS_OP_TO_LFN(TO, FROM,CS) rtfs_cs_to_unicode(TO, FROM, CS)
|
||
#define CS_OP_LFI_TO_TXT(TO, FROM,CS) rtfs_cs_unicode_to_cs(TO, FROM, CS)
|
||
#define CS_OP_IS_EOS(P,CS) rtfs_cs_is_eos(P, CS)
|
||
#define CS_OP_IS_NOT_EOS(P,CS) rtfs_cs_is_not_eos(P, CS)
|
||
#define CS_OP_TERM_STRING(P,CS) rtfs_cs_term_string(P, CS)
|
||
#define CS_OP_CMP_ASCII(P,C,CS) rtfs_cs_cmp_to_ascii_char((P),C,CS)
|
||
#define CS_OP_ASSIGN_ASCII(P,C,CS) rtfs_cs_assign_ascii_char((P),C,CS)
|
||
#define CS_OP_GOTO_EOS(P,CS) rtfs_cs_goto_eos((P),CS)
|
||
|
||
/* If mask specifies forcing asci characters to lower case or in 0x20 to ascii letter to force lower case */
|
||
#define CS_APPLY_NT_CASEMASK(MASK,C) (MASK && (C >= 'A') && (C <= 'Z'))?C|0x20:C
|
||
|
||
/* Make sure memory is initted prolog for api functions */
|
||
#define CHECK_MEM(TYPE, RET) if (!prtfs_cfg) {return((TYPE) RET);}
|
||
#define VOID_CHECK_MEM() if (!prtfs_cfg) {return;}
|
||
#define IS_AVOLORDIR(X) ((X->isroot) || (X->finode->fattribute & AVOLUME|ADIRENT))
|
||
|
||
/* Extra arguments to pc_get_inode() and pc_findin() */
|
||
#define GET_INODE_MATCH 0 /* Must match the pattern exactly */
|
||
#define GET_INODE_WILD 1 /* Pattern may contain wild cards */
|
||
#define GET_INODE_STAR 2 /* Like he passed *.* (pattern will be null) */
|
||
#define GET_INODE_DOTDOT 3 /* Like he past .. (pattern will be null */
|
||
|
||
#define FATPAGEREAD 0x00000001ul
|
||
#define FATPAGEWRITE 0x80000000ul
|
||
// HEREHERE - reduceme and clear current drive for all users if ejected
|
||
/* User structure management */
|
||
typedef struct rtfs_system_user
|
||
{
|
||
dword task_handle; /* Task this is for */
|
||
int rtfs_errno; /* current errno value for the task */
|
||
#if (INCLUDE_DEBUG_VERBOSE_ERRNO)
|
||
char *rtfs_errno_caller; /* If diagnostics enabled File name */
|
||
long rtfs_errno_line_number; /* If diagnostics enabled File line number */
|
||
#endif
|
||
|
||
int dfltdrv; /* Default drive to use if no drive specified 1-26 == a-z */
|
||
void * plcwd; /* current working directory, allocated at init time to hold NDRIVES pointers */
|
||
#if (INCLUDE_EXFATORFAT64) /* ExFat cwd strings per drive (13 K) */
|
||
word cwd_string[26][EMAXPATH_CHARS];
|
||
#endif
|
||
} RTFS_SYSTEM_USER;
|
||
|
||
typedef struct rtfs_system_user *PRTFS_SYSTEM_USER;
|
||
|
||
|
||
#define ARDONLY 0x1 /* MS-DOS File attributes */
|
||
#define AHIDDEN 0x2
|
||
#define ASYSTEM 0x4
|
||
#define AVOLUME 0x8
|
||
#define ADIRENT 0x10
|
||
#define ARCHIVE 0x20
|
||
#define ANORMAL 0x00
|
||
#define CHICAGO_EXT 0x0f /* Chicago extended filename attribute */
|
||
|
||
/* Information buffer for pc_get_dirent_info and pc_set_dirent_info */
|
||
typedef struct dirent_info {
|
||
byte fattribute;
|
||
dword fcluster;
|
||
word ftime;
|
||
word fdate;
|
||
dword fsize;
|
||
#if (INCLUDE_EXFATORFAT64)
|
||
ddword fsize64;
|
||
#endif
|
||
dword my_block;
|
||
int my_index;
|
||
} DIRENT_INFO;
|
||
|
||
/* Structure for use by pc_gfirst, pc_gnext */
|
||
typedef struct dstat {
|
||
unsigned char fname[10]; /* Null terminated file and extension only 9 bytes used */
|
||
unsigned char fext[4];
|
||
#if (INCLUDE_VFAT)
|
||
unsigned char lfname[FILENAMESIZE_BYTES]; /* Long file name for vfat. */
|
||
#else
|
||
unsigned char lfname[14]; /* Long file name non-vfat. */
|
||
#endif
|
||
unsigned char filename[14]; /* Null terminated file.ext only 13 bytes used */
|
||
unsigned char fattribute; /* File attributes */
|
||
unsigned short ftime; /* time & date lastmodified. See date */
|
||
unsigned short fdate; /* and time handlers for getting info */
|
||
unsigned short ctime; /* time & date created */
|
||
unsigned short cdate;
|
||
unsigned short atime; /* time & date accessed */
|
||
unsigned short adate; /* Date last accessed */
|
||
dword fsize; /* File size */
|
||
dword fsize_hi; /* File size hi if exFat file */
|
||
/* INTERNAL */
|
||
int driveno;
|
||
int drive_opencounter; /* Value of drive structures opencounter */
|
||
unsigned char pname[FILENAMESIZE_BYTES];
|
||
unsigned char pext[4];
|
||
unsigned char path[EMAXPATH_BYTES];
|
||
dword my_block; /* used by pc_gread() to acces the directory entry */
|
||
int my_index;
|
||
void *pobj; /* Info for getting at the inode */
|
||
void *pmom; /* Info for getting at parent inode */
|
||
#define SEARCH_BACKWARDS_MAGIC_NUMBER 0x12214343
|
||
#define SYS_SCAN_MAGIC_NUMBER 0x43432121
|
||
dword search_backwards_if_magic;
|
||
}
|
||
DSTAT;
|
||
|
||
/* Structure for use by pc_stat and pc_fstat */
|
||
/* Portions of this structure and the macros were lifted from BSD sources.
|
||
See the RTFS ANSI library for BSD terms & conditions */
|
||
typedef struct ertfs_stat
|
||
{
|
||
int st_dev; /* (drive number, rtfs) */
|
||
int st_ino; /* inode number (0) */
|
||
dword st_mode; /* (see S_xxxx below) */
|
||
int st_nlink; /* (always 1) */
|
||
int st_rdev; /* (drive number, rtfs) */
|
||
dword st_size; /* file size, in bytes */
|
||
#ifdef st_atime
|
||
#undef st_atime
|
||
#undef st_mtime
|
||
#undef st_ctime
|
||
#endif
|
||
DATESTR st_atime; /* last access (all times are the same) */
|
||
DATESTR st_mtime; /* last modification */
|
||
DATESTR st_ctime; /* last file status change */
|
||
dword st_blksize; /* optimal blocksize for I/O (cluster size) */
|
||
dword st_blocks; /* blocks allocated for file */
|
||
unsigned char fattribute; /* File attributes - DOS attributes
|
||
(non standard but useful) */
|
||
dword st_size_hi; /* File size hi always zero for Pro*/
|
||
} ERTFS_STAT;
|
||
|
||
|
||
/* Internal masks to dictate which date fileds to be update when a directory entry is written */
|
||
#define DATESETCREATE 1
|
||
#define DATESETUPDATE 2
|
||
#define DATESETACCESS 4
|
||
|
||
typedef struct chkdisk_stats {
|
||
dword n_sectors_total; /* Total sectors occupied by the volume */
|
||
dword n_clusters_total; /* Total clusters in the voume */
|
||
dword n_sectorspercluster; /* Number of sectors pper cluster */
|
||
dword n_reservedrootsectors; /* Number or sectors reserved for the root directory (0 for FAT32) */
|
||
dword n_bytespersector; /* Bytes per sector */
|
||
dword n_user_files; /* Total #user files found */
|
||
dword n_hidden_files; /* Total #hidden files found */
|
||
dword n_user_directories; /* Total #directories found */
|
||
dword n_free_clusters; /* # free available clusters */
|
||
dword n_bad_clusters; /* # clusters marked bad */
|
||
dword n_file_clusters; /* Clusters in non hidden files */
|
||
dword n_hidden_clusters; /* Clusters in hidden files */
|
||
dword n_dir_clusters; /* Clusters in directories */
|
||
BOOLEAN has_errors; /* Set to TRUE by check disk if it detected any errors. (set if any of the following 8 errors are reported) */
|
||
BOOLEAN has_endless_loop; /* Set to TRUE by check disk if it stopped because it detected and endless loop */
|
||
dword n_crossed_chains; /* Number of crossed chains. */
|
||
dword n_lost_chains; /* # lost chains */
|
||
dword n_lost_clusters; /* # lost clusters */
|
||
dword n_unterminated_chains; /* # of chains that were not terminated */
|
||
dword n_badcluster_values; /* # of invalid cluster values found in chains */
|
||
dword n_bad_dirents; /* # of directory entries containing bad cluster values or cluster values pointing to a free clusters */
|
||
dword n_bad_lfns; /* # corrupt/disjoint win95 lfn chains */
|
||
dword n_directories_removed; /* # of subdirectories removed because of invalid contents */
|
||
dword n_files_removed; /* # of files removed because of invalid contents */
|
||
dword n_clusters_freed; /* # of clusters free, includes lost clusters and any clusters freed when files or subdirectories where removed */
|
||
dword n_checkfiles_created; /* # of check files created from lost cluster chains */
|
||
dword n_directory_scans; /* # of times the directory tree was traversed */
|
||
} CHKDISK_STATS;
|
||
|
||
/************************************************************************
|
||
*
|
||
* CHKDSK data structure
|
||
*
|
||
* pc_check_disk_ex requires a context block to store information it acquires as it scans the volume.
|
||
*
|
||
* The caller must pass the address of a CHKDSK_CONTEXT structure to pc_check_disk_ex. pc_check_disk_ex will zero the data structure
|
||
* and the use it.
|
||
* If pc_check_disk_ex succeeds, this structure may then be passed to print_chkdsk_statistics()
|
||
************************************************************************/
|
||
#define CHKDSK_VERBOSE 0x01
|
||
#define CHKDSK_FIXPROBLEMS 0x02
|
||
#define CHKDSK_FREELOSTCLUSTERS 0x08
|
||
#define CHKDSK_FREEFILESWITHERRORS 0x10
|
||
#define CHKDSK_FREESUBDIRSWITHERRORS 0x20
|
||
|
||
typedef struct chkdsk_context {
|
||
dword chkdsk_opmode;
|
||
DDRIVE *drive_structure; /* The drive we are working on */
|
||
BOOLEAN has_endless_loop; /* If 1 and endless loop in a cluster chain was detected, call again with fix_problems to clear */
|
||
CHKDISK_STATS *pstats;
|
||
/* State machine logic controls rescanning options to identify directory objects with crossed cluster chains */
|
||
#define SC_STATE_PERFORM_SCAN 0
|
||
#define SC_STATE_REQUEST_RESCAN_FOR_CROSSED_CHAIN 1
|
||
#define SC_STATE_PERFORM_RESCAN_FOR_CROSSED_CHAIN 2
|
||
#define SC_STATE_FOUND_RESCAN_CROSSED_CHAIN 3
|
||
int scan_state;
|
||
dword crossed_cluster;
|
||
DROBJ *scan_crossed_drobj;
|
||
DROBJ *rescan_crossed_drobj;
|
||
void *scratch_memory; /* User supplied memory, optional for version 6 */
|
||
void *scratch_segment_heap; /* User supplied memory, threaded into a free list */
|
||
void *lost_chain_list; /* Type is actually REGION_FRAGMENT * */
|
||
void *used_segment_list; /* Type is actually REGION_FRAGMENT * */
|
||
|
||
/* Use a global buffer so we do not load the stack up during recursion */
|
||
byte gl_file_name[26];
|
||
byte gl_file_path[EMAXPATH_BYTES];
|
||
int recursion_depth; /* how deep in the stack we are */
|
||
dword current_file_no; /* Used to build check files in multiple passes */
|
||
dword n_bad_lfns; /* # corrupt/disjoint win95 lfn chains */
|
||
|
||
/* These fields bound the cluster map processing so we can process
|
||
disks with very large FATs by making multiple passes */
|
||
dword cl_start;
|
||
dword cl_end;
|
||
int on_which_pass;
|
||
} CHKDSK_CONTEXT;
|
||
|
||
/* Values for the st_mode field */
|
||
#define S_IFMT 0170000 /* type of file mask */
|
||
#define S_IFCHR 0020000 /* character special (unused) */
|
||
#define S_IFDIR 0040000 /* directory */
|
||
#define S_IFBLK 0060000 /* block special (unused) */
|
||
#define S_IFREG 0100000 /* regular */
|
||
#define S_IREAD 0000400 /* Read permitted. (Always true anyway)*/
|
||
#define S_IWRITE 0000200 /* Write permitted */
|
||
|
||
#define DEFFILEMODE (S_IREAD|S_IWRITE)
|
||
#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */
|
||
#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */
|
||
#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */
|
||
#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */
|
||
#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */
|
||
|
||
/* File creation permissions for open */
|
||
/* Note: OCTAL */
|
||
#define PS_IREAD 0000400 /* Read permitted. (Always true anyway)*/
|
||
#define PS_IWRITE 0000200 /* Write permitted */
|
||
|
||
|
||
/* File access flags */
|
||
#define PO_RDONLY 0x0000 /* Open for read only*/
|
||
#define PO_WRONLY 0x0001 /* Open for write only*/
|
||
#define PO_RDWR 0x0002 /* Read/write access allowed.*/
|
||
#define PO_APPEND 0x0008 /* Seek to eof on each write*/
|
||
#define PO_BUFFERED 0x0010 /* Non-Block alligned File IO is buffered */
|
||
#define PO_AFLUSH 0x0020 /* Auto-Flush. File is flushed automatically
|
||
each time po_write changes the size */
|
||
#define PO_CREAT 0x0100 /* Create the file if it does not exist.*/
|
||
#define PO_TRUNC 0x0200 /* Truncate the file if it already exists*/
|
||
#define PO_EXCL 0x0400 /* Fail if creating and already exists*/
|
||
#define PO_TEXT 0x4000 /* Ignored*/
|
||
#define PO_BINARY 0x8000 /* Ignored. All file access is binary*/
|
||
#define PO_NOSHAREANY 0x0004 /* Wants this open to fail if already open.
|
||
Other opens will fail while this open
|
||
is active */
|
||
#define PO_NOSHAREWRITE 0x0800 /* Wants this opens to fail if already open
|
||
for write. Other open for write calls
|
||
will fail while this open is active. */
|
||
|
||
/* Arguments to both po_lcseek and pc_efilio_lseek */
|
||
#define PSEEK_SET 0 /* offset from begining of file*/
|
||
#define PSEEK_CUR 1 /* offset from current file pointer*/
|
||
#define PSEEK_END 2 /* offset from end of file*/
|
||
#define PSEEK_CUR_NEG 3 /* negative offset from end of file*/
|
||
|
||
#if (INCLUDE_RTFS_PROPLUS)
|
||
/* Arguments to both po_lcseek and pc_efilio_lseek - these values start above
|
||
the standard seek arguments */
|
||
#define PSEEK_SET_RAW (PSEEK_CUR_NEG+1) /* internal true offset from beginning of file */
|
||
/* Arguments available to pc_efilio_lseek only */
|
||
#define PSEEK_SET_CIRC (PSEEK_SET_RAW+1) /* offset from begining of file*/
|
||
#define PSEEK_CUR_CIRC (PSEEK_SET_RAW+2) /* offset from current file pointer*/
|
||
#define PSEEK_END_CIRC (PSEEK_SET_RAW+3) /* offset from end of file*/
|
||
#define PSEEK_CUR_NEG_CIRC (PSEEK_SET_RAW+4) /* pc_efilio_seek only: negative offset from current*/
|
||
#endif
|
||
|
||
|
||
/* Partition table descriptions. */
|
||
/* One disk partition table */
|
||
typedef struct ptable_entry {
|
||
byte boot;
|
||
byte s_head;
|
||
word s_cyl;
|
||
byte p_typ;
|
||
byte e_head;
|
||
word e_cyl;
|
||
dword r_sec; /* Relative sector of start of part */
|
||
dword p_size; /* Size of partition */
|
||
} PTABLE_ENTRY;
|
||
|
||
typedef struct ptable {
|
||
PTABLE_ENTRY ents[4];
|
||
word signature; /* should be 0xaa55 */
|
||
} PTABLE;
|
||
|
||
|
||
|
||
typedef struct dev_geometry {
|
||
int bytespsector; /* 0 or 512 for 512 byte sectors otherwise, 1024, 2048, 4096 etc */
|
||
int dev_geometry_heads; /*- Must be < 256 */
|
||
dword dev_geometry_cylinders; /*- Must be < 1024 */
|
||
int dev_geometry_secptrack; /*- Must be < 64 */
|
||
dword dev_geometry_lbas; /* For oversized media that supports logical */
|
||
/* block addressing. If this is non zero */
|
||
/* dev_geometry_cylinders is ignored */
|
||
/* but dev_geometry_heads and */
|
||
/* dev_geometry_secptrack must still be valid */
|
||
int fmt_parms_valid; /*If the device io control call sets this */
|
||
/*TRUE then it it telling the applications */
|
||
/*layer that these format parameters should */
|
||
/*be used. This is a way to format floppy */
|
||
/*disks exactly as they are formatted by dos. */
|
||
FMTPARMS fmt;
|
||
} DEV_GEOMETRY;
|
||
|
||
typedef struct dev_geometry *PDEV_GEOMETRY;
|
||
|
||
|
||
|
||
|
||
|
||
/* Terminal input/output macros.
|
||
* RTFS_PRINT_LONG_1
|
||
* RTFS_PRINT_STRING_1
|
||
* RTFS_PRINT_STRING_2
|
||
*
|
||
* These macros by default are defined as calls to functions in rtfsterm.c as seen here
|
||
*
|
||
* #define RTFS_PRINT_LONG_1(L1,FLAGS) rtfs_print_long_1(L1,FLAGS)
|
||
* #define RTFS_PRINT_STRING_1(STR1ID,FLAGS) rtfs_print_string_1(STR1ID,FLAGS)
|
||
* #define RTFS_PRINT_STRING_2(STR1ID,STR2,FLAGS) rtfs_print_string_2(STR1ID,STR2,FLAGS)
|
||
*
|
||
* If no console output available thy may be dfined as seen here
|
||
*
|
||
* #define RTFS_PRINT_LONG_1(L1,FLAGS)
|
||
* #define RTFS_PRINT_STRING_1(STR1ID,FLAGS)
|
||
* #define RTFS_PRINT_STRING_2(STR1ID,STR2,FLAGS)
|
||
*
|
||
*/
|
||
/* String printing control characters used throughout the library */
|
||
#define PRFLG_NL 0x0001 /* Newline Carriage return at end */
|
||
#define PRFLG_CR 0x0002 /* Carriage Return only at end */
|
||
/* Macros that are used to access the print routines */
|
||
#define RTFS_PRINT_LONG_1(L1,FLAGS) rtfs_print_long_1(L1,FLAGS)
|
||
#define RTFS_PRINT_STRING_1(STR1ID,FLAGS) rtfs_print_string_1(STR1ID,FLAGS)
|
||
#define RTFS_PRINT_STRING_2(STR1ID,STR2,FLAGS) rtfs_print_string_2(STR1ID,STR2,FLAGS)
|
||
/* These STUBBED versions may be used instead if output is not available */
|
||
/*
|
||
#define RTFS_PRINT_LONG_1(L1,FLAGS)
|
||
#define RTFS_PRINT_STRING_1(STR1ID,FLAGS)
|
||
#define RTFS_PRINT_STRING_2(STR1ID,STR2,FLAGS)
|
||
*/
|
||
|
||
|
||
#define MATCH_DIR 0x01
|
||
#define MATCH_VOL 0x02
|
||
#define MATCH_FILES 0x04
|
||
#define MATCH_DOT 0x08
|
||
#define MATCH_DOTDOT 0x10
|
||
#define MATCH_SYSSCAN 0x20 /* Internal*/
|
||
typedef int (*PENUMCALLBACK)(byte *path, DSTAT *pstat);
|
||
|
||
/* Flags to fatop routines */
|
||
#define FOP_RMTELL 0x01 /* Tell the regioon manager */
|
||
#define FOP_LINK 0x02 /* Link the fragment else null it */
|
||
#define FOP_LINK_PREV 0x04 /* Link the cluster argument to this fragment */
|
||
#define FOP_LINK_NEXT 0x08 /* Link this fragment to the cluster argument */
|
||
#define FOP_TERM_PREV 0x10 /* Terminat the cluster argument */
|
||
#define FOP_EXF_CHAIN 0x20 /* EXFAT ignores LINK TERM, but if this is set, do it */
|
||
|
||
/* File seg info structure. An array of these structures is passed
|
||
to pc_get_file_extents(). The extents of the file are returned
|
||
in this array */
|
||
typedef struct fileseginfo {
|
||
dword block; /* Block number of the current extent */
|
||
dword nblocks; /* Number of blocks in the extent */
|
||
} FILESEGINFO;
|
||
|
||
/* Free list info structure. An array of these structures is passed
|
||
to pc_get_free_list(). The list of free clusters is returned in
|
||
this array */
|
||
typedef struct freelistinfo {
|
||
dword cluster; /* Cluster where the free region starts */
|
||
dword nclusters; /* Number of free clusters the free segment */
|
||
} FREELISTINFO;
|
||
|
||
|
||
|
||
#define READ_PARTITION_ERR -1 /* Internal error (couldn't allocate buffers ?) */
|
||
#define READ_PARTITION_NO_TABLE -2 /* No partition table */
|
||
#define READ_PARTITION_IOERROR -3 /* Device IO error */
|
||
|
||
/* System wide critical region semaphore */
|
||
#define OS_CLAIM_FSCRITICAL() rtfs_port_claim_mutex(prtfs_cfg->critical_semaphore);
|
||
#define OS_RELEASE_FSCRITICAL() rtfs_port_release_mutex(prtfs_cfg->critical_semaphore);
|
||
#if (INCLUDE_EXFATORFAT64)
|
||
BOOLEAN pcexfat_rmnode(DROBJ *pobj);
|
||
BOOLEAN pcexfat_mvnode(DROBJ *old_parent_obj,DROBJ *old_obj,DROBJ *new_parent_obj, byte *filename,int use_charset);
|
||
BOOLEAN pcexfat_set_volume(DDRIVE *pdrive, byte *volume_label,int use_charset);
|
||
BOOLEAN pcexfat_get_volume(DDRIVE *pdrive, byte *volume_label,int use_charset);
|
||
BOOLEAN pcexfat_get_cwd(DDRIVE *pdrive, byte *path, int use_charset);
|
||
BOOLEAN pcexfat_set_cwd(DDRIVE *pdrive, byte *name, int use_charset);
|
||
BOOLEAN pcexfat_update_by_finode(FINODE *pfi, int entry_index, BOOLEAN set_archive, int set_date_mask, BOOLEAN do_delete);
|
||
BOOLEAN pcexfat_flush(DDRIVE *pdrive);
|
||
dword exfatop_find_contiguous_free_clusters(DDRIVE *pdr, dword startpt, dword endpt, dword min_clusters, dword max_clusters, dword *p_contig, int *is_error);
|
||
BOOLEAN rtexfat_i_dskopen(DDRIVE *pdr);
|
||
void pc_release_exfat_buffers(DDRIVE *pdr);
|
||
BOOLEAN pcexfat_findin( DROBJ *pobj, byte *filename, int action, BOOLEAN oneshot, int use_charset);
|
||
byte * pcexfat_seglist2text(DDRIVE * pdrive, SEGDESC *s, byte *lfn, int use_charset);
|
||
dword exFatfatop_getdir_frag(DROBJ *pobj, dword startpt, dword *pnext_cluster, dword n_clusters, int *end_of_chain);
|
||
dword exFatfatop_getfile_frag(FINODE *pfi, dword startpt, dword *pnext_cluster, dword n_clusters, int *end_of_chain);
|
||
BOOLEAN pcexfat_gread(DSTAT *statobj, int blocks_to_read, byte *buffer, int *blocks_read);
|
||
BOOLEAN pcexfat_parse_path(DDRIVE *pdrive, byte *outpath, byte *inpath, int use_charset);
|
||
BOOLEAN rtexfat_gblk0(DDRIVE *pdr, struct pcblk0 *pbl0b, byte *b);
|
||
DROBJ * pcexfat_get_root( DDRIVE *pdrive);
|
||
BOOLEAN pc_exfatrfindin( DROBJ *pobj, byte *filename, int action, int use_charset, BOOLEAN starting);
|
||
#endif
|
||
|
||
#if (INCLUDE_FAILSAFE_RUNTIME)
|
||
struct rtfs_failsafe_cfg {
|
||
BOOLEAN (*block_devio_read)(DDRIVE *pdrive, dword blockno, byte * buf);
|
||
BOOLEAN (*block_devio_write)(BLKBUFF *pblk);
|
||
BOOLEAN (*block_devio_xfer)(DDRIVE *pdrive, dword blockno, byte * buf, dword n_to_xfer, BOOLEAN reading);
|
||
BOOLEAN (*fat_devio_read)(DDRIVE *pdrive, dword sectorno,dword nsectors, byte *fat_data);
|
||
BOOLEAN (*fat_devio_write)(DDRIVE *pdrive, dword fat_blockno, dword nblocks, byte *fat_data, int fatnumber);
|
||
BOOLEAN (*fs_recover_free_clusters)(DDRIVE *pdrive, dword required_clusters);
|
||
BOOLEAN (*fs_failsafe_autocommit)(DDRIVE *pdr);
|
||
BOOLEAN (*fs_add_free_region)(DDRIVE *pdr, dword cluster, dword n_contig);
|
||
BOOLEAN (*fs_failsafe_dskopen)(DDRIVE *pdrive);
|
||
BOOLEAN (*fs_dynamic_mount_volume_check)(DDRIVE *pdr);
|
||
void (*fs_claim_buffers)(DDRIVE *pdr);
|
||
BOOLEAN (*fs_allocate_volume_buffers)(struct rtfs_volume_resource_reply *pvolume_config_block, dword sector_size_bytes);
|
||
void (*fs_free_disk_configuration)(DDRIVE *pdr);
|
||
BOOLEAN (*fs_dynamic_configure_volume)(DDRIVE *pdr, struct rtfs_volume_resource_reply *preply);
|
||
dword (*free_fallback_find_contiguous_free_clusters)(DDRIVE *pdr, dword startpt, dword endpt, dword min_clusters, dword max_clusters, dword *p_contig, int *is_error);
|
||
|
||
};
|
||
#endif
|
||
|
||
/* Configuration structure. Must be filled in by the user.
|
||
see rtfscfg.c */
|
||
typedef struct rtfs_cfg {
|
||
int dynamically_allocated;
|
||
/* Configuration values */
|
||
int cfg_NDRIVES; /* The number of drives to support */
|
||
int cfg_NBLKBUFFS; /* The number of block buffers */
|
||
int cfg_NUSERFILES; /* The number of user files */
|
||
int cfg_NDROBJS; /* The number of directory objects */
|
||
int cfg_NFINODES; /* The number of directory inodes */
|
||
int cfg_NUM_USERS; /* The number of users to support */
|
||
int cfg_NREGIONS; /* The number of region management objects to support */
|
||
dword region_buffers_free;
|
||
dword region_buffers_low_water;
|
||
#if (INCLUDE_RTFS_PROPLUS) /* config structure: ProPlus specific element*/
|
||
int cfg_NFINODES_UEX; /* The number of combined extended and extended 64 directory inodes */
|
||
#endif
|
||
/* Core that must be provided by the user */
|
||
struct ddrive *mem_drive_pool; /* Point at cfg_NDRIVES * sizeof(DDRIVE) bytes*/
|
||
RTFS_DEVI_MEDIA_PARMS *mem_mediaparms_pool; /* Point at cfg_NDRIVES * sizeof(RTFS_DEVI_MEDIA_PARMS) bytes*/
|
||
BLKBUFF *mem_block_pool; /* Point at cfg_NBLKBUFFS * sizeof(BLKBUFF) bytes*/
|
||
byte *mem_block_data; /* Point at NBLKBUFFS*RTFS_CFG_DEFAULT_BLOCK_SIZE bytes */
|
||
struct pc_file *mem_file_pool; /* Point at cfg_USERFILES * sizeof(PC_FILE) bytes*/
|
||
struct finode *mem_finode_pool; /* Point at cfg_NFINODE * sizeof(FINODE) bytes*/
|
||
DROBJ *mem_drobj_pool; /* Point at cfg_NDROBJ * sizeof(DROBJ) bytes*/
|
||
struct region_fragment *mem_region_pool; /* Point at cfg_NREGIONS * sizeof(REGION_FRAGMENT) bytes*/
|
||
RTFS_SYSTEM_USER *rtfs_user_table; /* Point at cfg_NUM_USERS * sizeof(RTFS_SYSTEM_USER) bytes*/
|
||
void ** rtfs_user_cwd_pointers; /* Point at cfg_NUM_USERS * cfg_NDRIVES * sizeof(void *) bytes*/
|
||
|
||
struct region_fragment *mem_region_freelist;
|
||
|
||
|
||
|
||
#if (INCLUDE_RTFS_PROPLUS) /* config structure: ProPlus specific element*/
|
||
FINODE_EXTENSION_MEMORY *mem_finode_uex_pool; /* Point at cfg_NFINODES_UEX * sizeof(FINODE_EXTENSION_MEMORY) bytes*/
|
||
FINODE_EXTENSION_MEMORY *mem_finode_uex_freelist;
|
||
#endif
|
||
|
||
dword rtfs_exclusive_semaphore; /* Used by Rtfs to run single threaded so buffers may be shared */
|
||
#if (INCLUDE_FAILSAFE_RUNTIME)
|
||
struct rtfs_failsafe_cfg *pfailsafe; /* Zero unless pc_failsafe_init() was called */
|
||
dword shared_restore_transfer_buffer_size;
|
||
byte *shared_restore_transfer_buffer;
|
||
byte *shared_restore_transfer_buffer_base;
|
||
#endif
|
||
|
||
|
||
dword shared_user_buffer_size;
|
||
byte *shared_user_buffer_base;
|
||
byte *shared_user_buffer;
|
||
|
||
/* These pointers are internal no user setup is needed */
|
||
BLKBUFFCNTXT buffcntxt; /* Systemwide shared buffer pool */
|
||
struct finode *inoroot; /* Begining of inode pool */
|
||
struct finode *mem_finode_freelist;
|
||
DROBJ *mem_drobj_freelist;
|
||
struct ddrive *mem_drive_freelist;
|
||
struct ddrive *drno_to_dr_map[26];
|
||
dword userlist_semaphore; /* Used by ERTFS for accessing the user structure list */
|
||
dword critical_semaphore; /* Used by ERTFS for critical sections */
|
||
dword mountlist_semaphore; /* Used by ERTFS for accessing the mount list */
|
||
/* Note: cfg_NDRIVES semaphores are allocated and assigned to the individual
|
||
drive structure within routine pc_ertfs_init() */
|
||
/* This value is set in pc_rtfs_init(). It is the drive number of the
|
||
lowest (0-25) == A: - Z:. valid drive identifier in the system.
|
||
If the user does not set a default drive, this value will be used. */
|
||
int default_drive_id;
|
||
/* Counter used to uniquely identify a drive mount. Each time an open
|
||
succeeds this value is incremented and stored in the drive structure.
|
||
it is used by gfirst gnext et al to ensure that the drive was not
|
||
closed and remounted between calls */
|
||
int drive_opencounter;
|
||
dword rtfs_driver_errno; /* device driver can set driver specific errno value */
|
||
RTFS_DEVI_POLL_REQUEST_VECTOR *device_poll_list; /* Functions registered on this are called every time the API is entered to check for status change. */
|
||
/* Private callback functions that overrides calls to the user's callback handler */
|
||
void (* test_drive_async_complete_cb)(int driveno, int operation, int success);
|
||
|
||
#if (1) /* ||INCLUDE_V_1_0_DEVICES == 1) */
|
||
dword floppy_semaphore;
|
||
dword floppy_signal;
|
||
dword ide_semaphore;
|
||
#endif
|
||
|
||
} RTFS_CFG;
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" RTFS_CFG *prtfs_cfg;
|
||
#else
|
||
extern RTFS_CFG *prtfs_cfg;
|
||
#endif
|
||
|
||
/* Async operation status */
|
||
#define PC_ASYNC_COMPLETE 1
|
||
#define PC_ASYNC_CONTINUE 2
|
||
#define PC_ASYNC_ERROR -1
|
||
|
||
/* Hint for how to allocate clusters, when ALLOC_CLUSTERS_ALIGNED and the media is erase block based
|
||
then priority is given to allocating clusters from empty erase blocks */
|
||
#define ALLOC_CLUSTERS_PACKED 1
|
||
#define ALLOC_CLUSTERS_ALIGNED 2
|
||
#define ALLOC_CLUSTERS_UNALIGNED 3
|
||
|
||
#if (INCLUDE_DEBUG_TEST_CODE)
|
||
#define RTFS_DEBUG_LOG_DEVIO(DRIVESTRUCT, IOCATEGORY, BLOCKNO, NBLOCK) rtfs_devio_log_io(DRIVESTRUCT, IOCATEGORY, BLOCKNO, NBLOCK);
|
||
void rtfs_devio_log_io(DDRIVE *pdrive, int iocategory, dword blockno, dword nblock);
|
||
#else
|
||
#define RTFS_DEBUG_LOG_DEVIO(DRIVESTRUCT, IOCATEGORY, BLOCKNO, NBLOCK)
|
||
#endif
|
||
|
||
struct fat32_info {
|
||
dword fs_sig; /* Signature of FAT32 (0x61417272) */
|
||
#define FSINFOSIG 0x61417272ul
|
||
dword free_alloc; /* Free clusters on drive (-1 if unknown) */
|
||
dword next_alloc; /* Most recently allocated cluster */
|
||
dword reserved; /* Reserved - ignore */
|
||
};
|
||
|
||
extern KS_CONSTANT byte * pustring_sys_oemname;
|
||
extern KS_CONSTANT byte * pustring_sys_volume_label;
|
||
extern KS_CONSTANT byte * pustring_sys_badlfn;
|
||
extern KS_CONSTANT byte * pustring_sys_badalias;
|
||
extern KS_CONSTANT byte * pustring_sys_ucreserved_names;
|
||
extern KS_CONSTANT byte * pustring_sys_lcreserved_names;
|
||
|
||
#if (INCLUDE_MATH64)
|
||
#if (INCLUDE_NATIVE_64_TYPE)
|
||
#define M64EQ(A,B) ((A)==(B))
|
||
#define M64LT(A,B) ((A)<(B))
|
||
#define M64LTEQ(A,B) ((A)<=(B))
|
||
#define M64GT(A,B) ((A)>(B))
|
||
#define M64GTEQ(A,B) ((A)>=(B))
|
||
#define M64NOTZERO(A)((A)!=0)
|
||
#define M64ISZERO(A) ((A)==0)
|
||
#define M64IS64(A) ((A)>=0x100000000)
|
||
#define M64HIGHDW(A) ((dword)((A) >> 32))
|
||
#define M64LOWDW(A) ((dword)((A) & 0xffffffff))
|
||
#define M64MINUS(A,B) ((A)-(B))
|
||
#define M64MINUS32(A,B) ((A)-(ddword)(B))
|
||
#define M64PLUS(A,B) ((A)+(B))
|
||
#define M64PLUS32(A,B) ((A)+(ddword)(B))
|
||
#define M64SET32(A,B) m64_native_set32((A), (B))
|
||
#define M64LSHIFT(A,B) ((A)<<(B))
|
||
#define M64RSHIFT(A,B) ((A)>>(B))
|
||
#define M64MULT32(A,B) ((A)*(ddword)(B))
|
||
#else
|
||
#define M64EQ(A,B) ( ((A).hi==(B).hi) && ((A).lo==(B).lo) )
|
||
#define M64LT(A,B) ( ((A).hi<(B).hi) || ( ((A).hi==(B).hi) && ((A).lo<(B).lo) ))
|
||
#define M64LTEQ(A,B) ( ((A).hi<(B).hi) || ( ((A).hi==(B).hi) && ((A).lo<=(B).lo) ))
|
||
#define M64GT(A,B) ( ((A).hi>(B).hi) || ( ((A).hi==(B).hi) && ((A).lo>(B).lo) ))
|
||
#define M64GTEQ(A,B) ( ((A).hi>(B).hi) || ( ((A).hi==(B).hi) && ((A).lo>=(B).lo) ))
|
||
#define M64NOTZERO(A)( (A).hi||(A).lo )
|
||
#define M64ISZERO(A) ( ((A).hi==0)&&((A).lo==0) )
|
||
#define M64IS64(A) ( ((A).hi!=0) )
|
||
#define M64HIGHDW(A) ( (A).hi )
|
||
#define M64LOWDW(A) ( (A).lo )
|
||
#define M64MINUS(A,B) m64_minus((A), (B))
|
||
#define M64MINUS32(A,B) m64_minus32((A), (B))
|
||
#define M64PLUS(A,B) m64_plus((A), (B))
|
||
#define M64PLUS32(A,B) m64_plus32((A), (B))
|
||
#define M64SET32(A,B) m64_set32((A), (B))
|
||
#define M64LSHIFT(A,B) m64_lshift((A), (B))
|
||
#define M64RSHIFT(A,B) m64_rshift((A), (B))
|
||
#endif
|
||
#endif
|
||
|
||
#define PCE_FIRST_FIT 0x01
|
||
#define PCE_FORCE_FIRST 0x02
|
||
#define PCE_FORCE_CONTIGUOUS 0x04
|
||
#define PCE_KEEP_PREALLOC 0x08
|
||
#define PCE_CIRCULAR_FILE 0x10
|
||
#define PCE_CIRCULAR_BUFFER 0x20
|
||
#define PCE_REMAP_FILE 0x40
|
||
#define PCE_ASYNC_OPEN 0x100
|
||
#define PCE_TEMP_FILE 0x200
|
||
#define PCE_EXTENDED_FILE 0x400
|
||
#define PCE_TRANSACTION_FILE 0x800
|
||
#define PCE_LOAD_AS_NEEDED 0x1000
|
||
|
||
|
||
typedef struct efileoptions {
|
||
dword allocation_policy;
|
||
dword min_clusters_per_allocation;
|
||
dword allocation_hint;
|
||
/* The following field is for transaction files only */
|
||
#if (INCLUDE_TRANSACTION_FILES)
|
||
byte *transaction_buffer;
|
||
dword transaction_buffer_size;
|
||
#endif
|
||
#if (INCLUDE_CIRCULAR_FILES)
|
||
/* The following fields are for circular files only */
|
||
dword circular_file_size_hi; /* Loop back to zero when this is reached */
|
||
dword circular_file_size_lo; /* Loop back to zero when this is reached */
|
||
int n_remap_records; /* User supplied space for remapping circular */
|
||
REMAP_RECORD *remap_records; /* Regions to linear files */
|
||
#endif
|
||
} EFILEOPTIONS;
|
||
|
||
|
||
typedef struct ertfs_efilio_stat
|
||
{
|
||
/* Minimum number of bytes that will are pre-allocated at one time
|
||
when the file is extended- by default this is the cluster size
|
||
of the volume but it may be effected by the
|
||
extended file open option "min_clusters_per_allocation" */
|
||
dword minimum_allocation_size;
|
||
/* These are the policy bits that were set in the allocation_policy
|
||
field of the extended file open call */
|
||
dword allocation_policy;
|
||
/* NEW element 10/31/05 */
|
||
/* The count of seperate disjoint fragment in the file */
|
||
dword fragments_in_file;
|
||
/* First cluster in the file */
|
||
dword first_cluster;
|
||
/* cluster used for data in the file */
|
||
dword allocated_clusters;
|
||
/* cluster pre-allocated for data in the file */
|
||
dword preallocated_clusters;
|
||
/* cluster to link */
|
||
dword clusters_to_link;
|
||
/* End new element 10/31/05 */
|
||
|
||
/* The file size in bytes */
|
||
dword file_size_hi;
|
||
dword file_size_lo;
|
||
/* The number of bytes currently allocated to the file including
|
||
the file contents (current_file_size) and any additional
|
||
preallocated blocks due to minimum allocation guidelines */
|
||
dword allocated_size_hi;
|
||
dword allocated_size_lo;
|
||
/* current file pointer */
|
||
dword file_pointer_hi;
|
||
dword file_pointer_lo;
|
||
/* The file's cluster chain */
|
||
REGION_FRAGMENT *pfirst_fragment[1];
|
||
ERTFS_STAT stat_struct; /* Traditional stat structure */
|
||
} ERTFS_EFILIO_STAT;
|
||
|
||
|
||
/* From prapicsk.c */
|
||
#define CFREAD_POINTER 1 /* Arguments to circular file seek */
|
||
#define CFWRITE_POINTER 2
|
||
#define DEFAULT_SEGMENT_SIZE 0x80000000 /* 2 gigabyte */
|
||
|
||
|
||
|
||
#if (INCLUDE_DEBUG_LEAK_CHECKING)
|
||
struct mem_report {
|
||
int lost_count; /* Sum of all lost fileds, if zero, none lost, otherwise look at individual fields */
|
||
int nusers_configured;
|
||
int nusers_free;
|
||
|
||
int nfiles_configured;
|
||
int nfiles_free;
|
||
|
||
int ndrives_configured;
|
||
int ndrives_free;
|
||
int ndrives_mapped;
|
||
int ndrives_lost;
|
||
|
||
int ndrobjs_configured;
|
||
int ndrobjs_free;
|
||
int ndrobjs_in_files;
|
||
int ndrobjs_in_users;
|
||
int ndrobjs_lost;
|
||
|
||
int nfinodes_configured;
|
||
int nfinodes_free;
|
||
int nfinodes_in_drobj;
|
||
int nfinodes_in_pool;
|
||
int nfinodes_reference_errors;
|
||
int nfinodes_lost;
|
||
|
||
int nfinodeex_configured;
|
||
int nfinodeex_free;
|
||
int nfinodeex_lost;
|
||
|
||
int nglblkbuff_configured;
|
||
int nglblkbuff_free;
|
||
int nglblkbuff_in_filebuff;
|
||
int nglblkbuff_in_dirbuff;
|
||
int nglblkbuff_in_scratchbuff;
|
||
int nglblkbuff_lost;
|
||
|
||
int nrgnbuff_configured;
|
||
int nrgnbuff_free;
|
||
int nrgnbuff_in_files;
|
||
int nrgnbuff_in_freemap;
|
||
int nrgnbuff_in_failsafe;
|
||
int nrgnbuff_lost;
|
||
|
||
int nfatbuff_free;
|
||
int nfatbuff_committed;
|
||
int nfatbuff_uncommitted;
|
||
int nfatbuff_lost;
|
||
};
|
||
void pc_leak_test(struct mem_report * preport);
|
||
#endif /* INCLUDE_DEBUG_LEAK_CHECKING */
|
||
|
||
|
||
#endif /* ___RTFSTYPES___ */
|