diff options
Diffstat (limited to 'crates/windivert/src/error.rs')
| -rw-r--r-- | crates/windivert/src/error.rs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/crates/windivert/src/error.rs b/crates/windivert/src/error.rs new file mode 100644 index 0000000..2f37dd0 --- /dev/null +++ b/crates/windivert/src/error.rs @@ -0,0 +1,129 @@ +use std::convert::TryFrom; +use std::ffi::NulError; + +use thiserror::Error; +use windivert_sys::{WinDivertParam, WinDivertValueError}; + +/** +WinDivert error type. +*/ +#[derive(Debug, Error)] +pub enum WinDivertError { + /// Unexpected value in type conversions. + #[error(transparent)] + Value(#[from] WinDivertValueError), + /// Specific errors for divert constructor invocation. + #[error(transparent)] + Open(#[from] WinDivertOpenError), + /// Specific errors for [`WinDivert::recv()`](fn@super::WinDivert::<L>::recv). + #[error(transparent)] + Recv(#[from] WinDivertRecvError), + /// Error for nul terminated filter strings. + #[error(transparent)] + NullError(#[from] NulError), + /// Generic IO error. + #[error(transparent)] + IOError(#[from] std::io::Error), + /// Generic OS error. + #[error(transparent)] + OSError(#[from] windows::core::Error), + /// Error indicating that a wrong parameter was used in [`set_param()`](fn@crate::WinDivert::set_param) + #[error("Invalid parameter for set_param(). Parameter: {0:?}, Value: {1}")] + Parameter(WinDivertParam, u64), +} + +/** +Possible errors for [`WinDivertOpen()`](fn@windivert_sys::WinDivertOpen) +*/ +#[derive(Debug, Error)] +pub enum WinDivertOpenError { + /// The driver files WinDivert32.sys or WinDivert64.sys were not found. + #[error("SYS driver file not found")] + MissingSYS, // 2 + /// The calling application does not have Administrator privileges. + #[error("Running without elevated access rights")] + AccessDenied, // 5 + /// This indicates an invalid packet filter string, layer, priority, or flags. + #[error("Invalid parameter (filter string, layer, priority, or flags)")] + InvalidParameter, // 87 + /// The WinDivert32.sys or WinDivert64.sys driver does not have a valid digital signature. + #[error("SYS driver file has invalid digital signature")] + InvalidImageHash, // 577 + /// An incompatible version of the WinDivert driver is currently loaded. + #[error("An incompatible version of the WinDivert driver is currently loaded")] + IncompatibleVersion, // 654 + /// The handle was opened with the WINDIVERT_FLAG_NO_INSTALL flag and the WinDivert driver is not already installed. + #[error("The handle was opened with the WINDIVERT_FLAG_NO_INSTALL flag and the WinDivert driver is not already installed")] + MissingInstall, // 1060 + /// The WinDivert driver is blocked by security software or you are using a virtualization environment that does not support drivers. + #[error("WinDivert driver is blocked by security software or you are using a virtualization environment that does not support drivers")] + DriverBlocked, // 1257 + /// This error occurs when the Base Filtering Engine service has been disabled. + #[error("Base Filtering Engine service has been disabled")] + BaseFilteringEngineDisabled, // 1753 +} + +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)) + } +} + +/** +Possible errors for [`WinDivertRecv()`](fn@windivert_sys::WinDivertRecv) +*/ +#[derive(Debug, Error)] +pub enum WinDivertRecvError { + /// The captured packet is larger than the provided buffer. + #[error("Captured packet is larger than the provided buffer")] + InsufficientBuffer, // 122 + /// The handle has been shutdown and the packet queue is empty. + #[error("Not possible to get more data. Packet queue is empty and handle has been shutdown")] + NoData, // 232 +} + +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)) + } +} |
