HRESULT Library_spot_native_Microsoft_SPOT_CryptoState::LoadAsymmetricKey( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis;
    CLR_RT_HeapBlock_Array* array;

    pThis = stack.This(); FAULT_ON_NULL(pThis);

    //
    // Init RSA key.
    //
    array = pThis[ Library_spot_native_Microsoft_SPOT_Cryptography_Key_RSA::FIELD__m_modulus ].DereferenceArray(); FAULT_ON_NULL(array);
    memcpy( &m_keyAsymmetric.module, array->GetFirstElement(), sizeof(m_keyAsymmetric.module) );

    array = pThis[ Library_spot_native_Microsoft_SPOT_Cryptography_Key_RSA::FIELD__m_exponent ].DereferenceArray(); FAULT_ON_NULL(array);
    memcpy( &m_keyAsymmetric.exponent, array->GetFirstElement(), sizeof(m_keyAsymmetric.exponent) );

    m_keyAsymmetric.exponent_len = RSA_KEY_SIZE_BYTES / sizeof(DWORD);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Random::NextBytes___VOID__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();
    
    CLR_RT_Random* rand;
    CLR_RT_HeapBlock_Array* buffer;

    TINYCLR_CHECK_HRESULT(GetRandom( stack, rand ));

    buffer = stack.Arg1().DereferenceArray(); FAULT_ON_NULL(buffer);

    rand->NextBytes( buffer->GetFirstElement(), buffer->m_numOfElements );
        
    TINYCLR_NOCLEANUP();
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiSign::SignFinalInternal___SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis    = stack.This();
    CLR_RT_HeapBlock_Array* pRes;
    CLR_RT_HeapBlock*       pSession = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference();
    CK_SESSION_HANDLE       hSession;
    CLR_UINT32              sigLen   = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiSign::FIELD__m_signatureLength].NumericByRef().u4;
    CLR_RT_HeapBlock        hbRef;

    FAULT_ON_NULL(pSession);

    hSession = (CK_SESSION_HANDLE)pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_handle].NumericByRef().s4;

    if(hSession == CK_SESSION_HANDLE_INVALID) TINYCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED);

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(hbRef, sigLen, g_CLR_RT_WellKnownTypes.m_UInt8));

    pRes = hbRef.DereferenceArray();

    CRYPTOKI_CHECK_RESULT(stack, C_SignFinal(hSession, pRes->GetFirstElement(), (CK_ULONG_PTR)&sigLen));

    if(sigLen < pRes->m_numOfElements)
    {
        TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(stack.PushValue(), sigLen, g_CLR_RT_WellKnownTypes.m_UInt8));

        memcpy(stack.TopValue().DereferenceArray()->GetFirstElement(), pRes->GetFirstElement(), sigLen);
    }
    else
    {
        stack.SetResult_Object(pRes);
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::DeserializeParameter___STATIC__BOOLEAN__SZARRAY_U1__OBJECT( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32 offset = 0;

    CLR_RT_HeapBlock_Array* array = stack.Arg0().DereferenceArray();
    CLR_RT_HeapBlock&         obj = stack.Arg1();

    if(!DeserializeObject( &obj, array->GetFirstElement(), offset, array->m_numOfElements )) TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);

    stack.SetResult_Boolean(true);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_MethodBase::Invoke___OBJECT__OBJECT__SZARRAY_OBJECT( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock&           obj     = stack.Arg1();
    CLR_RT_MethodDef_Instance   md;
    const CLR_RECORD_METHODDEF* mdR;
    CLR_RT_HeapBlock_Array*     pArray  = stack.Arg2().DereferenceArray();
    CLR_RT_HeapBlock*           args    = NULL;
    int                         numArgs = 0;
    CLR_RT_HeapBlock*           hbMeth  = stack.Arg0().Dereference();

    TINYCLR_CHECK_HRESULT(GetMethodDescriptor( stack, *hbMeth, md ));

    mdR = md.m_target;

    if(stack.m_customState == 0)
    {
        stack.m_customState = 1;

        if(pArray)
        {
            args    = (CLR_RT_HeapBlock*)pArray->GetFirstElement();
            numArgs =                    pArray->m_numOfElements;
        }

        TINYCLR_CHECK_HRESULT(stack.MakeCall( md, &obj, args, numArgs ));
    }
    else
    {                
        if(mdR->retVal != DATATYPE_VOID)
        {                    
            if(mdR->retVal < DATATYPE_I4)
            {
                stack.TopValue().ChangeDataType( mdR->retVal );
            }

            TINYCLR_CHECK_HRESULT(stack.TopValue().PerformBoxingIfNeeded());
        }
        else
        {               
            stack.SetResult_Object( NULL );
        }
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_HardwareProvider::NativeGetPinsMap___VOID__SZARRAY_MicrosoftSPOTHardwareCpuPinUsage( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* map;
    CLR_INT32               mapLength;
    CLR_UINT8 *             ptr;
    map = stack.Arg1().DereferenceArray();  FAULT_ON_NULL(map);

    mapLength   = map->m_numOfElements;
    ptr         = map->GetFirstElement();

   ::CPU_GPIO_GetPinsMap( ptr, mapLength );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_BitConverter::ToBoolean___STATIC__BOOLEAN__SZARRAY_U1__I4( CLR_RT_StackFrame& stack )
{
	NATIVE_PROFILE_CLR_CORE();
	TINYCLR_HEADER();

	CLR_RT_HeapBlock_Array* pArray = stack.Arg0().DereferenceArray();
	FAULT_ON_NULL_ARG(pArray);

	int index;
	index = stack.Arg1().NumericByRefConst().s4;
	if (index < 0 || (unsigned int)index >= pArray->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

	BYTE* p;
	p  = pArray->GetFirstElement();
	stack.SetResult_Boolean(*reinterpret_cast<bool*>(p + index));

	TINYCLR_NOCLEANUP();
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiRNG::SeedRandom___VOID__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis    = stack.This();
    CLR_RT_HeapBlock_Array* pData    = stack.Arg1().DereferenceArray();
    CLR_RT_HeapBlock*       pSession;
    CK_SESSION_HANDLE       hSession;

    FAULT_ON_NULL_ARG(pData);

    pSession = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference(); FAULT_ON_NULL(pSession);
    hSession = pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_handle].NumericByRef().s4;

    CRYPTOKI_CHECK_RESULT(stack, C_SeedRandom(hSession, pData->GetFirstElement(), pData->m_numOfElements));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::SetUpdateProperty___STATIC__BOOLEAN__I4__STRING__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32  handle = stack.Arg0().NumericByRef().s4;
    LPCSTR szProperty = stack.Arg1().StringText(); 
    CLR_RT_HeapBlock_Array* pData;
    int dataLen;

    FAULT_ON_NULL(szProperty);

    pData   = stack.Arg2().DereferenceArray(); FAULT_ON_NULL_ARG(pData);
    dataLen = pData->m_numOfElements;

    stack.SetResult_Boolean(TRUE == MFUpdate_SetProperty(handle, szProperty, pData->GetFirstElement(), dataLen));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::GetMissingPackets___STATIC__VOID__I4__SZARRAY_U4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32 handle = stack.Arg0().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* pArray = stack.Arg1().DereferenceArray(); 
    CLR_INT32 pktCount;

    FAULT_ON_NULL(pArray);

    pktCount = pArray->m_numOfElements;

    if(!MFUpdate_GetMissingPackets(handle, (UINT32*)pArray->GetFirstElement(), &pktCount))
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_BitConverter::ToUInt16___STATIC__U2__SZARRAY_U1__I4(CLR_RT_StackFrame& stack)
{
	NATIVE_PROFILE_CLR_CORE();
	TINYCLR_HEADER();

	BYTE *p = NULL;
	int index = 0;

	CLR_RT_HeapBlock_Array* pArray = stack.Arg0().DereferenceArray();
	FAULT_ON_NULL_ARG(pArray);

	index = stack.Arg1().NumericByRefConst().s4;
	if (index < 0 || (unsigned int)index >= pArray->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
	if ((unsigned int)index + 2 > pArray->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

	p = pArray->GetFirstElement();
	stack.SetResult(*reinterpret_cast<unsigned short*>(p + index), DATATYPE_U2);

	TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::MarshalSockAddress( struct SOCK_sockaddr* addrDst, CLR_UINT32& addrLen, const CLR_RT_HeapBlock& blkSockAddress )
{        
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* ptrSockAddress;

    ptrSockAddress = blkSockAddress.DereferenceArray();                    
    FAULT_ON_NULL(ptrSockAddress);

    if(ptrSockAddress->m_numOfElements > addrLen) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    memcpy( addrDst, ptrSockAddress->GetFirstElement(), ptrSockAddress->m_numOfElements );

    addrLen = ptrSockAddress->m_numOfElements;

    _ASSERTE(addrDst->sa_family == SOCK_AF_INET);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Decryptor::DecryptInit___VOID__MicrosoftSPOTCryptokiSession__MicrosoftSPOTCryptokiMechanism__SystemSecurityCryptographyCryptoKey( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pSession   = stack.Arg1().Dereference(); 
    CLR_RT_HeapBlock*       pMech      = stack.Arg2().Dereference(); 
    CLR_RT_HeapBlock*       pKeyHandle = stack.Arg3().Dereference();
    CLR_RT_HeapBlock_Array* pArrParam;
    CK_MECHANISM            mech;
    CK_OBJECT_HANDLE        hKey;
    CK_SESSION_HANDLE       hSession;

    FAULT_ON_NULL_ARG(pSession);
    FAULT_ON_NULL_ARG(pMech);
    FAULT_ON_NULL_ARG(pKeyHandle);

    hSession = (CK_SESSION_HANDLE)pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_handle].NumericByRef().s4;

    if(hSession == CK_SESSION_HANDLE_INVALID) TINYCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED);

    mech.mechanism = pMech[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Mechanism::FIELD__Type].NumericByRef().u4;

    pArrParam = pMech[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Mechanism::FIELD__Parameter].DereferenceArray();

    if(pArrParam != NULL && pArrParam->m_numOfElements > 0)
    {
        mech.pParameter     = pArrParam->GetFirstElement();
        mech.ulParameterLen = pArrParam->m_numOfElements;
    }
    else
    {
        mech.pParameter     = NULL;
        mech.ulParameterLen = 0;
    }

    hKey = (CK_OBJECT_HANDLE)pKeyHandle[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiObject::FIELD__m_handle].NumericByRef().s4;

    CRYPTOKI_CHECK_RESULT(stack, C_DecryptInit(hSession, &mech, hKey));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Text_UTF8Encoding::GetBytes___SZARRAY_U1__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    size_t                  cBytes;
    CLR_RT_HeapBlock_Array* arr;
    LPCSTR                  str;
    CLR_RT_HeapBlock&       ret = stack.PushValueAndClear();

    str    = stack.Arg1().RecoverString();
    FAULT_ON_NULL(str);
    cBytes = hal_strlen_s(str);

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( ret, (CLR_UINT32)cBytes, g_CLR_RT_WellKnownTypes.m_UInt8 ));

    arr = ret.DereferenceArray();

    memcpy( arr->GetFirstElement(), str, cBytes );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Messaging_EndPoint::ReplyRaw___VOID__MicrosoftSPOTMessagingMessage__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_MESSAGING();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*                            pThis;
    CLR_RT_HeapBlock*                            pMsg;
    CLR_RT_HeapBlock_Array*                      pData;
    CLR_RT_HeapBlock_EndPoint*                   ep;
    CLR_Messaging_Commands::Messaging_Reply*     rpc = NULL;
    CLR_UINT32                                   len;

    pThis = stack.This()                   ; FAULT_ON_NULL(pThis);
    pMsg  = stack.Arg1().Dereference()     ; FAULT_ON_NULL(pMsg );
    pData = stack.Arg2().DereferenceArray(); FAULT_ON_NULL(pData);

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_EndPoint::ExtractInstance( pThis[ FIELD__m_handle ], ep ));

    len = sizeof(CLR_RT_HeapBlock_EndPoint::Address) + pData->m_numOfElements;
    rpc = (CLR_Messaging_Commands::Messaging_Reply*)CLR_RT_Memory::Allocate( len ); CHECK_ALLOCATION(rpc);

    rpc->m_addr.m_seq         = pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_seq      ].NumericByRefConst  ().u4;
    rpc->m_addr.m_to          = ep->m_addr;
    rpc->m_addr.m_from.m_type = pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_selector ].ReflectionDataConst().GetTypeHash();
    rpc->m_addr.m_from.m_id   = pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_id       ].NumericByRefConst  ().u4;

    memcpy( rpc->m_data, pData->GetFirstElement(), pData->m_numOfElements );

    CLR_EE_MSG_EVENT_RPC(CLR_Messaging_Commands::c_Messaging_Reply,len,rpc,WP_Flags::c_NonCritical);

    TINYCLR_CLEANUP();

    if(rpc)
    {
        CLR_RT_Memory::Release( rpc );
    }

    TINYCLR_CLEANUP_END();
}
HRESULT Library_corlib_native_System_BitConverter::ToString___STATIC__STRING__SZARRAY_U1(CLR_RT_StackFrame& stack)
{
	NATIVE_PROFILE_CLR_CORE();
	TINYCLR_HEADER();

	CLR_RT_HeapBlock_Array* pArray = stack.Arg0().DereferenceArray();
	FAULT_ON_NULL_ARG(pArray);

	if (pArray->m_numOfElements == 0)
	{
		TINYCLR_CHECK_HRESULT(stack.SetResult_String(""));
	}
	else
	{
		BYTE* p = pArray->GetFirstElement();
		char* pOutput = ByteArrayToHex(p, 0, pArray->m_numOfElements);
		TINYCLR_CHECK_HRESULT(stack.SetResult_String(pOutput));
		delete[] pOutput;
	}

	TINYCLR_NOCLEANUP();
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Cryptoki::GetSlotsInternal___STATIC__SZARRAY_MicrosoftSPOTCryptokiSlot( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CK_ULONG                i;
    CK_SLOT_ID              slots[NETMF_CRYPTOKI_MAX_SLOTS];
    CK_ULONG                count = NETMF_CRYPTOKI_MAX_SLOTS;
    CLR_RT_HeapBlock_Array* pSlots;
    CLR_RT_HeapBlock        ref;
    CLR_RT_HeapBlock*       pSlotRef;

    CRYPTOKI_CHECK_RESULT(stack, C_GetSlotList(CK_FALSE, slots, &count));

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(ref, (CLR_UINT32)count, g_CLR_RT_WellKnownTypes.m_CryptokiSlot));

    pSlots = ref.DereferenceArray();

    pSlotRef = (CLR_RT_HeapBlock*)pSlots->GetFirstElement();
            
    for(i=0; i<count; i++)
    {
        CLR_RT_HeapBlock* pSlot;
        
        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( pSlotRef[i], g_CLR_RT_WellKnownTypes.m_CryptokiSlot ));

        pSlot = pSlotRef[i].Dereference();
      
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_slotIndex    ].SetInteger        ((CLR_INT32)slots[i]);
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_disposed     ].SetBoolean        (false              );
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_evtDispatcher].SetObjectReference(NULL               );
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_slotEvent    ].SetObjectReference(NULL               );
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_slotInfo     ].SetObjectReference(NULL               );
    }

    stack.SetResult_Object(pSlots);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::SockOptHelper( CLR_RT_StackFrame& stack, bool fGet )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock* socket = stack.Arg0().Dereference();
    CLR_INT32 handle;
    CLR_INT32 level   = stack.Arg1().NumericByRef().s4;
    CLR_INT32 optname = stack.Arg2().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* arrOpt = stack.Arg3().DereferenceArray(); 
    char* optval;
    CLR_INT32 optlen;
    CLR_INT32 ret;

    FAULT_ON_NULL(socket);
    handle = socket[ FIELD__m_Handle ].NumericByRef().s4;

    FAULT_ON_NULL(arrOpt);
    
    optval = (char*)arrOpt->GetFirstElement();
    optlen = arrOpt->m_numOfElements;

    if(fGet)
    {
        ret = SOCK_getsockopt( handle, level, optname, optval, &optlen );
        _ASSERTE( optlen <= (CLR_INT32)arrOpt->m_numOfElements ); 
    }
    else
    {
        ret = SOCK_setsockopt( handle, level, optname, optval, optlen );
    }

    TINYCLR_CHECK_HRESULT(ThrowOnError( stack, ret ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::Install___STATIC__BOOLEAN__I4__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32               handle      = stack.Arg0().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* pValidation = stack.Arg1().DereferenceArray();
    CLR_UINT8*              pValidData;
    CLR_INT32               validLen;

    if(pValidation == NULL)
    {
        pValidData = NULL;
        validLen = 0;
    }
    else
    {
        pValidData = pValidation->GetFirstElement();
        validLen = pValidation->m_numOfElements;
    }

    stack.SetResult_Boolean(TRUE == MFUpdate_Install(handle, pValidData, validLen));

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiDigest::Init___VOID__MicrosoftSPOTCryptokiMechanism( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis    = stack.This(); 
    CLR_RT_HeapBlock*       pMech    = stack.Arg1().Dereference(); 
    CLR_RT_HeapBlock*       pSession = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference();
    CLR_RT_HeapBlock_Array* pParam;
    CK_MECHANISM            mech;
    CK_SESSION_HANDLE       hSession;

    FAULT_ON_NULL(pSession);
    FAULT_ON_NULL_ARG(pMech);

    hSession = (CK_SESSION_HANDLE)pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_handle].NumericByRef().s4;
    pParam   = pMech[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Mechanism::FIELD__Parameter].DereferenceArray();

    if(hSession == CK_SESSION_HANDLE_INVALID) TINYCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED);

    mech.mechanism  = pMech[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Mechanism::FIELD__Type].NumericByRef().u4;

    if(pParam != NULL)
    {
        mech.pParameter     = pParam->GetFirstElement();
        mech.ulParameterLen = pParam->m_numOfElements;
    }
    else
    {
        mech.pParameter     = NULL;
        mech.ulParameterLen = 0;
    }

    CRYPTOKI_CHECK_RESULT(stack, C_DigestInit(hSession, &mech));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::MarshalSockAddress( CLR_RT_HeapBlock& blkDst, const struct SOCK_sockaddr* addrSrc, CLR_UINT32 addrLenSrc )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* arr = NULL;

    CLR_RT_HeapBlock blkArr; blkArr.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC gc( blkArr );
        
    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( blkArr, addrLenSrc, g_CLR_RT_WellKnownTypes.m_UInt8 ));
    
    arr = blkArr.DereferenceArray();

    _ASSERTE(arr);

    memcpy( arr->GetFirstElement(), addrSrc, addrLenSrc );

    _ASSERTE(blkDst.DataType() == DATATYPE_BYREF || blkDst.DataType() == DATATYPE_ARRAY_BYREF);

    TINYCLR_CHECK_HRESULT(blkArr.StoreToReference( blkDst, 0 ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_BitConverter::ToSingle___STATIC__R4__SZARRAY_U1__I4(CLR_RT_StackFrame& stack)
{
	NATIVE_PROFILE_CLR_CORE();
	TINYCLR_HEADER();

	BYTE *p = NULL;
	int index = 0;

	CLR_RT_HeapBlock_Array* pArray = stack.Arg0().DereferenceArray();
	FAULT_ON_NULL_ARG(pArray);

	index = stack.Arg1().NumericByRefConst().s4;
	if (index < 0 || (unsigned int)index >= pArray->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
	if ((unsigned int)index + 4 > pArray->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

	p = pArray->GetFirstElement();
#if !defined(TINYCLR_EMULATED_FLOATINGPOINT)
	stack.SetResult_R4(*reinterpret_cast<float*>(p + index));
#else
	stack.SetResult_R4(*reinterpret_cast<CLR_INT32*>(p + index));
#endif

	TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_CryptoState::LoadSymmetricKey( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis;
    CLR_RT_HeapBlock_Array* array;

    pThis = stack.This()                                                                                                           ; FAULT_ON_NULL(pThis);
    array = pThis[ Library_spot_native_Microsoft_SPOT_Cryptography_Key_TinyEncryptionAlgorithm::FIELD__m_value ].DereferenceArray(); FAULT_ON_NULL(array);

    memcpy( m_keySymmetric.Seed, array->GetFirstElement(), ARRAYSIZE(m_keySymmetric.Seed) );

    if(pThis[ Library_spot_native_Microsoft_SPOT_Cryptography_Key_TinyEncryptionAlgorithm::FIELD__m_doublyEncrypted ].NumericByRefConst().u1 != 0)
    {
        KeySeed deviceKey;
        UINT8   iv[ TEA_KEY_SIZE_BYTES ]; memset( iv, 0, sizeof(iv) );

        GetDeviceKey( (UINT8*)deviceKey.Seed );

        ::Crypto_Decrypt( deviceKey.Seed, iv, sizeof(iv), m_keySymmetric.Seed, sizeof(m_keySymmetric.Seed), m_keySymmetric.Seed, sizeof(m_keySymmetric.Seed) );
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Text_UTF8Encoding::Helper__GetChars(CLR_RT_StackFrame& stack, bool fIndexed)
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    LPSTR szText;
    CLR_RT_HeapBlock ref;
    ref.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC gc( ref );
    CLR_RT_HeapBlock_Array* pArrayBytes = stack.Arg1().DereferenceArray();
    CLR_INT32               byteIdx     = fIndexed ? stack.Arg2().NumericByRef().s4 : 0;
    CLR_INT32               byteCnt     = fIndexed ? stack.Arg3().NumericByRef().s4 : pArrayBytes->m_numOfElements;
    CLR_RT_HeapBlock_Array* pArrayBytesCopy;
    CLR_RT_HeapBlock_Array* arrTmp;
    int cBytesCopy;

    FAULT_ON_NULL(pArrayBytes);

    _ASSERTE(pArrayBytes->m_typeOfElement == DATATYPE_U1);

    if((byteIdx + byteCnt) > (CLR_INT32)pArrayBytes->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    cBytesCopy = byteCnt+1;

    /* Copy the array to a temporary buffer to create a zero-terminated string */
    TINYCLR_CHECK_HRESULT( CLR_RT_HeapBlock_Array::CreateInstance( ref, cBytesCopy, g_CLR_RT_WellKnownTypes.m_UInt8 ));

    pArrayBytesCopy = ref.DereferenceArray();
    szText = (LPSTR)pArrayBytesCopy->GetFirstElement();

    hal_strncpy_s( szText, cBytesCopy, (LPSTR)pArrayBytes->GetElement(byteIdx), byteCnt );

    TINYCLR_CHECK_HRESULT(Library_corlib_native_System_String::ConvertToCharArray( szText, stack.PushValueAndClear(), arrTmp, 0, -1 ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_security_native_Microsoft_SPOT_Net_Security_SslNative::ParseCertificate___STATIC__VOID__SZARRAY_U1__STRING__BYREF_STRING__BYREF_STRING__BYREF_mscorlibSystemDateTime__BYREF_mscorlibSystemDateTime( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* arrData    = stack.Arg0().DereferenceArray(); 
    CLR_UINT8*              certBytes;
    CLR_RT_HeapBlock        hbIssuer;
    CLR_RT_HeapBlock        hbSubject;
    CLR_RT_ProtectFromGC    gc1( hbIssuer  );
    CLR_RT_ProtectFromGC    gc2( hbSubject );
    X509CertData            cert;
    CLR_INT64*              val;
    CLR_INT64               tzOffset;
    SYSTEMTIME              st;
    INT32                   standardBias;
    CLR_RT_HeapBlock*       hbPwd     = stack.Arg1().DereferenceString();
    LPCSTR                  szPwd;


    FAULT_ON_NULL_ARG(hbPwd);

    szPwd = hbPwd->StringText();

    CLR_RT_Memory::ZeroFill( &cert, sizeof(cert) );

    FAULT_ON_NULL(arrData);

    certBytes = arrData->GetFirstElement();

    if(!SSL_ParseCertificate( (const char*)certBytes, arrData->m_numOfElements, szPwd, &cert )) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbIssuer, cert.Issuer ));
    TINYCLR_CHECK_HRESULT(hbIssuer.StoreToReference( stack.Arg2(), 0 ));

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbSubject, cert.Subject ));
    TINYCLR_CHECK_HRESULT(hbSubject.StoreToReference( stack.Arg3(), 0 ));

    st.wYear         = cert.EffectiveDate.year;
    st.wMonth        = cert.EffectiveDate.month;
    st.wDay          = cert.EffectiveDate.day;
    st.wHour         = cert.EffectiveDate.hour;
    st.wMinute       = cert.EffectiveDate.minute;
    st.wSecond       = cert.EffectiveDate.second;
    st.wMilliseconds = cert.EffectiveDate.msec;

    standardBias     = Time_GetTimeZoneOffset();
    standardBias    *= TIME_CONVERSION__ONEMINUTE;

    val = Library_corlib_native_System_DateTime::GetValuePtr( stack.Arg4() );
    *val = Time_FromSystemTime( &st );

    tzOffset = cert.EffectiveDate.tzOffset;

    // adjust for timezone differences
    if(standardBias != tzOffset)
    {
        *val += tzOffset - standardBias; 
    }

    st.wYear         = cert.ExpirationDate.year;
    st.wMonth        = cert.ExpirationDate.month;
    st.wDay          = cert.ExpirationDate.day;
    st.wHour         = cert.ExpirationDate.hour;
    st.wMinute       = cert.ExpirationDate.minute;
    st.wSecond       = cert.ExpirationDate.second;
    st.wMilliseconds = cert.ExpirationDate.msec;
    
    val = Library_corlib_native_System_DateTime::GetValuePtr( stack.ArgN( 5 ) );
    *val = Time_FromSystemTime( &st );

    tzOffset = cert.ExpirationDate.tzOffset;
    
    if(standardBias != tzOffset)
    {
       *val += tzOffset - standardBias; 
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Reflection::GetTypesImplementingInterface___STATIC__SZARRAY_mscorlibSystemType__mscorlibSystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock&       top    = stack.PushValueAndClear();
    int                     tot    = 0;
    CLR_RT_HeapBlock*       pArray = NULL;
    CLR_RT_TypeDef_Instance tdMatch;
    CLR_RT_HeapBlock*       hbType = stack.Arg0().Dereference();

    TINYCLR_CHECK_HRESULT(Library_corlib_native_System_RuntimeType::GetTypeDescriptor( *hbType, tdMatch ));

    if((tdMatch.m_target->flags & CLR_RECORD_TYPEDEF::TD_Semantics_Mask) != CLR_RECORD_TYPEDEF::TD_Semantics_Interface)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }

    for(int pass=0; pass<2; pass++)
    {
        int              count = 0;

        TINYCLR_FOREACH_ASSEMBLY_IN_CURRENT_APPDOMAIN(g_CLR_RT_TypeSystem)
        {
            const CLR_RECORD_TYPEDEF* td      = pASSM->GetTypeDef( 0 );
            int                       tblSize = pASSM->m_pTablesSize[ TBL_TypeDef ];

            for(int i=0; i<tblSize; i++, td++)
            {
                if(td->flags & CLR_RECORD_TYPEDEF::TD_Abstract) continue;

                CLR_RT_TypeDef_Index idx; idx.Set( pASSM->m_idx, i );

                if(CLR_RT_ExecutionEngine::IsInstanceOf( idx, tdMatch ))
                {
                    if(pass == 0)
                    {
                        tot++;
                    }
                    else
                    {
                        CLR_RT_HeapBlock* hbObj;
                        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(pArray[count], g_CLR_RT_WellKnownTypes.m_TypeStatic));
                        hbObj = pArray[count].Dereference();
                        hbObj->SetReflection( idx );
                    }

                    count++;
                }
            }
        }
        TINYCLR_FOREACH_ASSEMBLY_IN_CURRENT_APPDOMAIN_END();

        if(pass == 0)
        {
            if(tot == 0) break;

            TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, tot, g_CLR_RT_WellKnownTypes.m_TypeStatic ));

            CLR_RT_HeapBlock_Array* array = top.DereferenceArray();

            pArray = (CLR_RT_HeapBlock*)array->GetFirstElement();
        }
    }


    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_serial_native_System_IO_Ports_SerialPort::Read___I4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* readBuffer;
    CLR_RT_HeapBlock*       pThis;
    CLR_RT_HeapBlock*       config;
    CLR_UINT8*              ptr;
    CLR_INT32               offset;
    CLR_INT32               count;
    CLR_INT32               totLength;
    CLR_INT32               totRead;
    CLR_RT_HeapBlock*       timeout;
    CLR_INT64*              timeoutTicks;
    CLR_INT32               port;
    bool                    fRes;

    pThis = stack.This();  FAULT_ON_NULL(pThis);

    // check if the object was disposed
    if(pThis[ FIELD__m_fDisposed ].NumericByRef().s1 != 0) 
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED);
    }
    
    config = pThis[ FIELD__m_config ].Dereference(); FAULT_ON_NULL(config);

    readBuffer = stack.Arg1().DereferenceArray();  FAULT_ON_NULL(readBuffer);
    offset     = stack.Arg2().NumericByRef().s4;
    count      = stack.Arg3().NumericByRef().s4;
    totLength  = readBuffer->m_numOfElements;
    timeout    = &config[ Library_spot_hardware_serial_native_System_IO_Ports_SerialPort__Configuration::FIELD__ReadTimeout ];
    port       = config[ Library_spot_hardware_serial_native_System_IO_Ports_SerialPort__Configuration::FIELD__PortIndex ].NumericByRef().s4;

    //
    // Bound checking.
    //
    if(offset < 0 || offset > totLength)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
    }

    if(count == -1)
    {
        count = totLength - offset;
    }
    else
    {
        if(count < 0 || (offset+count) > totLength)
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
        }
    }

    TINYCLR_CHECK_HRESULT(stack.SetupTimeout( *timeout, timeoutTicks ));

    //
    // Push "totRead" onto the eval stack.
    //
    if(stack.m_customState == 1)
    {
        stack.PushValueI4( 0 );
        
        stack.m_customState = 2;
    }

    //--//

    totRead = stack.m_evalStack[ 1 ].NumericByRef().s4;

    ptr    = readBuffer->GetFirstElement();
    ptr   += offset + totRead;
    count -= totRead;

    fRes = true;

    while(fRes && count > 0)
    {
        int read = ::USART_Read( port, (char*)ptr, count );

        if(read == 0)
        {
            stack.m_evalStack[ 1 ].NumericByRef().s4 = totRead;

            TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeoutTicks, CLR_RT_ExecutionEngine::c_Event_SerialPort, fRes ));
        }
        else if(read < 0)
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
        }
        else
        {
            ptr     += read;
            totRead += read;
            count   -= read;
        }
    }

    stack.PopValue();       // totRead
    stack.PopValue();       // Timeout

    stack.SetResult_I4( totRead );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Threading_WaitHandle::WaitMultiple___STATIC__I4__SZARRAY_SystemThreadingWaitHandle__I4__BOOLEAN__BOOLEAN( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* arr = stack.Arg0().DereferenceArray();  FAULT_ON_NULL(arr);

    TINYCLR_CHECK_HRESULT(Wait( stack, stack.Arg1(), stack.Arg2(), (CLR_RT_HeapBlock*)arr->GetFirstElement(), arr->m_numOfElements, stack.Arg3().NumericByRef().s1 == 1 ));
    
    stack.SetResult_I4( stack.m_owningThread->m_waitForObject_Result );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Messaging_EndPoint::SendMessageRaw___SZARRAY_U1__mscorlibSystemType__U4__I4__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_MESSAGING();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*                           pThis;
    CLR_Messaging_Commands::Messaging_Send*     rpc;
    CLR_RT_HeapBlock_EndPoint::Message*         msg;
    CLR_RT_HeapBlock_EndPoint::Port             port;
    CLR_RT_HeapBlock_EndPoint*                  ep;
    CLR_INT64*                                  timeout;
    CLR_RT_HeapBlock_Array*                     pData;
    CLR_UINT32                                  len;
    bool                                        fRes;
    CLR_UINT32                                  seq;

    pThis = stack.This(); FAULT_ON_NULL(pThis);

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_EndPoint::ExtractInstance( pThis[ FIELD__m_handle ], ep ));

    if(CLR_RT_ReflectionDef_Index::Convert( stack.Arg1(), port.m_type ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE);
    port.m_id = stack.Arg2().NumericByRefConst().u4;

    TINYCLR_CHECK_HRESULT(stack.SetupTimeout( stack.Arg3(), timeout ));

    pData = stack.Arg4().DereferenceArray(); FAULT_ON_NULL(pData);

    //Send message
    rpc = NULL;
    if(stack.m_customState == 1)
    {
        len = sizeof(CLR_RT_HeapBlock_EndPoint::Address) + pData->m_numOfElements;
        rpc = (CLR_Messaging_Commands::Messaging_Send*)CLR_RT_Memory::Allocate( len ); CHECK_ALLOCATION(rpc);

        rpc->m_addr.m_to   = port;
        rpc->m_addr.m_from = ep->m_addr;
        rpc->m_addr.m_seq  = ep->m_seq++;
        memcpy( rpc->m_data, pData->GetFirstElement(), pData->m_numOfElements );

        //Push sequence number onto the eval stack to wait for reply
        stack.PushValueI4( rpc->m_addr.m_seq );
        
        CLR_EE_MSG_EVENT_RPC( CLR_Messaging_Commands::c_Messaging_Send, len, rpc, WP_Flags::c_NonCritical );
        
        stack.m_customState = 2;
    }

    //get seq# from stack
    seq = stack.m_evalStack[ 1 ].NumericByRef().u4;

    fRes = true;
    msg  = NULL;

    while(fRes)
    {
        msg = ep->FindMessage( CLR_Messaging_Commands::c_Messaging_Reply, &seq );

        if(msg) break;

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_EndPoint, fRes ));
    }

    stack.PopValue();       //seq
    stack.PopValue();       //Timeout

    {
        CLR_RT_HeapBlock& top = stack.PushValueAndClear();

        if(msg)
        {
            TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, msg->m_length, g_CLR_RT_WellKnownTypes.m_UInt8 ));

            memcpy( top.DereferenceArray()->GetFirstElement(), msg->m_data, msg->m_length );

            msg->Unlink(); CLR_RT_Memory::Release( msg );
        }
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_security_native_Microsoft_SPOT_Net_Security_SslNative::InitHelper( CLR_RT_StackFrame& stack, bool isServer )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_INT32 sslContext            = -1;
    CLR_INT32 sslMode               = stack.Arg0().NumericByRef().s4;
    CLR_INT32 sslVerify             = stack.Arg1().NumericByRef().s4;
    CLR_RT_HeapBlock *hbCert        = stack.Arg2().Dereference(); 
    CLR_RT_HeapBlock_Array* arrCA   = stack.Arg3().DereferenceArray(); 
    CLR_RT_HeapBlock_Array* arrCert = NULL;
    CLR_UINT8*  sslCert             = NULL;
    int         result;
    int         i;
    bool        isFirstCall = false;
    LPCSTR      szPwd = "";

    if(!g_SSL_SeedData.Initialized)
    {
        BOOL fOK = FALSE;

        isFirstCall = true;

#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE)
        int i;

        if(!HAL_CONFIG_BLOCK::ApplyConfig( g_SSL_SeedData.Config.GetDriverName(), &g_SSL_SeedData.Config, sizeof(g_SSL_SeedData.Config) ))
        {
            return CLR_E_NOT_SUPPORTED;
        }

        // validate the security key (make sure it isn't all 0x00 or all 0xFF
        for(i=1; i<sizeof(g_SSL_SeedData.Config.SslSeedKey) && !fOK; i++)
        {
            if( g_SSL_SeedData.Config.SslSeedKey[ i   ] != 0 && 
                g_SSL_SeedData.Config.SslSeedKey[ i   ] != 0xFF && 
                g_SSL_SeedData.Config.SslSeedKey[ i-1 ] != g_SSL_SeedData.Config.SslSeedKey[ i ])
            {
                fOK = TRUE;
            }
        }

        if(!fOK)
        {
            return CLR_E_NOT_SUPPORTED;
        }
#endif

        g_SSL_SeedData.m_completion.Initialize();
        
        g_SSL_SeedData.m_completion.InitializeForUserMode( UpdateSslSeedValue, NULL ); 

        g_SSL_SeedData.Initialized = TRUE;
    }


    if(hbCert != NULL)
    {
        arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_certificate ].DereferenceArray(); //FAULT_ON_NULL(arrCert);

        // If arrCert == NULL then the certificate is an X509Certificate2 which uses a certificate handle
        if(arrCert == NULL)
        {
            arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_handle ].DereferenceArray(); FAULT_ON_NULL(arrCert);    

            // pass the certificate handle as the cert data parameter
            sslCert = arrCert->GetFirstElement();

            arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_sessionHandle ].DereferenceArray(); FAULT_ON_NULL(arrCert);    

            // pass the session handle as the ssl context parameter
            sslContext = *(INT32*)arrCert->GetFirstElement();

            // the certificate has already been loaded so just pass an empty string
            szPwd = "";
        }
        else
        {
            arrCert->Pin();
        
            sslCert = arrCert->GetFirstElement();

            CLR_RT_HeapBlock *hbPwd = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_password ].Dereference();// FAULT_ON_NULL(hbPwd);

            szPwd = hbPwd->StringText();
        }
    }

    SSL_RegisterTimeCallback( Time_GetDateTime );

    if(isServer)
    {
        result = (SSL_ServerInit( sslMode, sslVerify, (const char*)sslCert, sslCert == NULL ? 0 : arrCert->m_numOfElements, szPwd, sslContext ) ? 0 : -1);
    }
    else
    {
        result = (SSL_ClientInit( sslMode, sslVerify, (const char*)sslCert, sslCert == NULL ? 0 : arrCert->m_numOfElements, szPwd, sslContext ) ? 0 : -1);
    }

    TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result ));

    if(isFirstCall)
    {
        GenerateNewSslSeed();
    }

    if(arrCA != NULL)
    {
        for(i=0; i<(int)arrCA->m_numOfElements; i++)
        {
            hbCert = (CLR_RT_HeapBlock*)arrCA->GetElement( i ); FAULT_ON_NULL(hbCert);
            hbCert = hbCert->Dereference();                     FAULT_ON_NULL(hbCert);

            arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_certificate ].DereferenceArray(); //FAULT_ON_NULL(arrCert);

            // If arrCert == NULL then the certificate is an X509Certificate2 which uses a certificate handle
            if(arrCert == NULL)
            {
                CLR_INT32 sessionCtx = 0;

                arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_handle ].DereferenceArray(); FAULT_ON_NULL(arrCert);    

                sslCert = arrCert->GetFirstElement();

                arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_sessionHandle ].DereferenceArray(); FAULT_ON_NULL(arrCert);    

                sessionCtx = *(INT32*)arrCert->GetFirstElement();

                // pass the session handle down as the password paramter and the certificate handle as the data parameter
                result = (SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, (LPCSTR)&sessionCtx ) ? 0 : -1);
                
                TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result ));
            }
            else
            {

                arrCert->Pin();

                sslCert = arrCert->GetFirstElement();

                CLR_RT_HeapBlock *hbPwd = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_password ].Dereference(); FAULT_ON_NULL(hbPwd);

                LPCSTR szCAPwd = hbPwd->StringText();
                
                result = (SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, szCAPwd ) ? 0 : -1);
                
                TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result ));
            }
        }
    }

    stack.SetResult_I4( sslContext );    

    TINYCLR_CLEANUP();

    if(FAILED(hr) && (sslContext != -1))
    {
        SSL_ExitContext( sslContext );        
    }

    TINYCLR_CLEANUP_END();
}