winapi-rs

repository·0.3·Indexed 23 days ago

https://github.com/retep998/winapi-rs

Raw FFI bindings for the Windows API, gathered from the Windows 10 SDK. The crate provides comprehensive bindings across kernel mode (km), user mode (um), Universal C Runtime (ucrt), and Windows Runtime (winrt) modules. It is compatible with no_std environments and uses feature flags to gate specific API modules.

Tokens
1.2K
Snippets
2
Records
10
Agent score
34%

What's inside winapi

  1. Compatibility between winapi HANDLE and std HANDLE

    0.3

    By default, winapi defines its own c_void because it does not depend on std. This makes winapi's HANDLE type incompatible with std's HANDLE.

    To make them compatible, enable the std feature in winapi. This causes winapi to re-export c_void from std, aligning the types.

  2. Create an instance of a union

    0.3
    Because winapi provides raw FFI bindings, you cannot initialize unions using standard Rust syntax. Instead, use std::mem::zeroed() to create an initial instance of the union, and then assign the desired value using one of its variant methods.
  3. Install winapi via Cargo

    0.3

    To use winapi in your project, add it to your Cargo.toml. Since most Windows API functionality is gated behind feature flags, you must explicitly enable the features for the modules you intend to use.

    On non-Windows platforms, this crate acts as a no-op. For Windows targets, it is recommended to use target-specific dependencies.

    [target.'cfg(windows)'.dependencies]
    winapi = { version = "0.3", features = ["winuser"] }
  4. Explore the winapi module structure

    0.3

    The winapi crate is organized into several top-level modules representing different Windows subsystems and environments:

    • km: Kernel Mode APIs
    • shared: Shared definitions (like GUIDs) used across different modules
    • ucrt: Universal C Runtime
    • um: User Mode APIs
    • vc: Visual C++ specific bindings
    • winrt: Windows Runtime APIs
  5. Resolve unresolved import errors using feature flags

    0.3

    If you encounter errors stating that an import is unresolved, it is likely because the module containing that item is gated behind a feature flag. You must enable the specific feature in your Cargo.toml to access that module.

    For example, to use items in winapi::um::winuser, you must enable the winuser feature.

  6. Example: Display a Windows Message Box

    0.3

    This example demonstrates how to use the winuser feature to call MessageBoxW. It includes handling wide string conversion (UTF-16) required by the Windows API and managing the unsafe block.

    #[cfg(windows)] extern crate winapi;
    use std::io::Error;
    
    #[cfg(windows)]
    fn print_message(msg: &str) -> Result<i32, Error> {
        use std::ffi::OsStr;
        use std::iter::once;
        use std::os::windows::ffi::OsStrExt;
        use std::ptr::null_mut;
        use winapi::um::winuser::{MB_OK, MessageBoxW};
        let wide: Vec<u16> = OsStr::new(msg).encode_wide().chain(once(0)).collect();
        let ret = unsafe {
            MessageBoxW(null_mut(), wide.as_ptr(), wide.as_ptr(), MB_OK)
        };
        if ret == 0 { Err(Error::last_os_error()) }
        else { Ok(ret) }
    }
    #[cfg(not(windows))]
    fn print_message(msg: &str) -> Result<(), Error> {
        println!("{}", msg);
        Ok()
    }
    fn main() {
        print_message("Hello, world!").unwrap();
    }
  7. Use primitive C types from the `ctypes` module

    0.3

    The ctypes module provides type aliases for built-in primitive types used in C-style Windows FFI. These ensure correct bit-width and signedness when interfacing with Windows APIs. The module is compatible with both std and no_std environments.

    Available types include:

    • c_void (opaque pointer type)
    • c_char, c_schar: i8
    • c_uchar: u8
    • c_short: i16
    • c_ushort: u16
    • c_int, c_long: i32
    • c_uint, c_ulong: u32
    • c_longlong: i64
    • c_ulonglong: u64
    • c_float: f32
    • c_double: f64
    • __int8 through __uint64: standard sized integer aliases
    • wchar_t: u16 (used for wide characters)
  8. Implement the `Class` trait for COM classes

    0.3

    The Class trait is a requirement for all COM classes defined within the library. Implementing this trait allows a type to provide its unique Class Identifier (CLSID).

    To implement it, define the uuidof() method which returns a shared::guiddef::GUID.

  9. Implement the `Interface` trait for COM interfaces

    0.3

    The Interface trait is a requirement for all COM (Component Object Model) interfaces defined within the library. Implementing this trait allows a type to provide its unique Interface Identifier (IID).

    To implement it, define the uuidof() method which returns a shared::guiddef::GUID.