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 e9bd439

Browse files
committed
fix symlink test on windows
1 parent 1849b41 commit e9bd439

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

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

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,31 +1198,38 @@ impl Dir {
11981198
io::const_error!(io::ErrorKind::InvalidFilename, "File name is too long");
11991199
let mut opts = OpenOptions::new();
12001200
opts.write(true);
1201-
let linkfile = File::open(link, &opts)?;
1202-
let utf16: Vec<u16> = original.iter().chain(original).copied().collect();
1203-
let file_name_len = u16::try_from(original.len()).or(Err(TOO_LONG_ERR))?;
1201+
opts.create(true);
1202+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS);
1203+
opts.attributes(c::FILE_ATTRIBUTE_REPARSE_POINT);
1204+
let linkfile = self.open_with(link, &opts)?;
1205+
let original_name_byte_len =
1206+
u16::try_from(size_of::<u16>() * original.len()).or(Err(TOO_LONG_ERR))?;
12041207
let sym_buffer = c::SYMBOLIC_LINK_REPARSE_BUFFER {
12051208
SubstituteNameOffset: 0,
1206-
SubstituteNameLength: file_name_len,
1207-
PrintNameOffset: file_name_len,
1208-
PrintNameLength: file_name_len,
1209+
SubstituteNameLength: original_name_byte_len,
1210+
PrintNameOffset: 0,
1211+
PrintNameLength: original_name_byte_len,
12091212
Flags: if relative { c::SYMLINK_FLAG_RELATIVE } else { 0 },
12101213
PathBuffer: 0,
12111214
};
1212-
let layout = Layout::new::<c::REPARSE_DATA_BUFFER>();
1213-
let layout = layout
1214-
.extend(Layout::new::<c::SYMBOLIC_LINK_REPARSE_BUFFER>())
1215-
.or(Err(TOO_LONG_ERR))?
1216-
.0;
1217-
let layout = Layout::array::<u16>(original.len()*2)
1218-
.and_then(|arr| layout.extend(arr))
1219-
.or(Err(TOO_LONG_ERR))?
1220-
.0;
1215+
let layout = Layout::from_size_align(
1216+
size_of::<c::REPARSE_DATA_BUFFER>()
1217+
+ size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1218+
+ size_of::<u16>()*(original.len() - 1),
1219+
align_of::<c::REPARSE_DATA_BUFFER>()
1220+
.max(align_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>())
1221+
.max(align_of::<u16>()),
1222+
)
1223+
.or(Err(TOO_LONG_ERR))?;
12211224
let buffer = unsafe { alloc(layout) }.cast::<c::REPARSE_DATA_BUFFER>();
12221225
unsafe {
12231226
buffer.write(c::REPARSE_DATA_BUFFER {
12241227
ReparseTag: c::IO_REPARSE_TAG_SYMLINK,
1225-
ReparseDataLength: u16::try_from(size_of_val(&sym_buffer)).or(Err(TOO_LONG_ERR))?,
1228+
ReparseDataLength: u16::try_from(
1229+
size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1230+
+ size_of::<u16>() * (original.len() - 1),
1231+
)
1232+
.or(Err(TOO_LONG_ERR))?,
12261233
Reserved: 0,
12271234
rest: (),
12281235
});
@@ -1231,20 +1238,25 @@ impl Dir {
12311238
.cast::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
12321239
.write(sym_buffer);
12331240
ptr::copy_nonoverlapping(
1234-
utf16.as_ptr(),
1241+
original.as_ptr(),
12351242
buffer
12361243
.add(offset_of!(c::REPARSE_DATA_BUFFER, rest))
12371244
.add(offset_of!(c::SYMBOLIC_LINK_REPARSE_BUFFER, PathBuffer))
12381245
.cast::<u16>(),
1239-
original.len()*2,
1246+
original.len(),
12401247
);
12411248
};
12421249
let result = unsafe {
12431250
c::DeviceIoControl(
12441251
linkfile.handle.as_raw_handle(),
12451252
c::FSCTL_SET_REPARSE_POINT,
1246-
&raw const buffer as *const c_void,
1247-
u32::try_from(size_of_val(&buffer)).or(Err(TOO_LONG_ERR))?,
1253+
buffer as *mut c_void as *const c_void,
1254+
u32::try_from(
1255+
size_of::<c::REPARSE_DATA_BUFFER>()
1256+
+ size_of::<c::SYMBOLIC_LINK_REPARSE_BUFFER>()
1257+
+ size_of::<u16>() * (original.len() - 1),
1258+
)
1259+
.or(Err(TOO_LONG_ERR))?,
12481260
ptr::null_mut(),
12491261
0,
12501262
ptr::null_mut(),

0 commit comments

Comments
(0)

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