Skip to main content

max / audiofiles

Upgrade windows crate to 0.62, fix COM API for Windows cross-compilation Migrated drag_out/windows.rs from windows 0.54 to 0.62 (latest stable): Skip/Reset return Result<()>, GlobalFree takes Option<HGLOBAL>, OleInitialize returns Result, added required feature flags. Fixed build-macos.sh to use keychain profile. Added build-windows.sh. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-03-21 16:40 UTC
Commit: a3bca54bb9c6297e31834e1bb72f35c864a30c3c
Parent: 1084edc
3 files changed, +76 insertions, -16 deletions
M Cargo.lock +53 -1
@@ -430,7 +430,8 @@ dependencies = [
430 430 "tracing",
431 431 "wayland-backend",
432 432 "wayland-client",
433 - "windows 0.58.0",
433 + "windows 0.62.2",
434 + "windows-core 0.62.2",
434 435 ]
435 436
436 437 [[package]]
@@ -5967,6 +5968,27 @@ dependencies = [
5967 5968 ]
5968 5969
5969 5970 [[package]]
5971 + name = "windows"
5972 + version = "0.62.2"
5973 + source = "registry+https://github.com/rust-lang/crates.io-index"
5974 + checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
5975 + dependencies = [
5976 + "windows-collections",
5977 + "windows-core 0.62.2",
5978 + "windows-future",
5979 + "windows-numerics",
5980 + ]
5981 +
5982 + [[package]]
5983 + name = "windows-collections"
5984 + version = "0.3.2"
5985 + source = "registry+https://github.com/rust-lang/crates.io-index"
5986 + checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
5987 + dependencies = [
5988 + "windows-core 0.62.2",
5989 + ]
5990 +
5991 + [[package]]
5970 5992 name = "windows-core"
5971 5993 version = "0.54.0"
5972 5994 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6003,6 +6025,17 @@ dependencies = [
6003 6025 ]
6004 6026
6005 6027 [[package]]
6028 + name = "windows-future"
6029 + version = "0.3.2"
6030 + source = "registry+https://github.com/rust-lang/crates.io-index"
6031 + checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
6032 + dependencies = [
6033 + "windows-core 0.62.2",
6034 + "windows-link",
6035 + "windows-threading",
6036 + ]
6037 +
6038 + [[package]]
6006 6039 name = "windows-implement"
6007 6040 version = "0.58.0"
6008 6041 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6053,6 +6086,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
6053 6086 checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
6054 6087
6055 6088 [[package]]
6089 + name = "windows-numerics"
6090 + version = "0.3.1"
6091 + source = "registry+https://github.com/rust-lang/crates.io-index"
6092 + checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
6093 + dependencies = [
6094 + "windows-core 0.62.2",
6095 + "windows-link",
6096 + ]
6097 +
6098 + [[package]]
6056 6099 name = "windows-registry"
6057 6100 version = "0.6.1"
6058 6101 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6203,6 +6246,15 @@ dependencies = [
6203 6246 ]
6204 6247
6205 6248 [[package]]
6249 + name = "windows-threading"
6250 + version = "0.2.1"
6251 + source = "registry+https://github.com/rust-lang/crates.io-index"
6252 + checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
6253 + dependencies = [
6254 + "windows-link",
6255 + ]
6256 +
6257 + [[package]]
6206 6258 name = "windows_aarch64_gnullvm"
6207 6259 version = "0.42.2"
6208 6260 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -34,7 +34,8 @@ objc2-foundation = { version = "0.3", features = ["NSString", "NSURL", "NSArray"
34 34 objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSWindow", "NSView", "NSDragging", "NSDraggingItem", "NSDraggingSession", "NSPasteboard", "NSEvent", "NSResponder", "NSGraphicsContext"] }
35 35
36 36 [target.'cfg(target_os = "windows")'.dependencies]
37 - windows = { version = "0.58", features = ["implement", "Win32_Foundation", "Win32_System_Com", "Win32_System_Ole", "Win32_System_Memory"] }
37 + windows = { version = "0.62", features = ["Win32_Foundation", "Win32_System_Com", "Win32_System_Com_StructuredStorage", "Win32_System_Ole", "Win32_System_Memory", "Win32_System_SystemServices", "Win32_Graphics_Gdi"] }
38 + windows-core = "0.62"
38 39
39 40 [target.'cfg(target_os = "linux")'.dependencies]
40 41 wayland-client = { version = "0.31", default-features = false }
@@ -21,8 +21,10 @@ use tracing::{debug, warn};
21 21 use windows::core::*;
22 22 use windows::Win32::Foundation::*;
23 23 use windows::Win32::System::Com::*;
24 + // STGMEDIUM and STGMEDIUM_0 are in Win32::System::Com (re-exported via Com::*)
24 25 use windows::Win32::System::Memory::*;
25 26 use windows::Win32::System::Ole::*;
27 + use windows::Win32::System::SystemServices::MODIFIERKEYS_FLAGS;
26 28
27 29 const CF_HDROP_VALUE: u16 = 15;
28 30 const MK_LBUTTON: u32 = 0x0001;
@@ -70,7 +72,7 @@ unsafe fn build_hdrop(paths: &[PathBuf]) -> Result<(HGLOBAL, usize)> {
70 72 let h = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, total_bytes)?;
71 73 let ptr = GlobalLock(h);
72 74 if ptr.is_null() {
73 - let _ = GlobalFree(h);
75 + let _ = GlobalFree(Some(h));
74 76 return Err(Error::from(E_OUTOFMEMORY));
75 77 }
76 78 let ptr = ptr as *mut u8;
@@ -144,14 +146,14 @@ impl IEnumFORMATETC_Impl for HDropFormatEnum_Impl {
144 146 S_OK
145 147 }
146 148
147 - fn Skip(&self, celt: u32) -> HRESULT {
149 + fn Skip(&self, celt: u32) -> windows_core::Result<()> {
148 150 self.pos.fetch_add(celt, Ordering::Relaxed);
149 - S_OK
151 + Ok(())
150 152 }
151 153
152 - fn Reset(&self) -> HRESULT {
154 + fn Reset(&self) -> windows_core::Result<()> {
153 155 self.pos.store(0, Ordering::Relaxed);
154 - S_OK
156 + Ok(())
155 157 }
156 158
157 159 fn Clone(&self) -> Result<IEnumFORMATETC> {
@@ -176,7 +178,7 @@ struct FileDataObject {
176 178 impl Drop for FileDataObject {
177 179 fn drop(&mut self) {
178 180 unsafe {
179 - let _ = GlobalFree(self.hdrop);
181 + let _ = GlobalFree(Some(self.hdrop));
180 182 }
181 183 }
182 184 }
@@ -224,7 +226,7 @@ impl IDataObject_Impl for FileDataObject_Impl {
224 226 DATA_S_SAMEFORMATETC
225 227 }
226 228
227 - fn SetData(&self, _: *const FORMATETC, _: *mut STGMEDIUM, _: BOOL) -> Result<()> {
229 + fn SetData(&self, _: *const FORMATETC, _: *const STGMEDIUM, _: BOOL) -> Result<()> {
228 230 Err(Error::from(E_NOTIMPL))
229 231 }
230 232
@@ -239,7 +241,7 @@ impl IDataObject_Impl for FileDataObject_Impl {
239 241 Ok(e)
240 242 }
241 243
242 - fn DAdvise(&self, _: *const FORMATETC, _: u32, _: Option<&IAdviseSink>) -> Result<u32> {
244 + fn DAdvise(&self, _: *const FORMATETC, _: u32, _: Ref<IAdviseSink>) -> Result<u32> {
243 245 Err(Error::from(OLE_E_ADVISENOTSUPPORTED))
244 246 }
245 247
@@ -260,13 +262,18 @@ impl IDataObject_Impl for FileDataObject_Impl {
260 262 pub(super) fn begin_drag_session(paths: &[PathBuf]) -> bool {
261 263 unsafe {
262 264 // OleInitialize is the superset of CoInitializeEx — required for DoDragDrop.
263 - // S_FALSE means "already initialized on this thread", which is fine.
264 - let ole_hr = OleInitialize(None);
265 - if ole_hr != S_OK && ole_hr != S_FALSE {
266 - warn!(?ole_hr, "OleInitialize failed");
267 - return false;
265 + // Ok(()) means we initialized, Err with S_FALSE means already initialized (fine).
266 + let ole_result = OleInitialize(None);
267 + let we_initialized = ole_result.is_ok();
268 + if !we_initialized {
269 + // Check if it's the benign "already initialized" case
270 + if let Err(ref e) = ole_result {
271 + if e.code() != S_FALSE {
272 + warn!(?ole_result, "OleInitialize failed");
273 + return false;
274 + }
275 + }
268 276 }
269 - let we_initialized = ole_hr == S_OK;
270 277
271 278 let result = (|| -> Result<bool> {
272 279 let (hdrop, size) = build_hdrop(paths)?;