rust-lang / rust-lang/rfcs

Enable the native Windows subsystem

Open
#1,955 4 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

T-compiler
Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

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.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the driver.rs example and the rustc and link.exe commands in the issue, then review how Cargo handles Windows linking and how the proposed windows_subsystem attribute would interact with no_std and panic handling. Done would require a settled design for native-subsystem linking against ntoskrnl.lib, entry-point handling, and the kernel-driver panic behavior; winapi-kmd-rs is also identified for possible review.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.