From daf461dde2f0f2eb3ce341dcd4afe42f8aa3e047 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Wed, 26 Jun 2024 09:43:21 -0500 Subject: [PATCH] core imp --- crates/libs/core/src/com_object.rs | 2 +- crates/libs/core/src/event.rs | 32 +++++++++++- crates/libs/core/src/imp/bindings.rs | 4 -- crates/libs/core/src/imp/delay_load.rs | 29 ----------- crates/libs/core/src/imp/factory_cache.rs | 22 +++++++- crates/libs/core/src/imp/heap.rs | 58 ---------------------- crates/libs/core/src/imp/mod.rs | 14 ------ crates/libs/core/src/imp/ref_count.rs | 1 - crates/libs/core/src/imp/waiter.rs | 1 - crates/libs/core/src/imp/weak_ref_count.rs | 1 - crates/tools/bindings/src/core.txt | 3 -- 11 files changed, 52 insertions(+), 115 deletions(-) delete mode 100644 crates/libs/core/src/imp/delay_load.rs delete mode 100644 crates/libs/core/src/imp/heap.rs diff --git a/crates/libs/core/src/com_object.rs b/crates/libs/core/src/com_object.rs index ede313071e..eb11a38f60 100644 --- a/crates/libs/core/src/com_object.rs +++ b/crates/libs/core/src/com_object.rs @@ -165,7 +165,7 @@ impl ComObject { /// Gets a borrowed reference to an interface that is implemented by `T`. /// /// The returned reference does not have an additional reference count. - /// You can AddRef it by calling [`Self::to_owned`]. + /// You can AddRef it by calling [`InterfaceRef::to_owned`]. #[inline(always)] pub fn as_interface(&self) -> InterfaceRef<'_, I> where diff --git a/crates/libs/core/src/event.rs b/crates/libs/core/src/event.rs index bb74f7ad8b..18211f9c1b 100644 --- a/crates/libs/core/src/event.rs +++ b/crates/libs/core/src/event.rs @@ -1,4 +1,5 @@ use super::*; +use core::ffi::c_void; use core::marker::PhantomData; use core::mem::{size_of, transmute_copy}; use core::ptr::null_mut; @@ -212,7 +213,7 @@ impl Drop for Array { unsafe { if !self.is_empty() && (*self.buffer).0.release() == 0 { core::ptr::drop_in_place(self.as_mut_slice()); - imp::heap_free(self.buffer as _) + heap_free(self.buffer as _) } } } @@ -230,7 +231,7 @@ impl Buffer { Ok(null_mut()) } else { let alloc_size = size_of::() + len * size_of::>(); - let header = imp::heap_alloc(alloc_size)? as *mut Self; + let header = heap_alloc(alloc_size)? as *mut Self; unsafe { header.write(Self(imp::RefCount::new(1), PhantomData)); } @@ -285,3 +286,30 @@ impl Delegate { } } } + +/// Allocate memory of size `bytes` using `malloc` - the `Event` implementation does not +/// need to use any particular allocator so `HeapAlloc` need not be used. +fn heap_alloc(bytes: usize) -> crate::Result<*mut c_void> { + let ptr: *mut c_void = unsafe { + extern "C" { + fn malloc(bytes: usize) -> *mut c_void; + } + + malloc(bytes) + }; + + if ptr.is_null() { + Err(Error::from_hresult(imp::E_OUTOFMEMORY)) + } else { + Ok(ptr) + } +} + +/// Free memory allocated by `heap_alloc`. +unsafe fn heap_free(ptr: *mut c_void) { + extern "C" { + fn free(ptr: *mut c_void); + } + + free(ptr); +} diff --git a/crates/libs/core/src/imp/bindings.rs b/crates/libs/core/src/imp/bindings.rs index 599bc419a7..5c4b4e2d5f 100644 --- a/crates/libs/core/src/imp/bindings.rs +++ b/crates/libs/core/src/imp/bindings.rs @@ -11,9 +11,6 @@ windows_targets::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes windows_targets::link!("kernel32.dll" "system" fn EncodePointer(ptr : *const core::ffi::c_void) -> *mut core::ffi::c_void); windows_targets::link!("kernel32.dll" "system" fn FreeLibrary(hlibmodule : HMODULE) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC); -windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> HANDLE); -windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap : HANDLE, dwflags : HEAP_FLAGS, dwbytes : usize) -> *mut core::ffi::c_void); -windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap : HANDLE, dwflags : HEAP_FLAGS, lpmem : *const core::ffi::c_void) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn LoadLibraryExA(lplibfilename : PCSTR, hfile : HANDLE, dwflags : LOAD_LIBRARY_FLAGS) -> HMODULE); windows_targets::link!("kernel32.dll" "system" fn SetEvent(hevent : HANDLE) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT); @@ -337,7 +334,6 @@ impl GUID { } } pub type HANDLE = *mut core::ffi::c_void; -pub type HEAP_FLAGS = u32; pub type HMODULE = *mut core::ffi::c_void; pub type HRESULT = i32; #[repr(C)] diff --git a/crates/libs/core/src/imp/delay_load.rs b/crates/libs/core/src/imp/delay_load.rs deleted file mode 100644 index 27c85dab13..0000000000 --- a/crates/libs/core/src/imp/delay_load.rs +++ /dev/null @@ -1,29 +0,0 @@ -use super::*; - -/// Attempts to load a function from a given library. -/// -/// This is a small wrapper around `LoadLibrary` and `GetProcAddress`. -/// -/// # Safety -/// -/// * Both the library and function names must be valid null-terminated strings. -pub unsafe fn delay_load(library: crate::PCSTR, function: crate::PCSTR) -> Option { - let library = LoadLibraryExA( - library.0, - core::ptr::null_mut(), - LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, - ); - - if library.is_null() { - return None; - } - - let address = GetProcAddress(library, function.0); - - if address.is_some() { - return Some(core::mem::transmute_copy(&address)); - } - - FreeLibrary(library); - None -} diff --git a/crates/libs/core/src/imp/factory_cache.rs b/crates/libs/core/src/imp/factory_cache.rs index e2b03d0b79..b24cb4bb6c 100644 --- a/crates/libs/core/src/imp/factory_cache.rs +++ b/crates/libs/core/src/imp/factory_cache.rs @@ -6,7 +6,6 @@ use core::mem::{forget, transmute, transmute_copy}; use core::ptr::null_mut; use core::sync::atomic::{AtomicPtr, Ordering}; -#[doc(hidden)] pub struct FactoryCache { shared: AtomicPtr, _c: PhantomData, @@ -154,6 +153,27 @@ unsafe fn get_activation_factory( function(transmute_copy(name), &mut abi).and_then(|| crate::Type::from_abi(abi)) } +unsafe fn delay_load(library: crate::PCSTR, function: crate::PCSTR) -> Option { + let library = LoadLibraryExA( + library.0, + core::ptr::null_mut(), + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, + ); + + if library.is_null() { + return None; + } + + let address = GetProcAddress(library, function.0); + + if address.is_some() { + return Some(core::mem::transmute_copy(&address)); + } + + FreeLibrary(library); + None +} + type DllGetActivationFactory = extern "system" fn(name: *mut c_void, factory: *mut *mut c_void) -> crate::HRESULT; diff --git a/crates/libs/core/src/imp/heap.rs b/crates/libs/core/src/imp/heap.rs deleted file mode 100644 index b3868373df..0000000000 --- a/crates/libs/core/src/imp/heap.rs +++ /dev/null @@ -1,58 +0,0 @@ -use super::*; -use core::ffi::c_void; - -/// Allocate memory of size `bytes` using `HeapAlloc`. -/// -/// The memory allocated by this function is uninitialized. -/// -/// This function will fail in OOM situations, if the heap is otherwise corrupt, -/// or if getting a handle to the process heap fails. -pub fn heap_alloc(bytes: usize) -> crate::Result<*mut c_void> { - #[cfg(windows)] - let ptr: *mut c_void = unsafe { HeapAlloc(GetProcessHeap(), 0, bytes) }; - - #[cfg(not(windows))] - let ptr: *mut c_void = unsafe { - extern "C" { - fn malloc(bytes: usize) -> *mut c_void; - } - - malloc(bytes) - }; - - if ptr.is_null() { - Err(E_OUTOFMEMORY.into()) - } else { - // HeapAlloc is not guaranteed to return zero memory but usually does. This just ensures that - // it predictably returns non-zero memory for testing purposes. This is similar to what MSVC's - // debug allocator does for the same reason. - #[cfg(debug_assertions)] - unsafe { - core::ptr::write_bytes(ptr, 0xCC, bytes); - } - Ok(ptr) - } -} - -/// Free memory allocated by `HeapAlloc` or `HeapReAlloc`. -/// -/// The pointer is allowed to be null. -/// -/// # Safety -/// -/// `ptr` must be a valid pointer to memory allocated by `HeapAlloc` or `HeapReAlloc` -pub unsafe fn heap_free(ptr: *mut c_void) { - #[cfg(windows)] - { - HeapFree(GetProcessHeap(), 0, ptr); - } - - #[cfg(not(windows))] - { - extern "C" { - fn free(ptr: *mut c_void); - } - - free(ptr); - } -} diff --git a/crates/libs/core/src/imp/mod.rs b/crates/libs/core/src/imp/mod.rs index fbafcad084..badd497bd5 100644 --- a/crates/libs/core/src/imp/mod.rs +++ b/crates/libs/core/src/imp/mod.rs @@ -1,10 +1,8 @@ mod bindings; mod can_into; mod com_bindings; -mod delay_load; mod factory_cache; mod generic_factory; -mod heap; mod ref_count; mod sha1; mod waiter; @@ -13,25 +11,13 @@ mod weak_ref_count; pub use bindings::*; pub use can_into::*; pub use com_bindings::*; -pub use delay_load::*; pub use factory_cache::*; pub use generic_factory::*; -pub use heap::*; pub use ref_count::*; pub use sha1::*; pub use waiter::*; pub use weak_ref_count::*; -pub fn wide_trim_end(mut wide: &[u16]) -> &[u16] { - while let Some(last) = wide.last() { - match last { - 32 | 9..=13 => wide = &wide[..wide.len() - 1], - _ => break, - } - } - wide -} - #[doc(hidden)] #[macro_export] macro_rules! interface_hierarchy { diff --git a/crates/libs/core/src/imp/ref_count.rs b/crates/libs/core/src/imp/ref_count.rs index ee3ef3e53d..1dc3a97578 100644 --- a/crates/libs/core/src/imp/ref_count.rs +++ b/crates/libs/core/src/imp/ref_count.rs @@ -1,6 +1,5 @@ use core::sync::atomic::{fence, AtomicI32, Ordering}; -#[doc(hidden)] #[repr(transparent)] #[derive(Default)] pub struct RefCount(pub(crate) AtomicI32); diff --git a/crates/libs/core/src/imp/waiter.rs b/crates/libs/core/src/imp/waiter.rs index 67c9e2c1b6..64a31cd86d 100644 --- a/crates/libs/core/src/imp/waiter.rs +++ b/crates/libs/core/src/imp/waiter.rs @@ -1,6 +1,5 @@ use super::*; -#[doc(hidden)] pub struct Waiter(HANDLE); pub struct WaiterSignaler(HANDLE); diff --git a/crates/libs/core/src/imp/weak_ref_count.rs b/crates/libs/core/src/imp/weak_ref_count.rs index a6baa606b9..6346eb733b 100644 --- a/crates/libs/core/src/imp/weak_ref_count.rs +++ b/crates/libs/core/src/imp/weak_ref_count.rs @@ -5,7 +5,6 @@ use core::mem::{transmute, transmute_copy}; use core::ptr::null_mut; use core::sync::atomic::{AtomicIsize, Ordering}; -#[doc(hidden)] #[repr(transparent)] #[derive(Default)] pub struct WeakRefCount(AtomicIsize); diff --git a/crates/tools/bindings/src/core.txt b/crates/tools/bindings/src/core.txt index 41264afa28..0e624d5057 100644 --- a/crates/tools/bindings/src/core.txt +++ b/crates/tools/bindings/src/core.txt @@ -28,9 +28,6 @@ Windows.Win32.System.LibraryLoader.GetProcAddress Windows.Win32.System.LibraryLoader.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS Windows.Win32.System.LibraryLoader.LoadLibraryExA - Windows.Win32.System.Memory.GetProcessHeap - Windows.Win32.System.Memory.HeapAlloc - Windows.Win32.System.Memory.HeapFree Windows.Win32.System.Threading.CreateEventW Windows.Win32.System.Threading.SetEvent Windows.Win32.System.Threading.WaitForSingleObject