use crate::*;
use super::Wrap;
use super::imports::Import;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
pub enum Export<'a> {
Symbol(&'a u32),
Forward(&'a util::CStr),
}
impl<'a> Export<'a> {
#[inline]
pub fn symbol(self) -> Option<u32> {
match self {
Export::Symbol(&rva) => Some(rva),
_ => None,
}
}
#[inline]
pub fn forward(self) -> Option<&'a util::CStr> {
match self {
Export::Forward(name) => Some(name),
_ => None,
}
}
}
impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::exports::Exports<'a, Pe32>, pe64::exports::Exports<'a, Pe64>> {
#[inline]
pub fn pe(&self) -> Wrap<Pe32, Pe64> {
match self {
Wrap::T32(exports) => Wrap::T32(exports.pe()),
Wrap::T64(exports) => Wrap::T64(exports.pe()),
}
}
#[inline]
pub fn image(&self) -> &'a image::IMAGE_EXPORT_DIRECTORY {
match self {
Wrap::T32(exports) => exports.image(),
Wrap::T64(exports) => exports.image(),
}
}
#[inline]
pub fn dll_name(&self) -> Result<&'a util::CStr> {
match self {
Wrap::T32(exports) => exports.dll_name(),
Wrap::T64(exports) => exports.dll_name(),
}
}
#[inline]
pub fn ordinal_base(&self) -> u16 {
match self {
Wrap::T32(exports) => exports.ordinal_base(),
Wrap::T64(exports) => exports.ordinal_base(),
}
}
#[inline]
pub fn functions(&self) -> Result<&'a [u32]> {
match self {
Wrap::T32(exports) => exports.functions(),
Wrap::T64(exports) => exports.functions(),
}
}
#[inline]
pub fn names(&self) -> Result<&'a [u32]> {
match self {
Wrap::T32(exports) => exports.names(),
Wrap::T64(exports) => exports.names(),
}
}
#[inline]
pub fn name_indices(&self) -> Result<&'a [u16]> {
match self {
Wrap::T32(exports) => exports.name_indices(),
Wrap::T64(exports) => exports.name_indices(),
}
}
#[inline]
pub fn by(&self) -> Result<Wrap<pe32::exports::By<'a, Pe32>, pe64::exports::By<'a, Pe64>>> {
match self {
Wrap::T32(exports) => Wrap::T32(exports.by()).transpose(),
Wrap::T64(exports) => Wrap::T64(exports.by()).transpose(),
}
}
}
impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::exports::By<'a, Pe32>, pe64::exports::By<'a, Pe64>> {
#[inline]
pub fn pe(&self) -> Wrap<Pe32, Pe64> {
match self {
Wrap::T32(by) => Wrap::T32(by.pe()),
Wrap::T64(by) => Wrap::T64(by.pe()),
}
}
#[inline]
pub fn image(&self) -> &'a image::IMAGE_EXPORT_DIRECTORY {
match self {
Wrap::T32(by) => by.image(),
Wrap::T64(by) => by.image(),
}
}
#[inline]
pub fn dll_name(&self) -> Result<&'a util::CStr> {
match self {
Wrap::T32(by) => by.dll_name(),
Wrap::T64(by) => by.dll_name(),
}
}
#[inline]
pub fn ordinal_base(&self) -> u16 {
match self {
Wrap::T32(by) => by.ordinal_base(),
Wrap::T64(by) => by.ordinal_base(),
}
}
#[inline]
pub fn functions(&self) -> &'a [u32] {
match self {
Wrap::T32(by) => by.functions(),
Wrap::T64(by) => by.functions(),
}
}
#[inline]
pub fn names(&self) -> &'a [u32] {
match self {
Wrap::T32(by) => by.names(),
Wrap::T64(by) => by.names(),
}
}
#[inline]
pub fn name_indices(&self) -> &'a [u16] {
match self {
Wrap::T32(by) => by.name_indices(),
Wrap::T64(by) => by.name_indices(),
}
}
#[inline]
pub fn check_sorted(&self) -> Result<bool> {
match self {
Wrap::T32(by) => by.check_sorted(),
Wrap::T64(by) => by.check_sorted(),
}
}
#[inline]
pub fn ordinal(&self, ordinal: u16) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.ordinal(ordinal),
Wrap::T64(by) => by.ordinal(ordinal),
}
}
#[inline]
pub fn name_linear<S: AsRef<[u8]> + ?Sized>(&self, name: &S) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.name_linear(name),
Wrap::T64(by) => by.name_linear(name),
}
}
#[inline]
pub fn name<S: AsRef<[u8]> + ?Sized>(&self, name: &S) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.name(name),
Wrap::T64(by) => by.name(name),
}
}
#[inline]
pub fn import(&self, import: Import) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.import(import),
Wrap::T64(by) => by.import(import),
}
}
#[inline]
pub fn index(&self, index: usize) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.index(index),
Wrap::T64(by) => by.index(index),
}
}
#[inline]
pub fn hint(&self, hint: usize) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.hint(hint),
Wrap::T64(by) => by.hint(hint),
}
}
#[inline]
pub fn hint_name<S: AsRef<[u8]> + ?Sized>(&self, hint: usize, name: &S) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.hint_name(hint, name),
Wrap::T64(by) => by.hint_name(hint, name),
}
}
#[inline]
pub fn name_of_hint(&self, hint: usize) -> Result<&'a util::CStr> {
match self {
Wrap::T32(by) => by.name_of_hint(hint),
Wrap::T64(by) => by.name_of_hint(hint),
}
}
#[inline]
pub fn name_lookup(&self, index: usize) -> Result<Import<'a>> {
match self {
Wrap::T32(by) => by.name_lookup(index),
Wrap::T64(by) => by.name_lookup(index),
}
}
#[inline]
fn symbol_from_rva(&self, rva: &'a u32) -> Result<Export<'a>> {
match self {
Wrap::T32(by) => by.symbol_from_rva(rva),
Wrap::T64(by) => by.symbol_from_rva(rva),
}
}
#[inline]
pub fn iter<'s>(&'s self) -> impl 's + Clone + Iterator<Item = Result<Export<'a>>> {
self.functions().iter().map(move |rva| self.symbol_from_rva(rva))
}
#[inline]
pub fn iter_names<'s>(&'s self) -> impl 's + Clone + Iterator<Item = (Result<&'a util::CStr>, Result<Export<'a>>)> {
(0..self.names().len() as u32)
.map(move |hint| (
self.name_of_hint(hint as usize),
self.hint(hint as usize),
))
}
#[inline]
pub fn iter_name_indices<'s>(&'s self) -> impl 's + Clone + Iterator<Item = (Result<&'a util::CStr>, usize)> {
(0..self.names().len() as u32)
.map(move |hint| (
self.name_of_hint(hint as usize),
self.name_indices()[hint as usize] as usize,
))
}
}
impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<Pe32, Pe64> {
#[inline]
pub fn get_export_by_ordinal(&self, ordinal: u16) -> Result<Export<'a>> {
use pe32::exports::GetProcAddress as _;
use pe64::exports::GetProcAddress as _;
match self {
Wrap::T32(pe32) => pe32.get_export(ordinal),
Wrap::T64(pe64) => pe64.get_export(ordinal),
}
}
#[inline]
pub fn get_export_by_import(&self, import: Import<'a>) -> Result<Export<'a>> {
use pe32::exports::GetProcAddress as _;
use pe64::exports::GetProcAddress as _;
match self {
Wrap::T32(pe32) => pe32.get_export(import),
Wrap::T64(pe64) => pe64.get_export(import),
}
}
#[inline]
pub fn get_export_by_name<S: ?Sized + AsRef<[u8]>>(&self, name: &S) -> Result<Export<'a>> {
use pe32::exports::GetProcAddress as _;
use pe64::exports::GetProcAddress as _;
match self {
Wrap::T32(pe32) => pe32.get_export(name),
Wrap::T64(pe64) => pe64.get_export(name),
}
}
}