diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 5a0cccd159..e5ac894355 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -121,6 +121,7 @@ jobs: cargo clippy -p test_sys && cargo clippy -p test_targets && cargo clippy -p test_unions && + cargo clippy -p test_variant && cargo clippy -p test_wdk && cargo clippy -p test_weak && cargo clippy -p test_weak_ref && diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ce1da057fc..f945de9eeb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -100,8 +100,8 @@ jobs: cargo test -p test_enums && cargo test -p test_error && cargo test -p test_event && - cargo clean && cargo test -p test_extensions && + cargo clean && cargo test -p test_handles && cargo test -p test_helpers && cargo test -p test_implement && @@ -129,6 +129,7 @@ jobs: cargo test -p test_sys && cargo test -p test_targets && cargo test -p test_unions && + cargo test -p test_variant && cargo test -p test_wdk && cargo test -p test_weak && cargo test -p test_weak_ref && diff --git a/crates/libs/bindgen/src/rust/standalone.rs b/crates/libs/bindgen/src/rust/standalone.rs index 21daa55180..f77479aaa1 100644 --- a/crates/libs/bindgen/src/rust/standalone.rs +++ b/crates/libs/bindgen/src/rust/standalone.rs @@ -145,12 +145,10 @@ fn type_collect_standalone(ty: &metadata::Type, set: &mut std::collections::BTre return; } - let metadata::Type::TypeDef(def, generics) = &ty else { + let metadata::Type::TypeDef(def, generics) = ty.to_underlying_type() else { return; }; - let def = *def; - // Ensure that we collect all the typedefs of the same name. We need to // do this in the case where the user specifies a top level item that // references a typedef by name, but that name resolves to more than 1 @@ -167,7 +165,7 @@ fn type_collect_standalone(ty: &metadata::Type, set: &mut std::collections::BTre } } - for generic in generics { + for generic in &generics { type_collect_standalone(generic, set); } for field in def.fields() { @@ -184,7 +182,7 @@ fn type_collect_standalone(ty: &metadata::Type, set: &mut std::collections::BTre if method.name() == ".ctor" { continue; } - let signature = metadata::method_def_signature(def.namespace(), method, generics); + let signature = metadata::method_def_signature(def.namespace(), method, &generics); type_collect_standalone(&signature.return_type, set); signature.params.iter().for_each(|param| type_collect_standalone(¶m.ty, set)); } @@ -204,7 +202,7 @@ fn type_collect_standalone_nested(td: metadata::TypeDef, set: &mut std::collecti for field in nested.fields() { let ty = field.ty(Some(nested)); - if let metadata::Type::TypeDef(def, _) = &ty { + if let metadata::Type::TypeDef(def, _) = ty.to_underlying_type() { // Skip the fields that actually refer to the anonymous nested // type, otherwise it will get added to the typeset and emitted if def.namespace().is_empty() { diff --git a/crates/libs/core/src/imp/bindings.rs b/crates/libs/core/src/imp/bindings.rs index 43aa01c714..e6f849731b 100644 --- a/crates/libs/core/src/imp/bindings.rs +++ b/crates/libs/core/src/imp/bindings.rs @@ -16,28 +16,729 @@ ::windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT); ::windows_targets::link!("ole32.dll" "system" fn CoTaskMemAlloc(cb : usize) -> *mut ::core::ffi::c_void); ::windows_targets::link!("ole32.dll" "system" fn CoTaskMemFree(pv : *const ::core::ffi::c_void)); +::windows_targets::link!("ole32.dll" "system" fn PropVariantClear(pvar : *mut PROPVARIANT) -> HRESULT); ::windows_targets::link!("oleaut32.dll" "system" fn SysAllocStringLen(strin : PCWSTR, ui : u32) -> BSTR); ::windows_targets::link!("oleaut32.dll" "system" fn SysFreeString(bstrstring : BSTR)); ::windows_targets::link!("oleaut32.dll" "system" fn SysStringLen(pbstr : BSTR) -> u32); +::windows_targets::link!("oleaut32.dll" "system" fn VariantClear(pvarg : *mut VARIANT) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToBSTR(propvar : *const PROPVARIANT, pbstrout : *mut BSTR) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToBoolean(propvarin : *const PROPVARIANT, pfret : *mut BOOL) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToDouble(propvarin : *const PROPVARIANT, pdblret : *mut f64) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToInt16(propvarin : *const PROPVARIANT, piret : *mut i16) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToInt32(propvarin : *const PROPVARIANT, plret : *mut i32) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToInt64(propvarin : *const PROPVARIANT, pllret : *mut i64) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToUInt16(propvarin : *const PROPVARIANT, puiret : *mut u16) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToUInt32(propvarin : *const PROPVARIANT, pulret : *mut u32) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToUInt64(propvarin : *const PROPVARIANT, pullret : *mut u64) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn PropVariantToVariant(ppropvar : *const PROPVARIANT, pvar : *mut VARIANT) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToBoolean(varin : *const VARIANT, pfret : *mut BOOL) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToDouble(varin : *const VARIANT, pdblret : *mut f64) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToInt16(varin : *const VARIANT, piret : *mut i16) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToInt32(varin : *const VARIANT, plret : *mut i32) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToInt64(varin : *const VARIANT, pllret : *mut i64) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToPropVariant(pvar : *const VARIANT, ppropvar : *mut PROPVARIANT) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToUInt16(varin : *const VARIANT, puiret : *mut u16) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToUInt32(varin : *const VARIANT, pulret : *mut u32) -> HRESULT); +::windows_targets::link!("propsys.dll" "system" fn VariantToUInt64(varin : *const VARIANT, pullret : *mut u64) -> HRESULT); +pub type ADVANCED_FEATURE_FLAGS = u16; +#[repr(C)] +pub struct ARRAYDESC { + pub tdescElem: TYPEDESC, + pub cDims: u16, + pub rgbounds: [SAFEARRAYBOUND; 1], +} +impl ::core::marker::Copy for ARRAYDESC {} +impl ::core::clone::Clone for ARRAYDESC { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union BINDPTR { + pub lpfuncdesc: *mut FUNCDESC, + pub lpvardesc: *mut VARDESC, + pub lptcomp: ITypeComp, +} +impl ::core::marker::Copy for BINDPTR {} +impl ::core::clone::Clone for BINDPTR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct BLOB { + pub cbSize: u32, + pub pBlobData: *mut u8, +} +impl ::core::marker::Copy for BLOB {} +impl ::core::clone::Clone for BLOB { + fn clone(&self) -> Self { + *self + } +} pub type BOOL = i32; pub type BSTR = *const u16; +#[repr(C)] +pub struct BSTRBLOB { + pub cbSize: u32, + pub pData: *mut u8, +} +impl ::core::marker::Copy for BSTRBLOB {} +impl ::core::clone::Clone for BSTRBLOB { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CABOOL { + pub cElems: u32, + pub pElems: *mut VARIANT_BOOL, +} +impl ::core::marker::Copy for CABOOL {} +impl ::core::clone::Clone for CABOOL { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CABSTR { + pub cElems: u32, + pub pElems: *mut BSTR, +} +impl ::core::marker::Copy for CABSTR {} +impl ::core::clone::Clone for CABSTR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CABSTRBLOB { + pub cElems: u32, + pub pElems: *mut BSTRBLOB, +} +impl ::core::marker::Copy for CABSTRBLOB {} +impl ::core::clone::Clone for CABSTRBLOB { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAC { + pub cElems: u32, + pub pElems: PSTR, +} +impl ::core::marker::Copy for CAC {} +impl ::core::clone::Clone for CAC { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CACLIPDATA { + pub cElems: u32, + pub pElems: *mut CLIPDATA, +} +impl ::core::marker::Copy for CACLIPDATA {} +impl ::core::clone::Clone for CACLIPDATA { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CACLSID { + pub cElems: u32, + pub pElems: *mut GUID, +} +impl ::core::marker::Copy for CACLSID {} +impl ::core::clone::Clone for CACLSID { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CACY { + pub cElems: u32, + pub pElems: *mut CY, +} +impl ::core::marker::Copy for CACY {} +impl ::core::clone::Clone for CACY { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CADATE { + pub cElems: u32, + pub pElems: *mut f64, +} +impl ::core::marker::Copy for CADATE {} +impl ::core::clone::Clone for CADATE { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CADBL { + pub cElems: u32, + pub pElems: *mut f64, +} +impl ::core::marker::Copy for CADBL {} +impl ::core::clone::Clone for CADBL { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAFILETIME { + pub cElems: u32, + pub pElems: *mut FILETIME, +} +impl ::core::marker::Copy for CAFILETIME {} +impl ::core::clone::Clone for CAFILETIME { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAFLT { + pub cElems: u32, + pub pElems: *mut f32, +} +impl ::core::marker::Copy for CAFLT {} +impl ::core::clone::Clone for CAFLT { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAH { + pub cElems: u32, + pub pElems: *mut i64, +} +impl ::core::marker::Copy for CAH {} +impl ::core::clone::Clone for CAH { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAI { + pub cElems: u32, + pub pElems: *mut i16, +} +impl ::core::marker::Copy for CAI {} +impl ::core::clone::Clone for CAI { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAL { + pub cElems: u32, + pub pElems: *mut i32, +} +impl ::core::marker::Copy for CAL {} +impl ::core::clone::Clone for CAL { + fn clone(&self) -> Self { + *self + } +} +pub type CALLCONV = i32; +#[repr(C)] +pub struct CALPSTR { + pub cElems: u32, + pub pElems: *mut PSTR, +} +impl ::core::marker::Copy for CALPSTR {} +impl ::core::clone::Clone for CALPSTR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CALPWSTR { + pub cElems: u32, + pub pElems: *mut PWSTR, +} +impl ::core::marker::Copy for CALPWSTR {} +impl ::core::clone::Clone for CALPWSTR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAPROPVARIANT { + pub cElems: u32, + pub pElems: *mut PROPVARIANT, +} +impl ::core::marker::Copy for CAPROPVARIANT {} +impl ::core::clone::Clone for CAPROPVARIANT { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CASCODE { + pub cElems: u32, + pub pElems: *mut i32, +} +impl ::core::marker::Copy for CASCODE {} +impl ::core::clone::Clone for CASCODE { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAUB { + pub cElems: u32, + pub pElems: *mut u8, +} +impl ::core::marker::Copy for CAUB {} +impl ::core::clone::Clone for CAUB { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAUH { + pub cElems: u32, + pub pElems: *mut u64, +} +impl ::core::marker::Copy for CAUH {} +impl ::core::clone::Clone for CAUH { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAUI { + pub cElems: u32, + pub pElems: *mut u16, +} +impl ::core::marker::Copy for CAUI {} +impl ::core::clone::Clone for CAUI { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CAUL { + pub cElems: u32, + pub pElems: *mut u32, +} +impl ::core::marker::Copy for CAUL {} +impl ::core::clone::Clone for CAUL { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CLIPDATA { + pub cbSize: u32, + pub ulClipFmt: i32, + pub pClipData: *mut u8, +} +impl ::core::marker::Copy for CLIPDATA {} +impl ::core::clone::Clone for CLIPDATA { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union CY { + pub Anonymous: CY_0, + pub int64: i64, +} +impl ::core::marker::Copy for CY {} +impl ::core::clone::Clone for CY { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct CY_0 { + pub Lo: u32, + pub Hi: i32, +} +impl ::core::marker::Copy for CY_0 {} +impl ::core::clone::Clone for CY_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct DECIMAL { + pub wReserved: u16, + pub Anonymous1: DECIMAL_0, + pub Hi32: u32, + pub Anonymous2: DECIMAL_1, +} +impl ::core::marker::Copy for DECIMAL {} +impl ::core::clone::Clone for DECIMAL { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union DECIMAL_0 { + pub Anonymous: DECIMAL_0_0, + pub signscale: u16, +} +impl ::core::marker::Copy for DECIMAL_0 {} +impl ::core::clone::Clone for DECIMAL_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct DECIMAL_0_0 { + pub scale: u8, + pub sign: u8, +} +impl ::core::marker::Copy for DECIMAL_0_0 {} +impl ::core::clone::Clone for DECIMAL_0_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union DECIMAL_1 { + pub Anonymous: DECIMAL_1_0, + pub Lo64: u64, +} +impl ::core::marker::Copy for DECIMAL_1 {} +impl ::core::clone::Clone for DECIMAL_1 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct DECIMAL_1_0 { + pub Lo32: u32, + pub Mid32: u32, +} +impl ::core::marker::Copy for DECIMAL_1_0 {} +impl ::core::clone::Clone for DECIMAL_1_0 { + fn clone(&self) -> Self { + *self + } +} +pub type DESCKIND = i32; +pub type DISPATCH_FLAGS = u16; +#[repr(C)] +pub struct DISPPARAMS { + pub rgvarg: *mut VARIANT, + pub rgdispidNamedArgs: *mut i32, + pub cArgs: u32, + pub cNamedArgs: u32, +} +impl ::core::marker::Copy for DISPPARAMS {} +impl ::core::clone::Clone for DISPPARAMS { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct ELEMDESC { + pub tdesc: TYPEDESC, + pub Anonymous: ELEMDESC_0, +} +impl ::core::marker::Copy for ELEMDESC {} +impl ::core::clone::Clone for ELEMDESC { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union ELEMDESC_0 { + pub idldesc: IDLDESC, + pub paramdesc: PARAMDESC, +} +impl ::core::marker::Copy for ELEMDESC_0 {} +impl ::core::clone::Clone for ELEMDESC_0 { + fn clone(&self) -> Self { + *self + } +} pub const ERROR_NO_UNICODE_TRANSLATION: WIN32_ERROR = 1113u32; +#[repr(C)] +pub struct EXCEPINFO { + pub wCode: u16, + pub wReserved: u16, + pub bstrSource: BSTR, + pub bstrDescription: BSTR, + pub bstrHelpFile: BSTR, + pub dwHelpContext: u32, + pub pvReserved: *mut ::core::ffi::c_void, + pub pfnDeferredFillIn: LPEXCEPFINO_DEFERRED_FILLIN, + pub scode: i32, +} +impl ::core::marker::Copy for EXCEPINFO {} +impl ::core::clone::Clone for EXCEPINFO { + fn clone(&self) -> Self { + *self + } +} pub const E_INVALIDARG: HRESULT = -2147024809i32; pub type FARPROC = ::core::option::Option isize>; +#[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 + } +} pub const FORMAT_MESSAGE_ALLOCATE_BUFFER: FORMAT_MESSAGE_OPTIONS = 256u32; pub const FORMAT_MESSAGE_FROM_SYSTEM: FORMAT_MESSAGE_OPTIONS = 4096u32; pub const FORMAT_MESSAGE_IGNORE_INSERTS: FORMAT_MESSAGE_OPTIONS = 512u32; pub type FORMAT_MESSAGE_OPTIONS = u32; +#[repr(C)] +pub struct FUNCDESC { + pub memid: i32, + pub lprgscode: *mut i32, + pub lprgelemdescParam: *mut ELEMDESC, + pub funckind: FUNCKIND, + pub invkind: INVOKEKIND, + pub callconv: CALLCONV, + pub cParams: i16, + pub cParamsOpt: i16, + pub oVft: i16, + pub cScodes: i16, + pub elemdescFunc: ELEMDESC, + pub wFuncFlags: FUNCFLAGS, +} +impl ::core::marker::Copy for FUNCDESC {} +impl ::core::clone::Clone for FUNCDESC { + fn clone(&self) -> Self { + *self + } +} +pub type FUNCFLAGS = u16; +pub type FUNCKIND = i32; +#[repr(C)] +pub struct GUID { + pub data1: u32, + pub data2: u16, + pub data3: u16, + pub data4: [u8; 8], +} +impl ::core::marker::Copy for GUID {} +impl ::core::clone::Clone for GUID { + fn clone(&self) -> Self { + *self + } +} +impl GUID { + pub const fn from_u128(uuid: u128) -> Self { + Self { data1: (uuid >> 96) as u32, data2: (uuid >> 80 & 0xffff) as u16, data3: (uuid >> 64 & 0xffff) as u16, data4: (uuid as u64).to_be_bytes() } + } +} pub type HANDLE = isize; pub type HEAP_FLAGS = u32; pub type HMODULE = isize; pub type HRESULT = i32; +#[repr(C)] +pub struct IDLDESC { + pub dwReserved: usize, + pub wIDLFlags: IDLFLAGS, +} +impl ::core::marker::Copy for IDLDESC {} +impl ::core::clone::Clone for IDLDESC { + fn clone(&self) -> Self { + *self + } +} +pub type IDLFLAGS = u16; +pub type IDispatch = *mut ::core::ffi::c_void; +pub type IEnumSTATSTG = *mut ::core::ffi::c_void; +pub type IMPLTYPEFLAGS = i32; +pub type INVOKEKIND = i32; +pub type IRecordInfo = *mut ::core::ffi::c_void; +pub type ISequentialStream = *mut ::core::ffi::c_void; +pub type IStorage = *mut ::core::ffi::c_void; +pub type IStream = *mut ::core::ffi::c_void; +pub type ITypeComp = *mut ::core::ffi::c_void; +pub type ITypeInfo = *mut ::core::ffi::c_void; +pub type ITypeLib = *mut ::core::ffi::c_void; +pub type IUnknown = *mut ::core::ffi::c_void; pub type LOAD_LIBRARY_FLAGS = u32; pub const LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: LOAD_LIBRARY_FLAGS = 4096u32; +pub type LPEXCEPFINO_DEFERRED_FILLIN = ::core::option::Option HRESULT>; +#[repr(C)] +pub struct PARAMDESC { + pub pparamdescex: *mut PARAMDESCEX, + pub wParamFlags: PARAMFLAGS, +} +impl ::core::marker::Copy for PARAMDESC {} +impl ::core::clone::Clone for PARAMDESC { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct PARAMDESCEX { + pub cBytes: u32, + pub varDefaultValue: VARIANT, +} +impl ::core::marker::Copy for PARAMDESCEX {} +impl ::core::clone::Clone for PARAMDESCEX { + fn clone(&self) -> Self { + *self + } +} +pub type PARAMFLAGS = u16; pub type PCSTR = *const u8; pub type PCWSTR = *const u16; +#[repr(C)] +pub struct PROPVARIANT { + pub Anonymous: PROPVARIANT_0, +} +impl ::core::marker::Copy for PROPVARIANT {} +impl ::core::clone::Clone for PROPVARIANT { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union PROPVARIANT_0 { + pub Anonymous: PROPVARIANT_0_0, + pub decVal: DECIMAL, +} +impl ::core::marker::Copy for PROPVARIANT_0 {} +impl ::core::clone::Clone for PROPVARIANT_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct PROPVARIANT_0_0 { + pub vt: VARENUM, + pub wReserved1: u16, + pub wReserved2: u16, + pub wReserved3: u16, + pub Anonymous: PROPVARIANT_0_0_0, +} +impl ::core::marker::Copy for PROPVARIANT_0_0 {} +impl ::core::clone::Clone for PROPVARIANT_0_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union PROPVARIANT_0_0_0 { + pub cVal: u8, + pub bVal: u8, + pub iVal: i16, + pub uiVal: u16, + pub lVal: i32, + pub ulVal: u32, + pub intVal: i32, + pub uintVal: u32, + pub hVal: i64, + pub uhVal: u64, + pub fltVal: f32, + pub dblVal: f64, + pub boolVal: VARIANT_BOOL, + pub __OBSOLETE__VARIANT_BOOL: VARIANT_BOOL, + pub scode: i32, + pub cyVal: CY, + pub date: f64, + pub filetime: FILETIME, + pub puuid: *mut GUID, + pub pclipdata: *mut CLIPDATA, + pub bstrVal: BSTR, + pub bstrblobVal: BSTRBLOB, + pub blob: BLOB, + pub pszVal: PSTR, + pub pwszVal: PWSTR, + pub punkVal: IUnknown, + pub pdispVal: IDispatch, + pub pStream: IStream, + pub pStorage: IStorage, + pub pVersionedStream: *mut VERSIONEDSTREAM, + pub parray: *mut SAFEARRAY, + pub cac: CAC, + pub caub: CAUB, + pub cai: CAI, + pub caui: CAUI, + pub cal: CAL, + pub caul: CAUL, + pub cah: CAH, + pub cauh: CAUH, + pub caflt: CAFLT, + pub cadbl: CADBL, + pub cabool: CABOOL, + pub cascode: CASCODE, + pub cacy: CACY, + pub cadate: CADATE, + pub cafiletime: CAFILETIME, + pub cauuid: CACLSID, + pub caclipdata: CACLIPDATA, + pub cabstr: CABSTR, + pub cabstrblob: CABSTRBLOB, + pub calpstr: CALPSTR, + pub calpwstr: CALPWSTR, + pub capropvar: CAPROPVARIANT, + pub pcVal: PSTR, + pub pbVal: *mut u8, + pub piVal: *mut i16, + pub puiVal: *mut u16, + pub plVal: *mut i32, + pub pulVal: *mut u32, + pub pintVal: *mut i32, + pub puintVal: *mut u32, + pub pfltVal: *mut f32, + pub pdblVal: *mut f64, + pub pboolVal: *mut VARIANT_BOOL, + pub pdecVal: *mut DECIMAL, + pub pscode: *mut i32, + pub pcyVal: *mut CY, + pub pdate: *mut f64, + pub pbstrVal: *mut BSTR, + pub ppunkVal: *mut IUnknown, + pub ppdispVal: *mut IDispatch, + pub pparray: *mut *mut SAFEARRAY, + pub pvarVal: *mut PROPVARIANT, +} +impl ::core::marker::Copy for PROPVARIANT_0_0_0 {} +impl ::core::clone::Clone for PROPVARIANT_0_0_0 { + fn clone(&self) -> Self { + *self + } +} +pub type PSTR = *mut u8; pub type PWSTR = *mut u16; #[repr(C)] +pub struct SAFEARRAY { + pub cDims: u16, + pub fFeatures: ADVANCED_FEATURE_FLAGS, + pub cbElements: u32, + pub cLocks: u32, + pub pvData: *mut ::core::ffi::c_void, + pub rgsabound: [SAFEARRAYBOUND; 1], +} +impl ::core::marker::Copy for SAFEARRAY {} +impl ::core::clone::Clone for SAFEARRAY { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct SAFEARRAYBOUND { + pub cElements: u32, + pub lLbound: i32, +} +impl ::core::marker::Copy for SAFEARRAYBOUND {} +impl ::core::clone::Clone for SAFEARRAYBOUND { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] pub struct SECURITY_ATTRIBUTES { pub nLength: u32, pub lpSecurityDescriptor: *mut ::core::ffi::c_void, @@ -49,5 +750,249 @@ impl ::core::clone::Clone for SECURITY_ATTRIBUTES { *self } } +#[repr(C)] +pub struct STATSTG { + pub pwcsName: PWSTR, + pub r#type: u32, + pub cbSize: u64, + pub mtime: FILETIME, + pub ctime: FILETIME, + pub atime: FILETIME, + pub grfMode: STGM, + pub grfLocksSupported: u32, + pub clsid: GUID, + pub grfStateBits: u32, + pub reserved: u32, +} +impl ::core::marker::Copy for STATSTG {} +impl ::core::clone::Clone for STATSTG { + fn clone(&self) -> Self { + *self + } +} +pub type STGM = u32; +pub type STREAM_SEEK = u32; +pub type SYSKIND = i32; +#[repr(C)] +pub struct TLIBATTR { + pub guid: GUID, + pub lcid: u32, + pub syskind: SYSKIND, + pub wMajorVerNum: u16, + pub wMinorVerNum: u16, + pub wLibFlags: u16, +} +impl ::core::marker::Copy for TLIBATTR {} +impl ::core::clone::Clone for TLIBATTR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct TYPEATTR { + pub guid: GUID, + pub lcid: u32, + pub dwReserved: u32, + pub memidConstructor: i32, + pub memidDestructor: i32, + pub lpstrSchema: PWSTR, + pub cbSizeInstance: u32, + pub typekind: TYPEKIND, + pub cFuncs: u16, + pub cVars: u16, + pub cImplTypes: u16, + pub cbSizeVft: u16, + pub cbAlignment: u16, + pub wTypeFlags: u16, + pub wMajorVerNum: u16, + pub wMinorVerNum: u16, + pub tdescAlias: TYPEDESC, + pub idldescType: IDLDESC, +} +impl ::core::marker::Copy for TYPEATTR {} +impl ::core::clone::Clone for TYPEATTR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct TYPEDESC { + pub Anonymous: TYPEDESC_0, + pub vt: VARENUM, +} +impl ::core::marker::Copy for TYPEDESC {} +impl ::core::clone::Clone for TYPEDESC { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union TYPEDESC_0 { + pub lptdesc: *mut TYPEDESC, + pub lpadesc: *mut ARRAYDESC, + pub hreftype: u32, +} +impl ::core::marker::Copy for TYPEDESC_0 {} +impl ::core::clone::Clone for TYPEDESC_0 { + fn clone(&self) -> Self { + *self + } +} +pub type TYPEKIND = i32; +#[repr(C)] +pub struct VARDESC { + pub memid: i32, + pub lpstrSchema: PWSTR, + pub Anonymous: VARDESC_0, + pub elemdescVar: ELEMDESC, + pub wVarFlags: VARFLAGS, + pub varkind: VARKIND, +} +impl ::core::marker::Copy for VARDESC {} +impl ::core::clone::Clone for VARDESC { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union VARDESC_0 { + pub oInst: u32, + pub lpvarValue: *mut VARIANT, +} +impl ::core::marker::Copy for VARDESC_0 {} +impl ::core::clone::Clone for VARDESC_0 { + fn clone(&self) -> Self { + *self + } +} +pub type VARENUM = u16; +pub type VARFLAGS = u16; +#[repr(C)] +pub struct VARIANT { + pub Anonymous: VARIANT_0, +} +impl ::core::marker::Copy for VARIANT {} +impl ::core::clone::Clone for VARIANT { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union VARIANT_0 { + pub Anonymous: VARIANT_0_0, + pub decVal: DECIMAL, +} +impl ::core::marker::Copy for VARIANT_0 {} +impl ::core::clone::Clone for VARIANT_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct VARIANT_0_0 { + pub vt: VARENUM, + pub wReserved1: u16, + pub wReserved2: u16, + pub wReserved3: u16, + pub Anonymous: VARIANT_0_0_0, +} +impl ::core::marker::Copy for VARIANT_0_0 {} +impl ::core::clone::Clone for VARIANT_0_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union VARIANT_0_0_0 { + pub llVal: i64, + pub lVal: i32, + pub bVal: u8, + pub iVal: i16, + pub fltVal: f32, + pub dblVal: f64, + pub boolVal: VARIANT_BOOL, + pub __OBSOLETE__VARIANT_BOOL: VARIANT_BOOL, + pub scode: i32, + pub cyVal: CY, + pub date: f64, + pub bstrVal: BSTR, + pub punkVal: IUnknown, + pub pdispVal: IDispatch, + pub parray: *mut SAFEARRAY, + pub pbVal: *mut u8, + pub piVal: *mut i16, + pub plVal: *mut i32, + pub pllVal: *mut i64, + pub pfltVal: *mut f32, + pub pdblVal: *mut f64, + pub pboolVal: *mut VARIANT_BOOL, + pub __OBSOLETE__VARIANT_PBOOL: *mut VARIANT_BOOL, + pub pscode: *mut i32, + pub pcyVal: *mut CY, + pub pdate: *mut f64, + pub pbstrVal: *mut BSTR, + pub ppunkVal: *mut IUnknown, + pub ppdispVal: *mut IDispatch, + pub pparray: *mut *mut SAFEARRAY, + pub pvarVal: *mut VARIANT, + pub byref: *mut ::core::ffi::c_void, + pub cVal: u8, + pub uiVal: u16, + pub ulVal: u32, + pub ullVal: u64, + pub intVal: i32, + pub uintVal: u32, + pub pdecVal: *mut DECIMAL, + pub pcVal: PSTR, + pub puiVal: *mut u16, + pub pulVal: *mut u32, + pub pullVal: *mut u64, + pub pintVal: *mut i32, + pub puintVal: *mut u32, + pub Anonymous: VARIANT_0_0_0_0, +} +impl ::core::marker::Copy for VARIANT_0_0_0 {} +impl ::core::clone::Clone for VARIANT_0_0_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct VARIANT_0_0_0_0 { + pub pvRecord: *mut ::core::ffi::c_void, + pub pRecInfo: IRecordInfo, +} +impl ::core::marker::Copy for VARIANT_0_0_0_0 {} +impl ::core::clone::Clone for VARIANT_0_0_0_0 { + fn clone(&self) -> Self { + *self + } +} +pub type VARIANT_BOOL = i16; +pub type VARKIND = i32; +#[repr(C)] +pub struct VERSIONEDSTREAM { + pub guidVersion: GUID, + pub pStream: IStream, +} +impl ::core::marker::Copy for VERSIONEDSTREAM {} +impl ::core::clone::Clone for VERSIONEDSTREAM { + fn clone(&self) -> Self { + *self + } +} +pub const VT_BOOL: VARENUM = 11u16; +pub const VT_BSTR: VARENUM = 8u16; +pub const VT_EMPTY: VARENUM = 0u16; +pub const VT_I1: VARENUM = 16u16; +pub const VT_I2: VARENUM = 2u16; +pub const VT_I4: VARENUM = 3u16; +pub const VT_I8: VARENUM = 20u16; +pub const VT_R4: VARENUM = 4u16; +pub const VT_R8: VARENUM = 5u16; +pub const VT_UI1: VARENUM = 17u16; +pub const VT_UI2: VARENUM = 18u16; +pub const VT_UI4: VARENUM = 19u16; +pub const VT_UI8: VARENUM = 21u16; pub type WAIT_EVENT = u32; pub type WIN32_ERROR = u32; diff --git a/crates/libs/core/src/lib.rs b/crates/libs/core/src/lib.rs index 64b9dc1888..c0cd6dedc1 100644 --- a/crates/libs/core/src/lib.rs +++ b/crates/libs/core/src/lib.rs @@ -27,6 +27,7 @@ mod scoped_interface; mod strings; mod r#type; mod unknown; +mod variant; mod weak; pub use agile_reference::*; @@ -45,6 +46,7 @@ pub use runtime_type::*; pub use scoped_interface::*; pub use strings::*; pub use unknown::*; +pub use variant::*; pub use weak::*; /// A specialized [`Result`] type that provides Windows error information. diff --git a/crates/libs/core/src/variant.rs b/crates/libs/core/src/variant.rs new file mode 100644 index 0000000000..0c491e27d1 --- /dev/null +++ b/crates/libs/core/src/variant.rs @@ -0,0 +1,460 @@ +use super::*; + +#[repr(transparent)] +pub struct VARIANT(imp::VARIANT); + +#[repr(transparent)] +pub struct PROPVARIANT(imp::PROPVARIANT); + +impl Default for VARIANT { + fn default() -> Self { + Self::new() + } +} + +impl Default for PROPVARIANT { + fn default() -> Self { + Self::new() + } +} + +impl Drop for VARIANT { + fn drop(&mut self) { + unsafe { imp::VariantClear(&mut self.0) }; + } +} + +impl Drop for PROPVARIANT { + fn drop(&mut self) { + unsafe { imp::PropVariantClear(&mut self.0) }; + } +} + +impl VARIANT { + pub const fn new() -> Self { + unsafe { std::mem::zeroed() } + } + + pub const fn is_empty(&self) -> bool { + unsafe { self.0.Anonymous.Anonymous.vt == imp::VT_EMPTY } + } +} + +impl PROPVARIANT { + pub const fn new() -> Self { + unsafe { std::mem::zeroed() } + } + + pub const fn is_empty(&self) -> bool { + unsafe { self.0.Anonymous.Anonymous.vt == imp::VT_EMPTY } + } +} + +impl TryFrom<&VARIANT> for PROPVARIANT { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + unsafe { + let mut value = Self::new(); + HRESULT(imp::VariantToPropVariant(&from.0, &mut value as *mut _ as *mut _)).and_then(|| value) + } + } +} + +impl TryFrom<&PROPVARIANT> for VARIANT { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + unsafe { + let mut value = Self::new(); + HRESULT(imp::PropVariantToVariant(&from.0, &mut value as *mut _ as *mut _)).and_then(|| value) + } + } +} + +// VT_BSTR + +impl From for VARIANT { + fn from(value: BSTR) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { + Anonymous: imp::VARIANT_0_0 { vt: imp::VT_BSTR, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { bstrVal: value.into_raw() } }, + }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: BSTR) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_BSTR, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { bstrVal: value.into_raw() } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for BSTR { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let pv = PROPVARIANT::try_from(from)?; + BSTR::try_from(&pv) + } +} + +impl TryFrom<&PROPVARIANT> for BSTR { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = Self::new(); + HRESULT(unsafe { imp::PropVariantToBSTR(&from.0, &mut value as *mut _ as *mut _) }).and_then(|| value) + } +} + +// VT_BOOL + +impl From for VARIANT { + fn from(value: bool) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { + Anonymous: imp::VARIANT_0_0 { vt: imp::VT_BOOL, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { boolVal: if value { -1 } else { 0 } } }, + }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: bool) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_BOOL, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { boolVal: if value { -1 } else { 0 } } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for bool { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::VariantToBoolean(&from.0, &mut value) }).and_then(|| value != 0) + } +} + +impl TryFrom<&PROPVARIANT> for bool { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::PropVariantToBoolean(&from.0, &mut value) }).and_then(|| value != 0) + } +} + +// VT_UI1 + +impl From for VARIANT { + fn from(value: u8) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_UI1, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { bVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: u8) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_UI1, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { bVal: value } }, + }, + }) + } +} + +// VT_I1 +// TODO: cVal should be signed but metadata thinks its unsigned + +impl From for VARIANT { + fn from(value: i8) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_I1, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { cVal: value as u8 } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: i8) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_I1, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { cVal: value as u8 } }, + }, + }) + } +} + +// VT_UI2 + +impl From for VARIANT { + fn from(value: u16) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_UI2, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { uiVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: u16) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_UI2, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { uiVal: value } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for u16 { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::VariantToUInt16(&from.0, &mut value) }).and_then(|| value) + } +} + +impl TryFrom<&PROPVARIANT> for u16 { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::PropVariantToUInt16(&from.0, &mut value) }).and_then(|| value) + } +} + +// VT_I2 + +impl From for VARIANT { + fn from(value: i16) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_I2, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { iVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: i16) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_I2, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { iVal: value } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for i16 { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::VariantToInt16(&from.0, &mut value) }).and_then(|| value) + } +} + +impl TryFrom<&PROPVARIANT> for i16 { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::PropVariantToInt16(&from.0, &mut value) }).and_then(|| value) + } +} + +// VT_UI4 + +impl From for VARIANT { + fn from(value: u32) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_UI4, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { ulVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: u32) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_UI4, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { ulVal: value } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for u32 { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::VariantToUInt32(&from.0, &mut value) }).and_then(|| value) + } +} + +impl TryFrom<&PROPVARIANT> for u32 { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::PropVariantToUInt32(&from.0, &mut value) }).and_then(|| value) + } +} + +// VT_I4 + +impl From for VARIANT { + fn from(value: i32) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_I4, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { lVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: i32) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_I4, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { lVal: value } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for i32 { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::VariantToInt32(&from.0, &mut value) }).and_then(|| value) + } +} + +impl TryFrom<&PROPVARIANT> for i32 { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::PropVariantToInt32(&from.0, &mut value) }).and_then(|| value) + } +} + +// VT_UI8 + +impl From for VARIANT { + fn from(value: u64) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_UI8, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { ullVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: u64) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_UI8, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { uhVal: value } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for u64 { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::VariantToUInt64(&from.0, &mut value) }).and_then(|| value) + } +} + +impl TryFrom<&PROPVARIANT> for u64 { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::PropVariantToUInt64(&from.0, &mut value) }).and_then(|| value) + } +} + +// VT_I8 + +impl From for VARIANT { + fn from(value: i64) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_I8, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { llVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: i64) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_I8, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { hVal: value } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for i64 { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::VariantToInt64(&from.0, &mut value) }).and_then(|| value) + } +} + +impl TryFrom<&PROPVARIANT> for i64 { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0; + HRESULT(unsafe { imp::PropVariantToInt64(&from.0, &mut value) }).and_then(|| value) + } +} + +// VT_R4 + +impl From for VARIANT { + fn from(value: f32) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_R4, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { fltVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: f32) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_R4, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { fltVal: value } }, + }, + }) + } +} + +// VT_R8 + +impl From for VARIANT { + fn from(value: f64) -> Self { + Self(imp::VARIANT { + Anonymous: imp::VARIANT_0 { Anonymous: imp::VARIANT_0_0 { vt: imp::VT_R8, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::VARIANT_0_0_0 { dblVal: value } } }, + }) + } +} + +impl From for PROPVARIANT { + fn from(value: f64) -> Self { + Self(imp::PROPVARIANT { + Anonymous: imp::PROPVARIANT_0 { + Anonymous: imp::PROPVARIANT_0_0 { vt: imp::VT_R8, wReserved1: 0, wReserved2: 0, wReserved3: 0, Anonymous: imp::PROPVARIANT_0_0_0 { dblVal: value } }, + }, + }) + } +} + +impl TryFrom<&VARIANT> for f64 { + type Error = Error; + fn try_from(from: &VARIANT) -> Result { + let mut value = 0.0; + HRESULT(unsafe { imp::VariantToDouble(&from.0, &mut value) }).and_then(|| value) + } +} + +impl TryFrom<&PROPVARIANT> for f64 { + type Error = Error; + fn try_from(from: &PROPVARIANT) -> Result { + let mut value = 0.0; + HRESULT(unsafe { imp::PropVariantToDouble(&from.0, &mut value) }).and_then(|| value) + } +} diff --git a/crates/tests/variant/Cargo.toml b/crates/tests/variant/Cargo.toml new file mode 100644 index 0000000000..2d34b26a59 --- /dev/null +++ b/crates/tests/variant/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "test_variant" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies.windows-core] +path = "../../libs/core" diff --git a/crates/tests/variant/src/lib.rs b/crates/tests/variant/src/lib.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/crates/tests/variant/src/lib.rs @@ -0,0 +1 @@ + diff --git a/crates/tests/variant/tests/tests.rs b/crates/tests/variant/tests/tests.rs new file mode 100644 index 0000000000..6db145b8e3 --- /dev/null +++ b/crates/tests/variant/tests/tests.rs @@ -0,0 +1,108 @@ +use windows_core::*; + +const EMPTY_VARIANT: VARIANT = VARIANT::new(); +const EMPTY_PROPVARIANT: PROPVARIANT = PROPVARIANT::new(); + +#[test] +fn test_variant() -> Result<()> { + assert!(EMPTY_VARIANT.is_empty()); + + let v = VARIANT::default(); + assert!(v.is_empty()); + + let v = VARIANT::from(true); + assert!(!v.is_empty()); + assert_eq!(bool::try_from(&v)?, true); + let v = VARIANT::from(false); + assert_eq!(bool::try_from(&v)?, false); + + let v = VARIANT::from(123u8); + assert_eq!(u16::try_from(&v)?, 123u16); + + let v = VARIANT::from(-123i8); + assert_eq!(i16::try_from(&v)?, -123i16); + + let v = VARIANT::from(345u16); + assert_eq!(u16::try_from(&v)?, 345u16); + + let v = VARIANT::from(-345i16); + assert_eq!(i16::try_from(&v)?, -345i16); + + let v = VARIANT::from(67890u32); + assert_eq!(u32::try_from(&v)?, 67890u32); + + let v = VARIANT::from(-67890i32); + assert_eq!(i32::try_from(&v)?, -67890i32); + + let v = VARIANT::from(5294967295u64); + assert_eq!(u64::try_from(&v)?, 5294967295u64); + + let v = VARIANT::from(-5294967295i64); + assert_eq!(i64::try_from(&v)?, -5294967295i64); + + let v = VARIANT::from(3.5f32); + assert_eq!(f64::try_from(&v)?, 3.5f64); + + let v = VARIANT::from(3.5f64); + assert_eq!(f64::try_from(&v)?, 3.5f64); + + let v = VARIANT::from(BSTR::from("hello")); + assert_eq!(BSTR::try_from(&v)?, "hello"); + + let v = VARIANT::from(3.5f64); + assert_eq!(BSTR::try_from(&v)?, "3.5"); + + Ok(()) +} + +#[test] +fn test_propvariant() -> Result<()> { + assert!(EMPTY_PROPVARIANT.is_empty()); + + let v = PROPVARIANT::default(); + assert!(v.is_empty()); + + let v = PROPVARIANT::from(true); + assert!(!v.is_empty()); + assert_eq!(bool::try_from(&v)?, true); + let v = PROPVARIANT::from(false); + assert_eq!(bool::try_from(&v)?, false); + + let v = PROPVARIANT::from(123u8); + assert_eq!(u16::try_from(&v)?, 123u16); + + let v = PROPVARIANT::from(-123i8); + assert_eq!(i16::try_from(&v)?, -123i16); + + let v = PROPVARIANT::from(345u16); + assert_eq!(u16::try_from(&v)?, 345u16); + + let v = PROPVARIANT::from(-345i16); + assert_eq!(i16::try_from(&v)?, -345i16); + + let v = PROPVARIANT::from(67890u32); + assert_eq!(u32::try_from(&v)?, 67890u32); + + let v = PROPVARIANT::from(-67890i32); + assert_eq!(i32::try_from(&v)?, -67890i32); + + let v = PROPVARIANT::from(5294967295u64); + assert_eq!(u64::try_from(&v)?, 5294967295u64); + + let v = PROPVARIANT::from(-5294967295i64); + assert_eq!(i64::try_from(&v)?, -5294967295i64); + + let v = PROPVARIANT::from(3.5f32); + assert_eq!(f64::try_from(&v)?, 3.5f64); + + let v = PROPVARIANT::from(3.5f64); + assert_eq!(f64::try_from(&v)?, 3.5f64); + + let v = PROPVARIANT::from(BSTR::from("hello")); + assert_eq!(BSTR::try_from(&v)?, "hello"); + + let v = PROPVARIANT::from(3.5f64); + assert_eq!(BSTR::try_from(&v)?, "3.5"); + + Ok(()) +} diff --git a/crates/tools/core/bindings.txt b/crates/tools/core/bindings.txt index 6f902cc929..e9501f597c 100644 --- a/crates/tools/core/bindings.txt +++ b/crates/tools/core/bindings.txt @@ -5,8 +5,8 @@ --filter Windows.Win32.Foundation.CloseHandle - Windows.Win32.Foundation.ERROR_NO_UNICODE_TRANSLATION Windows.Win32.Foundation.E_INVALIDARG + Windows.Win32.Foundation.ERROR_NO_UNICODE_TRANSLATION Windows.Win32.Foundation.FreeLibrary Windows.Win32.Foundation.GetLastError Windows.Win32.Foundation.SysAllocStringLen @@ -14,6 +14,19 @@ Windows.Win32.Foundation.SysStringLen Windows.Win32.System.Com.CoTaskMemAlloc Windows.Win32.System.Com.CoTaskMemFree + Windows.Win32.System.Com.StructuredStorage.PROPVARIANT + Windows.Win32.System.Com.StructuredStorage.PropVariantClear + Windows.Win32.System.Com.StructuredStorage.PropVariantToBoolean + Windows.Win32.System.Com.StructuredStorage.PropVariantToBSTR + Windows.Win32.System.Com.StructuredStorage.PropVariantToDouble + Windows.Win32.System.Com.StructuredStorage.PropVariantToInt16 + Windows.Win32.System.Com.StructuredStorage.PropVariantToInt32 + Windows.Win32.System.Com.StructuredStorage.PropVariantToInt64 + Windows.Win32.System.Com.StructuredStorage.PropVariantToUInt16 + Windows.Win32.System.Com.StructuredStorage.PropVariantToUInt32 + Windows.Win32.System.Com.StructuredStorage.PropVariantToUInt64 + Windows.Win32.System.Com.StructuredStorage.PropVariantToVariant + Windows.Win32.System.Com.StructuredStorage.VariantToPropVariant Windows.Win32.System.Diagnostics.Debug.EncodePointer Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_ALLOCATE_BUFFER Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_FROM_SYSTEM @@ -27,4 +40,27 @@ Windows.Win32.System.Memory.HeapFree Windows.Win32.System.Threading.CreateEventW Windows.Win32.System.Threading.SetEvent - Windows.Win32.System.Threading.WaitForSingleObject \ No newline at end of file + Windows.Win32.System.Threading.WaitForSingleObject + Windows.Win32.System.Variant.VARIANT + Windows.Win32.System.Variant.VariantClear + Windows.Win32.System.Variant.VariantToBoolean + Windows.Win32.System.Variant.VariantToDouble + Windows.Win32.System.Variant.VariantToInt16 + Windows.Win32.System.Variant.VariantToInt32 + Windows.Win32.System.Variant.VariantToInt64 + Windows.Win32.System.Variant.VariantToUInt16 + Windows.Win32.System.Variant.VariantToUInt32 + Windows.Win32.System.Variant.VariantToUInt64 + Windows.Win32.System.Variant.VT_BOOL + Windows.Win32.System.Variant.VT_BSTR + Windows.Win32.System.Variant.VT_EMPTY + Windows.Win32.System.Variant.VT_I1 + Windows.Win32.System.Variant.VT_I2 + Windows.Win32.System.Variant.VT_I4 + Windows.Win32.System.Variant.VT_I8 + Windows.Win32.System.Variant.VT_R4 + Windows.Win32.System.Variant.VT_R8 + Windows.Win32.System.Variant.VT_UI1 + Windows.Win32.System.Variant.VT_UI2 + Windows.Win32.System.Variant.VT_UI4 + Windows.Win32.System.Variant.VT_UI8