4 ms·
Oh, yes, those. Please be advised that they are possibly one of the ugliest bits of the Windows API. You could blog about this nightmare. Particular hairballs
by AlyssaRowan 12y ago
Oh, yes, those. Please be advised that they are possibly one of the ugliest bits of the Windows API. You could blog about this nightmare.
Particular hairballs to watch out for regarding the path length/filename length issue (please forgive me if I've got these slightly wrong as I'm paraphrasing roughly from memory):
• Normal MAX_PATH == 260 WCHARs (hardcoded in the Windows API), including the drive letter, colon, backslash, and the trailing NUL;
• Directory names in the normal API can't be longer than (MAX_PATH-12) WCHARs, so that they can always contain a FILENAME.EXT;
• You can use extended-length paths with a "\\?\" prefix (exactly); UNC network drive paths which you want to be extended-length should start "\\?\UNC\" (exactly), then append the server name, backslash, share name, backslash, path and file etc;
• Extended-length paths only generally work with W/Ex APIs;
• The buffer used for extended-length paths is 65536 bytes, including the trailing NUL, but that also needs to contain any expansions during processing;
• Names passed with the extended-length API do not have to be valid or normalised Unicode;
• Components (split between backslashes, i.e. filenames) of an extended-length path are in fact still limited to GetVolumeInformation/GetVolumeInformationByHandleW/etc's lpMaximumComponentLength, which is often 255 (WCHARs) but not always;
• It counts WCHARs not codepoints (look out for codepoints beyond the Basic Multilingual Plane!);
• There are no relative paths or current directories in this API, everything is absolute, so no plain filenames, and "." and ".." are actually valid names not directory references;
• Most of the Explorer shell, and all of cmd.exe (as of W8, don't know about W10) doesn't use them, and because of the above you can't use them as a cd, you can pushd them but stuff will break;
• Several APIs don't even support it;
• So you can make files and directories which a good half of Windows and related applications can't do anything with, and are very pesky to delete…
…and beyond that is where it gets really hairy. The code in this area involving devices (from "\\.\PhysicalDisk0" to good ol' "COM1") is particularly Cthulhu-esque, as is the code regarding Terminal Services and Hyper-V. (A good sweep through there looking for off-by-ones might be fruitful, as those with sharp eyes may have spotted from the above.)
I'll make allowances for needing to be incredibly careful about backwards compatibility to a really old VMS/GEMDOSish codebase, and being patch-upon-patch-upon-patch as a result. But that they had the opportunity to fix it in NT, and sadly missed it irks me: that and the locking semantics (especially regarding running executables) are probably my least favourite characteristics of Windows.
Linux, for example, is much easier about this particular kind of thing, but its flexibility does have its own problems when absolutely anything can be in a filename and people often forget that (for example, the delightful fun that can ensue when someone starts a filename with "-", say, "-rf" and someone does a "rm " which globs it first, because globbing doesn't know or care what switches are, but you* will).
- cesarb 12y agoAnd AFAIK you can't have a file named "aux.c" (which would be a perfectly legitimate file name otherwise). That's the one which has the most probability of tripping developers using saner systems: create a file for your auxiliary functions, commit it to the repository, and congratulations, you just broke things on Windows.
- asveikau 12y agoAs bad as these behaviors are, I think the delete behaviors (specifically STATUS_DELETE_PENDING at the NT layer) are worse. Deleting a file reserves the name until the last handle is closed. "Delete file, re-create file with same name" is a very dangerous pattern on Windows.
- xenophonf 12y ago> globbing doesn't know or care what switches are, but you will I fondly remember learning the hard way to prefix my shell globs with paths, as in "rm ./*". I was root on that system, too.