@@ -12,12 +12,12 @@ use std::{
12
12
io:: Write ,
13
13
panic,
14
14
path:: { Path , PathBuf } ,
15
+ sync:: LazyLock ,
15
16
thread,
16
17
} ;
17
18
18
19
use anyhow:: Context ;
19
20
use bindgen:: CodegenConfig ;
20
- use lazy_static:: lazy_static;
21
21
use tracing:: { info, info_span, trace, Span } ;
22
22
use tracing_subscriber:: {
23
23
filter:: { LevelFilter , ParseError } ,
@@ -34,61 +34,33 @@ use wdk_build::{
34
34
UmdfConfig ,
35
35
} ;
36
36
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>" ;
41
37
const OUT_DIR_PLACEHOLDER : & str =
42
38
"<PLACEHOLDER FOR LITERAL VALUE CONTAINING OUT_DIR OF wdk-sys CRATE>" ;
43
39
const WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER : & str =
44
40
"<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 ! (
92
64
r#"
93
65
/// A procedural macro that allows WDF functions to be called by name.
94
66
///
@@ -138,18 +110,20 @@ macro_rules! call_unsafe_wdf_function_binding {{
138
110
)
139
111
}}
140
112
}}"#
141
- ) ;
142
- static ref TEST_STUBS_TEMPLATE : String = format!(
113
+ )
114
+ } ) ;
115
+
116
+ static TEST_STUBS_TEMPLATE : LazyLock < String > = LazyLock :: new ( || {
117
+ format ! (
143
118
r"
144
119
use crate::WDFFUNC;
145
120
146
121
/// Stubbed version of the symbol that [`WdfFunctions`] links to so that test targets will compile
147
122
#[no_mangle]
148
123
pub static mut {WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER}: *const WDFFUNC = core::ptr::null();
149
- "
150
- ) ;
151
- }
152
-
124
+ " ,
125
+ )
126
+ } ) ;
153
127
type GenerateFn = fn ( & Path , & Config ) -> Result < ( ) , ConfigError > ;
154
128
155
129
const BINDGEN_FILE_GENERATORS_TUPLES : & [ ( & str , GenerateFn ) ] = & [
@@ -347,15 +321,15 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
347
321
}
348
322
}
349
323
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 < ( ) > {
356
330
const MINIMUM_MINOR_VERSION_TO_GENERATE_WDF_FUNCTION_COUNT : u8 = 25 ;
357
331
358
- let generated_file_path = out_path. join ( "wdf_function_table .rs" ) ;
332
+ let generated_file_path = out_path. join ( "wdf_function_count .rs" ) ;
359
333
let mut generated_file = std:: fs:: File :: create ( generated_file_path) ?;
360
334
361
335
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
392
366
}
393
367
} ;
394
368
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
+ ) ;
413
377
414
- generated_file. write_all ( wdf_function_table_code_snippet . as_bytes ( ) ) ?;
378
+ generated_file. write_all ( wdf_function_table_count_snippet . as_bytes ( ) ) ?;
415
379
Ok ( ( ) )
416
380
}
417
381
@@ -540,8 +504,8 @@ fn main() -> anyhow::Result<()> {
540
504
. expect ( "Scoped Thread should spawn successfully" ) ,
541
505
) ;
542
506
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) ?;
545
509
Ok :: < ( ) , std:: io:: Error > ( ( ) )
546
510
} ) ?;
547
511
0 commit comments