The Root Directory
Use this information only if you agree to the terms in my Disclaimer
So far you know that
to store a file on disk requires it to be split up into pieces, you
know about the boot sector and how the file allocation tables track
the status of the clusters. The one thing that I haven't mentioned
yet is where the filenames and attributes etc. get stored, in this
section you will find that out.
As I'm sure you know a file has various attributes which can be set:
Read only | Meaning that you cannot alter it. |
Hidden | Meaning that the file will not show up under normal circumstances. |
Archive | Meaning that the file has been opened in way which would have allowed you to alter it (whether you have changed it or not). |
System | Which usually means the file is part of the operating system.
Or a program has set it for some reason. |
There are also two other less known attributes which are not usually set directly by the user.
Volume | Indicates that this is the Volume label and not a file at all. |
Directory | Which means that this file should be treated as a directory. |
Hopefully you are aware of directories and how they can hold files
and sub-directories of their own, the first thing you need to appreciate
is that a sub-directory is just a file like any other. The OS stops you
from accessing it as such because a special attribute is set, the directory
attribute.
This special file contains the names, attributes, last modified times
and other details concerning the files and sub-directories contained in it
each has a block of 32 bytes called a directory entry allocated to it.
Now think back to the FAT section, by reading the FAT we could follow
through the file chains but we never knew where the file began for certain (we could guess).
The directory entry holds the number of the first cluster of the file, to
read a file the OS reads in the data from that cluster, then looks at the
cluster's entry in the FAT to see where it continues, if does that is.
As well as holding the first cluster of the file, other
things are stored, these are:
- Name of the file, 8 main letters and 3 for the extension (exe, txt, doc etc. etc.).
- Its attributes.
- The time that the file was created.
- The date that the file was created.
- The date that the file was last accessed.
- The time that the file was last modified.
- The date that the file was last modified.
- The size of the file.
Although we can tell roughly how big the file is by using the EOC mark
in the FAT it's still necessary to know the exact file size. Sub-directories
do not have a file size specified, they can grow as required.
The first two entries in every sub-directory are reserved, they contain
sub-directory entries called "." dot and ".." dotdot entries. Now DOS
users will be very familiar with these since they appear whenever you issue
a DIR command. Windows users on the other hand may not because these are
not shown. Anyway the ".." entry points to the parent directory, the directory
which holds the sub-directory in which the entry resides. The "." entry points
to the directory in which it is in.
Every disk formatted using the FAT file system has a special
directory called the root directory, this is automatically created
at the time of format. This is where all other directories and files
originate from. The data contained inside is the same as described earlier
except that there are no "." or ".." entries.
FAT32 handles the root directory like it would any
other directory by allocating clusters from the data area (keeping track
of them in the FAT) as it requires. The cluster in which the root directory
begins is usually the first (cluster 2), but it doesn't have to. The cluster
address is stored in the boot record (only for FAT32).
With FAT12 and FAT16 the root directory has a certain number of sectors
set aside in the system area, this limits the number of files and directories
which the root directory can hold.
Here's a table of the maximum number of root directory entries:
Type | Capacity | Number of Entries |
5 1/4" | 180KB | 64 |
5 1/4" | 320KB | 64 |
5 1/4" | 360KB | 112 |
5 1/4" | 1.2MB | 224 |
3 1/2" | 720KB | 112 |
3 1/2" | 1.44MB | 224 |
Hard disks FAT12 and FAT16 | 512 |
What happens when you delete a file?
When a file gets deleted the first letter in the filename is changed to
the number 229 and all the entries, for the file, in the FAT get changed to
0 to indicate that they can now be used. This is how undelete utilities can exist
the name is left intact all bar the first letter, it still knows where the first
cluster was, and as for which cluster(s) were used, it just guesses.
There's one last thing that needs to be mentioned (for the non-technical
section), long filenames or LFN's for short. You may have noticed that I
said the names in the directory have 8 main letters plus 3 for the
extension, Windows 95, and later, allows LFN's which can be up to 254 characters long,
so how does it do this? Well basically it uses many entries for each file
and sets a nonsensical combination of attributes so that they do not show
up. Because the other details of file (size, first cluster, dates and times etc.)
only need be specified once, more characters of the name can be stored in their
place.
A normal directory entry is then created with all the necessary details.
This marks the end of the non-technical area, if you've been
reading this from the start then you know the drill, if you haven't then figure
it out.
Technical Information on Directory Entries.
You need to know where the root directory is before you can do anything
else, with FAT12 and FAT16 the first sector of the root directory is
calculated by: Number of FAT's*Sectors per FAT+Reserved sectors. The total
number of sector occupied depends upon the maximum number of root directory entries
Those fields are in the boot sector by the way.
FAT32 treats the root directory just like a file, the first cluster of the
root directory is located in the boot record.
As stated before each directory entry occupies 32 bytes of space, so
you can get 16 entries per 512 bytes. If a directory entry is free then the
first byte is set to E5h, or to 0 if all those which follow it are free
as well.
Note: E5h is a valid lead byte for a Japanese character set so because of
this 5 is used instead, this is the only value under 32 which is allowed
in the file name.
A Windows LFN is broken up into 13 character pieces and stored in a modified
directory entry, as seen below, the entries immediately precede the SFN alias of
the file and are in reverse order.
Like this:
LFN part 4 (bit 6 is set) |
LFN part 3 |
LFN part 2 |
LFN part 1 |
SFN alias |
Each LFN entry has a checksum calculated from the space padded
SFN name without a ".".
This code will calculate the checksum for a given name:
;CALKCHK Procedure: | |
; | DS:BX -> SFN. |
;Return: DL = checksum. | |
; | CX, DL and AL trashed, feel free to |
; | add some push's and pop's if you want to. |
CALKCHK PROC | |
| MOV CX,11 |
| XOR DL,DL |
MLOOP: | MOV AL,[BX] |
| ROR DL,1 |
| ADD DL,AL |
| INC BX |
| LOOP MLOOP |
| RET |
CALKCHK ENDP | |
Before the data layouts two important limitations need to be mentioned.
Number one, the maximum number of entries in a sub-directory, or the root
directory with FAT32, cannot be allowed to exceed 65536.
Lastly the maximum file size is limited to FFFFFFFFh with FAT32, but with
FAT12 and FAT16 the maximum is only half of that.
You can use these links to quickly locate items that are of interest.
- Directory Entry Layout.
- Extra Data Layout (previously reserved area).
- File Attribute Byte.
- Date Format.
- Time Format.
- LFN Directory Entry Layout.
Directory Entry Layout.
The old style directory entry had 10 reserved bytes starting at 0Ch, these are now used. |
Offset | Length | Field |
00h | 8 | Filename padded with spaces if required (see above). |
08h | 3 | Filename extension padded with spaces if required. |
0Bh | 1 | File Attribute Byte. |
0Ch | 10 | Reserved or extra data. |
16h | 2 | Time of last write to file (last modified or when created). |
18h | 2 | Date of last write to file (last modified or when created). |
1Ah | 2 | Starting cluster. |
1Ch | 4 | File size (set to zero if a directory). |
Extra data Layout (previously reserved area).
The old style directory entry had 10 reserved bytes starting at 0Ch, these are now used as follows.
Presumably these fields are used if non-zero. |
Offset | Length | Field |
0Ch | 1 | Reserved for use by Windows NT. |
0Dh | 1 | Tenths of a second at time of file creation, 0-199 is valid. |
0Eh | 2 | Time when file was created. |
10h | 2 | Date when file was created. |
12h | 2 | Date when file was last accessed. |
14h | 2 | High word of cluster number (always 0 for FAT12 and FAT16). |
File Attribute Byte
Bit | 7-6 | 5 | 4 | 3 | 2 | 1 | 0 |
Set if: | These are reserved, set to 0. | Archive | Directory | Volume Label | System | Hidden | Read Only |
Date Format.
Bits | 15-9 | 8-5 | 4-0 |
Give: | Years since 1980. Valid from 0-127 inclusive (1980-2107). |
Month of year. Valid from 1-12 inclusive(1=Jan). |
Day of the month. Valid from 1-31 inclusive. |
Time Format.
Bits | 15-11 | 10-5 | 4-0 |
Give: |
Hours. Valid from 0-23 inclusive. |
Minutes. Valid from 0-59 inclusive. |
Seconds/2. Valid from 0-29 inclusive (0-58 seconds). |
LFN Directory Entry Layout.
Each LFN directory entry holds 13 characters of the complete
LFN using 16-bit Unicode characters. |
Offset | Length | Field |
00h | 1 | Bits 0-5 give the LFN part number, bit 6 is set if this is the last entry for the file. |
01h | 10 | 1st 5 letters of LFN entry. |
0Bh | 1 | 0Fh (RSHV attributes set) |
0Ch | 1 | Reserved set to 0. |
0Dh | 1 | Checksum generated from SFN. |
0Eh | 12 | Next 6 letters of LFN entry. |
1Ah | 2 | 0 |
1Ch | 4 | Last 2 letters of LFN entry. |