Skip to content

Instantly share code, notes, and snippets.

@dmgolembiowski
Forked from Ciantic/build.rs
Created July 27, 2023 18:26
Show Gist options
  • Save dmgolembiowski/d1c8ce31b0f1e40e2ee401a7cd097a97 to your computer and use it in GitHub Desktop.
Save dmgolembiowski/d1c8ce31b0f1e40e2ee401a7cd097a97 to your computer and use it in GitHub Desktop.
Some in-memory stuff I threw away
use std::io::Write;
use std::{env, path::Path};
use std::{fs::OpenOptions, path::PathBuf};
use regex::Regex;
fn main() {
let dir = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()).join("lib");
println!("cargo:rustc-link-search=native={}", dir.display());
// Tell cargo to tell rustc to link the system bzip2
// shared library.
println!("cargo:rustc-link-lib=static=Everything64");
// Tell cargo to invalidate the built crate whenever the wrapper changes
println!("cargo:rerun-if-changed={}", dir.join("wrapper.h").display());
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header(dir.join("wrapper.h").display().to_string())
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.whitelist_function("Everything.*")
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings")
.to_string();
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from("./src");
// Replace with types for each function declaration:
//
// extern "C" {
// pub fn Everything_SetSearchW(lpString: LPCWSTR);
// }
//
// Is replaced with a type:
//
// type Everything_SetSearchW = unsafe extern "C" fn(lpString: LPCWSTR);
//
let re = Regex::new(r#"(?s)extern "C" \{\s+pub fn ([^\s]+)(\(.*?)\s+\}"#).unwrap();
let output = re.replace_all(&bindings, "pub type $1 = fn$2\n");
// let output = &bindings.replace(r#"extern "C""#, r#"#[link(name = "Everything64")]\nextern "C""#);
// let re = Regex::new(r#"extern "C"#).unwrap();
// let output = re.replace_all(&bindings, r#extern "C");
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(out_path.join("bindings.rs"))
.unwrap();
file.write_all(output.as_bytes()).unwrap();
}
use memory_module_sys::{MemoryGetProcAddress, MemoryLoadLibrary};
#[allow(warnings)]
#[allow(clippy::all)]
mod bindings {
include!("./bindings.rs");
}
use std::{
ffi::{c_void, CString},
mem,
};
pub use bindings::*;
use memory_module_sys::{MemoryGetProcAddress, MemoryLoadLibrary};
use once_cell::sync::Lazy;
use widestring::U16CString;
// const BYTES: &[u8] = include_bytes!("../lib/Everything64.dll");
struct SendPtr(*const c_void);
unsafe impl Send for SendPtr {}
unsafe impl Sync for SendPtr {}
macro_rules! load_function {
($lib: expr, $function: ident) => {
static $function: Lazy<$function> = Lazy::new(|| {
let name = stringify!($function);
let cstr = CString::new(name).unwrap();
let SendPtr(mem) = $lib;
let function_ptr = unsafe { MemoryGetProcAddress(mem, cstr.as_ptr()) };
if function_ptr.is_null() {
panic!("Could not load a function");
}
unsafe { mem::transmute::<_, $function>(function_ptr) }
});
};
}
static INMEMORY_DLL_HANDLE: Lazy<SendPtr> = Lazy::new(|| {
let mem = unsafe { MemoryLoadLibrary(BYTES.as_ptr() as _, BYTES.len()) };
if mem.is_null() {
panic!("Fail");
}
SendPtr(mem)
});
load_function!(*INMEMORY_DLL_HANDLE, Everything_SetSearchW);
load_function!(*INMEMORY_DLL_HANDLE, Everything_QueryW);
load_function!(*INMEMORY_DLL_HANDLE, Everything_GetNumResults);
load_function!(*INMEMORY_DLL_HANDLE, Everything_GetResultFileNameW);
load_function!(*INMEMORY_DLL_HANDLE, Everything_GetResultPathW);
load_function!(*INMEMORY_DLL_HANDLE, Everything_GetResultDateModified);
load_function!(*INMEMORY_DLL_HANDLE, Everything_GetResultSize);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment