summaryrefslogtreecommitdiffhomepage
path: root/crates/windivert/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/windivert/src/error.rs')
-rw-r--r--crates/windivert/src/error.rs129
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))
+ }
+}