moon-driver-utils 0.1.0

Windows Kernel Utils
use core::{ffi::c_void, marker::PhantomData};

use moon_struct::list_entry::ListEntryOffset;
use wdk::println;
use wdk_sys::LIST_ENTRY;

pub struct ListEntrty<T>
where
    T: ListEntryOffset,
{
    _marker: PhantomData<T>,
    head: *mut LIST_ENTRY,
}

pub unsafe fn initialize_list_head(list_head: &mut LIST_ENTRY) {
    list_head.Flink = list_head;
    list_head.Blink = list_head;
}

pub unsafe fn insert_tail_list(list_head: *mut LIST_ENTRY, entry: *mut LIST_ENTRY) {
    let prev_entry = (*list_head).Blink;
    if (*prev_entry).Flink != list_head {
        println!("insert tail list fault");
        panic!();
    }

    (*entry).Flink = list_head;
    (*entry).Blink = prev_entry;
    (*prev_entry).Flink = entry;
    (*list_head).Blink = entry;
}

pub unsafe fn remove_entry_list(entry: *mut LIST_ENTRY) -> bool {
    let node_ref = &mut *entry;
    let prev = &mut *node_ref.Blink;
    let next = &mut *node_ref.Flink;

    if next.Blink != entry || prev.Flink != entry {
        println!("remove list fault");
        panic!();
    }

    prev.Flink = next as *mut _;
    next.Blink = prev as *mut _;
    return prev as *mut _ == next as *mut _;
}

impl<T> ListEntrty<T>
where
    T: ListEntryOffset,
{
    pub fn from_head(head: *mut LIST_ENTRY) -> Self {
        Self {
            _marker: PhantomData,
            head: head,
        }
    }

    pub fn init(&mut self) {
        unsafe { initialize_list_head(&mut *self.head) };
    }

    pub fn insert_tail(&mut self, entry: *mut LIST_ENTRY) {
        unsafe { insert_tail_list(self.head, entry) };
    }

    pub fn remove_node(&mut self, entry: *mut LIST_ENTRY) {
        let _ = unsafe { remove_entry_list(entry) };
    }

    pub fn into_iter(&mut self) -> ListEntryIterMut<T> {
        ListEntryIterMut {
            current: Option::None,
            head: self.head,
            _marker: core::marker::PhantomData,
        }
    }

    pub fn as_ptr(&mut self) -> *mut LIST_ENTRY {
        self.head
    }
}

pub struct ListEntryIterMut<'a, T>
where
    T: ListEntryOffset,
{
    current: Option<*mut T>,
    head: *mut LIST_ENTRY,
    _marker: core::marker::PhantomData<&'a T>,
}

impl<'a, T> Iterator for ListEntryIterMut<'a, T>
where
    T: ListEntryOffset,
{
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
        let next_list;

        if self.current.is_none() {
            next_list = unsafe { (*(self.head)).Flink };
        } else {
            let node = self.current.unwrap();
            next_list = unsafe {
                (*((node as *mut c_void).add(T::get_list_entry_offset()) as *mut LIST_ENTRY)).Flink
            };
        }

        // no elements
        if next_list == self.head {
            return None;
        }

        let next = unsafe {
            (next_list as *mut _ as *mut c_void).add(0 - T::get_list_entry_offset()) as *mut T
        };

        self.current = Some(next);

        let next_item = unsafe { &mut (*next) };
        Some(next_item)
    }
}