use super::address_strategy::AddressStrategy;
use crate::memory::MemoryError;
use crate::memory_lock::MemoryLock;
use crate::memory_resolver::MemoryAddress;
use std::time::Duration;
use super::super::register::ModifierHandler;
#[derive(Clone, Debug)]
pub struct LockConfig {
pub name: String,
pub value: Vec<u8>,
pub scan_interval: Duration,
}
pub struct LockHandler {
config: LockConfig,
memory_address: Option<MemoryAddress>,
address_strategy: AddressStrategy,
instance: Option<MemoryLock>,
}
impl LockHandler {
fn new(config: LockConfig, address_strategy: AddressStrategy) -> Self {
Self {
config,
address_strategy,
memory_address: None,
instance: None,
}
}
pub fn new_lock<T: crate::memory_lock::AsBytes>(
name: impl Into<String>,
pattern: &str,
value: T,
scan_interval: Duration,
) -> Result<Box<dyn ModifierHandler>, crate::memory_resolver::ParseError> {
let config = LockConfig {
name: name.into(),
value: value.as_bytes().to_vec(),
scan_interval,
};
Ok(Box::new(Self::new(
config,
AddressStrategy::static_pattern(pattern),
)))
}
}
impl ModifierHandler for LockHandler {
fn name(&self) -> &str {
&self.config.name
}
fn activate(
&mut self,
ctx: &crate::memory_manager::manager::ProcessContext,
) -> Result<(), MemoryError> {
let context_changed = if let Some(ref lock) = self.instance {
lock.get_handle() != Some(ctx.handle) || lock.get_pid() != Some(ctx.pid)
} else {
true };
if !context_changed {
if let Some(ref mut lock) = self.instance {
return lock.lock_bytes(&self.config.value);
}
}
let mem_addr = self
.address_strategy
.build_memory_address(ctx.architecture)?;
self.memory_address = Some(mem_addr.clone());
let target_address = mem_addr.resolve_address(ctx.handle, ctx.pid).map_err(|e| {
MemoryError::InvalidAddress(format!("Failed to resolve lock address: {}", e))
})?;
let mut lock = MemoryLock::builder()
.handle(ctx.handle)
.pid(ctx.pid)
.address(target_address)
.bytes(self.config.value.clone())
.scan_interval(self.config.scan_interval)
.build()?;
lock.lock_bytes(&self.config.value)?;
self.instance = Some(lock);
Ok(())
}
fn deactivate(&mut self) -> Result<(), MemoryError> {
if let Some(ref mut lock) = self.instance {
lock.stop()?;
}
Ok(())
}
fn is_active(&self) -> bool {
self.instance
.as_ref()
.map_or(false, |lock| lock.is_running())
}
}
unsafe impl Send for LockHandler {}