Skip to content

Instantly share code, notes, and snippets.

@msizanoen1
Created November 3, 2019 15:31
Show Gist options
  • Save msizanoen1/2722cd221f857aa1a96f1d52d4f6a724 to your computer and use it in GitHub Desktop.
Save msizanoen1/2722cd221f857aa1a96f1d52d4f6a724 to your computer and use it in GitHub Desktop.
Remove Windows shadow backup
#[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