diff --git a/Cargo.toml b/Cargo.toml index ac55f10aab..9689637bd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ name = "chrono" default = ["clock", "std", "oldtime", "wasmbind"] alloc = [] libc = [] +winapi = ["windows-targets"] std = [] clock = ["std", "winapi", "iana-time-zone", "android-tzdata"] oldtime = ["time"] @@ -44,7 +45,10 @@ js-sys = { version = "0.3", optional = true } # contains FFI bindings for [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.0", features = ["std", "minwinbase", "minwindef", "timezoneapi", "sysinfoapi"], optional = true } +windows-targets = { version = "0.48", optional = true } + +[target.'cfg(windows)'.dev-dependencies] +windows-bindgen = { version = "0.51" } [target.'cfg(unix)'.dependencies] iana-time-zone = { version = "0.1.45", optional = true, features = ["fallback"] } diff --git a/src/offset/local/mod.rs b/src/offset/local/mod.rs index a710d081de..d1f084a341 100644 --- a/src/offset/local/mod.rs +++ b/src/offset/local/mod.rs @@ -21,6 +21,10 @@ mod inner; #[path = "windows.rs"] mod inner; +#[cfg(all(windows, feature = "clock"))] +#[allow(unreachable_pub)] +mod win_bindings; + #[cfg(all( not(unix), not(windows), diff --git a/src/offset/local/win_bindings.rs b/src/offset/local/win_bindings.rs new file mode 100644 index 0000000000..292c951414 --- /dev/null +++ b/src/offset/local/win_bindings.rs @@ -0,0 +1,51 @@ +// Bindings generated by `windows-bindgen` 0.51.1 + +#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)] +::windows_targets::link!("kernel32.dll" "system" fn SystemTimeToFileTime(lpsystemtime : *const SYSTEMTIME, lpfiletime : *mut FILETIME) -> BOOL); +::windows_targets::link!("kernel32.dll" "system" fn SystemTimeToTzSpecificLocalTime(lptimezoneinformation : *const TIME_ZONE_INFORMATION, lpuniversaltime : *const SYSTEMTIME, lplocaltime : *mut SYSTEMTIME) -> BOOL); +::windows_targets::link!("kernel32.dll" "system" fn TzSpecificLocalTimeToSystemTime(lptimezoneinformation : *const TIME_ZONE_INFORMATION, lplocaltime : *const SYSTEMTIME, lpuniversaltime : *mut SYSTEMTIME) -> BOOL); +pub type BOOL = i32; +#[repr(C)] +pub struct FILETIME { + pub dwLowDateTime: u32, + pub dwHighDateTime: u32, +} +impl ::core::marker::Copy for FILETIME {} +impl ::core::clone::Clone for FILETIME { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct SYSTEMTIME { + pub wYear: u16, + pub wMonth: u16, + pub wDayOfWeek: u16, + pub wDay: u16, + pub wHour: u16, + pub wMinute: u16, + pub wSecond: u16, + pub wMilliseconds: u16, +} +impl ::core::marker::Copy for SYSTEMTIME {} +impl ::core::clone::Clone for SYSTEMTIME { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct TIME_ZONE_INFORMATION { + pub Bias: i32, + pub StandardName: [u16; 32], + pub StandardDate: SYSTEMTIME, + pub StandardBias: i32, + pub DaylightName: [u16; 32], + pub DaylightDate: SYSTEMTIME, + pub DaylightBias: i32, +} +impl ::core::marker::Copy for TIME_ZONE_INFORMATION {} +impl ::core::clone::Clone for TIME_ZONE_INFORMATION { + fn clone(&self) -> Self { + *self + } +} diff --git a/src/offset/local/win_bindings.txt b/src/offset/local/win_bindings.txt new file mode 100644 index 0000000000..ce5d3acfe2 --- /dev/null +++ b/src/offset/local/win_bindings.txt @@ -0,0 +1,6 @@ +--out src/offset/local/win_bindings.rs +--config flatten sys +--filter + Windows.Win32.System.Time.SystemTimeToFileTime + Windows.Win32.System.Time.SystemTimeToTzSpecificLocalTime + Windows.Win32.System.Time.TzSpecificLocalTimeToSystemTime diff --git a/src/offset/local/windows.rs b/src/offset/local/windows.rs index 84585170c2..539b6880fd 100644 --- a/src/offset/local/windows.rs +++ b/src/offset/local/windows.rs @@ -13,10 +13,9 @@ use std::io::Error; use std::ptr; use std::result::Result; -use winapi::shared::minwindef::FILETIME; -use winapi::um::minwinbase::SYSTEMTIME; -use winapi::um::timezoneapi::{ +use super::win_bindings::{ SystemTimeToFileTime, SystemTimeToTzSpecificLocalTime, TzSpecificLocalTimeToSystemTime, + FILETIME, SYSTEMTIME, }; use super::FixedOffset; diff --git a/tests/win_bindings.rs b/tests/win_bindings.rs new file mode 100644 index 0000000000..bfb110c38e --- /dev/null +++ b/tests/win_bindings.rs @@ -0,0 +1,22 @@ +#![cfg(all(windows, feature = "clock", feature = "std"))] + +use std::fs; +use windows_bindgen::bindgen; + +#[test] +fn gen_bindings() { + let input = "src/offset/local/win_bindings.txt"; + let output = "src/offset/local/win_bindings.rs"; + let existing = fs::read_to_string(output).unwrap(); + + let log = bindgen(["--etc", input]).unwrap(); + eprintln!("{}", log); + + // Check the output is the same as before. + // Depending on the git configuration the file may have been checked out with `\r\n` newlines or + // with `\n`. Compare line-by-line to ignore this difference. + let new = fs::read_to_string(output).unwrap(); + if !new.lines().eq(existing.lines()) { + panic!("generated file `{}` is changed.", output); + } +}