moon-driver-core 0.1.3

Windows WDK driver core helpers: device, IOCTL, IRP, symlink
use core::ffi::c_void;

use wdk_sys::{
    ntddk::IofCompleteRequest, IO_NO_INCREMENT, IO_STACK_LOCATION, IRP, NTSTATUS, STATUS_SUCCESS,
    STATUS_UNSUCCESSFUL,
};

pub struct IoRequest {
    raw: *mut IRP,
}

impl IoRequest {
    pub fn complete(&mut self, value: Result<usize, &'static str>) {
        let irp = self.as_raw_mut();
        match value {
            Ok(value) => {
                irp.IoStatus.Information = value as _;
                irp.IoStatus.__bindgen_anon_1.Status = STATUS_SUCCESS;
            }
            Err(_) => {
                irp.IoStatus.Information = 0;
                irp.IoStatus.__bindgen_anon_1.Status = STATUS_UNSUCCESSFUL;
            }
        }
        unsafe {
            IofCompleteRequest(irp, IO_NO_INCREMENT as _);
        }
    }
    pub fn complete_status(&mut self, status: NTSTATUS, information: usize) {
        let irp = self.as_raw_mut();
        irp.IoStatus.Information = information as _;
        irp.IoStatus.__bindgen_anon_1.Status = status;
        unsafe {
            IofCompleteRequest(irp, IO_NO_INCREMENT as _);
        }
    }
    pub fn from_raw(irp: *mut IRP) -> Self {
        Self { raw: irp }
    }
    pub fn as_raw(&self) -> &IRP {
        unsafe { &*self.raw }
    }
    pub fn as_raw_mut(&mut self) -> &mut IRP {
        unsafe { &mut *self.raw }
    }
    pub fn stack_location(&self) -> &IO_STACK_LOCATION {
        unsafe { &*moon_driver_utils::kernel_fucntion::io_get_current_irp_stack_location(self.raw) }
    }
    pub fn major(&self) -> u8 {
        self.stack_location().MajorFunction
    }
    pub fn control_code(&self) -> u32 {
        unsafe {
            self.stack_location()
                .Parameters
                .DeviceIoControl
                .IoControlCode
        }
    }
    pub fn input_buffer_length(&self) -> u32 {
        unsafe {
            self.stack_location()
                .Parameters
                .DeviceIoControl
                .InputBufferLength
        }
    }
    pub fn output_buffer_length(&self) -> u32 {
        unsafe {
            self.stack_location()
                .Parameters
                .DeviceIoControl
                .OutputBufferLength
        }
    }
    pub fn system_buffer(&self) -> *mut c_void {
        unsafe { (*self.raw).AssociatedIrp.SystemBuffer }
    }
}