#windows #win32 #dll #macro #ffi

macro windows-dll-codegen

Macro for dynamically loading windows dll functions

6 releases

0.3.0 Jan 30, 2021
0.2.4 Dec 9, 2020
0.2.0 Apr 22, 2020
0.1.1 Apr 20, 2020

#56 in Windows APIs

Download history 391/week @ 2020-11-14 393/week @ 2020-11-21 552/week @ 2020-11-28 764/week @ 2020-12-05 1405/week @ 2020-12-12 521/week @ 2020-12-19 614/week @ 2020-12-26 798/week @ 2021-01-02 797/week @ 2021-01-09 1352/week @ 2021-01-16 1109/week @ 2021-01-23 983/week @ 2021-01-30 1236/week @ 2021-02-06 950/week @ 2021-02-13 757/week @ 2021-02-20 1071/week @ 2021-02-27

3,059 downloads per month
Used in windows-dll

MIT license

16KB
257 lines

windows-dll

Rust

Macro for dynamically loading windows dll functions

Usage

use {
    windows_dll::dll,
    winapi::shared::{
        minwindef::ULONG,
        ntdef::{NTSTATUS, NT_SUCCESS, WCHAR},
    },
};

#[allow(non_snake_case)]
#[repr(C)]
struct OSVERSIONINFOW {
    dwOSVersionInfoSize: ULONG,
    dwMajorVersion: ULONG,
    dwMinorVersion: ULONG,
    dwBuildNumber: ULONG,
    dwPlatformId: ULONG,
    szCSDVersion: [WCHAR; 128],
}

#[dll("ntdll.dll")]
extern "system" {
    #[allow(non_snake_case)]
    fn RtlGetVersion(lpVersionInformation: *mut OSVERSIONINFOW) -> NTSTATUS;
}


fn os_version_info() -> OSVERSIONINFOW {
    unsafe {
        let mut vi = OSVERSIONINFOW {
            dwOSVersionInfoSize: 0,
            dwMajorVersion: 0,
            dwMinorVersion: 0,
            dwBuildNumber: 0,
            dwPlatformId: 0,
            szCSDVersion: [0; 128],
        };

        let status = RtlGetVersion(&mut vi as _);

        if NT_SUCCESS(status) {
            vi
        } else {
            panic!()
        }
    }
}

Return a result to determine whether the function can be retrieved

#[dll("ntdll.dll")]
extern "system" {
    #[allow(non_snake_case)]
    #[fallible]
    fn RtlGetVersion(lpVersionInformation: *mut OSVERSIONINFOW) -> NTSTATUS;
}

fn os_version_info() -> Result<OSVERSIONINFOW, windows_dll::Error> {
    unsafe {
        let mut vi = OSVERSIONINFOW {
            dwOSVersionInfoSize: 0,
            dwMajorVersion: 0,
            dwMinorVersion: 0,
            dwBuildNumber: 0,
            dwPlatformId: 0,
            szCSDVersion: [0; 128],
        };

        let status = RtlGetVersion(&mut vi as _)?;

        if NT_SUCCESS(status) {
            Ok(vi)
        } else {
            panic!()
        }
    }
}

Give the rust wrapper a different name to the dll export

#[dll("ntdll.dll")]
extern "system" {
    #[link_name = "RtlGetVersion"]
    fn rtl_get_version(lp_version_information: *mut OSVERSIONINFOW) -> NTSTATUS;
}

Use a dll export without a name

#[dll("uxtheme.dll")]
extern "system" {
    #[link_ordinal = 133]
    fn allow_dark_mode_for_window(hwnd: HWND, allow: BOOL) -> BOOL;
}

Check whether a function exists

#[dll("ntdll.dll")]
extern "system" {
    #[link_name = "RtlGetVersion"]
    fn rtl_get_version(lp_version_information: *mut OSVERSIONINFOW) -> NTSTATUS;
}

fn rtl_get_version_exists() -> bool {
    rtl_get_version::exists()
}

Pass flags to the underlying LoadLibraryExW call

use windows_dll::*;
#[dll("ntdll.dll", LOAD_LIBRARY_SEARCH_SYSTEM32)]
extern "system" {
    #[link_name = "RtlGetVersion"]
    fn rtl_get_version(lp_version_information: *mut OSVERSIONINFOW) -> NTSTATUS;
}

fn rtl_get_version_exists() -> bool {
    rtl_get_version::exists()
}

Dependencies

~0.7–1.3MB
~31K SLoC