@@ -19,6 +19,11 @@ namespace Filesystem = std::filesystem;
19
19
#include < fcntl.h> // AT_* constants for statx()
20
20
#endif
21
21
22
+ #if defined(_WIN32)
23
+ #define WIN32_LEAN_AND_MEAN
24
+ #include < Windows.h>
25
+ #endif
26
+
22
27
#endif
23
28
24
29
@@ -38,6 +43,43 @@ bool fs_equivalent(std::string_view path1, std::string_view path2)
38
43
39
44
#else
40
45
46
+ #if defined(_WIN32)
47
+ // FUTURE: GetFileInformationByName Windows ~24H2
48
+ // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getfileinformationbyname
49
+ // https://github.com/rust-lang/rust/issues/130169
50
+ //
51
+ // for now use GetFileInformationByHandle
52
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileinformationbyhandle#remarks
53
+ // FILE_FLAG_BACKUP_SEMANTICS to allow opening directories
54
+
55
+ HANDLE h1 = CreateFileW (fs_win32_to_wide (path1).data (), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nullptr ,
56
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr );
57
+ if (h1 == INVALID_HANDLE_VALUE) {
58
+ fs_print_error (path1, __func__);
59
+ return false ;
60
+ }
61
+
62
+ HANDLE h2 = CreateFileW (fs_win32_to_wide (path2).data (), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nullptr ,
63
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr );
64
+ if (h2 == INVALID_HANDLE_VALUE) {
65
+ fs_print_error (path2, __func__);
66
+ CloseHandle (h1);
67
+ return false ;
68
+ }
69
+
70
+ BY_HANDLE_FILE_INFORMATION f1, f2;
71
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
72
+ BOOL ok1 = GetFileInformationByHandle (h1, &f1);
73
+ BOOL ok2 = GetFileInformationByHandle (h2, &f2);
74
+ CloseHandle (h1);
75
+ CloseHandle (h2);
76
+ if (ok1 && ok2) {
77
+ return f1.dwVolumeSerialNumber == f2.dwVolumeSerialNumber &&
78
+ f1.nFileIndexHigh == f2.nFileIndexHigh &&
79
+ f1.nFileIndexLow == f2.nFileIndexLow ;
80
+ }
81
+
82
+ #else
41
83
int r1 = 0 ;
42
84
int r2 = 0 ;
43
85
@@ -65,6 +107,7 @@ bool fs_equivalent(std::string_view path1, std::string_view path2)
65
107
return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino ;
66
108
}
67
109
110
+ #endif
68
111
#endif
69
112
70
113
fs_print_error (path1, path2, __func__, ec);
0 commit comments