mod implementation;
use crate::core::{g_pVBoxFuncs, get_version, pfnGetAPIVersion, pfnGetVersion};
use crate::utility::macros::macros::call_function;
use crate::VboxError;
use log::{debug, error};
use vbox_raw::sys_lib::IVirtualBoxClient;
use vbox_raw::BUILD_VER;
pub struct VirtualBoxClient {
object: *mut IVirtualBoxClient,
}
impl VirtualBoxClient {
pub fn init() -> Result<Self, VboxError> {
Self::check_version()?;
Self::init_unchecked()
}
pub fn init_unchecked() -> Result<Self, VboxError> {
debug!("get_vboxclient");
let api = g_pVBoxFuncs()?;
let mut virtualbox_client_ptr: *mut IVirtualBoxClient = std::ptr::null_mut();
let fn_ptr = unsafe { (*api).pfnClientInitialize }
.ok_or(VboxError::get_fn_error("GetVirtualBox"))?;
let result = unsafe { fn_ptr(std::ptr::null(), &mut virtualbox_client_ptr) };
debug!("{}", result);
if result != 0 || virtualbox_client_ptr.is_null() {
return Err(VboxError::new(
result,
"VirtualBoxClient::init",
"".to_string(),
None,
));
}
Ok(Self {
object: virtualbox_client_ptr,
})
}
pub fn check_version() -> Result<(), VboxError> {
let raw_ver = vbox_raw::get_version();
let vbox_sys_ver = get_version();
let vbox_ver = pfnGetVersion()?;
let current_major = vbox_ver / 1_000_000;
let current_minor = (vbox_ver / 1_000) % 1_000;
let vbox_api_ver = pfnGetAPIVersion()?;
let error = Err(VboxError::incorrect_version(
raw_ver.clone(),
vbox_sys_ver.to_string(),
vbox_ver,
vbox_api_ver,
BUILD_VER,
));
if raw_ver != vbox_sys_ver {
return error;
}
if raw_ver == "v6_1".to_string()
&& (current_major != 6 || current_minor != 1 || BUILD_VER != 61)
{
return error;
}
if raw_ver == "v7_0".to_string()
&& (current_major != 7 || current_minor != 0 || BUILD_VER != 70)
{
return error;
}
if raw_ver == "v7_1".to_string()
&& (current_major != 7 || current_minor != 1 || BUILD_VER != 71)
{
return error;
}
if raw_ver == "v7_2".to_string()
&& (current_major != 7 || current_minor != 2 || BUILD_VER != 72)
{
return error;
}
Ok(())
}
fn release(&self) -> Result<i32, VboxError> {
call_function!(self.object, Release)
}
}
impl Drop for VirtualBoxClient {
fn drop(&mut self) {
match self.release() {
Ok(count) => {
debug!("VirtualBoxClient refcount: {}", count)
}
Err(err) => {
error!("Failed drop VirtualBoxClient Error: {:?}", err)
}
}
}
}