nc = m_numchar - 1;
int cbwritten = InternalWideToAnsi(pString->GetBuffer(),
- nc,
- (CHAR*)pNativeValue,
- m_numchar,
- m_BestFitMap,
- m_ThrowOnUnmappableChar);
+ nc,
+ (CHAR*)pNativeValue,
+ m_numchar,
+ m_BestFitMap,
+ m_ThrowOnUnmappableChar);
+
+ // Handle the case where SizeConst == Number of bytes.For single byte chars
+ // this will never be the case since nc >= m_numchar check will truncate the last
+ // character, but for multibyte chars nc>= m_numchar check won't truncate since GetStringLength
+ // gives number of characters but not the actual number of bytes. For such cases need to make
+ // sure that we dont write one past the buffer.
+ if (cbwritten == m_numchar)
+ --cbwritten;
+
((CHAR*)pNativeValue)[cbwritten] = '\0';
}
-
}
}
else
{
- // Make sure the size of the array is the same as specified in the MarshalAs attribute (via the SizeConst field).
+ // Make sure the size of the array is >= as specified in the MarshalAs attribute (via the SizeConst field).
if ((*pCLRValue)->GetNumComponents() < m_numElems)
COMPlusThrow(kArgumentException, IDS_WRONGSIZEARRAY_IN_NSTRUCT);
-
+
// Marshal the contents from the managed array to the native array.
const OleVariant::Marshaler *pMarshaler = OleVariant::GetMarshalerForVarType(m_vt, TRUE);
if (pMarshaler == NULL || pMarshaler->ComToOleArray == NULL)
// We never operate on an uninitialized native layout here, we have zero'ed it if needed.
// Therefore fOleArrayIsValid is always TRUE.
- pMarshaler->ComToOleArray((BASEARRAYREF*)pCLRValue, pNativeValue, pElementMT, m_BestFitMap, m_ThrowOnUnmappableChar, TRUE);
+ pMarshaler->ComToOleArray((BASEARRAYREF*)pCLRValue, pNativeValue, pElementMT, m_BestFitMap, m_ThrowOnUnmappableChar, TRUE, m_numElems);
}
}
}
if (*pArrayRef != NULL)
{
const OleVariant::Marshaler* pMarshaler = OleVariant::GetMarshalerForVarType(pThis->m_vt, TRUE);
-
+ SIZE_T cElements = (*pArrayRef)->GetNumComponents();
if (pMarshaler == NULL || pMarshaler->ComToOleArray == NULL)
{
- SIZE_T cElements = (*pArrayRef)->GetNumComponents();
- SIZE_T cbArray = cElements;
- if ( (!SafeMulSIZE_T(&cbArray, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cbArray > MAX_SIZE_FOR_INTEROP)
+ if ( (!SafeMulSIZE_T(&cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cElements > MAX_SIZE_FOR_INTEROP)
COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE);
_ASSERTE(!GetTypeHandleForCVType(OleVariant::GetCVTypeForVarType(pThis->m_vt)).GetMethodTable()->ContainsPointers());
- memcpyNoGCRefs(*pNativeHome, (*pArrayRef)->GetDataPtr(), cbArray);
+ memcpyNoGCRefs(*pNativeHome, (*pArrayRef)->GetDataPtr(), cElements);
}
else
{
- pMarshaler->ComToOleArray(pArrayRef, *pNativeHome, pThis->m_pElementMT, pThis->m_BestFitMap, pThis->m_ThrowOnUnmappableChar, pThis->m_NativeDataValid);
+ pMarshaler->ComToOleArray(pArrayRef, *pNativeHome, pThis->m_pElementMT, pThis->m_BestFitMap,
+ pThis->m_ThrowOnUnmappableChar, pThis->m_NativeDataValid, cElements);
}
}
HELPER_METHOD_FRAME_END();
if (pMarshaler == NULL || pMarshaler->OleToComArray == NULL)
{
SIZE_T cElements = (*pArrayRef)->GetNumComponents();
- SIZE_T cbArray = cElements;
- if ( (!SafeMulSIZE_T(&cbArray, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cbArray > MAX_SIZE_FOR_INTEROP)
+ if ( (!SafeMulSIZE_T(&cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cElements > MAX_SIZE_FOR_INTEROP)
COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE);
// If we are copying variants, strings, etc, we need to use write barrier
_ASSERTE(!GetTypeHandleForCVType(OleVariant::GetCVTypeForVarType(pThis->m_vt)).GetMethodTable()->ContainsPointers());
- memcpyNoGCRefs((*pArrayRef)->GetDataPtr(), *pNativeHome, cbArray );
+ memcpyNoGCRefs((*pArrayRef)->GetDataPtr(), *pNativeHome, cElements);
}
else
{
void OleVariant::MarshalBoolArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
CONTRACTL_END;
ASSERT_PROTECTED(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
VARIANT_BOOL *pOle = (VARIANT_BOOL *) oleArray;
- VARIANT_BOOL *pOleEnd = pOle + elementCount;
+ VARIANT_BOOL *pOleEnd = pOle + cElements;
UCHAR *pCom = (UCHAR *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalWinBoolArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
CONTRACTL_END;
ASSERT_PROTECTED(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
BOOL *pOle = (BOOL *) oleArray;
- BOOL *pOleEnd = pOle + elementCount;
+ BOOL *pOleEnd = pOle + cElements;
UCHAR *pCom = (UCHAR *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalCBoolArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid,
+ SIZE_T cElements)
{
LIMITED_METHOD_CONTRACT;
ASSERT_PROTECTED(pComArray);
_ASSERTE((*pComArray)->GetArrayElementType() == ELEMENT_TYPE_BOOLEAN);
-
- SIZE_T cbArray = (*pComArray)->GetNumComponents();
+
BYTE *pOle = (BYTE *) oleArray;
- BYTE *pOleEnd = pOle + cbArray;
+ BYTE *pOleEnd = pOle + cElements;
UCHAR *pCom = (UCHAR *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalAnsiCharArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid,
+ SIZE_T cElements)
{
CONTRACTL
{
PRECONDITION(CheckPointer(pComArray));
}
CONTRACTL_END;
-
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
const WCHAR *pCom = (const WCHAR *) (*pComArray)->GetDataPtr();
- if (!FitsIn<int>(elementCount))
+ if (!FitsIn<int>(cElements))
COMPlusThrowHR(COR_E_OVERFLOW);
- int cchCount = (int)elementCount;
+ int cchCount = (int)cElements;
int cbBuffer;
if (!ClrSafeInt<int>::multiply(cchCount, GetMaxDBCSCharByteSize(), cbBuffer))
void OleVariant::MarshalIUnknownArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pElementMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
WRAPPER_NO_CONTRACT;
- MarshalInterfaceArrayComToOleHelper(pComArray, oleArray, pElementMT, FALSE);
+ MarshalInterfaceArrayComToOleHelper(pComArray, oleArray, pElementMT, FALSE, cElements);
}
void OleVariant::ClearInterfaceArray(void *oleArray, SIZE_T cElements, MethodTable *pInterfaceMT)
void OleVariant::MarshalBSTRArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
{
ASSERT_PROTECTED(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
-
BSTR *pOle = (BSTR *) oleArray;
- BSTR *pOleEnd = pOle + elementCount;
+ BSTR *pOleEnd = pOle + cElements;
STRINGREF *pCom = (STRINGREF *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalNonBlittableRecordArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
CONTRACTL_END;
ASSERT_PROTECTED(pComArray);
-
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
+
SIZE_T elemSize = pInterfaceMT->GetNativeSize();
BYTE *pOle = (BYTE *) oleArray;
- BYTE *pOleEnd = pOle + elemSize * elementCount;
+ BYTE *pOleEnd = pOle + elemSize * cElements;
if (!fOleArrayIsValid)
{
void OleVariant::MarshalLPWSTRRArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
ASSERT_PROTECTED(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
-
LPWSTR *pOle = (LPWSTR *) oleArray;
- LPWSTR *pOleEnd = pOle + elementCount;
+ LPWSTR *pOleEnd = pOle + cElements;
STRINGREF *pCom = (STRINGREF *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalLPSTRRArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
ASSERT_PROTECTED(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
-
LPSTR *pOle = (LPSTR *) oleArray;
- LPSTR *pOleEnd = pOle + elementCount;
+ LPSTR *pOleEnd = pOle + cElements;
STRINGREF *pCom = (STRINGREF *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalDateArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
CONTRACTL_END;
ASSERT_PROTECTED(pComArray);
-
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
-
+
DATE *pOle = (DATE *) oleArray;
- DATE *pOleEnd = pOle + elementCount;
+ DATE *pOleEnd = pOle + cElements;
INT64 *pCom = (INT64 *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalRecordArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pElementMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
{
// The array is blittable so we can simply copy it.
_ASSERTE(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
SIZE_T elemSize = pElementMT->GetNativeSize();
- memcpyNoGCRefs(oleArray, (*pComArray)->GetDataPtr(), elementCount * elemSize);
+ memcpyNoGCRefs(oleArray, (*pComArray)->GetDataPtr(), cElements * elemSize);
}
else
{
// The array is non blittable so we need to marshal the elements.
_ASSERTE(pElementMT->HasLayout());
- MarshalNonBlittableRecordArrayComToOle(pComArray, oleArray, pElementMT, fBestFitMapping, fThrowOnUnmappableChar, fOleArrayIsValid);
+ MarshalNonBlittableRecordArrayComToOle(pComArray, oleArray, pElementMT, fBestFitMapping, fThrowOnUnmappableChar, fOleArrayIsValid, cElements);
}
}
}
void OleVariant::MarshalInterfaceArrayComToOleHelper(BASEARRAYREF *pComArray, void *oleArray,
- MethodTable *pElementMT, BOOL bDefaultIsDispatch)
+ MethodTable *pElementMT, BOOL bDefaultIsDispatch,
+ SIZE_T cElements)
{
CONTRACTL
{
CONTRACTL_END;
ASSERT_PROTECTED(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
+
BOOL bDispatch = bDefaultIsDispatch;
BOOL bHeterogenous = (pElementMT == NULL);
// Determine the start and the end of the data in the OLE array.
IUnknown **pOle = (IUnknown **) oleArray;
- IUnknown **pOleEnd = pOle + elementCount;
+ IUnknown **pOleEnd = pOle + cElements;
// Retrieve the start of the data in the managed array.
BASEARRAYREF unprotectedArray = *pComArray;
void OleVariant::MarshalIDispatchArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pElementMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid,
+ SIZE_T cElements)
{
WRAPPER_NO_CONTRACT;
- MarshalInterfaceArrayComToOleHelper(pComArray, oleArray, pElementMT, TRUE);
+ MarshalInterfaceArrayComToOleHelper(pComArray, oleArray, pElementMT, TRUE, cElements);
}
void OleVariant::MarshalCurrencyArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
}
CONTRACTL_END;
- ASSERT_PROTECTED(pComArray);
- SIZE_T elementCount = (*pComArray)->GetNumComponents();
+ ASSERT_PROTECTED(pComArray);
CURRENCY *pOle = (CURRENCY *) oleArray;
- CURRENCY *pOleEnd = pOle + elementCount;
+ CURRENCY *pOleEnd = pOle + cElements;
DECIMAL *pCom = (DECIMAL *) (*pComArray)->GetDataPtr();
void OleVariant::MarshalVariantArrayComToOle(BASEARRAYREF *pComArray, void *oleArray,
MethodTable *pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid)
+ BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid, SIZE_T cElements)
{
CONTRACTL
{
// of UnknownWrapper or DispatchWrapper. It shall use a different logic and marshal each
// element according to its specific default interface.
pInterfaceMT = NULL;
- }
- marshal->ComToOleArray(&Array, pSafeArray->pvData, pInterfaceMT, TRUE, FALSE, fSafeArrayIsValid);
- }
+ }
+ marshal->ComToOleArray(&Array, pSafeArray->pvData, pInterfaceMT, TRUE, FALSE, fSafeArrayIsValid, dwNumComponents);
+ }
if (pSafeArray->cDims != 1)
{
// Helper called from MarshalIUnknownArrayComToOle and MarshalIDispatchArrayComToOle.
static void MarshalInterfaceArrayComToOleHelper(BASEARRAYREF* pComArray, void* oleArray,
- MethodTable* pElementMT, BOOL bDefaultIsDispatch);
+ MethodTable* pElementMT, BOOL bDefaultIsDispatch,
+ SIZE_T cElements);
#endif // FEATURE_COMINTEROP
struct Marshaler
#endif // FEATURE_COMINTEROP
void (*OleToComArray)(void* oleArray, BASEARRAYREF* pComArray, MethodTable* pInterfaceMT);
void (*ComToOleArray)(BASEARRAYREF* pComArray, void* oleArray, MethodTable* pInterfaceMT,
- BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid);
+ BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayIsValid,SIZE_T cElements);
void (*ClearOleArray)(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT);
};
static void MarshalBoolArrayOleToCom(void *oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalBoolArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
- MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid);
+ MethodTable* pInterfaceMT, BOOL fBestFitMapping,
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayIsValid,
+ SIZE_T cElements);
static void MarshalWinBoolArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalWinBoolArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void MarshalCBoolVariantOleToCom(VARIANT* pOleVariant, VariantData* pComVariant);
static void MarshalCBoolVariantComToOle(VariantData* pComVariant, VARIANT* pOleVariant);
static void MarshalCBoolVariantOleRefToCom(VARIANT* pOleVariant, VariantData* pComVariant);
static void MarshalCBoolArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalCBoolArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
- MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ MethodTable* pInterfaceMT, BOOL fBestFitMapping,
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void MarshalAnsiCharArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalAnsiCharArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
#ifdef FEATURE_COMINTEROP
static void MarshalIDispatchArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
#endif // FEATURE_COMINTEROP
#ifdef FEATURE_COMINTEROP
MethodTable* pInterfaceMT);
static void MarshalBSTRArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void ClearBSTRArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT);
#endif // FEATURE_COMINTEROP
MethodTable* pInterfaceMT);
static void MarshalNonBlittableRecordArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void ClearNonBlittableRecordArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT);
static void MarshalLPWSTRArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalLPWSTRRArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void ClearLPWSTRArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT);
static void MarshalLPSTRArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalLPSTRRArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void ClearLPSTRArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT);
static void MarshalDateArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalDateArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void MarshalRecordArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray, MethodTable* pElementMT);
static void MarshalRecordArrayComToOle(BASEARRAYREF* pComArray, void* oleArray, MethodTable* pElementMT,
- BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fBestFitMapping, BOOL fThrowOnUnmappableChar,
+ BOOL fOleArrayValid,
+ SIZE_T cElements);
static void ClearRecordArray(void* oleArray, SIZE_T cElements, MethodTable* pElementMT);
#ifdef FEATURE_COMINTEROP
MethodTable* pInterfaceMT);
static void MarshalIUnknownArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void ClearInterfaceArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT);
static void MarshalBoolVariantOleToCom(VARIANT* pOleVariant, VariantData* pComVariant);
MethodTable* pInterfaceMT);
static void MarshalCurrencyArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void MarshalVariantArrayOleToCom(void* oleArray, BASEARRAYREF* pComArray,
MethodTable* pInterfaceMT);
static void MarshalVariantArrayComToOle(BASEARRAYREF* pComArray, void* oleArray,
MethodTable* pInterfaceMT, BOOL fBestFitMapping,
- BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid);
+ BOOL fThrowOnUnmappableChar, BOOL fOleArrayValid,
+ SIZE_T cElements);
static void ClearVariantArray(void* oleArray, SIZE_T cElements, MethodTable* pInterfaceMT);
#ifdef FEATURE_CLASSIC_COMINTEROP
add_subdirectory(StringMarshalling/UTF8)
add_subdirectory(MarshalAPI/FunctionPointer)
add_subdirectory(MarshalAPI/IUnknown)
+add_subdirectory(SizeConst)
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+
+class Program
+{
+ static int Main(string[] args)
+ {
+ VerifyByValBoolArray();
+ VerifyByValArrayInStruct();
+ VerfiyByValDateArray();
+ return 100;
+ }
+
+ static void VerifyByValBoolArray()
+ {
+ var structure1 = new StructWithBoolArray()
+ {
+ array = new bool[]
+ {
+ true,true,true,true
+ }
+ };
+
+ int size = Marshal.SizeOf(structure1);
+ IntPtr memory = Marshal.AllocHGlobal(size + sizeof(Int32));
+
+ try
+ {
+ Marshal.WriteInt32(memory, size, 0xFF);
+ Marshal.StructureToPtr(structure1, memory, false);
+
+ if (Marshal.ReadInt32(memory, size) != 0xFF)
+ throw new Exception("Marshal.StructureToPtr buffer overwritten...");
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(memory);
+ }
+ }
+
+ static void VerifyByValArrayInStruct()
+ {
+ // equal
+ var structure1 = new StructWithByValArray()
+ {
+ array = new StructWithIntField[]
+ {
+ new StructWithIntField { value = 1 },
+ new StructWithIntField { value = 2 },
+ new StructWithIntField { value = 3 },
+ new StructWithIntField { value = 4 },
+ new StructWithIntField { value = 5 }
+ }
+ };
+ int size = Marshal.SizeOf(structure1);
+ IntPtr memory = Marshal.AllocHGlobal(size);
+ try
+ {
+ Marshal.StructureToPtr(structure1, memory, false);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(memory);
+ }
+
+ // underflow
+ var structure2 = new StructWithByValArray()
+ {
+ array = new StructWithIntField[]
+ {
+ new StructWithIntField { value = 1 },
+ new StructWithIntField { value = 2 },
+ new StructWithIntField { value = 3 },
+ new StructWithIntField { value = 4 }
+ }
+ };
+ bool expectedException = false;
+ size = Marshal.SizeOf(structure2);
+ memory = Marshal.AllocHGlobal(size);
+ try
+ {
+ Marshal.StructureToPtr(structure2, memory, false);
+ }
+ catch (ArgumentException)
+ {
+ expectedException = true;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(memory);
+ }
+ if (!expectedException)
+ throw new Exception("Expected ArgumentException");
+
+ // overflow
+ var structure3 = new StructWithByValArray()
+ {
+ array = new StructWithIntField[]
+ {
+ new StructWithIntField { value = 1 },
+ new StructWithIntField { value = 2 },
+ new StructWithIntField { value = 3 },
+ new StructWithIntField { value = 4 },
+ new StructWithIntField { value = 5 },
+ new StructWithIntField { value = 6 }
+ }
+ };
+
+ size = Marshal.SizeOf(structure3);
+ memory = Marshal.AllocHGlobal(size);
+ try
+ {
+ Marshal.StructureToPtr(structure3, memory, false);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(memory);
+ }
+ }
+
+ static void VerfiyByValDateArray()
+ {
+ var structure1 = new StructWithDateArray()
+ {
+ array = new DateTime[]
+ {
+ DateTime.Now, DateTime.Now , DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now , DateTime.Now, DateTime.Now
+ }
+ };
+
+ int size = Marshal.SizeOf(structure1);
+ IntPtr memory = Marshal.AllocHGlobal(size);
+ try
+ {
+ Marshal.StructureToPtr(structure1, memory, false);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(memory);
+ }
+ }
+
+ public struct StructWithIntField
+ {
+ public int value;
+ }
+
+ public struct StructWithByValArray
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
+ public StructWithIntField[] array;
+ }
+
+ public struct StructWithBoolArray
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ public bool[] array;
+ }
+
+ public struct StructWithDateArray
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ public DateTime[] array;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?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>MarshalStructure</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="*.cs" />
+ <Compile Include="..\..\common\Assertion.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
--- /dev/null
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc3-24117-00",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc3-24117-00",
+ "System.Collections.Specialized": "4.0.1-rc3-24117-00",
+ "System.ComponentModel": "4.0.1-rc3-24117-00",
+ "System.Console": "4.0.0-rc3-24117-00",
+ "System.Diagnostics.Process": "4.1.0-rc3-24117-00",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.1-rc3-24117-00",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.1.0-rc3-24117-00",
+ "System.Linq.Queryable": "4.0.1-rc3-24117-00",
+ "System.Reflection": "4.1.0-rc3-24117-00",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc3-24117-00",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc3-24117-00",
+ "System.Runtime.Loader": "4.0.0-rc3-24117-00",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc3-24117-00",
+ "System.Xml.ReaderWriter": "4.0.11-rc3-24117-00",
+ "System.Xml.XDocument": "4.0.11-rc3-24117-00",
+ "System.Xml.XmlDocument": "4.0.1-rc3-24117-00",
+ "System.Xml.XmlSerializer": "4.0.11-rc3-24117-00"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ },
+ "runtimes": {
+ "win7-x86": {},
+ "win7-x64": {},
+ "ubuntu.14.04-x64": {},
+ "osx.10.10-x64": {},
+ "centos.7-x64": {},
+ "rhel.7-x64": {},
+ "debian.8-x64": {}
+ }
+}
--- /dev/null
+cmake_minimum_required (VERSION 2.6)
+project (SizeConstNative)
+set(SOURCES SizeConstNative.cpp)
+
+# add the executable
+add_library (SizeConstNative SHARED ${SOURCES})
+
+# add the install targets
+install (TARGETS SizeConstNative DESTINATION bin)
+
+
--- /dev/null
+// 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 <xplatform.h>
+
+const int ARRAY_SIZE = 100;
+typedef struct { char arr[ARRAY_SIZE]; } S_CHARByValArray;
+extern "C" DLL_EXPORT BOOL TakeByValTStr(S_CHARByValArray s, int size)
+{
+ return true;
+}
\ No newline at end of file
--- /dev/null
+// 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.
+
+using System;
+using System.Runtime.InteropServices;
+
+
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+public struct S_CHARArray_ByValTStr
+{
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
+ public string arr;
+ public S_CHARArray_ByValTStr(string parr) { arr = parr; }
+}
+
+class Test
+{
+ internal const int ARRAY_SIZE = 100;
+
+ //UnmanagedType.ByValTStr
+ [DllImport("SizeConstNative",CharSet = CharSet.Ansi)]
+ static extern bool TakeByValTStr(S_CHARArray_ByValTStr s, int size);
+
+ static bool SizeConstByValTStr()
+ {
+ // always marshal managedArray.Length
+ S_CHARArray_ByValTStr s = new S_CHARArray_ByValTStr();
+ s.arr = "有个可爱";
+ TakeByValTStr(s, s.arr.Length);
+
+ // off by one byte since sizeconst == 4 and
+ // number of bytes == 4 . We used to write
+ // one past the buffer before but now we truncate at 3rd byte.
+ // In order to test this the locale of the machine need to
+ // a multibyte char set.
+ s.arr = "个个";
+ TakeByValTStr(s, s.arr.Length);
+ return true;
+ }
+
+ static int Main(string[] args)
+ {
+ SizeConstByValTStr();
+ return 100;
+ }
+}
--- /dev/null
+<?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>SizeConstTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SizeConstTest.cs" />
+ <Compile Include="..\common\Assertion.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
--- /dev/null
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc3-24117-00",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc3-24117-00",
+ "System.Collections.Specialized": "4.0.1-rc3-24117-00",
+ "System.ComponentModel": "4.0.1-rc3-24117-00",
+ "System.Console": "4.0.0-rc3-24117-00",
+ "System.Diagnostics.Process": "4.1.0-rc3-24117-00",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.1-rc3-24117-00",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.1.0-rc3-24117-00",
+ "System.Linq.Queryable": "4.0.1-rc3-24117-00",
+ "System.Reflection": "4.1.0-rc3-24117-00",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc3-24117-00",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc3-24117-00",
+ "System.Runtime.Loader": "4.0.0-rc3-24117-00",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc3-24117-00",
+ "System.Xml.ReaderWriter": "4.0.11-rc3-24117-00",
+ "System.Xml.XDocument": "4.0.11-rc3-24117-00",
+ "System.Xml.XmlDocument": "4.0.1-rc3-24117-00",
+ "System.Xml.XmlSerializer": "4.0.11-rc3-24117-00"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ },
+ "runtimes": {
+ "win7-x86": {},
+ "win7-x64": {},
+ "ubuntu.14.04-x64": {},
+ "osx.10.10-x64": {},
+ "centos.7-x64": {},
+ "rhel.7-x64": {},
+ "debian.8-x64": {}
+ }
+}
JIT/Regression/VS-ia64-JIT/V2.0-RTM/b286991/b286991/b286991.sh
managed/Compilation/Compilation/Compilation.sh
Regressions/coreclr/0584/Test584/Test584.sh
+Interop/SizeConst/SizeConstTest/SizeConstTest.sh