Professional Documents
Culture Documents
Fte
Fte
/*
/*
/*
/*
/*
*/
*/
*/
*/
*/
short
char
short
short
short
NumberOfSectors;
descriptor;
SectorsPerFat;
SectorsPerTrack;
Heads;
boot sector. */
/* sectors per cluster.
/* number of reserved sectors.
/* number of fats.
/* number of files or directories in
/* the root directory.
/* number of sectors in the volume.
/* media descriptor.
/* number of sectors per fat.
/* sectors per track.
/* number of read/write heads.
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
short
char
short
short
short
short
NumberOfSectors;
descriptor;
SectorsPerFat;
SectorsPerTrack;
Heads;
Divider;
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
char BootRoutine[482];
/* bootroutine.
*/
};
The following two functions read and write the boot sector from disk:
int ReadBootSector(RDWRHandle handle, struct BootSectorStruct* buffer);
int WriteBootSector(RDWRHandle handle, struct BootSectorStruct* buffer);
For reasons of speed the fields that make up the bios parameter block
(+ Heads + SectorsPerTrack) are repeated in the RDWRHandle. Since the
above functions only read and write from disk and do no caching the following
functions are provided. These functions first look wether the right values
are allready in the RDWRHandle and if they are they are read from the
handle, otherwise they are read from disk using ReadBootSector and
WriteBootSector.
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
short
char
short
char
short
short
short
short
GetSectorsPerCluster
GetReservedSectors
GetNumberOfFats
GetNumberOfRootEntries
GetMediaDescriptor
GetNumberOfSectors
GetSectorsPerFat
GetSectorsPerTrack
GetReadWriteHeads
(RDWRHandle
(RDWRHandle
(RDWRHandle
(RDWRHandle
(RDWRHandle
(RDWRHandle
(RDWRHandle
(RDWRHandle
(RDWRHandle
handle);
handle);
handle);
handle);
handle);
handle);
handle);
handle);
handle);
There is one caveet here. Since there is no way to link an instance of the
BootSectorStruct to a RDWRHandle. The cached values in the RDWRHandle are
only updated when a boot sector is read from or written to disk.
Root directory.
--------------The root directory is the root of the directory structure. It contains
the following information associated with a file.
-
file name
file extension
file attribute
time last changed
date last changed
first cluster in file (accessed from the FAT)
file size
Or as the c structure:
struct DirectoryStruct
{
char filename[8];
char extension[3];
char attribute;
char reserved[10];
short timestamp;
short datestamp;
short firstclust;
long filesize;
};
/*
/*
/*
/*
/*
/*
/*
/*
file name.
extension.
file attribute.
reserved.
time last modified.
date last modified.
first cluster of file.
file size.
*/
*/
*/
*/
*/
*/
*/
*/
Since each of these entries contains 32 bytes and there are 512 bytes in a
sector we can uniquelly refer to each directory entry by a sector and
Since the number of directory entries is fixed we can refer to each directory
entry using an index. Therefore the functions to querry and change the
root directory entries are as follows:
int ReadDirEntry(RDWRHandle handle, int index,
struct DirectoryStruct* entry);
int WriteDirEntry(RDWRHandle handle, int index,
struct DirectoryStruct* entry);
The constants for the file attributes can be taken from the header files
of the C library. For tc201 these are:
FA_RDONLY
FA_HIDDEN
FA_SYSTEM
FA_LABEL
FA_DIREC
FA_ARCH
as defined in <dos.h>
Last in this section we have to mention that the dates and time in the
directory are encoded. To work with this coding the following functions
are provided:
void UnPackTimeDateStamp(struct tm* time,
short timestamp, short datestamp);
void PackTimeDateStamp(struct tm* time,
short* timestamp, short* datestamp);
Struct tm is the c structure define in <time.h>.
FAT
--The fat indicates the position of the file clusters in the data area. It
exist of linked lists of labels. These labels can be any of the following
values, depending on the size of the fat labels:
#define FAT12 12
#define FAT16 16
/* FAT labels for FAT12. */
#define FAT12_FREE_LABEL
0x000
#define FAT12_BAD_LABEL
0xff7
#define
#define
#define
#define
FAT12_FREE(x)
FAT12_BAD(x)
FAT12_RESERVED(x)
FAT12_LAST(x)
(x == FAT12_FREE_LABEL)
(x == FAT12_BAD_LABEL)
((x >= 0xff0) && (x <= 0xff6))
((x >= 0xff8) && (x <= 0xfff))
#define FAT12_NORMAL(x)
FAT16_FREE(x)
FAT16_BAD(x)
FAT16_RESERVED(x)
FAT16_LAST(x)
FAT16_NORMAL(x)
(x == FAT16_FREE_LABEL)
(x == FAT16_BAD_LABEL)
((x >= 0xfff0) && (x <= 0xfff6))
((x >= 0xfff8) && (x <= 0xffff))
((x != 0) && (x < 0xfff0))
To iterate over the different parts of the fat two traversal functions
are provided:
typedef unsigned long CLUSTER;
int LinearTraverseFat(RDWRHandle handle,
int (*func) (unsigned long label,
unsigned long datasector,
void** structure),
void** structure);
int FileTraverseFat(RDWRHandle handle, CLUSTER startcluster,
int (*func) (unsigned long label,
unsigned long datasector,
void** structure),
void** structure);
These functions call a function for each label that is being traversed.
The function needs to have the following proto type:
int <func> (unsigned long label, unsigned long datasector,
void** structure),
Label is the encountered label in the fat extended to a 32 bit integer,
datasector is the start sector of the corresponding cluster in the
data area.
The structure is a structure which is passed directly from the caller
of the traversal function to the function which is periodically called. This
allows to accumulate any amount of data over the traversal.
The reason to use void** comes from the expected need for realloc,
which has as proto type:
void* realloc(void* block, size_t size);
So the pointer to the memory that contains the accumulated data can
change, to be able to handle this change in pointers we need
an extra level in indirection, so a void**.
In case of LinearTraverseFat it calls the function for every label in the
fat. In case of FileTraverseFat the function is called for every label in
a file.
There are some other functions to work on the fat, these include:
with entries from the root directory, for which the position of a directory
can be calculated with:
int GetRootDirPosition(RDWRHandle handle, int index,
struct DirectoryPosition* pos);
which puts the corresponding position in pos.