Yes, it isn't strictly part of the device name, it is a separator. But it still works well for distinguishing device names from file names. For a character device, the path name has to be blank. "COM1:" is definitely a device not a file, as long as colons are not allowed in filenames.
(Well, strictly speaking you might argue it could be the default unnamed data stream of a file called "COM1". But almost nobody ever refers to the unnamed data stream explicitly like that, just using the bare file name to do so; and if one must, the canonical name for it is to include the stream type, giving the default unnamed stream of the file "COM1" a name of "COM1::$DATA". That's obviously not a reference to the "COM1" device, since it violates the "path name must be blank" rule)
DOS required extensions and most early DOS apps just always appended their own extensions automatically and only took in the base name. The system ignoring the file extension made it easier to use the devices in every DOS app, not just ones aware of the devices.
> Unfortunately the API was that you used CreateFile without colon.
I don't have time to do any detailed testing of this right now, but I believe that `CreateFileA("COM1",...)` and `CreateFileA("COM1:",...)` are equivalent, and both work identically. Am I wrong about that?
(Well, strictly speaking you might argue it could be the default unnamed data stream of a file called "COM1". But almost nobody ever refers to the unnamed data stream explicitly like that, just using the bare file name to do so; and if one must, the canonical name for it is to include the stream type, giving the default unnamed stream of the file "COM1" a name of "COM1::$DATA". That's obviously not a reference to the "COM1" device, since it violates the "path name must be blank" rule)