aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/windivert/src/error.rs
blob: 2f37dd0a64ff00606ac480a08fe73f4e0d4c9f25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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))
    }
}