Long File Names and the Windows VFAT

Materials:
Working complete PC
Blank Diskette
Student Diskette, "New Boot A Ver 2.0+"
Student CD-ROM, "Room 6359"
Objectives:
The student will become familiar with how the system stores long file names,
The student will learn the Windows VFAT and how it works.
Competency:
The student will understand the nature and function of the original FAT12/16/32 file systems and structures physically stored on the drive. The student will learn the nature and function of the Windows VFAT - Virtual File Allocation Table drivers.

    The FAT File Systems

  1. The FAT - File Allocation Table, based file systems have been used since before the IBM PC, but became the standard file system since their introduction as the file system used by DOS on the IBM PC.

  2. The FAT file system began as a way to organize information stored on floppy disks which were a form of random access storage rather than a sequential access storage like tapes. Because the drive can quickly locate any sector without having to go through all of the data in front of it like tapes have to do, it was reasoned that a fast and efficient method of locating the information stored on the disk should be developed. This fast and efficient method of locating information stored on the disk is called a file system.

  3. Instead of having to memorize the sectors where a program is stored, the user only has to remember the name of the file and the file system will retrieve it. Under normal circumstances the user never has to know the actual sectors where the program is located on the disk either.

  4. The FAT file system is one possible solution to this problem, rumor has it that Bill Gates himself invented it as a teenager. In its first form used on floppy diskettes it was called FAT12. FAT12 uses 12-bit numbers in the file allocation table hence the name. Later this kind of file system was expanded upon for use on hard drive partitions. This new form was called FAT16 and as its name implies, it uses 16-bit numbers in the FAT. Finally FAT32, which uses 32-bit numbers in the FAT was developed during the Windows 9x family's run in the mid-90's.

  5. In order to fully understand the FAT file system it is important to remember that the file system is applied to a hard drive partition and that partitions are nothing more than a logical mapping of an area on the hard drive. Partition mappings are called partition tables and these are stored in the Master Boot Record. The MBR is nothing more than the name for the information held in the first physical sector of the hard drive, specifically the sector located at Cylinder=0, Head=0, Sector=1 (in geometric coordinate addressing.)

  6. The MBR also holds the operating system's 1st stage boot strap loader code. This small program is designed to read the partition tables and find the one marked active. Then within that partition table is the address to the first sector of that partition. This is read into RAM and if it passes a simple test, control of the processor is passed to it. This first sector of the active partition is called the DBR - DOS Boot Record, for the DOS/Windows family of operating systems and the VBR - Volume Boot Record for the Windows NT family of operating systems, but they are functionally the same.

  7. The MBR must end in the two bytes "55 AA" in hexadecimal, called the boot signature. Here then is the logical layout of the contents of the first physical sector of a bootable hard drive:






    1st stage OS Boot Strap Loader




    Partition Tables (4, 1 must be marked "active")
    Boot Signature (sector must end in the two bytes "55 AA"

  8. The location and meanings of the values within the partition tables are a published BIOS standard and all MBR's layout are very similar because of this. The first sector of the active partition may be laid out however the OS designers wish. In the case of the Microsoft DOS/Windows family this sector, called the DBR (or VBR for Windows NT) is laid out like this:



    DPB - Drive Parameter Block





    2nd Stage OS Boot Strap Loader



    Boot Signature (sector must end in the two bytes "55 AA"

  9. It is the DPB that indicates where the file system low level structures reside within the partition. These structures include the DPB itself (located within the first sector of the partition which is itself pointed to by the partition table in the MBR), the File Allocation Tables (Microsoft always places two on magnetic storage devices; floppies, hard drives, Zip drives, etc.) The two FAT's are always stored back to back very near the DBR sector. In the case of FAT12 and FAT16 the root directory of the partition is stored immediately behind the 2nd FAT and is fixed in size (specified within the DPB as well.) Here is the layout of a hard drive with a FAT16 Primary DOS partition:

    MBR   DBR FAT#1   FAT#2   ROOT   DC#2   DC#3   ...

  10. The root directory is a small simple database consisting of records. Each record is fixed in size and holds a fixed set of fields including the filename, file extension, file attributes, creation time/date stamp, the file's size in bytes and most importantly of all, its starting FAT entry.

  11. The root directory in FAT16 partitions occupies a certain limited number of sectors. Then the first data sector follows it. If the root directory were not limited in size, but could continue to swell with entries, then they would eventually reach the first data sector occupied by a file and overwrite it. FAT32 has no root directory entry limit, but be very careful about polluting the root especially if you ever want to convert back to FAT16. NTFS has no root directory limit either.
    FAT TypeMax Root EntriesRoot Directory size in Sectors
    FAT1222414
    FAT1651232
    FAT32Unlimited?

  12. The root directory is a simple database file. This means that it stores records. Each record consists of fixed length fields, each field holds one piece of data about the record. The structure looks like this:

    Field NameContentsSize in bytes
    File NameASCII chars8
    File ExtensionASCII chars3
    Attribute bytebit fields1
    Reserved Fieldunknown10
    Time/Date stampencoded values4
    Starting FAT entryword2
    File Lengthdword4

  13. When the OS needs a file it searches the directory entries for the matching FileName field. When the match is found it then matches the File Extension field. Under a DIR command it will check the File attributes to ensure that the file is visible to the user or not. If it must retrieve the file it will check the starting FAT entry. This indicates which allocation unit the file occupies on the hard drive. It will check the like numbered entry in the actual file allocation table to see if there is another occupied allocation unit. If so it will proceed to read that one into RAM and check the corresponding FAT entry. It will continue in this manner until it reaches an EOF - end of file marker indicating that all of the file has been retrieved. The File Attribute byte bit fields are as follows:

  14. So to copy a file, the file system drivers will look through the directory entries until they match the file name and extension specified, they will check the file attributes to make sure that the file is not hidden. If it is hidden then the "File not found" error will displayed and the copy operation will be aborted. If the file is not hidden, then the starting FAT entry will indicate the first occupied cluster. The actual sectors that make up this cluster will be calculated and retrieved into RAM. If the file size is smaller than a cluster, the information already in RAM will be truncated to the file's actual size and copied to the target location. If the file is larger than a cluster, then the corresponding FAT entry will be checked. It will hold the number of the next occupied cluster of the file. The location of the sectors that make up that cluster will be made, the sectors retrieved into RAM and if the file is larger than 2 clusters, they will be copied to the target and the corresponding FAT entry checked for the location of the next occupied cluster number. This will continue until the last cluster is found, it will then be truncated to the actual file size and be copied to the target location.

  15. Example of a file's root directory entry, its FAT entries and its occupied clusters:

    Start of first sector of FAT #1:
    Entry 0 Entry 1 Entry 2 Entry 3 Entry 4 Entry 5 Entry 6 ...
     F8 FF   FF FF   03 00   04 00   FF FF   00 00   00 00 ...
    

    Entries 0 and 1 are reserved and not assocaited with any data clusters. Entry 2 is associated with the first usable data cluster that follows the root directory in the partition. Here is the file's actual root directory record (as seen from DEBUG):

    0B03:0100  46 49 4C 45 20 20 20 20-54 58 54 20 00 00 00 00   FILE    TXT ....
    0B03:0110  00 00 00 00 00 00 5A 4F-73 36 02 00 00 05 00 00   ................ 
    

    The green area holds the file name and extension fields. The red byte is the attribute byte (the file has the Archive bit only) and the blue field is the starting FAT entry, and the yellow field is the file's actual size in bytes. So FILE.TXT is not hidden, starts in data cluster #2 and is 500h bytes (1280) in size.

  16. Assuming that each cluster is one sector in size, this starting FAT entry indicates that the first 512 bytes of the file reside in data cluster #2. This is the first cluster after the end of the root directory itself. According to Entry #2 which is associated with this cluster, the next 512 bytes of the file are located in data cluster #3, the next sector on the drive. This sector will be retrieved, and according to Entry #3, the next part of the file (the remaining 256 bytes are held in data cluster #4. This sector will be retrieved. According to FAT entry #4 (the "FF FF") this is the end of the file.

  17. To further illustrate:

    FAT ROOT DC#2 DC#3 DC#4 DC#5
    F8 FF FF FF 03 00 04 00 ... FILE.TXT...02 00 00 05 00 00 First 512 bytes of FILE.TXT Next 512 bytes Last 256 bytes unrelated data

  18. According to the directory entry noted above, the file starts in Data Cluster #2. According to the FAT Entry #2, it continues in Data Cluster #3. According to FAT Entry #3, it continues in cluster #4. According to FAT Entry #4, it ends within data cluster #4.

  19. In the case of FAT16 each entry is 16 bits or 2 bytes in size. That entry will contain one of the following values:
    Code Means
    0000hCluster is unoccupied and is available for write operation
    0001hReserved for use by the operating system
    0002h-FFF6hIn use by part of a file
    FFF7hHas been marked bad by format or scandisk
    FFF8h-FFFFhIn use by a file and holds the end of the file

  20. By following the codes, the file system drivers can quickly determine which cluster holds the next piece of the file, or if the file ends within the cluster, or if it has been marked bad, or if it is available for use by a new file (or a file that is being modified and getting larger.) In this way the OS can literally chase down each used cluster and stitch the file back together whenever it is called upon to do so.

  21. So far each cluster has consisted of one sector. This however, is rarely the case. In fact FAT started by associating each entry with a raw sector on the drive. But even with FAT16 which can only count from 0 to 65,535 for a maximum theoretical total of 65,536 entries this would only allow for 65,536 sectors in the partition which is: 65,536 x 512 bytes/sector = 32MB. Very small even by the standards of the mid-80's.

  22. To solve this problem, allocation units were invented. The BIOS and DOS natively support the untranslated CHS limits for hard drives of 504MB so a sectors/cluster number could be loaded into the DBR sector's DPB for the file system drivers to read at boot up time. If it is set to 8 for example, then the FAT entries each point to a group of 8 sectors rather than just one. The location of the beginning sector of the next allocation unit is then 8 sectors further down the track. MSDOS.SYS handles the imaginable headache of rapping around to the next head and/or cylinder. Allocation units are always multiples of 2 so that the MSDOS.SYS code can be kept simple (though it certainly wasn't necessary for them to do this). The largest allocation unit for Pure Good Old DOS is 64 sectors/cluster (cluster is the antequated term for allocation unit) or 32KB in size. This allows a maximum theoretical partition size of 2GB. Here is a set of sector/cluster tables:

    FAT16 Cluster Size Chart:
    Partition SizeSectors/clusterCluster Size
    <16MBFAT12FAT12
    16MB to <64MB21KB
    64MB to <128MB42KB
    128MB to <256MB84KB
    256MB to <512MB168KB
    512MB to <1024MB3216KB
    1024MB to <2048MB6432KB

    There are some discrepancies between sources on the cluster size of a partition between 16MB and 128MB. This may be due to the fact that Microsoft modified FAT16 somewhere along the line so that there is an original DOS era FAT16 and a new and improved FAT16 (Powerquest calls it FAT16X). The entry highlighted in red is related to the virtual memory optimization strategy.

    FAT 32 Cluster Size Chart:
    Partition SizeSectors/clusterCluster Size
    <512MBFAT16FAT16
    512MB to 8GB84KB
    8GB to 16GB168KB
    16GB to 32GB3216KB
    >32GB6432KB

    The largest possible FAT32 partition according to Microsoft is 2TB. The maximum number of FAT32 entries in the file allocation table is 524,208 (not 232=4,294,927,296) due to the fact that the file system only actually uses the lowest 28-bits of each entry and the EOF marker is FFF7h-FFFFh and other such values are reserved for use by the OS.

    NTFS Cluster Size chart:
    Partition SizeSectors/clusterCluster Size
    <512MBFAT16FAT16
    512MB to 1GB21KB
    1GB to 2GB42KB
    >2GB84KB

    NTFS does not use a File Allocation Table. It is a completely different file system that uses totally different methods of organizing files within the partition. Instead it uses a Master File Table which is functionally quite different. It more resembles a blend of the root directory entries in which each holds an entire miniature FAT table for the file. The MFT entry also holds security information which allows the file system to determine if a user has the right to "see" a file listed within a window (or DIR listing in a DOS box). The NTFS MFT has within it the functionality of a 64 bit FAT meaning that the maximum theoretical partition size is: 264=16 exabytes or 18,446,744,073,709,551,616 bytes which is probably big enough. It is also as large as EDD BIOS mentioned under the LBA discussion.

  23. The Windows VFAT

  24. Windows has the ability of the system to store files with names longer than the old DOS 8.3 naming rule (8 character file name period 3 character extension.) The interesting thing about the Windows LFN (Long File Name) file system is that the low level structures that store the file names and directories, have the same exact layout as they did in a pure DOS file system. That is to say, that on the physical disk, the file system is still exactly FAT16 or FAT32 with no changes.

  25. As a result of this, pure DOS can access a FAT16 partition that has been set up by Windows. This allows for systems to be set up for dual booting to either DOS or Windows, as well as the ability to access and rescue data files from a system in which Windows has become damaged and will no longer boot up.

    The LFN driver is the VFAT - Virtual File Allocation Table, driver. The VFAT driver does not just handle LFN's, it is also responsible for the management of the vache driver, the 32-bit integrated version of SMARTDRV.EXE. It is also responsible for detecting improper shut down of the system.

  26. The realmode VFAT driver is IFSHLP.SYS which must be launched by IO.SYS early in the Windows 98 boot sequence so that all files with long names can be accessed during the boot process.

  27. The way the LFN driver works is quite interesting. It turns out that there is a particular combination of file attributes that when given to a file are both an illegal combination and they will be ignored by DOS. This second point is very significant. This means that information can be stored in extra directory entries and DOS will see these while reading the directory and discard the entries as invalid without throwing a fit and displaying error messages all over the screen. It will quietly keep on working despite what it sees. This behavior is what allowed the LFN support to be developed quickly and easily for the early versions of Windows residing on FAT based file systems.

  28. The invalid file attribute combination used by the VFAT drivers is: Volume Label + System + Hidden + Read-Only. When a directory entry is marked as a file that has all of these attributes (a system, hidden, and read-only volume label is not what DOS expects a volume label to be) DOS will discard the entry. Since the entire entry gets ignored by DOS the Windows VFAT drivers do the following when a file is saved to the directory that has a filename that would be illegal to DOS:

    • Create a DOS legal 8.3 filename for the file. In the case of a directory named "Program Files" there are two problems with it. One; it is too long. Two; it contains an illegal character, the space. So the VFAT drivers will take the first 6 legal characters in the name and then attach a tilde (~) and a number starting with 1 to create an 8 character legal name for the file. If the first six characters in the name contain lower case letters they will be kept and converted to uppercase (since lower case letters are illegal in DOS file names). So the legal DOS name for the directory "Program Files" created by the VFAT drivers would be: "PROGRA~1"

    • Calculate how many extra directory entries will be needed in order to store the long file name. Each LFN entry can hold a maximum of 13 characters, but they are not stored as ASCII. Instead they are stored as Unicode characters. Unicode is a form of binary storage of language characters just like ASCII. But where ASCII uses a byte to store a letter (character), Unicode uses 2 bytes or 16-bit values to store each character. This allows Unicode to store a character set with up to 65,536 different characters. While we Westerners can't appreciate this, the Chinese sure do!

    • Store the last entry first in the next available (empty) entry in the directory, followed by the next to the last entry, and so on up to the first LFN entry which is then followed by the pure DOS 8.3 entry. This is a "real" directory entry that contains the file's true information (size, starting FAT entry point, etc).

    When the system boots to pure DOS mode, the full LFN driver set does not load (IFSHLP.SYS contains just enough code to allow the Windows boot process to work, but DOS cannot use it.) It can still access all files on the drive but only the pure DOS 8.3 names will show up. Any file with an LFN entry will have a "name tail" (end in "~n"). If two files would end up getting the same pure DOS name such as "Program Files" and "Program Source Files" then the second entry being created will get the same truncated name which would create a duplicate so then the VFAT will count up to the next available digit to go in the name after the tilde. So "Program Source Files" will get "PROGRA~2" for its pure DOS name.

  29. Experiments with the Windows VFAT

  30. In Windows format a bootable floppy diskette. First open My Computer, then right click on it and select "Format..." in the resulting box be sure to select "Quick format" in the "Format Type" box and fill in the Label textbox with 11 "@" symbols and in the "Other Options" box check the "Copy system files" check box then click the Start button. When the diskette's format is complete click the Close button on the summary results box and then Close on the Format window.

  31. Now open Notepad and type 11 "#" symbols into the contents of the file. Click File > Save As... > Save. The file was saved as "Untitled.txt in My Documents.

  32. Close Notepad and open My Documents. Be sure that the "Show all Files" modification has already been done. (See Configuring Windows) Right click on the file and select Rename:

  33. With the file name selected, press and hold the [z] key renaming it "zzzzzzzzzz..." until the box stops adding z's to the name. At this point the file has the longest Long File Name that the VFAT drivers will allow:

  34. Press [enter] to save the new name. With Windows explorer configured so that it is not hiding known file extensions, the ".txt" extension has also been changed. Since extensions are used to associate a data file with the proper executable to be used to open it when it is double clicked, Windows warns the user that changing the extension will change the application that will be automatically used to open it. Click the OK button:

  35. Now single click the file to select it. Now press [Ctrl]+[C]. This is the Copy command, the file has been copied to the Windows clipboard. Now press and hold the [Ctrl] key and then type the [V] key about 20 times. This is the Windows Paste command and Windows will paste 20 copies of the file in the current directory. Note that it automatically renames them to "Copy (x) of ..." because every file must have a unique name within the same directory:

  36. Now click the Edit main menu choice and in the pop down menu click Select All. Now right click on any of the selected files and hover the mouse over the Send To choice, then click on the "3½ Floppy (A:)" choice:

  37. Windows displays a file copy progress box:

  38. All of these little files (each only 11 bytes in length) should easily fit on a 1.44MB floppy diskette, but:

  39. Obviously they don't. This is because they are being copied to the root directory of the floppy which has a limit of 224 entries. But the bootable diskette had 3 or 4 files (IO.SYS, MSDOS.SYS, COMMAND.COM and sometimes DRVSPACE.BIN) and they copy only requested 20 more files. So the root directory should not run out of room, unless the files have long file names and the extra information of the LFN's is being stored in directory entries, which is exactly what the VFAT drivers do and exactly why the root ran out of room to store them. Restart the machine in MSDOS Mode and run DEBUG:

    C:\WINDOWS>debug
    -_
    
    
  40. At the DEBUG "dash prompt" enter the command "L 100 0 13 2" which instructs DEBUG to Load into RAM address offset 100h from the A: drive (A: = 0, B: = 1, C: = 2, etc.) the sector(s) starting with sector 13h and load 2 sectors. This is a raw sector read of the floppy diskette and we are reading the first 2 sectors of the root directory into RAM:

    C:\WINDOWS>debug
    -L 100 0 13 2
    -_
    
    
  41. Now display the top half (256 bytes) of the first sector of the root directory on screen:

    C:\WINDOWS>debug
    -L 100 0 13 2
    -D 100 1FF
    0F6D:0100  49 4F 20 20 20 20 20 20-53 59 53 27 00 00 00 00   IO      SYS'....
    0F6D:0110  00 00 00 00 00 00 C0 B2-97 26 02 00 B6 64 03 00   .........&...d..
    0F6D:0120  4D 53 44 4F 53 20 20 20-53 59 53 27 00 00 00 00   MSDOS   SYS'....
    0F6D:0130  00 00 00 00 00 00 C0 B2-97 26 00 00 00 00 00 00   .........&......
    0F6D:0140  44 52 56 53 50 41 43 45-42 49 4E 27 00 00 00 00   DRVSPACEBIN'....
    0F6D:0150  00 00 00 00 00 00 C0 B2-97 26 B5 01 07 0D 01 00   .........&......
    0F6D:0160  43 4F 4D 4D 41 4E 44 20-43 4F 4D 20 00 00 00 00   COMMAND COM ....
    0F6D:0170  00 00 00 00 00 00 C0 B2-97 26 3C 02 C2 6E 01 00   .........&<..n..
    0F6D:0180  40 40 40 40 40 40 40 40-40 40 40 28 00 00 00 00   @@@@@@@@@@@(....
    0F6D:0190  00 00 00 00 00 00 01 60-75 36 00 00 00 00 00 00   .......`u6......
    0F6D:01A0  53 7A 00 7A 00 7A 00 7A-00 00 00 0F 00 44 FF FF   Sz.z.z.z.....D..
    0F6D:01B0  FF FF FF FF FF FF FF FF-FF FF 00 00 FF FF FF FF   ................
    0F6D:01C0  12 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:01D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:01E0  11 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:01F0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    -_
    
    
  42. These are the raw root directory entries of the files. IO.SYS is the first one. Each field is highlighted below to illustrate them clearly:

    0F6D:0100  49 4F 20 20 20 20 20 20-53 59 53 27 00 00 00 00   IO      SYS'....
    0F6D:0110  00 00 00 00 00 00 C0 B2-97 26 02 00 B6 64 03 00   .........&...d..
    

    The first yellow field is the eight byte wide filename field. It is ASCII code which DEBUG displays to the far right. The field hold the file's name "IO" in this case and is padded with spaces which are ASCII code 20h. DOS is allowed to use spaces in filenames but not the user! The next yellow field is the file extension, "SYS" in this case. The red field is the file attribute field. This is displayed in hex, but each bit has a meaning so it must be changed from hex to binary:

    File Attribute byte in hex: 27
                               /  \
                              /    \
                         0 0 1 0  0 1 1 1
    Bit Meanings:        x x A D  V S H R
    
  43. So the file has the A = Archive bit set meaning that it has been newly copied onto the diskette. Backup software can be set to only backup files with the archive bit set and also turn the bit off. So if the file does not change between backups it will not get backed up again. The file also has the System, Hidden, and Read-Only bits set which is exactly what is expected of IO.SYS.

  44. The green field is the time/date stamp. It is bit fielded and if the actual bit fields are needed they can be found at Microsoft's website. The blue field is the starting FAT entry/Cluster Number field. Remember that Intel processors store 16-bit values, byte reversed so this field holds 02 00 =x=> 00 02 and indicates that the first part of the file occupies data cluster #2. The orange field indicates the file's size in bytes. This is a 32-bit value which when byte reversed yields: B6 64 03 00 =x=> 00 03 64 B6. Converted to decimal this value is: 222,390 bytes. When a DIR /AH is executed from the prompt, this is the size that the command reports.

  45. Each directory entry occupies two full lines of the raw hex display. So the next two lines are the directory entry for MSDOS.SYS, the next two are the entry for COMMAND.COM and the next two are for the file DRVSPACE.BIN. The next two lines are the root directory entry for the volume label. Count across the filename and file extension fields (the 11 ASCII code 40's) and the next byte is "28." This is the entry's file attributes and don't forget it is hexadecimal. When converted into binary and compared with the bit field meanings it reveals:

    File Attribute byte in hex: 28
                               /  \
                              /    \
                         0 0 1 0  1 0 0 0
    Bit Meanings:        x x A D  V S H R
    
  46. It is then marked correctly as the volume label of the diskette. Also note on the second line of the entry that it has a time/date stamp but the starting FAT entry field is zero and the file size field is also zero. This makes sense since it is only a volume label and it is not the entry for a file or subdirectory and therefore does not occupy any clusters on the diskette and it has no size either.

  47. The next entry and the entries below it are quite strange looking. That is because they are a file's Long File Name. These are even stranger than they look because they are stored backwards. Display the next 256 bytes of the root directory:

    -D 200 2FF
    0F6D:0200  10 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0210  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0220  0F 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0230  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0240  0E 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0250  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0260  0D 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0270  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0280  0C 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0290  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:02A0  0B 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:02B0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:02C0  0A 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:02D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:02E0  09 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:02F0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    -_
    
  48. More LFN entries of some file, but we have not reached its "true" directory entry yet. Display the next 256 bytes:

    -D 300 3FF
    0F6D:0300  08 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0310  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0320  07 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0330  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0340  06 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0350  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0360  05 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0370  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0380  04 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0390  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:03A0  03 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:03B0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:03C0  02 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:03D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:03E0  01 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:03F0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    -_
    
  49. It had quite a long Long File Name! Display the next 256 bytes:

    -D 400 4FF
    0F6D:0400  5A 5A 5A 5A 5A 5A 7E 31-20 20 20 20 00 60 8A 61   ZZZZZZ~1    .`.a
    0F6D:0410  75 36 75 36 00 00 D9 60-75 36 F4 02 0B 00 00 00   u6u6...`u6......
    0F6D:0420  53 7A 00 7A 00 00 00 FF-FF FF FF 0F 00 AC FF FF   Sz.z............
    0F6D:0430  FF FF FF FF FF FF FF FF-FF FF 00 00 FF FF FF FF   ................
    0F6D:0440  12 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 AC 7A 00   .z.z.z.z.z....z.
    0F6D:0450  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0460  11 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 AC 7A 00   .z.z.z.z.z....z.
    0F6D:0470  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0480  10 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 AC 7A 00   .z.z.z.z.z....z.
    0F6D:0490  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:04A0  0F 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 AC 7A 00   .z.z.z.z.z....z.
    0F6D:04B0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:04C0  0E 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 AC 7A 00   .z.z.z.z.z....z.
    0F6D:04D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:04E0  0D 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 AC 7A 00   .z.z.z.z.z....z.
    0F6D:04F0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    
  50. Finally the "true" directory entry has been reached for the file. The one right there at the top. Here are the highlighted fields to illustrate:

    0F6D:0400  5A 5A 5A 5A 5A 5A 7E 31-20 20 20 20 00 60 8A 61   ZZZZZZ~1    .`.a
    0F6D:0410  75 36 75 36 00 00 D9 60-75 36 F4 02 0B 00 00 00   u6u6...`u6......
    
  51. The VFAT drivers did take the first six legal characters of the orginal LFN and in this case convert them to upper case and then add the "~1" The attribute is a normal file with only the Archive bit set. And the file has an actual starting FAT entry number of F4 02 =x=> 2F4 and a file size of 0B = 11 bytes. Preceding this entry starting with the last LFN entry and counting down to LFN entry #1 are the entries that store the file's Long File Name. Display the RAM offsets from 320 to 41F so that they can be seen residing in front of the "true" directory entry more clearly:

    -D 320 41F
    0F6D:0320  07 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0330  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0340  06 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0350  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0360  05 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0370  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0380  04 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0390  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:03A0  03 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:03B0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:03C0  02 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:03D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:03E0  01 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:03F0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0400  5A 5A 5A 5A 5A 5A 7E 31-20 20 20 20 00 60 8A 61   ZZZZZZ~1    .`.a
    0F6D:0410  75 36 75 36 00 00 D9 60-75 36 F4 02 0B 00 00 00   u6u6...`u6......
    -_
    
  52. The first byte of each LFN entry is numbered sequentially starting with the first one which is the one numbered "01" that immediately precedes the "true" entry. The one in front of that one is the next one numbered "02" and so on. Display the 256 bytes in front of the ones currently being displayed:

    -D 220 31F
    0F6D:0220  0F 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0230  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0240  0E 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0250  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0260  0D 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0270  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0280  0C 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0290  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:02A0  0B 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:02B0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:02C0  0A 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:02D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:02E0  09 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:02F0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0300  08 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0310  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    -_
    
  53. This holds the entries numbered from 15 (0F) down to 8. Display the next 256 bytes up:

    -D 120 21F
    0F6D:0120  4D 53 44 4F 53 20 20 20-53 59 53 27 00 00 00 00   MSDOS   SYS'....
    0F6D:0130  00 00 00 00 00 00 C0 B2-97 26 00 00 00 00 00 00   .........&......
    0F6D:0140  44 52 56 53 50 41 43 45-42 49 4E 27 00 00 00 00   DRVSPACEBIN'....
    0F6D:0150  00 00 00 00 00 00 C0 B2-97 26 B5 01 07 0D 01 00   .........&......
    0F6D:0160  43 4F 4D 4D 41 4E 44 20-43 4F 4D 20 00 00 00 00   COMMAND COM ....
    0F6D:0170  00 00 00 00 00 00 C0 B2-97 26 3C 02 C2 6E 01 00   .........&<..n..
    0F6D:0180  40 40 40 40 40 40 40 40-40 40 40 28 00 00 00 00   @@@@@@@@@@@(....
    0F6D:0190  00 00 00 00 00 00 01 60-75 36 00 00 00 00 00 00   .......`u6......
    0F6D:01A0  53 7A 00 7A 00 7A 00 7A-00 00 00 0F 00 44 FF FF   Sz.z.z.z.....D..
    0F6D:01B0  FF FF FF FF FF FF FF FF-FF FF 00 00 FF FF FF FF   ................
    0F6D:01C0  12 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:01D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:01E0  11 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:01F0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    0F6D:0200  10 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:0210  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    -_
    
  54. This holds the entries from the last one numbered "53" down to number 16 (10 in hex don't forget.) Concerning the last entry numbered 53h, converting this number into binary reveals:

    LFN sequence number byte in hex: 53
                                    /  \
                                   /    \
                              0 1 0 1  0 0 1 1
                                ^
                                |
                          if this were 0
                        the number would be
                              0 0 0 1  0 0 1 1 = 13h
    
  55. The bits are numbered bit #7 is the highest and bit #0 within the byte is the lowest, so it can be seen that bit #6 is used to indicate that the entry is the last one in the sequence of entries that hold the LFN, and that this is entry number 19 (13h). Each entry, looking at entry number 18 (12h) holds a maximum of 13 characters highlighted in green below. The LFN entry number is highlighted in blue and the file attribute byte for the entry is highlighted in red:

    0F6D:01C0  12 7A 00 7A 00 7A 00 7A-00 7A 00 0F 00 44 7A 00   .z.z.z.z.z...Dz.
    0F6D:01D0  7A 00 7A 00 7A 00 7A 00-7A 00 00 00 7A 00 7A 00   z.z.z.z.z...z.z.
    
  56. Each character is not stored in ASCII code since each one occupies 2 bytes instead of one. LFN characters are therefore stored in another kind of encoding called Unicode. In Unicode, each character is stored as a 16-bit number (2 bytes) and the driver must load a code page. The code page is then used to look up the code value and find the actual bit map of the character to be displayed on screen (the exact same process used in ASCII as well except that the BIOS has the look up code page for ASCII) Windows out of the box, without setting it up for an alternate language, uses the code page called "ISO-Latin 1282" which defines the basic letter set used in English with the same numbers as those in the ASCII code set, that is why DEBUG can display the lower case z's down the right hand columns of the display. But Unicode, being a 16-bit code can hold values from zero to 65,535 for a total of 65,536 different characters. This allows Windows and the VFAT driver to support many of the world's languages including Chinese.

  57. The file attribute byte for the entry holds the value 0F. When converted into binary this reveals:

    File Attribute byte in hex: 0F
                               /  \
                              /    \
                         0 0 0 0  1 1 1 1
    Bit Meanings:        x x A D  V S H R
    
  58. The reason the VFAT driver's support for LFN's can stuff these entries into the actual FAT file system directory entries is because real DOS sees this directory entry stuffed with illegal characters, but before it can complain about it, it checks the file attrbutes and finds that it has been marked as a volume label and as a system file. This is certainly illegal, but it is also marked as hidden, which means it has to keep this hidden from the user. Therefore DOS decides to simply ignore the entire entry. This behavior is critical since it allows the VFAT's storage of LFN's within the physical file system without upsetting or crashing true DOS making it fully backwards compatible and capable of booting up in "MS-DOS Mode" or "Command Prompt Only" as they put it.

  59. Another operation that falls under the responsibilities of the Windows VFAT driver is the maanagement of all open files moving through the vcache driver. The vcache driver is a powerful 32-bit version of the old DOS SMARTDRV.EXE driver. One of the main differences in how it works is that it is not only a read-ahead disk cache, it is also a write-back cache. This means that changes that are to be written to the actual file stored on the disk are not always immediately committed to the disk but are held up in a queue in the vcache RAM and then filter down to the disk once a group have been collected that make it worth moving the heads for. This reduces wear and tear on the drive head assembly but, since changes to files are not always immediately written out to the disk, it makes it much more likely that a file (or many) could get corrupted if the power is suddenly interrupted. Because of this, the VFAT drivers change a bit at the beginning of the file allocation table from a one to a zero as they initialize. When the system is properly shut down, the VFAT drivers then close all open files and flush the contents of the vcache buffer out to the disk and then change the zero back to a one, then they pass control to the ATX driver that turns the machine off. So if the machine suddenly loses power, they VFAT driver would never get the chance to change the bit back to a one and it would be caught with a zero in it. WIN.COM checks for this FAT bit and if it finds it is a zero instead of a one, it will punish you and admonish you for shutting down Windows improperly and run SCANDISK.

  60. To test the theory, open the first sector of the FAT of the C: drive and display the top half of it on screen:

    -L 100 2 20 1
    -D 100 1FF
    0F6D:0100  F8 FF FF 0F FF FF FF 0F-FF FF FF 0F 04 00 00 00   ................
    0F6D:0110  05 00 00 00 06 00 00 00-07 00 00 00 08 00 00 00   ................
    0F6D:0120  09 00 00 00 0A 00 00 00-0B 00 00 00 0C 00 00 00   ................
    0F6D:0130  0D 00 00 00 0E 00 00 00-0F 00 00 00 FF FF FF 0F   ................
    0F6D:0140  11 00 00 00 12 00 00 00-13 00 00 00 14 00 00 00   ................
    0F6D:0150  15 00 00 00 16 00 00 00-17 00 00 00 18 00 00 00   ................
    0F6D:0160  19 00 00 00 1A 00 00 00-1B 00 00 00 1C 00 00 00   ................
    0F6D:0170  1D 00 00 00 1E 00 00 00-1F 00 00 00 20 00 00 00   ............ ...
    0F6D:0180  21 00 00 00 22 00 00 00-23 00 00 00 24 00 00 00   !..."...#...$...
    0F6D:0190  25 00 00 00 26 00 00 00-FF FF FF 0F 28 00 00 00   %...&.......(...
    0F6D:01A0  FF FF FF 0F FF FF FF 0F-FF FF FF 0F 2C 00 00 00   ............,...
    0F6D:01B0  2D 00 00 00 2E 00 00 00-2F 00 00 00 30 00 00 00   -......./...0...
    0F6D:01C0  31 00 00 00 32 00 00 00-33 00 00 00 34 00 00 00   1...2...3...4...
    0F6D:01D0  35 00 00 00 36 00 00 00-37 00 00 00 38 00 00 00   5...6...7...8...
    0F6D:01E0  39 00 00 00 3A 00 00 00-3B 00 00 00 3C 00 00 00   9...:...;...<...
    0F6D:01F0  3D 00 00 00 3E 00 00 00-3F 00 00 00 40 00 00 00   =...>...?...@...
    -_
    
    
  61. NOTE: This only works on the drives in the classroom! Now change the eighth byte on the first row which currently reads "0F" or 0 0 0 0 1 1 1 1 to read "07" or 0 0 0 0 0 1 1 1. This means that bit #3 is the one that the VFAT drivers manipulate:

    -E 107 07
    -_
    
    
  62. Now write the modified sector back to the hard drive then quit DEBUG and start Windows by executing WIN.COM at the prompt:

    -W 100 2 20 1
    -Q
    C:\WINDOWS>win
    
    
  63. Shortly after launching WIN.COM, SCANDISK will launch indicating that it was indeed bit #3 of the eighth byte of the File Allocation Table that caused WIN.COM to launch SCANDISK and it is this bit that the VFAT drivers manipulate. When SCANDISK is done, WIN.COM will continue launching Windows up to the desktop and the VFAT drivers will again hold the bit at zero. Properly shut down the machine and restart in MS-DOS Mode and run DEBUG and check the value. It will be "0F" again.

  64. Back to top

    Copyright©2000-2007 Brian Robinson ALL RIGHTS RESERVED