diff --git a/src/coreclr/src/vm/ilmarshalers.cpp b/src/coreclr/src/vm/ilmarshalers.cpp index a9257e048bf70..ec846aaadc624 100644 --- a/src/coreclr/src/vm/ilmarshalers.cpp +++ b/src/coreclr/src/vm/ilmarshalers.cpp @@ -4515,7 +4515,7 @@ void MngdNativeArrayMarshaler::DoClearNativeContents(MngdNativeArrayMarshaler* p if (pMarshaler != NULL && pMarshaler->ClearOleArray != NULL) { - pMarshaler->ClearOleArray((BASEARRAYREF*)pManagedHome, *pNativeHome, cElements, pThis->m_pElementMT, pThis->m_pManagedMarshaler); + pMarshaler->ClearOleArray(*pNativeHome, cElements, pThis->m_pElementMT, pThis->m_pManagedMarshaler); } } } @@ -4733,15 +4733,13 @@ FCIMPL3(void, MngdFixedArrayMarshaler::ClearNativeContents, MngdFixedArrayMarsha { FCALL_CONTRACT; - BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome; - - HELPER_METHOD_FRAME_BEGIN_1(arrayRef); + HELPER_METHOD_FRAME_BEGIN_0(); const OleVariant::Marshaler* pMarshaler = OleVariant::GetMarshalerForVarType(pThis->m_vt, FALSE); if (pMarshaler != NULL && pMarshaler->ClearOleArray != NULL) { - pMarshaler->ClearOleArray(&arrayRef, pNativeHome, pThis->m_cElements, pThis->m_pElementMT, pThis->m_pManagedElementMarshaler); + pMarshaler->ClearOleArray(pNativeHome, pThis->m_cElements, pThis->m_pElementMT, pThis->m_pManagedElementMarshaler); } HELPER_METHOD_FRAME_END(); diff --git a/src/coreclr/src/vm/olevariant.cpp b/src/coreclr/src/vm/olevariant.cpp index 7be1d015db8a3..240b56427f761 100644 --- a/src/coreclr/src/vm/olevariant.cpp +++ b/src/coreclr/src/vm/olevariant.cpp @@ -1835,7 +1835,7 @@ void OleVariant::MarshalIUnknownArrayComToOle(BASEARRAYREF *pComArray, void *ole MarshalInterfaceArrayComToOleHelper(pComArray, oleArray, pElementMT, FALSE, cElements); } -void OleVariant::ClearInterfaceArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) +void OleVariant::ClearInterfaceArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) { CONTRACTL { @@ -2009,7 +2009,7 @@ void OleVariant::MarshalBSTRArrayComToOle(BASEARRAYREF *pComArray, void *oleArra GCPROTECT_END(); } -void OleVariant::ClearBSTRArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) +void OleVariant::ClearBSTRArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) { CONTRACTL { @@ -2112,7 +2112,7 @@ void OleVariant::MarshalNonBlittableRecordArrayComToOle(BASEARRAYREF *pComArray, } } -void OleVariant::ClearNonBlittableRecordArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) +void OleVariant::ClearNonBlittableRecordArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) { CONTRACTL { @@ -2124,20 +2124,15 @@ void OleVariant::ClearNonBlittableRecordArray(BASEARRAYREF* pComArray, void *ole } CONTRACTL_END; - ASSERT_PROTECTED(pComArray); - SIZE_T elemSize = pInterfaceMT->GetNativeSize(); + SIZE_T componentSize = TypeHandle(pInterfaceMT).MakeSZArray().GetMethodTable()->GetComponentSize(); BYTE *pOle = (BYTE *) oleArray; BYTE *pOleEnd = pOle + elemSize * cElements; - SIZE_T srcofs = *pComArray != NULL ? ArrayBase::GetDataPtrOffset((*pComArray)->GetMethodTable()) : 0; while (pOle < pOleEnd) { - BYTE* managedData = (BYTE*)(*(LPVOID*)pComArray) + srcofs; - - MarshalStructViaILStubCode(pManagedMarshalerCode, managedData, pOle, StructMarshalStubs::MarshalOperation::Cleanup); + MarshalStructViaILStubCode(pManagedMarshalerCode, nullptr, pOle, StructMarshalStubs::MarshalOperation::Cleanup); pOle += elemSize; - srcofs += (*pComArray)->GetComponentSize(); } } @@ -2255,7 +2250,7 @@ void OleVariant::MarshalLPWSTRRArrayComToOle(BASEARRAYREF *pComArray, void *oleA } } -void OleVariant::ClearLPWSTRArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) +void OleVariant::ClearLPWSTRArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) { CONTRACTL { @@ -2392,7 +2387,7 @@ void OleVariant::MarshalLPSTRRArrayComToOle(BASEARRAYREF *pComArray, void *oleAr } } -void OleVariant::ClearLPSTRArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) +void OleVariant::ClearLPSTRArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) { CONTRACTL { @@ -2736,7 +2731,7 @@ void OleVariant::MarshalRecordArrayComToOle(BASEARRAYREF *pComArray, void *oleAr } -void OleVariant::ClearRecordArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pElementMT, PCODE pManagedMarshalerCode) +void OleVariant::ClearRecordArray(void *oleArray, SIZE_T cElements, MethodTable *pElementMT, PCODE pManagedMarshalerCode) { CONTRACTL { @@ -2751,7 +2746,7 @@ void OleVariant::ClearRecordArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_ if (!pElementMT->IsBlittable()) { _ASSERTE(pElementMT->HasLayout()); - ClearNonBlittableRecordArray(pComArray, oleArray, cElements, pElementMT, pManagedMarshalerCode); + ClearNonBlittableRecordArray(oleArray, cElements, pElementMT, pManagedMarshalerCode); } } @@ -4072,7 +4067,7 @@ void OleVariant::MarshalVariantArrayComToOle(BASEARRAYREF *pComArray, void *oleA GCPROTECT_END(); } -void OleVariant::ClearVariantArray(BASEARRAYREF* pComArray, void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) +void OleVariant::ClearVariantArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT, PCODE pManagedMarshalerCode) { CONTRACTL { diff --git a/src/coreclr/src/vm/olevariant.h b/src/coreclr/src/vm/olevariant.h index 2cca65fadf8cb..a09616d781809 100644 --- a/src/coreclr/src/vm/olevariant.h +++ b/src/coreclr/src/vm/olevariant.h @@ -462,7 +462,7 @@ class OleVariant BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid,SIZE_T cElements, PCODE pManagedMarshalerCode); - void (*ClearOleArray)(BASEARRAYREF* pComArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); + void (*ClearOleArray)(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); }; static const Marshaler* GetMarshalerForVarType(VARTYPE vt, BOOL fThrow); @@ -521,7 +521,7 @@ class OleVariant MethodTable* pInterfaceMT, BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid, SIZE_T cElements, PCODE pManagedMarshalerCode); - static void ClearBSTRArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); + static void ClearBSTRArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); #endif // FEATURE_COMINTEROP static void MarshalNonBlittableRecordArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray, @@ -530,7 +530,7 @@ class OleVariant MethodTable* pInterfaceMT, BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid, SIZE_T cElements, PCODE pManagedMarshalerCode); - static void ClearNonBlittableRecordArray(BASEARRAYREF* comArray, void* oleArray, + static void ClearNonBlittableRecordArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); @@ -540,7 +540,7 @@ class OleVariant MethodTable* pInterfaceMT, BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid, SIZE_T cElements, PCODE pManagedMarshalerCode); - static void ClearLPWSTRArray(BASEARRAYREF* comArray, void* oleArray, + static void ClearLPWSTRArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); static void MarshalLPSTRArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray, @@ -549,7 +549,7 @@ class OleVariant MethodTable* pInterfaceMT, BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid, SIZE_T cElements, PCODE pManagedMarshalerCode); - static void ClearLPSTRArray(BASEARRAYREF* comArray, void* oleArray, + static void ClearLPSTRArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); static void MarshalDateArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray, @@ -564,7 +564,7 @@ class OleVariant BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid, SIZE_T cElements, PCODE pManagedMarshalerCode); - static void ClearRecordArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pElementMT, PCODE pManagedMarshalerCode); + static void ClearRecordArray(void* oleArray, SIZE_T cElements, MethodTable* pElementMT, PCODE pManagedMarshalerCode); #ifdef FEATURE_COMINTEROP static HRESULT MarshalCommonOleRefVariantForObject(OBJECTREF *pObj, VARIANT *pOle); @@ -574,7 +574,7 @@ class OleVariant MethodTable* pInterfaceMT, BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid, SIZE_T cElements, PCODE pManagedMarshalerCode); - static void ClearInterfaceArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); + static void ClearInterfaceArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); static void MarshalBoolVariantOleToCom(VARIANT* pOleVariant, VariantData* pComVariant); @@ -623,7 +623,7 @@ class OleVariant MethodTable* pInterfaceMT, BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid, SIZE_T cElements, PCODE pManagedMarshalerCode); - static void ClearVariantArray(BASEARRAYREF* comArray, void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); + static void ClearVariantArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT, PCODE pManagedMarshalerCode); #ifdef FEATURE_CLASSIC_COMINTEROP static void MarshalArrayVariantOleToCom(VARIANT* pOleVariant, VariantData* pComVariant); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs index c0e26a720ad59..7ca8b00f6450d 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs @@ -106,6 +106,28 @@ public void DestroyStructure_AutoLayout_ThrowsArgumentException() AssertExtensions.Throws("structureType", () => Marshal.DestroyStructure((IntPtr)1, typeof(AutoLayoutStruct))); } + [Fact] + public void DestroyStructure_NestedNonBlittableStruct_Success() + { + WINTRUST_BLOB_INFO wbi = new WINTRUST_BLOB_INFO(); + byte[] contentBytes = System.Text.Encoding.Unicode.GetBytes("foo"); + + wbi.gSubject.Data1 = 0x603bcc1f; + wbi.gSubject.Data2 = 0x4b59; + wbi.gSubject.Data3 = 0x4e08; + wbi.gSubject.Data4 = new byte[] { 0xb7, 0x24, 0xd2, 0xc6, 0x29, 0x7e, 0xf3, 0x51 }; + + wbi.cbStruct = (uint)Marshal.SizeOf(wbi); + wbi.pcwszDisplayName = "bar"; + + IntPtr pBlob = Marshal.AllocCoTaskMem(Marshal.SizeOf(wbi)); + Marshal.StructureToPtr(wbi, pBlob, false); + + Marshal.DestroyStructure(pBlob); + + Marshal.FreeCoTaskMem(pBlob); + } + [StructLayout(LayoutKind.Sequential)] public struct TestStruct { @@ -118,5 +140,30 @@ public struct AutoLayoutStruct { public int i; } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal struct GUID + { + internal uint Data1; + internal ushort Data2; + internal ushort Data3; + + /// unsigned char[8] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + internal byte[] Data4; + } + [StructLayout(LayoutKind.Sequential)] + internal struct WINTRUST_BLOB_INFO + { + internal uint cbStruct; + + /// GUID->_GUID + internal GUID gSubject; + //[MarshalAs(UnmanagedType.Struct)] + //internal Guid gSubject; + + [MarshalAsAttribute(UnmanagedType.LPWStr)] + internal string pcwszDisplayName; + } } }