Hi, Corinna: On Jun 17 07:25, Bill Zissimopoulos wrote: > > Windows hard links are rather un-POSIX like and rarely used on Windows. > > After considering the required changes on the FSD for a feature that is > > so rarely used I opted against supporting them. > > I disagree here. Windows hardlinks work fine and pretty much as on > POSIX with the exception of DOS mode bits. Those are not per file but > per file entry as far as my experiecen goes. One of the reasons we try > to ignore them as much as possible.
I no longer remember all the details now, because it was a few months ago that I looked into this and determined that hard links are "un-POSIX like". As far as I recall there was the FileAttributes issue (which I now think may have been my incorrect understanding of the documentation), but there was also the issue of FindFirstFileName/FindNextFileName, which is not something that POSIX supports out of the box (AFAIK). Regarding the FileAttributes issue. The Windows documentation seems to suggest that they are stored with the file and not the directory entry. I have not experimented though to confirm whether this is true. From MSDN "Hard Links and Junctions" [1]: << Note that the attributes on the file are reflected in every hard link to that file, and changes to that file's attributes propagate to all the hard links. For example if you reset the READONLY attribute on a hard link to delete that particular hard link, and there are multiple hard links to the actual file, then you will need to reset the READONLY bit on the file from one of the remaining hard links to bring the file and all remaining hard links back to the READONLY state. >> And then of course there is this ambiguous bit: << However, the directory entry size and attribute information is updated only for the link through which the change was made. >> I think that attribute information in this case means "NTFS attribute" and not FILE_ATTRIBUTE_*. NTFS attributes are simply the method that NTFS uses to store information about files. Taken together this information suggests that NTFS hard links are more "POSIX like" than I thought. In fact they may be "POSIX like with extra capabilities". The bigger issue is that the FSD now maintains an internal table of open files that is indexed by file name. It actually started as a table of open files indexed by IndexNumber (inode number Windows equivalent), but I eventually had to change it for a number of issues (notably Rename support). I am not saying that it would not be possible to change this part of WinFsp, I just believe that it is a non-trivial change at this moment. > > > You write that you are mapping > > > - characters not supported by Win32 but by POSIX via the Unicode > > > private use page > > > - Security apspects (SID vs. uid/gid, ACL) > > > between POSIX and Windows and that you do it like Cygwin/SFU/SFM is > > > doing it. > > Uhm... I don't understand. Cygwin is using the private unicode range as > well to map characters invalid in a Windows filename (e.g. colon 0x3a is > mapped to 0xf03a). This is how such filenames are given to the OS >functions. > > This means, WinFsp would get these filenames from a Cygwin process > already in the transposed form, with invalid FS chars transposed into the > private area. > > If WinFsp would support that, it would be transparent to applications > with very minor effort. I think I may have inadequately explained what WinFsp does with this mapping. It basically does the opposite of what Cygwin does on any given code path. Let's examine the lifetime of a call to creat(). Suppose a Cygwin process does creat("/cygdrive/z/foo*bar"). In the following OP is the "originating process", CW is the "Cygwin runtime", NT is NTOS, WD is the "WinFsp FSD", WL is the "WinFsp DLL", FL is the "FUSE layer", and FS is the "user mode FUSE file system". OP: creat("/cygdrive/z/foo*bar") CW: NtCreateFile(L"<DEVICE>\\foo\xf02abar") <--- Cygwin translation NT: IRP_MJ_CREATE L"\\foo\xf02abar" WD: FspFsctlTransactCreateKind L"\\foo\xf02abar" WL: FSP_FILE_SYSTEM_INTERFACE::Create L"\\foo\xf02abar" FL: fuse_operations::create "/foo*bar" <--- WinFsp/FUSE translation FS: somehow satisfies fuse_operations::create [snip return path] The opposite happens when the file system communicates a file name back to the originating process, as in readdir(). OP: readdir("/cygdrive/z/") [snip call path] FS: fuse_operations::readdir response: "foo*bar" FL: FSP_FILE_SYSTEM_INTERFACE::ReadDirectory response: L"foo\xf02abar" WL: FspFsctlTransactQueryDirectoryKind response: L"foo\xf02abar" WD: IRP_MN_QUERY_DIRECTORY response: L"foo\xf02abar" NT: NtQueryDirectoryFile response: L"foo\xf02abar" CW: readdir response: "foo*bar" OP: receives "foo*bar" Now also recall that native Windows is my primary target environment and that the originating process will likely not be a Cygwin process. Suppose that SSHFS is used to mount a directory that has a "foo*bar" file. How to present that to a Win32 process? I hope that this makes the need for the WinFsp mapping more apparent. Bill [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365006(v=vs.85). aspx