The VFAT system is an extension of the existing FAT file system designed to support both old DOS / WIN16 / OS/2 / Linux applications which only supports 8.3 (both OS/2 and Linux supports LFN, just not on FATFS).
VFAT achieves this new advantage by introducing a new variation of the ordinary Directory Entry (see FAT explanation). The new extended DirEntry looks like this:
Field Name | Offset | Length | Description |
---|---|---|---|
Name | 0 | 8 | Contains the 8 chars for the DOS name. |
Extension | 8 | 3 | Contains the 3 chars for the DOS extension. |
Attributes | 11 | 1 | Standard DOS attributes field - see FAT explanation. |
?? | 12 | 2 | Seems to vary randomly |
Create-date | 14 | 4 | Time of creation - standard DOS date-time field - see FAT explanation. |
LastAccess | 18 | 2 | Date of last access - coding described below. |
EA-index | 20 | 2 | Unused in VFAT but protected to support OS/2 and avoid corruption when used with OS/2. |
Date | 22 | 4 | Standard DOS date-time field - see FAT explanation. |
EntryCluster | 26 | 2 | First cluster in the FAT chain - see FAT explanation. |
FileSize | 28 | 4 | Size of file in bytes. |
Total | 32 |
A completely new DirEntry is introduced - the DELFN (DirEntry for LongFileName)
Field Name | Offset | Length | Description |
---|---|---|---|
SeqNumber | 0 | 1 | This field describes the number of this entry in the sequence of entries which creates the total LFN. If the 7th bit is set it is the last entry in the chain making up the LFN. |
Name1 | 1 | 10 | Contains 5 chars. |
Attributes | 11 | 1 | Always contains 0Fh (= R/O+System+Hidden+VolumeID). This ensures that DOS-programs will avoid interpreting the LFN entry. |
Reserved | 12 | 1 | = 0 |
Checksum | 13 | 1 | So far I have not been able to figure out how it is calculated. |
Name2 | 14 | 12 | Contains 6 chars. |
EntryCluster | 26 | 2 | First cluster in the FAT chain-. This is always 0 since there is no cluster chain associated with a LFN entry. This field is probably kept zero to avoid old app. attempting to interpret it as a ordinary DE. |
Name3 | 28 | 4 | Contains 2 chars. |
Total | 32 |
Note that in a LFN entry a char consists of 2 bytes (a DBCS) therefore an entry only contains 13 chars. Given below is an example of a hex-listing of a directory containing only 1 LFN - the file "This is a test of a very long file name with additional.dots.so.you.may.see.how.they.are.stored.txt" and 1 DOS-name: "DOSNAME.EXT".
00000000: 2E 20 20 20 20 20 20 20 20 20 20 10 00 B0 A3 6E [ . ..°£n ] 00000010: 38 23 38 23 00 00 A3 6E 38 23 69 BD 00 00 00 00 [ 8#8#..£n8#i½.... ] 00000020: 2E 2E 20 20 20 20 20 20 20 20 20 10 00 B0 A3 6E [ .. ..°£n ] 00000030: 38 23 38 23 00 00 A3 6E 38 23 00 00 00 00 00 00 [ 8#8#..£n8#...... ] 00000040: 48 6F 00 72 00 65 00 64 00 2E 00 0F 00 54 74 00 [ Ho.r.e.d.....Tt. ] 00000050: 78 00 74 00 00 00 FF FF FF FF 00 00 FF FF FF FF [ x.t............. ] 00000060: 07 77 00 2E 00 74 00 68 00 65 00 0F 00 54 79 00 [ .w...t.h.e...Ty. ] 00000070: 2E 00 61 00 72 00 65 00 2E 00 00 00 73 00 74 00 [ ..a.r.e.....s.t. ] 00000080: 06 6F 00 75 00 2E 00 6D 00 61 00 0F 00 54 79 00 [ .o.u...m.a...Ty. ] 00000090: 2E 00 73 00 65 00 65 00 2E 00 00 00 68 00 6F 00 [ ..s.e.e.....h.o. ] 000000A0: 05 6E 00 61 00 6C 00 2E 00 64 00 0F 00 54 6F 00 [ .n.a.l...d...To. ] 000000B0: 74 00 73 00 2E 00 73 00 6F 00 00 00 2E 00 79 00 [ t.s...s.o.....y. ] 000000C0: 04 20 00 77 00 69 00 74 00 68 00 0F 00 54 20 00 [ . .w.i.t.h...T . ] 000000D0: 61 00 64 00 64 00 69 00 74 00 00 00 69 00 6F 00 [ a.d.d.i.t...i.o. ] 000000E0: 03 6F 00 6E 00 67 00 20 00 66 00 0F 00 54 69 00 [ .o.n.g. .f...Ti. ] 000000F0: 6C 00 65 00 20 00 6E 00 61 00 00 00 6D 00 65 00 [ l.e. .n.a...m.e. ] 00000100: 02 74 00 20 00 6F 00 66 00 20 00 0F 00 54 61 00 [ .t. .o.f. ...Ta. ] 00000110: 20 00 76 00 65 00 72 00 79 00 00 00 20 00 6C 00 [ .v.e.r.y... .l. ] 00000120: 01 54 00 68 00 69 00 73 00 20 00 0F 00 54 69 00 [ .T.h.i.s. ...Ti. ] 00000130: 73 00 20 00 61 00 20 00 74 00 00 00 65 00 73 00 [ s. .a. .t...e.s. ] 00000140: 54 48 49 53 49 53 41 54 54 58 54 20 00 84 AA 6E [ THISISATTXT ..ªn ] 00000150: 38 23 38 23 00 00 89 6E 38 23 6B BD 65 00 00 00 [ 8#8#...n8#k½e... ] 00000160: 44 4F 53 4E 41 4D 45 20 45 58 54 20 00 AF E0 6E [ DOSNAME EXT .¯àn ] 00000170: 38 23 38 23 00 00 F4 6E 38 23 53 01 0B 00 00 00 [ 8#8#..ôn8#S..... ]
The first to entries are of course the pointers to the current and the parent directory.
Take a look at the fragments. They are stored backwards before the name used
by DOS - like
this:
LFN-8
LFN-7
LFN-6
LFN-5
LFN-4
LFN-3
LFN-2
LFN-1
DOSNAME
The calculation of the checksums goes like this:
CHECKSUM( name-ext from normal direntry ) checksum = name[1] for i = 2 to 11 do rotate checksum 1 right checksum = checksum + name[i]
I have received this nice Pascal implementation of the checksum calculation from Marcos Moraes (Brazil)
function checksum(Name: string): byte; (* function to calcule CRC of VFAT *) var I, CRC: byte; begin CRC := ord(Name[1]); for I := 2 to length(Name) do begin if odd(CRC) then (* This part is used to rotate CRC bitwise *) CRC := CRC shr 1 + $80 else CRC := CRC shr 1; CRC := CRC + ord(Name[I]); (* sum CRC with the next character. *) end; CheckSum := CRC; end;
My quick (untested) C-hack of it (note - slightly modified algorithm to better match typical C)
char calc_crc(char name[11]) { int i; char csum=0; /* initialise checksum to 0 */ /* while we have not read 11 characters * and we did not receive a null-termination * (for those i... who call us not with a 11-char * array but a null-terminated string) * do the calculation */ for (i=0;i<11 && *name;i++,name++) csum = ( (csum>>1) | ((csum&1)<<7) ) + *(name); return csum; }
This small enhancement of the FAT makes life less troubling for the ordinary user but just illustrates that Win95 did not take us far beyond WfW. Why did they not use either HPFS or NTFS in Win95, one may ask - they deliver much higher performance and advanced facilities like Extended Attributes that would eliminate the dependence on extensions still found in Win95 - why must my text files end with .TXT???. Take a look at OS/2's WPS - it avoids this problem using EA's with WPClassInfo (i thinks it's called). With NTFS you would have gained access restrictions and automatically compression of files. Finally they could have used Ext2 (UNIX/Linux) which supports access restrictions and LFN too.
Another thing that puzzles me is why are the names stored in backwards order? would it not be easier to search if the DOSNAME was stored first with a field containing the number of DE's used for LFN and then the LFN's in forward order??? (turned out it was a caching question - the entries could be cached while searching for the DE).