2

I recently discovered that due to backward compatibility with DOS, the Windows OS has some reserved keywords that cannot be created in the file system, since these were originally used to write streams of data to other hardware like printers. Microsoft states that you cannot name a folder nor a file (regardless of extension) with the following reserved keywords: CON, PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9. If you try to create one of these in Windows explorer you should receive the error message "the specified device name is invalid".

However, using Windows Explorer (Windows 11) I was actually able to create all of them as files as long as they had an extension, and I could create some of the folders named COM0-COM9.

I wanted to know if there were any safeguards to help avoid accidentally creating these folders in Java, and first checked if the java.io.File or java.nio.file.Path classes would throw exceptions like InvalidPathException when trying to store any of these reserved keywords. No exceptions were thrown.

So then I was curious to see if I could use File.mkdir (and Files.createDirectories) to create any of these invalid files, and I could. In fact they all returned true for success, and I can view them all in Windows Explorer fine, except for NUL which seems to be the only case that wasn't created.

My question is, are there any risks on modern Windows when creating one of these 'illegal" names? Why doesn't Microsoft's own documentation match my results, is it a recent update in Windows 11? What kinds of bugs might happen or go unnoticed if I don't add my own safeguards? Are Unix/macOS plagued with any of these reserved keywords?

Here is a passing unit test:

@Test
public void test() throws IOException {
    Path dirTest = Paths.get("C:\\Testing");
    File fNul = dirTest.resolve("NUL").toFile();
    assertTrue(fNul.mkdir());
    assertFalse(fNul.exists()); //The only one impossible to create

    String[] vKeywords = {"CON", "PRN", "AUX" };
    for (String s : vKeywords) {
        File f = dirTest.resolve(s).toFile();
        assertTrue(f.mkdir());
        assertTrue(f.exists() || s.equals("NUL"));
    }
    String[] vPrefixes = {"COM", "LPT" };
    for (String s : vPrefixes) {
        for (int i = 0; i < 10; i++) { // 0-9 suffix
            File f = dirTest.resolve(s + i).toFile();
            assertTrue(f.mkdir());
            assertTrue(f.exists());
        }
    }
}
MasterHD
  • 2,264
  • 1
  • 32
  • 41
  • 2
    For what it's worth, the documentation you linked never states that it is an error to create such files. In fact that whole list is under a section called "Naming **Conventions**", so it may be that such restrictions were relaxed and while Windows Explorer (or whatever the current Windows shell is called) keeps stopping you from creating files with those names, the actual operating system does not. Having said that, this is not really a Java question. It is borderline a *programming* question, imho. – Federico klez Culloca Mar 22 '23 at 17:21
  • 1
    Just as an aside, I seem to recall once accidentally creating a directory or file with one of these reserved names. The creation occurred without errors. But it was a pain to delete. I believe this was with Windows 10 though. – Slaw Mar 22 '23 at 17:46
  • CON0-CON9 are not reserved and never were. CON is reserved (it stands for "console"), and COM0..COM9 are (those stand for the RS232 serial ports). – Seva Alekseyev Mar 22 '23 at 18:29

1 Answers1

0

The files are a remnant of the days of PC-DOS. These pseudo-files are considered to exist regardless of any subdirectory (because DOS 1.0 didn't support directories).

The filename, NUL for example, is reserved and cannot be used. Back in the day, DOS would also ignore the extension so NUL.TXT was equivalent to NUL but I believe that went away when Windows started to support long filenames. Nowadays, the naked reserved words tend to be treated differently to when used as part of a larger filename such as NUL.txt or C:\NUL. This may be because many commands use \\?\ naming to avoid issues with filenames longer than MAX_PATH.

David Jones
  • 2,879
  • 2
  • 18
  • 23