diff options
| author | Fuwn <[email protected]> | 2022-01-04 13:48:00 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2022-01-04 13:48:00 -0800 |
| commit | c33b9e296ab9563f2b180a8fa63155665055261e (patch) | |
| tree | 086cf2702939fd25769fea83e117d7058af2e75a | |
| parent | fix(makefile.toml): tidy up (diff) | |
| download | driver-c33b9e296ab9563f2b180a8fa63155665055261e.tar.xz driver-c33b9e296ab9563f2b180a8fa63155665055261e.zip | |
feat(examples): lots of new examples
Thanks, StephanvanSchaik.
20 files changed, 523 insertions, 5 deletions
@@ -1,9 +1,19 @@ [workspace] members = [ "crates/driver", + "crates/windows-kernel-build", + "crates/windows-kernel-build/examples/hello_world", + "crates/windows-kernel-rs", + "crates/windows-kernel-rs/examples/creating_devices", + "crates/windows-kernel-rs/examples/io_controls", + "crates/windows-kernel-rs/examples/reading_and_writing", + "crates/windows-kernel-rs/examples/safe_framework", + "crates/windows-kernel-sys", + "crates/windows-kernel-sys/examples/generate_bindings", + "crates/winioctl" ] diff --git a/crates/windows-kernel-build/Cargo.toml b/crates/windows-kernel-build/Cargo.toml index 8938bc0..bd23fab 100644 --- a/crates/windows-kernel-build/Cargo.toml +++ b/crates/windows-kernel-build/Cargo.toml @@ -3,7 +3,13 @@ name = "windows-kernel-build" version = "0.1.0" edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[example]] +name = "hello_world" +crate-type = ["cdylib"] +path = "examples/hello_world/src/lib.rs" + +[dev-dependencies] +winapi = { git = "https://github.com/Trantect/winapi-rs.git", branch = "feature/km", features = ["wdm", "ntstatus", "ntdef"] } [dependencies] thiserror = "1.0" diff --git a/crates/windows-kernel-build/examples/hello_world/Cargo.toml b/crates/windows-kernel-build/examples/hello_world/Cargo.toml new file mode 100644 index 0000000..1baf105 --- /dev/null +++ b/crates/windows-kernel-build/examples/hello_world/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "hello_world" +version = "0.1.0" +authors = ["Fuwn <[email protected]>"] +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +windows-kernel-build = { path = "../../../windows-kernel-build" } + +[dependencies.winapi] +git = "https://github.com/Trantect/winapi-rs.git" +branch = "feature/km" +features = [ + "wdm", + "ntstatus", + "ntdef" +] diff --git a/crates/windows-kernel-build/examples/hello_world/build.rs b/crates/windows-kernel-build/examples/hello_world/build.rs new file mode 100644 index 0000000..362047d --- /dev/null +++ b/crates/windows-kernel-build/examples/hello_world/build.rs @@ -0,0 +1 @@ +fn main() { windows_kernel_build::build().unwrap() } diff --git a/crates/windows-kernel-build/examples/hello_world/src/lib.rs b/crates/windows-kernel-build/examples/hello_world/src/lib.rs new file mode 100644 index 0000000..124c7c6 --- /dev/null +++ b/crates/windows-kernel-build/examples/hello_world/src/lib.rs @@ -0,0 +1,43 @@ +#![no_std] +#![feature(lang_items, const_extern_fn)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] + +use winapi::{ + km::wdm::{DbgPrint, DRIVER_OBJECT}, + shared::ntdef::{NTSTATUS, UNICODE_STRING}, +}; + +#[panic_handler] +const fn panic(_info: &core::panic::PanicInfo<'_>) -> ! { loop {} } + +#[lang = "eh_personality"] +const extern "C" fn eh_personality() {} + +/// # Safety +/// `unsafe` +#[no_mangle] +pub extern "system" fn driver_entry(driver: &mut DRIVER_OBJECT, _: &UNICODE_STRING) -> NTSTATUS { + unsafe { + DbgPrint("driver_entry()\0".as_ptr()); + } + + driver.DriverUnload = Some(driver_exit); + + winapi::shared::ntstatus::STATUS_SUCCESS +} + +/// # Safety +/// `unsafe` +#[no_mangle] +pub extern "system" fn driver_exit(_driver: &mut DRIVER_OBJECT) { + unsafe { + DbgPrint("driver_exit()\0".as_ptr()); + } +} diff --git a/crates/windows-kernel-rs/Cargo.toml b/crates/windows-kernel-rs/Cargo.toml index b361135..a22660c 100644 --- a/crates/windows-kernel-rs/Cargo.toml +++ b/crates/windows-kernel-rs/Cargo.toml @@ -3,7 +3,25 @@ name = "windows-kernel-rs" version = "0.1.0" edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[example]] +name = "creating_devices" +crate-type = ["cdylib"] +path = "examples/creating_devices/src/lib.rs" + +[[example]] +name = "io_controls" +crate-type = ["cdylib"] +path = "examples/io_controls/src/lib.rs" + +[[example]] +name = "reading_and_writing" +crate-type = ["cdylib"] +path = "examples/reading_and_writing/src/lib.rs" + +[[example]] +name = "safe_framework" +crate-type = ["cdylib"] +path = "examples/safe_framework/src/lib.rs" [profile.dev] panic = "abort" diff --git a/crates/windows-kernel-rs/examples/build.rs b/crates/windows-kernel-rs/examples/build.rs new file mode 100644 index 0000000..362047d --- /dev/null +++ b/crates/windows-kernel-rs/examples/build.rs @@ -0,0 +1 @@ +fn main() { windows_kernel_build::build().unwrap() } diff --git a/crates/windows-kernel-rs/examples/creating_devices/Cargo.toml b/crates/windows-kernel-rs/examples/creating_devices/Cargo.toml new file mode 100644 index 0000000..1a7fbc4 --- /dev/null +++ b/crates/windows-kernel-rs/examples/creating_devices/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "creating_devices" +version = "0.1.0" +authors = ["Fuwn <[email protected]>"] +edition = "2021" +publish = false +build = "../build.rs" + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +windows-kernel-build = { path = "../../../windows-kernel-build" } + +[dependencies] +widestring = { version = "0.4", default-features = false, features = ["alloc"] } +windows-kernel-rs = { path = "../../../windows-kernel-rs" } +windows-kernel-sys = { path = "../../../windows-kernel-sys" } diff --git a/crates/windows-kernel-rs/examples/creating_devices/src/lib.rs b/crates/windows-kernel-rs/examples/creating_devices/src/lib.rs new file mode 100644 index 0000000..119f9b4 --- /dev/null +++ b/crates/windows-kernel-rs/examples/creating_devices/src/lib.rs @@ -0,0 +1,80 @@ +#![no_std] +#![feature(lang_items, const_extern_fn)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] + +use windows_kernel_rs::{ + device::{ + Completion, + Device, + DeviceDoFlags, + DeviceFlags, + DeviceOperations, + DeviceType, + RequestError, + }, + kernel_module, + println, + request::IoRequest, + Access, + Driver, + Error, + KernelModule, + SymbolicLink, +}; + +struct MyDevice; + +impl DeviceOperations for MyDevice { + fn create(&mut self, _device: &Device, request: IoRequest) -> Result<Completion, RequestError> { + println!("userspace opened the device"); + + Ok(Completion::Complete(0, request)) + } + + fn close(&mut self, _device: &Device, request: IoRequest) -> Result<Completion, RequestError> { + println!("userspace closed the device"); + + Ok(Completion::Complete(0, request)) + } + + fn cleanup(&mut self, _device: &Device, request: IoRequest) -> Result<Completion, RequestError> { + println!("device is no longer in use by userspace"); + + Ok(Completion::Complete(0, request)) + } +} + +struct Module { + _device: Device, + _symbolic_link: SymbolicLink, +} + +impl KernelModule for Module { + fn init(mut driver: Driver, _: &str) -> Result<Self, Error> { + let device = driver.create_device( + "\\Device\\Example", + DeviceType::Unknown, + DeviceFlags::SECURE_OPEN, + DeviceDoFlags::DO_BUFFERED_IO, + Access::NonExclusive, + MyDevice, + )?; + let symbolic_link = SymbolicLink::new("\\??\\Example", "\\Device\\Example")?; + + Ok(Module { + _device: device, + _symbolic_link: symbolic_link, + }) + } + + fn cleanup(&mut self, _driver: Driver) {} +} + +kernel_module!(Module); diff --git a/crates/windows-kernel-rs/examples/io_controls/Cargo.toml b/crates/windows-kernel-rs/examples/io_controls/Cargo.toml new file mode 100644 index 0000000..1d8e6a5 --- /dev/null +++ b/crates/windows-kernel-rs/examples/io_controls/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "io_controls" +version = "0.1.0" +authors = ["Fuwn <[email protected]>"] +edition = "2021" +publish = false +build = "../build.rs" + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +windows-kernel-build = { path = "../../../windows-kernel-build" } + +[dependencies] +widestring = { version = "0.4", default-features = false, features = ["alloc"] } +windows-kernel-rs = { path = "../../../windows-kernel-rs" } +windows-kernel-sys = { path = "../../../windows-kernel-sys" } diff --git a/crates/windows-kernel-rs/examples/io_controls/src/lib.rs b/crates/windows-kernel-rs/examples/io_controls/src/lib.rs new file mode 100644 index 0000000..15e59e9 --- /dev/null +++ b/crates/windows-kernel-rs/examples/io_controls/src/lib.rs @@ -0,0 +1,98 @@ +#![no_std] +#![feature(lang_items, const_extern_fn)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] + +use windows_kernel_rs::device::{ + Completion, Device, DeviceDoFlags, DeviceFlags, DeviceOperations, DeviceType, RequestError}; +use windows_kernel_rs::request::IoControlRequest; +use windows_kernel_rs::{kernel_module, println}; +use windows_kernel_rs::{Access, Driver, Error, KernelModule, RequiredAccess, SymbolicLink}; + +struct MyDevice { + value: u32, +} + +const IOCTL_PRINT_VALUE: u32 = 0x800; +const IOCTL_READ_VALUE: u32 = 0x801; +const IOCTL_WRITE_VALUE: u32 = 0x802; + +impl MyDevice { + fn print_value(&mut self, _request: &IoControlRequest) -> Result<u32, Error> { + println!("value: {}", self.value); + + Ok(0) + } + + fn read_value(&mut self, request: &IoControlRequest) -> Result<u32, Error> { + let mut user_ptr = request.user_ptr(); + + user_ptr.write(&self.value)?; + + Ok(core::mem::size_of::<u32>() as u32) + } + + fn write_value(&mut self, request: &IoControlRequest) -> Result<u32, Error> { + let user_ptr = request.user_ptr(); + + self.value = user_ptr.read()?; + + Ok(0) + } +} + +impl DeviceOperations for MyDevice { + fn ioctl(&mut self, _device: &Device, request: IoControlRequest) -> Result<Completion, RequestError> { + let result = match request.function() { + (_, IOCTL_PRINT_VALUE) => + self.print_value(&request), + (RequiredAccess::READ_DATA, IOCTL_READ_VALUE) => + self.read_value(&request), + (RequiredAccess::WRITE_DATA, IOCTL_WRITE_VALUE) => + self.write_value(&request), + _ => Err(Error::INVALID_PARAMETER), + }; + + match result { + Ok(size) => Ok(Completion::Complete(size, request.into())), + Err(e) => Err(RequestError(e, request.into())), + } + } +} + +struct Module { + _device: Device, + _symbolic_link: SymbolicLink, +} + +impl KernelModule for Module { + fn init(mut driver: Driver, _: &str) -> Result<Self, Error> { + let device = driver.create_device( + "\\Device\\Example", + DeviceType::Unknown, + DeviceFlags::SECURE_OPEN, + DeviceDoFlags::DO_BUFFERED_IO, + Access::NonExclusive, + MyDevice { + value: 0, + }, + )?; + let symbolic_link = SymbolicLink::new("\\??\\Example", "\\Device\\Example")?; + + Ok(Module { + _device: device, + _symbolic_link: symbolic_link, + }) + } + + fn cleanup(&mut self, _driver: Driver) { + } +} + +kernel_module!(Module); diff --git a/crates/windows-kernel-rs/examples/reading_and_writing/Cargo.toml b/crates/windows-kernel-rs/examples/reading_and_writing/Cargo.toml new file mode 100644 index 0000000..2e6dad0 --- /dev/null +++ b/crates/windows-kernel-rs/examples/reading_and_writing/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "reading_and_writing" +version = "0.1.0" +authors = ["Fuwn <[email protected]>"] +edition = "2021" +publish = false +build = "../build.rs" + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +windows-kernel-build = { path = "../../../windows-kernel-build" } + +[dependencies] +widestring = { version = "0.4", default-features = false, features = ["alloc"] } +windows-kernel-rs = { path = "../../../windows-kernel-rs" } +windows-kernel-sys = { path = "../../../windows-kernel-sys" } diff --git a/crates/windows-kernel-rs/examples/reading_and_writing/src/lib.rs b/crates/windows-kernel-rs/examples/reading_and_writing/src/lib.rs new file mode 100644 index 0000000..38453ca --- /dev/null +++ b/crates/windows-kernel-rs/examples/reading_and_writing/src/lib.rs @@ -0,0 +1,80 @@ +#![no_std] +#![feature(lang_items, const_extern_fn)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] + +extern crate alloc; + +use alloc::vec; +use alloc::vec::Vec; +use windows_kernel_rs::device::{ + Completion, Device, DeviceDoFlags, DeviceFlags, DeviceOperations, DeviceType, RequestError}; +use windows_kernel_rs::request::{ReadRequest, WriteRequest}; +use windows_kernel_rs::{Access, Driver, Error, kernel_module, KernelModule, SymbolicLink}; + +struct MyDevice { + data: Vec<u8>, +} + +impl DeviceOperations for MyDevice { + fn read(&mut self, _device: &Device, request: ReadRequest) -> Result<Completion, RequestError> { + let mut user_ptr = request.user_ptr(); + let slice = user_ptr.as_mut_slice(); + + let offset = (request.offset() as usize).min(self.data.len()); + let size = slice.len().min(self.data.len() - offset); + + slice[0..size].copy_from_slice(&self.data[offset..offset + size]); + + Ok(Completion::Complete(size as u32, request.into())) + } + + fn write(&mut self, _device: &Device, request: WriteRequest) -> Result<Completion, RequestError> { + let user_ptr = request.user_ptr(); + + if request.offset() > 0 { + return Err(RequestError(Error::END_OF_FILE, request.into()))?; + } + + let slice = user_ptr.as_slice(); + let size = slice.len().min(4096); + + self.data = slice[0..size].to_vec(); + + Ok(Completion::Complete(size as u32, request.into())) + } +} + +struct Module { + _device: Device, + _symbolic_link: SymbolicLink, +} + +impl KernelModule for Module { + fn init(mut driver: Driver, _: &str) -> Result<Self, Error> { + let device = driver.create_device( + "\\Device\\Example", + DeviceType::Unknown, + DeviceFlags::SECURE_OPEN, + DeviceDoFlags::DO_BUFFERED_IO, + Access::NonExclusive, + MyDevice { + data: vec![], + }, + )?; + let symbolic_link = SymbolicLink::new("\\??\\Example", "\\Device\\Example")?; + + Ok(Module { + _device: device, + _symbolic_link: symbolic_link, + }) + } +} + +kernel_module!(Module); diff --git a/crates/windows-kernel-rs/examples/safe_framework/Cargo.toml b/crates/windows-kernel-rs/examples/safe_framework/Cargo.toml new file mode 100644 index 0000000..df9e4df --- /dev/null +++ b/crates/windows-kernel-rs/examples/safe_framework/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "safe_framework" +version = "0.1.0" +authors = ["Fuwn <[email protected]>"] +edition = "2021" +publish = false +build = "../build.rs" + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +windows-kernel-build = { path = "../../../windows-kernel-build" } + +[dependencies] +windows-kernel-rs = { path = "../../../windows-kernel-rs" } +windows-kernel-sys = { path = "../../../windows-kernel-sys" } diff --git a/crates/windows-kernel-rs/examples/safe_framework/src/lib.rs b/crates/windows-kernel-rs/examples/safe_framework/src/lib.rs new file mode 100644 index 0000000..33292e4 --- /dev/null +++ b/crates/windows-kernel-rs/examples/safe_framework/src/lib.rs @@ -0,0 +1,27 @@ +#![no_std] +#![feature(lang_items, const_extern_fn)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] + +use windows_kernel_rs::{kernel_module, println, Driver, Error, KernelModule}; + +struct Module; +impl KernelModule for Module { + fn init(_: Driver, _: &str) -> Result<Self, Error> { + println!("Hello, world!"); + + Ok(Module) + } + + fn cleanup(&mut self, _: Driver) { + println!("Bye bye!"); + } +} + +kernel_module!(Module); diff --git a/crates/windows-kernel-sys/Cargo.toml b/crates/windows-kernel-sys/Cargo.toml index dc0819d..cfbd487 100644 --- a/crates/windows-kernel-sys/Cargo.toml +++ b/crates/windows-kernel-sys/Cargo.toml @@ -3,7 +3,10 @@ name = "windows-kernel-sys" version = "0.1.0" edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[example]] +name = "generate_bindings" +crate-type = ["cdylib"] +path = "examples/generate_bindings/src/lib.rs" [features] default = ["intrin", "ntoskrnl"] diff --git a/crates/windows-kernel-sys/examples/generate_bindings/Cargo.toml b/crates/windows-kernel-sys/examples/generate_bindings/Cargo.toml new file mode 100644 index 0000000..92579f7 --- /dev/null +++ b/crates/windows-kernel-sys/examples/generate_bindings/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "generate_bindings" +version = "0.1.0" +authors = ["Fuwn <[email protected]>"] +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +windows-kernel-build = { path = "../../../windows-kernel-build" } + + +[dependencies] +winapi = { git = "https://github.com/Trantect/winapi-rs.git", branch = "feature/km", features = ["wdm", "ntstatus", "ntdef"] } +windows-kernel-sys = { path = "../../../windows-kernel-sys" } diff --git a/crates/windows-kernel-sys/examples/generate_bindings/build.rs b/crates/windows-kernel-sys/examples/generate_bindings/build.rs new file mode 100644 index 0000000..362047d --- /dev/null +++ b/crates/windows-kernel-sys/examples/generate_bindings/build.rs @@ -0,0 +1 @@ +fn main() { windows_kernel_build::build().unwrap() } diff --git a/crates/windows-kernel-sys/examples/generate_bindings/src/lib.rs b/crates/windows-kernel-sys/examples/generate_bindings/src/lib.rs new file mode 100644 index 0000000..636cadb --- /dev/null +++ b/crates/windows-kernel-sys/examples/generate_bindings/src/lib.rs @@ -0,0 +1,43 @@ +#![no_std] +#![feature(lang_items, const_extern_fn)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] + +use windows_kernel_sys::{ + base::{DRIVER_OBJECT, NTSTATUS, STATUS_SUCCESS, UNICODE_STRING}, + ntoskrnl::DbgPrint, +}; + +#[panic_handler] +const fn panic(_info: &core::panic::PanicInfo<'_>) -> ! { loop {} } + +#[lang = "eh_personality"] +const extern "C" fn eh_personality() {} + +/// # Safety +/// `unsafe` +#[no_mangle] +pub unsafe extern "system" fn driver_entry( + driver: &mut DRIVER_OBJECT, + _: &UNICODE_STRING, +) -> NTSTATUS { + // DbgPrint("driver_entry()\0".as_ptr() as _); + DbgPrint("driver_entry()\0".as_ptr().cast()); + + driver.DriverUnload = Some(driver_exit); + + STATUS_SUCCESS +} + +/// # Safety +/// `unsafe` +#[no_mangle] +pub unsafe extern "C" fn driver_exit(_driver: *mut DRIVER_OBJECT) { + DbgPrint("driver_exit()\0".as_ptr().cast()); +} diff --git a/crates/winioctl/Cargo.toml b/crates/winioctl/Cargo.toml index 656c14c..e01a387 100644 --- a/crates/winioctl/Cargo.toml +++ b/crates/winioctl/Cargo.toml @@ -3,8 +3,6 @@ name = "winioctl" version = "0.1.0" edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] bitflags = "1.3" thiserror = "1.0" |