summaryrefslogtreecommitdiff
path: root/crates/windows-kernel-rs/src/lib.rs
blob: 9acac055ebd14596cad549a6514126281d3e92f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#![no_std]
#![feature(alloc_error_handler)]
// TODO
// #![deny(
//   warnings,
//   nonstandard_style,
//   unused,
//   future_incompatible,
//   rust_2018_idioms
// )]
// #![deny(clippy::all, clippy::nursery, clippy::pedantic)]

extern crate alloc;

pub mod affinity;
pub mod allocator;
pub mod device;
pub mod driver;
pub mod error;
pub mod intrin;
pub mod io;
pub mod ioctl;
pub mod mdl;
pub mod memory;
pub mod process;
pub mod request;
pub mod section;
pub mod string;
pub mod symbolic_link;
pub mod sync;
pub mod user_ptr;
pub mod version;

pub use widestring::U16CString;
pub use windows_kernel_sys::base::{
  DRIVER_OBJECT,
  IRP_MJ_MAXIMUM_FUNCTION,
  NTSTATUS,
  STATUS_SUCCESS,
  UNICODE_STRING,
};

pub use crate::{
  affinity::{get_cpu_count, get_current_cpu_num, run_on_cpu, run_on_each_cpu},
  device::{
    dispatch_device,
    Access,
    Completion,
    Device,
    DeviceDoFlags,
    DeviceFlags,
    DeviceOperations,
    DeviceType,
    RequestError,
  },
  driver::Driver,
  error::Error,
  ioctl::{ControlCode, RequiredAccess, TransferMethod},
  request::{IoControlRequest, IoRequest, ReadRequest, WriteRequest},
  symbolic_link::SymbolicLink,
  user_ptr::UserPtr,
};

#[cfg(feature = "alloc")]
#[global_allocator]
static ALLOCATOR: allocator::KernelAllocator =
  allocator::KernelAllocator::new(u32::from_ne_bytes(*b"rust"));

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }

#[used]
#[no_mangle]
pub static _fltused: i32 = 0;

#[no_mangle]
pub extern "system" fn __CxxFrameHandler3() -> i32 { 0 }

#[macro_export]
macro_rules! kernel_module {
  ($module:ty) => {
    static mut __MOD: Option<$module> = None;

    #[no_mangle]
    pub extern "system" fn driver_entry(
      driver: &mut $crate::DRIVER_OBJECT,
      registry_path: &$crate::UNICODE_STRING,
    ) -> $crate::NTSTATUS {
      unsafe {
        driver.DriverUnload = Some(driver_exit);

        for i in 0..$crate::IRP_MJ_MAXIMUM_FUNCTION {
          driver.MajorFunction[i as usize] = Some($crate::dispatch_device);
        }
      }

      let driver = unsafe { Driver::from_raw(driver) };

      let registry_path = unsafe { $crate::U16CString::from_ptr_str(registry_path.Buffer) };
      let registry_path = registry_path.to_string_lossy();

      match <$module as $crate::KernelModule>::init(driver, registry_path.as_str()) {
        Ok(m) => {
          unsafe {
            __MOD = Some(m);
          }

          $crate::STATUS_SUCCESS
        }
        Err(e) => e.to_ntstatus(),
      }
    }

    pub unsafe extern "C" fn driver_exit(driver: *mut $crate::DRIVER_OBJECT) {
      let driver = unsafe { Driver::from_raw(driver) };

      match __MOD.take() {
        Some(mut m) => m.cleanup(driver),
        _ => (),
      }
    }
  };
}

pub trait KernelModule: Sized + Sync {
  fn init(driver: Driver, registry_path: &str) -> Result<Self, Error>;
  fn cleanup(&mut self, _driver: Driver) {}
}