use std::ptr;
use winapi::shared::minwindef::DWORD;
use winapi::shared::ntdef::WCHAR;
use winapi::um::winbase::{FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS};
use Errno;
pub fn with_description<F, T>(err: Errno, callback: F) -> T where
F: FnOnce(Result<&str, Errno>) -> T
{
let lang_id = 0x0800 as DWORD;
let mut buf = [0 as WCHAR; 2048];
unsafe {
let res = ::winapi::um::winbase::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
ptr::null_mut(),
err.0 as DWORD,
lang_id,
buf.as_mut_ptr(),
buf.len() as DWORD,
ptr::null_mut());
if res == 0 {
let fm_err = errno();
return callback(Err(fm_err));
}
let msg = String::from_utf16_lossy(&buf[..res as usize]);
callback(Ok(msg.trim_right()))
}
}
pub const STRERROR_NAME: &'static str = "FormatMessageW";
pub fn errno() -> Errno {
unsafe {
Errno(::winapi::um::errhandlingapi::GetLastError() as i32)
}
}
pub fn set_errno(Errno(errno): Errno) {
unsafe {
::winapi::um::errhandlingapi::SetLastError(errno as DWORD)
}
}