moon-driver-core 0.1.3

Windows WDK driver core helpers: device, IOCTL, IRP, symlink
#![no_std]
extern crate alloc;

pub mod device;
pub mod driver;
pub mod io_request;
pub mod ioctl;
pub mod symbolic_link;

use core::cell::UnsafeCell;
use device::{dispatch_device, Device, DeviceOperations};
use driver::Driver;
use symbolic_link::SymbolicLink;
use wdk_sys::{IRP_MJ_MAXIMUM_FUNCTION, _DRIVER_OBJECT};

struct Holder(UnsafeCell<Option<(Device, SymbolicLink)>>);
unsafe impl Sync for Holder {}
static CORE_HOLDER: Holder = Holder(UnsafeCell::new(None));
static mut CUSTOM_UNLOAD: Option<unsafe extern "C" fn(*mut wdk_sys::DRIVER_OBJECT)> = None;

pub unsafe extern "C" fn driver_unload(driver: *mut wdk_sys::DRIVER_OBJECT) {
    let slot = &mut *CORE_HOLDER.0.get();
    slot.take();
    if let Some(f) = CUSTOM_UNLOAD {
        f(driver);
    }
}

pub unsafe fn init<T: DeviceOperations>(
    driver_object: *mut _DRIVER_OBJECT,
    device_name: &str,
    symlink_name: &str,
    data: T,
) -> Result<(), &'static str> {
    if driver_object.is_null() {
        return Err("driver_object is null");
    }
    let driver_object = &mut *driver_object;
    let mut driver = Driver::from_raw(driver_object);
    let device = driver.create_device(device_name, 0x22, 0, 0, data)?;
    for i in 0..IRP_MJ_MAXIMUM_FUNCTION {
        driver_object.MajorFunction[i as usize] = Some(dispatch_device);
    }
    let symlink = SymbolicLink::new(symlink_name, device_name)?;
    driver_object.DriverUnload = Some(driver_unload);
    let slot = &mut *CORE_HOLDER.0.get();
    *slot = Some((device, symlink));
    Ok(())
}

pub unsafe fn init_with_unload<T: DeviceOperations>(
    driver_object: *mut _DRIVER_OBJECT,
    device_name: &str,
    symlink_name: &str,
    data: T,
    unload: Option<unsafe extern "C" fn(*mut wdk_sys::DRIVER_OBJECT)>,
) -> Result<(), &'static str> {
    CUSTOM_UNLOAD = unload;
    init(driver_object, device_name, symlink_name, data)
}