Filenames are stored in the MFT in the $30 attribute of the file record. Before Windows 10 a file record would most often have two $30 attributes, the first one for the 8.3 filenames and - if the length of the filename exceeded 8 characters - a second one for the long filename. (More $30 attributes are possible if hard links are present).
This has changed in Windows 10. Both the 8.3 and the long filename are stored in one $30 attribute (unless the creation of 8.3 filenames has been switched off in the registry).
This leaves me with 2 questions:
- How do you extract the 8.3 filenames from the $30 attribute?
- Apparently there existed versions of Windows 10 with still two $30 attributes. At what point did that change?
Frankly, I was hoping that MFT expert Sebastian-Laurenţiu Plesciuc would come along to my rescue, but he hasn't and I haven't found any means to attract his attention, so I had to find out myself.
The answer is given in the Documentation of the Linux-NTFS Project which is quoted here.
In the standard header of the $FILE_NAME attribute you'll find at the offset 0x41 the Filename Namespace member with possible values ranging from 0 to 4:
The vast majority of files on today's drives will comprise files from the POSIX namespace. Please note the difference between NTFS as a file system and Windows as an operating system. Unlike Windows NTFS is case sensitive and has almost no restrictions concerning file naming. Apparently it is possible to use filenames in the MFT that are not legal in the Windows environment.
Namespace 0 and 1 filenames are the usual long filenames exceeding 8 characters. Namespace 2 filenames are the typical uppercase 8.3 names (FILENA~1.TXT) from the DOS era. Namespace 3 filenames just don't exceed 8 characters. Namespace 2 and 3 filenames are restricted to the ANSI character set.
Now, how do you read 8.3 filenames of Namespace 0 or 1 filenames from the MFT in Windows 10? Well, you simply don't. You build them from the long filenames following the recipy given in the documentation: