summaryrefslogtreecommitdiffstats
path: root/vendor/junction
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/junction
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/junction')
-rw-r--r--vendor/junction/.cargo-checksum.json1
-rw-r--r--vendor/junction/CHANGELOG.md66
-rw-r--r--vendor/junction/COPYRIGHT21
-rw-r--r--vendor/junction/Cargo.toml59
-rw-r--r--vendor/junction/README.md29
-rw-r--r--vendor/junction/src/internals.rs155
-rw-r--r--vendor/junction/src/internals/helpers.rs229
-rw-r--r--vendor/junction/src/internals/helpers/utf16.rs15
-rw-r--r--vendor/junction/src/internals/types.rs105
-rw-r--r--vendor/junction/src/lib.rs111
-rw-r--r--vendor/junction/src/tests.rs231
11 files changed, 0 insertions, 1022 deletions
diff --git a/vendor/junction/.cargo-checksum.json b/vendor/junction/.cargo-checksum.json
deleted file mode 100644
index 4ddcfec7a..000000000
--- a/vendor/junction/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"22da70a36c108924fe4daa627e579442c9bed138d97da8cfba3b9a026e2ac120","COPYRIGHT":"fd9d249f2332358a001c6bac6afdf5a06971fa3683085fd8aec609dd4cc264d4","Cargo.toml":"8b7dc08048cb598cfed96d57dcd80e66579e5d026b22d13a7f46b1e8c59b9198","README.md":"643287db5e132f715a63fea78c6e9538220b44698b7296d9f21d0b9e15cc5c46","src/internals.rs":"733250bbbcb62534d39dc35c741bf92d78aa6ff900dd2b2de87ae4b97222c080","src/internals/helpers.rs":"a6d711cceccec879d700fe63b6f93a2b48baacf14adc4f0d33447c49312bc1e3","src/internals/helpers/utf16.rs":"df1e6365b33653956576b6a80f9bf4b65e088a53432d2b3a2684e09c8b49704a","src/internals/types.rs":"0022454ab78785a111316689a5c58b4d812ff0ad28ed627834e5c2d4b7f1d722","src/lib.rs":"f1f9fd8961bba333ed583de641b1b2ed47643fda407d4c1dd5ad3db2aa17b577","src/tests.rs":"35558b2b39f2950abdec33d5e5f14cf9f0bdc8d8e28c1d5ce97a391bb45cb020"},"package":"ca39ef0d69b18e6a2fd14c2f0a1d593200f4a4ed949b240b5917ab51fac754cb"} \ No newline at end of file
diff --git a/vendor/junction/CHANGELOG.md b/vendor/junction/CHANGELOG.md
deleted file mode 100644
index f6aa7fda1..000000000
--- a/vendor/junction/CHANGELOG.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-<!--
-# Guiding Principles
-
-* Changelogs are for _humans_, not machines.
-* There should be an entry for every single version.
-* The same types of changes should be grouped.
-* Versions and sections should be linkable.
-* The latest version comes first.
-* The release date of each version is displayed.
-* Mention whether you follow Semantic Versioning.
-
-# Types of changes
-
-* `Added` for new features.
-* `Changed` for changes in existing functionality.
-* `Deprecated` for soon-to-be removed features.
-* `Removed` for now removed features.
-* `Fixed` for any bug fixes.
-* `Security` in case of vulnerabilities.
--->
-
-## [v1.0.0] - 2023-02-26
-### First major version
-The public API of this crate has been unchanged around 3 years without complains.
-It signals that the API is mature enough to be stable for a long time.
-
-## [v0.2.1] - 2023-02-25
-### Fixed
-* Fix weird build failure when cross-compiling from non-Windows hosts
- 657c176a440a64437236ba9d88a2ebd98a8babb1
-
-## [v0.2.0] - 2020-09-05
-### Changed
-* Some internal refactorings that requires Rust v1.46.0
-
-## [v0.1.5] - 2020-03-18
-### Fixed
-* Prevent a panic happen when open a reparse point (Commit fd9bbec6061fb100f79795ac9b64db59fbb6a3c0)
-
-## [v0.1.4] - 2020-01-30
-### Changed
-* Ask for forgiveness in case we have no necessary permission
- instead of always asking for permission.
-
-## [v0.1.3] - 2019-10-28
-### Changed
-* Obtain appropriate privilege before opening directories.
-
-## [v0.1.0] - 2019-05-15
-
-First release
-
-[v1.0.0]: https://github.com/lzutao/junction/compare/v0.2.1...v1.0.0
-[v0.2.1]: https://github.com/lzutao/junction/compare/v0.2.0...v0.2.1
-[v0.2.0]: https://github.com/lzutao/junction/compare/v0.1.0...v0.2.0
-[v0.1.5]: https://github.com/lzutao/junction/compare/v0.1.4...v0.1.5
-[v0.1.4]: https://github.com/lzutao/junction/compare/v0.1.3...v0.1.4
-[v0.1.3]: https://github.com/lzutao/junction/compare/v0.1.0...v0.1.3
-[v0.1.0]: https://github.com/lzutao/junction/releases/tag/v0.1.0
diff --git a/vendor/junction/COPYRIGHT b/vendor/junction/COPYRIGHT
deleted file mode 100644
index 9cbcc2004..000000000
--- a/vendor/junction/COPYRIGHT
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 lzutao
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/junction/Cargo.toml b/vendor/junction/Cargo.toml
deleted file mode 100644
index 8e4198529..000000000
--- a/vendor/junction/Cargo.toml
+++ /dev/null
@@ -1,59 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2018"
-name = "junction"
-version = "1.0.0"
-authors = ["Lzu Tao <taolzu@gmail.com>"]
-exclude = [
- "/.github",
- "/HOW-TO-RELEASE.md",
- "/azure-pipelines.yml",
-]
-description = "library for working with NTFS junctions"
-documentation = "https://docs.rs/junction/*/x86_64-pc-windows-msvc/junction/"
-readme = "README.md"
-keywords = [
- "junction",
- "symlink",
-]
-categories = [
- "api-bindings",
- "os::windows-apis",
-]
-license = "MIT"
-repository = "https://github.com/lzutao/junction"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-pc-windows-msvc"]
-
-[dev-dependencies.tempfile]
-version = "3"
-
-[target."cfg(windows)".dependencies.scopeguard]
-version = "1"
-default-features = false
-
-[target."cfg(windows)".dependencies.winapi]
-version = "0.3"
-features = [
- "errhandlingapi",
- "fileapi",
- "guiddef",
- "handleapi",
- "ioapiset",
- "processthreadsapi",
- "securitybaseapi",
- "winbase",
- "winioctl",
- "winnt",
-]
diff --git a/vendor/junction/README.md b/vendor/junction/README.md
deleted file mode 100644
index 2917708e7..000000000
--- a/vendor/junction/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# junction
-
-Library for working with NTFS junctions.
-
-[![Build Status][actions-badge]][actions-url]
-[![Documentation](https://docs.rs/junction/badge.svg)](https://docs.rs/junction)
-[![Crates.io](https://img.shields.io/crates/v/junction.svg)](https://crates.io/crates/junction)
-
-### Minimal Supported Rust versions
-
-1.48.0
-
-## All relevant references
-
-* https://www.codeproject.com/Articles/194/Windows-2000-Junction-Points#The_Solution
-* https://www.codeproject.com/Articles/15633/Manipulating-NTFS-Junction-Points-in-NET
-* http://www.flexhex.com/docs/articles/hard-links.phtml
-* https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html
-* https://github.com/googleprojectzero/symboliclink-testing-tools/blob/master/DumpReparsePoint/DumpReparsePoint.cpp
-* https://github.com/googleprojectzero/symboliclink-testing-tools/blob/master/CommonUtils/ReparsePoint.cpp
-* https://github.com/containerd/continuity/blob/master/syscallx/syscall_windows.go
-
-## License
-
-All the code in this repository is released under the MIT License,
-for more information, please read COPYRIGHT file.
-
-[actions-badge]: https://github.com/lzutao/junction/workflows/Rust/badge.svg?branchName=master
-[actions-url]: https://github.com/lzutao/junction/actions
diff --git a/vendor/junction/src/internals.rs b/vendor/junction/src/internals.rs
deleted file mode 100644
index 71b03863f..000000000
--- a/vendor/junction/src/internals.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-mod helpers;
-mod types;
-
-use types::ReparseDataBuffer;
-use types::{MOUNT_POINT_REPARSE_BUFFER_HEADER_SIZE, REPARSE_DATA_BUFFER_HEADER_SIZE};
-
-use std::cmp;
-use std::fs;
-use std::path::{Path, PathBuf};
-use std::ptr;
-use std::slice;
-use std::{ffi::OsString, os::windows::ffi::OsStringExt};
-use std::{io, os::windows::io::AsRawHandle};
-
-use winapi::um::winnt::{IO_REPARSE_TAG_MOUNT_POINT, MAXIMUM_REPARSE_DATA_BUFFER_SIZE};
-
-// makes sure layout of RawHandle and winapi's HANDLE are the same
-// for pointer casts between them.
-const _: () = {
- use std::alloc::Layout;
- let std_layout = Layout::new::<std::os::windows::io::RawHandle>();
- let winapi_layout = Layout::new::<winapi::um::winnt::HANDLE>();
- // MSVR(Rust v1.57): use assert! instead
- [(); 1][!(std_layout.size() == winapi_layout.size()) as usize];
- [(); 1][!(std_layout.align() == winapi_layout.align()) as usize];
-};
-
-/// This prefix indicates to NTFS that the path is to be treated as a non-interpreted
-/// path in the virtual file system.
-const NON_INTERPRETED_PATH_PREFIX: [u16; 4] = [b'\\' as u16, b'?' as _, b'?' as _, b'\\' as _];
-const WCHAR_SIZE: u16 = std::mem::size_of::<u16>() as _;
-
-pub fn create(target: &Path, junction: &Path) -> io::Result<()> {
- const UNICODE_NULL_SIZE: u16 = WCHAR_SIZE;
- const MAX_AVAILABLE_PATH_BUFFER: u16 = MAXIMUM_REPARSE_DATA_BUFFER_SIZE as u16
- - REPARSE_DATA_BUFFER_HEADER_SIZE
- - MOUNT_POINT_REPARSE_BUFFER_HEADER_SIZE
- - 2 * UNICODE_NULL_SIZE;
-
- // We're using low-level APIs to create the junction, and these are more picky about paths.
- // For example, forward slashes cannot be used as a path separator, so we should try to
- // canonicalize the path first.
- let mut target = helpers::get_full_path(target)?;
- fs::create_dir(junction)?;
- let file = helpers::open_reparse_point(junction, true)?;
- // "\??\" + target
- let len = NON_INTERPRETED_PATH_PREFIX.len().saturating_add(target.len());
- let target_len_in_bytes = {
- let min_len = cmp::min(len, u16::MAX as usize) as u16;
- // Len without `UNICODE_NULL` at the end
- let target_len_in_bytes = min_len.saturating_mul(WCHAR_SIZE);
- // Check if `target_wchar.len()` may lead to a buffer overflow.
- if target_len_in_bytes > MAX_AVAILABLE_PATH_BUFFER {
- return Err(io::Error::new(io::ErrorKind::Other, "`target` is too long"));
- }
- target_len_in_bytes
- };
- let mut target_wchar: Vec<u16> = Vec::with_capacity(len);
- target_wchar.extend(&NON_INTERPRETED_PATH_PREFIX);
- target_wchar.append(&mut target);
-
- // Redefine the above char array into a ReparseDataBuffer we can work with
- let mut data = AlignAs {
- value: Vec::with_capacity(MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize),
- };
- let rdb = data.value.as_mut_ptr().cast::<ReparseDataBuffer>();
- let in_buffer_size: u16 = unsafe {
- // Set the type of reparse point we are creating
- ptr::addr_of_mut!((*rdb).reparse_tag).write(IO_REPARSE_TAG_MOUNT_POINT);
- ptr::addr_of_mut!((*rdb).reserved).write(0);
-
- // Copy the junction's target
- ptr::addr_of_mut!((*rdb).reparse_buffer.substitute_name_offset).write(0);
- ptr::addr_of_mut!((*rdb).reparse_buffer.substitute_name_length).write(target_len_in_bytes);
-
- // Copy the junction's link name
- ptr::addr_of_mut!((*rdb).reparse_buffer.print_name_offset).write(target_len_in_bytes + UNICODE_NULL_SIZE);
- ptr::addr_of_mut!((*rdb).reparse_buffer.print_name_length).write(0);
-
- // Safe because we checked `MAX_AVAILABLE_PATH_BUFFER`
- ptr::copy_nonoverlapping(
- target_wchar.as_ptr().cast::<u16>(),
- ptr::addr_of_mut!((*rdb).reparse_buffer.path_buffer).cast(),
- target_wchar.len(),
- );
-
- // Set the total size of the data buffer
- let size = target_len_in_bytes.wrapping_add(MOUNT_POINT_REPARSE_BUFFER_HEADER_SIZE + 2 * UNICODE_NULL_SIZE);
- ptr::addr_of_mut!((*rdb).reparse_data_length).write(size);
- size.wrapping_add(REPARSE_DATA_BUFFER_HEADER_SIZE)
- };
-
- helpers::set_reparse_point(file.as_raw_handle().cast(), rdb, u32::from(in_buffer_size))
-}
-
-pub fn delete(junction: &Path) -> io::Result<()> {
- let file = helpers::open_reparse_point(junction, true)?;
- helpers::delete_reparse_point(file.as_raw_handle().cast())
-}
-
-// Makes sure `align(ReparseDataBuffer) == 4` for struct `AlignAs` to be sound.
-const _: () = {
- const A: usize = std::mem::align_of::<ReparseDataBuffer>();
- if A != 4 {
- let _ = [0; 0][A];
- }
-};
-
-type MaybeU8 = std::mem::MaybeUninit<u8>;
-#[repr(align(4))]
-struct AlignAs {
- value: Vec<MaybeU8>,
-}
-
-pub fn exists(junction: &Path) -> io::Result<bool> {
- if !junction.exists() {
- return Ok(false);
- }
- let file = helpers::open_reparse_point(junction, false)?;
- // Allocate enough space to fit the maximum sized reparse data buffer
- let mut data = AlignAs {
- value: Vec::with_capacity(MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize),
- };
- let rdb = data.value.as_mut_ptr().cast::<ReparseDataBuffer>();
- helpers::get_reparse_data_point(file.as_raw_handle().cast(), rdb)?;
- // The reparse tag indicates if this is a junction or not
- Ok(unsafe { (*rdb).reparse_tag } == IO_REPARSE_TAG_MOUNT_POINT)
-}
-
-pub fn get_target(junction: &Path) -> io::Result<PathBuf> {
- if !junction.exists() {
- return Err(io::Error::new(io::ErrorKind::NotFound, "`junction` does not exist"));
- }
- let file = helpers::open_reparse_point(junction, false)?;
- let mut data = AlignAs {
- value: Vec::with_capacity(MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize),
- };
- let rdb = data.value.as_mut_ptr().cast::<ReparseDataBuffer>();
- helpers::get_reparse_data_point(file.as_raw_handle().cast(), rdb)?;
- // SAFETY: rdb should be initialized now
- let rdb = unsafe { &*rdb };
- if rdb.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT {
- let offset = rdb.reparse_buffer.substitute_name_offset / WCHAR_SIZE;
- let len = rdb.reparse_buffer.substitute_name_length / WCHAR_SIZE;
- let wide = unsafe {
- let buf = rdb.reparse_buffer.path_buffer.as_ptr().add(offset as usize);
- slice::from_raw_parts(buf, len as usize)
- };
- // In case of "\??\C:\foo\bar"
- let wide = wide.strip_prefix(&NON_INTERPRETED_PATH_PREFIX).unwrap_or(wide);
- Ok(PathBuf::from(OsString::from_wide(wide)))
- } else {
- Err(io::Error::new(io::ErrorKind::Other, "not a reparse tag mount point"))
- }
-}
diff --git a/vendor/junction/src/internals/helpers.rs b/vendor/junction/src/internals/helpers.rs
deleted file mode 100644
index 4731dfca2..000000000
--- a/vendor/junction/src/internals/helpers.rs
+++ /dev/null
@@ -1,229 +0,0 @@
-#[macro_use]
-mod utf16;
-
-use super::types::REPARSE_GUID_DATA_BUFFER_HEADER_SIZE;
-use super::types::{ReparseDataBuffer, ReparseGuidDataBuffer};
-
-use std::ffi::OsStr;
-use std::fs::{File, OpenOptions};
-use std::io;
-use std::mem::{self, MaybeUninit};
-use std::os::windows::ffi::OsStrExt;
-use std::os::windows::fs::OpenOptionsExt;
-use std::path::Path;
-use std::ptr;
-
-use scopeguard::ScopeGuard;
-use winapi::um::errhandlingapi::{GetLastError, SetLastError};
-use winapi::um::fileapi::GetFullPathNameW;
-use winapi::um::handleapi::CloseHandle;
-use winapi::um::ioapiset::DeviceIoControl;
-use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcessToken};
-use winapi::um::securitybaseapi::AdjustTokenPrivileges;
-use winapi::um::winbase::LookupPrivilegeValueW;
-use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT};
-use winapi::um::winioctl::{FSCTL_DELETE_REPARSE_POINT, FSCTL_GET_REPARSE_POINT, FSCTL_SET_REPARSE_POINT};
-use winapi::um::winnt::*;
-
-pub static SE_RESTORE_NAME: [u16; 19] = utf16s!(b"SeRestorePrivilege\0");
-pub static SE_BACKUP_NAME: [u16; 18] = utf16s!(b"SeBackupPrivilege\0");
-
-pub fn open_reparse_point(reparse_point: &Path, rdwr: bool) -> io::Result<File> {
- let access = if rdwr {
- GENERIC_READ | GENERIC_WRITE
- } else {
- GENERIC_READ
- };
- let mut opts = OpenOptions::new();
- opts.access_mode(access)
- .share_mode(0)
- .custom_flags(FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS);
- match opts.open(reparse_point) {
- Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {
- // Obtain privilege in case we don't have it yet
- set_privilege(rdwr)?;
- opts.open(reparse_point)
- }
- other => other,
- }
-}
-
-fn set_privilege(rdwr: bool) -> io::Result<()> {
- const ERROR_NOT_ALL_ASSIGNED: u32 = 1300;
- const TOKEN_PRIVILEGES_SIZE: u32 = mem::size_of::<TOKEN_PRIVILEGES>() as _;
- unsafe {
- let mut handle = ptr::null_mut();
- if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &mut handle) == 0 {
- return Err(io::Error::last_os_error());
- }
- let handle = scopeguard::guard(handle, |h| {
- CloseHandle(h);
- });
- let mut tp: TOKEN_PRIVILEGES = mem::zeroed();
- let name = if rdwr {
- SE_RESTORE_NAME.as_ptr()
- } else {
- SE_BACKUP_NAME.as_ptr()
- };
- if LookupPrivilegeValueW(ptr::null(), name, &mut tp.Privileges[0].Luid) == 0 {
- return Err(io::Error::last_os_error());
- }
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- if AdjustTokenPrivileges(
- *handle,
- 0,
- &mut tp,
- TOKEN_PRIVILEGES_SIZE,
- ptr::null_mut(),
- ptr::null_mut(),
- ) == 0
- {
- return Err(io::Error::last_os_error());
- }
- if GetLastError() == ERROR_NOT_ALL_ASSIGNED {
- return Err(io::Error::from_raw_os_error(ERROR_NOT_ALL_ASSIGNED as i32));
- }
-
- let handle = ScopeGuard::into_inner(handle);
- if CloseHandle(handle) == 0 {
- Err(io::Error::last_os_error())
- } else {
- Ok(())
- }
- }
-}
-
-pub fn get_reparse_data_point(handle: HANDLE, rdb: *mut ReparseDataBuffer) -> io::Result<()> {
- // Call DeviceIoControl to get the reparse point data
- let mut bytes_returned: u32 = 0;
- if unsafe {
- DeviceIoControl(
- handle,
- FSCTL_GET_REPARSE_POINT,
- ptr::null_mut(),
- 0,
- rdb.cast(),
- MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
- &mut bytes_returned,
- ptr::null_mut(),
- )
- } == 0
- {
- return Err(io::Error::last_os_error());
- }
- Ok(())
-}
-
-pub fn set_reparse_point(handle: HANDLE, rdb: *mut ReparseDataBuffer, len: u32) -> io::Result<()> {
- let mut bytes_returned: u32 = 0;
- if unsafe {
- DeviceIoControl(
- handle,
- FSCTL_SET_REPARSE_POINT,
- rdb.cast(),
- len,
- ptr::null_mut(),
- 0,
- &mut bytes_returned,
- ptr::null_mut(),
- )
- } == 0
- {
- return Err(io::Error::last_os_error());
- }
- Ok(())
-}
-
-// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa364560(v=vs.85).aspx
-pub fn delete_reparse_point(handle: HANDLE) -> io::Result<()> {
- let mut rgdb: ReparseGuidDataBuffer = unsafe { mem::zeroed() };
- rgdb.reparse_tag = IO_REPARSE_TAG_MOUNT_POINT;
- let mut bytes_returned: u32 = 0;
-
- if unsafe {
- DeviceIoControl(
- handle,
- FSCTL_DELETE_REPARSE_POINT,
- (&mut rgdb as *mut ReparseGuidDataBuffer).cast(),
- u32::from(REPARSE_GUID_DATA_BUFFER_HEADER_SIZE),
- ptr::null_mut(),
- 0,
- &mut bytes_returned,
- ptr::null_mut(),
- )
- } == 0
- {
- return Err(io::Error::last_os_error());
- }
- Ok(())
-}
-
-fn os_str_to_utf16(s: &OsStr) -> Vec<u16> {
- s.encode_wide().chain(std::iter::once(0)).collect()
-}
-
-type MaybeU16 = MaybeUninit<u16>;
-// Returns the len of buf when success.
-// Ref: <rust-lang/rust/src/libstd/sys/windows/mod.rs#L106>.
-pub fn get_full_path(target: &Path) -> io::Result<Vec<u16>> {
- let path = os_str_to_utf16(target.as_os_str());
- let file_part = ptr::null_mut();
- const U16_UNINIT: MaybeU16 = MaybeU16::uninit();
- const ERROR_INSUFFICIENT_BUFFER: u32 = 122;
- // Start off with a stack buf but then spill over to the heap if we end up
- // needing more space.
- //
- // This initial size also works around `GetFullPathNameW` returning
- // incorrect size hints for some short paths:
- // https://github.com/dylni/normpath/issues/5
- let mut stack_buf: [MaybeU16; 512] = [U16_UNINIT; 512];
- let mut heap_buf: Vec<MaybeU16> = Vec::new();
- unsafe {
- let mut n = stack_buf.len();
- loop {
- let buf = if n <= stack_buf.len() {
- &mut stack_buf[..]
- } else {
- let extra = n - heap_buf.len();
- heap_buf.reserve(extra);
- // We used `reserve` and not `reserve_exact`, so in theory we
- // may have gotten more than requested. If so, we'd like to use
- // it... so long as we won't cause overflow.
- n = heap_buf.capacity().min(u32::MAX as usize);
- // Safety: MaybeUninit<u16> does not need initialization
- heap_buf.set_len(n);
- &mut heap_buf[..]
- };
-
- SetLastError(0);
- let k = GetFullPathNameW(
- path.as_ptr().cast::<u16>(),
- n as u32,
- maybe_slice_to_ptr(buf),
- file_part,
- ) as usize;
- if k == 0 {
- return Err(crate::io::Error::last_os_error());
- }
- if GetLastError() == ERROR_INSUFFICIENT_BUFFER {
- n = n.saturating_mul(2).min(u32::MAX as usize);
- } else if k > n {
- n = k;
- } else {
- // Safety: First `k` values are initialized.
- let slice: &[u16] = maybe_slice_assume_init(&buf[..k]);
- return Ok(slice.into());
- }
- }
- }
-}
-
-unsafe fn maybe_slice_to_ptr(s: &mut [MaybeU16]) -> *mut u16 {
- s.as_mut_ptr() as *mut u16
-}
-
-unsafe fn maybe_slice_assume_init(s: &[MaybeU16]) -> &[u16] {
- // SAFETY: `MaybeUninit<T>` and T are guaranteed to have the same layout
- &*(s as *const [MaybeU16] as *const [u16])
-}
diff --git a/vendor/junction/src/internals/helpers/utf16.rs b/vendor/junction/src/internals/helpers/utf16.rs
deleted file mode 100644
index 57b75fb61..000000000
--- a/vendor/junction/src/internals/helpers/utf16.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// FIXME(const_generic)
-/// Convert ASCII bytes to UTF-16 sequences.
-macro_rules! utf16s {
- ($src:expr) => {{
- const SRC: &[u8] = $src;
- const N: usize = SRC.len();
- let mut i = 0;
- let mut dst = [0u16; N];
- while i < N {
- dst[i] = SRC[i] as u16;
- i += 1;
- }
- dst
- }};
-}
diff --git a/vendor/junction/src/internals/types.rs b/vendor/junction/src/internals/types.rs
deleted file mode 100644
index b10bf2935..000000000
--- a/vendor/junction/src/internals/types.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-use winapi::shared::guiddef;
-
-// NOTE: to use `size_of` operator, below structs should be packed.
-/// Reparse Data Buffer header size = `sizeof(u32) + 2 * sizeof(u16)`
-pub const REPARSE_DATA_BUFFER_HEADER_SIZE: u16 = 8;
-/// Reparse GUID Data Buffer header size = `sizeof(u32) + 2*sizeof(u16) + sizeof(GUID)`
-pub const REPARSE_GUID_DATA_BUFFER_HEADER_SIZE: u16 = 24;
-/// MountPointReparseBuffer header size = `4 * sizeof(u16)`
-pub const MOUNT_POINT_REPARSE_BUFFER_HEADER_SIZE: u16 = 8;
-
-type VarLenArr<T> = [T; 1];
-
-#[repr(C)]
-#[derive(Debug)]
-pub struct MountPointReparseBuffer {
- /// Offset, in bytes, of the substitute name string in the `path_buffer` array.
- /// Note that this offset must be divided by `sizeof(u16)` to get the array index.
- pub substitute_name_offset: u16,
- /// Length, in bytes, of the substitute name string. If this string is `NULL`-terminated,
- /// it does not include space for the `UNICODE_NULL` character.
- pub substitute_name_length: u16,
- /// Offset, in bytes, of the print name string in the `path_buffer` array.
- /// Note that this offset must be divided by `sizeof(u16)` to get the array index.
- pub print_name_offset: u16,
- /// Length, in bytes, of the print name string. If this string is `NULL`-terminated,
- /// it does not include space for the `UNICODE_NULL` character.
- pub print_name_length: u16,
- /// A buffer containing the Unicode-encoded path string. The path string contains the
- /// substitute name string and print name string. The substitute name and print name strings
- /// can appear in any order in the path_buffer. (To locate the substitute name and print name
- /// strings in the path_buffer, use the `substitute_name_offset`, `substitute_name_length`,
- /// `print_name_offset`, and `print_name_length` members.)
- pub path_buffer: VarLenArr<u16>,
-}
-
-/// This structure contains reparse point data for a Microsoft reparse point.
-///
-/// Read more:
-/// * https://msdn.microsoft.com/en-us/windows/desktop/ff552012
-/// * https://www.pinvoke.net/default.aspx/Structures.REPARSE_DATA_BUFFER
-#[repr(C)]
-#[derive(Debug)]
-pub struct ReparseDataBuffer {
- /// Reparse point tag. Must be a Microsoft reparse point tag.
- pub reparse_tag: u32,
- /// Size, in bytes, of the reparse data in the `data_buffer` member.
- /// Or the size of the `path_buffer` field, in bytes, plus 8 (= 4 * sizeof(u16))
- pub reparse_data_length: u16,
- /// Reversed. It SHOULD be set to 0, and MUST be ignored.
- pub reserved: u16,
- pub reparse_buffer: MountPointReparseBuffer,
-}
-
-#[repr(C)]
-#[derive(Debug)]
-pub struct GenericReparseBuffer {
- /// Microsoft-defined data for the reparse point.
- pub data_buffer: VarLenArr<u8>,
-}
-
-/// Used by all third-party layered drivers to store data for a reparse point.
-///
-/// Each reparse point contains one instance of a `ReparseGuidDataBuffer` structure.
-///
-/// Read more:
-/// * <https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_reparse_guid_data_buffer>
-#[repr(C)]
-pub struct ReparseGuidDataBuffer {
- /// Reparse point tag. This member identifies the structure of the user-defined
- /// reparse data.
- pub reparse_tag: u32,
- /// The size of the reparse data in the `data_buffer` member, in bytes. This
- /// value may vary with different tags and may vary between two uses of the
- /// same tag.
- pub reparse_data_length: u16,
- /// Reserved; do not use.
- pub reserved: u16,
- /// A `GUID` that uniquely identifies the reparse point. When setting a reparse
- /// point, the application must provide a non-`NULL` `GUID` in the `reparse_guid`
- /// member. When retrieving a reparse point from the file system, `reparse_guid`
- /// is the `GUID` assigned when the reparse point was set.
- pub reparse_guid: guiddef::GUID,
- /// The user-defined data for the reparse point. The contents are determined by
- /// the reparse point implementer. The tag in the `reparse_tag` member and the
- /// `GUID` in the `reparse_guid` member indicate how the data is to be interpreted.
- pub generic: GenericReparseBuffer,
-}
-
-impl std::fmt::Debug for ReparseGuidDataBuffer {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("ReparseGuidDataBuffer")
- .field("reparse_tag", &self.reparse_tag)
- .field("reparse_data_length", &self.reparse_data_length)
- .field("reserved", &self.reserved)
- .field(
- "reparse_guid",
- &format_args!(
- "{}:{}:{}:{:?}",
- self.reparse_guid.Data1, self.reparse_guid.Data2, self.reparse_guid.Data3, self.reparse_guid.Data4,
- ),
- )
- .field("generic", &self.generic.data_buffer)
- .finish()
- }
-}
diff --git a/vendor/junction/src/lib.rs b/vendor/junction/src/lib.rs
deleted file mode 100644
index 5f86f792b..000000000
--- a/vendor/junction/src/lib.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-/*!
-Library for working with NTFS junctions.
-
-Junction Points are a little known NTFS v5+ feature roughly equivalent to Unix
-directory symbolic links.
-
-They are supported in Windows 2000 and onwards, where a directory
-serves as a symbolic link to another directory on the computer. For example,
-if the directory `D:\SYMLINK` specified `C:\WINNT\SYSTEM32` as its target, then
-an application accessing `D:\SYMLINK\DRIVERS` would in reality be accessing
-`C:\WINNT\SYSTEM32\DRIVERS`.
-*/
-#![doc(html_root_url = "https://docs.rs/junction/~1")]
-#![cfg(windows)]
-#![deny(rust_2018_idioms)]
-
-mod internals;
-
-#[cfg(test)]
-mod tests;
-
-use std::io;
-use std::path::{Path, PathBuf};
-
-/// Creates a junction point from the specified directory to the specified target directory.
-///
-/// N.B. Only works on NTFS.
-///
-/// # Example
-///
-/// ```rust
-/// use std::io;
-/// use std::path::Path;
-/// # use std::fs;
-/// # use junction::create;
-/// fn main() -> io::Result<()> {
-/// let tmpdir = tempfile::tempdir()?;
-/// let target = tmpdir.path().join("target");
-/// let junction = tmpdir.path().join("junction");
-/// # fs::create_dir_all(&target)?;
-/// create(&target, &junction)
-/// }
-/// ```
-pub fn create<P, Q>(target: P, junction: Q) -> io::Result<()>
-where
- P: AsRef<Path>,
- Q: AsRef<Path>,
-{
- internals::create(target.as_ref(), junction.as_ref())
-}
-
-/// Deletes a `junction` reparse point from the specified file or directory.
-///
-/// N.B. Only works on NTFS.
-///
-/// This function does not delete the file or directory. Also it does nothing
-/// if the `junction` point does not exist.
-///
-/// # Example
-///
-/// ```rust
-/// use std::io;
-/// use std::path::Path;
-/// # use std::fs;
-/// # use junction::{create, delete};
-/// fn main() -> io::Result<()> {
-/// let tmpdir = tempfile::tempdir()?;
-/// let target = tmpdir.path().join("target");
-/// let junction = tmpdir.path().join("junction");
-/// # fs::create_dir_all(&target)?;
-/// create(&target, &junction)?;
-/// delete(&junction)
-/// }
-/// ```
-pub fn delete<P: AsRef<Path>>(junction: P) -> io::Result<()> {
- internals::delete(junction.as_ref())
-}
-
-/// Determines whether the specified path exists and refers to a junction point.
-///
-/// # Example
-///
-/// ```rust
-/// use std::io;
-/// # use junction::exists;
-/// fn main() -> io::Result<()> {
-/// assert!(exists(r"C:\Users\Default User")?);
-/// Ok(())
-/// }
-/// ```
-pub fn exists<P: AsRef<Path>>(junction: P) -> io::Result<bool> {
- internals::exists(junction.as_ref())
-}
-
-/// Gets the target of the specified junction point.
-///
-/// N.B. Only works on NTFS.
-///
-/// # Example
-///
-/// ```rust
-/// use std::io;
-/// # use junction::get_target;
-/// fn main() -> io::Result<()> {
-/// assert_eq!(get_target(r"C:\Users\Default User")?.to_str(), Some(r"C:\Users\Default"));
-/// Ok(())
-/// }
-/// ```
-pub fn get_target<P: AsRef<Path>>(junction: P) -> io::Result<PathBuf> {
- internals::get_target(junction.as_ref())
-}
diff --git a/vendor/junction/src/tests.rs b/vendor/junction/src/tests.rs
deleted file mode 100644
index 961e5e450..000000000
--- a/vendor/junction/src/tests.rs
+++ /dev/null
@@ -1,231 +0,0 @@
-use std::fs::{self, File};
-use std::io::{self, Write};
-use std::os::windows::fs::symlink_file;
-#[cfg(miri)]
-use std::path::{Path, PathBuf};
-
-#[cfg(not(miri))]
-use tempfile::TempDir;
-
-#[cfg(miri)]
-struct TempDir {
- path: PathBuf,
-}
-
-#[cfg(miri)]
-impl TempDir {
- fn path(&self) -> &Path {
- self.path.as_path()
- }
-}
-
-// https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes
-const ERROR_NOT_A_REPARSE_POINT: i32 = 0x1126;
-const ERROR_ALREADY_EXISTS: i32 = 0xb7;
-
-#[cfg(not(miri))]
-fn create_tempdir() -> TempDir {
- tempfile::Builder::new()
- .prefix("junction-test-")
- .tempdir_in("target/debug")
- .unwrap()
-}
-
-#[cfg(miri)]
-fn create_tempdir() -> TempDir {
- TempDir {
- path: PathBuf::from("target/debug/junction-test"),
- }
-}
-
-#[test]
-fn create_dir_all_with_junctions() {
- let tmpdir = create_tempdir();
- let target = tmpdir.path().join("target");
-
- let junction = tmpdir.path().join("junction");
- let b = junction.join("a/b");
-
- fs::create_dir_all(&target).unwrap();
-
- super::create(&target, &junction).unwrap();
- fs::create_dir_all(&b).unwrap();
- // the junction itself is not a directory, but `is_dir()` on a Path
- // follows links
- assert!(junction.is_dir());
- assert!(b.exists());
-}
-
-#[test]
-fn create_recursive_rmdir() {
- let tmpdir = create_tempdir();
- let d1 = tmpdir.path().join("d1"); // "d1"
- let dt = d1.join("t"); // "d1/t"
- let dtt = dt.join("t"); // "d1/t/t"
- let d2 = tmpdir.path().join("d2"); // "d2"
- let canary = d2.join("do_not_delete"); // "d2/do_not_delete"
-
- fs::create_dir_all(dtt).unwrap();
- fs::create_dir_all(&d2).unwrap();
- File::create(&canary).unwrap().write_all(b"foo").unwrap();
-
- super::create(d2, dt.join("d2")).unwrap(); // "d1/t/d2" -> "d2"
-
- let _ = symlink_file(&canary, d1.join("canary")); // d1/canary -> d2/do_not_delete
- fs::remove_dir_all(&d1).unwrap();
-
- assert!(!d1.is_dir());
- assert!(canary.exists());
-}
-
-#[test]
-fn create_recursive_rmdir_of_symlink() {
- // test we do not recursively delete a symlink but only dirs.
- let tmpdir = create_tempdir();
- let link = tmpdir.path().join("link");
- let dir = tmpdir.path().join("dir");
- let canary = dir.join("do_not_delete");
- fs::create_dir_all(&dir).unwrap();
- File::create(&canary).unwrap().write_all(b"foo").unwrap();
- super::create(&dir, &link).unwrap();
- fs::remove_dir_all(&link).unwrap();
-
- assert!(!link.is_dir());
- assert!(canary.exists());
-}
-
-#[test]
-fn create_directory_exist_before() {
- let tmpdir = create_tempdir();
-
- let target = tmpdir.path().join("target");
- let junction = tmpdir.path().join("junction");
-
- fs::create_dir_all(&junction).unwrap();
-
- match super::create(target, &junction) {
- Err(ref e) if e.raw_os_error() == Some(ERROR_ALREADY_EXISTS) => {}
- _ => panic!("directory exists before creating"),
- }
-}
-
-#[test]
-fn create_target_no_exist() {
- let tmpdir = create_tempdir();
-
- let target = tmpdir.path().join("target");
- let junction = tmpdir.path().join("junction");
-
- match super::create(target, junction) {
- Ok(()) => {}
- _ => panic!("junction should point to non exist target path"),
- }
-}
-
-#[test]
-fn delete_junctions() {
- let tmpdir = create_tempdir();
-
- let non_existence_dir = tmpdir.path().join("non_existence_dir");
- match super::delete(non_existence_dir) {
- Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
- _ => panic!("target path does not exist or is not a directory"),
- }
-
- let dir_not_junction = tmpdir.path().join("dir_not_junction");
- fs::create_dir_all(&dir_not_junction).unwrap();
- match super::delete(dir_not_junction) {
- Err(ref e) if e.raw_os_error() == Some(ERROR_NOT_A_REPARSE_POINT) => {}
- _ => panic!("target path is not a junction point"),
- }
-
- let file = tmpdir.path().join("foo-file");
- File::create(&file).unwrap().write_all(b"foo").unwrap();
- match super::delete(&file) {
- Err(ref e) if e.raw_os_error() == Some(ERROR_NOT_A_REPARSE_POINT) => {}
- _ => panic!("target path is not a junction point"),
- }
-}
-
-#[test]
-fn exists_verify() {
- let tmpdir = create_tempdir();
-
- // Check no such directory or file
- let no_such_dir = tmpdir.path().join("no_such_dir");
- assert!(!super::exists(no_such_dir).unwrap());
-
- // Target exists but not a junction
- let no_such_file = tmpdir.path().join("file");
- File::create(&no_such_file).unwrap().write_all(b"foo").unwrap();
- match super::exists(&no_such_file) {
- Err(ref e) if e.raw_os_error() == Some(ERROR_NOT_A_REPARSE_POINT) => {}
- _ => panic!("target exists but not a junction"),
- }
-
- let target = tmpdir.path().join("target");
- let junction = tmpdir.path().join("junction");
- let file = target.join("file");
- let junction_file = junction.join("file");
-
- fs::create_dir_all(&target).unwrap();
- File::create(file).unwrap().write_all(b"foo").unwrap();
-
- assert!(
- !junction_file.exists(),
- "file should not be located until junction created"
- );
- assert!(!super::exists(&junction).unwrap(), "junction not created yet");
-
- super::create(&target, &junction).unwrap();
- assert!(super::exists(&junction).unwrap(), "junction should exist now");
- assert_eq!(&super::get_target(&junction).unwrap(), &target);
- assert!(junction_file.exists(), "file should be accessible via the junction");
-
- super::delete(&junction).unwrap();
- match super::exists(&junction) {
- Err(ref e) if e.raw_os_error() == Some(ERROR_NOT_A_REPARSE_POINT) => {}
- _ => panic!("junction had been deleted"),
- }
- assert!(
- !junction_file.exists(),
- "file should not be located after junction deleted"
- );
- assert!(junction.exists(), "directory should not be deleted");
-}
-
-#[test]
-fn get_target_user_dirs() {
- // junction
- assert_eq!(
- super::get_target(r"C:\Users\Default User").unwrap().to_str(),
- Some(r"C:\Users\Default"),
- );
- // junction with special permissions
- assert_eq!(
- super::get_target(r"C:\Documents and Settings\").unwrap().to_str(),
- Some(r"C:\Users"),
- );
-
- let tmpdir = create_tempdir();
-
- let non_existence_dir = tmpdir.path().join("non_existence_dir");
- match super::get_target(non_existence_dir) {
- Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
- _ => panic!("target path does not exist or is not a directory"),
- }
-
- let dir_not_junction = tmpdir.path().join("dir_not_junction");
- fs::create_dir_all(&dir_not_junction).unwrap();
- match super::get_target(dir_not_junction) {
- Err(ref e) if e.raw_os_error() == Some(ERROR_NOT_A_REPARSE_POINT) => {}
- _ => panic!("target path is not a junction point"),
- }
-
- let file = tmpdir.path().join("foo-file");
- File::create(&file).unwrap().write_all(b"foo").unwrap();
- match super::get_target(file) {
- Err(ref e) if e.raw_os_error() == Some(ERROR_NOT_A_REPARSE_POINT) => {}
- _ => panic!("target path is not a junction point"),
- }
-}