mirror of
https://github.com/StephanvanSchaik/windows-kernel-rs
synced 2026-08-09 12:23:09 +00:00
05-creating-devices: add example on creating devices
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
[build]
|
||||
target = "x86_64-pc-windows-msvc"
|
||||
|
||||
rustflags = [
|
||||
# Pre Link Args
|
||||
"-Z", "pre-link-arg=/NOLOGO",
|
||||
"-Z", "pre-link-arg=/NXCOMPAT",
|
||||
"-Z", "pre-link-arg=/NODEFAULTLIB",
|
||||
"-Z", "pre-link-arg=/SUBSYSTEM:NATIVE",
|
||||
"-Z", "pre-link-arg=/DRIVER",
|
||||
"-Z", "pre-link-arg=/DYNAMICBASE",
|
||||
"-Z", "pre-link-arg=/MANIFEST:NO",
|
||||
|
||||
# Post Link Args
|
||||
"-C", "link-arg=/OPT:REF,ICF",
|
||||
"-C", "link-arg=/ENTRY:driver_entry",
|
||||
"-C", "link-arg=/MERGE:.edata=.rdata",
|
||||
"-C", "link-arg=/MERGE:.rustc=.data",
|
||||
"-C", "link-arg=/INTEGRITYCHECK",
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "driver"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
|
||||
[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" }
|
||||
@@ -0,0 +1,37 @@
|
||||
[env]
|
||||
VC_BUILD_DIR="C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat"
|
||||
|
||||
[env.development]
|
||||
TARGET_PATH = "target/x86_64-pc-windows-msvc/debug"
|
||||
|
||||
[env.production]
|
||||
TARGET_PATH = "target/x86_64-pc-windows-msvc/release"
|
||||
BUILD_RELEASE = "--release"
|
||||
|
||||
[tasks.clean-cert]
|
||||
script = '''
|
||||
# Remove the self-signed certificate.
|
||||
if exist DriverCertificate.cer ( rm DriverCertificate.cer )
|
||||
'''
|
||||
|
||||
[tasks.build-driver]
|
||||
script = '''
|
||||
cargo b %BUILD_FLAGS%
|
||||
'''
|
||||
|
||||
[tasks.rename]
|
||||
ignore_errors = true
|
||||
script = '''
|
||||
cd %TARGET_PATH%
|
||||
rename driver.dll driver.sys
|
||||
'''
|
||||
|
||||
[tasks.sign]
|
||||
dependencies = ["build-driver", "rename"]
|
||||
script = '''
|
||||
call "%VC_BUILD_DIR%"
|
||||
|
||||
if not exist DriverCertificate.cer ( makecert -r -pe -ss PrivateCertStore -n CN=DriverCertificate DriverCertificate.cer ) else ( echo Certificate already exists. )
|
||||
|
||||
signtool sign /a /v /s PrivateCertStore /n DriverCertificate /fd certHash /t http://timestamp.digicert.com %TARGET_PATH%/driver.sys
|
||||
'''
|
||||
@@ -0,0 +1,22 @@
|
||||
use windows_kernel_build::DirectoryType;
|
||||
|
||||
fn main() {
|
||||
// Get the path to the kernel libraries.
|
||||
let dir = windows_kernel_build::get_km_dir(DirectoryType::Library).unwrap();
|
||||
|
||||
// Append the architecture based on our target.
|
||||
let target = std::env::var("TARGET").unwrap();
|
||||
|
||||
let arch = if target.contains("x86_64") {
|
||||
"x64"
|
||||
} else if target.contains("i686") {
|
||||
"x86"
|
||||
} else {
|
||||
panic!("The target {} is currently not supported.", target);
|
||||
};
|
||||
|
||||
let dir = dir.join(arch);
|
||||
|
||||
// Specify the link path.
|
||||
println!("cargo:rustc-link-search=native={}", dir.to_str().unwrap());
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
nightly
|
||||
@@ -0,0 +1,55 @@
|
||||
#![no_std]
|
||||
|
||||
use windows_kernel_rs::{Access, Device, DeviceFlags, DeviceOperations, DeviceType, Driver, Error, kernel_module, KernelModule, println, SymbolicLink, UserPtr};
|
||||
|
||||
struct MyDevice;
|
||||
|
||||
impl DeviceOperations for MyDevice {
|
||||
fn create(&mut self, device: &Device) -> Result<(), Error> {
|
||||
println!("userspace opened the device");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&mut self, device: &Device) -> Result<(), Error> {
|
||||
println!("userspace closed the device");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cleanup(&mut self, device: &Device) -> Result<(), Error> {
|
||||
println!("device is no longer in use by userspace");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ioctl(&mut self, device: &Device, ioctl_num: u32, user_ptr: &mut UserPtr) -> Result<(), Error> {
|
||||
println!("request from userspace");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
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);
|
||||
Reference in New Issue
Block a user