diff --git a/src/values/hwnd.rs b/src/values/hwnd.rs index 74963ca..13aa214 100644 --- a/src/values/hwnd.rs +++ b/src/values/hwnd.rs @@ -36,6 +36,8 @@ use core::ptr::NonNull; /// #[doc = include_str!("hwnd.conversion.md")] /// +#[doc = include_str!("provenance.md")] +/// #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct HWND(*mut c_void); // N.B.: ntdef.h defines HWND via `DECLARE_HANDLE(HWND);`. This either resolves to `HANDLE` ≈ `void*` or `struct HWND__*` depending on `STRICT`. // https://clang.llvm.org/docs/ControlFlowIntegrity.html#fsanitize-cfi-icall-generalize-pointers might be necessary to make things play nice... diff --git a/src/values/non_null_hwnd.rs b/src/values/non_null_hwnd.rs index bf0a5ae..457cbc5 100644 --- a/src/values/non_null_hwnd.rs +++ b/src/values/non_null_hwnd.rs @@ -36,6 +36,8 @@ use core::ptr::NonNull; /// #[doc = include_str!("non_null_hwnd.conversion.md")] /// +#[doc = include_str!("provenance.md")] +/// #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct NonNullHWND(NonNull); // N.B.: ntdef.h defines HWND via `DECLARE_HANDLE(HWND);`. This either resolves to `HANDLE` ≈ `void*` or `struct HWND__*` depending on `STRICT`. // https://clang.llvm.org/docs/ControlFlowIntegrity.html#fsanitize-cfi-icall-generalize-pointers might be necessary to make things play nice... diff --git a/src/values/provenance.md b/src/values/provenance.md new file mode 100644 index 0000000..1df985b --- /dev/null +++ b/src/values/provenance.md @@ -0,0 +1,11 @@ +### Pointer Provenance + +`HWND`s aren't real pointers ever since Windows 95 / 32-bit Windows, and effectively have no pointer provenance to worry about. +Perhaps someday [`core::ptr::without_provenance_mut`] will be stabilized, be made `const`-friendly, and used... until then, this crate theoretically allows `HWND`s to gain overly permissive provenances. +This should cause no additional undefined behavior, but might make sanitizer diagnostics less clear if you do something incredibly silly like try to dereference an `HWND` (which is always undefined behavior.) + +| OS | Implementation | Notes | +| ------------------| ------------------| ------| +| Windows 3.1 | Near pointer into the window manager's data segment \[[tont](https://devblogs.microsoft.com/oldnewthing/20070716-00/?p=26003)\] | Technically would have provenance, but 16-bit Windows isn't supported by `rustc`, mooting the issue. Even [Dennis Duda](https://seri.tools/blog/compiling-rust-for-legacy-windows/) hasn't tried backporting Rust binaries to Windows 3.1. | +| Windows 95+ | ≈ Byte offset into 64 KiB handle table \[[tont](https://devblogs.microsoft.com/oldnewthing/20070716-00/?p=26003)\] | Effectively a [`u16`] index/offset, not a pointer. | +| Windows NT+ | ≈ ([u16], [u16]) index/offset and "uniquifier" \[[tont](https://devblogs.microsoft.com/oldnewthing/20070717-00/?p=25983)\] | Fixes most handle reuse bugs in practice. |