use std::convert::TryFrom;
use std::ffi::NulError;
use thiserror::Error;
use windivert_sys::{WinDivertParam, WinDivertValueError};
#[derive(Debug, Error)]
pub enum WinDivertError {
#[error(transparent)]
Value(#[from] WinDivertValueError),
#[error(transparent)]
Open(#[from] WinDivertOpenError),
#[error(transparent)]
Recv(#[from] WinDivertRecvError),
#[error(transparent)]
NullError(#[from] NulError),
#[error(transparent)]
IOError(#[from] std::io::Error),
#[error(transparent)]
OSError(#[from] windows::core::Error),
#[error("Invalid parameter for set_param(). Parameter: {0:?}, Value: {1}")]
Parameter(WinDivertParam, u64),
}
#[derive(Debug, Error)]
pub enum WinDivertOpenError {
#[error("SYS driver file not found")]
MissingSYS, #[error("Running without elevated access rights")]
AccessDenied, #[error("Invalid parameter (filter string, layer, priority, or flags)")]
InvalidParameter, #[error("SYS driver file has invalid digital signature")]
InvalidImageHash, #[error("An incompatible version of the WinDivert driver is currently loaded")]
IncompatibleVersion, #[error("The handle was opened with the WINDIVERT_FLAG_NO_INSTALL flag and the WinDivert driver is not already installed")]
MissingInstall, #[error("WinDivert driver is blocked by security software or you are using a virtualization environment that does not support drivers")]
DriverBlocked, #[error("Base Filtering Engine service has been disabled")]
BaseFilteringEngineDisabled, }
impl TryFrom<i32> for WinDivertOpenError {
type Error = std::io::Error;
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
2 => Ok(WinDivertOpenError::MissingSYS),
5 => Ok(WinDivertOpenError::AccessDenied),
87 => Ok(WinDivertOpenError::InvalidParameter),
577 => Ok(WinDivertOpenError::InvalidImageHash),
654 => Ok(WinDivertOpenError::IncompatibleVersion),
1060 => Ok(WinDivertOpenError::MissingInstall),
1257 => Ok(WinDivertOpenError::DriverBlocked),
1753 => Ok(WinDivertOpenError::BaseFilteringEngineDisabled),
_ => Err(std::io::Error::from_raw_os_error(value)),
}
}
}
impl TryFrom<std::io::Error> for WinDivertOpenError {
type Error = std::io::Error;
fn try_from(error: std::io::Error) -> Result<Self, Self::Error> {
error
.raw_os_error()
.map(WinDivertOpenError::try_from)
.unwrap_or(Err(error))
}
}
#[derive(Debug, Error)]
pub enum WinDivertRecvError {
#[error("Captured packet is larger than the provided buffer")]
InsufficientBuffer, #[error("Not possible to get more data. Packet queue is empty and handle has been shutdown")]
NoData, }
impl TryFrom<i32> for WinDivertRecvError {
type Error = std::io::Error;
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
122 => Ok(WinDivertRecvError::InsufficientBuffer),
232 => Ok(WinDivertRecvError::NoData),
_ => Err(std::io::Error::from_raw_os_error(value)),
}
}
}
impl TryFrom<std::io::Error> for WinDivertRecvError {
type Error = std::io::Error;
fn try_from(error: std::io::Error) -> Result<Self, Self::Error> {
error
.raw_os_error()
.map(WinDivertRecvError::try_from)
.unwrap_or(Err(error))
}
}