1use crate::*;
2use super::Wrap;
3use super::imports::Import;
4
5#[derive(Copy, Clone, Debug, Eq, PartialEq)]
7#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
8pub enum Export<'a> {
9 Symbol(&'a u32),
11 Forward(&'a util::CStr),
16}
17impl<'a> Export<'a> {
18 #[inline]
20 pub fn symbol(self) -> Option<u32> {
21 match self {
22 Export::Symbol(&rva) => Some(rva),
23 _ => None,
24 }
25 }
26 #[inline]
28 pub fn forward(self) -> Option<&'a util::CStr> {
29 match self {
30 Export::Forward(name) => Some(name),
31 _ => None,
32 }
33 }
34}
35
36impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::exports::Exports<'a, Pe32>, pe64::exports::Exports<'a, Pe64>> {
38 #[inline]
40 pub fn pe(&self) -> Wrap<Pe32, Pe64> {
41 match self {
42 Wrap::T32(exports) => Wrap::T32(exports.pe()),
43 Wrap::T64(exports) => Wrap::T64(exports.pe()),
44 }
45 }
46 #[inline]
48 pub fn image(&self) -> &'a image::IMAGE_EXPORT_DIRECTORY {
49 match self {
50 Wrap::T32(exports) => exports.image(),
51 Wrap::T64(exports) => exports.image(),
52 }
53 }
54 #[inline]
56 pub fn dll_name(&self) -> Result<&'a util::CStr> {
57 match self {
58 Wrap::T32(exports) => exports.dll_name(),
59 Wrap::T64(exports) => exports.dll_name(),
60 }
61 }
62 #[inline]
64 pub fn ordinal_base(&self) -> u16 {
65 match self {
66 Wrap::T32(exports) => exports.ordinal_base(),
67 Wrap::T64(exports) => exports.ordinal_base(),
68 }
69 }
70 #[inline]
72 pub fn functions(&self) -> Result<&'a [u32]> {
73 match self {
74 Wrap::T32(exports) => exports.functions(),
75 Wrap::T64(exports) => exports.functions(),
76 }
77 }
78 #[inline]
80 pub fn names(&self) -> Result<&'a [u32]> {
81 match self {
82 Wrap::T32(exports) => exports.names(),
83 Wrap::T64(exports) => exports.names(),
84 }
85 }
86 #[inline]
88 pub fn name_indices(&self) -> Result<&'a [u16]> {
89 match self {
90 Wrap::T32(exports) => exports.name_indices(),
91 Wrap::T64(exports) => exports.name_indices(),
92 }
93 }
94 #[inline]
96 pub fn by(&self) -> Result<Wrap<pe32::exports::By<'a, Pe32>, pe64::exports::By<'a, Pe64>>> {
97 match self {
98 Wrap::T32(exports) => Wrap::T32(exports.by()).transpose(),
99 Wrap::T64(exports) => Wrap::T64(exports.by()).transpose(),
100 }
101 }
102}
103
104impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::exports::By<'a, Pe32>, pe64::exports::By<'a, Pe64>> {
106 #[inline]
108 pub fn pe(&self) -> Wrap<Pe32, Pe64> {
109 match self {
110 Wrap::T32(by) => Wrap::T32(by.pe()),
111 Wrap::T64(by) => Wrap::T64(by.pe()),
112 }
113 }
114 #[inline]
116 pub fn image(&self) -> &'a image::IMAGE_EXPORT_DIRECTORY {
117 match self {
118 Wrap::T32(by) => by.image(),
119 Wrap::T64(by) => by.image(),
120 }
121 }
122 #[inline]
124 pub fn dll_name(&self) -> Result<&'a util::CStr> {
125 match self {
126 Wrap::T32(by) => by.dll_name(),
127 Wrap::T64(by) => by.dll_name(),
128 }
129 }
130 #[inline]
132 pub fn ordinal_base(&self) -> u16 {
133 match self {
134 Wrap::T32(by) => by.ordinal_base(),
135 Wrap::T64(by) => by.ordinal_base(),
136 }
137 }
138 #[inline]
140 pub fn functions(&self) -> &'a [u32] {
141 match self {
142 Wrap::T32(by) => by.functions(),
143 Wrap::T64(by) => by.functions(),
144 }
145 }
146 #[inline]
148 pub fn names(&self) -> &'a [u32] {
149 match self {
150 Wrap::T32(by) => by.names(),
151 Wrap::T64(by) => by.names(),
152 }
153 }
154 #[inline]
156 pub fn name_indices(&self) -> &'a [u16] {
157 match self {
158 Wrap::T32(by) => by.name_indices(),
159 Wrap::T64(by) => by.name_indices(),
160 }
161 }
162 #[inline]
164 pub fn check_sorted(&self) -> Result<bool> {
165 match self {
166 Wrap::T32(by) => by.check_sorted(),
167 Wrap::T64(by) => by.check_sorted(),
168 }
169 }
170 #[inline]
172 pub fn ordinal(&self, ordinal: u16) -> Result<Export<'a>> {
173 match self {
174 Wrap::T32(by) => by.ordinal(ordinal),
175 Wrap::T64(by) => by.ordinal(ordinal),
176 }
177 }
178 #[inline]
180 pub fn name_linear<S: AsRef<[u8]> + ?Sized>(&self, name: &S) -> Result<Export<'a>> {
181 match self {
182 Wrap::T32(by) => by.name_linear(name),
183 Wrap::T64(by) => by.name_linear(name),
184 }
185 }
186 #[inline]
188 pub fn name<S: AsRef<[u8]> + ?Sized>(&self, name: &S) -> Result<Export<'a>> {
189 match self {
190 Wrap::T32(by) => by.name(name),
191 Wrap::T64(by) => by.name(name),
192 }
193 }
194 #[inline]
196 pub fn import(&self, import: Import) -> Result<Export<'a>> {
197 match self {
198 Wrap::T32(by) => by.import(import),
199 Wrap::T64(by) => by.import(import),
200 }
201 }
202 #[inline]
204 pub fn index(&self, index: usize) -> Result<Export<'a>> {
205 match self {
206 Wrap::T32(by) => by.index(index),
207 Wrap::T64(by) => by.index(index),
208 }
209 }
210 #[inline]
212 pub fn hint(&self, hint: usize) -> Result<Export<'a>> {
213 match self {
214 Wrap::T32(by) => by.hint(hint),
215 Wrap::T64(by) => by.hint(hint),
216 }
217 }
218 #[inline]
220 pub fn hint_name<S: AsRef<[u8]> + ?Sized>(&self, hint: usize, name: &S) -> Result<Export<'a>> {
221 match self {
222 Wrap::T32(by) => by.hint_name(hint, name),
223 Wrap::T64(by) => by.hint_name(hint, name),
224 }
225 }
226 #[inline]
228 pub fn name_of_hint(&self, hint: usize) -> Result<&'a util::CStr> {
229 match self {
230 Wrap::T32(by) => by.name_of_hint(hint),
231 Wrap::T64(by) => by.name_of_hint(hint),
232 }
233 }
234 #[inline]
236 pub fn name_lookup(&self, index: usize) -> Result<Import<'a>> {
237 match self {
238 Wrap::T32(by) => by.name_lookup(index),
239 Wrap::T64(by) => by.name_lookup(index),
240 }
241 }
242 #[inline]
243 fn symbol_from_rva(&self, rva: &'a u32) -> Result<Export<'a>> {
244 match self {
245 Wrap::T32(by) => by.symbol_from_rva(rva),
246 Wrap::T64(by) => by.symbol_from_rva(rva),
247 }
248 }
249 #[inline]
251 pub fn iter<'s>(&'s self) -> impl 's + Clone + Iterator<Item = Result<Export<'a>>> {
252 self.functions().iter().map(move |rva| self.symbol_from_rva(rva))
253 }
254 #[inline]
256 pub fn iter_names<'s>(&'s self) -> impl 's + Clone + Iterator<Item = (Result<&'a util::CStr>, Result<Export<'a>>)> {
257 (0..self.names().len() as u32)
258 .map(move |hint| (
259 self.name_of_hint(hint as usize),
260 self.hint(hint as usize),
261 ))
262 }
263 #[inline]
265 pub fn iter_name_indices<'s>(&'s self) -> impl 's + Clone + Iterator<Item = (Result<&'a util::CStr>, usize)> {
266 (0..self.names().len() as u32)
267 .map(move |hint| (
268 self.name_of_hint(hint as usize),
269 self.name_indices()[hint as usize] as usize,
270 ))
271 }
272}
273
274impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<Pe32, Pe64> {
276 #[inline]
278 pub fn get_export_by_ordinal(&self, ordinal: u16) -> Result<Export<'a>> {
279 use pe32::exports::GetProcAddress as _;
280 use pe64::exports::GetProcAddress as _;
281 match self {
282 Wrap::T32(pe32) => pe32.get_export(ordinal),
283 Wrap::T64(pe64) => pe64.get_export(ordinal),
284 }
285 }
286 #[inline]
288 pub fn get_export_by_import(&self, import: Import<'a>) -> Result<Export<'a>> {
289 use pe32::exports::GetProcAddress as _;
290 use pe64::exports::GetProcAddress as _;
291 match self {
292 Wrap::T32(pe32) => pe32.get_export(import),
293 Wrap::T64(pe64) => pe64.get_export(import),
294 }
295 }
296 #[inline]
298 pub fn get_export_by_name<S: ?Sized + AsRef<[u8]>>(&self, name: &S) -> Result<Export<'a>> {
299 use pe32::exports::GetProcAddress as _;
300 use pe64::exports::GetProcAddress as _;
301 match self {
302 Wrap::T32(pe32) => pe32.get_export(name),
303 Wrap::T64(pe64) => pe64.get_export(name),
304 }
305 }
306}