Skip to content

Commit d5b7b6e

Browse files
authored
docs: add AGENTS.md and CLAUDE.md for Copilot code review (#50)
Adds AGENTS.md (and a CLAUDE.md pointer) so that GitHub Copilot code review has the repo context it needs to give useful feedback: driver crate anatomy, WDF patterns, lint configuration, and build/test commands. Also useful for other AI coding assistants that read these files.
1 parent ff8a63e commit d5b7b6e

2 files changed

Lines changed: 183 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Copilot Instructions
2+
3+
Rust ports of Windows driver samples from the official [Windows Driver Samples](https://github.com/microsoft/Windows-driver-samples), using crates from [windows-drivers-rs](https://github.com/microsoft/windows-drivers-rs). All driver crates target `#![no_std]` and compile as `cdylib` for the Windows kernel.
4+
5+
## Build Commands
6+
7+
Requires EWDK build environment, Clang (LLVM), and `cargo-make`.
8+
9+
```shell
10+
# Build all workspace members
11+
cargo build --locked
12+
13+
# Build and package drivers (stamps INF, creates CAT file in Package/)
14+
cargo make
15+
16+
# Build a specific driver sample
17+
cargo make --cwd general/echo/kmdf/driver/DriverSync
18+
19+
# Run the echo test app
20+
cargo run --bin echoapp
21+
cargo run --bin echoapp -- -Async
22+
```
23+
24+
## Lint and Formatting
25+
26+
CI enforces all of these — run before submitting PRs:
27+
28+
```shell
29+
# Clippy (treats warnings as errors)
30+
cargo clippy --locked --all-targets -- -D warnings
31+
32+
# Clippy with nightly features
33+
cargo +nightly clippy --locked --all-targets --features nightly -- -D warnings
34+
35+
# Rust formatting (requires nightly due to unstable rustfmt options)
36+
cargo +nightly fmt --all -- --check
37+
38+
# TOML formatting
39+
taplo fmt --check --diff
40+
41+
# Unused dependency detection
42+
cargo machete
43+
44+
# Security audit
45+
cargo audit --deny warnings
46+
47+
# Documentation build (warnings are errors via RUSTDOCFLAGS=-D warnings in CI)
48+
cargo doc --locked
49+
```
50+
51+
## Architecture
52+
53+
### Workspace Layout
54+
55+
- **`general/`** — Functional driver samples (e.g., `echo/kmdf/driver/DriverSync` is a KMDF echo driver)
56+
- **`tools/`** — Diagnostic/verification drivers (e.g., `dv/kmdf/fail_driver_pool_leak` intentionally leaks memory for Driver Verifier testing)
57+
- **`general/echo/kmdf/exe`** — User-mode test app (`echoapp`) for the echo driver
58+
59+
### Driver Crate Anatomy
60+
61+
Each driver crate follows this file structure:
62+
63+
- **`lib.rs`** — Crate root with `#![no_std]`, clippy lints, module declarations, context structs, `WDF_*_SIZE` constants, and `wdf_declare_context_type!` macro invocations
64+
- **`driver.rs`**`DriverEntry` (exported as `#[export_name = "DriverEntry"]`, `extern "system"`) and `EvtDriverDeviceAdd` callback
65+
- **`device.rs`** — Device creation, PnP/power callbacks
66+
- **`queue.rs`** — I/O queue initialization and request handling callbacks
67+
- **`build.rs`** — Calls `wdk_build::configure_wdk_binary_build()`
68+
- **`*.inx`** — INF template file for driver installation
69+
70+
### Key Crate Dependencies (from windows-drivers-rs)
71+
72+
| Crate | Purpose |
73+
|-------|---------|
74+
| `wdk` | Safe Rust wrappers and macros (`println!`, `paged_code!`, `nt_success`, `wdf::Timer`, `wdf::SpinLock`) |
75+
| `wdk-sys` | Raw FFI bindings to WDK. Use via `call_unsafe_wdf_function_binding!` macro |
76+
| `wdk-alloc` | `WdkAllocator` — kernel-compatible global allocator |
77+
| `wdk-panic` | Kernel-compatible panic handler |
78+
| `wdk-build` | Build-time configuration for driver compilation and `cargo-make` integration |
79+
80+
## Key Conventions
81+
82+
### Driver Entry Points
83+
84+
- `DriverEntry` must use `#[export_name = "DriverEntry"]` and `extern "system"` calling convention
85+
- Place init code in `#[link_section = "INIT"]`; place pageable code in `#[link_section = "PAGE"]` and invoke `paged_code!()` at function entry
86+
- WDF callbacks use `extern "C"` calling convention
87+
88+
### WDF Function Calls
89+
90+
All WDF framework function calls go through the `call_unsafe_wdf_function_binding!` macro from `wdk-sys`. These are always `unsafe` blocks:
91+
92+
```rust
93+
unsafe {
94+
call_unsafe_wdf_function_binding!(
95+
WdfDriverCreate,
96+
driver as PDRIVER_OBJECT,
97+
registry_path,
98+
WDF_NO_OBJECT_ATTRIBUTES,
99+
&raw mut driver_config,
100+
driver_handle_output,
101+
)
102+
}
103+
```
104+
105+
### WDF Structure Sizes
106+
107+
WDF structs require their `Size` field to be set. Use const-evaluated `WDF_*_SIZE` constants with compile-time truncation assertions:
108+
109+
```rust
110+
#[allow(
111+
clippy::cast_possible_truncation,
112+
reason = "size_of::<WDF_DRIVER_CONFIG>() is known to fit in ULONG due to below const assert"
113+
)]
114+
const WDF_DRIVER_CONFIG_SIZE: ULONG = {
115+
const S: usize = core::mem::size_of::<WDF_DRIVER_CONFIG>();
116+
const { assert!(S <= ULONG::MAX as usize) };
117+
S as ULONG
118+
};
119+
```
120+
121+
### WDF Object Contexts
122+
123+
Context types are registered using macros from `wdf_object_context.rs`:
124+
125+
- `wdf_declare_context_type!(MyContext)` — generates `wdf_object_get_my_context` accessor
126+
- `wdf_declare_context_type_with_name!(MyContext, custom_getter_name)` — generates a named accessor
127+
- `wdf_get_context_type_info!(MyContext)` — retrieves the type info pointer for `WDF_OBJECT_ATTRIBUTES.ContextTypeInfo`
128+
129+
### Kernel Allocator and Panic Handler
130+
131+
Every driver crate must include both, gated behind `#[cfg(not(test))]`:
132+
133+
```rust
134+
#[cfg(not(test))]
135+
extern crate wdk_panic;
136+
137+
#[cfg(not(test))]
138+
use wdk_alloc::WdkAllocator;
139+
140+
#[cfg(not(test))]
141+
#[global_allocator]
142+
static GLOBAL_ALLOCATOR: WdkAllocator = WdkAllocator;
143+
```
144+
145+
### Clippy Configuration
146+
147+
All driver crates enable strict clippy lints:
148+
149+
```rust
150+
#![deny(clippy::all)]
151+
#![warn(clippy::pedantic)]
152+
#![warn(clippy::nursery)]
153+
#![warn(clippy::cargo)]
154+
#![allow(clippy::missing_safety_doc)]
155+
```
156+
157+
### Nightly Feature Gating
158+
159+
Crates expose an optional `nightly` feature for unstable Rust capabilities. The feature cascades through `wdk` and `wdk-sys`:
160+
161+
```toml
162+
[features]
163+
nightly = ["wdk/nightly", "wdk-sys/nightly"]
164+
```
165+
166+
### Formatting
167+
168+
- Rust: Uses nightly `rustfmt` with unstable options (see `rustfmt.toml`): `imports_granularity = "Crate"`, `group_imports = "StdExternalCrate"`, `hex_literal_case = "Upper"`, among others
169+
- TOML: Uses `taplo` with CRLF line endings (`taplo.toml`)
170+
171+
### Rust Flags
172+
173+
`-C target-feature=+crt-static` is set in `.cargo/config.toml` and must also be in CI `RUSTFLAGS`. CI also sets `-D warnings` to deny all warnings.
174+
175+
### Copyright Headers
176+
177+
Every `.rs` file starts with:
178+
179+
```rust
180+
// Copyright (c) Microsoft Corporation.
181+
// License: MIT OR Apache-2.0
182+
```

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@AGENTS.md

0 commit comments

Comments
 (0)