use super::process::*;
use super::{AddressCallback, ProcessInfo, ProcessInfoCallback};
use crate::prelude::v1::{Result, *};
use crate::cglue::*;
use std::prelude::v1::*;
pub trait Os: for<'a> OsInner<'a> {}
impl<T: for<'a> OsInner<'a>> Os for T {}
#[cfg_attr(feature = "plugins", cglue_trait)]
#[int_result]
pub trait OsInner<'a>: Send {
#[wrap_with_group(crate::plugins::os::ProcessInstance)]
type ProcessType: crate::os::process::Process + MemoryView + 'a;
#[wrap_with_group(crate::plugins::os::IntoProcessInstance)]
type IntoProcessType: crate::os::process::Process + MemoryView + Clone + 'static;
fn process_address_list_callback(&mut self, callback: AddressCallback) -> Result<()>;
#[skip_func]
fn process_address_list(&mut self) -> Result<Vec<Address>> {
let mut ret = vec![];
self.process_address_list_callback((&mut ret).into())?;
Ok(ret)
}
fn process_info_list_callback(&mut self, mut callback: ProcessInfoCallback) -> Result<()> {
let sptr = self as *mut Self;
let inner_callback = &mut |addr| match unsafe { &mut *sptr }.process_info_by_address(addr) {
Ok(info) => callback.call(info),
Err(Error(_, ErrorKind::PartialData)) => {
log::trace!("Partial error when reading process {:x}", addr);
true
}
Err(e) => {
log::trace!("Error when reading process {:x} {:?}", addr, e);
false
}
};
unsafe { sptr.as_mut().unwrap() }.process_address_list_callback(inner_callback.into())
}
#[skip_func]
fn process_info_list(&mut self) -> Result<Vec<ProcessInfo>> {
let mut ret = vec![];
self.process_info_list_callback((&mut ret).into())?;
Ok(ret)
}
fn process_info_by_address(&mut self, address: Address) -> Result<ProcessInfo>;
fn process_info_by_name(&mut self, name: &str) -> Result<ProcessInfo> {
let mut ret = Err(Error(ErrorOrigin::OsLayer, ErrorKind::ProcessNotFound));
let callback = &mut |data: ProcessInfo| {
if (data.state == ProcessState::Unknown || data.state == ProcessState::Alive)
&& data.name.as_ref() == name
{
ret = Ok(data);
false
} else {
true
}
};
self.process_info_list_callback(callback.into())?;
ret
}
fn process_info_by_pid(&mut self, pid: Pid) -> Result<ProcessInfo> {
let mut ret = Err(Error(ErrorOrigin::OsLayer, ErrorKind::ProcessNotFound));
let callback = &mut |data: ProcessInfo| {
if data.pid == pid {
ret = Ok(data);
false
} else {
true
}
};
self.process_info_list_callback(callback.into())?;
ret
}
fn process_by_info(&'a mut self, info: ProcessInfo) -> Result<Self::ProcessType>;
fn into_process_by_info(self, info: ProcessInfo) -> Result<Self::IntoProcessType>;
fn process_by_address(&'a mut self, addr: Address) -> Result<Self::ProcessType> {
self.process_info_by_address(addr)
.and_then(move |i| self.process_by_info(i))
}
fn process_by_name(&'a mut self, name: &str) -> Result<Self::ProcessType> {
self.process_info_by_name(name)
.and_then(move |i| self.process_by_info(i))
}
fn process_by_pid(&'a mut self, pid: Pid) -> Result<Self::ProcessType> {
self.process_info_by_pid(pid)
.and_then(move |i| self.process_by_info(i))
}
fn into_process_by_address(mut self, addr: Address) -> Result<Self::IntoProcessType>
where
Self: Sized,
{
self.process_info_by_address(addr)
.and_then(|i| self.into_process_by_info(i))
}
fn into_process_by_name(mut self, name: &str) -> Result<Self::IntoProcessType>
where
Self: Sized,
{
self.process_info_by_name(name)
.and_then(|i| self.into_process_by_info(i))
}
fn into_process_by_pid(mut self, pid: Pid) -> Result<Self::IntoProcessType>
where
Self: Sized,
{
self.process_info_by_pid(pid)
.and_then(|i| self.into_process_by_info(i))
}
fn module_address_list_callback(&mut self, callback: AddressCallback) -> Result<()>;
fn module_list_callback(&mut self, mut callback: ModuleInfoCallback) -> Result<()> {
let sptr = self as *mut Self;
let inner_callback =
&mut |address: Address| match unsafe { &mut *sptr }.module_by_address(address) {
Ok(info) => callback.call(info),
Err(e) => {
log::trace!("Error when reading module {:x} {:?}", address, e);
true }
};
unsafe { sptr.as_mut().unwrap() }.module_address_list_callback(inner_callback.into())
}
fn module_by_address(&mut self, address: Address) -> Result<ModuleInfo>;
fn module_by_name(&mut self, name: &str) -> Result<ModuleInfo> {
let mut ret = Err(Error(ErrorOrigin::OsLayer, ErrorKind::ProcessNotFound));
let callback = &mut |data: ModuleInfo| {
if data.name.as_ref() == name {
ret = Ok(data);
false
} else {
true
}
};
self.module_list_callback(callback.into())?;
ret
}
#[skip_func]
fn module_list(&mut self) -> Result<Vec<ModuleInfo>> {
let mut ret = vec![];
self.module_list_callback((&mut ret).into())?;
Ok(ret)
}
fn primary_module_address(&mut self) -> Result<Address>;
fn primary_module(&mut self) -> Result<ModuleInfo> {
let addr = self.primary_module_address()?;
self.module_by_address(addr)
}
fn module_import_list_callback(
&mut self,
info: &ModuleInfo,
callback: ImportCallback,
) -> Result<()>;
fn module_export_list_callback(
&mut self,
info: &ModuleInfo,
callback: ExportCallback,
) -> Result<()>;
fn module_section_list_callback(
&mut self,
info: &ModuleInfo,
callback: SectionCallback,
) -> Result<()>;
#[skip_func]
fn module_import_list(&mut self, info: &ModuleInfo) -> Result<Vec<ImportInfo>> {
let mut ret = vec![];
self.module_import_list_callback(info, (&mut ret).into())?;
Ok(ret)
}
#[skip_func]
fn module_export_list(&mut self, info: &ModuleInfo) -> Result<Vec<ExportInfo>> {
let mut ret = vec![];
self.module_export_list_callback(info, (&mut ret).into())?;
Ok(ret)
}
#[skip_func]
fn module_section_list(&mut self, info: &ModuleInfo) -> Result<Vec<SectionInfo>> {
let mut ret = vec![];
self.module_section_list_callback(info, (&mut ret).into())?;
Ok(ret)
}
fn module_import_by_name(&mut self, info: &ModuleInfo, name: &str) -> Result<ImportInfo> {
let mut ret = Err(Error(ErrorOrigin::OsLayer, ErrorKind::ImportNotFound));
let callback = &mut |data: ImportInfo| {
if data.name.as_ref() == name {
ret = Ok(data);
false
} else {
true
}
};
self.module_import_list_callback(info, callback.into())?;
ret
}
fn module_export_by_name(&mut self, info: &ModuleInfo, name: &str) -> Result<ExportInfo> {
let mut ret = Err(Error(ErrorOrigin::OsLayer, ErrorKind::ImportNotFound));
let callback = &mut |data: ExportInfo| {
if data.name.as_ref() == name {
ret = Ok(data);
false
} else {
true
}
};
self.module_export_list_callback(info, callback.into())?;
ret
}
fn module_section_by_name(&mut self, info: &ModuleInfo, name: &str) -> Result<SectionInfo> {
let mut ret = Err(Error(ErrorOrigin::OsLayer, ErrorKind::ImportNotFound));
let callback = &mut |data: SectionInfo| {
if data.name.as_ref() == name {
ret = Ok(data);
false
} else {
true
}
};
self.module_section_list_callback(info, callback.into())?;
ret
}
fn info(&self) -> &OsInfo;
}
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
pub struct OsInfo {
pub base: Address,
pub size: umem,
pub arch: ArchitectureIdent,
}