use core::fmt;
pub type NtStatus = i32;
#[derive(Debug)]
pub enum KmError {
NtStatus(NtStatus),
PoolAllocationFailed {
size: usize,
pool_type: u32,
},
MdlOperationFailed {
reason: &'static str,
},
PhysicalMemoryFailed {
address: u64,
size: usize,
},
VirtualMemoryFailed {
address: u64,
size: usize,
reason: &'static str,
},
ProcessOperationFailed {
pid: u32,
reason: &'static str,
},
DeviceCreationFailed {
reason: &'static str,
},
SymbolicLinkFailed {
reason: &'static str,
},
IoctlFailed {
code: u32,
reason: &'static str,
},
InvalidParameter {
context: &'static str,
},
BufferTooSmall {
required: usize,
provided: usize,
},
AccessDenied {
context: &'static str,
},
InvalidAddress {
address: u64,
},
NotImplemented {
feature: &'static str,
},
}
impl fmt::Display for KmError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NtStatus(status) => write!(f, "NTSTATUS error: {status:#x}"),
Self::PoolAllocationFailed { size, pool_type } => {
write!(f, "pool allocation failed: {size} bytes, type {pool_type}")
}
Self::MdlOperationFailed { reason } => {
write!(f, "MDL operation failed: {reason}")
}
Self::PhysicalMemoryFailed { address, size } => {
write!(f, "physical memory access failed at {address:#x} ({size} bytes)")
}
Self::VirtualMemoryFailed { address, size, reason } => {
write!(f, "virtual memory operation failed at {address:#x} ({size} bytes): {reason}")
}
Self::ProcessOperationFailed { pid, reason } => {
write!(f, "process operation failed for PID {pid}: {reason}")
}
Self::DeviceCreationFailed { reason } => {
write!(f, "device creation failed: {reason}")
}
Self::SymbolicLinkFailed { reason } => {
write!(f, "symbolic link creation failed: {reason}")
}
Self::IoctlFailed { code, reason } => {
write!(f, "IOCTL {code:#x} failed: {reason}")
}
Self::InvalidParameter { context } => {
write!(f, "invalid parameter in {context}")
}
Self::BufferTooSmall { required, provided } => {
write!(f, "buffer too small: need {required} bytes, got {provided}")
}
Self::AccessDenied { context } => {
write!(f, "access denied: {context}")
}
Self::InvalidAddress { address } => {
write!(f, "invalid address: {address:#x}")
}
Self::NotImplemented { feature } => {
write!(f, "not implemented: {feature}")
}
}
}
}
pub type KmResult<T> = core::result::Result<T, KmError>;
pub mod status {
use super::NtStatus;
pub const STATUS_SUCCESS: NtStatus = 0;
pub const STATUS_UNSUCCESSFUL: NtStatus = 0xC0000001_u32 as i32;
pub const STATUS_NOT_IMPLEMENTED: NtStatus = 0xC0000002_u32 as i32;
pub const STATUS_INVALID_HANDLE: NtStatus = 0xC0000008_u32 as i32;
pub const STATUS_INVALID_PARAMETER: NtStatus = 0xC000000D_u32 as i32;
pub const STATUS_NO_SUCH_DEVICE: NtStatus = 0xC000000E_u32 as i32;
pub const STATUS_NO_SUCH_FILE: NtStatus = 0xC000000F_u32 as i32;
pub const STATUS_ACCESS_DENIED: NtStatus = 0xC0000022_u32 as i32;
pub const STATUS_BUFFER_TOO_SMALL: NtStatus = 0xC0000023_u32 as i32;
pub const STATUS_OBJECT_NAME_NOT_FOUND: NtStatus = 0xC0000034_u32 as i32;
pub const STATUS_OBJECT_NAME_COLLISION: NtStatus = 0xC0000035_u32 as i32;
pub const STATUS_INSUFFICIENT_RESOURCES: NtStatus = 0xC000009A_u32 as i32;
pub const STATUS_INVALID_DEVICE_REQUEST: NtStatus = 0xC0000010_u32 as i32;
pub const STATUS_INFO_LENGTH_MISMATCH: NtStatus = 0xC0000004_u32 as i32;
pub const STATUS_PARTIAL_COPY: NtStatus = 0x8000000D_u32 as i32;
pub const STATUS_NO_MEMORY: NtStatus = 0xC0000017_u32 as i32;
#[inline]
pub const fn nt_success(status: NtStatus) -> bool {
status >= 0
}
#[inline]
pub const fn nt_information(status: NtStatus) -> bool {
(status as u32) >> 30 == 1
}
#[inline]
pub const fn nt_warning(status: NtStatus) -> bool {
(status as u32) >> 30 == 2
}
#[inline]
pub const fn nt_error(status: NtStatus) -> bool {
(status as u32) >> 30 == 3
}
}
impl From<NtStatus> for KmError {
fn from(status: NtStatus) -> Self {
KmError::NtStatus(status)
}
}
impl KmError {
pub fn to_ntstatus(&self) -> NtStatus {
match self {
Self::NtStatus(s) => *s,
Self::PoolAllocationFailed { .. } => status::STATUS_INSUFFICIENT_RESOURCES,
Self::MdlOperationFailed { .. } => status::STATUS_UNSUCCESSFUL,
Self::PhysicalMemoryFailed { .. } => status::STATUS_ACCESS_DENIED,
Self::VirtualMemoryFailed { .. } => status::STATUS_ACCESS_DENIED,
Self::ProcessOperationFailed { .. } => status::STATUS_UNSUCCESSFUL,
Self::DeviceCreationFailed { .. } => status::STATUS_UNSUCCESSFUL,
Self::SymbolicLinkFailed { .. } => status::STATUS_UNSUCCESSFUL,
Self::IoctlFailed { .. } => status::STATUS_UNSUCCESSFUL,
Self::InvalidParameter { .. } => status::STATUS_INVALID_PARAMETER,
Self::BufferTooSmall { .. } => status::STATUS_BUFFER_TOO_SMALL,
Self::AccessDenied { .. } => status::STATUS_ACCESS_DENIED,
Self::InvalidAddress { .. } => status::STATUS_INVALID_PARAMETER,
Self::NotImplemented { .. } => status::STATUS_NOT_IMPLEMENTED,
}
}
}