Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f62937b

Browse files
committed
fix symlink test on windows
1 parent ced0e20 commit f62937b

File tree

1 file changed

+42
-39
lines changed

1 file changed

+42
-39
lines changed

‎library/std/src/sys/fs/windows.rs‎

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,53 +1199,56 @@ impl Dir {
11991199
io::const_error!(io::ErrorKind::InvalidFilename, "File name is too long");
12001200
let mut opts = OpenOptions::new();
12011201
opts.write(true);
1202-
let linkfile = File::open(link, &opts)?;
1203-
let utf16: Vec<u16> = original.iter().chain(original).copied().collect();
1204-
let file_name_len = u16::try_from(original.len()).or(Err(TOO_LONG_ERR))?;
1205-
let sym_buffer = c::SYMBOLIC_LINK_REPARSE_BUFFER {
1206-
SubstituteNameOffset: 0,
1207-
SubstituteNameLength: file_name_len,
1208-
PrintNameOffset: file_name_len,
1209-
PrintNameLength: file_name_len,
1210-
Flags: if relative { c::SYMLINK_FLAG_RELATIVE } else { 0 },
1211-
PathBuffer: 0,
1212-
};
1213-
let layout = Layout::new::<c::REPARSE_DATA_BUFFER>();
1214-
let layout = layout
1215-
.extend(Layout::new::<c::SYMBOLIC_LINK_REPARSE_BUFFER>())
1216-
.or(Err(TOO_LONG_ERR))?
1217-
.0;
1218-
let layout = Layout::array::<u16>(original.len() * 2)
1219-
.and_then(|arr| layout.extend(arr))
1220-
.or(Err(TOO_LONG_ERR))?
1221-
.0;
1202+
opts.create(true);
1203+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS);
1204+
opts.attributes(c::FILE_ATTRIBUTE_REPARSE_POINT);
1205+
let linkfile = self.open_with(link, &opts)?;
1206+
let original_name_byte_len =
1207+
u16::try_from(size_of::<u16>() * original.len()).or(Err(TOO_LONG_ERR))?;
1208+
let layout = Layout::from_size_align(
1209+
size_of::<c::REPARSE_DATA_BUFFER>()
1210+
+ size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1211+
+ size_of::<u16>() * (original.len() - 1),
1212+
align_of::<c::REPARSE_DATA_BUFFER>()
1213+
.max(align_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>())
1214+
.max(align_of::<u16>()),
1215+
)
1216+
.or(Err(TOO_LONG_ERR))?;
12221217
let buffer = unsafe { alloc(layout) }.cast::<c::REPARSE_DATA_BUFFER>();
1218+
if buffer.is_null() {
1219+
return Err(io::ErrorKind::OutOfMemory.into());
1220+
}
12231221
unsafe {
1224-
buffer.write(c::REPARSE_DATA_BUFFER {
1225-
ReparseTag: c::IO_REPARSE_TAG_SYMLINK,
1226-
ReparseDataLength: u16::try_from(size_of_val(&sym_buffer)).or(Err(TOO_LONG_ERR))?,
1227-
Reserved: 0,
1228-
rest: (),
1229-
});
1230-
buffer
1231-
.add(offset_of!(c::REPARSE_DATA_BUFFER, rest))
1232-
.cast::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1233-
.write(sym_buffer);
1234-
ptr::copy_nonoverlapping(
1235-
utf16.as_ptr(),
1236-
buffer
1237-
.add(offset_of!(c::REPARSE_DATA_BUFFER, rest))
1238-
.add(offset_of!(c::SYMBOLIC_LINK_REPARSE_BUFFER, PathBuffer))
1239-
.cast::<u16>(),
1240-
original.len() * 2,
1222+
(&raw mut (*buffer).ReparseTag).write(c::IO_REPARSE_TAG_SYMLINK);
1223+
(&raw mut (*buffer).ReparseDataLength).write(
1224+
u16::try_from(
1225+
size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1226+
+ size_of::<u16>() * (original.len() - 1),
1227+
)
1228+
.or(Err(TOO_LONG_ERR))?,
12411229
);
1230+
(&raw mut (*buffer).Reserved).write(0);
1231+
let rest = (&raw mut (*buffer).rest).cast::<c::SYMBOLIC_LINK_REPARSE_BUFFER>();
1232+
1233+
(&raw mut (*rest).SubstituteNameOffset).write(0);
1234+
(&raw mut (*rest).SubstituteNameLength).write(original_name_byte_len);
1235+
(&raw mut (*rest).PrintNameOffset).write(0);
1236+
(&raw mut (*rest).PrintNameLength).write(original_name_byte_len);
1237+
(&raw mut (*rest).Flags).write(if relative { c::SYMLINK_FLAG_RELATIVE } else { 0 });
1238+
1239+
original.as_ptr().copy_to_nonoverlapping(&raw mut (*rest).PathBuffer, original.len());
12421240
};
12431241
let result = unsafe {
12441242
c::DeviceIoControl(
12451243
linkfile.handle.as_raw_handle(),
12461244
c::FSCTL_SET_REPARSE_POINT,
1247-
&raw const buffer as *const c_void,
1248-
u32::try_from(size_of_val(&buffer)).or(Err(TOO_LONG_ERR))?,
1245+
buffer as *mut c_void as *const c_void,
1246+
u32::try_from(
1247+
size_of::<c::REPARSE_DATA_BUFFER>()
1248+
+ size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1249+
+ size_of::<u16>() * (original.len() - 1),
1250+
)
1251+
.or(Err(TOO_LONG_ERR))?,
12491252
ptr::null_mut(),
12501253
0,
12511254
ptr::null_mut(),

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /