diff options
author | Aaron Robinson <arobins@microsoft.com> | 2018-10-23 20:22:24 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-23 20:22:24 -0700 |
commit | 28ef0a4f6eb50988b0c1b6392894a3f7de6db6ad (patch) | |
tree | 9786a25b7d0418793fab5c42fdf35c25c7884b58 | |
parent | 377e744a976d09d1d392f43e7fa8a999401fe74f (diff) | |
parent | 177a80924432bcfcb60cc6218126e0b45c7941d4 (diff) | |
download | coreclr-28ef0a4f6eb50988b0c1b6392894a3f7de6db6ad.tar.gz coreclr-28ef0a4f6eb50988b0c1b6392894a3f7de6db6ad.tar.bz2 coreclr-28ef0a4f6eb50988b0c1b6392894a3f7de6db6ad.zip |
Merge pull request #20497 from AaronRobinsonMSFT/additional_com_tests
Support for IDispatch
40 files changed, 2741 insertions, 1458 deletions
diff --git a/src/System.Private.CoreLib/src/System/RtType.cs b/src/System.Private.CoreLib/src/System/RtType.cs index 63cf950d9d..3bab50597e 100644 --- a/src/System.Private.CoreLib/src/System/RtType.cs +++ b/src/System.Private.CoreLib/src/System/RtType.cs @@ -3966,8 +3966,6 @@ namespace System return members; } -#if FEATURE_COMINTEROP -#endif [DebuggerStepThroughAttribute] [Diagnostics.DebuggerHidden] public override object InvokeMember( @@ -4009,7 +4007,6 @@ namespace System } #endregion - #region COM Interop #if FEATURE_COMINTEROP && FEATURE_USE_LCID if (target != null && target.GetType().IsCOMObject) { @@ -4048,7 +4045,6 @@ namespace System } } #endif // FEATURE_COMINTEROP && FEATURE_USE_LCID - #endregion #region Check that any named parameters are not null if (namedParams != null && Array.IndexOf(namedParams, null) != -1) @@ -4887,8 +4883,199 @@ namespace System #endregion - #region COM - #endregion +#if FEATURE_COMINTEROP + private Object ForwardCallToInvokeMember( + String memberName, + BindingFlags flags, + Object target, + Object[] aArgs, // in/out - only byref values are in a valid state upon return + bool[] aArgsIsByRef, + int[] aArgsWrapperTypes, // _maybe_null_ + Type[] aArgsTypes, + Type retType) + { + Debug.Assert( + aArgs.Length == aArgsIsByRef.Length + && aArgs.Length == aArgsTypes.Length + && (aArgsWrapperTypes == null || aArgs.Length == aArgsWrapperTypes.Length), "Input arrays should all be of the same length"); + + int cArgs = aArgs.Length; + + // Handle arguments that are passed as ByRef and those + // arguments that need to be wrapped. + ParameterModifier[] aParamMod = null; + if (cArgs > 0) + { + ParameterModifier paramMod = new ParameterModifier(cArgs); + for (int i = 0; i < cArgs; i++) + { + paramMod[i] = aArgsIsByRef[i]; + } + + aParamMod = new ParameterModifier[] { paramMod }; + if (aArgsWrapperTypes != null) + { + WrapArgsForInvokeCall(aArgs, aArgsWrapperTypes); + } + } + + // For target invocation exceptions, the exception is wrapped. + flags |= BindingFlags.DoNotWrapExceptions; + Object ret = InvokeMember(memberName, flags, null, target, aArgs, aParamMod, null, null); + + // Convert each ByRef argument that is _not_ of the proper type to + // the parameter type. + for (int i = 0; i < cArgs; i++) + { + // Determine if the parameter is ByRef. + if (aParamMod[0][i] && aArgs[i] != null) + { + Type argType = aArgsTypes[i]; + if (!Object.ReferenceEquals(argType, aArgs[i].GetType())) + { + aArgs[i] = ForwardCallBinder.ChangeType(aArgs[i], argType, null); + } + } + } + + // If the return type is _not_ of the proper type, then convert it. + if (ret != null) + { + if (!Object.ReferenceEquals(retType, ret.GetType())) + { + ret = ForwardCallBinder.ChangeType(ret, retType, null); + } + } + + return ret; + } + + private void WrapArgsForInvokeCall(Object[] aArgs, int[] aArgsWrapperTypes) + { + int cArgs = aArgs.Length; + for (int i = 0; i < cArgs; i++) + { + if (aArgsWrapperTypes[i] == 0) + { + continue; + } + + if (((DispatchWrapperType)aArgsWrapperTypes[i]).HasFlag(DispatchWrapperType.SafeArray)) + { + Type wrapperType = null; + bool isString = false; + + // Determine the type of wrapper to use. + switch ((DispatchWrapperType)aArgsWrapperTypes[i] & ~DispatchWrapperType.SafeArray) + { + case DispatchWrapperType.Unknown: + wrapperType = typeof(UnknownWrapper); + break; + case DispatchWrapperType.Dispatch: + wrapperType = typeof(DispatchWrapper); + break; + case DispatchWrapperType.Error: + wrapperType = typeof(ErrorWrapper); + break; + case DispatchWrapperType.Currency: + wrapperType = typeof(CurrencyWrapper); + break; + case DispatchWrapperType.BStr: + wrapperType = typeof(BStrWrapper); + isString = true; + break; + default: + Debug.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified."); + break; + } + + // Allocate the new array of wrappers. + Array oldArray = (Array)aArgs[i]; + int numElems = oldArray.Length; + Object[] newArray = (Object[])Array.UnsafeCreateInstance(wrapperType, numElems); + + // Retrieve the ConstructorInfo for the wrapper type. + ConstructorInfo wrapperCons; + if (isString) + { + wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(String)}); + } + else + { + wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(Object)}); + } + + // Wrap each of the elements of the array. + for (int currElem = 0; currElem < numElems; currElem++) + { + if(isString) + { + newArray[currElem] = wrapperCons.Invoke(new Object[] {(String)oldArray.GetValue(currElem)}); + } + else + { + newArray[currElem] = wrapperCons.Invoke(new Object[] {oldArray.GetValue(currElem)}); + } + } + + // Update the argument. + aArgs[i] = newArray; + } + else + { + // Determine the wrapper to use and then wrap the argument. + switch ((DispatchWrapperType)aArgsWrapperTypes[i]) + { + case DispatchWrapperType.Unknown: + aArgs[i] = new UnknownWrapper(aArgs[i]); + break; + case DispatchWrapperType.Dispatch: + aArgs[i] = new DispatchWrapper(aArgs[i]); + break; + case DispatchWrapperType.Error: + aArgs[i] = new ErrorWrapper(aArgs[i]); + break; + case DispatchWrapperType.Currency: + aArgs[i] = new CurrencyWrapper(aArgs[i]); + break; + case DispatchWrapperType.BStr: + aArgs[i] = new BStrWrapper((String)aArgs[i]); + break; + default: + Debug.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified."); + break; + } + } + } + } + + private static OleAutBinder s_ForwardCallBinder; + private OleAutBinder ForwardCallBinder + { + get + { + // Synchronization is not required. + if (s_ForwardCallBinder == null) + s_ForwardCallBinder = new OleAutBinder(); + + return s_ForwardCallBinder; + } + } + + [Flags] + private enum DispatchWrapperType : int + { + // This enum must stay in sync with the DispatchWrapperType enum defined in MLInfo.h + Unknown = 0x00000001, + Dispatch = 0x00000002, + // Record = 0x00000004, + Error = 0x00000008, + Currency = 0x00000010, + BStr = 0x00000020, + SafeArray = 0x00010000 + } + +#endif // FEATURE_COMINTEROP } #region Library diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index 58de64694e..1e68b9938a 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -287,6 +287,7 @@ set(VM_SOURCES_WKS cachelinealloc.cpp callcounter.cpp callhelpers.cpp + callsiteinspect.cpp ceemain.cpp clrconfignative.cpp clrex.cpp @@ -402,6 +403,7 @@ set(VM_HEADERS_WKS cachelinealloc.h callcounter.h callhelpers.h + callsiteinspect.h ceemain.h clrconfignative.h clrex.h diff --git a/src/vm/callsiteinspect.cpp b/src/vm/callsiteinspect.cpp new file mode 100644 index 0000000000..953714d910 --- /dev/null +++ b/src/vm/callsiteinspect.cpp @@ -0,0 +1,516 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "common.h" +#include "object.h" +#include "callsiteinspect.h" + +namespace +{ + // Given a frame and value, get a reference to the object + OBJECTREF GetOBJECTREFFromStack( + _In_ FramedMethodFrame *frame, + _In_ PVOID val, + _In_ const CorElementType eType, + _In_ TypeHandle ty, + _In_ BOOL fIsByRef) + { + CONTRACT(OBJECTREF) + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(frame)); + PRECONDITION(CheckPointer(val)); + } + CONTRACT_END; + + // Value types like Nullable<T> have special unboxing semantics + if (eType == ELEMENT_TYPE_VALUETYPE) + { + // box the value class + _ASSERTE(ty.GetMethodTable()->IsValueType() || ty.GetMethodTable()->IsEnum()); + + MethodTable* pMT = ty.GetMethodTable(); + + // What happens when the type contains a stack pointer? + _ASSERTE(!pMT->IsByRefLike()); + + PVOID* pVal = (PVOID *)val; + if (!fIsByRef) + { + val = StackElemEndianessFixup(val, pMT->GetNumInstanceFieldBytes()); + pVal = &val; + } + + RETURN (pMT->FastBox(pVal)); + } + + switch (CorTypeInfo::GetGCType(eType)) + { + case TYPE_GC_NONE: + { + if (ELEMENT_TYPE_PTR == eType) + COMPlusThrow(kNotSupportedException); + + MethodTable *pMT = MscorlibBinder::GetElementType(eType); + + OBJECTREF pObj = pMT->Allocate(); + if (fIsByRef) + { + val = *((PVOID *)val); + } + else + { + val = StackElemEndianessFixup(val, CorTypeInfo::Size(eType)); + } + + void *pDest = pObj->UnBox(); + +#ifdef COM_STUBS_SEPARATE_FP_LOCATIONS + if (!fIsByRef + && (ELEMENT_TYPE_R4 == eType || ELEMENT_TYPE_R8 == eType) + && frame != nullptr + && !TransitionBlock::IsStackArgumentOffset(static_cast<int>((TADDR) val - frame->GetTransitionBlock()))) + { + if (ELEMENT_TYPE_R4 == eType) + *(UINT32*)pDest = (UINT32)FPSpillToR4(val); + else + *(UINT64*)pDest = (UINT64)FPSpillToR8(val); + } + else +#endif // COM_STUBS_SEPARATE_FP_LOCATIONS + { + memcpyNoGCRefs(pDest, val, CorTypeInfo::Size(eType)); + } + + RETURN (pObj); + } + + case TYPE_GC_REF: + if (fIsByRef) + val = *((PVOID *)val); + RETURN (ObjectToOBJECTREF(*(Object **)val)); + + default: + COMPlusThrow(kInvalidOperationException, W("InvalidOperation_TypeCannotBeBoxed")); + } + } + + struct ArgDetails + { + int Offset; + BOOL IsByRef; + CorElementType ElementType; + TypeHandle Type; + }; + + ArgDetails GetArgDetails( + _In_ FramedMethodFrame *frame, + _In_ ArgIterator &pArgIter) + { + CONTRACT(ArgDetails) + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + PRECONDITION(CheckPointer(frame)); + } + CONTRACT_END; + + ArgDetails details{}; + details.Offset = pArgIter.GetNextOffset(); + details.ElementType = pArgIter.GetArgType(); + +#ifdef COM_STUBS_SEPARATE_FP_LOCATIONS + // BUGBUG do we need to handle this? + if ((ELEMENT_TYPE_R4 == details.ElementType || ELEMENT_TYPE_R8 == details.ElementType) + && TransitionBlock::IsArgumentRegisterOffset(details.Offset)) + { + int iFPArg = TransitionBlock::GetArgumentIndexFromOffset(details.Offset); + details.Offset = static_cast<int>(frame->GetFPArgOffset(iFPArg)); + } +#endif // COM_STUBS_SEPARATE_FP_LOCATIONS + + // Get the TypeHandle for the argument's type. + MetaSig *pSig = pArgIter.GetSig(); + details.Type = pSig->GetLastTypeHandleThrowing(); + + if (details.ElementType == ELEMENT_TYPE_BYREF) + { + details.IsByRef = TRUE; + // If this is a by-ref arg, GetOBJECTREFFromStack() will dereference "addr" to + // get the real argument address. Dereferencing now will open a gc hole if "addr" + // points into the gc heap, and we trigger gc between here and the point where + // we return the arguments. + + TypeHandle tycopy; + details.ElementType = pSig->GetByRefType(&tycopy); + if (details.ElementType == ELEMENT_TYPE_VALUETYPE) + details.Type = tycopy; + } +#ifdef ENREGISTERED_PARAMTYPE_MAXSIZE + else if (details.ElementType == ELEMENT_TYPE_VALUETYPE) + { + details.IsByRef = ArgIterator::IsArgPassedByRef(details.Type); + } +#endif // ENREGISTERED_PARAMTYPE_MAXSIZE + + RETURN (details); + } + + INT64 CopyOBJECTREFToStack( + _In_ OBJECTREF *src, + _In_opt_ PVOID pvDest, + _In_ CorElementType typ, + _In_ TypeHandle ty, + _In_ MetaSig *pSig, + _In_ BOOL fCopyClassContents) + { + // Use local to ensure proper alignment + INT64 ret = 0; + + CONTRACT(INT64) + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + INJECT_FAULT(COMPlusThrowOM()); + PRECONDITION(CheckPointer(pvDest, NULL_OK)); + PRECONDITION(CheckPointer(pSig)); + PRECONDITION(typ != ELEMENT_TYPE_VOID); + } + CONTRACT_END; + + if (fCopyClassContents) + { + // We have to copy the contents of a value class to pvDest + + // write unboxed version back to memory provided by the caller + if (pvDest) + { + if (ty.IsNull()) + ty = pSig->GetRetTypeHandleThrowing(); + + _ASSERTE((*src) != NULL || Nullable::IsNullableType(ty)); +#ifdef PLATFORM_UNIX + // Unboxing on non-Windows ABIs must be special cased + COMPlusThrowHR(COR_E_NOTSUPPORTED); +#else + ty.GetMethodTable()->UnBoxIntoUnchecked(pvDest, (*src)); +#endif + + // return the object so it can be stored in the frame and + // propagated to the root set + *(OBJECTREF*)&ret = (*src); + } + } + else if (CorTypeInfo::IsObjRef(typ)) + { + // We have a real OBJECTREF + + // Check if it is an OBJECTREF (from the GC heap) + if (pvDest) + SetObjectReferenceUnchecked((OBJECTREF *)pvDest, *src); + + *(OBJECTREF*)&ret = (*src); + } + else + { + // We have something that does not have a return buffer associated. + + // Note: this assert includes ELEMENT_TYPE_VALUETYPE because for enums, + // ArgIterator::HasRetBuffArg() returns 'false'. This occurs because the + // normalized type for enums is ELEMENT_TYPE_I4 even though + // MetaSig::GetReturnType() returns ELEMENT_TYPE_VALUETYPE. + // Almost all ELEMENT_TYPE_VALUETYPEs will go through the copy class + // contents codepath above. + // Also, CorTypeInfo::IsPrimitiveType() does not check for IntPtr, UIntPtr + // hence we have ELEMENT_TYPE_I and ELEMENT_TYPE_U. + _ASSERTE( + CorTypeInfo::IsPrimitiveType(typ) + || (typ == ELEMENT_TYPE_VALUETYPE) + || (typ == ELEMENT_TYPE_I) + || (typ == ELEMENT_TYPE_U) + || (typ == ELEMENT_TYPE_FNPTR)); + + // For a "ref int" arg, if a nasty sink replaces the boxed int with + // a null OBJECTREF, this is where we check. We need to be uniform + // in our policy w.r.t. this (throw vs ignore). + // The branch above throws. + if ((*src) != NULL) + { + PVOID srcData = (*src)->GetData(); + int cbsize = gElementTypeInfo[typ].m_cbSize; + decltype(ret) retBuff; + + // ElementTypeInfo.m_cbSize can be less than zero for cases that need + // special handling (e.g. value types) to be sure of the size (see siginfo.cpp). + // The type handle has the actual byte count, so we look there for such cases. + if (cbsize < 0) + { + if (ty.IsNull()) + ty = pSig->GetRetTypeHandleThrowing(); + + _ASSERTE(!ty.IsNull()); + cbsize = ty.GetSize(); + + // Assert the value class fits in the buffer + _ASSERTE(cbsize <= (int) sizeof(retBuff)); + + // Unbox value into a local buffer, this covers the Nullable<T> case. + ty.GetMethodTable()->UnBoxIntoUnchecked(&retBuff, *src); + + srcData = &retBuff; + } + + if (pvDest) + memcpyNoGCRefs(pvDest, srcData, cbsize); + + // need to sign-extend signed types + bool fEndianessFixup = false; + switch (typ) + { + case ELEMENT_TYPE_I1: + ret = *(INT8*)srcData; + fEndianessFixup = true; + break; + case ELEMENT_TYPE_I2: + ret = *(INT16*)srcData; + fEndianessFixup = true; + break; + case ELEMENT_TYPE_I4: + ret = *(INT32*)srcData; + fEndianessFixup = true; + break; + default: + memcpyNoGCRefs(StackElemEndianessFixup(&ret, cbsize), srcData, cbsize); + break; + } + +#if !defined(_WIN64) && BIGENDIAN + if (fEndianessFixup) + ret <<= 32; +#endif + } + } + + RETURN (ret); + } +} + +void CallsiteInspect::GetCallsiteArgs( + _In_ CallsiteDetails &callsite, + _Outptr_ PTRARRAYREF *args, + _Outptr_ BOOLARRAYREF *argsIsByRef, + _Outptr_ PTRARRAYREF *argsTypes) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(args)); + PRECONDITION(CheckPointer(argsIsByRef)); + PRECONDITION(CheckPointer(argsTypes)); + } + CONTRACTL_END; + + struct _gc + { + PTRARRAYREF Args; + PTRARRAYREF ArgsTypes; + BOOLARRAYREF ArgsIsByRef; + OBJECTREF CurrArgType; + OBJECTREF CurrArg; + } gc; + ZeroMemory(&gc, sizeof(gc)); + GCPROTECT_BEGIN(gc); + { + // Ensure the sig is in a known state + callsite.MetaSig.Reset(); + + // scan the sig for the argument count + INT32 numArgs = callsite.MetaSig.NumFixedArgs(); + if (callsite.IsDelegate) + numArgs -= 2; // Delegates have 2 implicit additional arguments + + // Allocate all needed arrays for callsite arg details + gc.Args = (PTRARRAYREF)AllocateObjectArray(numArgs, g_pObjectClass); + MethodTable *typeMT = MscorlibBinder::GetClass(CLASS__TYPE); + gc.ArgsTypes = (PTRARRAYREF)AllocateObjectArray(numArgs, typeMT); + gc.ArgsIsByRef = (BOOLARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_BOOLEAN, numArgs); + + ArgIterator iter{ &callsite.MetaSig }; + for (int index = 0; index < numArgs; index++) + { + ArgDetails details = GetArgDetails(callsite.Frame, iter); + PVOID addr = (LPBYTE)callsite.Frame->GetTransitionBlock() + details.Offset; + + // How do we handle pointer types? + _ASSERTE(details.ElementType != ELEMENT_TYPE_PTR); + + gc.CurrArg = GetOBJECTREFFromStack( + callsite.Frame, + addr, + details.ElementType, + details.Type, + details.IsByRef); + + // Store argument + gc.Args->SetAt(index, gc.CurrArg); + + // Record the argument's type + gc.CurrArgType = details.Type.GetManagedClassObject(); + _ASSERTE(gc.CurrArgType != NULL); + gc.ArgsTypes->SetAt(index, gc.CurrArgType); + + // Record if the argument is ByRef + *((UCHAR*)gc.ArgsIsByRef->GetDataPtr() + index) = (!!details.IsByRef); + } + } + GCPROTECT_END(); + + // Return details + *args = gc.Args; + *argsTypes = gc.ArgsTypes; + *argsIsByRef = gc.ArgsIsByRef; +} + +void CallsiteInspect::PropagateOutParametersBackToCallsite( + _In_ PTRARRAYREF outArgs, + _In_ OBJECTREF retVal, + _In_ CallsiteDetails &callsite) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + struct _gc + { + OBJECTREF RetVal; + PTRARRAYREF OutArgs; + OBJECTREF CurrArg; + } gc; + ZeroMemory(&gc, sizeof(gc)); + gc.OutArgs = outArgs; + gc.RetVal = retVal; + GCPROTECT_BEGIN(gc); + { + FramedMethodFrame *frame = callsite.Frame; + const INT32 flags = callsite.Flags; + MetaSig *pSig = &callsite.MetaSig; + pSig->Reset(); // Ensure the sig is in a known state + + // Construct an ArgIterator from the sig + ArgIterator argit{ pSig }; + + // Propagate the return value only if the call is not a constructor call + // and the return type is non-void + if ((flags & CallsiteDetails::Ctor) == 0 + && pSig->GetReturnType() != ELEMENT_TYPE_VOID) + { + if (argit.HasRetBuffArg()) + { + // Copy from RetVal into the retBuff. + INT64 retVal = CopyOBJECTREFToStack( + &gc.RetVal, + *(void**)(frame->GetTransitionBlock() + argit.GetRetBuffArgOffset()), + pSig->GetReturnType(), + TypeHandle{}, + pSig, + TRUE /* should copy */); + + // Copy the return value + *(ARG_SLOT *)(frame->GetReturnValuePtr()) = retVal; + } +#ifdef ENREGISTERED_RETURNTYPE_MAXSIZE + else if (argit.HasNonStandardByvalReturn()) + { + // In these cases, put the pointer to the return buffer into + // the frame's return value slot. + CopyOBJECTREFToStack( + &gc.RetVal, + frame->GetReturnValuePtr(), + pSig->GetReturnType(), + TypeHandle(), + pSig, + TRUE /* should copy */); + } +#endif // ENREGISTERED_RETURNTYPE_MAXSIZE + else + { + // There is no separate return buffer, + // the retVal should fit in an INT64. + INT64 retVal = CopyOBJECTREFToStack( + &gc.RetVal, + nullptr, + pSig->GetReturnType(), + TypeHandle{}, + pSig, + FALSE /* should copy */); + + // Copy the return value + *(ARG_SLOT *)(frame->GetReturnValuePtr()) = retVal; + } + } + + // Refetch all the variables as GC could have happened + // after copying the return value. + UINT32 cOutArgs = (gc.OutArgs != NULL) ? gc.OutArgs->GetNumComponents() : 0; + if (cOutArgs > 0) + { + MetaSig syncSig{ callsite.MethodDesc }; + MetaSig *pSyncSig = nullptr; + + if (flags & CallsiteDetails::EndInvoke) + pSyncSig = &syncSig; + + PVOID *argAddr; + for (UINT32 i = 0; i < cOutArgs; ++i) + { + // Determine the address of the argument + if (pSyncSig) + { + CorElementType typ = pSyncSig->NextArg(); + if (typ == ELEMENT_TYPE_END) + break; + + if (typ != ELEMENT_TYPE_BYREF) + continue; + + argAddr = reinterpret_cast<PVOID *>(frame->GetTransitionBlock() + argit.GetNextOffset()); + } + else + { + int ofs = argit.GetNextOffset(); + if (ofs == TransitionBlock::InvalidOffset) + break; + + if (argit.GetArgType() != ELEMENT_TYPE_BYREF) + continue; + + argAddr = reinterpret_cast<PVOID *>(frame->GetTransitionBlock() + ofs); + } + + TypeHandle ty; + CorElementType brType = pSig->GetByRefType(&ty); + + gc.CurrArg = gc.OutArgs->GetAt(i); + CopyOBJECTREFToStack( + &gc.CurrArg, + *argAddr, + brType, + ty, + pSig, + ty.IsNull() ? FALSE : ty.IsValueType()); + } + } + } + GCPROTECT_END(); +} diff --git a/src/vm/callsiteinspect.h b/src/vm/callsiteinspect.h new file mode 100644 index 0000000000..8a2d7cca49 --- /dev/null +++ b/src/vm/callsiteinspect.h @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +struct CallsiteDetails +{ + // The signature of the current call + MetaSig MetaSig; + + // The current call frame + FramedMethodFrame *Frame; + + // The relevant method for the callsite + MethodDesc *MethodDesc; + + // Is the callsite for a delegate + // Note the relevant method may _not_ be a delegate + BOOL IsDelegate; + + // Flags for callsite + enum + { + None = 0x0, + BeginInvoke = 0x01, + EndInvoke = 0x02, + Ctor = 0x04, + }; + INT32 Flags; +}; + +namespace CallsiteInspect +{ + // Get all arguments and associated argument details at the supplied callsite + void GetCallsiteArgs( + _In_ CallsiteDetails &callsite, + _Outptr_ PTRARRAYREF *args, + _Outptr_ BOOLARRAYREF *argsIsByRef, + _Outptr_ PTRARRAYREF *argsTypes); + + // Properly propagate out parameters + void PropagateOutParametersBackToCallsite( + _In_ PTRARRAYREF outParams, + _In_ OBJECTREF retVal, + _In_ CallsiteDetails &callsite); +} diff --git a/src/vm/clrtocomcall.cpp b/src/vm/clrtocomcall.cpp index 372cf6f30a..e56c4b4159 100644 --- a/src/vm/clrtocomcall.cpp +++ b/src/vm/clrtocomcall.cpp @@ -16,6 +16,7 @@ #include "excep.h" #include "clrtocomcall.h" #include "siginfo.hpp" +#include "comdelegate.h" #include "comcallablewrapper.h" #include "runtimecallablewrapper.h" #include "dllimport.h" @@ -25,6 +26,7 @@ #include "reflectioninvocation.h" #include "mdaassistants.h" #include "sigbuilder.h" +#include "callsiteinspect.h" #define DISPATCH_INVOKE_SLOT 6 @@ -629,6 +631,314 @@ UINT32 CLRToCOMEventCallWorker(ComPlusMethodFrame* pFrame, ComPlusCallMethodDesc return 0; } +CallsiteDetails CreateCallsiteDetails(_In_ FramedMethodFrame *pFrame) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(pFrame)); + } + CONTRACTL_END; + + MethodDesc *pMD = pFrame->GetFunction(); + _ASSERTE(!pMD->ContainsGenericVariables() && pMD->IsRuntimeMethodHandle()); + + const BOOL fIsDelegate = pMD->GetMethodTable()->IsDelegate(); + _ASSERTE(!fIsDelegate && pMD->IsRuntimeMethodHandle()); + + MethodDesc *pDelegateMD = nullptr; + INT32 callsiteFlags = CallsiteDetails::None; + if (fIsDelegate) + { + // Gather details on the delegate itself + DelegateEEClass* delegateCls = (DelegateEEClass*)pMD->GetMethodTable()->GetClass(); + _ASSERTE(pFrame->GetThis()->GetMethodTable()->IsDelegate()); + + if (pMD == delegateCls->m_pBeginInvokeMethod.GetValue()) + { + callsiteFlags |= CallsiteDetails::BeginInvoke; + } + else + { + _ASSERTE(pMD == delegateCls->m_pEndInvokeMethod.GetValue()); + callsiteFlags |= CallsiteDetails::EndInvoke; + } + + pDelegateMD = pMD; + + // Get at the underlying method desc for this frame + pMD = COMDelegate::GetMethodDesc(pFrame->GetThis()); + _ASSERTE(pDelegateMD != nullptr + && pMD != nullptr + && !pMD->ContainsGenericVariables() + && pMD->IsRuntimeMethodHandle()); + } + + if (pMD->IsCtor()) + callsiteFlags |= CallsiteDetails::Ctor; + + Signature signature; + Module *pModule; + SigTypeContext typeContext; + + if (fIsDelegate) + { + _ASSERTE(pDelegateMD != nullptr); + signature = pDelegateMD->GetSignature(); + pModule = pDelegateMD->GetModule(); + + // If the delegate is generic, pDelegateMD may not represent the exact instantiation so we recover it from 'this'. + SigTypeContext::InitTypeContext(pFrame->GetThis()->GetMethodTable()->GetInstantiation(), Instantiation{}, &typeContext); + } + else if (pMD->IsVarArg()) + { + VASigCookie *pVACookie = pFrame->GetVASigCookie(); + signature = pVACookie->signature; + pModule = pVACookie->pModule; + SigTypeContext::InitTypeContext(&typeContext); + } + else + { + // COM doesn't support generics so the type is obvious + TypeHandle actualType = TypeHandle{ pMD->GetMethodTable() }; + + signature = pMD->GetSignature(); + pModule = pMD->GetModule(); + SigTypeContext::InitTypeContext(pMD, actualType, &typeContext); + } + + _ASSERTE(!signature.IsEmpty() && pModule != nullptr); + + // Create details + return CallsiteDetails{ { signature, pModule, &typeContext }, pFrame, pMD, fIsDelegate }; +} + +UINT32 CLRToCOMLateBoundWorker( + _In_ ComPlusMethodFrame *pFrame, + _In_ ComPlusCallMethodDesc *pMD) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + INJECT_FAULT(COMPlusThrowOM()); + PRECONDITION(CheckPointer(pFrame)); + PRECONDITION(CheckPointer(pMD)); + } + CONTRACTL_END; + + HRESULT hr; + + LOG((LF_STUBS, LL_INFO1000, "Calling CLRToCOMLateBoundWorker %s::%s \n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); + + // Retrieve the method table and the method desc of the call. + MethodTable *pItfMT = pMD->GetInterfaceMethodTable(); + ComPlusCallMethodDesc *pItfMD = pMD; + + // Make sure this is only called on IDispatch only interfaces. + _ASSERTE(pItfMT->GetComInterfaceType() == ifDispatch); + + // If this is a method impl MD then we need to retrieve the actual interface MD that + // this is a method impl for. + // REVISIT_TODO: Stop using ComSlot to convert method impls to interface MD + // _ASSERTE(pMD->m_pComPlusCallInfo->m_cachedComSlot == 7); + if (!pMD->GetMethodTable()->IsInterface()) + { + const unsigned cbExtraSlots = 7; + pItfMD = (ComPlusCallMethodDesc*)pItfMT->GetMethodDescForSlot(pMD->m_pComPlusCallInfo->m_cachedComSlot - cbExtraSlots); + CONSISTENCY_CHECK(pMD->GetInterfaceMD() == pItfMD); + } + + // Token of member to call + mdToken tkMember; + DWORD binderFlags = BINDER_AllLookup; + + // Property details + mdProperty propToken; + LPCUTF8 strMemberName; + ULONG uSemantic; + + // See if there is property information for this member. + hr = pItfMT->GetModule()->GetPropertyInfoForMethodDef(pItfMD->GetMemberDef(), &propToken, &strMemberName, &uSemantic); + if (hr != S_OK) + { + // Non-property method + strMemberName = pItfMD->GetName(); + tkMember = pItfMD->GetMemberDef(); + binderFlags |= BINDER_InvokeMethod; + } + else + { + // Property accessor + tkMember = propToken; + + // Determine which type of accessor we are dealing with. + switch (uSemantic) + { + case msGetter: + { + // INVOKE_PROPERTYGET + binderFlags |= BINDER_GetProperty; + break; + } + + case msSetter: + { + // INVOKE_PROPERTYPUT or INVOKE_PROPERTYPUTREF + ULONG cAssoc; + ASSOCIATE_RECORD* pAssoc; + + IMDInternalImport *pMDImport = pItfMT->GetMDImport(); + + // Retrieve all the associates. + HENUMInternalHolder henum{ pMDImport }; + henum.EnumAssociateInit(propToken); + + cAssoc = henum.EnumGetCount(); + _ASSERTE(cAssoc > 0); + + ULONG allocSize = cAssoc * sizeof(*pAssoc); + if (allocSize < cAssoc) + COMPlusThrowHR(COR_E_OVERFLOW); + + pAssoc = (ASSOCIATE_RECORD*)_alloca((size_t)allocSize); + IfFailThrow(pMDImport->GetAllAssociates(&henum, pAssoc, cAssoc)); + + // Check to see if there is both a set and an other. If this is the case + // then the setter is a INVOKE_PROPERTYPUTREF otherwise we will make it a + // INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF. + bool propHasOther = false; + for (ULONG i = 0; i < cAssoc; i++) + { + if (pAssoc[i].m_dwSemantics == msOther) + { + propHasOther = true; + break; + } + } + + if (propHasOther) + { + // There is both a INVOKE_PROPERTYPUT and a INVOKE_PROPERTYPUTREF for this + // property. Therefore be specific and make this invoke a INVOKE_PROPERTYPUTREF. + binderFlags |= BINDER_PutRefDispProperty; + } + else + { + // Only a setter so make the invoke a set which maps to + // INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF. + binderFlags = BINDER_SetProperty; + } + break; + } + + case msOther: + { + // INVOKE_PROPERTYPUT + binderFlags |= BINDER_PutDispProperty; + break; + } + + default: + { + _ASSERTE(!"Invalid method semantic!"); + } + } + } + + // If the method has a void return type, then set the IgnoreReturn binding flag. + if (pItfMD->IsVoid()) + binderFlags |= BINDER_IgnoreReturn; + + UINT32 fpRetSize = 0; + + struct + { + OBJECTREF MemberName; + OBJECTREF ItfTypeObj; + PTRARRAYREF Args; + BOOLARRAYREF ArgsIsByRef; + PTRARRAYREF ArgsTypes; + OBJECTREF ArgsWrapperTypes; + OBJECTREF RetValType; + OBJECTREF RetVal; + } gc; + ZeroMemory(&gc, sizeof(gc)); + GCPROTECT_BEGIN(gc); + { + // Retrieve the exposed type object for the interface. + gc.ItfTypeObj = pItfMT->GetManagedClassObject(); + + // Retrieve the name of the target member. If the member + // has a DISPID then use that to optimize the invoke. + DISPID dispId = DISPID_UNKNOWN; + hr = pItfMD->GetMDImport()->GetDispIdOfMemberDef(tkMember, (ULONG*)&dispId); + if (hr == S_OK) + { + WCHAR strTmp[ARRAYSIZE(DISPID_NAME_FORMAT_STRING W("4294967295"))]; + _snwprintf_s(strTmp, COUNTOF(strTmp), _TRUNCATE, DISPID_NAME_FORMAT_STRING, dispId); + gc.MemberName = StringObject::NewString(strTmp); + } + else + { + gc.MemberName = StringObject::NewString(strMemberName); + } + + CallsiteDetails callsite = CreateCallsiteDetails(pFrame); + + // Arguments + CallsiteInspect::GetCallsiteArgs(callsite, &gc.Args, &gc.ArgsIsByRef, &gc.ArgsTypes); + + // If call requires object wrapping, set up the array of wrapper types. + if (pMD->RequiresArgumentWrapping()) + gc.ArgsWrapperTypes = SetUpWrapperInfo(pItfMD); + + // Return type + TypeHandle retValHandle = callsite.MetaSig.GetRetTypeHandleThrowing(); + gc.RetValType = retValHandle.GetManagedClassObject(); + + // the return value is written into the Frame's neginfo, so we don't + // need to return it directly. We can just have the stub do that work. + // However, the stub needs to know what type of FP return this is, if + // any, so we return the return size info as the return value. + if (callsite.MetaSig.HasFPReturn()) + { + callsite.MetaSig.Reset(); + ArgIterator argit{ &callsite.MetaSig }; + fpRetSize = argit.GetFPReturnSize(); + _ASSERTE(fpRetSize > 0); + } + + // Create a call site for the invoke + MethodDescCallSite forwardCallToInvoke(METHOD__CLASS__FORWARD_CALL_TO_INVOKE, &gc.ItfTypeObj); + + // Prepare the arguments that will be passed to the method. + ARG_SLOT invokeArgs[] = + { + ObjToArgSlot(gc.ItfTypeObj), + ObjToArgSlot(gc.MemberName), + (ARG_SLOT)binderFlags, + ObjToArgSlot(pFrame->GetThis()), + ObjToArgSlot(gc.Args), + ObjToArgSlot(gc.ArgsIsByRef), + ObjToArgSlot(gc.ArgsWrapperTypes), + ObjToArgSlot(gc.ArgsTypes), + ObjToArgSlot(gc.RetValType) + }; + + // Invoke the method + gc.RetVal = forwardCallToInvoke.CallWithValueTypes_RetOBJECTREF(invokeArgs); + + // Ensure all outs and return values are moved back to the current callsite + CallsiteInspect::PropagateOutParametersBackToCallsite(gc.Args, gc.RetVal, callsite); + } + GCPROTECT_END(); + + return fpRetSize; +} // calls that propagate from CLR to COM @@ -681,6 +991,12 @@ UINT32 STDCALL CLRToCOMWorker(TransitionBlock * pTransitionBlock, ComPlusCallMet { returnValue = CLRToCOMEventCallWorker(pFrame, pMD); } + else if (pItfMT->GetComInterfaceType() == ifDispatch) + { + // If the interface is a Dispatch only interface then convert the early bound + // call to a late bound call. + returnValue = CLRToCOMLateBoundWorker(pFrame, pMD); + } else { LOG((LF_STUBS, LL_INFO1000, "Calling CLRToCOMWorker %s::%s \n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); diff --git a/src/vm/metasig.h b/src/vm/metasig.h index b3a4139a7c..e826526976 100644 --- a/src/vm/metasig.h +++ b/src/vm/metasig.h @@ -455,6 +455,7 @@ DEFINE_METASIG(IM(IntPtr_UInt_IntPtr_IntPtr_RetVoid, I K I I, v)) DEFINE_METASIG(IM(Obj_Bool_RetVoid, j F, v)) #ifdef FEATURE_COMINTEROP DEFINE_METASIG(SM(Obj_RetStr, j, s)) +DEFINE_METASIG_T(IM(Str_BindingFlags_Obj_ArrObj_ArrBool_ArrInt_ArrType_Type_RetObj, s g(BINDING_FLAGS) j a(j) a(F) a(i) a(C(TYPE)) C(TYPE), j)) #endif // FEATURE_COMINTEROP DEFINE_METASIG_T(IM(Obj_Obj_BindingFlags_Binder_CultureInfo_RetVoid, j j g(BINDING_FLAGS) C(BINDER) C(CULTURE_INFO), v)) DEFINE_METASIG_T(IM(Obj_Obj_BindingFlags_Binder_ArrObj_CultureInfo_RetVoid, j j g(BINDING_FLAGS) C(BINDER) a(j) C(CULTURE_INFO), v)) diff --git a/src/vm/mlinfo.h b/src/vm/mlinfo.h index b27dcc01c3..b31e34f138 100644 --- a/src/vm/mlinfo.h +++ b/src/vm/mlinfo.h @@ -31,6 +31,7 @@ enum DispatchWrapperType { DispatchWrapperType_Unknown = 0x00000001, DispatchWrapperType_Dispatch = 0x00000002, + //DispatchWrapperType_Record = 0x00000004, DispatchWrapperType_Error = 0x00000008, DispatchWrapperType_Currency = 0x00000010, DispatchWrapperType_BStr = 0x00000020, diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h index 2813fc6e04..ab00e94577 100644 --- a/src/vm/mscorlib.h +++ b/src/vm/mscorlib.h @@ -191,10 +191,6 @@ DEFINE_METHOD(BINDER, CHANGE_TYPE, ChangeType, DEFINE_CLASS(BINDING_FLAGS, Reflection, BindingFlags) -#ifdef FEATURE_COMINTEROP -DEFINE_CLASS(BSTR_WRAPPER, Interop, BStrWrapper) -#endif // FEATURE_COMINTEROP - DEFINE_CLASS_U(System, RuntimeType, ReflectClassBaseObject) DEFINE_FIELD_U(m_cache, ReflectClassBaseObject, m_cache) DEFINE_FIELD_U(m_handle, ReflectClassBaseObject, m_typeHandle) @@ -210,6 +206,19 @@ DEFINE_METHOD(CLASS, GET_FIELD_INFO, GetFieldInfo, DEFINE_METHOD(CLASS, GET_PROPERTY_INFO, GetPropertyInfo, SM_RuntimeType_Int_RetPropertyInfo) #ifdef FEATURE_COMINTEROP +DEFINE_METHOD(CLASS, FORWARD_CALL_TO_INVOKE, ForwardCallToInvokeMember, IM_Str_BindingFlags_Obj_ArrObj_ArrBool_ArrInt_ArrType_Type_RetObj) +#endif // FEATURE_COMINTEROP + +#ifdef FEATURE_COMINTEROP +DEFINE_CLASS(BSTR_WRAPPER, Interop, BStrWrapper) +DEFINE_CLASS(CURRENCY_WRAPPER, Interop, CurrencyWrapper) +DEFINE_CLASS(DISPATCH_WRAPPER, Interop, DispatchWrapper) +DEFINE_CLASS(ERROR_WRAPPER, Interop, ErrorWrapper) +DEFINE_CLASS(UNKNOWN_WRAPPER, Interop, UnknownWrapper) +DEFINE_CLASS(VARIANT_WRAPPER, Interop, VariantWrapper) +#endif // FEATURE_COMINTEROP + +#ifdef FEATURE_COMINTEROP DEFINE_CLASS_U(System, __ComObject, ComObject) DEFINE_FIELD_U(m_ObjectToDataMap, ComObject, m_ObjectToDataMap) DEFINE_CLASS(COM_OBJECT, System, __ComObject) @@ -296,10 +305,6 @@ DEFINE_PROPERTY(CULTURE_INFO, PARENT, Parent, DEFINE_CLASS(CURRENCY, System, Currency) DEFINE_METHOD(CURRENCY, DECIMAL_CTOR, .ctor, IM_Dec_RetVoid) -#ifdef FEATURE_COMINTEROP -DEFINE_CLASS(CURRENCY_WRAPPER, Interop, CurrencyWrapper) -#endif - DEFINE_CLASS(DATE_TIME, System, DateTime) DEFINE_METHOD(DATE_TIME, LONG_CTOR, .ctor, IM_Long_RetVoid) @@ -322,10 +327,6 @@ DEFINE_FIELD(DELEGATE, METHOD_PTR_AUX, _methodPtrAux) DEFINE_METHOD(DELEGATE, CONSTRUCT_DELEGATE, DelegateConstruct, IM_Obj_IntPtr_RetVoid) DEFINE_METHOD(DELEGATE, GET_INVOKE_METHOD, GetInvokeMethod, IM_RetIntPtr) -#ifdef FEATURE_COMINTEROP -DEFINE_CLASS(DISPATCH_WRAPPER, Interop, DispatchWrapper) -#endif // FEATURE_COMINTEROP - DEFINE_CLASS(DYNAMICMETHOD, ReflectionEmit, DynamicMethod) DEFINE_CLASS(DYNAMICRESOLVER, ReflectionEmit, DynamicResolver) @@ -344,10 +345,6 @@ DEFINE_CLASS(ENVIRONMENT, System, Environment) DEFINE_METHOD(ENVIRONMENT, GET_RESOURCE_STRING_LOCAL, GetResourceStringLocal, SM_Str_RetStr) DEFINE_METHOD(ENVIRONMENT, SET_COMMAND_LINE_ARGS, SetCommandLineArgs, SM_ArrStr_RetVoid) -#ifdef FEATURE_COMINTEROP -DEFINE_CLASS(ERROR_WRAPPER, Interop, ErrorWrapper) -#endif - DEFINE_CLASS(EVENT, Reflection, RuntimeEventInfo) DEFINE_CLASS(EVENT_ARGS, System, EventArgs) @@ -960,18 +957,10 @@ DEFINE_CLASS(LAZY, System, Lazy`1) DEFINE_CLASS(LAZY_INITIALIZER, Threading, LazyInitializer) -#ifdef FEATURE_COMINTEROP -DEFINE_CLASS(UNKNOWN_WRAPPER, Interop, UnknownWrapper) -#endif - DEFINE_CLASS(VALUE_TYPE, System, ValueType) DEFINE_METHOD(VALUE_TYPE, GET_HASH_CODE, GetHashCode, IM_RetInt) DEFINE_METHOD(VALUE_TYPE, EQUALS, Equals, IM_Obj_RetBool) -#ifdef FEATURE_COMINTEROP -DEFINE_CLASS(VARIANT_WRAPPER, Interop, VariantWrapper) -#endif // FEATURE_COMINTEROP - DEFINE_CLASS(GC, System, GC) DEFINE_METHOD(GC, KEEP_ALIVE, KeepAlive, SM_Obj_RetVoid) DEFINE_METHOD(GC, COLLECT, Collect, SM_RetVoid) diff --git a/src/vm/stdinterfaces.cpp b/src/vm/stdinterfaces.cpp index 5726df9958..005748ce2d 100644 --- a/src/vm/stdinterfaces.cpp +++ b/src/vm/stdinterfaces.cpp @@ -583,25 +583,6 @@ ClassInfo_GetClassInfo(IUnknown* pUnk, ITypeInfo** ppTI) return hr; } -//------------------------------------------------------------------------------------- -// Helper to get the ITypeLib* for a Assembly. -HRESULT GetITypeLibForAssembly(Assembly *pAssembly, ITypeLib **ppTLB, int bAutoCreate, int flags) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - PRECONDITION(CheckPointer(pAssembly)); - PRECONDITION(CheckPointer(ppTLB)); - } - CONTRACTL_END; - - //@CORESYSTODO: what to do? - return E_FAIL; -} // HRESULT GetITypeLibForAssembly() - - //------------------------------------------------------------------------------------------ // Helper to get the ITypeInfo* for a type. HRESULT GetITypeLibForEEClass(MethodTable *pClass, ITypeLib **ppTLB, int bAutoCreate, int flags) @@ -614,7 +595,7 @@ HRESULT GetITypeLibForEEClass(MethodTable *pClass, ITypeLib **ppTLB, int bAutoCr } CONTRACTL_END; - return GetITypeLibForAssembly(pClass->GetAssembly(), ppTLB, bAutoCreate, flags); + return COR_E_NOTSUPPORTED; } // HRESULT GetITypeLibForEEClass() diff --git a/src/vm/stdinterfaces.h b/src/vm/stdinterfaces.h index 57981fa868..3ef26d1563 100644 --- a/src/vm/stdinterfaces.h +++ b/src/vm/stdinterfaces.h @@ -539,18 +539,10 @@ HRESULT TryGetGuid(MethodTable* pClass, GUID* pGUID, BOOL b); //------------------------------------------------------------------------------------------ // Helpers to get the ITypeInfo* for a type. -HRESULT ExportTypeLibFromLoadedAssemblyNoThrow(Assembly *pAssembly, LPCWSTR szTlb, ITypeLib **ppTlb, ITypeLibExporterNotifySink *pINotify, int flags); -void ExportTypeLibFromLoadedAssembly(Assembly *pAssembly, LPCWSTR szTlb, ITypeLib **ppTlb, ITypeLibExporterNotifySink *pINotify, int flags); -HRESULT GetITypeLibForEEClass(MethodTable *pMT, ITypeLib **ppTLB, int bAutoCreate, int flags); HRESULT GetITypeInfoForEEClass(MethodTable *pMT, ITypeInfo **ppTI, int bClassInfo=false, int bAutoCreate=true, int flags=0); -HRESULT GetTypeLibIdForRegisteredEEClass(MethodTable *pMT, GUID *pGuid); HRESULT GetDefaultInterfaceForCoclass(ITypeInfo *pTI, ITypeInfo **ppTIDef); //------------------------------------------------------------------------------------- -// Helper to get the ITypeLib* for a Assembly. -HRESULT GetITypeLibForAssembly(Assembly *pAssembly, ITypeLib **ppTLB, int bAutoCreate, int flags); - -//------------------------------------------------------------------------------------- // Helper to get the GUID of the typelib that is created from an assembly. HRESULT GetTypeLibGuidForAssembly(Assembly *pAssembly, GUID *pGuid); diff --git a/tests/src/Interop/COM/NETClients/Aggregation/App.manifest b/tests/src/Interop/COM/NETClients/Aggregation/App.manifest new file mode 100644 index 0000000000..a4e4b690e2 --- /dev/null +++ b/tests/src/Interop/COM/NETClients/Aggregation/App.manifest @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> + <assemblyIdentity + type="win32" + name="NetPrimitivesAggregation" + version="1.0.0.0" /> + + <dependency> + <dependentAssembly> + <!-- RegFree COM --> + <assemblyIdentity + type="win32" + name="COMNativeServer.X" + version="1.0.0.0"/> + </dependentAssembly> + </dependency> + +</assembly> diff --git a/tests/src/Interop/COM/NETClients/Aggregation/NETClientAggregation.csproj b/tests/src/Interop/COM/NETClients/Aggregation/NETClientAggregation.csproj new file mode 100644 index 0000000000..fb0fcd51f5 --- /dev/null +++ b/tests/src/Interop/COM/NETClients/Aggregation/NETClientAggregation.csproj @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>NETClientAggregation</AssemblyName> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{85C57688-DA98-4DE3-AC9B-526E4747434C}</ProjectGuid> + <OutputType>Exe</OutputType> + <ProjectTypeGuids>{209912F9-0DA1-4184-9CC1-8D583BAF4A28};{87799F5D-CEBD-499D-BDBA-B2C6105CD766}</ProjectTypeGuids> + <ApplicationManifest>App.manifest</ApplicationManifest> + + <!-- Test unsupported outside of windows --> + <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows> + <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild> + </PropertyGroup> + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + </PropertyGroup> + <ItemGroup> + <Compile Include="Program.cs" /> + <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.Contracts.cs" /> + <Compile Include="../../ServerContracts/ServerGuids.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="../../NativeServer/CMakeLists.txt" /> + <ProjectReference Include="../../../../Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Interop/COM/NETClients/Aggregation/Program.cs b/tests/src/Interop/COM/NETClients/Aggregation/Program.cs new file mode 100644 index 0000000000..4d595634ed --- /dev/null +++ b/tests/src/Interop/COM/NETClients/Aggregation/Program.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace NetClient +{ + using System; + using System.Runtime.InteropServices; + + using TestLibrary; + using Server.Contract; + using Server.Contract.Servers; + + class Program + { + class ManagedInner : AggregationTestingClass + { + } + + static void ValidateNativeOuter() + { + var managedInner = new ManagedInner(); + var nativeOuter = (AggregationTesting)managedInner; + + Assert.IsTrue(nativeOuter.IsAggregated()); + Assert.IsTrue(nativeOuter.AreAggregated(managedInner, nativeOuter)); + Assert.IsFalse(nativeOuter.AreAggregated(nativeOuter, new object())); + } + + static int Main(string[] doNotUse) + { + try + { + ValidateNativeOuter(); + } + catch (Exception e) + { + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + + return 100; + } + } +} diff --git a/tests/src/Interop/COM/NETClients/IDispatch/App.manifest b/tests/src/Interop/COM/NETClients/IDispatch/App.manifest new file mode 100644 index 0000000000..ca47bbbaad --- /dev/null +++ b/tests/src/Interop/COM/NETClients/IDispatch/App.manifest @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> + <assemblyIdentity + type="win32" + name="NetPrimitivesIDispatch" + version="1.0.0.0" /> + + <dependency> + <dependentAssembly> + <!-- RegFree COM --> + <assemblyIdentity + type="win32" + name="COMNativeServer.X" + version="1.0.0.0"/> + </dependentAssembly> + </dependency> + +</assembly> diff --git a/tests/src/Interop/COM/NETClients/IDispatch/NETClientIDispatch.csproj b/tests/src/Interop/COM/NETClients/IDispatch/NETClientIDispatch.csproj new file mode 100644 index 0000000000..d98acf8a57 --- /dev/null +++ b/tests/src/Interop/COM/NETClients/IDispatch/NETClientIDispatch.csproj @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>NETClientIDispatch</AssemblyName> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{85C57688-DA98-4DE3-AC9B-526E4747434C}</ProjectGuid> + <OutputType>Exe</OutputType> + <ProjectTypeGuids>{209912F9-0DA1-4184-9CC1-8D583BAF4A28};{87799F5D-CEBD-499D-BDBA-B2C6105CD766}</ProjectTypeGuids> + <ApplicationManifest>App.manifest</ApplicationManifest> + + <!-- Test unsupported outside of windows --> + <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows> + <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild> + </PropertyGroup> + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + </PropertyGroup> + <ItemGroup> + <Compile Include="Program.cs" /> + <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.Contracts.cs" /> + <Compile Include="../../ServerContracts/ServerGuids.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="../../NativeServer/CMakeLists.txt" /> + <ProjectReference Include="../../../../Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Interop/COM/NETClients/IDispatch/Program.cs b/tests/src/Interop/COM/NETClients/IDispatch/Program.cs new file mode 100644 index 0000000000..58083bf835 --- /dev/null +++ b/tests/src/Interop/COM/NETClients/IDispatch/Program.cs @@ -0,0 +1,173 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace NetClient +{ + using System; + using System.Reflection; + using System.Runtime.InteropServices; + + using TestLibrary; + using Server.Contract; + using Server.Contract.Servers; + + class Program + { + static void Validate_Numeric_In_ReturnByRef() + { + var dispatchTesting = (DispatchTesting)new DispatchTestingClass(); + + byte b1 = 1; + byte b2 = b1; + short s1 = -1; + short s2 = s1; + ushort us1 = 1; + ushort us2 = us1; + int i1 = -1; + int i2 = i1; + uint ui1 = 1; + uint ui2 = ui1; + long l1 = -1; + long l2 = l1; + ulong ul1 = 1; + ulong ul2 = ul1; + + Console.WriteLine($"Calling {nameof(DispatchTesting.DoubleNumeric_ReturnByRef)} ..."); + dispatchTesting.DoubleNumeric_ReturnByRef ( + b1, ref b2, + s1, ref s2, + us1, ref us2, + i1, ref i2, + ui1, ref ui2, + l1, ref l2, + ul1, ref ul2); + Console.WriteLine($"Call to {nameof(DispatchTesting.DoubleNumeric_ReturnByRef)} complete"); + + Assert.AreEqual(b1 * 2, b2); + Assert.AreEqual(s1 * 2, s2); + Assert.AreEqual(us1 * 2, us2); + Assert.AreEqual(i1 * 2, i2); + Assert.AreEqual(ui1 * 2, ui2); + Assert.AreEqual(l1 * 2, l2); + Assert.AreEqual(ul1 * 2, ul2); + } + + static private bool EqualByBound(float expected, float actual) + { + float low = expected - 0.0001f; + float high = expected + 0.0001f; + float eps = Math.Abs(expected - actual); + return eps < float.Epsilon || (low < actual && actual < high); + } + + static private bool EqualByBound(double expected, double actual) + { + double low = expected - 0.00001; + double high = expected + 0.00001; + double eps = Math.Abs(expected - actual); + return eps < double.Epsilon || (low < actual && actual < high); + } + + static void Validate_Float_In_ReturnAndUpdateByRef() + { + var dispatchTesting = (DispatchTesting)new DispatchTestingClass(); + + float a = .1f; + float b = .2f; + float expected = a + b; + + Console.WriteLine($"Calling {nameof(DispatchTesting.Add_Float_ReturnAndUpdateByRef)} ..."); + float c = b; + float d = dispatchTesting.Add_Float_ReturnAndUpdateByRef (a, ref c); + + Console.WriteLine($"Call to {nameof(DispatchTesting.Add_Float_ReturnAndUpdateByRef)} complete: {a} + {b} = {d}; {c} == {d}"); + Assert.IsTrue(EqualByBound(expected, c)); + Assert.IsTrue(EqualByBound(expected, d)); + } + + static void Validate_Double_In_ReturnAndUpdateByRef() + { + var dispatchTesting = (DispatchTesting)new DispatchTestingClass(); + + double a = .1; + double b = .2; + double expected = a + b; + + Console.WriteLine($"Calling {nameof(DispatchTesting.Add_Double_ReturnAndUpdateByRef)} ..."); + double c = b; + double d = dispatchTesting.Add_Double_ReturnAndUpdateByRef (a, ref c); + + Console.WriteLine($"Call to {nameof(DispatchTesting.Add_Double_ReturnAndUpdateByRef)} complete: {a} + {b} = {d}; {c} == {d}"); + Assert.IsTrue(EqualByBound(expected, c)); + Assert.IsTrue(EqualByBound(expected, d)); + } + + static int GetErrorCodeFromHResult(int hresult) + { + // https://msdn.microsoft.com/en-us/library/cc231198.aspx + return hresult & 0xffff; + } + + static void Validate_Exception() + { + var dispatchTesting = (DispatchTesting)new DispatchTestingClass(); + + int errorCode = 127; + string resultString = errorCode.ToString("x"); + try + { + Console.WriteLine($"Calling {nameof(DispatchTesting.TriggerException)} with {nameof(IDispatchTesting_Exception.Disp)} {errorCode}..."); + dispatchTesting.TriggerException(IDispatchTesting_Exception.Disp, errorCode); + Assert.Fail("DISP exception not thrown properly"); + } + catch (TargetInvocationException tie) + { + var e = (COMException)tie.InnerException; + Assert.AreEqual(GetErrorCodeFromHResult(e.HResult), errorCode); + Assert.AreEqual(e.Message, resultString); + } + + try + { + Console.WriteLine($"Calling {nameof(DispatchTesting.TriggerException)} with {nameof(IDispatchTesting_Exception.HResult)} {errorCode}..."); + dispatchTesting.TriggerException(IDispatchTesting_Exception.HResult, errorCode); + Assert.Fail("HRESULT exception not thrown properly"); + } + catch (TargetInvocationException tie) + { + var e = (COMException)tie.InnerException; + Assert.AreEqual(GetErrorCodeFromHResult(e.HResult), errorCode); + // Failing HRESULT exceptions contain CLR generated messages + } + } + + static void Validate_StructNotSupported() + { + Console.WriteLine($"IDispatch with structs not supported..."); + var dispatchTesting = (DispatchTesting)new DispatchTestingClass(); + + var input = new HFA_4() { x = 1f, y = 2f, z = 3f, w = 4f }; + Assert.Throws<NotSupportedException>(() => dispatchTesting.DoubleHVAValues(ref input)); + } + + static int Main(string[] doNotUse) + { + try + { + Validate_Numeric_In_ReturnByRef(); + Validate_Float_In_ReturnAndUpdateByRef(); + Validate_Double_In_ReturnAndUpdateByRef(); + Validate_Exception(); + Validate_StructNotSupported(); + } + catch (Exception e) + { + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + + return 100; + } + } +} diff --git a/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj b/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj index 5cbfe1d75b..ca4cac420a 100644 --- a/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj +++ b/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj @@ -26,8 +26,8 @@ <Compile Include="ErrorTests.cs" /> <Compile Include="NumericTests.cs" /> <Compile Include="StringTests.cs" /> - <Compile Include="../../ServerContracts/Primitives.cs" /> - <Compile Include="../../ServerContracts/PrimitivesNativeServer.cs" /> + <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.Contracts.cs" /> <Compile Include="../../ServerContracts/ServerGuids.cs" /> </ItemGroup> <ItemGroup> diff --git a/tests/src/Interop/COM/NETServer/NETServer.csproj b/tests/src/Interop/COM/NETServer/NETServer.csproj index 0610fca6ae..0af019f787 100644 --- a/tests/src/Interop/COM/NETServer/NETServer.csproj +++ b/tests/src/Interop/COM/NETServer/NETServer.csproj @@ -22,7 +22,7 @@ <Compile Include="ArrayTesting.cs" /> <Compile Include="StringTesting.cs" /> <Compile Include="ErrorMarshalTesting.cs" /> - <Compile Include="../ServerContracts/Primitives.cs" /> + <Compile Include="../ServerContracts/Server.Contracts.cs" /> <Compile Include="../ServerContracts/ServerGuids.cs" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> diff --git a/tests/src/Interop/COM/NativeClients/Primitives/ArrayTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/ArrayTests.cpp index 96c5554f61..1bbdc10ad8 100644 --- a/tests/src/Interop/COM/NativeClients/Primitives/ArrayTests.cpp +++ b/tests/src/Interop/COM/NativeClients/Primitives/ArrayTests.cpp @@ -95,17 +95,17 @@ namespace ::printf("Byte[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_Byte_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Byte_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_Byte_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Byte_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<byte> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_Byte_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Byte_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -118,17 +118,17 @@ namespace ::printf("Short[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_Short_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Short_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_Short_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Short_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<int16_t> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_Short_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Short_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -141,17 +141,17 @@ namespace ::printf("UShort[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_UShort_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_UShort_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_UShort_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_UShort_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<uint16_t> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_UShort_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_UShort_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -164,17 +164,17 @@ namespace ::printf("Int[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_Int_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Int_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_Int_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Int_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<int32_t> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_Int_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Int_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -187,17 +187,17 @@ namespace ::printf("UInt[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_UInt_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_UInt_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_UInt_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_UInt_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<uint32_t> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_UInt_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_UInt_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -210,17 +210,17 @@ namespace ::printf("Long[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_Long_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Long_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_Long_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Long_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<int64_t> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_Long_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Long_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -233,17 +233,17 @@ namespace ::printf("ULong[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_ULong_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_ULong_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_ULong_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_ULong_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<uint64_t> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_ULong_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_ULong_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -256,17 +256,17 @@ namespace ::printf("Float[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_Float_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Float_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_Float_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Float_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<float> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_Float_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Float_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } @@ -279,17 +279,17 @@ namespace ::printf("Double[] marshalling\n"); double actual; - THROW_IF_FAILED(arrayTesting->raw_Mean_Double_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Double_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; - THROW_IF_FAILED(arrayTesting->raw_Mean_Double_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Double_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); actual = 0.0; int len; SafeArraySmartPtr<double> saData{ data }; - THROW_IF_FAILED(arrayTesting->raw_Mean_Double_SafeArray_OutLen(saData, &len, &actual)); + THROW_IF_FAILED(arrayTesting->Mean_Double_SafeArray_OutLen(saData, &len, &actual)); THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); THROW_FAIL_IF_FALSE(len == saData.Length()); } diff --git a/tests/src/Interop/COM/NativeClients/Primitives/ClientTests.h b/tests/src/Interop/COM/NativeClients/Primitives/ClientTests.h index 029ed028ce..5ad87e8eac 100644 --- a/tests/src/Interop/COM/NativeClients/Primitives/ClientTests.h +++ b/tests/src/Interop/COM/NativeClients/Primitives/ClientTests.h @@ -4,7 +4,7 @@ #include <xplatform.h> #include <cassert> -#include <Server.Contracts.tlh> +#include <Server.Contracts.h> #define COM_CLIENT #include <Servers.h> diff --git a/tests/src/Interop/COM/NativeClients/Primitives/ErrorTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/ErrorTests.cpp index 9f0af224bd..7e40716ce9 100644 --- a/tests/src/Interop/COM/NativeClients/Primitives/ErrorTests.cpp +++ b/tests/src/Interop/COM/NativeClients/Primitives/ErrorTests.cpp @@ -24,7 +24,7 @@ namespace for (int i = 0; i < ARRAYSIZE(hrs); ++i) { HRESULT hr = hrs[i]; - HRESULT hrMaybe = et->raw_Throw_HResult(hr); + HRESULT hrMaybe = et->Throw_HResult(hr); THROW_FAIL_IF_FALSE(hr == hrMaybe); } } diff --git a/tests/src/Interop/COM/NativeClients/Primitives/NumericTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/NumericTests.cpp index 68ae4f4560..3d1a624349 100644 --- a/tests/src/Interop/COM/NativeClients/Primitives/NumericTests.cpp +++ b/tests/src/Interop/COM/NativeClients/Primitives/NumericTests.cpp @@ -16,15 +16,15 @@ namespace ::printf("Byte test invariant: %d + %d = %d\n", a, b, expected); byte c; - THROW_IF_FAILED(numericTesting->raw_Add_Byte(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Byte(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_Byte_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Byte_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_Byte_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Byte_Out(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); } @@ -36,15 +36,15 @@ namespace ::printf("Short test invariant: %d + %d = %d\n", a, b, expected); int16_t c; - THROW_IF_FAILED(numericTesting->raw_Add_Short(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Short(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_Short_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Short_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_Short_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Short_Out(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); } @@ -56,15 +56,15 @@ namespace ::printf("UShort test invariant: %u + %u = %u\n", a, b, expected); uint16_t c; - THROW_IF_FAILED(numericTesting->raw_Add_UShort(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_UShort(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_UShort_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_UShort_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_UShort_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_UShort_Out(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); } @@ -76,15 +76,15 @@ namespace ::printf("Int test invariant: %d + %d = %d\n", a, b, expected); int32_t c; - THROW_IF_FAILED(numericTesting->raw_Add_Int(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Int(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_Int_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Int_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_Int_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Int_Out(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); } @@ -96,15 +96,15 @@ namespace ::printf("UInt test invariant: %u + %u = %u\n", a, b, expected); uint32_t c; - THROW_IF_FAILED(numericTesting->raw_Add_UInt(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_UInt(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_UInt_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_UInt_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_UInt_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_UInt_Out(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); } @@ -116,15 +116,15 @@ namespace ::printf("Long test invariant: %lld + %lld = %lld\n", a, b, expected); int64_t c; - THROW_IF_FAILED(numericTesting->raw_Add_Long(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Long(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_Long_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Long_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_Long_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Long_Out(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); } @@ -136,15 +136,15 @@ namespace ::printf("ULong test invariant: %llu + %llu = %llu\n", a, b, expected); uint64_t c; - THROW_IF_FAILED(numericTesting->raw_Add_ULong(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_ULong(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_ULong_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_ULong_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_ULong_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_ULong_Out(a, b, &c)); THROW_FAIL_IF_FALSE(expected == c); } @@ -165,15 +165,15 @@ namespace ::printf("Float test invariant: %f + %f = %f\n", a, b, expected); float c; - THROW_IF_FAILED(numericTesting->raw_Add_Float(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Float(a, b, &c)); THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_Float_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Float_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_Float_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Float_Out(a, b, &c)); THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); } @@ -185,15 +185,15 @@ namespace ::printf("Double test invariant: %f + %f = %f\n", a, b, expected); double c; - THROW_IF_FAILED(numericTesting->raw_Add_Double(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Double(a, b, &c)); THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); c = std::numeric_limits<decltype(c)>::max(); - THROW_IF_FAILED(numericTesting->raw_Add_Double_Ref(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Double_Ref(a, b, &c)); THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); c = 0; - THROW_IF_FAILED(numericTesting->raw_Add_Double_Out(a, b, &c)); + THROW_IF_FAILED(numericTesting->Add_Double_Out(a, b, &c)); THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); } } diff --git a/tests/src/Interop/COM/NativeClients/Primitives/StringTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/StringTests.cpp index a9dad99668..32b5187070 100644 --- a/tests/src/Interop/COM/NativeClients/Primitives/StringTests.cpp +++ b/tests/src/Interop/COM/NativeClients/Primitives/StringTests.cpp @@ -249,7 +249,7 @@ namespace LPSTR tmp; NStr expected{ p.first, p.second }; - THROW_IF_FAILED(stringTesting->raw_Add_LPStr(p.first, p.second, &tmp)); + THROW_IF_FAILED(stringTesting->Add_LPStr(p.first, p.second, &tmp)); NStr actual; actual.Attach(tmp); @@ -272,28 +272,28 @@ namespace NStr expected; THROW_IF_FAILED(r.Reverse(expected)); - THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr(local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPStr(local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); - THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_Ref(&local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPStr_Ref(&local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); THROW_FAIL_IF_FALSE(r == local); // Local should not be changed local = r; - THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_InRef(&local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPStr_InRef(&local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); THROW_FAIL_IF_FALSE(r == local); // Local should not be changed - THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_Out(local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPStr_Out(local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); actual = local; tmp = actual; - THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_OutAttr(local, tmp)); // No-op for strings + THROW_IF_FAILED(stringTesting->Reverse_LPStr_OutAttr(local, tmp)); // No-op for strings THROW_FAIL_IF_FALSE(local == actual); } } @@ -309,7 +309,7 @@ namespace { LPWSTR tmp; WStr expected{ p.first, p.second }; - THROW_IF_FAILED(stringTesting->raw_Add_LPWStr(p.first, p.second, &tmp)); + THROW_IF_FAILED(stringTesting->Add_LPWStr(p.first, p.second, &tmp)); WStr actual; actual.Attach(tmp); @@ -326,28 +326,28 @@ namespace WStr expected; THROW_IF_FAILED(r.Reverse(expected)); - THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr(local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPWStr(local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); - THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_Ref(&local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPWStr_Ref(&local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); THROW_FAIL_IF_FALSE(r == local); // Local should not be changed local = r; - THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_InRef(&local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPWStr_InRef(&local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); THROW_FAIL_IF_FALSE(r == local); // Local should not be changed - THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_Out(local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_LPWStr_Out(local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); actual = local; tmp = actual; - THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_OutAttr(local, tmp)); // No-op for strings + THROW_IF_FAILED(stringTesting->Reverse_LPWStr_OutAttr(local, tmp)); // No-op for strings THROW_FAIL_IF_FALSE(local == actual); } } @@ -363,7 +363,7 @@ namespace { BSTR tmp; BStr expected{ p.first, p.second }; - THROW_IF_FAILED(stringTesting->raw_Add_BStr(p.first, p.second, &tmp)); + THROW_IF_FAILED(stringTesting->Add_BStr(p.first, p.second, &tmp)); BStr actual; actual.Attach(tmp); @@ -380,28 +380,28 @@ namespace BStr expected; THROW_IF_FAILED(r.Reverse(expected)); - THROW_IF_FAILED(stringTesting->raw_Reverse_BStr(local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_BStr(local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); - THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_Ref(&local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_BStr_Ref(&local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); THROW_FAIL_IF_FALSE(r == local); // Local should not be changed local = r; - THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_InRef(&local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_BStr_InRef(&local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); THROW_FAIL_IF_FALSE(r == local); // Local should not be changed - THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_Out(local, &tmp)); + THROW_IF_FAILED(stringTesting->Reverse_BStr_Out(local, &tmp)); actual.Attach(tmp); THROW_FAIL_IF_FALSE(expected == actual); actual = local; tmp = actual; - THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_OutAttr(local, tmp)); // No-op for strings + THROW_IF_FAILED(stringTesting->Reverse_BStr_OutAttr(local, tmp)); // No-op for strings THROW_FAIL_IF_FALSE(local == actual); } } diff --git a/tests/src/Interop/COM/NativeServer/AggregationTesting.h b/tests/src/Interop/COM/NativeServer/AggregationTesting.h new file mode 100644 index 0000000000..259e1f3914 --- /dev/null +++ b/tests/src/Interop/COM/NativeServer/AggregationTesting.h @@ -0,0 +1,119 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#pragma once + +#include "Servers.h" + +class AggregationTesting : public UnknownImpl, public IUnknown +{ +public: + AggregationTesting(_In_opt_ IUnknown *pUnkOuter) + : _outer{ pUnkOuter == nullptr ? this : pUnkOuter } + , _impl{ _outer, _outer != this } + { } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + if (ppvObject == nullptr) + return E_POINTER; + + if (riid == IID_IUnknown) + { + *ppvObject = static_cast<IUnknown*>(this); + } + else if(riid == IID_IAggregationTesting) + { + *ppvObject = static_cast<IAggregationTesting*>(&_impl); + } + else + { + return E_NOINTERFACE; + } + + ((IUnknown*)*ppvObject)->AddRef(); + return S_OK; + } + + DEFINE_REF_COUNTING(); + +private: + // Implementation for class to support COM aggregation + class AggregationTestingImpl : public IAggregationTesting + { + public: + AggregationTestingImpl(_In_ IUnknown *pUnkOuter, _In_ bool isAggregated) + : _implOuter{ pUnkOuter } + , _isAggregated{ isAggregated } + { } + + public: // IAggregationTesting + HRESULT STDMETHODCALLTYPE Add_Int( + /*[in]*/ int a, + /*[in]*/ int b, + /*[out,retval]*/ int * pRetVal) + { + *pRetVal = a + b; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE IsAggregated( + _Out_ VARIANT_BOOL *isAggregated) + { + *isAggregated = _isAggregated ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE AreAggregated( + _In_ IUnknown *aggregateMaybe1, + _In_ IUnknown *aggregateMaybe2, + _Out_ VARIANT_BOOL *areAggregated) + { + HRESULT hr; + + *areAggregated = VARIANT_FALSE; + + IUnknown *unknown1; + RETURN_IF_FAILED(aggregateMaybe1->QueryInterface(IID_IUnknown, (void**)&unknown1)); + + IUnknown *unknown2; + RETURN_IF_FAILED(aggregateMaybe2->QueryInterface(IID_IUnknown, (void**)&unknown2)); + + if (unknown1 == unknown2) + *areAggregated = VARIANT_TRUE; + + unknown1->Release(); + unknown2->Release(); + return S_OK; + } + + public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return _implOuter->QueryInterface(riid, ppvObject); + } + + STDMETHODIMP_(ULONG) AddRef(void) + { + return _implOuter->AddRef(); + } + + STDMETHODIMP_(ULONG) Release(void) + { + return _implOuter->Release(); + } + + private: + IUnknown *_implOuter; + const bool _isAggregated; + }; + + IUnknown *_outer; + AggregationTestingImpl _impl; +}; diff --git a/tests/src/Interop/COM/NativeServer/ArrayTesting.h b/tests/src/Interop/COM/NativeServer/ArrayTesting.h index 27d02396a2..8366a1c149 100644 --- a/tests/src/Interop/COM/NativeServer/ArrayTesting.h +++ b/tests/src/Interop/COM/NativeServer/ArrayTesting.h @@ -73,7 +73,7 @@ private: } public: // IArrayTesting - DEF_RAWFUNC(Mean_Byte_LP_PreLen)( + DEF_FUNC(Mean_Byte_LP_PreLen)( /*[in]*/ int len, /*[in]*/ unsigned char * d, /*[out,retval]*/ double * pRetVal) @@ -83,7 +83,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Short_LP_PreLen)( + DEF_FUNC(Mean_Short_LP_PreLen)( /*[in]*/ int len, /*[in]*/ short * d, /*[out,retval]*/ double * pRetVal) @@ -93,7 +93,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_UShort_LP_PreLen)( + DEF_FUNC(Mean_UShort_LP_PreLen)( /*[in]*/ int len, /*[in]*/ unsigned short * d, /*[out,retval]*/ double * pRetVal) @@ -103,7 +103,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Int_LP_PreLen)( + DEF_FUNC(Mean_Int_LP_PreLen)( /*[in]*/ int len, /*[in]*/ int * d, /*[out,retval]*/ double * pRetVal) @@ -113,7 +113,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_UInt_LP_PreLen)( + DEF_FUNC(Mean_UInt_LP_PreLen)( /*[in]*/ int len, /*[in]*/ unsigned int * d, /*[out,retval]*/ double * pRetVal) @@ -123,7 +123,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Long_LP_PreLen)( + DEF_FUNC(Mean_Long_LP_PreLen)( /*[in]*/ int len, /*[in]*/ __int64 * d, /*[out,retval]*/ double * pRetVal) @@ -133,7 +133,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_ULong_LP_PreLen)( + DEF_FUNC(Mean_ULong_LP_PreLen)( /*[in]*/ int len, /*[in]*/ unsigned __int64 * d, /*[out,retval]*/ double * pRetVal) @@ -143,7 +143,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Float_LP_PreLen)( + DEF_FUNC(Mean_Float_LP_PreLen)( /*[in]*/ int len, /*[in]*/ float * d, /*[out,retval]*/ double * pRetVal) @@ -153,7 +153,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Double_LP_PreLen)( + DEF_FUNC(Mean_Double_LP_PreLen)( /*[in]*/ int len, /*[in]*/ double * d, /*[out,retval]*/ double * pRetVal) @@ -163,7 +163,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Byte_LP_PostLen)( + DEF_FUNC(Mean_Byte_LP_PostLen)( /*[in]*/ unsigned char * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -173,7 +173,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Short_LP_PostLen)( + DEF_FUNC(Mean_Short_LP_PostLen)( /*[in]*/ short * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -183,7 +183,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_UShort_LP_PostLen)( + DEF_FUNC(Mean_UShort_LP_PostLen)( /*[in]*/ unsigned short * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -193,7 +193,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Int_LP_PostLen)( + DEF_FUNC(Mean_Int_LP_PostLen)( /*[in]*/ int * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -203,7 +203,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_UInt_LP_PostLen)( + DEF_FUNC(Mean_UInt_LP_PostLen)( /*[in]*/ unsigned int * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -213,7 +213,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Long_LP_PostLen)( + DEF_FUNC(Mean_Long_LP_PostLen)( /*[in]*/ __int64 * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -223,7 +223,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_ULong_LP_PostLen)( + DEF_FUNC(Mean_ULong_LP_PostLen)( /*[in]*/ unsigned __int64 * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -233,7 +233,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Float_LP_PostLen)( + DEF_FUNC(Mean_Float_LP_PostLen)( /*[in]*/ float * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -243,7 +243,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Double_LP_PostLen)( + DEF_FUNC(Mean_Double_LP_PostLen)( /*[in]*/ double * d, /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) @@ -253,7 +253,7 @@ public: // IArrayTesting *pRetVal = Mean(len, d); return S_OK; } - DEF_RAWFUNC(Mean_Byte_SafeArray_OutLen)( + DEF_FUNC(Mean_Byte_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -262,7 +262,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_UI1>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_Short_SafeArray_OutLen)( + DEF_FUNC(Mean_Short_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -271,7 +271,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_I2>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_UShort_SafeArray_OutLen)( + DEF_FUNC(Mean_UShort_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -280,7 +280,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_UI2>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_Int_SafeArray_OutLen)( + DEF_FUNC(Mean_Int_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -289,7 +289,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_I4>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_UInt_SafeArray_OutLen)( + DEF_FUNC(Mean_UInt_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -298,7 +298,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_UI4>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_Long_SafeArray_OutLen)( + DEF_FUNC(Mean_Long_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -307,7 +307,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_I8>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_ULong_SafeArray_OutLen)( + DEF_FUNC(Mean_ULong_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -316,7 +316,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_UI8>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_Float_SafeArray_OutLen)( + DEF_FUNC(Mean_Float_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) @@ -325,7 +325,7 @@ public: // IArrayTesting return E_POINTER; return Mean<VT_R4>(d, len, pRetVal); } - DEF_RAWFUNC(Mean_Double_SafeArray_OutLen)( + DEF_FUNC(Mean_Double_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) diff --git a/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest b/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest index 13c36c9099..adeaba1361 100644 --- a/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest +++ b/tests/src/Interop/COM/NativeServer/COMNativeServer.X.manifest @@ -26,6 +26,16 @@ <comClass clsid="{71CF5C45-106C-4B32-B418-43A463C6041F}" threadingModel="Both" /> + + <!-- DispatchTesting --> + <comClass + clsid="{0F8ACD0C-ECE0-4F2A-BD1B-6BFCA93A0726}" + threadingModel="Both" /> + + <!-- AggregationTesting --> + <comClass + clsid="{4CEFE36D-F377-4B6E-8C34-819A8BB9CB04}" + threadingModel="Both" /> </file> </assembly> diff --git a/tests/src/Interop/COM/NativeServer/ComHelpers.h b/tests/src/Interop/COM/NativeServer/ComHelpers.h index 651ccc5364..fd8963996f 100644 --- a/tests/src/Interop/COM/NativeServer/ComHelpers.h +++ b/tests/src/Interop/COM/NativeServer/ComHelpers.h @@ -167,3 +167,62 @@ public: // IUnknown DEFINE_REF_COUNTING(); }; + +// Templated class factory for aggregation +template<typename T> +class ClassFactoryAggregate : public UnknownImpl, public IClassFactory +{ +public: // static + static HRESULT Create(_In_ REFIID riid, _Outptr_ LPVOID FAR* ppv) + { + try + { + auto cf = new ClassFactoryAggregate(); + HRESULT hr = cf->QueryInterface(riid, ppv); + cf->Release(); + return hr; + } + catch (const std::bad_alloc&) + { + return E_OUTOFMEMORY; + } + } + +public: // IClassFactory + STDMETHOD(CreateInstance)( + _In_opt_ IUnknown *pUnkOuter, + _In_ REFIID riid, + _COM_Outptr_ void **ppvObject) + { + if (pUnkOuter != nullptr && riid != IID_IUnknown) + return CLASS_E_NOAGGREGATION; + + try + { + auto ti = new T(pUnkOuter); + HRESULT hr = ti->QueryInterface(riid, ppvObject); + ti->Release(); + return hr; + } + catch (const std::bad_alloc&) + { + return E_OUTOFMEMORY; + } + } + + STDMETHOD(LockServer)(/* [in] */ BOOL fLock) + { + assert(false && "Not impl"); + return E_NOTIMPL; + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface<ClassFactoryAggregate, IClassFactory>(this, riid, ppvObject); + } + + DEFINE_REF_COUNTING(); +}; diff --git a/tests/src/Interop/COM/NativeServer/DispatchTesting.h b/tests/src/Interop/COM/NativeServer/DispatchTesting.h new file mode 100644 index 0000000000..8ee32a1dae --- /dev/null +++ b/tests/src/Interop/COM/NativeServer/DispatchTesting.h @@ -0,0 +1,434 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#pragma once + +#include "Servers.h" + +template<typename T> +HRESULT VerifyValues(_In_ const T expected, _In_ const T actual) +{ + return (expected == actual) ? S_OK : E_INVALIDARG; +} + +VARIANTARG *NextArg(_In_ VARIANTARG *args, _Inout_ size_t &currIndex) +{ + return (args + (currIndex--)); +} + +class DispatchTesting : public UnknownImpl, public IDispatchTesting +{ +private: + static const WCHAR * const Names[]; + static const int NamesCount; + +public: // IDispatch + virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( + /* [out] */ __RPC__out UINT *pctinfo) + { + *pctinfo = 0; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) + { + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( + /* [in] */ __RPC__in REFIID, + /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, + /* [range][in] */ __RPC__in_range(0,16384) UINT cNames, + /* [in] */ LCID, + /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) + { + bool containsUnknown = false; + DISPID *curr = rgDispId; + for (UINT i = 0; i < cNames; ++i) + { + *curr = DISPID_UNKNOWN; + LPOLESTR name = rgszNames[i]; + for (int j = 1; j < NamesCount; ++j) + { + const WCHAR *nameMaybe = Names[j]; + if (::wcscmp(name, nameMaybe) == 0) + { + *curr = DISPID{ j }; + break; + } + } + + containsUnknown &= (*curr == DISPID_UNKNOWN); + curr++; + } + + return (containsUnknown) ? DISP_E_UNKNOWNNAME : S_OK; + } + + virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( + /* [annotation][in] */ _In_ DISPID dispIdMember, + /* [annotation][in] */ _In_ REFIID riid, + /* [annotation][in] */ _In_ LCID lcid, + /* [annotation][in] */ _In_ WORD wFlags, + /* [annotation][out][in] */ _In_ DISPPARAMS *pDispParams, + /* [annotation][out] */ _Out_opt_ VARIANT *pVarResult, + /* [annotation][out] */ _Out_opt_ EXCEPINFO *pExcepInfo, + /* [annotation][out] */ _Out_opt_ UINT *puArgErr) + { + // + // Note that arguments are received in reverse order for IDispatch::Invoke() + // + + HRESULT hr; + + switch (dispIdMember) + { + case 1: + { + RETURN_IF_FAILED(VerifyValues<VARIANT*>(pVarResult, nullptr)); + return DoubleNumeric_ReturnByRef_Proxy(pDispParams); + } + case 2: + { + return Add_Float_ReturnAndUpdateByRef_Proxy(pDispParams, pVarResult); + } + case 3: + { + return Add_Double_ReturnAndUpdateByRef_Proxy(pDispParams, pVarResult); + } + case 4: + { + return TriggerException_Proxy(pDispParams, pExcepInfo, puArgErr); + } + case 5: + { + return DoubleHVAValues_Proxy(pDispParams, pVarResult); + } + } + + return E_NOTIMPL; + } + +public: // IDispatchTesting + virtual HRESULT STDMETHODCALLTYPE DoubleNumeric_ReturnByRef ( + /*[in]*/ unsigned char b1, + /*[in,out]*/ unsigned char *b2, + /*[in]*/ short s1, + /*[in,out]*/ short *s2, + /*[in]*/ unsigned short us1, + /*[in,out]*/ unsigned short *us2, + /*[in]*/ int i1, + /*[in,out]*/ int *i2, + /*[in]*/ unsigned int ui1, + /*[in,out]*/ unsigned int *ui2, + /*[in]*/ __int64 l1, + /*[in,out]*/ __int64 *l2, + /*[in]*/ unsigned __int64 ul1, + /*[in,out]*/ unsigned __int64 *ul2 ) + { + *b2 = static_cast<unsigned char>(b1 * 2); + *s2 = static_cast<short>(s1 * 2); + *us2 = static_cast<unsigned short>(us1 * 2); + *i2 = i1 * 2; + *ui2 = ui1 * 2u; + *l2 = l1 * 2ll; + *ul2 = ul1 * 2ull; + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE Add_Float_ReturnAndUpdateByRef( + /*[in]*/ float a, + /*[in,out]*/ float *b, + /*[out,retval]*/ float * pRetVal) + { + float c = a + *b; + *pRetVal = *b = c; + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE Add_Double_ReturnAndUpdateByRef( + /*[in]*/ double a, + /*[in,out]*/ double *b, + /*[out,retval]*/ double * pRetVal) + { + double c = a + *b; + *pRetVal = *b = c; + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE TriggerException ( + /*[in]*/ enum IDispatchTesting_Exception excep, + /*[in]*/ int errorCode) + { + switch (excep) + { + case IDispatchTesting_Exception_Disp: + return DISP_E_EXCEPTION; + case IDispatchTesting_Exception_HResult: + return HRESULT_FROM_WIN32(errorCode); + default: + return S_FALSE; // Return a success case to indicate failure to trigger a failure. + } + } + virtual HRESULT STDMETHODCALLTYPE DoubleHVAValues ( + /*[in,out]*/ HFA_4 *input, + /*[out,retval]*/ HFA_4 *pRetVal) + { + pRetVal->x = (input->x * 2); + pRetVal->y = (input->y * 2); + pRetVal->z = (input->z * 2); + pRetVal->w = (input->w * 2); + return S_OK; + } + +private: + HRESULT DoubleNumeric_ReturnByRef_Proxy(_In_ DISPPARAMS *pDispParams) + { + HRESULT hr; + + unsigned char *b_args[2]; + short *s_args[2]; + unsigned short *us_args[2]; + int *i_args[2]; + unsigned int *ui_args[2]; + __int64 *l_args[2]; + unsigned __int64 *ul_args[2]; + size_t expectedArgCount = + ARRAYSIZE(b_args) + + ARRAYSIZE(s_args) + + ARRAYSIZE(us_args) + + ARRAYSIZE(i_args) + + ARRAYSIZE(ui_args) + + ARRAYSIZE(l_args) + + ARRAYSIZE(ul_args); + RETURN_IF_FAILED(VerifyValues(UINT(expectedArgCount), pDispParams->cArgs)); + + VARENUM currType; + VARIANTARG *currArg; + size_t argIdx = expectedArgCount - 1; + + // Extract args + { + currType = VT_UI1; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + b_args[0] = &currArg->bVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + b_args[1] = (unsigned char*)currArg->byref; + } + { + currType = VT_I2; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + s_args[0] = &currArg->iVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + s_args[1] = (short*)currArg->byref; + } + { + currType = VT_UI2; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + us_args[0] = &currArg->uiVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + us_args[1] = (unsigned short*)currArg->byref; + } + { + currType = VT_I4; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + i_args[0] = &currArg->intVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + i_args[1] = (int*)currArg->byref; + } + { + currType = VT_UI4; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + ui_args[0] = &currArg->uintVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + ui_args[1] = (unsigned int*)currArg->byref; + } + { + currType = VT_I8; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + l_args[0] = &currArg->llVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + l_args[1] = (__int64*)currArg->byref; + } + { + currType = VT_UI8; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + ul_args[0] = &currArg->ullVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + ul_args[1] = (unsigned __int64*)currArg->byref; + } + + return DoubleNumeric_ReturnByRef( + *b_args[0], b_args[1], + *s_args[0], s_args[1], + *us_args[0], us_args[1], + *i_args[0], i_args[1], + *ui_args[0], ui_args[1], + *l_args[0], l_args[1], + *ul_args[0], ul_args[1]); + } + + HRESULT Add_Float_ReturnAndUpdateByRef_Proxy(_In_ DISPPARAMS *pDispParams, _Inout_ VARIANT *pVarResult) + { + HRESULT hr; + + float *args[2]; + size_t expectedArgCount = ARRAYSIZE(args); + RETURN_IF_FAILED(VerifyValues(UINT(expectedArgCount), pDispParams->cArgs)); + + if (pVarResult == nullptr) + return E_POINTER; + + VARENUM currType; + VARIANTARG *currArg; + size_t argIdx = expectedArgCount - 1; + + // Extract args + { + currType = VT_R4; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + args[0] = &currArg->fltVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + args[1] = (float*)currArg->byref; + } + + RETURN_IF_FAILED(::VariantChangeType(pVarResult, pVarResult, 0, VT_R4)); + return Add_Float_ReturnAndUpdateByRef(*args[0], args[1], &pVarResult->fltVal); + } + + HRESULT Add_Double_ReturnAndUpdateByRef_Proxy(_In_ DISPPARAMS *pDispParams, _Inout_ VARIANT *pVarResult) + { + HRESULT hr; + + double *args[2]; + size_t expectedArgCount = ARRAYSIZE(args); + RETURN_IF_FAILED(VerifyValues(UINT(expectedArgCount), pDispParams->cArgs)); + + if (pVarResult == nullptr) + return E_POINTER; + + VARENUM currType; + VARIANTARG *currArg; + size_t argIdx = expectedArgCount - 1; + + // Extract args + { + currType = VT_R8; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + args[0] = &currArg->dblVal; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(VT_BYREF | currType), VARENUM(currArg->vt))); + args[1] = (double*)currArg->byref; + } + + RETURN_IF_FAILED(::VariantChangeType(pVarResult, pVarResult, 0, VT_R8)); + return Add_Double_ReturnAndUpdateByRef(*args[0], args[1], &pVarResult->dblVal); + } + + HRESULT TriggerException_Proxy( + _In_ DISPPARAMS *pDispParams, + _Out_ EXCEPINFO *pExcepInfo, + _Out_ UINT *puArgErr) + { + HRESULT hr; + + int *args[2]; + size_t expectedArgCount = ARRAYSIZE(args); + RETURN_IF_FAILED(VerifyValues(UINT(expectedArgCount), pDispParams->cArgs)); + + VARENUM currType; + VARIANTARG *currArg; + size_t argIdx = expectedArgCount - 1; + + // Extract args + { + currType = VT_I4; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + args[0] = &currArg->intVal; + } + { + currType = VT_I4; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + args[1] = &currArg->intVal; + } + + hr = TriggerException(static_cast<IDispatchTesting_Exception>(*args[0]), *args[1]); + if (hr == DISP_E_EXCEPTION) + { + *puArgErr = 1; + pExcepInfo->scode = HRESULT_FROM_WIN32(*args[1]); + + WCHAR buffer[ARRAYSIZE(W("4294967295"))]; + _snwprintf_s(buffer, ARRAYSIZE(buffer), _TRUNCATE, W("%x"), *args[1]); + pExcepInfo->bstrDescription = SysAllocString(buffer); + } + + return hr; + } + + HRESULT DoubleHVAValues_Proxy(_In_ DISPPARAMS *pDispParams, _Inout_ VARIANT *pVarResult) + { + HRESULT hr; + + HFA_4 *args[1]; + size_t expectedArgCount = ARRAYSIZE(args); + RETURN_IF_FAILED(VerifyValues(UINT(expectedArgCount), pDispParams->cArgs)); + + VARENUM currType; + VARIANTARG *currArg; + size_t argIdx = expectedArgCount - 1; + + // Extract args + { + currType = VT_RECORD; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + args[0] = (HFA_4*)currArg->pvRecord; + } + + RETURN_IF_FAILED(::VariantChangeType(pVarResult, pVarResult, 0, VT_RECORD)); + return DoubleHVAValues(args[0], (HFA_4*)&pVarResult->pvRecord); + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface<DispatchTesting, IDispatch, IDispatchTesting>(this, riid, ppvObject); + } + + DEFINE_REF_COUNTING(); +}; + +const WCHAR * const DispatchTesting::Names[] = +{ + W("__RESERVED__"), + W("DoubleNumeric_ReturnByRef"), + W("Add_Float_ReturnAndUpdateByRef"), + W("Add_Double_ReturnAndUpdateByRef"), + W("TriggerException"), + W("DoubleHVAValues") +}; + +const int DispatchTesting::NamesCount = ARRAYSIZE(DispatchTesting::Names); diff --git a/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h b/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h index 2b1276c989..28c0011601 100644 --- a/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h +++ b/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h @@ -9,7 +9,7 @@ class ErrorMarshalTesting : public UnknownImpl, public IErrorMarshalTesting { public: // IErrorMarshalTesting - DEF_RAWFUNC(Throw_HResult)( + DEF_FUNC(Throw_HResult)( /*[in]*/ int hresultToReturn) { return HRESULT{ hresultToReturn }; diff --git a/tests/src/Interop/COM/NativeServer/NumericTesting.h b/tests/src/Interop/COM/NativeServer/NumericTesting.h index 1f4acf9b0f..a6e76ec7a6 100644 --- a/tests/src/Interop/COM/NativeServer/NumericTesting.h +++ b/tests/src/Interop/COM/NativeServer/NumericTesting.h @@ -11,7 +11,7 @@ class NumericTesting : public UnknownImpl, public INumericTesting { public: - DEF_RAWFUNC(Add_Byte)( + DEF_FUNC(Add_Byte)( /*[in]*/ unsigned char a, /*[in]*/ unsigned char b, /*[out,retval]*/ unsigned char * pRetVal) @@ -19,7 +19,7 @@ public: *pRetVal = static_cast<unsigned char>(a + b); return S_OK; } - DEF_RAWFUNC(Add_Short)( + DEF_FUNC(Add_Short)( /*[in]*/ short a, /*[in]*/ short b, /*[out,retval]*/ short * pRetVal) @@ -27,7 +27,7 @@ public: *pRetVal = static_cast<short>(a + b); return S_OK; } - DEF_RAWFUNC(Add_UShort)( + DEF_FUNC(Add_UShort)( /*[in]*/ unsigned short a, /*[in]*/ unsigned short b, /*[out,retval]*/ unsigned short * pRetVal) @@ -35,7 +35,7 @@ public: *pRetVal = static_cast<unsigned short>(a + b); return S_OK; } - DEF_RAWFUNC(Add_Int)( + DEF_FUNC(Add_Int)( /*[in]*/ int a, /*[in]*/ int b, /*[out,retval]*/ int * pRetVal) @@ -43,7 +43,7 @@ public: *pRetVal = a + b; return S_OK; } - DEF_RAWFUNC(Add_UInt)( + DEF_FUNC(Add_UInt)( /*[in]*/ unsigned int a, /*[in]*/ unsigned int b, /*[out,retval]*/ unsigned int * pRetVal) @@ -51,7 +51,7 @@ public: *pRetVal = a + b; return S_OK; } - DEF_RAWFUNC(Add_Long)( + DEF_FUNC(Add_Long)( /*[in]*/ __int64 a, /*[in]*/ __int64 b, /*[out,retval]*/ __int64 * pRetVal) @@ -59,7 +59,7 @@ public: *pRetVal = a + b; return S_OK; } - DEF_RAWFUNC(Add_ULong)( + DEF_FUNC(Add_ULong)( /*[in]*/ unsigned __int64 a, /*[in]*/ unsigned __int64 b, /*[out,retval]*/ unsigned __int64 * pRetVal) @@ -67,7 +67,7 @@ public: *pRetVal = a + b; return S_OK; } - DEF_RAWFUNC(Add_Float)( + DEF_FUNC(Add_Float)( /*[in]*/ float a, /*[in]*/ float b, /*[out,retval]*/ float * pRetVal) @@ -75,7 +75,7 @@ public: *pRetVal = a + b; return S_OK; } - DEF_RAWFUNC(Add_Double)( + DEF_FUNC(Add_Double)( /*[in]*/ double a, /*[in]*/ double b, /*[out,retval]*/ double * pRetVal) @@ -83,7 +83,7 @@ public: *pRetVal = a + b; return S_OK; } - DEF_RAWFUNC(Add_Byte_Ref)( + DEF_FUNC(Add_Byte_Ref)( /*[in]*/ unsigned char a, /*[in]*/ unsigned char b, /*[in,out]*/ unsigned char * c) @@ -93,7 +93,7 @@ public: *c = static_cast<unsigned char>(a + b); return S_OK; } - DEF_RAWFUNC(Add_Short_Ref)( + DEF_FUNC(Add_Short_Ref)( /*[in]*/ short a, /*[in]*/ short b, /*[in,out]*/ short * c) @@ -103,7 +103,7 @@ public: *c = static_cast<short>(a + b); return S_OK; } - DEF_RAWFUNC(Add_UShort_Ref)( + DEF_FUNC(Add_UShort_Ref)( /*[in]*/ unsigned short a, /*[in]*/ unsigned short b, /*[in,out]*/ unsigned short * c) @@ -113,7 +113,7 @@ public: *c = static_cast<unsigned short>(a + b); return S_OK; } - DEF_RAWFUNC(Add_Int_Ref)( + DEF_FUNC(Add_Int_Ref)( /*[in]*/ int a, /*[in]*/ int b, /*[in,out]*/ int * c) @@ -123,7 +123,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_UInt_Ref)( + DEF_FUNC(Add_UInt_Ref)( /*[in]*/ unsigned int a, /*[in]*/ unsigned int b, /*[in,out]*/ unsigned int * c) @@ -133,7 +133,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_Long_Ref)( + DEF_FUNC(Add_Long_Ref)( /*[in]*/ __int64 a, /*[in]*/ __int64 b, /*[in,out]*/ __int64 * c) @@ -143,7 +143,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_ULong_Ref)( + DEF_FUNC(Add_ULong_Ref)( /*[in]*/ unsigned __int64 a, /*[in]*/ unsigned __int64 b, /*[in,out]*/ unsigned __int64 * c) @@ -153,7 +153,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_Float_Ref)( + DEF_FUNC(Add_Float_Ref)( /*[in]*/ float a, /*[in]*/ float b, /*[in,out]*/ float * c) @@ -163,7 +163,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_Double_Ref)( + DEF_FUNC(Add_Double_Ref)( /*[in]*/ double a, /*[in]*/ double b, /*[in,out]*/ double * c) @@ -173,7 +173,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_Byte_Out)( + DEF_FUNC(Add_Byte_Out)( /*[in]*/ unsigned char a, /*[in]*/ unsigned char b, /*[out]*/ unsigned char * c) @@ -181,7 +181,7 @@ public: *c = static_cast<unsigned char>(a + b); return S_OK; } - DEF_RAWFUNC(Add_Short_Out)( + DEF_FUNC(Add_Short_Out)( /*[in]*/ short a, /*[in]*/ short b, /*[out]*/ short * c) @@ -189,7 +189,7 @@ public: *c = static_cast<short>(a + b); return S_OK; } - DEF_RAWFUNC(Add_UShort_Out)( + DEF_FUNC(Add_UShort_Out)( /*[in]*/ unsigned short a, /*[in]*/ unsigned short b, /*[out]*/ unsigned short * c) @@ -197,7 +197,7 @@ public: *c = static_cast<unsigned short>(a + b); return S_OK; } - DEF_RAWFUNC(Add_Int_Out)( + DEF_FUNC(Add_Int_Out)( /*[in]*/ int a, /*[in]*/ int b, /*[out]*/ int * c) @@ -205,7 +205,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_UInt_Out)( + DEF_FUNC(Add_UInt_Out)( /*[in]*/ unsigned int a, /*[in]*/ unsigned int b, /*[out]*/ unsigned int * c) @@ -213,7 +213,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_Long_Out)( + DEF_FUNC(Add_Long_Out)( /*[in]*/ __int64 a, /*[in]*/ __int64 b, /*[out]*/ __int64 * c) @@ -221,7 +221,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_ULong_Out)( + DEF_FUNC(Add_ULong_Out)( /*[in]*/ unsigned __int64 a, /*[in]*/ unsigned __int64 b, /*[out]*/ unsigned __int64 * c) @@ -229,7 +229,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_Float_Out)( + DEF_FUNC(Add_Float_Out)( /*[in]*/ float a, /*[in]*/ float b, /*[out]*/ float * c) @@ -237,7 +237,7 @@ public: *c = a + b; return S_OK; } - DEF_RAWFUNC(Add_Double_Out)( + DEF_FUNC(Add_Double_Out)( /*[in]*/ double a, /*[in]*/ double b, /*[out]*/ double * c) diff --git a/tests/src/Interop/COM/NativeServer/Servers.cpp b/tests/src/Interop/COM/NativeServer/Servers.cpp index 27f0d29963..af1848300d 100644 --- a/tests/src/Interop/COM/NativeServer/Servers.cpp +++ b/tests/src/Interop/COM/NativeServer/Servers.cpp @@ -164,6 +164,8 @@ STDAPI DllRegisterServer(void) RETURN_IF_FAILED(RegisterClsid(__uuidof(ArrayTesting), L"Both")); RETURN_IF_FAILED(RegisterClsid(__uuidof(StringTesting), L"Both")); RETURN_IF_FAILED(RegisterClsid(__uuidof(ErrorMarshalTesting), L"Both")); + RETURN_IF_FAILED(RegisterClsid(__uuidof(DispatchTesting), L"Both")); + RETURN_IF_FAILED(RegisterClsid(__uuidof(AggregationTesting), L"Both")); return S_OK; } @@ -176,6 +178,8 @@ STDAPI DllUnregisterServer(void) RETURN_IF_FAILED(RemoveClsid(__uuidof(ArrayTesting))); RETURN_IF_FAILED(RemoveClsid(__uuidof(StringTesting))); RETURN_IF_FAILED(RemoveClsid(__uuidof(ErrorMarshalTesting))); + RETURN_IF_FAILED(RemoveClsid(__uuidof(DispatchTesting))); + RETURN_IF_FAILED(RemoveClsid(__uuidof(AggregationTesting))); return S_OK; } @@ -194,5 +198,11 @@ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID FA if (rclsid == __uuidof(ErrorMarshalTesting)) return ClassFactoryBasic<ErrorMarshalTesting>::Create(riid, ppv); + if (rclsid == __uuidof(DispatchTesting)) + return ClassFactoryBasic<DispatchTesting>::Create(riid, ppv); + + if (rclsid == __uuidof(AggregationTesting)) + return ClassFactoryAggregate<AggregationTesting>::Create(riid, ppv); + return CLASS_E_CLASSNOTAVAILABLE; } diff --git a/tests/src/Interop/COM/NativeServer/Servers.h b/tests/src/Interop/COM/NativeServer/Servers.h index 4f279e0a14..475aeded96 100644 --- a/tests/src/Interop/COM/NativeServer/Servers.h +++ b/tests/src/Interop/COM/NativeServer/Servers.h @@ -7,24 +7,29 @@ #include <xplatform.h> #include <cassert> -//#import "Server.Contract.tlb" no_namespace -#include <Server.Contracts.tlh> +#include <Server.Contracts.h> // Forward declare servers so COM clients can reference the CLSIDs class DECLSPEC_UUID("53169A33-E85D-4E3C-B668-24E438D0929B") NumericTesting; class DECLSPEC_UUID("B99ABE6A-DFF6-440F-BFB6-55179B8FE18E") ArrayTesting; class DECLSPEC_UUID("C73C83E8-51A2-47F8-9B5C-4284458E47A6") StringTesting; class DECLSPEC_UUID("71CF5C45-106C-4B32-B418-43A463C6041F") ErrorMarshalTesting; +class DECLSPEC_UUID("0F8ACD0C-ECE0-4F2A-BD1B-6BFCA93A0726") DispatchTesting; +class DECLSPEC_UUID("4CEFE36D-F377-4B6E-8C34-819A8BB9CB04") AggregationTesting; #define CLSID_NumericTesting __uuidof(NumericTesting) #define CLSID_ArrayTesting __uuidof(ArrayTesting) #define CLSID_StringTesting __uuidof(StringTesting) #define CLSID_ErrorMarshalTesting __uuidof(ErrorMarshalTesting) +#define CLSID_DispatchTesting __uuidof(DispatchTesting) +#define CLSID_AggregationTesting __uuidof(AggregationTesting) #define IID_INumericTesting __uuidof(INumericTesting) #define IID_IArrayTesting __uuidof(IArrayTesting) #define IID_IStringTesting __uuidof(IStringTesting) #define IID_IErrorMarshalTesting __uuidof(IErrorMarshalTesting) +#define IID_IDispatchTesting __uuidof(IDispatchTesting) +#define IID_IAggregationTesting __uuidof(IAggregationTesting) // Class used for COM activation when using CoreShim struct CoreShimComActivation @@ -52,11 +57,12 @@ private: #ifndef COM_CLIENT #include "ComHelpers.h" - #define DEF_RAWFUNC(n) virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE raw_ ## n - #define DEF_FUNC(n) virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE ## n + #define DEF_FUNC(n) virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE n #include "NumericTesting.h" #include "ArrayTesting.h" #include "StringTesting.h" #include "ErrorMarshalTesting.h" + #include "DispatchTesting.h" + #include "AggregationTesting.h" #endif diff --git a/tests/src/Interop/COM/NativeServer/StringTesting.h b/tests/src/Interop/COM/NativeServer/StringTesting.h index 1f3a35c1f9..7a6ff3c989 100644 --- a/tests/src/Interop/COM/NativeServer/StringTesting.h +++ b/tests/src/Interop/COM/NativeServer/StringTesting.h @@ -60,7 +60,7 @@ private: } public: // IStringTesting - DEF_RAWFUNC(Add_LPStr)( + DEF_FUNC(Add_LPStr)( /*[in]*/ LPSTR a, /*[in]*/ LPSTR b, /*[out,retval]*/ LPSTR * pRetVal) @@ -78,7 +78,7 @@ public: // IStringTesting *pRetVal = buf; return S_OK; } - DEF_RAWFUNC(Add_LPWStr)( + DEF_FUNC(Add_LPWStr)( /*[in]*/ LPWSTR a, /*[in]*/ LPWSTR b, /*[out,retval]*/ LPWSTR * pRetVal) @@ -96,7 +96,7 @@ public: // IStringTesting *pRetVal = buf; return S_OK; } - DEF_RAWFUNC(Add_BStr)( + DEF_FUNC(Add_BStr)( /*[in]*/ BSTR a, /*[in]*/ BSTR b, /*[out,retval]*/ BSTR * pRetVal) @@ -114,13 +114,13 @@ public: // IStringTesting *pRetVal = buf; return S_OK; } - DEF_RAWFUNC(Reverse_LPStr)( + DEF_FUNC(Reverse_LPStr)( /*[in]*/ LPSTR a, /*[out,retval]*/ LPSTR * pRetVal) { return Reverse(a, pRetVal); } - DEF_RAWFUNC(Reverse_LPStr_Ref)( + DEF_FUNC(Reverse_LPStr_Ref)( /*[in,out]*/ LPSTR * a, /*[out,retval]*/ LPSTR * pRetVal) { @@ -129,26 +129,26 @@ public: // IStringTesting ReverseInplace(::strlen(*a), *a); return S_OK; } - DEF_RAWFUNC(Reverse_LPStr_InRef)( + DEF_FUNC(Reverse_LPStr_InRef)( /*[in]*/ LPSTR * a, /*[out,retval]*/ LPSTR * pRetVal) { return Reverse(*a, pRetVal); } - DEF_RAWFUNC(Reverse_LPStr_Out)( + DEF_FUNC(Reverse_LPStr_Out)( /*[in]*/ LPSTR a, /*[out]*/ LPSTR * b) { return Reverse(a, b); } - DEF_RAWFUNC(Reverse_LPStr_OutAttr)( + DEF_FUNC(Reverse_LPStr_OutAttr)( /*[in]*/ LPSTR a, /*[out]*/ LPSTR b) { ReverseInplace(::strlen(b), b); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPStr)( + DEF_FUNC(Reverse_SB_LPStr)( /*[in,out]*/ LPSTR a, /*[out,retval]*/ LPSTR * pRetVal) { @@ -157,7 +157,7 @@ public: // IStringTesting ReverseInplace(::strlen(a), a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPStr_Ref)( + DEF_FUNC(Reverse_SB_LPStr_Ref)( /*[in,out]*/ LPSTR * a, /*[out,retval]*/ LPSTR * pRetVal) { @@ -166,7 +166,7 @@ public: // IStringTesting ReverseInplace(::strlen(*a), *a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPStr_InRef)( + DEF_FUNC(Reverse_SB_LPStr_InRef)( /*[in]*/ LPSTR * a, /*[out,retval]*/ LPSTR * pRetVal) { @@ -175,7 +175,7 @@ public: // IStringTesting ReverseInplace(::strlen(*a), *a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPStr_Out)( + DEF_FUNC(Reverse_SB_LPStr_Out)( /*[in,out]*/ LPSTR a, /*[out]*/ LPSTR * b) { @@ -184,7 +184,7 @@ public: // IStringTesting ReverseInplace(::strlen(a), a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPStr_OutAttr)( + DEF_FUNC(Reverse_SB_LPStr_OutAttr)( /*[in,out]*/ LPSTR a, /*[out]*/ LPSTR b) { @@ -194,13 +194,13 @@ public: // IStringTesting ::memcpy_s(b, byteLen, a, byteLen); return S_OK; } - DEF_RAWFUNC(Reverse_LPWStr)( + DEF_FUNC(Reverse_LPWStr)( /*[in]*/ LPWSTR a, /*[out,retval]*/ LPWSTR * pRetVal) { return Reverse(a, pRetVal); } - DEF_RAWFUNC(Reverse_LPWStr_Ref)( + DEF_FUNC(Reverse_LPWStr_Ref)( /*[in,out]*/ LPWSTR * a, /*[out,retval]*/ LPWSTR * pRetVal) { @@ -209,26 +209,26 @@ public: // IStringTesting ReverseInplace(::wcslen(*a), *a); return S_OK; } - DEF_RAWFUNC(Reverse_LPWStr_InRef)( + DEF_FUNC(Reverse_LPWStr_InRef)( /*[in]*/ LPWSTR * a, /*[out,retval]*/ LPWSTR * pRetVal) { return Reverse(*a, pRetVal); } - DEF_RAWFUNC(Reverse_LPWStr_Out)( + DEF_FUNC(Reverse_LPWStr_Out)( /*[in]*/ LPWSTR a, /*[out]*/ LPWSTR * b) { return Reverse(a, b); } - DEF_RAWFUNC(Reverse_LPWStr_OutAttr)( + DEF_FUNC(Reverse_LPWStr_OutAttr)( /*[in]*/ LPWSTR a, /*[out]*/ LPWSTR b) { ReverseInplace(::wcslen(b), b); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPWStr)( + DEF_FUNC(Reverse_SB_LPWStr)( /*[in,out]*/ LPWSTR a, /*[out,retval]*/ LPWSTR * pRetVal) { @@ -237,7 +237,7 @@ public: // IStringTesting ReverseInplace(::wcslen(a), a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPWStr_Ref)( + DEF_FUNC(Reverse_SB_LPWStr_Ref)( /*[in,out]*/ LPWSTR * a, /*[out,retval]*/ LPWSTR * pRetVal) { @@ -246,7 +246,7 @@ public: // IStringTesting ReverseInplace(::wcslen(*a), *a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPWStr_InRef)( + DEF_FUNC(Reverse_SB_LPWStr_InRef)( /*[in]*/ LPWSTR * a, /*[out,retval]*/ LPWSTR * pRetVal) { @@ -255,7 +255,7 @@ public: // IStringTesting ReverseInplace(::wcslen(*a), *a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPWStr_Out)( + DEF_FUNC(Reverse_SB_LPWStr_Out)( /*[in,out]*/ LPWSTR a, /*[out]*/ LPWSTR * b) { @@ -264,7 +264,7 @@ public: // IStringTesting ReverseInplace(::wcslen(a), a); return S_OK; } - DEF_RAWFUNC(Reverse_SB_LPWStr_OutAttr)( + DEF_FUNC(Reverse_SB_LPWStr_OutAttr)( /*[in,out]*/ LPWSTR a, /*[out]*/ LPWSTR b) { @@ -274,13 +274,13 @@ public: // IStringTesting ::memcpy_s(b, byteLen, a, byteLen); return S_OK; } - DEF_RAWFUNC(Reverse_BStr)( + DEF_FUNC(Reverse_BStr)( /*[in]*/ BSTR a, /*[out,retval]*/ BSTR * pRetVal) { return ReverseBstr(a, pRetVal); } - DEF_RAWFUNC(Reverse_BStr_Ref)( + DEF_FUNC(Reverse_BStr_Ref)( /*[in,out]*/ BSTR * a, /*[out,retval]*/ BSTR * pRetVal) { @@ -289,19 +289,19 @@ public: // IStringTesting ReverseInplace(::SysStringLen(*a), *a); return S_OK; } - DEF_RAWFUNC(Reverse_BStr_InRef)( + DEF_FUNC(Reverse_BStr_InRef)( /*[in]*/ BSTR * a, /*[out,retval]*/ BSTR * pRetVal) { return ReverseBstr(*a, pRetVal); } - DEF_RAWFUNC(Reverse_BStr_Out)( + DEF_FUNC(Reverse_BStr_Out)( /*[in]*/ BSTR a, /*[out]*/ BSTR * b) { return ReverseBstr(a, b); } - DEF_RAWFUNC(Reverse_BStr_OutAttr)( + DEF_FUNC(Reverse_BStr_OutAttr)( /*[in]*/ BSTR a, /*[out]*/ BSTR b) { diff --git a/tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs b/tests/src/Interop/COM/ServerContracts/NativeServers.cs index 86a256d8f7..2e8dd60227 100644 --- a/tests/src/Interop/COM/ServerContracts/PrimitivesNativeServer.cs +++ b/tests/src/Interop/COM/ServerContracts/NativeServers.cs @@ -84,6 +84,44 @@ namespace Server.Contract.Servers internal class ErrorMarshalTestingClass { } + + /// <summary> + /// Managed definition of CoClass + /// </summary> + [ComImport] + [CoClass(typeof(DispatchTestingClass))] + [Guid("a5e04c1c-474e-46d2-bbc0-769d04e12b54")] + internal interface DispatchTesting : Server.Contract.IDispatchTesting + { + } + + /// <summary> + /// Managed activation for CoClass + /// </summary> + [ComImport] + [Guid(Server.Contract.Guids.DispatchTesting)] + internal class DispatchTestingClass + { + } + + /// <summary> + /// Managed definition of CoClass + /// </summary> + [ComImport] + [CoClass(typeof(AggregationTestingClass))] + [Guid("98cc27f0-d521-4f79-8b63-e980e3a92974")] + internal interface AggregationTesting : Server.Contract.IAggregationTesting + { + } + + /// <summary> + /// Managed activation for CoClass + /// </summary> + [ComImport] + [Guid(Server.Contract.Guids.AggregationTesting)] + internal class AggregationTestingClass + { + } } #pragma warning restore IDE1006 // Naming Styles diff --git a/tests/src/Interop/COM/ServerContracts/Primitives.cs b/tests/src/Interop/COM/ServerContracts/Server.Contracts.cs index 0714047003..0aa247f078 100644 --- a/tests/src/Interop/COM/ServerContracts/Primitives.cs +++ b/tests/src/Interop/COM/ServerContracts/Server.Contracts.cs @@ -184,6 +184,64 @@ namespace Server.Contract [PreserveSig] int Return_As_HResult(int hresultToReturn); } + + public enum IDispatchTesting_Exception + { + Disp, + HResult, + } + + [StructLayout(LayoutKind.Sequential)] + public struct HFA_4 + { + public float x; + public float y; + public float z; + public float w; + } + + [ComVisible(true)] + [Guid("a5e04c1c-474e-46d2-bbc0-769d04e12b54")] + [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] + public interface IDispatchTesting + { + void DoubleNumeric_ReturnByRef ( + byte b1, + ref byte b2, + short s1, + ref short s2, + ushort us1, + ref ushort us2, + int i1, + ref int i2, + uint ui1, + ref uint ui2, + long l1, + ref long l2, + ulong ul1, + ref ulong ul2); + + float Add_Float_ReturnAndUpdateByRef(float a, ref float b); + double Add_Double_ReturnAndUpdateByRef(double a, ref double b); + void TriggerException(IDispatchTesting_Exception excep, int errorCode); + + // Special cases + HFA_4 DoubleHVAValues(ref HFA_4 input); + } + + [ComVisible(true)] + [Guid("98cc27f0-d521-4f79-8b63-e980e3a92974")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IAggregationTesting + { + // Check if the current object is aggregated + [return: MarshalAs(UnmanagedType.VariantBool)] + bool IsAggregated(); + + // Check if the two object represent an aggregated pair + [return: MarshalAs(UnmanagedType.VariantBool)] + bool AreAggregated([MarshalAs(UnmanagedType.IUnknown)] object aggregateMaybe1, [MarshalAs(UnmanagedType.IUnknown)] object aggregateMaybe2); + }; } #pragma warning restore 618 // Must test deprecated features diff --git a/tests/src/Interop/COM/ServerContracts/Server.Contracts.h b/tests/src/Interop/COM/ServerContracts/Server.Contracts.h new file mode 100644 index 0000000000..972310615e --- /dev/null +++ b/tests/src/Interop/COM/ServerContracts/Server.Contracts.h @@ -0,0 +1,431 @@ +// Created by Microsoft (R) C/C++ Compiler + +#pragma once +#pragma pack(push, 8) + +#include <comdef.h> + +// +// Forward references and typedefs +// + +struct __declspec(uuid("05655a94-a915-4926-815d-a9ea648baad9")) +/* interface */ INumericTesting; +struct __declspec(uuid("7731cb31-e063-4cc8-bcd2-d151d6bc8f43")) +/* interface */ IArrayTesting; +struct __declspec(uuid("7044c5c0-c6c6-4713-9294-b4a4e86d58cc")) +/* interface */ IStringTesting; +struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556")) +/* interface */ IErrorMarshalTesting; +struct __declspec(uuid("a5e04c1c-474e-46d2-bbc0-769d04e12b54")) +/* interface */ IDispatchTesting; +struct __declspec(uuid("98cc27f0-d521-4f79-8b63-e980e3a92974")) +/* interface */ IAggregationTesting; + +// +// Smart pointer typedef declarations +// + +_COM_SMARTPTR_TYPEDEF(INumericTesting, __uuidof(INumericTesting)); +_COM_SMARTPTR_TYPEDEF(IArrayTesting, __uuidof(IArrayTesting)); +_COM_SMARTPTR_TYPEDEF(IStringTesting, __uuidof(IStringTesting)); +_COM_SMARTPTR_TYPEDEF(IErrorMarshalTesting, __uuidof(IErrorMarshalTesting)); +_COM_SMARTPTR_TYPEDEF(IDispatchTesting, __uuidof(IDispatchTesting)); +_COM_SMARTPTR_TYPEDEF(IAggregationTesting, __uuidof(IAggregationTesting)); + +// +// Type library items +// + +struct __declspec(uuid("05655a94-a915-4926-815d-a9ea648baad9")) +INumericTesting : IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE Add_Byte ( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[out,retval]*/ unsigned char * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Short ( + /*[in]*/ short a, + /*[in]*/ short b, + /*[out,retval]*/ short * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_UShort ( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[out,retval]*/ unsigned short * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Int ( + /*[in]*/ int a, + /*[in]*/ int b, + /*[out,retval]*/ int * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_UInt ( + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[out,retval]*/ unsigned int * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Long ( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[out,retval]*/ __int64 * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_ULong ( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[out,retval]*/ unsigned __int64 * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Float ( + /*[in]*/ float a, + /*[in]*/ float b, + /*[out,retval]*/ float * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Double ( + /*[in]*/ double a, + /*[in]*/ double b, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Byte_Ref ( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[in,out]*/ unsigned char * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Short_Ref ( + /*[in]*/ short a, + /*[in]*/ short b, + /*[in,out]*/ short * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_UShort_Ref ( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[in,out]*/ unsigned short * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Int_Ref ( + /*[in]*/ int a, + /*[in]*/ int b, + /*[in,out]*/ int * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_UInt_Ref ( + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[in,out]*/ unsigned int * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Long_Ref ( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[in,out]*/ __int64 * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_ULong_Ref ( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[in,out]*/ unsigned __int64 * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Float_Ref ( + /*[in]*/ float a, + /*[in]*/ float b, + /*[in,out]*/ float * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Double_Ref ( + /*[in]*/ double a, + /*[in]*/ double b, + /*[in,out]*/ double * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Byte_Out ( + /*[in]*/ unsigned char a, + /*[in]*/ unsigned char b, + /*[out]*/ unsigned char * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Short_Out ( + /*[in]*/ short a, + /*[in]*/ short b, + /*[out]*/ short * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_UShort_Out ( + /*[in]*/ unsigned short a, + /*[in]*/ unsigned short b, + /*[out]*/ unsigned short * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Int_Out ( + /*[in]*/ int a, + /*[in]*/ int b, + /*[out]*/ int * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_UInt_Out ( + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[out]*/ unsigned int * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Long_Out ( + /*[in]*/ __int64 a, + /*[in]*/ __int64 b, + /*[out]*/ __int64 * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_ULong_Out ( + /*[in]*/ unsigned __int64 a, + /*[in]*/ unsigned __int64 b, + /*[out]*/ unsigned __int64 * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Float_Out ( + /*[in]*/ float a, + /*[in]*/ float b, + /*[out]*/ float * c ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Double_Out ( + /*[in]*/ double a, + /*[in]*/ double b, + /*[out]*/ double * c ) = 0; +}; + +struct __declspec(uuid("7731cb31-e063-4cc8-bcd2-d151d6bc8f43")) +IArrayTesting : IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE Mean_Byte_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ unsigned char * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Short_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ short * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_UShort_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ unsigned short * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Int_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ int * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_UInt_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ unsigned int * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Long_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ __int64 * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_ULong_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ unsigned __int64 * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Float_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ float * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Double_LP_PreLen ( + /*[in]*/ int len, + /*[in]*/ double * d, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Byte_LP_PostLen ( + /*[in]*/ unsigned char * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Short_LP_PostLen ( + /*[in]*/ short * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_UShort_LP_PostLen ( + /*[in]*/ unsigned short * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Int_LP_PostLen ( + /*[in]*/ int * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_UInt_LP_PostLen ( + /*[in]*/ unsigned int * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Long_LP_PostLen ( + /*[in]*/ __int64 * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_ULong_LP_PostLen ( + /*[in]*/ unsigned __int64 * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Float_LP_PostLen ( + /*[in]*/ float * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Double_LP_PostLen ( + /*[in]*/ double * d, + /*[in]*/ int len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Byte_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Short_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_UShort_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Int_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_UInt_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Long_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_ULong_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Float_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Mean_Double_SafeArray_OutLen ( + /*[in]*/ SAFEARRAY * d, + /*[out]*/ int * len, + /*[out,retval]*/ double * pRetVal ) = 0; +}; + +struct __declspec(uuid("7044c5c0-c6c6-4713-9294-b4a4e86d58cc")) +IStringTesting : IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE Add_LPStr ( + /*[in]*/ LPSTR a, + /*[in]*/ LPSTR b, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_LPWStr ( + /*[in]*/ LPWSTR a, + /*[in]*/ LPWSTR b, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_BStr ( + /*[in]*/ BSTR a, + /*[in]*/ BSTR b, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPStr ( + /*[in]*/ LPSTR a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPStr_Ref ( + /*[in,out]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPStr_InRef ( + /*[in]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPStr_Out ( + /*[in]*/ LPSTR a, + /*[out]*/ LPSTR * b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPStr_OutAttr ( + /*[in]*/ LPSTR a, + /*[out]*/ LPSTR b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPStr ( + /*[in,out]*/ LPSTR a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPStr_Ref ( + /*[in,out]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPStr_InRef ( + /*[in]*/ LPSTR * a, + /*[out,retval]*/ LPSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPStr_Out ( + /*[in,out]*/ LPSTR a, + /*[out]*/ LPSTR * b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPStr_OutAttr ( + /*[in,out]*/ LPSTR a, + /*[out]*/ LPSTR b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPWStr ( + /*[in]*/ LPWSTR a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPWStr_Ref ( + /*[in,out]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPWStr_InRef ( + /*[in]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPWStr_Out ( + /*[in]*/ LPWSTR a, + /*[out]*/ LPWSTR * b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_LPWStr_OutAttr ( + /*[in]*/ LPWSTR a, + /*[out]*/ LPWSTR b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPWStr ( + /*[in,out]*/ LPWSTR a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPWStr_Ref ( + /*[in,out]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPWStr_InRef ( + /*[in]*/ LPWSTR * a, + /*[out,retval]*/ LPWSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPWStr_Out ( + /*[in,out]*/ LPWSTR a, + /*[out]*/ LPWSTR * b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_SB_LPWStr_OutAttr ( + /*[in,out]*/ LPWSTR a, + /*[out]*/ LPWSTR b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_BStr ( + /*[in]*/ BSTR a, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_BStr_Ref ( + /*[in,out]*/ BSTR * a, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_BStr_InRef ( + /*[in]*/ BSTR * a, + /*[out,retval]*/ BSTR * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_BStr_Out ( + /*[in]*/ BSTR a, + /*[out]*/ BSTR * b ) = 0; + virtual HRESULT STDMETHODCALLTYPE Reverse_BStr_OutAttr ( + /*[in]*/ BSTR a, + /*[out]*/ BSTR b ) = 0; +}; + +struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556")) +IErrorMarshalTesting : IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE Throw_HResult ( + /*[in]*/ int hresultToReturn ) = 0; + virtual int STDMETHODCALLTYPE Return_As_HResult ( + /*[in]*/ int hresultToReturn ) = 0; +}; + +enum IDispatchTesting_Exception +{ + IDispatchTesting_Exception_Disp, + IDispatchTesting_Exception_HResult, +}; + +struct HFA_4 +{ + float x; + float y; + float z; + float w; +}; + +struct __declspec(uuid("a5e04c1c-474e-46d2-bbc0-769d04e12b54")) +IDispatchTesting : IDispatch +{ + virtual HRESULT STDMETHODCALLTYPE DoubleNumeric_ReturnByRef ( + /*[in]*/ unsigned char b1, + /*[in,out]*/ unsigned char *b2, + /*[in]*/ short s1, + /*[in,out]*/ short *s2, + /*[in]*/ unsigned short us1, + /*[in,out]*/ unsigned short *us2, + /*[in]*/ int i1, + /*[in,out]*/ int *i2, + /*[in]*/ unsigned int ui1, + /*[in,out]*/ unsigned int *ui2, + /*[in]*/ __int64 l1, + /*[in,out]*/ __int64 *l2, + /*[in]*/ unsigned __int64 ul1, + /*[in,out]*/ unsigned __int64 *ul2 ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Float_ReturnAndUpdateByRef ( + /*[in]*/ float a, + /*[in,out]*/ float *b, + /*[out,retval]*/ float * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE Add_Double_ReturnAndUpdateByRef ( + /*[in]*/ double a, + /*[in,out]*/ double *b, + /*[out,retval]*/ double * pRetVal ) = 0; + virtual HRESULT STDMETHODCALLTYPE TriggerException ( + /*[in]*/ enum IDispatchTesting_Exception excep, + /*[in]*/ int errorCode) = 0; + + // Special cases + virtual HRESULT STDMETHODCALLTYPE DoubleHVAValues( + /*[in,out]*/ HFA_4 *input, + /*[out,retval]*/ HFA_4 *pRetVal) = 0; +}; + +struct __declspec(uuid("98cc27f0-d521-4f79-8b63-e980e3a92974")) +IAggregationTesting : IUnknown +{ + // Check if the current object is aggregated + virtual HRESULT STDMETHODCALLTYPE IsAggregated( + _Out_ VARIANT_BOOL *isAggregated) = 0; + + // Check if the two object represent an aggregated pair + virtual HRESULT STDMETHODCALLTYPE AreAggregated( + _In_ IUnknown *aggregateMaybe1, + _In_ IUnknown *aggregateMaybe2, + _Out_ VARIANT_BOOL *areAggregated) = 0; +}; + +#pragma pack(pop) diff --git a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh deleted file mode 100644 index 412d352156..0000000000 --- a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh +++ /dev/null @@ -1,656 +0,0 @@ -// Created by Microsoft (R) C/C++ Compiler - -#pragma once -#pragma pack(push, 8) - -#include <comdef.h> - -// -// Forward references and typedefs -// - -struct __declspec(uuid("3b973377-8c69-4208-96c1-475da757861c")) -/* LIBID */ __Server_Contract; -struct __declspec(uuid("05655a94-a915-4926-815d-a9ea648baad9")) -/* interface */ INumericTesting; -struct __declspec(uuid("7731cb31-e063-4cc8-bcd2-d151d6bc8f43")) -/* interface */ IArrayTesting; -struct __declspec(uuid("7044c5c0-c6c6-4713-9294-b4a4e86d58cc")) -/* interface */ IStringTesting; -struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556")) -/* interface */ IErrorMarshalTesting; - -// -// Smart pointer typedef declarations -// - -_COM_SMARTPTR_TYPEDEF(INumericTesting, __uuidof(INumericTesting)); -_COM_SMARTPTR_TYPEDEF(IArrayTesting, __uuidof(IArrayTesting)); -_COM_SMARTPTR_TYPEDEF(IStringTesting, __uuidof(IStringTesting)); -_COM_SMARTPTR_TYPEDEF(IErrorMarshalTesting, __uuidof(IErrorMarshalTesting)); - -// -// Type library items -// - -struct __declspec(uuid("05655a94-a915-4926-815d-a9ea648baad9")) -INumericTesting : IUnknown -{ - // - // Wrapper methods for error-handling - // - - unsigned char Add_Byte ( - unsigned char a, - unsigned char b ); - short Add_Short ( - short a, - short b ); - unsigned short Add_UShort ( - unsigned short a, - unsigned short b ); - int Add_Int ( - int a, - int b ); - unsigned int Add_UInt ( - unsigned int a, - unsigned int b ); - __int64 Add_Long ( - __int64 a, - __int64 b ); - unsigned __int64 Add_ULong ( - unsigned __int64 a, - unsigned __int64 b ); - float Add_Float ( - float a, - float b ); - double Add_Double ( - double a, - double b ); - HRESULT Add_Byte_Ref ( - unsigned char a, - unsigned char b, - unsigned char * c ); - HRESULT Add_Short_Ref ( - short a, - short b, - short * c ); - HRESULT Add_UShort_Ref ( - unsigned short a, - unsigned short b, - unsigned short * c ); - HRESULT Add_Int_Ref ( - int a, - int b, - int * c ); - HRESULT Add_UInt_Ref ( - unsigned int a, - unsigned int b, - unsigned int * c ); - HRESULT Add_Long_Ref ( - __int64 a, - __int64 b, - __int64 * c ); - HRESULT Add_ULong_Ref ( - unsigned __int64 a, - unsigned __int64 b, - unsigned __int64 * c ); - HRESULT Add_Float_Ref ( - float a, - float b, - float * c ); - HRESULT Add_Double_Ref ( - double a, - double b, - double * c ); - HRESULT Add_Byte_Out ( - unsigned char a, - unsigned char b, - unsigned char * c ); - HRESULT Add_Short_Out ( - short a, - short b, - short * c ); - HRESULT Add_UShort_Out ( - unsigned short a, - unsigned short b, - unsigned short * c ); - HRESULT Add_Int_Out ( - int a, - int b, - int * c ); - HRESULT Add_UInt_Out ( - unsigned int a, - unsigned int b, - unsigned int * c ); - HRESULT Add_Long_Out ( - __int64 a, - __int64 b, - __int64 * c ); - HRESULT Add_ULong_Out ( - unsigned __int64 a, - unsigned __int64 b, - unsigned __int64 * c ); - HRESULT Add_Float_Out ( - float a, - float b, - float * c ); - HRESULT Add_Double_Out ( - double a, - double b, - double * c ); - - // - // Raw methods provided by interface - // - - virtual HRESULT STDMETHODCALLTYPE raw_Add_Byte ( - /*[in]*/ unsigned char a, - /*[in]*/ unsigned char b, - /*[out,retval]*/ unsigned char * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Short ( - /*[in]*/ short a, - /*[in]*/ short b, - /*[out,retval]*/ short * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_UShort ( - /*[in]*/ unsigned short a, - /*[in]*/ unsigned short b, - /*[out,retval]*/ unsigned short * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Int ( - /*[in]*/ int a, - /*[in]*/ int b, - /*[out,retval]*/ int * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_UInt ( - /*[in]*/ unsigned int a, - /*[in]*/ unsigned int b, - /*[out,retval]*/ unsigned int * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Long ( - /*[in]*/ __int64 a, - /*[in]*/ __int64 b, - /*[out,retval]*/ __int64 * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_ULong ( - /*[in]*/ unsigned __int64 a, - /*[in]*/ unsigned __int64 b, - /*[out,retval]*/ unsigned __int64 * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Float ( - /*[in]*/ float a, - /*[in]*/ float b, - /*[out,retval]*/ float * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Double ( - /*[in]*/ double a, - /*[in]*/ double b, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Byte_Ref ( - /*[in]*/ unsigned char a, - /*[in]*/ unsigned char b, - /*[in,out]*/ unsigned char * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Short_Ref ( - /*[in]*/ short a, - /*[in]*/ short b, - /*[in,out]*/ short * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_UShort_Ref ( - /*[in]*/ unsigned short a, - /*[in]*/ unsigned short b, - /*[in,out]*/ unsigned short * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Int_Ref ( - /*[in]*/ int a, - /*[in]*/ int b, - /*[in,out]*/ int * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_UInt_Ref ( - /*[in]*/ unsigned int a, - /*[in]*/ unsigned int b, - /*[in,out]*/ unsigned int * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Long_Ref ( - /*[in]*/ __int64 a, - /*[in]*/ __int64 b, - /*[in,out]*/ __int64 * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_ULong_Ref ( - /*[in]*/ unsigned __int64 a, - /*[in]*/ unsigned __int64 b, - /*[in,out]*/ unsigned __int64 * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Float_Ref ( - /*[in]*/ float a, - /*[in]*/ float b, - /*[in,out]*/ float * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Double_Ref ( - /*[in]*/ double a, - /*[in]*/ double b, - /*[in,out]*/ double * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Byte_Out ( - /*[in]*/ unsigned char a, - /*[in]*/ unsigned char b, - /*[out]*/ unsigned char * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Short_Out ( - /*[in]*/ short a, - /*[in]*/ short b, - /*[out]*/ short * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_UShort_Out ( - /*[in]*/ unsigned short a, - /*[in]*/ unsigned short b, - /*[out]*/ unsigned short * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Int_Out ( - /*[in]*/ int a, - /*[in]*/ int b, - /*[out]*/ int * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_UInt_Out ( - /*[in]*/ unsigned int a, - /*[in]*/ unsigned int b, - /*[out]*/ unsigned int * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Long_Out ( - /*[in]*/ __int64 a, - /*[in]*/ __int64 b, - /*[out]*/ __int64 * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_ULong_Out ( - /*[in]*/ unsigned __int64 a, - /*[in]*/ unsigned __int64 b, - /*[out]*/ unsigned __int64 * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Float_Out ( - /*[in]*/ float a, - /*[in]*/ float b, - /*[out]*/ float * c ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_Double_Out ( - /*[in]*/ double a, - /*[in]*/ double b, - /*[out]*/ double * c ) = 0; -}; - -struct __declspec(uuid("7731cb31-e063-4cc8-bcd2-d151d6bc8f43")) -IArrayTesting : IUnknown -{ - // - // Wrapper methods for error-handling - // - - double Mean_Byte_LP_PreLen ( - int len, - unsigned char * d ); - double Mean_Short_LP_PreLen ( - int len, - short * d ); - double Mean_UShort_LP_PreLen ( - int len, - unsigned short * d ); - double Mean_Int_LP_PreLen ( - int len, - int * d ); - double Mean_UInt_LP_PreLen ( - int len, - unsigned int * d ); - double Mean_Long_LP_PreLen ( - int len, - __int64 * d ); - double Mean_ULong_LP_PreLen ( - int len, - unsigned __int64 * d ); - double Mean_Float_LP_PreLen ( - int len, - float * d ); - double Mean_Double_LP_PreLen ( - int len, - double * d ); - double Mean_Byte_LP_PostLen ( - unsigned char * d, - int len ); - double Mean_Short_LP_PostLen ( - short * d, - int len ); - double Mean_UShort_LP_PostLen ( - unsigned short * d, - int len ); - double Mean_Int_LP_PostLen ( - int * d, - int len ); - double Mean_UInt_LP_PostLen ( - unsigned int * d, - int len ); - double Mean_Long_LP_PostLen ( - __int64 * d, - int len ); - double Mean_ULong_LP_PostLen ( - unsigned __int64 * d, - int len ); - double Mean_Float_LP_PostLen ( - float * d, - int len ); - double Mean_Double_LP_PostLen ( - double * d, - int len ); - double Mean_Byte_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_Short_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_UShort_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_Int_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_UInt_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_Long_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_ULong_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_Float_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - double Mean_Double_SafeArray_OutLen ( - SAFEARRAY * d, - int * len ); - - // - // Raw methods provided by interface - // - - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Byte_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ unsigned char * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Short_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ short * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_UShort_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ unsigned short * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Int_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ int * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_UInt_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ unsigned int * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Long_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ __int64 * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_ULong_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ unsigned __int64 * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Float_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ float * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Double_LP_PreLen ( - /*[in]*/ int len, - /*[in]*/ double * d, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Byte_LP_PostLen ( - /*[in]*/ unsigned char * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Short_LP_PostLen ( - /*[in]*/ short * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_UShort_LP_PostLen ( - /*[in]*/ unsigned short * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Int_LP_PostLen ( - /*[in]*/ int * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_UInt_LP_PostLen ( - /*[in]*/ unsigned int * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Long_LP_PostLen ( - /*[in]*/ __int64 * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_ULong_LP_PostLen ( - /*[in]*/ unsigned __int64 * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Float_LP_PostLen ( - /*[in]*/ float * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Double_LP_PostLen ( - /*[in]*/ double * d, - /*[in]*/ int len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Byte_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Short_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_UShort_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Int_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_UInt_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Long_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_ULong_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Float_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Mean_Double_SafeArray_OutLen ( - /*[in]*/ SAFEARRAY * d, - /*[out]*/ int * len, - /*[out,retval]*/ double * pRetVal ) = 0; -}; - -struct __declspec(uuid("7044c5c0-c6c6-4713-9294-b4a4e86d58cc")) -IStringTesting : IUnknown -{ - // - // Wrapper methods for error-handling - // - - LPSTR Add_LPStr ( - LPSTR a, - LPSTR b ); - LPWSTR Add_LPWStr ( - LPWSTR a, - LPWSTR b ); - _bstr_t Add_BStr ( - _bstr_t a, - _bstr_t b ); - LPSTR Reverse_LPStr ( - LPSTR a ); - LPSTR Reverse_LPStr_Ref ( - LPSTR * a ); - LPSTR Reverse_LPStr_InRef ( - LPSTR * a ); - HRESULT Reverse_LPStr_Out ( - LPSTR a, - LPSTR * b ); - HRESULT Reverse_LPStr_OutAttr ( - LPSTR a, - LPSTR b ); - LPSTR Reverse_SB_LPStr ( - LPSTR a ); - LPSTR Reverse_SB_LPStr_Ref ( - LPSTR * a ); - LPSTR Reverse_SB_LPStr_InRef ( - LPSTR * a ); - HRESULT Reverse_SB_LPStr_Out ( - LPSTR a, - LPSTR * b ); - HRESULT Reverse_SB_LPStr_OutAttr ( - LPSTR a, - LPSTR b ); - LPWSTR Reverse_LPWStr ( - LPWSTR a ); - LPWSTR Reverse_LPWStr_Ref ( - LPWSTR * a ); - LPWSTR Reverse_LPWStr_InRef ( - LPWSTR * a ); - HRESULT Reverse_LPWStr_Out ( - LPWSTR a, - LPWSTR * b ); - HRESULT Reverse_LPWStr_OutAttr ( - LPWSTR a, - LPWSTR b ); - LPWSTR Reverse_SB_LPWStr ( - LPWSTR a ); - LPWSTR Reverse_SB_LPWStr_Ref ( - LPWSTR * a ); - LPWSTR Reverse_SB_LPWStr_InRef ( - LPWSTR * a ); - HRESULT Reverse_SB_LPWStr_Out ( - LPWSTR a, - LPWSTR * b ); - HRESULT Reverse_SB_LPWStr_OutAttr ( - LPWSTR a, - LPWSTR b ); - _bstr_t Reverse_BStr ( - _bstr_t a ); - _bstr_t Reverse_BStr_Ref ( - BSTR * a ); - _bstr_t Reverse_BStr_InRef ( - BSTR * a ); - HRESULT Reverse_BStr_Out ( - _bstr_t a, - BSTR * b ); - HRESULT Reverse_BStr_OutAttr ( - _bstr_t a, - _bstr_t b ); - - // - // Raw methods provided by interface - // - - virtual HRESULT STDMETHODCALLTYPE raw_Add_LPStr ( - /*[in]*/ LPSTR a, - /*[in]*/ LPSTR b, - /*[out,retval]*/ LPSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_LPWStr ( - /*[in]*/ LPWSTR a, - /*[in]*/ LPWSTR b, - /*[out,retval]*/ LPWSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Add_BStr ( - /*[in]*/ BSTR a, - /*[in]*/ BSTR b, - /*[out,retval]*/ BSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPStr ( - /*[in]*/ LPSTR a, - /*[out,retval]*/ LPSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPStr_Ref ( - /*[in,out]*/ LPSTR * a, - /*[out,retval]*/ LPSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPStr_InRef ( - /*[in]*/ LPSTR * a, - /*[out,retval]*/ LPSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPStr_Out ( - /*[in]*/ LPSTR a, - /*[out]*/ LPSTR * b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPStr_OutAttr ( - /*[in]*/ LPSTR a, - /*[out]*/ LPSTR b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPStr ( - /*[in,out]*/ LPSTR a, - /*[out,retval]*/ LPSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPStr_Ref ( - /*[in,out]*/ LPSTR * a, - /*[out,retval]*/ LPSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPStr_InRef ( - /*[in]*/ LPSTR * a, - /*[out,retval]*/ LPSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPStr_Out ( - /*[in,out]*/ LPSTR a, - /*[out]*/ LPSTR * b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPStr_OutAttr ( - /*[in,out]*/ LPSTR a, - /*[out]*/ LPSTR b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPWStr ( - /*[in]*/ LPWSTR a, - /*[out,retval]*/ LPWSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPWStr_Ref ( - /*[in,out]*/ LPWSTR * a, - /*[out,retval]*/ LPWSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPWStr_InRef ( - /*[in]*/ LPWSTR * a, - /*[out,retval]*/ LPWSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPWStr_Out ( - /*[in]*/ LPWSTR a, - /*[out]*/ LPWSTR * b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_LPWStr_OutAttr ( - /*[in]*/ LPWSTR a, - /*[out]*/ LPWSTR b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPWStr ( - /*[in,out]*/ LPWSTR a, - /*[out,retval]*/ LPWSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPWStr_Ref ( - /*[in,out]*/ LPWSTR * a, - /*[out,retval]*/ LPWSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPWStr_InRef ( - /*[in]*/ LPWSTR * a, - /*[out,retval]*/ LPWSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPWStr_Out ( - /*[in,out]*/ LPWSTR a, - /*[out]*/ LPWSTR * b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_SB_LPWStr_OutAttr ( - /*[in,out]*/ LPWSTR a, - /*[out]*/ LPWSTR b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_BStr ( - /*[in]*/ BSTR a, - /*[out,retval]*/ BSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_BStr_Ref ( - /*[in,out]*/ BSTR * a, - /*[out,retval]*/ BSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_BStr_InRef ( - /*[in]*/ BSTR * a, - /*[out,retval]*/ BSTR * pRetVal ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_BStr_Out ( - /*[in]*/ BSTR a, - /*[out]*/ BSTR * b ) = 0; - virtual HRESULT STDMETHODCALLTYPE raw_Reverse_BStr_OutAttr ( - /*[in]*/ BSTR a, - /*[out]*/ BSTR b ) = 0; -}; - -struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556")) -IErrorMarshalTesting : IUnknown -{ - // - // Wrapper methods for error-handling - // - - HRESULT Throw_HResult ( - int hresultToReturn ); - - // - // Raw methods provided by interface - // - - virtual HRESULT STDMETHODCALLTYPE raw_Throw_HResult ( - /*[in]*/ int hresultToReturn ) = 0; - virtual int STDMETHODCALLTYPE Return_As_HResult ( - /*[in]*/ int hresultToReturn ) = 0; -}; - -// -// Wrapper method implementations -// - -#include "Server.Contracts.tli" - -#pragma pack(pop) diff --git a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli deleted file mode 100644 index 94046af919..0000000000 --- a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli +++ /dev/null @@ -1,571 +0,0 @@ -// Created by Microsoft (R) C/C++ Compiler - -#pragma once - -// -// interface INumericTesting wrapper method implementations -// - -inline unsigned char INumericTesting::Add_Byte ( unsigned char a, unsigned char b ) { - unsigned char _result = 0; - HRESULT _hr = raw_Add_Byte(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline short INumericTesting::Add_Short ( short a, short b ) { - short _result = 0; - HRESULT _hr = raw_Add_Short(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline unsigned short INumericTesting::Add_UShort ( unsigned short a, unsigned short b ) { - unsigned short _result = 0; - HRESULT _hr = raw_Add_UShort(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline int INumericTesting::Add_Int ( int a, int b ) { - int _result = 0; - HRESULT _hr = raw_Add_Int(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline unsigned int INumericTesting::Add_UInt ( unsigned int a, unsigned int b ) { - unsigned int _result = 0; - HRESULT _hr = raw_Add_UInt(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline __int64 INumericTesting::Add_Long ( __int64 a, __int64 b ) { - __int64 _result = 0; - HRESULT _hr = raw_Add_Long(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline unsigned __int64 INumericTesting::Add_ULong ( unsigned __int64 a, unsigned __int64 b ) { - unsigned __int64 _result = 0; - HRESULT _hr = raw_Add_ULong(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline float INumericTesting::Add_Float ( float a, float b ) { - float _result = 0; - HRESULT _hr = raw_Add_Float(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double INumericTesting::Add_Double ( double a, double b ) { - double _result = 0; - HRESULT _hr = raw_Add_Double(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline HRESULT INumericTesting::Add_Byte_Ref ( unsigned char a, unsigned char b, unsigned char * c ) { - HRESULT _hr = raw_Add_Byte_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Short_Ref ( short a, short b, short * c ) { - HRESULT _hr = raw_Add_Short_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_UShort_Ref ( unsigned short a, unsigned short b, unsigned short * c ) { - HRESULT _hr = raw_Add_UShort_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Int_Ref ( int a, int b, int * c ) { - HRESULT _hr = raw_Add_Int_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_UInt_Ref ( unsigned int a, unsigned int b, unsigned int * c ) { - HRESULT _hr = raw_Add_UInt_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Long_Ref ( __int64 a, __int64 b, __int64 * c ) { - HRESULT _hr = raw_Add_Long_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_ULong_Ref ( unsigned __int64 a, unsigned __int64 b, unsigned __int64 * c ) { - HRESULT _hr = raw_Add_ULong_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Float_Ref ( float a, float b, float * c ) { - HRESULT _hr = raw_Add_Float_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Double_Ref ( double a, double b, double * c ) { - HRESULT _hr = raw_Add_Double_Ref(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Byte_Out ( unsigned char a, unsigned char b, unsigned char * c ) { - HRESULT _hr = raw_Add_Byte_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Short_Out ( short a, short b, short * c ) { - HRESULT _hr = raw_Add_Short_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_UShort_Out ( unsigned short a, unsigned short b, unsigned short * c ) { - HRESULT _hr = raw_Add_UShort_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Int_Out ( int a, int b, int * c ) { - HRESULT _hr = raw_Add_Int_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_UInt_Out ( unsigned int a, unsigned int b, unsigned int * c ) { - HRESULT _hr = raw_Add_UInt_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Long_Out ( __int64 a, __int64 b, __int64 * c ) { - HRESULT _hr = raw_Add_Long_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_ULong_Out ( unsigned __int64 a, unsigned __int64 b, unsigned __int64 * c ) { - HRESULT _hr = raw_Add_ULong_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Float_Out ( float a, float b, float * c ) { - HRESULT _hr = raw_Add_Float_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT INumericTesting::Add_Double_Out ( double a, double b, double * c ) { - HRESULT _hr = raw_Add_Double_Out(a, b, c); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -// -// interface IArrayTesting wrapper method implementations -// - -inline double IArrayTesting::Mean_Byte_LP_PreLen ( int len, unsigned char * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_Byte_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Short_LP_PreLen ( int len, short * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_Short_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_UShort_LP_PreLen ( int len, unsigned short * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_UShort_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Int_LP_PreLen ( int len, int * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_Int_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_UInt_LP_PreLen ( int len, unsigned int * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_UInt_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Long_LP_PreLen ( int len, __int64 * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_Long_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_ULong_LP_PreLen ( int len, unsigned __int64 * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_ULong_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Float_LP_PreLen ( int len, float * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_Float_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Double_LP_PreLen ( int len, double * d ) { - double _result = 0; - HRESULT _hr = raw_Mean_Double_LP_PreLen(len, d, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Byte_LP_PostLen ( unsigned char * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Byte_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Short_LP_PostLen ( short * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Short_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_UShort_LP_PostLen ( unsigned short * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_UShort_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Int_LP_PostLen ( int * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Int_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_UInt_LP_PostLen ( unsigned int * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_UInt_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Long_LP_PostLen ( __int64 * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Long_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_ULong_LP_PostLen ( unsigned __int64 * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_ULong_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Float_LP_PostLen ( float * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Float_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Double_LP_PostLen ( double * d, int len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Double_LP_PostLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Byte_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Byte_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Short_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Short_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_UShort_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_UShort_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Int_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Int_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_UInt_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_UInt_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Long_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Long_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_ULong_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_ULong_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Float_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Float_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline double IArrayTesting::Mean_Double_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { - double _result = 0; - HRESULT _hr = raw_Mean_Double_SafeArray_OutLen(d, len, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -// -// interface IStringTesting wrapper method implementations -// - -inline LPSTR IStringTesting::Add_LPStr ( LPSTR a, LPSTR b ) { - LPSTR _result = 0; - HRESULT _hr = raw_Add_LPStr(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPWSTR IStringTesting::Add_LPWStr ( LPWSTR a, LPWSTR b ) { - LPWSTR _result = 0; - HRESULT _hr = raw_Add_LPWStr(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline _bstr_t IStringTesting::Add_BStr ( _bstr_t a, _bstr_t b ) { - BSTR _result = 0; - HRESULT _hr = raw_Add_BStr(a, b, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _bstr_t(_result, false); -} - -inline LPSTR IStringTesting::Reverse_LPStr ( LPSTR a ) { - LPSTR _result = 0; - HRESULT _hr = raw_Reverse_LPStr(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPSTR IStringTesting::Reverse_LPStr_Ref ( LPSTR * a ) { - LPSTR _result = 0; - HRESULT _hr = raw_Reverse_LPStr_Ref(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPSTR IStringTesting::Reverse_LPStr_InRef ( LPSTR * a ) { - LPSTR _result = 0; - HRESULT _hr = raw_Reverse_LPStr_InRef(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline HRESULT IStringTesting::Reverse_LPStr_Out ( LPSTR a, LPSTR * b ) { - HRESULT _hr = raw_Reverse_LPStr_Out(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT IStringTesting::Reverse_LPStr_OutAttr ( LPSTR a, LPSTR b ) { - HRESULT _hr = raw_Reverse_LPStr_OutAttr(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline LPSTR IStringTesting::Reverse_SB_LPStr ( LPSTR a ) { - LPSTR _result = 0; - HRESULT _hr = raw_Reverse_SB_LPStr(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPSTR IStringTesting::Reverse_SB_LPStr_Ref ( LPSTR * a ) { - LPSTR _result = 0; - HRESULT _hr = raw_Reverse_SB_LPStr_Ref(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPSTR IStringTesting::Reverse_SB_LPStr_InRef ( LPSTR * a ) { - LPSTR _result = 0; - HRESULT _hr = raw_Reverse_SB_LPStr_InRef(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline HRESULT IStringTesting::Reverse_SB_LPStr_Out ( LPSTR a, LPSTR * b ) { - HRESULT _hr = raw_Reverse_SB_LPStr_Out(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT IStringTesting::Reverse_SB_LPStr_OutAttr ( LPSTR a, LPSTR b ) { - HRESULT _hr = raw_Reverse_SB_LPStr_OutAttr(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline LPWSTR IStringTesting::Reverse_LPWStr ( LPWSTR a ) { - LPWSTR _result = 0; - HRESULT _hr = raw_Reverse_LPWStr(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPWSTR IStringTesting::Reverse_LPWStr_Ref ( LPWSTR * a ) { - LPWSTR _result = 0; - HRESULT _hr = raw_Reverse_LPWStr_Ref(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPWSTR IStringTesting::Reverse_LPWStr_InRef ( LPWSTR * a ) { - LPWSTR _result = 0; - HRESULT _hr = raw_Reverse_LPWStr_InRef(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline HRESULT IStringTesting::Reverse_LPWStr_Out ( LPWSTR a, LPWSTR * b ) { - HRESULT _hr = raw_Reverse_LPWStr_Out(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT IStringTesting::Reverse_LPWStr_OutAttr ( LPWSTR a, LPWSTR b ) { - HRESULT _hr = raw_Reverse_LPWStr_OutAttr(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline LPWSTR IStringTesting::Reverse_SB_LPWStr ( LPWSTR a ) { - LPWSTR _result = 0; - HRESULT _hr = raw_Reverse_SB_LPWStr(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPWSTR IStringTesting::Reverse_SB_LPWStr_Ref ( LPWSTR * a ) { - LPWSTR _result = 0; - HRESULT _hr = raw_Reverse_SB_LPWStr_Ref(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline LPWSTR IStringTesting::Reverse_SB_LPWStr_InRef ( LPWSTR * a ) { - LPWSTR _result = 0; - HRESULT _hr = raw_Reverse_SB_LPWStr_InRef(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _result; -} - -inline HRESULT IStringTesting::Reverse_SB_LPWStr_Out ( LPWSTR a, LPWSTR * b ) { - HRESULT _hr = raw_Reverse_SB_LPWStr_Out(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT IStringTesting::Reverse_SB_LPWStr_OutAttr ( LPWSTR a, LPWSTR b ) { - HRESULT _hr = raw_Reverse_SB_LPWStr_OutAttr(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline _bstr_t IStringTesting::Reverse_BStr ( _bstr_t a ) { - BSTR _result = 0; - HRESULT _hr = raw_Reverse_BStr(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _bstr_t(_result, false); -} - -inline _bstr_t IStringTesting::Reverse_BStr_Ref ( BSTR * a ) { - BSTR _result = 0; - HRESULT _hr = raw_Reverse_BStr_Ref(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _bstr_t(_result, false); -} - -inline _bstr_t IStringTesting::Reverse_BStr_InRef ( BSTR * a ) { - BSTR _result = 0; - HRESULT _hr = raw_Reverse_BStr_InRef(a, &_result); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _bstr_t(_result, false); -} - -inline HRESULT IStringTesting::Reverse_BStr_Out ( _bstr_t a, BSTR * b ) { - HRESULT _hr = raw_Reverse_BStr_Out(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -inline HRESULT IStringTesting::Reverse_BStr_OutAttr ( _bstr_t a, _bstr_t b ) { - HRESULT _hr = raw_Reverse_BStr_OutAttr(a, b); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} - -// -// interface IErrorMarshalTesting wrapper method implementations -// - -inline HRESULT IErrorMarshalTesting::Throw_HResult ( int hresultToReturn ) { - HRESULT _hr = raw_Throw_HResult(hresultToReturn); - if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); - return _hr; -} diff --git a/tests/src/Interop/COM/ServerContracts/ServerGuids.cs b/tests/src/Interop/COM/ServerContracts/ServerGuids.cs index 8b89f26175..167a2373a1 100644 --- a/tests/src/Interop/COM/ServerContracts/ServerGuids.cs +++ b/tests/src/Interop/COM/ServerContracts/ServerGuids.cs @@ -13,5 +13,7 @@ namespace Server.Contract public const string ArrayTesting = "B99ABE6A-DFF6-440F-BFB6-55179B8FE18E"; public const string StringTesting = "C73C83E8-51A2-47F8-9B5C-4284458E47A6"; public const string ErrorMarshalTesting = "71CF5C45-106C-4B32-B418-43A463C6041F"; + public const string DispatchTesting = "0F8ACD0C-ECE0-4F2A-BD1B-6BFCA93A0726"; + public const string AggregationTesting = "4CEFE36D-F377-4B6E-8C34-819A8BB9CB04"; } }
\ No newline at end of file diff --git a/tests/src/Interop/COM/ServerContracts/readme.md b/tests/src/Interop/COM/ServerContracts/readme.md deleted file mode 100644 index 347c7fc3f2..0000000000 --- a/tests/src/Interop/COM/ServerContracts/readme.md +++ /dev/null @@ -1,9 +0,0 @@ -## Server Contracts - -This directory contains the API contracts for the testing of .NET COM interop. The contract is defined in C# to the degree that the [TlbExp.exe](https://docs.microsoft.com/en-us/dotnet/framework/tools/tlbexp-exe-type-library-exporter) tool can be used to generate a TLB that can then be used by the Microsoft VC++ compiler to generate the `tlh` and `tli` files. This is a manual process at the moment, but as more support is added to CoreCLR, this may change. - -The process to create a TLB and update the native contracts are as follows: - -1) Take the `Primitives.cs` file and create a DLL using a SDK project. -1) Use the .NET Framework [TlbExp.exe](https://docs.microsoft.com/en-us/dotnet/framework/tools/tlbexp-exe-type-library-exporter) to create a `tlb` based on the DLL previously compiled. -1) Using the Microsoft VC++ compiler consume the `tlb` using the [`#import`](https://msdn.microsoft.com/en-us/library/8etzzkb6.aspx) directive (See commented out line in `Servers.h`). The compiler will generate two files (`tlh` and `tli`). The files in this directory can then be updated.
\ No newline at end of file |