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 6759de5

Browse files
committed
fix symlink test on windows
1 parent b1332e7 commit 6759de5

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
@@ -1204,53 +1204,56 @@ impl Dir {
12041204
io::const_error!(io::ErrorKind::InvalidFilename, "File name is too long");
12051205
let mut opts = OpenOptions::new();
12061206
opts.write(true);
1207-
let linkfile = File::open(link, &opts)?;
1208-
let utf16: Vec<u16> = original.iter().chain(original).copied().collect();
1209-
let file_name_len = u16::try_from(original.len()).or(Err(TOO_LONG_ERR))?;
1210-
let sym_buffer = c::SYMBOLIC_LINK_REPARSE_BUFFER {
1211-
SubstituteNameOffset: 0,
1212-
SubstituteNameLength: file_name_len,
1213-
PrintNameOffset: file_name_len,
1214-
PrintNameLength: file_name_len,
1215-
Flags: if relative { c::SYMLINK_FLAG_RELATIVE } else { 0 },
1216-
PathBuffer: 0,
1217-
};
1218-
let layout = Layout::new::<c::REPARSE_DATA_BUFFER>();
1219-
let layout = layout
1220-
.extend(Layout::new::<c::SYMBOLIC_LINK_REPARSE_BUFFER>())
1221-
.or(Err(TOO_LONG_ERR))?
1222-
.0;
1223-
let layout = Layout::array::<u16>(original.len() * 2)
1224-
.and_then(|arr| layout.extend(arr))
1225-
.or(Err(TOO_LONG_ERR))?
1226-
.0;
1207+
opts.create(true);
1208+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS);
1209+
opts.attributes(c::FILE_ATTRIBUTE_REPARSE_POINT);
1210+
let linkfile = self.open_with(link, &opts)?;
1211+
let original_name_byte_len =
1212+
u16::try_from(size_of::<u16>() * original.len()).or(Err(TOO_LONG_ERR))?;
1213+
let layout = Layout::from_size_align(
1214+
size_of::<c::REPARSE_DATA_BUFFER>()
1215+
+ size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1216+
+ size_of::<u16>() * (original.len() - 1),
1217+
align_of::<c::REPARSE_DATA_BUFFER>()
1218+
.max(align_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>())
1219+
.max(align_of::<u16>()),
1220+
)
1221+
.or(Err(TOO_LONG_ERR))?;
12271222
let buffer = unsafe { alloc(layout) }.cast::<c::REPARSE_DATA_BUFFER>();
1223+
if buffer.is_null() {
1224+
return Err(io::ErrorKind::OutOfMemory.into());
1225+
}
12281226
unsafe {
1229-
buffer.write(c::REPARSE_DATA_BUFFER {
1230-
ReparseTag: c::IO_REPARSE_TAG_SYMLINK,
1231-
ReparseDataLength: u16::try_from(size_of_val(&sym_buffer)).or(Err(TOO_LONG_ERR))?,
1232-
Reserved: 0,
1233-
rest: (),
1234-
});
1235-
buffer
1236-
.add(offset_of!(c::REPARSE_DATA_BUFFER, rest))
1237-
.cast::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1238-
.write(sym_buffer);
1239-
ptr::copy_nonoverlapping(
1240-
utf16.as_ptr(),
1241-
buffer
1242-
.add(offset_of!(c::REPARSE_DATA_BUFFER, rest))
1243-
.add(offset_of!(c::SYMBOLIC_LINK_REPARSE_BUFFER, PathBuffer))
1244-
.cast::<u16>(),
1245-
original.len() * 2,
1227+
(&raw mut (*buffer).ReparseTag).write(c::IO_REPARSE_TAG_SYMLINK);
1228+
(&raw mut (*buffer).ReparseDataLength).write(
1229+
u16::try_from(
1230+
size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1231+
+ size_of::<u16>() * (original.len() - 1),
1232+
)
1233+
.or(Err(TOO_LONG_ERR))?,
12461234
);
1235+
(&raw mut (*buffer).Reserved).write(0);
1236+
let rest = (&raw mut (*buffer).rest).cast::<c::SYMBOLIC_LINK_REPARSE_BUFFER>();
1237+
1238+
(&raw mut (*rest).SubstituteNameOffset).write(0);
1239+
(&raw mut (*rest).SubstituteNameLength).write(original_name_byte_len);
1240+
(&raw mut (*rest).PrintNameOffset).write(0);
1241+
(&raw mut (*rest).PrintNameLength).write(original_name_byte_len);
1242+
(&raw mut (*rest).Flags).write(if relative { c::SYMLINK_FLAG_RELATIVE } else { 0 });
1243+
1244+
original.as_ptr().copy_to_nonoverlapping(&raw mut (*rest).PathBuffer, original.len());
12471245
};
12481246
let result = unsafe {
12491247
c::DeviceIoControl(
12501248
linkfile.handle.as_raw_handle(),
12511249
c::FSCTL_SET_REPARSE_POINT,
1252-
&raw const buffer as *const c_void,
1253-
u32::try_from(size_of_val(&buffer)).or(Err(TOO_LONG_ERR))?,
1250+
buffer as *mut c_void as *const c_void,
1251+
u32::try_from(
1252+
size_of::<c::REPARSE_DATA_BUFFER>()
1253+
+ size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1254+
+ size_of::<u16>() * (original.len() - 1),
1255+
)
1256+
.or(Err(TOO_LONG_ERR))?,
12541257
ptr::null_mut(),
12551258
0,
12561259
ptr::null_mut(),

0 commit comments

Comments
(0)

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