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 0d60852

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

File tree

7 files changed

+48
-45
lines changed

7 files changed

+48
-45
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(),

‎src/doc/book

Submodule book updated 73 files

‎src/doc/embedded-book

‎src/doc/reference

‎src/llvm-project

Submodule llvm-project updated 132 files

‎src/tools/cargo

Submodule cargo updated 733 files

0 commit comments

Comments
(0)

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