Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement bindings for g_win32 functions #1042

Merged
merged 1 commit into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 86 additions & 7 deletions glib/src/win32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,94 @@

use std::path::PathBuf;

use crate::translate::*;
use crate::{translate::*, GString, StrV};

#[doc(alias = "g_win32_get_package_installation_directory_of_module")]
pub fn win32_get_package_installation_directory_of_module(
hmodule: ffi::gpointer,
) -> Option<PathBuf> {
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum OSType {
#[doc(alias = "G_WIN32_OS_ANY")]
Any,
#[doc(alias = "G_WIN32_OS_WORKSTATION")]
Workstation,
#[doc(alias = "G_WIN32_OS_SERVER")]
Server,
}

#[doc(hidden)]
impl IntoGlib for OSType {
type GlibType = ffi::GWin32OSType;

#[inline]
fn into_glib(self) -> Self::GlibType {
match self {
Self::Any => ffi::G_WIN32_OS_ANY,
Self::Workstation => ffi::G_WIN32_OS_WORKSTATION,
Self::Server => ffi::G_WIN32_OS_SERVER,
}
}
}

#[doc(alias = "g_win32_check_windows_version")]
pub fn check_windows_version(major: i32, minor: i32, spver: i32, os_type: OSType) -> bool {
unsafe {
from_glib_full(ffi::g_win32_get_package_installation_directory_of_module(
hmodule,
from_glib(ffi::g_win32_check_windows_version(
major,
minor,
spver,
os_type.into_glib(),
))
}
}

#[doc(alias = "g_win32_get_command_line")]
#[doc(alias = "get_command_line")]
pub fn command_line() -> StrV {
unsafe { FromGlibPtrContainer::from_glib_full(ffi::g_win32_get_command_line()) }
}

#[doc(alias = "g_win32_error_message")]
pub fn error_message(error: i32) -> GString {
sdroege marked this conversation as resolved.
Show resolved Hide resolved
unsafe { from_glib_full(ffi::g_win32_error_message(error)) }
}

#[doc(alias = "g_win32_getlocale")]
pub fn getlocale() -> GString {
unsafe { from_glib_full(ffi::g_win32_getlocale()) }
}

#[doc(alias = "g_win32_get_package_installation_directory_of_module")]
#[doc(alias = "get_package_installation_directory_of_module")]
pub fn package_installation_directory_of_module(
hmodule: std::os::windows::raw::HANDLE,
) -> Result<PathBuf, std::io::Error> {
// # Safety
// The underlying `GetModuleFilenameW` function has three possible
// outcomes when a raw pointer get passed to it:
// - When the pointer is a valid HINSTANCE of a DLL (e.g. acquired
// through the `GetModuleHandleW`), it sets a file path to the
// assigned "out" buffer and sets the return value to be the length
// of said path string
// - When the pointer is null, it sets the full path of the process'
// executable binary to the assigned buffer and sets the return value
// to be the length of said string
// - Whenever the provided buffer size is too small, it will set a
// truncated version of the path and return the length of said string
// while also setting the thread-local last-error code to
// `ERROR_INSUFFICIENT_BUFFER` (evaluates to 0x7A)
// - When the pointer is not a valid HINSTANCE that isn't NULL (e.g.
// a pointer to some GKeyFile), it will return 0 and set the last-error
// code to `ERROR_MOD_NOT_FOUND` (evaluates to 0x7E)
//
// The `g_win32_get_package_installation_directory_of_module` already
// handles all of the outcomes gracefully by:
// - Preallocating a MAX_PATH-long array of wchar_t for the out buffer,
// so that outcome #3 can be safely assumed to never happen
// - Returning NULL when outcome #4 happens
match unsafe {
from_glib_full::<_, Option<PathBuf>>(
ffi::g_win32_get_package_installation_directory_of_module(hmodule),
)
} {
Some(pb) => Ok(pb),
None => Err(std::io::Error::last_os_error()),
}
}
27 changes: 24 additions & 3 deletions glib/sys/Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,33 @@ status = "generate"
name = "unix_get_passwd_entry"
cfg_condition = "unix"
[[object.function]]
name = "win32_get_package_installation_directory_of_module"
name = "get_user_state_dir"
version = "2.72"
[[object.function]]
name = "check_windows_version"
manual = true
cfg_condition = "windows"
[[object.function]]
name = "get_user_state_dir"
version = "2.72"
name = "get_command_line"
manual = true
cfg_condition = "windows"
[[object.function]]
name = "error_message"
manual = true
cfg_condition = "windows"
[[object.function]]
name = "getlocale"
manual = true
cfg_condition = "windows"
[[object.function]]
name = "get_package_installation_directory_of_module"
manual = true
cfg_condition = "windows"
[[object.function]]
name = "locale_filename_from_utf8"
manual = true
cfg_condition = "windows"


[[object]]
name = "GLib.LOG_DOMAIN"
Expand Down
26 changes: 23 additions & 3 deletions glib/sys/src/manual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,34 @@ pub use self::win32::*;

#[cfg(target_family = "windows")]
mod win32 {
use libc::c_char;
use libc::{c_char, c_int};

use crate::gpointer;
use crate::gboolean;

pub type GWin32OSType = c_int;
pub const G_WIN32_OS_ANY: GWin32OSType = 0;
pub const G_WIN32_OS_WORKSTATION: GWin32OSType = 1;
pub const G_WIN32_OS_SERVER: GWin32OSType = 2;

extern "C" {
pub fn g_win32_check_windows_version(
major: c_int,
minor: c_int,
spver: c_int,
os_type: GWin32OSType,
) -> gboolean;

pub fn g_win32_get_command_line() -> *mut *mut c_char;

pub fn g_win32_error_message(error: c_int) -> *mut c_char;

pub fn g_win32_getlocale() -> *mut c_char;

pub fn g_win32_get_package_installation_directory_of_module(
hmodule: gpointer,
hmodule: std::os::windows::raw::HANDLE,
) -> *mut c_char;

pub fn g_win32_locale_filename_from_utf8(utf8filename: *const c_char) -> *mut c_char;
}
}

Expand Down