Naming in Windows 2000 file systems is a seemingly simple process that is surprisingly complicated in reality. One of the aspects of naming that often confuses people is that in the Windows 2000 file systems, each file can have two names: one name is the “long file name” (LFN) and if the LFN is not compliant with the DOS 8.3 name semantics, there is a second “short file name” (SFN). Thus, each file can be referred to using either one of these names.
The confusion begins to arise when we begin to perform operations on those files using both 16 and 32-bit application programs. After all, 16 bit applications can only use the SFN variant, not the LFN variant. If a 16-bit application modifies a file that has both an LFN and an SFN, it does so by using the SFN – yet, how does the file system keep from losing the matching LFN information?
File systems achieve this “sleight of hand” by using the File System Runtime Library (FsRtl) “tunnel cache,” which is a mechanism introduced to allow the preservation of LFN and SFN names when a file is being used in an environment where both 16 and 32-bit applications are accessing the same files.
For example, suppose that a 32-bit application creates a file “Sarsaparilla Performance Report.doc.” Subsequently, a 16-bit application is used to modify the contents of that file. It does this by following a “classic” pattern for editors:
· it renames the original file using a “.bak” suffix;
· it creates a new file, using the original file name;
· it writes the contents to the new file
The issue here is that the new file will be created with the same SFN. Of course, to preserve compatibility with 32-bit applications, it is best if the original LFN is also restored.
The Windows 2000 file systems do, in fact, preserve the LFN! This is done using a technique known as “name tunneling” and is implemented as a series of FsRtl routines that are responsible for managing a name tunnel cache. File systems, and file system filter drivers, need to be aware of this behavior. File systems also should be aware of these routines and how they are to be used within the file system.
The tunnel cache is managed and maintained by the functions:
· FsRtlInitializeTunnelCache – this is used to initialize the tunnel cache on a per volume basis;
· FsRtlAddToTunnelCache – this is used to add an entry to the tunnel cache;
· FsRtlFindInTunnelCache – this is used to look up an entry in the tunnel cache;
· FsRtlDeleteKeyFromTunnelCache – this is used to clean up all entries for a given directory that might be in the tunnel cache;
· FsRtlDeleteTunnelCache – this is used to delete the tunnel cache when the volume data structures are being deleted
Using the tunnel cache is actually fairly simple for a file system. The only two events that normally trigger inserting an entry into the tunnel cache are a deletion operation on a file and a rename operation on a file.
We can observe both of these within the FAT file system. In cleanup.c we see two calls to FAT’s FatTunnelFcbOrDcb (which in turn is FAT’s wrapper around the call to FsRtlAddToTunnelCache). In both cases within cleanup.c, it is done immediately prior to the FAT internal call FatDeleteDirent (which is how FAT deletes the file from the directory, after freeing all of its data blocks).
In fileinfo.c, we see this call associated with the rename operation – essentially any rename operation will insert data into the tunnel cache.
Once an entry is inserted into the tunnel cache, it remains there for a short period of time (where that period of time is a function of the implementation of the tunnel cache, but it is on the order of 10 seconds or so). In addition, the tunnel cache size is limited in size (256 entries on Professional, 1024 on the Server platforms) and additional entries cause an LRU-style recycling scheme to be implemented.
The two cases in which the FAT file system checks the tunnel cache are when a file is being newly created and renamed.
What is interesting about the tunnel cache is that it is keyed based upon both the SFN and LFN. Thus, the tunnel cache is used to preserve not only long file names, but also short file names. In addition, when the FSD inserts an entry into the tunnel cache, it associates “extra” information with the file. This can include any information the file system chooses to maintain within that tunnel cache and typically includes any attributes of the file that the FSD wishes to preserve. For example, FAT preserves the creation time of the file. NTFS also preserves the object ID of the file in addition to its creation time.
Utilizing this within a file system allows better coexistence between 16-bit and 32-bit applications. While not necessary for correct behavior, by supporting this feature, a third-party file system more closely mimics the behavior of the Windows 2000 file systems.