Skip to content

Commit

Permalink
Merge pull request #48 from Boddlnagg/winapi-update
Browse files Browse the repository at this point in the history
Update to winapi 0.3
  • Loading branch information
Boddlnagg authored Dec 21, 2017
2 parents 9d1b87b + 877b43b commit 3bdf959
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 123 deletions.
6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ license = "MIT OR Apache-2.0"
exclude = ["Generator/**"]

[dependencies]
winapi = "0.2.8"
runtimeobject-sys = "0.2.0"
ole32-sys = "0.2.0"
oleaut32-sys = "0.2.0"
winapi = { version = "0.3", features = ["winnt", "combaseapi", "oleauto", "roapi", "roerrorapi", "hstring", "winstring", "winerror", "restrictederrorinfo"] }

[features]
nightly = []
lang-compat = []
windows-applicationmodel = []
windows-data = []
windows-devices = []
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Since we can not yet guarantee the safety of the generated wrappers, all methods
Creating custom WinRT classes using inheritance is not yet supported, so it is currently not possible to create user interfaces using *XAML*.

## Prerequisites
Using this crate requires at least Rust 1.13 and the MSVC toolchain (because there is a bug in one of MinGW's import libraries).
Additional nightly features (e.g. generating enum variants as associated constants) can be enabled with the `nightly` Cargo feature.
Using this crate requires at least Rust 1.20. A compatibility mode that requires only Rust 1.15 can be enabled with the `lang-compat` Cargo feature.
Additional nightly features (e.g. using specialization) can be enabled with the `nightly` Cargo feature.

## Design
All definitions are automatically generated from *WinMD* metadata files.
Expand Down
10 changes: 4 additions & 6 deletions examples/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
extern crate winapi as w;
extern crate winrt;
// TODO: don't use functions from runtimeobject directly
extern crate runtimeobject;

use std::ptr;

Expand Down Expand Up @@ -36,8 +34,8 @@ fn run() {
println!("{}", device_selector);

unsafe {
use runtimeobject::*;
use ::w::S_OK;
use w::shared::winerror::S_OK;
use w::winrt::roerrorapi::GetRestrictedErrorInfo;

// Test some error reporting by using an invalid device selector
let wrong_deviceselector: FastHString = "Foobar".into();
Expand Down Expand Up @@ -122,7 +120,7 @@ fn run() {
let array = &mut [true, false, false, true];
let boxed_array = PropertyValue::create_boolean_array(array);
let boxed_array = boxed_array.unwrap().query_interface::<IPropertyValue>().unwrap();
assert_eq!(unsafe { boxed_array.get_type().unwrap() }, PropertyType_BooleanArray);
assert_eq!(unsafe { boxed_array.get_type().unwrap() }, PropertyType::BooleanArray);
let boxed_array = boxed_array.query_interface::<IReferenceArray<bool>>().unwrap();
let returned_array = unsafe { boxed_array.get_value().unwrap() };
println!("{:?} = {:?}", array, &returned_array[..]);
Expand All @@ -133,7 +131,7 @@ fn run() {
let array = &mut [&*str1, &*str2, &*str1, &*str2];
let boxed_array = PropertyValue::create_string_array(array);
let boxed_array = boxed_array.unwrap().query_interface::<IPropertyValue>().unwrap();
assert_eq!(unsafe { boxed_array.get_type().unwrap() }, PropertyType_StringArray);
assert_eq!(unsafe { boxed_array.get_type().unwrap() }, PropertyType::StringArray);
let boxed_array = boxed_array.query_interface::<IReferenceArray<HString>>().unwrap();
let returned_array = unsafe { boxed_array.get_value().unwrap() };
assert_eq!(array.len(), returned_array.len());
Expand Down
2 changes: 1 addition & 1 deletion examples/toast_notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn main() {

fn run() { unsafe {
// Get a toast XML template
let toast_xml = ToastNotificationManager::get_template_content(ToastTemplateType_ToastText02).unwrap();
let toast_xml = ToastNotificationManager::get_template_content(ToastTemplateType::ToastText02).unwrap();

// Fill in the text elements
let toast_text_elements = toast_xml.get_elements_by_tag_name(&FastHString::new("text")).unwrap();
Expand Down
6 changes: 4 additions & 2 deletions src/bstr.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use ::std::ptr;
use ::std::fmt;

use ::w::*;
use ::oleaut32::*;
use w::shared::wtypes::BSTR;
use w::shared::basetsd::UINT32;
use w::shared::wtypesbase::OLECHAR;
use w::um::oleauto::{SysStringLen, SysAllocStringLen, SysFreeString};

// TODO: move to separate crate?

Expand Down
15 changes: 8 additions & 7 deletions src/cominterfaces.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use ::Guid;
use Guid;
use w::um::unknwnbase::IUnknownVtbl;

/// Marker trait for all COM-compatible interfaces.
pub trait ComInterface {
Expand All @@ -20,15 +21,15 @@ pub trait ComIid {
DEFINE_IID!(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);

/// Re-export from WinAPI crate
pub type IUnknown = ::w::IUnknown;
pub type IUnknown = ::w::um::unknwnbase::IUnknown;
impl ComIid for IUnknown { #[inline] fn iid() -> &'static Guid { &IID_IUnknown } }
impl ComInterface for IUnknown { type Vtbl = ::w::IUnknownVtbl; }
impl ComInterface for IUnknown { type Vtbl = IUnknownVtbl; }

DEFINE_IID!(IID_IRestrictedErrorInfo, 0x82BA7092, 0x4C88, 0x427D, 0xA7, 0xBC, 0x16, 0xDD, 0x93, 0xFE, 0xB6, 0x7E);

/// Re-export from WinAPI crate
pub type IRestrictedErrorInfo = ::w::IRestrictedErrorInfo;
pub type IRestrictedErrorInfoVtbl = ::w::IRestrictedErrorInfoVtbl;
pub type IRestrictedErrorInfo = ::w::um::restrictederrorinfo::IRestrictedErrorInfo;
pub type IRestrictedErrorInfoVtbl = ::w::um::restrictederrorinfo::IRestrictedErrorInfoVtbl;
impl ComIid for IRestrictedErrorInfo { #[inline] fn iid() -> &'static Guid { &IID_IRestrictedErrorInfo } }
impl ComInterface for IRestrictedErrorInfo { type Vtbl = IRestrictedErrorInfoVtbl; }

Expand All @@ -38,7 +39,7 @@ DEFINE_IID!(IID_IAgileObject, 0x94EA2B94, 0xE9CC, 0x49E0, 0xC0, 0xFF, 0xEE, 0x64
/// It inherits from `IUnknown` and does not have additional members.
#[repr(C)] #[derive(Debug)]
pub struct IAgileObject {
lpVtbl: *const ::w::IUnknownVtbl // IAgileObject has no methods besides what IUnknown has
lpVtbl: *const IUnknownVtbl // IAgileObject has no methods besides what IUnknown has
}
impl ::std::ops::Deref for IAgileObject {
type Target = IUnknown;
Expand All @@ -54,4 +55,4 @@ impl ::std::ops::DerefMut for IAgileObject {
}
}
impl ComIid for IAgileObject { #[inline] fn iid() -> &'static Guid { &IID_IAgileObject } }
impl ComInterface for IAgileObject { type Vtbl = ::w::IUnknownVtbl; }
impl ComInterface for IAgileObject { type Vtbl = IUnknownVtbl; }
18 changes: 12 additions & 6 deletions src/comptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ use std::fmt;
use std::ptr;
use ::{ComIid, ComInterface, RtInterface, RtClassInterface, IInspectable, Guid};

use w::shared::ntdef::VOID;
use w::shared::minwindef::LPVOID;
use w::shared::winerror::S_OK;
use w::um::unknwnbase::IUnknown;
use w::um::combaseapi::CoTaskMemFree;

/// Smart pointer for Windows Runtime objects. This pointer automatically maintains the
/// reference count of the underlying COM object.
#[repr(C)] #[derive(Debug)]
Expand All @@ -19,11 +25,11 @@ impl<T> fmt::Pointer for ComPtr<T> {
#[inline]
pub fn query_interface<T, Target>(interface: &T) -> Option<ComPtr<Target>> where Target: ComIid, T: ComInterface {
let iid: &'static Guid = Target::iid();
let as_unknown = unsafe { &mut *(interface as *const T as *mut T as *mut ::w::IUnknown) };
let as_unknown = unsafe { &mut *(interface as *const T as *mut T as *mut IUnknown) };
let mut res = ptr::null_mut();
unsafe {
match as_unknown.QueryInterface(iid.as_ref(), &mut res as *mut _ as *mut *mut ::w::VOID) {
::w::S_OK => Some(ComPtr::wrap(res)),
match as_unknown.QueryInterface(iid.as_ref(), &mut res as *mut _ as *mut *mut VOID) {
S_OK => Some(ComPtr::wrap(res)),
_ => None
}
}
Expand Down Expand Up @@ -53,8 +59,8 @@ impl<T> ComPtr<T> {

/// Returns the underlying WinRT or COM object as a reference to an `IUnknown` object.
#[inline]
fn as_unknown(&self) -> &mut ::w::IUnknown {
unsafe { &mut *(self.0 as *mut ::w::IUnknown) }
fn as_unknown(&self) -> &mut IUnknown {
unsafe { &mut *(self.0 as *mut IUnknown) }
}

/// Changes the type of the underlying COM object to a different interface without doing `QueryInterface`.
Expand Down Expand Up @@ -173,7 +179,7 @@ impl<T> Drop for ComArray<T> where T: ::RtType {
fn drop(&mut self) {
unsafe {
::std::ptr::drop_in_place(&mut self[..]);
::ole32::CoTaskMemFree(self.first as ::w::LPVOID)
CoTaskMemFree(self.first as LPVOID)
};
}
}
Expand Down
10 changes: 6 additions & 4 deletions src/guid.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::{fmt, cmp, mem};

use w::shared::guiddef::GUID;

/// Represents a GUID type in the Windows Runtime type system.
#[derive(Copy, Clone)]
#[repr(C)]
Expand All @@ -10,16 +12,16 @@ pub struct Guid { // TODO: fields should not be public (requires const fn constr
pub Data4: [u8; 8]
}

impl AsRef<::w::GUID> for Guid {
impl AsRef<GUID> for Guid {
#[inline]
fn as_ref(&self) -> &::w::GUID {
fn as_ref(&self) -> &GUID {
unsafe { mem::transmute(self) }
}
}

impl From<::w::GUID> for Guid {
impl From<GUID> for Guid {
#[inline]
fn from(guid: ::w::GUID) -> Self {
fn from(guid: GUID) -> Self {
unsafe { mem::transmute(guid) }
}
}
Expand Down
40 changes: 17 additions & 23 deletions src/hstring.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use ::std::ptr;
use ::std::fmt;
use ::std::cmp;
use ::std::mem;
use ::std::marker::PhantomData;
use ::std::ops::Deref;

use ::w::*;
use ::runtimeobject::*;
use std::ptr;
use std::fmt;
use std::cmp;
use std::mem;
use std::marker::PhantomData;
use std::ops::Deref;

use w::shared::basetsd::UINT32;
use w::shared::ntdef::LPCWSTR;
use w::shared::winerror::S_OK;
use w::winrt::hstring::{HSTRING, HSTRING__, HSTRING_HEADER};
use w::winrt::winstring::{WindowsCreateString, WindowsGetStringLen, WindowsIsStringEmpty,
WindowsGetStringRawBuffer, WindowsCreateStringReference,
WindowsDuplicateString, WindowsDeleteString, WindowsCompareStringOrdinal};

// For some information about HSTRINGs, see http://ksav.com.np/tech/2016/06/16/raymonds-complete-guide-to-hstring-semantics/

Expand Down Expand Up @@ -34,20 +39,9 @@ fn internal_cmp(left: HSTRING, right: HSTRING) -> cmp::Ordering {
}

#[inline]
#[cfg(target_arch = "x86_64")]
fn zero_header() -> HSTRING_HEADER {
HSTRING_HEADER {
Reserved: [ptr::null_mut(); 0],
Reserved2: [0; 24]
}
}

#[inline]
#[cfg(target_arch = "x86")]
fn zero_header() -> HSTRING_HEADER {
HSTRING_HEADER {
Reserved: [ptr::null_mut(); 0],
Reserved2: [0; 20]
Reserved: unsafe { mem::zeroed() }
}
}

Expand Down Expand Up @@ -569,8 +563,8 @@ mod tests {
#[test]
fn check_sizes() {
use ::std::mem::size_of;
assert_eq!(size_of::<::HString>(), size_of::<::w::HSTRING>());
assert_eq!(size_of::<&::HStringArg>(), size_of::<::w::HSTRING>());
assert_eq!(size_of::<::HString>(), size_of::<::w::winrt::hstring::HSTRING>());
assert_eq!(size_of::<&::HStringArg>(), size_of::<::w::winrt::hstring::HSTRING>());
}

#[test]
Expand Down
23 changes: 16 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,16 @@
#![cfg_attr(test,feature(test))]

#![cfg_attr(feature = "nightly", feature(specialization))]
#![cfg_attr(feature = "nightly", feature(associated_consts))]

#![allow(dead_code,non_upper_case_globals,non_snake_case)]

extern crate winapi as w;
extern crate runtimeobject;
extern crate ole32;
extern crate oleaut32;

mod guid;
pub use guid::Guid;

///Represents the trust level of an activatable class (re-export from WinAPI crate)
pub type TrustLevel = ::w::TrustLevel;
pub type TrustLevel = ::w::winrt::inspectable::TrustLevel;

// Compared to the DEFINE_GUID macro from winapi, this one creates a private const
macro_rules! DEFINE_IID {
Expand Down Expand Up @@ -85,7 +81,9 @@ mod prelude {
pub use ::comptr::{ComPtr, ComArray};
pub use ::hstring::{HString, HStringArg};
pub use ::result::{Result, HRESULT};
pub use ::w::{IUnknownVtbl, S_OK, HSTRING};
pub use ::w::winrt::hstring::HSTRING;
pub use ::w::shared::winerror::S_OK;
pub use ::w::um::unknwnbase::IUnknownVtbl;
pub use ::std::ptr::null_mut;
pub use ::std::mem::zeroed;
pub use ::guid::Guid;
Expand All @@ -94,4 +92,15 @@ mod prelude {
pub fn err<T>(hr: ::result::HRESULT) -> ::result::Result<T> {
Err(::result::Error::from_hresult(hr))
}
}
}

// For definitions that are different depending on the lang-compat feature
#[cfg(not(feature = "lang-compat"))]
mod langcompat {
pub const ASYNC_STATUS_COMPLETED: ::windows::foundation::AsyncStatus = ::windows::foundation::AsyncStatus::Completed;
}

#[cfg(feature = "lang-compat")]
mod langcompat {
pub const ASYNC_STATUS_COMPLETED: ::windows::foundation::AsyncStatus = ::windows::foundation::AsyncStatus_Completed;
}
52 changes: 27 additions & 25 deletions src/result.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Re-export from WinAPI crate
pub type HRESULT = ::w::HRESULT;
pub type HRESULT = ::w::um::winnt::HRESULT;

// TODO: add more codes from https://msdn.microsoft.com/en-us/library/windows/desktop/dd542643(v=vs.85).aspx, especially the `RO_`-prefixed

Expand All @@ -25,41 +25,43 @@ impl Error {
#[inline]
pub fn from_hresult(hr: HRESULT) -> Error {
use Error::*;
use ::w::shared::winerror::*;

match hr {
::w::E_ABORT => OperationAborted,
::w::E_ACCESSDENIED => AccessDenied,
::w::E_FAIL => UnspecifiedFailure,
::w::E_HANDLE => InvalidHandle,
::w::E_INVALIDARG => InvalidArgument,
::w::E_NOINTERFACE => NoSuchInterface,
::w::E_NOTIMPL => NotImplemented,
::w::E_OUTOFMEMORY => OutOfMemory,
::w::E_POINTER => InvalidPointer,
::w::E_UNEXPECTED => UnexpectedFailure,
::w::E_BOUNDS => OutOfBounds,
::w::E_ILLEGAL_METHOD_CALL => IllegalMethodCall,
E_ABORT => OperationAborted,
E_ACCESSDENIED => AccessDenied,
E_FAIL => UnspecifiedFailure,
E_HANDLE => InvalidHandle,
E_INVALIDARG => InvalidArgument,
E_NOINTERFACE => NoSuchInterface,
E_NOTIMPL => NotImplemented,
E_OUTOFMEMORY => OutOfMemory,
E_POINTER => InvalidPointer,
E_UNEXPECTED => UnexpectedFailure,
E_BOUNDS => OutOfBounds,
E_ILLEGAL_METHOD_CALL => IllegalMethodCall,
_ => Other(hr)
}
}

#[inline]
pub fn as_hresult(&self) -> HRESULT {
use Error::*;
use ::w::shared::winerror::*;

match *self {
OperationAborted => ::w::E_ABORT,
AccessDenied => ::w::E_ACCESSDENIED,
UnspecifiedFailure => ::w::E_FAIL,
InvalidHandle => ::w::E_HANDLE,
InvalidArgument => ::w::E_INVALIDARG,
NoSuchInterface => ::w::E_NOINTERFACE,
NotImplemented => ::w::E_NOTIMPL,
OutOfMemory => ::w::E_OUTOFMEMORY,
InvalidPointer => ::w::E_POINTER,
UnexpectedFailure => ::w::E_UNEXPECTED,
OutOfBounds => ::w::E_BOUNDS,
IllegalMethodCall => ::w::E_ILLEGAL_METHOD_CALL,
OperationAborted => E_ABORT,
AccessDenied => E_ACCESSDENIED,
UnspecifiedFailure => E_FAIL,
InvalidHandle => E_HANDLE,
InvalidArgument => E_INVALIDARG,
NoSuchInterface => E_NOINTERFACE,
NotImplemented => E_NOTIMPL,
OutOfMemory => E_OUTOFMEMORY,
InvalidPointer => E_POINTER,
UnexpectedFailure => E_UNEXPECTED,
OutOfBounds => E_BOUNDS,
IllegalMethodCall => E_ILLEGAL_METHOD_CALL,
Other(hr) => hr,
}
}
Expand Down
Loading

0 comments on commit 3bdf959

Please sign in to comment.