Description
Since this is my first opened issue and I am not entirely sure if I am doing this right, feel free to moderate this as necessary and/or move it to the correct queue. Since this is a feature request, the guidelines told me to open the issue here, so this is what I am doing, alas not with great confidence (this is by no means an RFC).
Right now, if I want
extern "fastcall" fn unload(_ : &mut DRIVER_OBJECT) {
unsafe {
DbgPrint("Goodbye World\n\0".as_bytes().as_ptr());
}
}
#[no_mangle]
pub extern "fastcall" fn DriverEntry(d : &mut DRIVER_OBJECT, _ : *const u8) -> u32 {
unsafe {
DbgPrint("Hello World\n\0".as_bytes().as_ptr());
}
d.DriverUnload = unload;
0
}
with the type bindings from eg. the winapi-kmd-rs crate to successfully run on my machine, I have to compile it with
rustc --emit obj driver.rs
and then link it manually
link.exe /subsystem:native,5.02 /entry:DriverEntry /out:driver.sys driver.o ntoskrnl.lib
It would be great to be able to build this with cargo and be it only because the rls only supports cargo projects at the moment. For this to happen, there'd need to be the possibility to write
#![windows_subsystem = "native"]
at the top of the crate which would prompt cargo to link it with the /subsystem:native
switch and against the ntoskrnl.lib
library instead of the standard userspace Windows libraries. A quick test showed that this will probably have to go in conjunction with somethingl ike #![no_std]
or some additional work is required to define what happens should a panic! occur; this is actually not easy to do because a Windows Kernel Mode driver can only be successfully unloaded if it calls IoDeleteDevice
on all its devices, which should be possible (all the devices are available as a linked list through the DRIVER_OBJECT
variable passed to the unload function) but which itself can only be called once there are no pending interrupt/io requests on that device. For now I would be content with something as small as
#[lang = "panic_fmt"]
#[no_mangle]
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
_file: &'static str,
_line: u32) -> ! {
unsafe {
DbgPrint("A panic occured!\n\0".as_bytes().as_ptr());
}
loop {}
}
Also, the aforementioned winapi-kmd-rs should probably be reviewed (some unions in MS-structs are implemented by picking a more or less random member — maybe these could be made into untagged unions once these land) and if deemed worthy, be elevated to something more „official“ like the winapi crate.