diff options
| author | bors <bors@rust-lang.org> | 2015-07-10 11:07:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-07-10 11:07:25 +0000 |
| commit | d0d37075a54b68df99c46d42655a06c575eecd3f (patch) | |
| tree | 03a0f0e30444469beca4f346f495b368ed37d2d2 /src/libstd/sys/windows | |
| parent | 4695fbde2157d1a172cea5df99bd661c4aa1204a (diff) | |
| parent | 1d202692ecfddb4b731993a5db4271c8698cbade (diff) | |
| download | rust-d0d37075a54b68df99c46d42655a06c575eecd3f.tar.gz rust-d0d37075a54b68df99c46d42655a06c575eecd3f.zip | |
Auto merge of #26751 - retep998:copy-that-floppy, r=alexcrichton
Using the OS mechanism for copying files allows the OS to optimize the transfer using stuff such as [Offloaded Data Transfers (ODX)](https://msdn.microsoft.com/en-us/library/windows/desktop/hh848056%28v=vs.85%29.aspx). Also preserves a lot more information, including NTFS [File Streams](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364404%28v=vs.85%29.aspx), which the manual implementation threw away. In addition, it is an atomic operation, unlike the manual implementation which has extra calls for copying over permissions. r? @alexcrichton
Diffstat (limited to 'src/libstd/sys/windows')
| -rw-r--r-- | src/libstd/sys/windows/c.rs | 24 | ||||
| -rw-r--r-- | src/libstd/sys/windows/fs.rs | 25 |
2 files changed, 49 insertions, 0 deletions
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 2ddf685729b..16563be2cfb 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -66,6 +66,11 @@ pub const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD; pub const HANDLE_FLAG_INHERIT: libc::DWORD = 0x00000001; +pub const PROGRESS_CONTINUE: libc::DWORD = 0; +pub const PROGRESS_CANCEL: libc::DWORD = 1; +pub const PROGRESS_STOP: libc::DWORD = 2; +pub const PROGRESS_QUIET: libc::DWORD = 3; + #[repr(C)] #[cfg(target_arch = "x86")] pub struct WSADATA { @@ -249,6 +254,19 @@ pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE; pub type PSRWLOCK = *mut SRWLOCK; pub type ULONG = c_ulong; pub type ULONG_PTR = c_ulong; +pub type LPBOOL = *mut BOOL; + +pub type LPPROGRESS_ROUTINE = ::option::Option<unsafe extern "system" fn( + TotalFileSize: libc::LARGE_INTEGER, + TotalBytesTransferred: libc::LARGE_INTEGER, + StreamSize: libc::LARGE_INTEGER, + StreamBytesTransferred: libc::LARGE_INTEGER, + dwStreamNumber: DWORD, + dwCallbackReason: DWORD, + hSourceFile: HANDLE, + hDestinationFile: HANDLE, + lpData: LPVOID, +) -> DWORD>; #[repr(C)] pub struct CONDITION_VARIABLE { pub ptr: LPVOID } @@ -413,6 +431,12 @@ extern "system" { pub fn SetHandleInformation(hObject: libc::HANDLE, dwMask: libc::DWORD, dwFlags: libc::DWORD) -> libc::BOOL; + pub fn CopyFileExW(lpExistingFileName: libc::LPCWSTR, + lpNewFileName: libc::LPCWSTR, + lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: libc::LPVOID, + pbCancel: LPBOOL, + dwCopyFlags: libc::DWORD) -> libc::BOOL; } // Functions that aren't available on Windows XP, but we still use them and just diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 36fabe72aa0..ae6b20de639 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -575,3 +575,28 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> { PathBuf::from(OsString::from_wide(buf)) }) } + +pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { + unsafe extern "system" fn callback( + _TotalFileSize: libc::LARGE_INTEGER, + TotalBytesTransferred: libc::LARGE_INTEGER, + _StreamSize: libc::LARGE_INTEGER, + _StreamBytesTransferred: libc::LARGE_INTEGER, + _dwStreamNumber: libc::DWORD, + _dwCallbackReason: libc::DWORD, + _hSourceFile: HANDLE, + _hDestinationFile: HANDLE, + lpData: libc::LPVOID, + ) -> libc::DWORD { + *(lpData as *mut i64) = TotalBytesTransferred; + c::PROGRESS_CONTINUE + } + let pfrom = to_utf16(from); + let pto = to_utf16(to); + let mut size = 0i64; + try!(cvt(unsafe { + c::CopyFileExW(pfrom.as_ptr(), pto.as_ptr(), Some(callback), + &mut size as *mut _ as *mut _, ptr::null_mut(), 0) + })); + Ok(size as u64) +} |
