use crate::error::{Error, Result};
use win32_min::foundation::HANDLE;
use win32_min::security_token::{ImpersonateLoggedOnUser, RevertToSelf, SetThreadToken};
#[must_use = "dropping this guard calls RevertToSelf; if you drop it immediately \
the impersonation is instantly reverted"]
pub struct ImpersonationGuard {
_not_send: core::marker::PhantomData<*const ()>,
}
impl ImpersonationGuard {
pub(crate) fn impersonate_logged_on(token: HANDLE) -> Result<Self> {
let ok = unsafe { ImpersonateLoggedOnUser(token) };
if ok == 0 {
return Err(Error::from_last_os_error("ImpersonateLoggedOnUser"));
}
Ok(ImpersonationGuard {
_not_send: core::marker::PhantomData,
})
}
pub(crate) fn set_on_current_thread(token: HANDLE) -> Result<Self> {
let ok = unsafe { SetThreadToken(core::ptr::null(), token) };
if ok == 0 {
return Err(Error::from_last_os_error("SetThreadToken"));
}
Ok(ImpersonationGuard {
_not_send: core::marker::PhantomData,
})
}
}
impl Drop for ImpersonationGuard {
fn drop(&mut self) {
let ok = unsafe { RevertToSelf() };
debug_assert!(ok != 0, "RevertToSelf failed in ImpersonationGuard::drop");
}
}