Ticket #10900: boost.patch.165

File boost.patch.165, 5.4 KB (added by martin.apel@…, 5 years ago)

Patch to improve reparse point handling

Line 
1diff -cr boost_1_65_1/libs/filesystem/src/operations.cpp boost_1_65_1.mod/libs/filesystem/src/operations.cpp
2*** boost_1_65_1/libs/filesystem/src/operations.cpp 2017-09-02 11:56:12.000000000 +0200
3--- boost_1_65_1.mod/libs/filesystem/src/operations.cpp 2017-09-22 10:42:52.713234509 +0200
4***************
5*** 172,177 ****
6--- 172,183 ----
7 # ifndef IO_REPARSE_TAG_SYMLINK
8 # define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
9 # endif
10+ # ifndef IO_REPARSE_TAG_MOUNT_POINT
11+ # define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
12+ # endif
13+ # ifndef IO_REPARSE_TAG_DEDUP
14+ # define IO_REPARSE_TAG_DEDUP (0x80000013L)
15+ # endif
16
17 inline std::wstring wgetenv(const wchar_t* name)
18 {
19***************
20*** 684,690 ****
21 hTemplateFile);
22 }
23
24! bool is_reparse_point_a_symlink(const path& p)
25 {
26 handle_wrapper h(create_file_handle(p, FILE_READ_EA,
27 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
28--- 690,696 ----
29 hTemplateFile);
30 }
31
32! ULONG get_reparse_tag(const path& p)
33 {
34 handle_wrapper h(create_file_handle(p, FILE_READ_EA,
35 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
36***************
37*** 700,716 ****
38 MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRetLen, NULL);
39 if (!result) return false;
40
41! return reinterpret_cast<const REPARSE_DATA_BUFFER*>(buf.get())->ReparseTag
42! == IO_REPARSE_TAG_SYMLINK
43! // Issue 9016 asked that NTFS directory junctions be recognized as directories.
44! // That is equivalent to recognizing them as symlinks, and then the normal symlink
45! // mechanism will take care of recognizing them as directories.
46! //
47! // Directory junctions are very similar to symlinks, but have some performance
48! // and other advantages over symlinks. They can be created from the command line
49! // with "mklink /j junction-name target-path".
50! || reinterpret_cast<const REPARSE_DATA_BUFFER*>(buf.get())->ReparseTag
51! == IO_REPARSE_TAG_MOUNT_POINT; // aka "directory junction" or "junction"
52 }
53
54 inline std::size_t get_full_path_name(
55--- 706,712 ----
56 MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRetLen, NULL);
57 if (!result) return false;
58
59! return reinterpret_cast<const REPARSE_DATA_BUFFER*>(buf.get())->ReparseTag;
60 }
61
62 inline std::size_t get_full_path_name(
63***************
64*** 754,765 ****
65
66 if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
67 {
68! if (is_reparse_point_a_symlink(p))
69 return (attr & FILE_ATTRIBUTE_DIRECTORY)
70 ? fs::_detail_directory_symlink
71 : fs::symlink_file;
72 return fs::reparse_file;
73 }
74
75 return (attr & FILE_ATTRIBUTE_DIRECTORY)
76 ? fs::directory_file
77--- 750,771 ----
78
79 if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
80 {
81! switch(get_reparse_tag(p))
82! {
83! case IO_REPARSE_TAG_DEDUP:
84! return (attr & FILE_ATTRIBUTE_DIRECTORY)
85! ? fs::directory_file
86! : fs::regular_file;
87! case IO_REPARSE_TAG_MOUNT_POINT:
88! return fs::directory_file;
89! case IO_REPARSE_TAG_SYMLINK:
90 return (attr & FILE_ATTRIBUTE_DIRECTORY)
91 ? fs::_detail_directory_symlink
92 : fs::symlink_file;
93+ default:
94 return fs::reparse_file;
95 }
96+ }
97
98 return (attr & FILE_ATTRIBUTE_DIRECTORY)
99 ? fs::directory_file
100***************
101*** 1818,1826 ****
102 return process_status_failure(p, ec);
103 }
104
105! if (!is_reparse_point_a_symlink(p))
106 return file_status(reparse_file, make_permissions(p, attr));
107 }
108
109 if (ec != 0) ec->clear();
110 return (attr & FILE_ATTRIBUTE_DIRECTORY)
111--- 1824,1840 ----
112 return process_status_failure(p, ec);
113 }
114
115! switch(get_reparse_tag(p))
116! {
117! case IO_REPARSE_TAG_DEDUP:
118! case IO_REPARSE_TAG_SYMLINK:
119! case IO_REPARSE_TAG_MOUNT_POINT:
120! // Treat deduplicated files/dirs, mount points and symlinks as normals files/dirs
121! break;
122! default:
123 return file_status(reparse_file, make_permissions(p, attr));
124 }
125+ }
126
127 if (ec != 0) ec->clear();
128 return (attr & FILE_ATTRIBUTE_DIRECTORY)
129***************
130*** 1885,1898 ****
131 if (ec != 0) ec->clear();
132
133 if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
134! return is_reparse_point_a_symlink(p)
135! ? file_status(symlink_file, make_permissions(p, attr))
136! : file_status(reparse_file, make_permissions(p, attr));
137!
138 return (attr & FILE_ATTRIBUTE_DIRECTORY)
139 ? file_status(directory_file, make_permissions(p, attr))
140 : file_status(regular_file, make_permissions(p, attr));
141-
142 # endif
143 }
144
145--- 1899,1920 ----
146 if (ec != 0) ec->clear();
147
148 if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
149! {
150! switch(get_reparse_tag(p))
151! {
152! case IO_REPARSE_TAG_DEDUP:
153! case IO_REPARSE_TAG_MOUNT_POINT:
154! // Treat deduplicated files and mount points just as their normal counterparts
155! break;
156! case IO_REPARSE_TAG_SYMLINK:
157! return file_status(symlink_file, make_permissions(p, attr));
158! default:
159! return file_status(reparse_file, make_permissions(p, attr));
160! }
161! }
162 return (attr & FILE_ATTRIBUTE_DIRECTORY)
163 ? file_status(directory_file, make_permissions(p, attr))
164 : file_status(regular_file, make_permissions(p, attr));
165 # endif
166 }
167