Skip to content

Commit 2ec9f2d

Browse files
committed
docs: add AGENTS.md and CLAUDE.md for Copilot code review
1 parent 0e5d77c commit 2ec9f2d

2 files changed

Lines changed: 190 additions & 0 deletions

File tree

AGENTS.md

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

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)