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

``