hmod 0.1.1

Reliably discovers the module handle of the current PE image
Documentation
//! # Introduction
//!
//! This crate exposes a single public-facing function: [`current()`]. It returns the load
//! address of the PE image containing the currently executing code. This address, when
//! reinterpreted as an [`HINSTANCE` or
//! `HMODULE`](https://devblogs.microsoft.com/oldnewthing/20040614-00/?p=38903), serves as
//! a module identifier used throughout the Win32 API to reference per-module resources,
//! code, and data.
//!
//! This is useful in contexts such as:
//!
//! - Loading embedded resources (icons, cursors, dialogs)
//! - Registering window classes
//! - Setting up global hooks
//!
//! # Interoperability
//!
//! Values returned by [`current()`] are typically reinterpreted as `HINSTANCE` or
//! `HMODULE` handles to interface with Win32 APIs. Since popular Win32 bindings represent
//! these types differently, this section outlines how to integrate with the three most
//! common crates.
//!
//! ## [`windows-sys`](https://crates.io/crates/windows-sys)
//!
//! This low-level binding crate uses type aliases for `HINSTANCE` and `HMODULE`:
//!
//! ```rust
//! # use core::ffi::c_void;
//! pub type HINSTANCE = *mut c_void;
//! pub type HMODULE = *mut c_void;
//! ```
//!
//! These are identical to the return type of [`current()`] and values can be passed
//! without conversion:
//!
//! ```rust,no_run
//! # use windows_sys::Win32::UI::WindowsAndMessaging::LoadCursorW;
//! # use windows_sys::core::w;
//! let cursor = unsafe { LoadCursorW(hmod::current(), w!("arrow")) };
//! ```
//!
//! ## [`windows`](https://crates.io/crates/windows)
//!
//! The higher-level `windows` crate wraps Win32 handles in newtypes for stronger type
//! safety. Its `HINSTANCE` and `HMODULE` types are defined as:
//!
//! ```rust
//! # use core::ffi::c_void;
//! pub struct HINSTANCE(pub *mut c_void);
//! pub struct HMODULE(pub *mut c_void);
//! ```
//!
//! Since the fields are public, these wrappers can be constructed via direct
//! initialization:
//!
//! ```rust,no_run
//! # use windows::{core::w, Win32::{Foundation::HINSTANCE, UI::WindowsAndMessaging::LoadCursorW}};
//! # fn main() -> windows::core::Result<()> {
//! let hmod = hmod::current();
//! let hmod = HINSTANCE(hmod); // construct wrapper
//! let cursor = unsafe { LoadCursorW(Some(hmod), w!("arrow")) }?;
//! # Ok(())
//! # }
//! ```
//!
//! This crate does not implement `From` traits for these types to avoid coupling to a
//! specific version of the `windows` crate.
//!
//! ## [`winapi`](https://crates.io/crates/winapi)
//!
//! The `winapi` crate models `HINSTANCE` as a pointer to an empty enum to prevent
//! accidental construction and enforce type safety at compile time. `HMODULE` is a type
//! alias for `HINSTANCE`:
//!
//! ```rust
//! pub enum HINSTANCE__ {}
//! pub type HINSTANCE = *mut HINSTANCE__;
//! pub type HMODULE = HINSTANCE;
//! ```
//!
//! To convert to `winapi`-compatible types an `as`-cast is required:
//!
//! ```rust,no_run
//! # use winapi::{shared::minwindef::HINSTANCE, um::winuser::LoadCursorW};
//! # use windows_sys::core::w;
//! let hmod = hmod::current();
//! let hmod = hmod as HINSTANCE;
//! let cursor = unsafe { LoadCursorW(hmod, w!("arrow")) };
//! ```
//!
//! # Implementation details
//!
//! This crate makes use of the `__ImageBase` pseudo-variable (as explained in Raymond
//! Chen's blog post [Accessing the current module’s HINSTANCE from a static
//! library](https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483)). It is a
//! synthetic symbol supplied by the linker, located at relative virtual address (RVA)
//! zero.
//!
//! The `__ImageBase` symbol is provided by all mainstream Windows linkers (MSVC's
//! link.exe, Clang's lld, and MinGW's ld).
//!
//! The value is resolved at module load time. Accessing it involves a single memory load
//! at run-time, with no function calls or system interaction.
//!

#![cfg(target_os = "windows")]
#![no_std]
#![warn(missing_docs)]

/// Returns the load address of the PE image that contains the currently executing code.
/// This address serves as a module handle in Win32 APIs.
///
/// <div class="warning">
///
/// ⚠️ **Important:** This handle does not increment the module's reference count. Passing
/// it to APIs like
/// [`FreeLibrary`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-freelibrary)
/// may result in the module being unloaded prematurely.
///
/// </div>
///
/// <div class="warning">
///
/// ⚠️ **Caution:** The returned address is valid only while the module remains loaded. If
/// you dereference it, ensure the module is still mapped and large enough to satisfy the
/// read.
///
/// </div>
///
/// # Examples
///
/// ## Displaying the module's load address.
///
/// ```rust
/// let load_addr = hmod::current();
/// println!("Load address: {load_addr:#?}");
/// ```
///
/// ## Loading a cursor resource
///
/// ```rust,no_run
/// # use windows_sys::Win32::UI::WindowsAndMessaging::LoadCursorW;
/// # use windows_sys::core::w;
/// let cursor = unsafe { LoadCursorW(hmod::current(), w!("arrow")) };
/// ```
///
#[inline(always)]
#[allow(unused_unsafe)]
#[must_use]
pub fn current() -> *mut ::core::ffi::c_void {
    extern "C" {
        static __ImageBase: u8;
    }
    (unsafe { ::core::ptr::addr_of!(__ImageBase) }) as *mut ::core::ffi::c_void
}

// MSRV 1.82: Use the following implementation instead

// #[inline(always)]
// #[must_use]
// pub fn current() -> *mut ::core::ffi::c_void {
//     unsafe extern "C" {
//         static __ImageBase: u8;
//     }
//     ::core::ptr::addr_of!(__ImageBase) as *mut ::core::ffi::c_void
// }

#[cfg(doctest)]
mod test_readme;