1use std::{
2 error::Error, fmt::Display, num::ParseIntError, str::Utf8Error,
3 string::FromUtf8Error,
4};
5
6#[derive(Debug)]
7pub enum ProcessError {
8 ProcessNotFound,
9 ExecutablePathNotFound,
10 NotEnoughPermissions,
11 IoError {
12 inner: std::io::Error,
13 },
14 FromUtf8Error,
15 ConvertionError,
16 BadAddress(usize, usize),
17 SignatureNotFound(String),
18 OsError {
19 #[cfg(target_os = "linux")]
20 inner: nix::errno::Errno,
21 #[cfg(target_os = "windows")]
22 inner: windows::core::Error,
23 },
24}
25
26impl From<std::io::Error> for ProcessError {
27 fn from(value: std::io::Error) -> Self {
28 Self::IoError { inner: value }
29 }
30}
31
32impl From<std::num::ParseIntError> for ProcessError {
33 fn from(_: std::num::ParseIntError) -> Self {
34 Self::ConvertionError
35 }
36}
37
38impl From<std::num::TryFromIntError> for ProcessError {
39 fn from(_: std::num::TryFromIntError) -> Self {
40 Self::ConvertionError
41 }
42}
43
44impl From<FromUtf8Error> for ProcessError {
45 fn from(_: FromUtf8Error) -> Self {
46 Self::FromUtf8Error
47 }
48}
49
50impl From<Utf8Error> for ProcessError {
51 fn from(_: Utf8Error) -> Self {
52 Self::FromUtf8Error
53 }
54}
55
56#[cfg(target_os = "linux")]
58impl From<nix::errno::Errno> for ProcessError {
59 fn from(inner: nix::errno::Errno) -> Self {
60 match inner {
61 nix::errno::Errno::EPERM => Self::NotEnoughPermissions,
62 nix::errno::Errno::ESRCH => Self::ProcessNotFound,
63 _ => Self::OsError { inner },
64 }
65 }
66}
67
68#[cfg(target_os = "windows")]
70impl From<windows::core::Error> for ProcessError {
71 fn from(inner: windows::core::Error) -> Self {
72 Self::OsError { inner } }
74}
75
76impl Display for ProcessError {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 match self {
79 ProcessError::ProcessNotFound => write!(f, "Process not found!"),
80 ProcessError::IoError { .. } => write!(f, "Got I/O error!"),
81 ProcessError::FromUtf8Error => {
82 write!(f, "Got Error when converting bytes to string!")
83 }
84 ProcessError::ConvertionError => {
85 write!(f, "Got error during type convertion")
86 }
87 ProcessError::SignatureNotFound(v) => {
88 write!(f, "Cannot find signature {}", v)
89 }
90 ProcessError::OsError { .. } => write!(f, "Got OS error"),
91 ProcessError::NotEnoughPermissions => {
92 write!(f, "Not enough permissions to run, please run as sudo")
93 }
94 ProcessError::BadAddress(addr, len) => {
95 let _ = writeln!(f, "Trying to read bad address");
96 writeln!(f, "Address: {:X}, Length: {:X}", addr, len)
97 }
98 ProcessError::ExecutablePathNotFound => {
99 write!(f, "Executable path not found!")
100 }
101 }
102 }
103}
104
105impl std::error::Error for ProcessError {
106 fn source(&self) -> Option<&(dyn Error + 'static)> {
107 match self {
108 ProcessError::ProcessNotFound => None,
109 ProcessError::ExecutablePathNotFound => None,
110 ProcessError::NotEnoughPermissions => None,
111 ProcessError::IoError { inner } => Some(inner),
112 ProcessError::FromUtf8Error => None,
113 ProcessError::ConvertionError => None,
114 ProcessError::SignatureNotFound(_) => None,
115 ProcessError::OsError { inner } => Some(inner),
116 ProcessError::BadAddress(..) => None,
117 }
118 }
119}
120
121#[derive(Debug)]
122pub enum ParseSignatureError {
123 InvalidLength(usize),
124 InvalidInt { inner: ParseIntError },
125}
126
127impl From<ParseIntError> for ParseSignatureError {
128 fn from(inner: ParseIntError) -> Self {
129 Self::InvalidInt { inner }
130 }
131}
132
133impl Error for ParseSignatureError {
134 fn source(&self) -> Option<&(dyn Error + 'static)> {
135 match self {
136 ParseSignatureError::InvalidLength(_) => None,
137 ParseSignatureError::InvalidInt { inner } => Some(inner),
138 }
139 }
140}
141
142impl Display for ParseSignatureError {
143 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144 match self {
145 ParseSignatureError::InvalidLength(len) => {
146 write!(f, "Invalid string length {len}")
147 }
148 ParseSignatureError::InvalidInt { .. } => {
149 f.write_str("Failed to parse integer")
150 }
151 }
152 }
153}