Support unprivileged symlink creation in Windows · rust-lang/rust@02ae1e1 (original) (raw)
`@@ -646,9 +646,25 @@ pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
`
646
646
`let src = to_u16s(src)?;
`
647
647
`let dst = to_u16s(dst)?;
`
648
648
`let flags = if dir { c::SYMBOLIC_LINK_FLAG_DIRECTORY } else { 0 };
`
649
``
`-
cvt(unsafe {
`
650
``
`-
c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as c::BOOL
`
651
``
`-
})?;
`
``
649
`+
// Formerly, symlink creation required the SeCreateSymbolicLink privilege. For the Windows 10
`
``
650
`+
// Creators Update, Microsoft loosened this to allow unprivileged symlink creation if the
`
``
651
`+
// computer is in Developer Mode, but SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE must be
`
``
652
`+
// added to dwFlags to opt into this behaviour.
`
``
653
`+
let result = cvt(unsafe {
`
``
654
`+
c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(),
`
``
655
`+
flags | c::SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) as c::BOOL
`
``
656
`+
});
`
``
657
`+
if let Err(err) = result {
`
``
658
`+
if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as i32) {
`
``
659
`+
// Older Windows objects to SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE,
`
``
660
`+
// so if we encounter ERROR_INVALID_PARAMETER, retry without that flag.
`
``
661
`+
cvt(unsafe {
`
``
662
`+
c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as c::BOOL
`
``
663
`+
})?;
`
``
664
`+
} else {
`
``
665
`+
return Err(err);
`
``
666
`+
}
`
``
667
`+
}
`
652
668
`Ok(())
`
653
669
`}
`
654
670
``