use windows::core::PCSTR;
use windows::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};
const WNF_QUIETHOURS_ACTIVE_PROFILE: u64 = 0x0D83063EA3BF1C75;
type NtQueryWnfStateDataFn =
unsafe extern "system" fn(*const u64, *const u8, *const u8, *mut u32, *mut u8, *mut u32) -> i32;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DndState {
Off,
PriorityOnly,
AlarmsOnly,
Unknown(u32),
}
impl DndState {
pub fn is_on(self) -> bool {
!matches!(self, DndState::Off)
}
fn from_raw(v: u32) -> Self {
match v {
0 => DndState::Off,
1 => DndState::PriorityOnly,
2 => DndState::AlarmsOnly,
other => DndState::Unknown(other),
}
}
}
pub fn query() -> Option<DndState> {
unsafe {
let ntdll = GetModuleHandleA(PCSTR(c"ntdll.dll".as_ptr() as *const u8)).ok()?;
let proc = GetProcAddress(ntdll, PCSTR(c"NtQueryWnfStateData".as_ptr() as *const u8))?;
let f: NtQueryWnfStateDataFn = std::mem::transmute(proc);
let mut buf = [0u8; 16];
let mut size = buf.len() as u32;
let mut stamp = 0u32;
let status = f(
&WNF_QUIETHOURS_ACTIVE_PROFILE,
std::ptr::null(),
std::ptr::null(),
&mut stamp,
buf.as_mut_ptr(),
&mut size,
);
if status < 0 || size < 4 {
return None;
}
Some(DndState::from_raw(u32::from_le_bytes([
buf[0], buf[1], buf[2], buf[3],
])))
}
}