Microsoft Extensible Firmware Initiative fat32 File System Specification


“foo.bar” -> “FOO BAR” “FOO.BAR” -> “FOO BAR”



Yüklə 225,69 Kb.
səhifə8/9
tarix11.10.2017
ölçüsü225,69 Kb.
#4468
1   2   3   4   5   6   7   8   9

“foo.bar” -> “FOO BAR”

“FOO.BAR” -> “FOO BAR”

“Foo.Bar” -> “FOO BAR”

“foo” -> “FOO “

“foo.” -> “FOO “

“PICKLE.A” -> “PICKLE A “

“prettybg.big” -> “PRETTYBGBIG”

“.big” -> illegal, DIR_Name[0] cannot be 0x20

In FAT directories all names are unique. Look at the first three examples earlier. Those different names all refer to the same file, and there can only be one file with DIR_Name set to “FOO BAR” in any directory.


DIR_Attr specifies attributes of the file:
ATTR_READ_ONLY Indicates that writes to the file should fail.

ATTR_HIDDEN Indicates that normal directory listings should not show this file.

ATTR_SYSTEM Indicates that this is an operating system file.

ATTR_VOLUME_ID There should only be one “file” on the volume that has this attribute set, and that file must be in the root directory. This name of this file is actually the label for the volume. DIR_FstClusHI and DIR_FstClusLO must always be 0 for the volume label (no data clusters are allocated to the volume label file).

ATTR_DIRECTORY Indicates that this file is actually a container for other files.

ATTR_ARCHIVE This attribute supports backup utilities. This bit is set by the FAT file system driver when a file is created, renamed, or written to. Backup utilities may use this attribute to indicate which files on the volume have been modified since the last time that a backup was performed.


Note that the ATTR_LONG_NAME attribute bit combination indicates that the “file” is actually part of the long name entry for some other file. See the next section for more information on this attribute combination.
When a directory is created, a file with the ATTR_DIRECTORY bit set in its DIR_Attr field, you set its DIR_FileSize to 0. DIR_FileSize is not used and is always 0 on a file with the ATTR_DIRECTORY attribute (directories are sized by simply following their cluster chains to the EOC mark). One cluster is allocated to the directory (unless it is the root directory on a FAT16/FAT12 volume), and you set DIR_FstClusLO and DIR_FstClusHI to that cluster number and place an EOC mark in that clusters entry in the FAT. Next, you initialize all bytes of that cluster to 0. If the directory is the root directory, you are done (there are no dot or dotdot entries in the root directory). If the directory is not the root directory, you need to create two special entries in the first two 32-byte directory entries of the directory (the first two 32 byte entries in the data region of the cluster you just allocated).
The first directory entry has DIR_Name set to:

“. ”

The second has DIR_Name set to:


“.. ”

These are called the dot and dotdot entries. The DIR_FileSize field on both entries is set to 0, and all of the date and time fields in both of these entries are set to the same values as they were in the directory entry for the directory that you just created. You now set DIR_FstClusLO and DIR_FstClusHI for the dot entry (the first entry) to the same values you put in those fields for the directories directory entry (the cluster number of the cluster that contains the dot and dotdot entries).


Finally, you set DIR_FstClusLO and DIR_FstClusHI for the dotdot entry (the second entry) to the first cluster number of the directory in which you just created the directory (value is 0 if this directory is the root directory even for FAT32 volumes).
Here is the summary for the dot and dotdot entries:

  • The dot entry is a directory that points to itself.

  • The dotdot entry points to the starting cluster of the parent of this directory (which is 0 if this directories parent is the root directory).



Date and Time Formats


Many FAT file systems do not support Date/Time other than DIR_WrtTime and DIR_WrtDate. For this reason, DIR_CrtTimeMil, DIR_CrtTime, DIR_CrtDate, and DIR_LstAccDate are actually optional fields. DIR_WrtTime and DIR_WrtDate must be supported, however. If the other date and time fields are not supported, they should be set to 0 on file create and ignored on other file operations.
Date Format. A FAT directory entry date stamp is a 16-bit field that is basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word):
Bits 0–4: Day of month, valid value range 1-31 inclusive.

Bits 5–8: Month of year, 1 = January, valid value range 1–12 inclusive.

Bits 9–15: Count of years from 1980, valid value range 0–127 inclusive (1980–2107).
Time Format. A FAT directory entry time stamp is a 16-bit field that has a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word).
Bits 0–4: 2-second count, valid value range 0–29 inclusive (0 – 58 seconds).

Bits 5–10: Minutes, valid value range 0–59 inclusive.

Bits 11–15: Hours, valid value range 0–23 inclusive.
The valid time range is from Midnight 00:00:00 to 23:59:58.

FAT Long Directory Entries


In adding long directory entries to the FAT file system it was crucial that their addition to the FAT file system's existing design:
· Be essentially transparent on earlier versions of MS-DOS. The primary goal being that existing MS-DOS APIs on previous versions of MS-DOS/Windows do not easily "find" long directory entries. The only MS-DOS APIs that can "find" long directory entries are the FCB-based-find APIs when used with a full meta-character matching pattern (i.e. *.*) and full attribute matching bits (i.e. matching attributes are FFh). On post-Windows 95 versions of MS-DOS/Windows, no MS-DOS API can accidentally "find" a single long directory entry.

· Be located in close physical proximity, on the media, to the short directory entries they are associated with. As will be evident, long directory entries are immediately contiguous to the short directory entry they are associated with and their existence imposes an unnoticeable performance impact on the file system.

· If detected by disk maintenance utilities, they do not jeopardize the integrity of existing file data. Disk maintenance utilities typically do not use MS-DOS APIs to access on-media file-system-specific data structures. Rather they read physical or logical sector information from the disk and judge for themselves what the directory entries contain. Based on the heuristics employed in the utilities, the utility may take various steps to "repair" what it perceives to be "damaged" file-system-specific data structures. Long directory entries were added to the FAT file system in such a way as to not cause the loss of file data if a disk containing long directory entries was "repaired" by a pre-Windows 95-compatible disk utility on a previous version of MS-DOS/Windows.
In order to meet the goals of locality-of-access and transparency, the long directory entry is defined as a short directory entry with a special attribute. As described previously, a long directory entry is just a regular directory entry in which the attribute field has a value of:
ATTR_LONG_NAME ATTR_READ_ONLY |
ATTR_HIDDEN |
ATTR_SYSTEM |
ATTR_VOLUME_ID
A mask for determining whether an entry is a long-name sub-component should also be defined:
ATTR_LONG_NAME_MASK ATTR_READ_ONLY |
ATTR_HIDDEN |
ATTR_SYSTEM |
ATTR_VOLUME_ID |
ATTR_DIRECTORY |
ATTR_ARCHIVE

When such a directory entry is encountered it is given special treatment by the file system. It is treated as part of a set of directory entries that are associated with a single short directory entry. Each long directory entry has the following structure:


FAT Long Directory Entry Structure

Name

Offset

(byte)

Size

(bytes)

Description

LDIR_Ord

0

1

The order of this entry in the sequence of long dir entries associated with the short dir entry at the end of the long dir set.

If masked with 0x40 (LAST_LONG_ENTRY), this indicates the entry is the last long dir entry in a set of long dir entries. All valid sets of long dir entries must begin with an entry having this mask.



LDIR_Name1

1

10

Characters 1-5 of the long-name sub-component in this dir entry.

LDIR_Attr

11

1

Attributes - must be ATTR_LONG_NAME

LDIR_Type

12

1

If zero, indicates a directory entry that is a sub-component of a long name. NOTE: Other values reserved for future extensions.

Non-zero implies other dirent types.



LDIR_Chksum

13

1

Checksum of name in the short dir entry at the end of the long dir set.

LDIR_Name2

14

12

Characters 6-11 of the long-name sub-component in this dir entry.

LDIR_FstClusLO

26

2

Must be ZERO. This is an artifact of the FAT "first cluster" and must be zero for compatibility with existing disk utilities. It's meaningless in the context of a long dir entry.

LDIR_Name3

28

4

Characters 12-13 of the long-name sub-component in this dir entry.

Organization and Association of Short & Long Directory Entries

A set of long entries is always associated with a short entry that they always immediately precede. Long entries are paired with short entries for one reason: only short directory entries are visible to previous versions of MS-DOS/Windows. Without a short entry to accompany it, a long directory entry would be completely invisible on previous versions of MS-DOS/Windows. A long entry never legally exists all by itself. If long entries are found without being paired with a valid short entry, they are termed orphans. The following figure depicts a set of n long directory entries associated with it's single short entry.


Long entries always immediately precede and are physically contiguous with, the short entry they are associated with. The file system makes a few other checks to ensure that a set of long entries is actually associated with a short entry.
Sequence Of Long Directory Entries

Entry

Ordinal

Nth Long entry

LAST_LONG_ENTRY (0x40) | N

… Additional Long Entries



1st Long entry

1

Short Entry Associated With Preceding Long Entries

(not applicable)

First, every member of a set of long entries is uniquely numbered and the last member of the set is or'd with a flag indicating that it is, in fact, the last member of the set. The LDIR_Ord field is used to make this determination. The first member of a set has an LDIR_Ord value of one. The nth long member of the set has a value of (n OR LAST_LONG_ENTRY). Note that the LDIR_Ord field cannot have values of 0xE5 or 0x00. These values have always been used by the file system to indicate a "free" directory entry, or the "last" directory entry in a cluster. Values for LDIR_Ord do not take on these two values over their range. Values for LDIR_Ord must run from 1 to (n OR LAST_LONG_ENTRY). If they do not, the long entries are "damaged" and are treated as orphans by the file system.


Second, an 8-bit checksum is computed on the name contained in the short directory entry at the time the short and long directory entries are created. All 11 characters of the name in the short entry are used in the checksum calculation. The check sum is placed in every long entry. If any of the check sums in the set of long entries do not agree with the computed checksum of the name contained in the short entry, then the long entries are treated as orphans. This can occur if a disk containing long and short entries is taken to a previous version of MS-DOS/Windows and only the short name of a file or directory with a long entries is renamed.
The algorithm, implemented in C, for computing the checksum is:
//-----------------------------------------------------------------------------
// ChkSum()
// Returns an unsigned byte checksum computed on an unsigned byte
// array. The array must be 11 bytes long and is assumed to contain
// a name stored in the format of a MS-DOS directory entry.
// Passed: pFcbName Pointer to an unsigned byte array assumed to be

// 11 bytes long.


// Returns: Sum An 8-bit unsigned checksum of the array pointed

// to by pFcbName.


//------------------------------------------------------------------------------
unsigned char ChkSum (unsigned char *pFcbName)
{
short FcbNameLen;
unsigned char Sum;

Sum = 0;
for (FcbNameLen=11; FcbNameLen!=0; FcbNameLen--) {


// NOTE: The operation is an unsigned char rotate right
Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pFcbName++;
}
return (Sum);
}
As a consequence of this pairing, the short directory entry serves as the structure that contains fields like: last access date, creation time, creation date, first cluster, and size. It also holds a name that is visible on previous versions of MS-DOS/Windows. The long directory entries are free to contain new information and need not replicate information already available in the short entry. Principally, the long entries contain the long name of a file. The name contained in a short entry which is associated with a set of long entries is termed the alias name, or simply alias, of the file.

Storage of a Long-Name Within Long Directory Entries

A long name can consist of more characters than can fit in a single long directory entry. When this occurs the name is stored in more than one long entry. In any event, the name fields themselves within the long entries are disjoint. The following example is provided to illustrate how a long name is stored across several long directory entries. Names are also NUL terminated and padded with 0xFFFF characters in order to detect corruption of long name fields by errant disk utilities. A name that fits exactly in a n long directory entries (i.e. is an integer multiple of 13) is not NUL terminated and not padded with 0xFFFFs.


Suppose a file is created with the name: "The quick brown.fox". The following example illustrates how the name is packed into long and short directory entries. Most fields in the directory entries are also filled in as well.

The heuristics used to "auto-generate" a short name from a long name are explained in a later section.


Yüklə 225,69 Kb.

Dostları ilə paylaş:
1   2   3   4   5   6   7   8   9




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə