Working with 8.3 (a.k.a. compatibility, short) filenames on Windows systems has been an evolving task since their introduction in Windows 95 as part of the long filename (LFN) feature set. The 8.3 name was required for down-level compatibility with earlier systems, which did not understand LFNs, and in fact could easily crash trying to manage LFNs.
There are several registry settings that control if and how 8.3 names are built. For those programmers who care about such things, Windows Vista and Server 2003 introduced a new feature: per-volume 8.3 name support. When 8.3 name support occurs on a per-volume basis, that information is stored in a newly-defined, but poorly documented location in the volume header. This project shows you how to find and interpret this setting for any Windows-supported disk volume.
For programmers who care about 8.3 name generation, Windows exposes its various 8.3 configuration options through a series of Registry keys, all found in HKLM\System\CurrentControlSet\Control\FileSystem. The values used include:
NameNumericTail, Win95TruncatedExtensions and
NtfsDisable8dot3NameCreation (among others). This article deals only with
NtfsDisable8dot3NameCreation and new values exposed with the release of Vista.
Before Vista and Windows Server 2003,
NtfsDisable8dot3NameCreation could be 0 (create 8.3 names on all volumes) or 1 (no 8.3 names are created on any volumes); the default was 0. Vista and Server 2003 defined two new values: 2 (8.3 name support is enumerated per-volume) and 3 (only the system volume creates 8.3 names). With the new value
NtfsDisable8dot3NameCreation = 2 (which became the new default value), Microsoft failed to release any documentation explaining how one might enumerate the per-volume settings. This sample code shows you how query a Windows disk volume for its 8.3 configuration when
NtfsDisable8dot3NameCreation = 2.
Using the Code
The code as supplied builds as a C++ Win32 console application; the sample source project was built with VS 2005. While it is not complied for Unicode, it should work fine without modification in a Unicode build. If your application supports the specialized NTFS path name convention (e.g. along with c:\windows\explorer.exe, you support names in the format \\?\c:\windows\explorer.exe), then you should change
#define _MAX_PATHBUF _MAX_PATH in Is8dot3.h to
#define _MAX_PATHBUF 32768 (or whatever buffer size your application supports for paths); you'll also need to build Is8dot3.cpp for Unicode. Note that unless you rebuild this sample for Unicode, the \\?\c:\windows\explorer.exe style for pathnames will fail with an error.
The sample Console application takes as its argument any relative or absolute pathname. It breaks the path down to discover its underlying volume mount point (with the call to
TranslatePathToVolume()). The volume mount point is opened, and then the magic (i.e. very poorly documented) call to
FSCTL_QUERY_PERSISTENT_VOLUME_STATE is made via
DeviceIOControl(). What little documentation there is was -- insofar as I can tell -- was first described by Alan Brown, who was kind enough to not only direct me to the Microsoft DDK include file required, but also sent me his prototype code. Is8dot3.cpp is based on that prototype.
DeviceIOControl call for
FSCTL_QUERY_PERSISTENT_VOLUME_STATE returns a
FILE_FS_PERSISTENT_VOLUME_INFORMATION structure on Vista and later versions of Windows; on earlier versions it returns an error (e.g. on XP, it returns error code 1: incorrect function). The
VolumeFlags member of this structure contains persistant state flags; the one we are looking for is
PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED. If it is set, then this volume does not support creation of 8.3 names. If it is clear, then this volume does support 8.3 name creation. Testing on FAT volumes under Windows 7 shows that this call seems to work for FAT as well as NTFS. This testing was not exhaustive.
On pre-Vista systems, there is no
PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED bit stored per-volume. On such systems, one should not find
NtfsDisable8dot3NameCreation = 2 in the registry. If a disk formatted on a down-level system is mounted on Vista or later systems, it is unclear to me how those disks are treated. My best guess is that they are treated as if the
PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED bit is zero (i.e. 8.3 names are enabled). Further testing with this demo application using such disks would quickly reveal how they are handled.
The Windows Server 2003 TechNet article NtfsDisable8dot3NameCreation describes how one can use the Win32 console application FSUtil.exe to query and set the 8.3 name creation, including the persistant per-volume support bit. Remember that
IsVolume8dot3() returns the setting for any given volume, but the overall 8.3 name support depends on other factors (including the value of
NtfsDisable8dot3NameCreation). FSUtil.exe may also be used on down-level created disk volumes attached to Vista (or later) systems to determine how Windows deals with the lack of a
PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED bit on such a volume.
Points of Interest
This code works only for local drives; it will fail on a UNC pathname.
- 20th December, 2011 - Initial release
- 27th December, 2011 - Updated article
I've been writing code as a hobby or for a living since 1970, working in machine code (octal input on a Compucorp programmable calculator), Assembler, Fortran (various flavors), Basic, APL, C, C++, Java, C#, PL/1 and others over the years. OS's used (sometimes as little as possible) include none (when writing machine code), IBM System/360 & 370 (with keypunch and TSO), OS/360 (really don't miss JCL), VM/CMS, DG RDOS, Unix, VAX/VMS, PC-DOS, MS-DOS and the many flavors of Windows.