Skip to content

Commit 684e087

Browse files
authored
Merge pull request #1042 from rmnscnce/win32-bindings
Implement bindings for g_win32 functions
2 parents 4118872 + 248b3f7 commit 684e087

File tree

3 files changed

+133
-13
lines changed

3 files changed

+133
-13
lines changed

glib/src/win32.rs

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,94 @@
22

33
use std::path::PathBuf;
44

5-
use crate::translate::*;
5+
use crate::{translate::*, GString, StrV};
66

7-
#[doc(alias = "g_win32_get_package_installation_directory_of_module")]
8-
pub fn win32_get_package_installation_directory_of_module(
9-
hmodule: ffi::gpointer,
10-
) -> Option<PathBuf> {
7+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
8+
pub enum OSType {
9+
#[doc(alias = "G_WIN32_OS_ANY")]
10+
Any,
11+
#[doc(alias = "G_WIN32_OS_WORKSTATION")]
12+
Workstation,
13+
#[doc(alias = "G_WIN32_OS_SERVER")]
14+
Server,
15+
}
16+
17+
#[doc(hidden)]
18+
impl IntoGlib for OSType {
19+
type GlibType = ffi::GWin32OSType;
20+
21+
#[inline]
22+
fn into_glib(self) -> Self::GlibType {
23+
match self {
24+
Self::Any => ffi::G_WIN32_OS_ANY,
25+
Self::Workstation => ffi::G_WIN32_OS_WORKSTATION,
26+
Self::Server => ffi::G_WIN32_OS_SERVER,
27+
}
28+
}
29+
}
30+
31+
#[doc(alias = "g_win32_check_windows_version")]
32+
pub fn check_windows_version(major: i32, minor: i32, spver: i32, os_type: OSType) -> bool {
1133
unsafe {
12-
from_glib_full(ffi::g_win32_get_package_installation_directory_of_module(
13-
hmodule,
34+
from_glib(ffi::g_win32_check_windows_version(
35+
major,
36+
minor,
37+
spver,
38+
os_type.into_glib(),
1439
))
1540
}
1641
}
42+
43+
#[doc(alias = "g_win32_get_command_line")]
44+
#[doc(alias = "get_command_line")]
45+
pub fn command_line() -> StrV {
46+
unsafe { FromGlibPtrContainer::from_glib_full(ffi::g_win32_get_command_line()) }
47+
}
48+
49+
#[doc(alias = "g_win32_error_message")]
50+
pub fn error_message(error: i32) -> GString {
51+
unsafe { from_glib_full(ffi::g_win32_error_message(error)) }
52+
}
53+
54+
#[doc(alias = "g_win32_getlocale")]
55+
pub fn getlocale() -> GString {
56+
unsafe { from_glib_full(ffi::g_win32_getlocale()) }
57+
}
58+
59+
#[doc(alias = "g_win32_get_package_installation_directory_of_module")]
60+
#[doc(alias = "get_package_installation_directory_of_module")]
61+
pub fn package_installation_directory_of_module(
62+
hmodule: std::os::windows::raw::HANDLE,
63+
) -> Result<PathBuf, std::io::Error> {
64+
// # Safety
65+
// The underlying `GetModuleFilenameW` function has three possible
66+
// outcomes when a raw pointer get passed to it:
67+
// - When the pointer is a valid HINSTANCE of a DLL (e.g. acquired
68+
// through the `GetModuleHandleW`), it sets a file path to the
69+
// assigned "out" buffer and sets the return value to be the length
70+
// of said path string
71+
// - When the pointer is null, it sets the full path of the process'
72+
// executable binary to the assigned buffer and sets the return value
73+
// to be the length of said string
74+
// - Whenever the provided buffer size is too small, it will set a
75+
// truncated version of the path and return the length of said string
76+
// while also setting the thread-local last-error code to
77+
// `ERROR_INSUFFICIENT_BUFFER` (evaluates to 0x7A)
78+
// - When the pointer is not a valid HINSTANCE that isn't NULL (e.g.
79+
// a pointer to some GKeyFile), it will return 0 and set the last-error
80+
// code to `ERROR_MOD_NOT_FOUND` (evaluates to 0x7E)
81+
//
82+
// The `g_win32_get_package_installation_directory_of_module` already
83+
// handles all of the outcomes gracefully by:
84+
// - Preallocating a MAX_PATH-long array of wchar_t for the out buffer,
85+
// so that outcome #3 can be safely assumed to never happen
86+
// - Returning NULL when outcome #4 happens
87+
match unsafe {
88+
from_glib_full::<_, Option<PathBuf>>(
89+
ffi::g_win32_get_package_installation_directory_of_module(hmodule),
90+
)
91+
} {
92+
Some(pb) => Ok(pb),
93+
None => Err(std::io::Error::last_os_error()),
94+
}
95+
}

glib/sys/Gir.toml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,33 @@ status = "generate"
7171
name = "unix_get_passwd_entry"
7272
cfg_condition = "unix"
7373
[[object.function]]
74-
name = "win32_get_package_installation_directory_of_module"
74+
name = "get_user_state_dir"
75+
version = "2.72"
76+
[[object.function]]
77+
name = "check_windows_version"
7578
manual = true
7679
cfg_condition = "windows"
7780
[[object.function]]
78-
name = "get_user_state_dir"
79-
version = "2.72"
81+
name = "get_command_line"
82+
manual = true
83+
cfg_condition = "windows"
84+
[[object.function]]
85+
name = "error_message"
86+
manual = true
87+
cfg_condition = "windows"
88+
[[object.function]]
89+
name = "getlocale"
90+
manual = true
91+
cfg_condition = "windows"
92+
[[object.function]]
93+
name = "get_package_installation_directory_of_module"
94+
manual = true
95+
cfg_condition = "windows"
96+
[[object.function]]
97+
name = "locale_filename_from_utf8"
98+
manual = true
99+
cfg_condition = "windows"
100+
80101

81102
[[object]]
82103
name = "GLib.LOG_DOMAIN"

glib/sys/src/manual.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,34 @@ pub use self::win32::*;
4646

4747
#[cfg(target_family = "windows")]
4848
mod win32 {
49-
use libc::c_char;
49+
use libc::{c_char, c_int};
5050

51-
use crate::gpointer;
51+
use crate::gboolean;
52+
53+
pub type GWin32OSType = c_int;
54+
pub const G_WIN32_OS_ANY: GWin32OSType = 0;
55+
pub const G_WIN32_OS_WORKSTATION: GWin32OSType = 1;
56+
pub const G_WIN32_OS_SERVER: GWin32OSType = 2;
5257

5358
extern "C" {
59+
pub fn g_win32_check_windows_version(
60+
major: c_int,
61+
minor: c_int,
62+
spver: c_int,
63+
os_type: GWin32OSType,
64+
) -> gboolean;
65+
66+
pub fn g_win32_get_command_line() -> *mut *mut c_char;
67+
68+
pub fn g_win32_error_message(error: c_int) -> *mut c_char;
69+
70+
pub fn g_win32_getlocale() -> *mut c_char;
71+
5472
pub fn g_win32_get_package_installation_directory_of_module(
55-
hmodule: gpointer,
73+
hmodule: std::os::windows::raw::HANDLE,
5674
) -> *mut c_char;
75+
76+
pub fn g_win32_locale_filename_from_utf8(utf8filename: *const c_char) -> *mut c_char;
5777
}
5878
}
5979

0 commit comments

Comments
 (0)