@@ -12,12 +12,12 @@ use std::{
1212 io:: Write ,
1313 panic,
1414 path:: { Path , PathBuf } ,
15+ sync:: LazyLock ,
1516 thread,
1617} ;
1718
1819use anyhow:: Context ;
1920use bindgen:: CodegenConfig ;
20- use lazy_static:: lazy_static;
2121use tracing:: { info, info_span, trace, Span } ;
2222use tracing_subscriber:: {
2323 filter:: { LevelFilter , ParseError } ,
@@ -34,61 +34,33 @@ use wdk_build::{
3434 UmdfConfig ,
3535} ;
3636
37- const NUM_WDF_FUNCTIONS_PLACEHOLDER : & str =
38- "<PLACEHOLDER FOR IDENTIFIER FOR VARIABLE CORRESPONDING TO NUMBER OF WDF FUNCTIONS>" ;
39- const WDF_FUNCTION_COUNT_DECLARATION_PLACEHOLDER : & str =
40- "<PLACEHOLDER FOR DECLARATION OF wdf_function_count VARIABLE>" ;
4137const OUT_DIR_PLACEHOLDER : & str =
4238 "<PLACEHOLDER FOR LITERAL VALUE CONTAINING OUT_DIR OF wdk-sys CRATE>" ;
4339const WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER : & str =
4440 "<PLACEHOLDER FOR LITERAL VALUE CONTAINING WDFFUNCTIONS SYMBOL NAME>" ;
45-
46- /// Rust code snippet that declares and initializes `wdf_function_count` based
47- /// off the bindgen-generated `WdfFunctionCount` symbol
48- ///
49- /// This is only used in configurations where WDF generates a
50- /// `WdfFunctionCount`.
51- const WDF_FUNCTION_COUNT_DECLARATION_EXTERNAL_SYMBOL : & str = "
52- // SAFETY: `crate::WdfFunctionCount` is generated as a mutable static, but is not supposed \
53- to be ever mutated by WDF.
54- let wdf_function_count = unsafe { crate::WdfFunctionCount } as usize;" ;
55- /// Rust code snippet that declares and initializes `wdf_function_count` based
56- /// off the bindgen-generated `WdfFunctionTableNumEntries` constant
57- ///
58- /// This is only used in older WDF versions that didn't generate a
59- /// `WdfFunctionCount` symbol
60- const WDF_FUNCTION_COUNT_DECLARATION_TABLE_INDEX : & str = "
61- let wdf_function_count = crate::_WDFFUNCENUM::WdfFunctionTableNumEntries as usize;" ;
62-
63- // FIXME: replace lazy_static with std::Lazy once available: https://github.com/rust-lang/rust/issues/109736
64- lazy_static ! {
65- static ref WDF_FUNCTION_TABLE_TEMPLATE : String = format!(
66- r#"
67- // FIXME: replace lazy_static with std::Lazy once available: https://github.com/rust-lang/rust/issues/109736
68- #[cfg(any(driver_model__driver_type = "KMDF", driver_model__driver_type = "UMDF"))]
69- lazy_static::lazy_static! {{
70- #[allow(missing_docs)]
71- pub static ref WDF_FUNCTION_TABLE: &'static [crate::WDFFUNC] = {{
72- // SAFETY: `WdfFunctions` is generated as a mutable static, but is not supposed to be ever mutated by WDF.
73- let wdf_function_table = unsafe {{ crate::WdfFunctions }};
74- {WDF_FUNCTION_COUNT_DECLARATION_PLACEHOLDER}
75-
76- // SAFETY: This is safe because:
77- // 1. `WdfFunctions` is valid for reads for `{NUM_WDF_FUNCTIONS_PLACEHOLDER}` * `core::mem::size_of::<WDFFUNC>()`
78- // bytes, and is guaranteed to be aligned and it must be properly aligned.
79- // 2. `WdfFunctions` points to `{NUM_WDF_FUNCTIONS_PLACEHOLDER}` consecutive properly initialized values of
80- // type `WDFFUNC`.
81- // 3. WDF does not mutate the memory referenced by the returned slice for for its entire `'static' lifetime.
82- // 4. The total size, `{NUM_WDF_FUNCTIONS_PLACEHOLDER}` * `core::mem::size_of::<WDFFUNC>()`, of the slice must be no
83- // larger than `isize::MAX`. This is proven by the below `debug_assert!`.
84- unsafe {{
85- debug_assert!(isize::try_from(wdf_function_count * core::mem::size_of::<crate::WDFFUNC>()).is_ok());
86- core::slice::from_raw_parts(wdf_function_table, wdf_function_count)
87- }}
88- }};
89- }}"#
90- ) ;
91- static ref CALL_UNSAFE_WDF_BINDING_TEMPLATE : String = format!(
41+ const WDF_FUNCTION_COUNT_PLACEHOLDER : & str =
42+ "<PLACEHOLDER FOR EXPRESSION FOR NUMBER OF WDF FUNCTIONS IN `wdk_sys::WdfFunctions`" ;
43+
44+ const WDF_FUNCTION_COUNT_DECLARATION_EXTERNAL_SYMBOL : & str =
45+ "// SAFETY: `crate::WdfFunctionCount` is generated as a mutable static, but is not supposed \
46+ to be ever mutated by WDF.
47+ (unsafe { crate::WdfFunctionCount }) as usize" ;
48+
49+ const WDF_FUNCTION_COUNT_DECLARATION_TABLE_INDEX : & str =
50+ "crate::_WDFFUNCENUM::WdfFunctionTableNumEntries as usize" ;
51+
52+ static WDF_FUNCTION_COUNT_FUNCTION_TEMPLATE : LazyLock < String > = LazyLock :: new ( || {
53+ format ! (
54+ r"/// Returns the number of functions available in the WDF function table.
55+ /// Should not be used in public API.
56+ pub fn get_wdf_function_count() -> usize {{
57+ {WDF_FUNCTION_COUNT_PLACEHOLDER}
58+ }}"
59+ )
60+ } ) ;
61+
62+ static CALL_UNSAFE_WDF_BINDING_TEMPLATE : LazyLock < String > = LazyLock :: new ( || {
63+ format ! (
9264 r#"
9365/// A procedural macro that allows WDF functions to be called by name.
9466///
@@ -138,18 +110,20 @@ macro_rules! call_unsafe_wdf_function_binding {{
138110 )
139111 }}
140112}}"#
141- ) ;
142- static ref TEST_STUBS_TEMPLATE : String = format!(
113+ )
114+ } ) ;
115+
116+ static TEST_STUBS_TEMPLATE : LazyLock < String > = LazyLock :: new ( || {
117+ format ! (
143118 r"
144119use crate::WDFFUNC;
145120
146121/// Stubbed version of the symbol that [`WdfFunctions`] links to so that test targets will compile
147122#[no_mangle]
148123pub static mut {WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER}: *const WDFFUNC = core::ptr::null();
149- "
150- ) ;
151- }
152-
124+ " ,
125+ )
126+ } ) ;
153127type GenerateFn = fn ( & Path , & Config ) -> Result < ( ) , ConfigError > ;
154128
155129const BINDGEN_FILE_GENERATORS_TUPLES : & [ ( & str , GenerateFn ) ] = & [
@@ -347,15 +321,15 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
347321 }
348322}
349323
350- /// Generates a `wdf_function_table .rs` file in `OUT_DIR` which contains the
351- /// definition of `WDF_FUNCTION_TABLE `. This is required to be generated here
352- /// since the size of the table is derived from either a global symbol
353- /// (`WDF_FUNCTION_COUNT`) that newer WDF versions expose, or an enum that older
354- /// versions use.
355- fn generate_wdf_function_table ( out_path : & Path , config : & Config ) -> std:: io:: Result < ( ) > {
324+ /// Generates a `wdf_function_count .rs` file in `OUT_DIR` which contains the
325+ /// definition of the function `get_wdf_function_count() `. This is required to
326+ /// be generated here since the size of the table is derived from either a
327+ /// global symbol that newer WDF versions expose, or an enum that older versions
328+ /// use.
329+ fn generate_wdf_function_count ( out_path : & Path , config : & Config ) -> std:: io:: Result < ( ) > {
356330 const MINIMUM_MINOR_VERSION_TO_GENERATE_WDF_FUNCTION_COUNT : u8 = 25 ;
357331
358- let generated_file_path = out_path. join ( "wdf_function_table .rs" ) ;
332+ let generated_file_path = out_path. join ( "wdf_function_count .rs" ) ;
359333 let mut generated_file = std:: fs:: File :: create ( generated_file_path) ?;
360334
361335 let is_wdf_function_count_generated = match * config {
@@ -392,26 +366,16 @@ fn generate_wdf_function_table(out_path: &Path, config: &Config) -> std::io::Res
392366 }
393367 } ;
394368
395- let wdf_function_table_code_snippet = if is_wdf_function_count_generated {
396- WDF_FUNCTION_TABLE_TEMPLATE
397- . replace ( NUM_WDF_FUNCTIONS_PLACEHOLDER , "crate::WdfFunctionCount" )
398- . replace (
399- WDF_FUNCTION_COUNT_DECLARATION_PLACEHOLDER ,
400- WDF_FUNCTION_COUNT_DECLARATION_EXTERNAL_SYMBOL ,
401- )
402- } else {
403- WDF_FUNCTION_TABLE_TEMPLATE
404- . replace (
405- NUM_WDF_FUNCTIONS_PLACEHOLDER ,
406- "crate::_WDFFUNCENUM::WdfFunctionTableNumEntries" ,
407- )
408- . replace (
409- WDF_FUNCTION_COUNT_DECLARATION_PLACEHOLDER ,
410- WDF_FUNCTION_COUNT_DECLARATION_TABLE_INDEX ,
411- )
412- } ;
369+ let wdf_function_table_count_snippet = WDF_FUNCTION_COUNT_FUNCTION_TEMPLATE . replace (
370+ WDF_FUNCTION_COUNT_PLACEHOLDER ,
371+ if is_wdf_function_count_generated {
372+ WDF_FUNCTION_COUNT_DECLARATION_EXTERNAL_SYMBOL
373+ } else {
374+ WDF_FUNCTION_COUNT_DECLARATION_TABLE_INDEX
375+ } ,
376+ ) ;
413377
414- generated_file. write_all ( wdf_function_table_code_snippet . as_bytes ( ) ) ?;
378+ generated_file. write_all ( wdf_function_table_count_snippet . as_bytes ( ) ) ?;
415379 Ok ( ( ) )
416380}
417381
@@ -540,8 +504,8 @@ fn main() -> anyhow::Result<()> {
540504 . expect ( "Scoped Thread should spawn successfully" ) ,
541505 ) ;
542506
543- info_span ! ( "wdf_function_table .rs generation" ) . in_scope ( || {
544- generate_wdf_function_table ( out_path, config) ?;
507+ info_span ! ( "wdf_function_count .rs generation" ) . in_scope ( || {
508+ generate_wdf_function_count ( out_path, config) ?;
545509 Ok :: < ( ) , std:: io:: Error > ( ( ) )
546510 } ) ?;
547511
0 commit comments