windows_ext/minwindef/mod.rs
1//! # `minwindef.h` macros for use in Rust with the windows-rs and windows-sys crates
2//! This module defines equivalents to the macros defined in Include/<version>/shared/minwindef.h
3//! as part of the Windows SDK. These macros serve to (un)pack numeric values into and from larger
4//! numeric types.
5//!
6//! Besides the existing `#define`s, this module adds a couple functions useful for those working
7//! with 64-bit integers and pointers:
8//! - [`lodword`] and [`hidword`] to get the lower and higher 32 bits from them
9//! - [`makelonglong`] to pack two 32-bit ints into a 64-bit int.
10//! These were added because they're useful for working with e.g. `CreateFileMapping*` functions.
11//!
12//! Lastly some additional methods were added for splitting and returning both values at once.
13//! Consider them syntactical sugar over the others, as that really is all they are.
14//! They just return a tuple containing (in order) the low order and high order components. This
15//! is achieved by just calling both of those functions one after the other.
16//!
17//! ```
18//! use windows_ext::minwindef::*;
19//! // existing minwindef.h macros:
20//! let full: u32 = 9548625;
21//! let lo1 = loword(full);
22//! let hi1 = hiword(full);
23//!
24//! // convenience wrapper:
25//! let full: u32 = 9548625;
26//! let (lo2, hi2) = splitdword(full);
27//! assert_eq!(lo1, lo2);
28//! assert_eq!(hi1, hi2);
29//! ```
30
31#[cfg(feature = "ext-impls")]
32pub mod ext;
33
34/// Get the low order word as u16
35#[inline(always)]
36pub const fn loword(dw: u32) -> u16 {
37 dw as u16 // truncate the first 16 bits
38}
39
40/// Get the high order word as u16
41#[inline(always)]
42pub const fn hiword(dw: u32) -> u16 {
43 (dw >> 16) as u16 // truncate the zero-padding
44}
45
46/// Split a single dword (`u32`) in both of its words (`u16`s) ordered (low, high)
47#[inline(always)]
48pub const fn splitdword(dw: u32) -> (u16, u16) {
49 (loword(dw), hiword(dw))
50}
51
52/// Get the low order byte from a word (u16)
53#[inline(always)]
54pub const fn lobyte(word: u16) -> u8 {
55 word as u8
56}
57
58/// Get the high order byte from a word (u16)
59#[inline(always)]
60pub const fn hibyte(word: u16) -> u8 {
61 (word >> 8) as u8
62}
63
64/// Split a single word (`u16`) in both of its bytes (`u8`s) ordered (low, high)
65#[inline(always)]
66pub const fn splitword(word: u16) -> (u8, u8) {
67 (lobyte(word), hibyte(word))
68}
69
70/// Get the low order double word from a u64
71#[inline(always)]
72pub const fn lodword(longlong: u64) -> u32 {
73 longlong as u32
74}
75
76/// Get the high order double word from a u64
77#[inline(always)]
78pub const fn hidword(longlong: u64) -> u32 {
79 (longlong >> 32) as u32
80}
81
82/// Split a single dword (`u32`) in both of its words (`u16`s) ordered (low, high)
83#[inline(always)]
84pub const fn splitqword(qw: u64) -> (u32, u32) {
85 (lodword(qw), hidword(qw))
86}
87
88/// Turn two bytes into a word
89#[inline(always)]
90pub const fn makeword(low: u8, high: u8) -> u16 {
91 (low as u16) | ((high as u16) << 8)
92}
93
94/// Turn two words into a dword/long
95/// docs are somewhat weird, the macro is named "MAKELONG" but returns a DWORD?
96#[inline(always)]
97pub const fn makelong(low: u16, high: u16) -> u32 {
98 (low as u32) | ((high as u32) << 16)
99}
100
101/// Not part of the standard macros, but a logical step to accommodate 64-bit
102/// Named after the underlying C datatype, in Win32 terms this would be a QWORD
103#[inline(always)]
104pub const fn makelonglong(low: u32, high: u32) -> u64 {
105 (low as u64) | ((high as u64) << 32)
106}