mirror of
https://github.com/0xflux/wdk-mutex
synced 2026-06-08 10:14:26 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
[build]
|
||||
rustflags = [
|
||||
"-C",
|
||||
"target-feature=+crt-static",
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
/target
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"alertable",
|
||||
"cdylib",
|
||||
"Irql",
|
||||
"kmtx",
|
||||
"kmutex",
|
||||
"KMUTEXGUARD",
|
||||
"KWAIT",
|
||||
"ntddk",
|
||||
"NTSTATUS",
|
||||
"PCUNICODE",
|
||||
"PDEVICE",
|
||||
"PKMUTEX",
|
||||
"println",
|
||||
"PRKMUTEX",
|
||||
"RAII"
|
||||
]
|
||||
}
|
||||
Generated
+958
@@ -0,0 +1,958 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap-cargo"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b2ea69cefa96b848b73ad516ad1d59a195cdf9263087d977f648a818c8b43e"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.9",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
dependencies = [
|
||||
"regex-syntax 0.6.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.216"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.216"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.134"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "wdk"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c80cc00b5c587d3a43f489350a797a258eefca5ab0bb5d0d5b56d4ce09ab42f2"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"wdk-build",
|
||||
"wdk-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wdk-alloc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd1c139c6b9c05475bc7e8b356d4fbc252954d685691d70cfaec8b42c41b72d"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"wdk-build",
|
||||
"wdk-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wdk-build"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b276786d848e5ab00e021968e89cfdc591938b69741a3733e7e3d91b23f547f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bindgen",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"cfg-if",
|
||||
"clap",
|
||||
"clap-cargo",
|
||||
"lazy_static",
|
||||
"paste",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wdk-macros"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f069b2e89e5a3327e84bc2f672f7f35d94059da590666d7d605f33f2ae2fa3"
|
||||
dependencies = [
|
||||
"itertools 0.13.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wdk-mutex"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"wdk",
|
||||
"wdk-alloc",
|
||||
"wdk-build",
|
||||
"wdk-panic",
|
||||
"wdk-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wdk-panic"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba15dc2294f5c87df4b30218d93fb459ac8484a45683d4ad06fc0243e58736c"
|
||||
|
||||
[[package]]
|
||||
name = "wdk-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f974829a3b0b362723d55f0d05d8f1715bb7a88297558c4127f69d85bbff7e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bindgen",
|
||||
"cargo_metadata",
|
||||
"cc",
|
||||
"lazy_static",
|
||||
"rustversion",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"wdk-build",
|
||||
"wdk-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
|
||||
dependencies = [
|
||||
"windows-result",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
[package]
|
||||
name = "wdk-mutex"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
authors = ["Flux Sec <fluxsec@proton.me>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/0xflux/wdk_mutex"
|
||||
documentation = "https://docs.rs/wdk-mutex"
|
||||
readme = "Readme.md"
|
||||
keywords = ["windows", "driver", "mutex", "kernel", "wdk"]
|
||||
|
||||
[package.metadata.wdk.driver-model]
|
||||
driver-type = "WDM"
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
||||
[features]
|
||||
default = []
|
||||
nightly = ["wdk/nightly", "wdk-sys/nightly"]
|
||||
debug = []
|
||||
|
||||
[dependencies]
|
||||
wdk = "^0.3.0"
|
||||
wdk-alloc = "^0.3.0"
|
||||
wdk-sys = "^0.3.0"
|
||||
wdk-panic = "^0.3.0"
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
lto = true
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
lto = true
|
||||
|
||||
[build-dependencies]
|
||||
wdk-build = "^0.3.0"
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 0xflux
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,139 @@
|
||||
# wdk-mutex
|
||||
|
||||
An idiomatic Rust mutex type for Windows kernel driver development.
|
||||
|
||||
To use this crate, simply:
|
||||
|
||||
```
|
||||
cargo add wdk-mutex
|
||||
```
|
||||
|
||||
**See the sections below for examples**. This crate assumes you already have a Rust Windows Driver Kit project
|
||||
using the Microsoft [windows-drivers-rs](https://github.com/microsoft/windows-drivers-rs) crate. You will
|
||||
not be able to use this crate unless you are in a wdk development environment, setup steps outlined on
|
||||
their repository.
|
||||
|
||||
This crate checks IRQL when acquiring and releasing the mutex, returning an error if IRQL is too high. See the crate documentation for details.
|
||||
|
||||
`wdk-mutex` is a work in progress to implement additional mutex types and functionality as required. Contributions, issues, and discussions are welcome. This crate is **NOT** affiliated with the WDK crates provided by Microsoft, but is designed to work with them and their ecosystem for Windows Rust
|
||||
Kernel Driver development.
|
||||
|
||||
As this crate integrates into the wdk ecosystem, Microsoft stipulate: This project is still in early stages of development and is not yet recommended for production use.
|
||||
|
||||
Tests have been conducted on public modules, but are not included in the crate due to the complexity of
|
||||
deploying kernel level tests. A new repo will be created specifically for testing this crate which
|
||||
can be built as a driver.
|
||||
|
||||
This is licenced with an MIT Licence, conditions can be found in LICENCE in the crate GitHub repository.
|
||||
|
||||
## Stability
|
||||
|
||||
This crate has been built and tested with **nightly-2024-12-21**. Stability outside of nightly versions
|
||||
stipulated here are considered undefined.
|
||||
|
||||
The crate has been tested on a Windows 11 image as a driver. No testing of other Windows versions have
|
||||
been conducted.
|
||||
|
||||
## Features:
|
||||
|
||||
**KMUTEX:**
|
||||
|
||||
The `wdk-mutex` crate supports acquiring a KMUTEX. The type `Kmutex<T>` provides mutually exclusive access
|
||||
to the inner type T allocated through this crate in the non-paged pool. All data required to initialise the
|
||||
KMutex is allocated in the non-paged pool and as such is safe to pass stack data into the type as it will not go out of scope.
|
||||
|
||||
Access to the `T` within the `KMutex` can be done through calling `lock`, similar to the Rust std Mutex.
|
||||
|
||||
As the `KMutex` is designed to be used in the Windows Kernel, with the Windows `wdk` crate, the lifetimes of
|
||||
the `KMutex` must be considered by the caller. See **examples** below for usage.
|
||||
|
||||
# Examples
|
||||
|
||||
## Locally scoped mutex:
|
||||
|
||||
```rust
|
||||
{
|
||||
let mtx = KMutex::new(0u32).unwrap();
|
||||
let lock = mtx.lock().unwrap();
|
||||
|
||||
// If T implements display, you do not need to dereference the lock to print.
|
||||
println!("The value is: {}", lock);
|
||||
} // Mutex will become unlocked as it is managed via RAII
|
||||
```
|
||||
|
||||
## Global scope via static pointer:
|
||||
|
||||
A future release is planned to make this process more ergonomic.
|
||||
|
||||
```rust
|
||||
pub static HEAP_MTX_PTR: AtomicPtr<KMutex<u32>> = AtomicPtr::new(null_mut());
|
||||
|
||||
fn my_fn() {
|
||||
let heap_mtx = Box::new(KMutex::new(0u32).unwrap());
|
||||
let heap_mtx_ptr = Box::into_raw(heap_mtx);
|
||||
HEAP_MTX_PTR.store(heap_mtx_ptr, Ordering::SeqCst);
|
||||
|
||||
// spawn some system threads
|
||||
r _ in 0..3 {
|
||||
let mut thread_handle: HANDLE = null_mut();
|
||||
let status = unsafe {
|
||||
PsCreateSystemThread(
|
||||
&mut thread_handle,
|
||||
0,
|
||||
null_mut::<OBJECT_ATTRIBUTES>(),
|
||||
null_mut(),
|
||||
null_mut::<CLIENT_ID>(),
|
||||
Some(callback_fn),
|
||||
null_mut(),
|
||||
)
|
||||
};
|
||||
println!("[i] Thread status: {status}");
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn callback_fn(_: *mut c_void) {
|
||||
for _ in 0..50 {
|
||||
let p = HEAP_MTX_PTR.load(Ordering::SeqCst);
|
||||
if !p.is_null() {
|
||||
let p = unsafe { &*p };
|
||||
let mut lock = p.lock().unwrap();
|
||||
println!("Got the lock before change! {}", *lock);
|
||||
*lock += 1;
|
||||
println!("After the change: {}", *lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMPORTANT ensure the KMutex in the static is properly dropped to clean memory
|
||||
extern "C" fn driver_exit(driver: *mut DRIVER_OBJECT) {
|
||||
let ptr: *mut KMutex<u32> = HEAP_MTX_PTR.load(Ordering::SeqCst);
|
||||
if !ptr.is_null() {
|
||||
unsafe {
|
||||
// RAII will kick in here to deallocate our memory
|
||||
let _ = Box::from_raw(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Planned updates
|
||||
|
||||
## Global interface:
|
||||
|
||||
A future addition is planned which will make the API more flexible for dynamically managing globally
|
||||
available mutexes to somewhat reduce the overhead required to use this crate.
|
||||
|
||||
## Critical Sections:
|
||||
|
||||
An idiomatic implementation for entering and leaving a mutex critical section where no underlying
|
||||
T is protected.
|
||||
|
||||
## FAST_MUTEX
|
||||
|
||||
An idiomatic implementation for FAST_MUTEX.
|
||||
|
||||
The next planned release will add Critical Section behaviour, where you do not want to wrap a generic T in a mutex (similar to std::mutex), but you want a section to be a critical section nonetheless.
|
||||
|
||||
Please note that each planned feature will be introduced gradually, and might undergo changes based on community feedback.
|
||||
|
||||
I welcome any contributions or suggestions to improve functionality, documentation, and compatibility.
|
||||
@@ -0,0 +1,4 @@
|
||||
fn main() -> Result<(), wdk_build::ConfigError> {
|
||||
println!("Starting build process...");
|
||||
wdk_build::configure_wdk_binary_build()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
extend = "target/rust-driver-makefile.toml"
|
||||
|
||||
[config]
|
||||
load_script = '''
|
||||
#!@rust
|
||||
//! ```cargo
|
||||
//! [dependencies]
|
||||
//! wdk-build = "0.3.0"
|
||||
//! ```
|
||||
#![allow(unused_doc_comments)]
|
||||
|
||||
wdk_build::cargo_make::load_rust_driver_makefile()?
|
||||
'''
|
||||
@@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-12-21"
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
//! Deprecated but leaving for reference as some of this logic may be useful in a
|
||||
//! future planned addition.
|
||||
|
||||
use core::{ops::Deref, ptr::{drop_in_place, write}, sync::atomic::AtomicUsize};
|
||||
|
||||
use wdk::println;
|
||||
use wdk_sys::{ntddk::{ExAllocatePool2, ExFreePool}, POOL_FLAG_NON_PAGED};
|
||||
|
||||
use crate::errors::DriverMutexError;
|
||||
|
||||
/// An atomically reference counted Arc in the non-paged pool
|
||||
#[derive(Debug)]
|
||||
pub struct ArcNP<T> {
|
||||
/// A pointer to the actual allocation, which holds the reference count and T
|
||||
ptr: *mut ArcInner<T>,
|
||||
}
|
||||
|
||||
#[repr(C, align(8))]
|
||||
#[derive(Debug)]
|
||||
struct ArcInner<T> {
|
||||
/// The atomic reference count
|
||||
refcount: AtomicUsize,
|
||||
data: T,
|
||||
}
|
||||
|
||||
impl<T> ArcNP<T> {
|
||||
/// Allocates a new atomically reference counted smart pointer in the
|
||||
/// NonPagedPool with a given tag.
|
||||
pub fn new(data: T, tag: u32) -> Result<Self, DriverMutexError> {
|
||||
|
||||
//
|
||||
// Calculate the size required for the non-paged pool allocation and
|
||||
// then allocate.
|
||||
//
|
||||
|
||||
let inner_size = size_of::<ArcInner<T>>();
|
||||
|
||||
let mem = unsafe {
|
||||
ExAllocatePool2(POOL_FLAG_NON_PAGED, inner_size as u64, tag)
|
||||
};
|
||||
|
||||
if mem.is_null() {
|
||||
return Err(DriverMutexError::PagedPoolAllocFailed);
|
||||
}
|
||||
|
||||
// Cast the memory allocation to our type
|
||||
let ptr = mem as *mut ArcInner<T>;
|
||||
|
||||
//
|
||||
// write the ArcInner<T> into the newly allocated memory
|
||||
//
|
||||
|
||||
// SAFETY: A null pointer check above ensures this operation is writing to properly
|
||||
// initialised memory.
|
||||
unsafe {
|
||||
write(
|
||||
ptr,
|
||||
ArcInner {
|
||||
refcount: AtomicUsize::new(1),
|
||||
data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Self { ptr })
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for ArcNP<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY: This is safe as the type keeps track of the validity of the reference
|
||||
// via
|
||||
unsafe {
|
||||
&(*self.ptr).data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for ArcNP<T> {
|
||||
fn clone(&self) -> Self {
|
||||
|
||||
// increment the reference count
|
||||
// SAFETY this operation is safe as Self's memory is tracked by the implementation of our smart pointer
|
||||
unsafe {
|
||||
let _ = &(*self.ptr).refcount.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
|
||||
};
|
||||
|
||||
// Return the underlying ArcNP
|
||||
Self { ptr: self.ptr }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for ArcNP<T> {
|
||||
fn drop(&mut self) {
|
||||
|
||||
// dec the ref count
|
||||
let count_prior_to_dec = unsafe {
|
||||
&(*self.ptr).refcount
|
||||
}.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
println!("[wdk-mutex] Dec val: {}...", count_prior_to_dec);
|
||||
|
||||
// if the new count == 0, then we need to clean up the memory, else, there are still
|
||||
// valid references living.
|
||||
if count_prior_to_dec == 1 {
|
||||
// SAFETY: At this point we are operating on the final Arc lifetime, so the data is still
|
||||
// valid (as the count was 1, now 0 as it leaves its scope or is otherwise dropped).
|
||||
println!("[wdk-mutex] Dropping underlying memory...");
|
||||
unsafe {
|
||||
// drop the underlying data
|
||||
drop_in_place(&mut (*self.ptr).data);
|
||||
|
||||
ExFreePool(self.ptr as *mut _);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
//! Error types used by wdk-mutex
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum DriverMutexError {
|
||||
IrqlTooHigh,
|
||||
IrqlNotAPCLevel,
|
||||
PagedPoolAllocFailed,
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//! This module is out of commission pending a future release, and is a work in progress.
|
||||
//!
|
||||
//! Public interfaces disabled during development so it cannot be used by somebody using this crate.
|
||||
//!
|
||||
//! Use the `KMutex` module of this crate in the meantime.
|
||||
|
||||
#[cfg(not(test))]
|
||||
extern crate wdk_panic;
|
||||
|
||||
use core::{cell::UnsafeCell, ops::{Deref, DerefMut}};
|
||||
use wdk::println;
|
||||
use wdk_sys::{ntddk::{ExAcquireFastMutex, ExReleaseFastMutex, KeGetCurrentIrql, KeInitializeEvent}, DISPATCH_LEVEL, FALSE, FAST_MUTEX, FM_LOCK_BIT, _EVENT_TYPE::SynchronizationEvent, APC_LEVEL};
|
||||
|
||||
use crate::errors::DriverMutexError;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn ExInitializeFastMutex(kmutex: *mut FAST_MUTEX) {
|
||||
// check IRQL
|
||||
let irql = unsafe { KeGetCurrentIrql() };
|
||||
assert!(irql as u32 <= DISPATCH_LEVEL);
|
||||
|
||||
core::ptr::write_volatile(&mut (*kmutex).Count, FM_LOCK_BIT as i32);
|
||||
|
||||
(*kmutex).Owner = core::ptr::null_mut();
|
||||
(*kmutex).Contention = 0;
|
||||
KeInitializeEvent(&mut (*kmutex).Event, SynchronizationEvent, FALSE as _)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FastMutex<T> {
|
||||
mutex: UnsafeCell<FAST_MUTEX>,
|
||||
inner: UnsafeCell<T>,
|
||||
}
|
||||
|
||||
unsafe impl<T: Sync> Sync for FastMutex<T>{}
|
||||
|
||||
impl<T> FastMutex<T> {
|
||||
|
||||
pub fn new(data: T) -> Result<Self, DriverMutexError> {
|
||||
if unsafe { KeGetCurrentIrql() } > DISPATCH_LEVEL as u8 {
|
||||
return Err(DriverMutexError::IrqlTooHigh)
|
||||
}
|
||||
|
||||
let mut mutex = FAST_MUTEX::default();
|
||||
unsafe { ExInitializeFastMutex(&mut mutex) };
|
||||
let c = UnsafeCell::new(mutex);
|
||||
|
||||
Ok(FastMutex {
|
||||
mutex: c,
|
||||
inner: UnsafeCell::new(data),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
pub fn lock(&self) -> Result<FastMutexGuard<'_, T>, DriverMutexError> {
|
||||
if unsafe { KeGetCurrentIrql() } > APC_LEVEL as u8 {
|
||||
return Err(DriverMutexError::IrqlTooHigh);
|
||||
}
|
||||
|
||||
unsafe { ExAcquireFastMutex(self.mutex.get()) };
|
||||
|
||||
Ok(FastMutexGuard {
|
||||
fast_mutex: self
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FastMutexGuard<'a, T> {
|
||||
fast_mutex: &'a FastMutex<T>,
|
||||
}
|
||||
|
||||
|
||||
impl<'a, T> Deref for FastMutexGuard<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { &*self.fast_mutex.inner.get() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> DerefMut for FastMutexGuard<'a, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { &mut *self.fast_mutex.inner.get() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for FastMutexGuard<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { ExReleaseFastMutex(self.fast_mutex.mutex.get()) };
|
||||
|
||||
}
|
||||
}
|
||||
+332
@@ -0,0 +1,332 @@
|
||||
//! A Rust idiomatic Windows Kernel Driver KMUTEX type which protects the inner type T
|
||||
|
||||
#[cfg(not(test))]
|
||||
extern crate wdk_panic;
|
||||
|
||||
use core::{ffi::c_void, fmt::Display, ops::{Deref, DerefMut}, ptr::{self, drop_in_place, null_mut}};
|
||||
use wdk::println;
|
||||
use wdk_sys::{ntddk::{ExAllocatePool2, ExFreePool, KeGetCurrentIrql, KeInitializeMutex, KeReleaseMutex, KeWaitForSingleObject}, APC_LEVEL, DISPATCH_LEVEL, FALSE, KMUTEX, POOL_FLAG_NON_PAGED, _KWAIT_REASON::Executive, _MODE::KernelMode};
|
||||
|
||||
use crate::errors::DriverMutexError;
|
||||
/// A thread safe mutex implemented through acquiring a KMUTEX in the Windows kernel.
|
||||
///
|
||||
/// The type `Kmutex<T>` provides mutually exclusive access to the inner type T allocated through
|
||||
/// this crate in the non-paged pool. All data required to initialise the KMutex is allocated in the
|
||||
/// non-paged pool and as such is safe to pass stack data into the type as it will not go out of scope.
|
||||
///
|
||||
/// `KMutex` holds an inner value which is a pointer to a `KMutexInner` type which is the actual type
|
||||
/// allocated in the non-paged pool, and this holds information relating to the mutex.
|
||||
///
|
||||
/// Access to the `T` within the `KMutex` can be done through calling [`Self::lock`].
|
||||
///
|
||||
/// To receive debug messages when the IRQL is too high for an operation, enable the feature flag `debug`.
|
||||
///
|
||||
/// # Lifetimes
|
||||
///
|
||||
/// As the `KMutex` is designed to be used in the Windows Kernel, with the Windows `wdk` crate, the lifetimes of
|
||||
/// the `KMutex` must be considered by the caller. See examples below for usage.
|
||||
///
|
||||
/// The KMutex can exist in a locally scoped function with little additional configuration. To use the mutex across
|
||||
/// thread boundaries, or to use it in callback functions, the recommended course of action is to utilise either a
|
||||
/// globally accessible `static AtomicPtr<KMutex<T>>`; or to utilise a
|
||||
/// [Device Extension](https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/device-extensions)
|
||||
/// provided in the wdk.
|
||||
///
|
||||
/// <section class="warning">
|
||||
/// If you use a `static AtomicPtr<KMutex<T>>` you MUST ensure that the memory is cleaned up when you exit the driver
|
||||
/// otherwise you cause a memory leak.
|
||||
///
|
||||
/// A future addition is planned which will make the API more flexible for dynamically managing globally available
|
||||
/// mutexes to somewhat reduce the overhead required to use this crate.
|
||||
/// </section>
|
||||
///
|
||||
/// # Deallocation
|
||||
///
|
||||
/// KMutex handles the deallocation of resources at the point the KMutex is dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ## Locally scoped mutex:
|
||||
///
|
||||
/// ```
|
||||
/// {
|
||||
/// let mtx = KMutex::new(0u32).unwrap();
|
||||
/// let lock = mtx.lock().unwrap();
|
||||
///
|
||||
/// // If T implements display, you do not need to dereference the lock to print.
|
||||
/// println!("The value is: {}", lock);
|
||||
/// } // Mutex will become unlocked as it is managed via RAII
|
||||
/// ```
|
||||
///
|
||||
/// ## Global scope via static pointer:
|
||||
///
|
||||
/// A future release is planned to make this process more ergonomic.
|
||||
///
|
||||
/// ```
|
||||
/// pub static HEAP_MTX_PTR: AtomicPtr<KMutex<u32>> = AtomicPtr::new(null_mut());
|
||||
///
|
||||
/// fn my_fn() {
|
||||
/// let heap_mtx = Box::new(KMutex::new(0u32).unwrap());
|
||||
/// let heap_mtx_ptr = Box::into_raw(heap_mtx);
|
||||
/// HEAP_MTX_PTR.store(heap_mtx_ptr, Ordering::SeqCst);
|
||||
///
|
||||
/// // spawn some system threads
|
||||
/// r _ in 0..3 {
|
||||
/// let mut thread_handle: HANDLE = null_mut();
|
||||
/// let status = unsafe {
|
||||
/// PsCreateSystemThread(
|
||||
/// &mut thread_handle,
|
||||
/// 0,
|
||||
/// null_mut::<OBJECT_ATTRIBUTES>(),
|
||||
/// null_mut(),
|
||||
/// null_mut::<CLIENT_ID>(),
|
||||
/// Some(callback_fn),
|
||||
/// null_mut(),
|
||||
/// )
|
||||
/// };
|
||||
/// println!("[i] Thread status: {status}");
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// unsafe extern "C" fn callback_fn(_: *mut c_void) {
|
||||
/// for _ in 0..50 {
|
||||
/// let p = HEAP_MTX_PTR.load(Ordering::SeqCst);
|
||||
/// if !p.is_null() {
|
||||
/// let p = unsafe { &*p };
|
||||
/// let mut lock = p.lock().unwrap();
|
||||
/// println!("Got the lock before change! {}", *lock);
|
||||
/// *lock += 1;
|
||||
/// println!("After the change: {}", *lock);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // IMPORTANT ensure the KMutex in the static is properly dropped to clean memory
|
||||
/// extern "C" fn driver_exit(driver: *mut DRIVER_OBJECT) {
|
||||
/// let ptr: *mut KMutex<u32> = HEAP_MTX_PTR.load(Ordering::SeqCst);
|
||||
/// if !ptr.is_null() {
|
||||
/// unsafe {
|
||||
/// // RAII will kick in here to deallocate our memory
|
||||
/// let _ = Box::from_raw(ptr);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub struct KMutex<T> {
|
||||
inner: *mut KMutexInner<T>
|
||||
}
|
||||
|
||||
/// The underlying data which is non-page pool allocated which is pointed to by the `KMutex`.
|
||||
struct KMutexInner<T> {
|
||||
/// A KMUTEX structure allocated into KMutexInner
|
||||
mutex: KMUTEX,
|
||||
/// The data for which the mutex is protecting
|
||||
data: T,
|
||||
}
|
||||
|
||||
|
||||
unsafe impl<T: Sync> Sync for KMutex<T>{}
|
||||
|
||||
impl<T> KMutex<T> {
|
||||
|
||||
/// Creates a new KMUTEX Windows Kernel Driver Mutex in a signaled (free) state.
|
||||
///
|
||||
/// # IRQL
|
||||
///
|
||||
/// This can be called at any IRQL.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use wdk_mutex::Mutex;
|
||||
///
|
||||
/// let my_mutex = wdk_mutex::KMutex::new(0u32);
|
||||
/// ```
|
||||
pub fn new(data: T) -> Result<Self, DriverMutexError> {
|
||||
//
|
||||
// Non-Paged heap alloc for all struct data required for KMutexInner
|
||||
//
|
||||
let total_sz_required = size_of::<KMutexInner<T>>();
|
||||
let inner_heap_ptr: *mut c_void = unsafe {
|
||||
ExAllocatePool2(POOL_FLAG_NON_PAGED, total_sz_required as u64, u32::from_be_bytes(*b"kmtx"))
|
||||
};
|
||||
if inner_heap_ptr.is_null() {
|
||||
return Err(DriverMutexError::PagedPoolAllocFailed);
|
||||
}
|
||||
|
||||
// Cast the memory allocation to a pointer to the inner
|
||||
let kmutex_inner_ptr = inner_heap_ptr as *mut KMutexInner<T>;
|
||||
|
||||
// SAFETY: This raw write is safe as the pointer validity is checked above.
|
||||
unsafe {
|
||||
ptr::write(
|
||||
kmutex_inner_ptr,
|
||||
KMutexInner {
|
||||
mutex: KMUTEX::default(),
|
||||
data
|
||||
}
|
||||
);
|
||||
|
||||
// Initialise the KMUTEX object via the kernel
|
||||
KeInitializeMutex(&(*kmutex_inner_ptr).mutex as *const _ as *mut _, 0);
|
||||
}
|
||||
|
||||
Ok(Self { inner: kmutex_inner_ptr })
|
||||
}
|
||||
|
||||
|
||||
/// Acquires a mutex in a non-alertable manner.
|
||||
///
|
||||
/// A future release is planned to include an alternate implementation
|
||||
/// which will lock the mutex and become alertable if it has to wait for the mutex to become free.
|
||||
/// This function will block the local thread until it is available to acquire the mutex.
|
||||
///
|
||||
/// Once the thread has acquired the mutex, it will return a `KMutexGuard` which is a RAII scoped
|
||||
/// guard allowing exclusive access to the inner T.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// todo
|
||||
///
|
||||
/// # IRQL
|
||||
///
|
||||
/// This function must be called at IRQL `<= APC_LEVEL`, if the IRQL is higher than this,
|
||||
/// the function will return an error.
|
||||
///
|
||||
/// It is the callers responsibility to ensure the IRQL is sufficient to call this function and it
|
||||
/// will not alter the IRQL for the caller, as this may introduce undefined behaviour elsewhere in the
|
||||
/// driver / kernel.
|
||||
pub fn lock(&self) -> Result<KMutexGuard<'_, T>, DriverMutexError> {
|
||||
|
||||
// Check the IRQL is <= APC_LEVEL as per remarks at
|
||||
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-kewaitforsingleobject
|
||||
let irql = unsafe {KeGetCurrentIrql()};
|
||||
if irql > APC_LEVEL as u8 {
|
||||
if cfg!(feature = "debug") {
|
||||
println!("[wdk-mutex] [-] IRQL is too high to call .lock(). Current IRQL: {}", irql);
|
||||
return Err(DriverMutexError::IrqlTooHigh);
|
||||
}
|
||||
}
|
||||
|
||||
// Discard the return value; the status code does not represent an error or contain information
|
||||
// relevant to the context of no timeout.
|
||||
let _ = unsafe {
|
||||
// SAFETY: The IRQL is sufficient for the operation as checked above, and we know our pointer
|
||||
// is valid as RAII manages the lifetime of the heap allocation, ensuring it will only be deallocated
|
||||
// once Self gets dropped.
|
||||
KeWaitForSingleObject(
|
||||
&mut (*self.inner).mutex as *mut _ as *mut _,
|
||||
Executive,
|
||||
KernelMode as i8,
|
||||
FALSE as u8,
|
||||
null_mut(),
|
||||
)
|
||||
};
|
||||
|
||||
Ok(KMutexGuard {
|
||||
kmutex: self
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for KMutex<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Drop the underlying data and run destructors for the data, this would be relevant in the
|
||||
// case where Self contains other heap allocated types which have their own deallocation
|
||||
// methods.
|
||||
drop_in_place(&mut (*self.inner).data);
|
||||
|
||||
// Free the memory we allocated
|
||||
ExFreePool(self.inner as *mut _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A RAII scoped guard for the inner data protected by the mutex. Once this guard is given out, the protected data
|
||||
/// may be safely mutated by the caller as we guarantee exclusive access via Windows Kernel Mutex primitives.
|
||||
///
|
||||
/// When this structure is dropped (falls out of scope), the lock will be unlocked.
|
||||
///
|
||||
/// # IRQL
|
||||
///
|
||||
/// Access to the data within this guard must be done at <= APC_LEVEL if a non-alertable lock was acquired, or <=
|
||||
/// DISPATCH_LEVEL if an alertable lock was acquired. It is the callers responsible to manage APC levels whilst
|
||||
/// using the KMutex.
|
||||
///
|
||||
/// If you wish to manually drop the lock with a safety check, call the function [`drop_safe`].
|
||||
///
|
||||
/// # Kernel panic
|
||||
///
|
||||
/// Raising the IRQL above safe limits whilst using the mutex will cause a Kernel Panic if not appropriately handled.
|
||||
/// When RAII drops this type, the mutex is released, if the mutex goes out of scope whilst you hold an IRQL that
|
||||
/// is too high, you will receive a kernel panic.
|
||||
///
|
||||
pub struct KMutexGuard<'a, T> {
|
||||
kmutex: &'a KMutex<T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Display for KMutexGuard<'a, T>
|
||||
where T: Display
|
||||
{
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
// SAFETY: Dereferencing the inner data is safe as RAII controls the memory allocations.
|
||||
write!(f, "{}", unsafe { &(*self.kmutex.inner).data })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a, T> Deref for KMutexGuard<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY: Dereferencing the inner data is safe as RAII controls the memory allocations.
|
||||
unsafe { &(*self.kmutex.inner).data }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> DerefMut for KMutexGuard<'a, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
// SAFETY: Dereferencing the inner data is safe as RAII controls the memory allocations.
|
||||
// Mutable access is safe due to Self only being given out whilst a mutex is held from the
|
||||
// kernel.
|
||||
unsafe { &mut (*self.kmutex.inner).data }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for KMutexGuard<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
// NOT SAFE AT A IRQL TOO HIGH
|
||||
unsafe { KeReleaseMutex(&mut (*self.kmutex.inner).mutex, FALSE as u8) };
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> KMutexGuard<'a, T> {
|
||||
/// Safely drop the KMutexGuard, an alternative to RAII.
|
||||
///
|
||||
/// This function checks the IRQL before attempting to drop the guard.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the IRQL > DISPATCH_LEVEL, no unlock will occur and a DriverMutexError will be returned to the
|
||||
/// caller.
|
||||
///
|
||||
/// # IRQL
|
||||
///
|
||||
/// This function is safe to call at any IRQL, but it will not release the mutex if IRQL > DISPATCH_LEVEL
|
||||
fn drop_safe(&mut self) -> Result<(), DriverMutexError> {
|
||||
|
||||
let irql = unsafe {KeGetCurrentIrql()};
|
||||
if irql > DISPATCH_LEVEL as u8 {
|
||||
if cfg!(feature = "debug") {
|
||||
println!("[wdk-mutex] [-] Unable to safely drop the KMUTEX. Calling IRQL is too high: {}", irql);
|
||||
return Err(DriverMutexError::IrqlTooHigh);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe { KeReleaseMutex(&mut (*self.kmutex.inner).mutex, FALSE as u8) };
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
//! An idiomatic Rust mutex type for Windows kernel driver development.
|
||||
//!
|
||||
//! The crate will safely check IRQL before doing operations which would cause a STOP CODE of
|
||||
//! IRQL NOT LESS OR EQUAL (except for RAII dropping of scoped Mutex Guards).
|
||||
//! In those cases, the API will return an error of the internal type `DriverMutexError`.
|
||||
//!
|
||||
//! This crate is a work in progress to implement additional mutex types and functionality as required. Contributions, issues,
|
||||
//! and discussions are welcome.
|
||||
//!
|
||||
//! This crate is **NOT** affiliated with the WDK crates provided by Microsoft, but is designed to work with them for Windows Rust Kernel Driver
|
||||
//! development.
|
||||
//!
|
||||
//! # Additional features:
|
||||
//!
|
||||
//! - `debug`: Enabling this feature will print debug messages to an attached debugger or kernel message viewer when an IRQL error occurs.
|
||||
//!
|
||||
//! # Planned updates
|
||||
//!
|
||||
//! ## Global interface:
|
||||
//!
|
||||
//! A future addition is planned which will make the API more flexible for dynamically managing globally available
|
||||
//! mutexes to somewhat reduce the overhead required to use this crate.
|
||||
//!
|
||||
//! ## Critical Sections:
|
||||
//!
|
||||
//! An idiomatic implementation for entering and leaving a mutex critical section where no underlying T is protected.
|
||||
//!
|
||||
//! ## FAST_MUTEX
|
||||
//!
|
||||
//! An idiomatic implementation for FAST_MUTEX.
|
||||
//!
|
||||
//! # Tests
|
||||
//!
|
||||
//! Tests have been conducted on public modules.
|
||||
//!
|
||||
//! No tests are included in the crate. Tests have been conducted on another project https://github.com/0xflux/Sanctum; but a new repo
|
||||
//! will be created specifically for testing this crate which can be built as a driver.
|
||||
//!
|
||||
//! <section class="warning">
|
||||
//! As this crate integrates into the wdk ecosystem, Microsoft stipulate: This project is still in early stages of development and
|
||||
//! is not yet recommended for production use.
|
||||
//!
|
||||
//! This is licenced with an MIT Licence, conditions can be found in LICENCE in the crate GitHub repository.
|
||||
//! </section>
|
||||
|
||||
#![no_std]
|
||||
|
||||
#[cfg(not(test))]
|
||||
extern crate wdk_panic;
|
||||
|
||||
pub mod kmutex;
|
||||
// mod fast_mutex;
|
||||
|
||||
pub mod errors;
|
||||
Reference in New Issue
Block a user