1

As most of us know, Windows bans the following characters in file names:

* . " / \ [ ] : ; | = ,

Linux, and other Unix based systems, only ban \0 (the null character) and / (the path separator) for reasons that seem immediately obvious.

Why does Windows have so many banned characters?

I've looked, and every answer I find is some variation of "is this valid" or "what is valid", nothing discussing the design decisions that caused the Windows (DOS?) team to make them illegal.

Mike Holler
  • 945
  • 2
  • 13
  • 28
  • 2
    Where did you get that list? A bit of experimentation shows that `[`, `]`, `;`, `=`, and `,` are all accepted in file names, and `.` is only prohibited as the last character. Windows Explorer says that `<`, `>`, and `?` are also prohibited. – Harry Johnston Apr 10 '15 at 02:59
  • This doesn't appear to be "a practical programming question", per the FAQ. – Ben Voigt Apr 10 '15 at 03:16
  • See also [MSDN System.IO.Path.GetInvalidPathChars Method](https://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars%28v=vs.110%29.aspx) and [MSDN: System.IO.Path.GetInvalidFileNameChars Method](https://msdn.microsoft.com/en-us/library/system.io.path.getinvalidfilenamechars(v=vs.110).aspx) for more complete list of _troublesome_ characters and some explanation why some file systems and shells don't like them – xmojmr Apr 10 '15 at 05:04
  • @HarryJohnston. Only the Windows *Explorer* prohibits a file with a trailing `.` Windows itself does not. You can do `echo Foobar > test.` and then do `type test.` without problems. –  Apr 10 '15 at 10:04
  • @a_horse_with_no_name, that doesn't create a file with a trailing dot. `CreateFileW` calls an NT runtime library function to convert the DOS path to a native NT path, which strips trailing dots and spaces. For example, `C:\test ...` becomes `\??\C:\test`. It also removes dots before slashes, e.g. `C:\Temp.\test` becomes `\??\C:\Temp\test`. To create and open non-conforming paths such as these, you have to call [`NtCreateFile`](https://msdn.microsoft.com/en-us/library/ff566424) directly. That's not supported from user mode, so caveat emptor. – Eryk Sun Apr 11 '15 at 01:07
  • I kinda want to know the answer to this question for it's folklore value. How about moving to http://programmers.stackexchange.com/ ? – David J. Liszewski Jul 30 '15 at 23:32

2 Answers2

6

To take them in order:

  • * is prohibited because it is a Win32 wildcard character. Note that unlike Linux, wildcards are processed by the API, not by the shell.

  • . is not prohibited (obviously!) although it does have special semantics when it appears at the end of a file name, i.e., it is removed. That is for backwards compatibility with FAT file systems and/or applications designed for them.

  • " is a kernel wildcard character.

  • The backward slash is the path separator, and the forward slash is also treated as a path separator (sometimes) for compatibility with UNIX.

  • [ and ] are not prohibited.

  • : is used to indicate an alternate data stream.

  • ; is not prohibited.

  • | - I'm not sure about this one. Possibly because of the special meaning on the command line, although there are other characters with special meanings that are not prohibited in file names.

  • = and , are not prohibited.

Additional prohibited characters not on your list:

  • ? is a Win32 wildcard character.

  • <, > are kernel wildcard characters.

  • Spaces are trimmed from the end of file names in the same way periods are.

Community
  • 1
  • 1
Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • Primary sources: [Naming Conventions](https://msdn.microsoft.com/en-us/library/aa365247#Naming_Conventions), [Naming Conventions for Streams](https://msdn.microsoft.com/en-us/library/aa364404#Naming_Conventions_for_Streams), [`FsRtlIsNameInExpression`](https://msdn.microsoft.com/en-us/library/ff546850) (`DOS_QM`, etc), [`FsRtlIsAnsiCharacterLegal`](https://msdn.microsoft.com/en-us/library/ff546731). – Eryk Sun Apr 10 '15 at 12:22
  • I can't find the "ANSI legal character array" documented, as referenced by `FsRtlIsAnsiCharacterLegal`, but you can view it in a debugger using `db poi(nt!FsRtlLegalAnsiCharacterArray)`. This reveals that `NUL`, ``\`` and `/` are never allowed. `:` is allowed in an NTFS name (i.e. to delimit the stream component), but not in a stream name. `"`, `*`, `<`, `>`, and `?` are wilcards and forbidden, except in stream names, which can also include ASCII control characters and `|`. – Eryk Sun Apr 10 '15 at 12:40
  • @eryksun: any idea why Win32 prohibits the pipe character? I'm wondering if it used to be another wildcard, or more likely was set aside at some point to be a possible future wildcard or delimiter and never used. – Harry Johnston Apr 11 '15 at 01:47
  • I don't think MS-DOS COMMAND.COM had an escape character, so for backward compatibility `|` is an illegal character except in stream names. It's not flagged as a wildcard in `*FsRtlLegalAnsiCharacterArray`. They only added `"`, `<`, and `>` as wildcards to implement DOS quirks. `FindFirstFile` uses these. – Eryk Sun Apr 11 '15 at 02:12
2

The reason is that those characters have a special meaning in DOS commands, for example:

dir c:\"Long folder name"\*.* | more

The colon is used to specify the c: drive, the quotation marks for names with otherwise problematic characters (usually spaces), the asterisk is a wildcard character, the period is the file extension separator, the pipe is sending the output into another program.

Early versions of Windows were simply running on top of DOS, so they had to adopt the limitations of DOS. When Windows became an operating system in itself, it still used the same file system so it kept the limitations to be compatible.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 1
    So basically, Windows was built on DOS, which had a weak parser that used "reserved characters" to make the parsing simpler, similar to reserved words in programming languages? – Mike Holler Apr 10 '15 at 01:42
  • @MikeHoller: Yes, the DOS parser was basically the same as in CP/M that it was based on. It was expanded with new features over the years (for example subdirectories), needing more reserved characters for parsing. – Guffa Apr 10 '15 at 02:39
  • Your quotes are misplaced. – Mark Ransom Apr 10 '15 at 03:21
  • @MarkRansom: it's a valid command as-is. The quotes don't *have* to be at the beginning and end of the file name, so long as they enclose all of the spaces. – Harry Johnston Apr 10 '15 at 04:58