Created
November 3, 2019 15:31
-
-
Save msizanoen1/2722cd221f857aa1a96f1d52d4f6a724 to your computer and use it in GitHub Desktop.
Remove Windows shadow backup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[cfg_attr(not(windows), allow(unused_imports))] | |
use std::ffi::OsString; | |
#[cfg(not(windows))] | |
pub fn ensure() {} | |
#[cfg(windows)] | |
fn all_volumes() -> Vec<OsString> { | |
use std::os::windows::prelude::*; | |
use winapi::shared::minwindef; | |
use winapi::shared::winerror; | |
use winapi::um::errhandlingapi; | |
use winapi::um::fileapi; | |
use winapi::um::handleapi; | |
let mut found = vec![]; | |
let mut path_buf = vec![0; minwindef::MAX_PATH]; | |
let handle = unsafe { | |
fileapi::FindFirstVolumeW(path_buf.as_mut_ptr(), path_buf.len() as minwindef::DWORD) | |
}; | |
if handle == handleapi::INVALID_HANDLE_VALUE { | |
eprintln!("Unable to begin volume enumeration"); | |
return vec![]; | |
} | |
loop { | |
let len = unsafe { libc::wcslen(path_buf.as_ptr() as *const libc::wchar_t) } as usize; | |
found.push(OsString::from_wide(&path_buf[..len])); | |
let is_success = unsafe { | |
fileapi::FindNextVolumeW( | |
handle, | |
path_buf.as_mut_ptr(), | |
path_buf.len() as minwindef::DWORD, | |
) | |
}; | |
if is_success != minwindef::TRUE { | |
let error = unsafe { errhandlingapi::GetLastError() }; | |
if error != winerror::ERROR_NO_MORE_FILES { | |
eprintln!("Error occured during volume enumeration"); | |
} | |
break; | |
} | |
} | |
unsafe { | |
fileapi::FindClose(handle); | |
} | |
found | |
} | |
#[cfg(windows)] | |
pub fn ensure() { | |
use std::mem::MaybeUninit; | |
use std::os::windows::ffi::OsStrExt; | |
use winapi::shared::minwindef; | |
use winapi::shared::winerror::S_OK; | |
use winapi::um::cguid::GUID_NULL; | |
use winapi::um::vsbackup; | |
use winapi::um::vss; | |
let mut backup_component = MaybeUninit::uninit(); | |
let result = unsafe { vsbackup::CreateVssBackupComponents(backup_component.as_mut_ptr()) }; | |
if result != S_OK { | |
eprintln!("Cannot obtain backup components"); | |
return; | |
} | |
let backup_component = unsafe { &mut *backup_component.assume_init() }; | |
let all_volumes = all_volumes(); | |
let mut snapshot_set = MaybeUninit::uninit(); | |
let result = unsafe { backup_component.StartSnapshotSet(snapshot_set.as_mut_ptr()) }; | |
if result != S_OK { | |
eprintln!("Cannot create snapshot set"); | |
return; | |
} | |
let mut snapshot_set = unsafe { snapshot_set.assume_init() }; | |
for volume in all_volumes { | |
let mut volume_w = volume.encode_wide().collect::<Vec<_>>(); | |
let result = unsafe { | |
backup_component.AddToSnapshotSet(volume_w.as_mut_ptr(), GUID_NULL, &mut snapshot_set) | |
}; | |
if result != S_OK { | |
eprintln!("Unable to add {} to snapshot set", volume.to_string_lossy()); | |
return; | |
} | |
} | |
let mut deleted_snapshots = MaybeUninit::uninit(); | |
let mut nondeleted_id = MaybeUninit::uninit(); | |
let result = unsafe { | |
backup_component.DeleteSnapshots( | |
snapshot_set, | |
vss::VSS_OBJECT_SNAPSHOT_SET, | |
minwindef::TRUE, | |
deleted_snapshots.as_mut_ptr(), | |
nondeleted_id.as_mut_ptr(), | |
) | |
}; | |
let deleted_snapshots = unsafe { deleted_snapshots.assume_init() }; | |
if result != S_OK { | |
eprintln!( | |
"Unable to delete snapshots; deleted {} snapshots", | |
deleted_snapshots | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment