Vendor things

This commit is contained in:
John Doty 2024-03-08 11:03:01 -08:00
parent 5deceec006
commit 977e3c17e5
19434 changed files with 10682014 additions and 0 deletions

187
third-party/vendor/com-rs/src/comptr.rs vendored Normal file
View file

@ -0,0 +1,187 @@
// Copyright (c) 2016 com-rs developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
use std::mem;
use std::ops::Deref;
use std::os::raw::c_void;
use std::ptr;
use {IID, IUnknown};
/**
Wrapper type for COM interface pointers.
# Usage
## Passing COM pointers to/from FFI methods
`ComPtr<T>` has the following methods for accessing the underlying pointer:
* `as_ptr` returns the raw pointer `*const T`
* `as_mut_ptr` returns a mutable reference to the raw pointer `&mut *mut T`
The `AsComPtr` trait defines which pointer types can be returned by these
methods. These methods should be used carefully to ensure the returned pointers
do not outlive the `ComPtr` object.
```
extern crate com_rs;
use com_rs::*;
fn create_iunknown_object(p: *mut *mut IUnknown) { }
fn use_iunknown_object(p: *const IUnknown) { }
fn main() {
let mut unknown: ComPtr<IUnknown> = ComPtr::new();
create_iunknown_object(unknown.as_mut_ptr());
use_iunknown_object(unknown.as_ptr());
}
```
## Reference Counting
`ComPtr` implements the `Clone` and `Drop` traits, which call the
`IUnknown::add_ref` and `IUnknown::release` methods respectively to handle the
internal reference counting.
## Accessing COM interface methods
`ComPtr<T>` coerces into `T` using the `Deref` trait, allowing interface methods
to be called directly. However, dereferencing a `ComPtr` containing a null
pointer in this way results in a panic. All method calls should be guarded with
`is_null` checks to prevent this.
```
# use com_rs::*;
# fn create_iunknown_object(p: *mut *mut IUnknown) { }
let mut ptr: ComPtr<IUnknown> = ComPtr::new();
create_iunknown_object(ptr.as_mut_ptr());
if !ptr.is_null() {
// This is just for demonstration, don't call these directly
unsafe { ptr.add_ref() };
unsafe { ptr.release() };
}
```
## Conversion using `From`
`ComPtr<T>` also implements the `From` trait for conversion between different
COM interfaces. This is a wrapper around the `IUnknown::query_interface` method
which automatically uses the IID of the target type.
```
# use com_rs::*;
# fn create_iunknown_object(p: *mut *mut IUnknown) { }
# type IFoobar = IUnknown;
let mut unknown: ComPtr<IUnknown> = ComPtr::new();
create_iunknown_object(unknown.as_mut_ptr());
let other: ComPtr<IFoobar> = ComPtr::from(&unknown);
```
This will try to query the `IFoobar` interface on the unknown object. If the
interface is unavailable (or `unknown` is null), the returned object will be
null.
*/
#[derive(Debug)]
pub struct ComPtr<T: ComInterface> {
ptr: *mut T
}
/// Helper trait for `ComPtr`. Implemented automatically by the
/// `com_interface!` macro.
pub unsafe trait ComInterface: AsComPtr<IUnknown> {
#[doc(hidden)]
type Vtable;
/// Get the IID associated with a COM interface struct.
fn iid() -> IID;
}
/// Helper trait for `ComPtr`. Defines which types of raw pointer can be
/// returned by `as_ptr`/`as_mut_ptr`.
pub unsafe trait AsComPtr<T> { }
impl<T: ComInterface> ComPtr<T> {
/// Constructs a new `ComPtr<T>`.
pub fn new() -> ComPtr<T> {
ComPtr { ptr: ptr::null_mut() }
}
/// Returns the raw pointer as type `U`. Depends on the `AsComPtr` trait.
pub fn as_ptr<U>(&self) -> *const U where T: AsComPtr<U> {
self.ptr as *const U
}
/// Returns a mutable reference to the raw pointer.
/// Depends on the 'AsComPtr' trait.
pub fn as_mut_ptr<U>(&mut self) -> &mut *mut U where T: AsComPtr<U> {
unsafe { mem::transmute(&mut self.ptr) }
}
/// Returns true if the contained interface pointer is null. This should
/// always be checked before calling any methods on the contained interface.
pub fn is_null(&self) -> bool {
self.ptr.is_null()
}
/// Return the IID associated with type `T`.
pub fn iid(&self) -> IID {
T::iid()
}
}
/// All types can be cast into `c_void` pointers.
unsafe impl<T: ComInterface> AsComPtr<c_void> for T { }
impl<'a, T, U> From<&'a ComPtr<T>> for ComPtr<U>
where T: ComInterface, U: ComInterface + AsComPtr<c_void> {
/// Create a `ComPtr` of a different interface type `U`. Calls
/// `IUnknown::query_interface` and returns a new `ComPtr<U>` object.
/// If the requested interface is unavailable, the returned `ComPtr<U>`
/// will contain a null pointer.
fn from(other: &'a ComPtr<T>) -> ComPtr<U> {
let mut new: ComPtr<U> = ComPtr::new();
if !other.is_null() {
unsafe {
(*other.as_ptr()).query_interface(&U::iid(), new.as_mut_ptr());
}
}
new
}
}
impl<T: ComInterface> Deref for ComPtr<T> {
type Target = T;
/// Dereference into contained interface `T` to call methods directly.
///
/// # Panics
/// If the contained pointer is null, any dereference will result in a
/// panic. Use the [`is_null`](#method.is_null) method before dereferencing.
fn deref<'a>(&'a self) -> &'a T {
assert!(!self.is_null(), "dereferenced null ComPtr");
unsafe { &*self.ptr }
}
}
impl<T: ComInterface> Clone for ComPtr<T> {
/// Clones the `ComPtr<T>`. Increments the internal reference counter by
/// calling `IUnknown::add_ref` on the contained COM object
/// (if the pointer is non-null).
fn clone(&self) -> ComPtr<T> {
if !self.is_null() {
unsafe { (*self.as_ptr()).add_ref() };
}
ComPtr { ptr: self.ptr }
}
}
impl<T: ComInterface> Drop for ComPtr<T> {
/// Drops the `ComPtr<T>`. Decrements the internal reference counter by
/// calling `IUnknown::release` on the contained COM object
/// (if the pointer is non-null).
fn drop(&mut self) {
if !self.is_null() {
unsafe { (*self.as_ptr()).release() };
}
}
}

76
third-party/vendor/com-rs/src/lib.rs vendored Normal file
View file

@ -0,0 +1,76 @@
// Copyright (c) 2016 com-rs developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
/*!
# com-rs 0.1.4
Rust bindings for the Win32 [Component Object Model]
(https://msdn.microsoft.com/en-us/library/ms680573.aspx).
# Overview
This crate is composed of three main components:
* The [`com_interface!`] (macro.com_interface!.html) macro for
defining new interface types.
* The [`ComPtr`](struct.ComPtr.html) type for making use of them.
* Definition of [`IUnknown`](struct.IUnknown.html), the base COM interface.
*/
// TODO:
// * Implement the rest of COM, this is just a tiny subset necessary to consume
// IUnknown interfaces.
// * Tests for IUnknown/ComPtr, hard to test with no way of acquiring
// IUnknown objects directly.
#![deny(dead_code)]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
use std::fmt;
pub use comptr::{AsComPtr, ComInterface, ComPtr};
pub use unknown::IUnknown;
/// Interface identifier.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(C)]
pub struct IID {
/// First component, 32-bit value.
pub data1: u32,
/// Second component, 16-bit value.
pub data2: u16,
/// Third component, 16-bit value.
pub data3: u16,
/// Fourth component, array of 8-bit values.
pub data4: [u8; 8],
}
/// Print IID in Windows registry format {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}.
impl fmt::Display for IID {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{{{:08X}-{:04X}-{:04X}-{:02X}{:02X}-\
{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}}}",
self.data1, self.data2, self.data3,
self.data4[0], self.data4[1], self.data4[2], self.data4[3],
self.data4[4], self.data4[5], self.data4[6], self.data4[7])
}
}
#[test]
fn iid_display() {
assert_eq!(IUnknown::iid().to_string(),
"{00000000-0000-0000-C000-000000000046}");
}
/// Result type.
pub type HResult = i32;
#[macro_use]
mod macros;
mod comptr;
mod unknown;

199
third-party/vendor/com-rs/src/macros.rs vendored Normal file
View file

@ -0,0 +1,199 @@
// Copyright (c) 2016 com-rs developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
/**
Macro for generating COM interface definitions.
# Usage
```
#[macro_use]
extern crate com_rs;
use com_rs::IUnknown;
iid!(IID_IFOO =
0x12345678, 0x90AB, 0xCDEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF);
com_interface! {
interface IFoo: IUnknown {
iid: IID_IFOO,
vtable: IFooVtbl,
fn foo() -> bool;
}
}
# fn main() { }
```
This example defines an interface called `IFoo`. In this case, the base type is
IUnknown, the root COM type. The IID for the interface must also be defined,
along with the name of the vtable type, `IFooVtbl`. This isn't publicly exposed,
but there is currently no way to generate an ident within a macro so the callee
must define one instead.
The trait `Foo` defines the methods available for the interface, in this case
a single method named `foo`. Note that any methods that return no value
(e.g. the `void` type in C/C++) should return the unit type `()`.
## Inheritance
To define interfaces with a deeper hierarchy, add additional parent identifiers
to the type definitions. e.g:
```
# #[macro_use]
# extern crate com_rs;
# use com_rs::IUnknown;
# iid!(IID_IFOO = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
# com_interface! {
# interface IFoo: IUnknown {
# iid: IID_IFOO,
# vtable: IFooVtbl,
# fn foo() -> bool;
# }
# }
iid!(IID_IBAR =
0x12345678, 0x90AB, 0xCDEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF);
com_interface! {
interface IBar: IFoo, IUnknown {
iid: IID_IBAR,
vtable: IBarVtbl,
fn bar(baz: i32) -> ();
}
}
# fn main() { }
```
This example defines an interface called `IBar` which extends `IFoo` from the
previous example. Note that it is necessary to specify the parent types
for both the interface and trait declarations.
The interface hierarchy automates pointer conversion using the `AsComPtr` trait,
and the trait hierarchy automatically implements the parent methods for the
child interface.
*/
#[macro_export]
macro_rules! com_interface {
(
$(#[$iface_attr:meta])*
interface $iface:ident: $base_iface:ty {
iid: $iid:ident,
vtable: $vtable:ident,
$(
$(#[$fn_attr:meta])*
fn $func:ident($($i:ident: $t:ty),*) -> $rt:ty;
)*
}
) => (
#[allow(missing_debug_implementations)]
#[doc(hidden)]
#[repr(C)]
pub struct $vtable {
base: <$base_iface as $crate::ComInterface>::Vtable,
$($func: extern "stdcall" fn(*const $iface, $($t),*) -> $rt),*
}
$(#[$iface_attr])*
#[derive(Debug)]
#[repr(C)]
pub struct $iface {
vtable: *const $vtable
}
impl $iface {
$($(#[$fn_attr])*
pub unsafe fn $func(&self, $($i: $t),*) -> $rt {
((*self.vtable).$func)(self $(,$i)*)
})*
}
impl ::std::ops::Deref for $iface {
type Target = $base_iface;
fn deref(&self) -> &$base_iface {
unsafe { ::std::mem::transmute(self) }
}
}
unsafe impl $crate::AsComPtr<$iface> for $iface {}
unsafe impl $crate::AsComPtr<$base_iface> for $iface {}
unsafe impl $crate::ComInterface for $iface {
#[doc(hidden)]
type Vtable = $vtable;
#[allow(unused_unsafe)]
fn iid() -> $crate::IID { unsafe { $iid } }
}
);
(
$(#[$iface_attr:meta])*
interface $iface:ident: $base_iface:ty, $($extra_base:ty),+ {
iid: $iid:ident,
vtable: $vtable:ident,
$(
$(#[$fn_attr:meta])*
fn $func:ident($($i:ident: $t:ty),*) -> $rt:ty;
)*
}
) => (
com_interface! {
$(#[$iface_attr])*
interface $iface: $base_iface {
iid: $iid,
vtable: $vtable,
$($(#[$fn_attr])* fn $func($($i: $t),*) -> $rt;)*
}
}
$(unsafe impl $crate::AsComPtr<$extra_base> for $iface {})*
)
}
/**
Helper macro for defining [`IID`](struct.IID.html) constants.
# Usage
```
# #[macro_use]
# extern crate com_rs;
iid!(IID_IFOO = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
# fn main() {}
```
IIDs are private by default as they are only supposed to be exposed by the
`ComPtr::iid` method. If you want to make them public, just add the `pub`
keyword before the identifier.
```
# #[macro_use]
# extern crate com_rs;
iid!(pub IID_IBAR = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
# fn main() {}
```
*/
#[macro_export]
macro_rules! iid {
($(#[$iid_attr:meta])*
$name:ident = $d1:expr, $d2:expr, $d3:expr, $($d4:expr),*) => (
$(#[$iid_attr])*
const $name: $crate::IID = $crate::IID {
data1: $d1,
data2: $d2,
data3: $d3,
data4: [$($d4),*],
};
);
($(#[$iid_attr:meta])*
pub $name:ident = $d1:expr, $d2:expr, $d3:expr, $($d4:expr),*) => (
$(#[$iid_attr])*
pub const $name: $crate::IID = $crate::IID {
data1: $d1,
data2: $d2,
data3: $d3,
data4: [$($d4),*],
};
);
}

View file

@ -0,0 +1,65 @@
// Copyright (c) 2016 com-rs developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
use std::os::raw::c_void;
use super::{AsComPtr, HResult, IID};
/// Base interface for all COM types.
///
/// None of the methods on this struct should be called directly,
/// use [`ComPtr`](struct.ComPtr.html) instead.
#[derive(Debug)]
#[repr(C)]
pub struct IUnknown {
vtable: *const IUnknownVtbl
}
#[allow(missing_debug_implementations)]
#[repr(C)]
#[doc(hidden)]
pub struct IUnknownVtbl {
query_interface: extern "stdcall" fn(
*const IUnknown, &IID, *mut *mut c_void) -> HResult,
add_ref: extern "stdcall" fn(*const IUnknown) -> u32,
release: extern "stdcall" fn(*const IUnknown) -> u32
}
extern {
static IID_IUnknown: IID;
}
impl IUnknown {
/// Retrieves pointers to the supported interfaces on an object.
/// Use [`ComPtr::from`](struct.ComPtr.html#method.from) instead.
pub unsafe fn query_interface(&self, iid: &IID, object: *mut *mut c_void)
-> HResult {
((*self.vtable).query_interface)(self, iid, object)
}
/// Increments the reference count for an interface on an object.
/// Should never need to call this directly.
pub unsafe fn add_ref(&self) -> u32 {
((*self.vtable).add_ref)(self)
}
/// Decrements the reference count for an interface on an object.
/// Should never need to call this directly.
pub unsafe fn release(&self) -> u32 {
((*self.vtable).release)(self)
}
}
unsafe impl AsComPtr<IUnknown> for IUnknown { }
unsafe impl ::ComInterface for IUnknown {
#[doc(hidden)]
type Vtable = IUnknownVtbl;
fn iid() -> ::IID { unsafe { IID_IUnknown } }
}