On 5/13/20, Antoine Pitrou
If you know of a system function which accepts filenames with embedded NULs (which probably means it also takes the filename length as a separate parameter), I'd be curious to know about it.
Windows is layered over the base NT system, which uses counted strings and a root object namespace that reserves only the path separator, backslash. Null characters are allowed, at least as far as the object manager cares, but using them is a bad idea, if only because such names aren't generally accessible in Windows. But let's look at an example just for kicks. When the object manager parses a path up to a Device object (e.g. "\Device\NamedPipe"), the I/O manager takes over parsing the remaining path, which calls the device driver's IRP_MJ_CREATE routine with the remaining path. Whether or not a name with nulls is allowed depends on the device driver -- or a filesystem driver if the device is mounted. Almost all filesystem drivers reject a component name that contains nulls as invalid. One exception is the named-pipe filesystem (NPFS). NPFS doesn't disallow any characters. It even allows backslash in pipe names since it doesn't support subdirectories, and if you check via os.listdir('//./pipe'), you should see several Winsock pipes with backslash in their name. Creating a pipe with nulls in its name is impossible via WINAPI CreateNamedPipeW. It requires native NtCreateNamedPipeFile, with the name passed in an OBJECT_ATTRIBUTES record [1]. This system function is undocumented, but just to show that it's possible in principle, I created a pipe named "spam\x00eggs". We can query the name via GetFileInformationByHandleEx: FileNameInfo [2], which returns a counted string: >>> GetFileInformationByHandleEx(h, FileNameInfo) '\\spam\x00eggs' The name is in the root path of the device, but we don't get the fully-qualified name "\\Device\\NamedPipe\\spam\x00eggs". WINAPI GetFinalPathNameByHandleW [3] can figure this out, at least for the native NT path (from NtQueryObject). However, it works with null-terminated strings, so the pipe name gets truncated as "spam": >>> flags = VOLUME_NAME_NT | FILE_NAME_OPENED >>> GetFinalPathNameByHandle(h, flags) '\\Device\\NamedPipe\\spam' [1]: https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-_object_at... [2]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_n... [3]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfin...