HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiDigest::DigestInternal___SZARRAY_U1__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis      = stack.This();
    CLR_RT_HeapBlock_Array* pData      = stack.Arg1().DereferenceArray(); 
    CLR_INT32               offset     = stack.Arg2().NumericByRef().s4;
    CLR_INT32               len        = stack.Arg3().NumericByRef().s4;
    CLR_RT_HeapBlock*       pSession   = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference();
    CLR_INT32               digestSize = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiDigest::FIELD__m_hashSize].NumericByRef().s4;
    CK_SESSION_HANDLE       hSession;
    //CLR_INT32                     maxProcessingBytes;

    FAULT_ON_NULL_ARG(pData);
    FAULT_ON_NULL(pSession);

    if((offset + len) > (CLR_INT32)pData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    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);

    // TODO: add code for processing chunks at a time if size is too big
    //maxProcessingBytes = pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_maxProcessingBytes].NumericByRef().s4;

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(stack.PushValue(), digestSize, g_CLR_RT_WellKnownTypes.m_UInt8));

    CRYPTOKI_CHECK_RESULT(stack, C_Digest(hSession, pData->GetElement(offset), len, stack.TopValue().DereferenceArray()->GetFirstElement(), (CK_ULONG_PTR)&digestSize));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiVerify::VerifyInternal___BOOLEAN__SZARRAY_U1__I4__I4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis    = stack.This();
    CLR_RT_HeapBlock_Array* pData    = stack.Arg1().DereferenceArray(); 
    CLR_INT32               offset   = stack.Arg2().NumericByRef().s4;
    CLR_INT32               len      = stack.Arg3().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* pSig     = stack.Arg4().DereferenceArray(); 
    CLR_INT32               sigOff   = stack.Arg5().NumericByRef().s4;
    CLR_INT32               sigLen   = stack.Arg6().NumericByRef().s4;
    CLR_RT_HeapBlock*       pSession = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference();
    CK_SESSION_HANDLE       hSession;
    bool                    retVal   = false;
    CK_RV                   result;

    FAULT_ON_NULL_ARG(pData);
    FAULT_ON_NULL_ARG(pSig);

    if((offset + len   ) > (CLR_INT32)pData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
    if((sigOff + sigLen) > (CLR_INT32)pSig->m_numOfElements ) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    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);

    result = C_Verify(hSession, pData->GetElement(offset), len, pSig->GetElement(sigOff), sigLen);

    retVal = CKR_OK == result;

    stack.SetResult_Boolean(retVal);

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

    CLR_INT32 sslContext     = stack.Arg0().NumericByRef().s4;
    CLR_RT_HeapBlock* hb     = stack.Arg1().DereferenceString();
    CLR_RT_HeapBlock* socket = stack.Arg2().Dereference();
    CLR_INT32         timeout_ms = -1; // wait forever
    CLR_RT_HeapBlock  hbTimeout;
    
    int        result;    
    LPCSTR     szName;
    CLR_INT32  handle;
    bool       fRes = true;
    CLR_INT64 *timeout;

    FAULT_ON_NULL(socket);

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

    /* Because we could have been a rescheduled call due to a prior call that would have blocked, we need to see
     * if our handle has been shutdown before continuing. */
    if (handle == Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::DISPOSED_HANDLE)
    {
        ThrowError( stack, CLR_E_OBJECT_DISPOSED );
        TINYCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION);
    }

    FAULT_ON_NULL_ARG(hb);

    szName = hb->StringText();

    hbTimeout.SetInteger( timeout_ms );
        
    TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout ));

    while(true)
    {
        result = SSL_Connect( handle, szName, sslContext );

        if(result == SOCK_EWOULDBLOCK || result == SOCK_TRY_AGAIN)
        {
            // non-blocking - allow other threads to run while we wait for socket activity
            TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_Socket, fRes ));

            if(result < 0) break;
        }
        else
        {
            break;
        }
    }

    stack.PopValue();       // Timeout

    TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_BitConverter::ToString___STATIC__STRING__SZARRAY_U1__I4__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;
	int length;
	length = stack.Arg2().NumericByRefConst().s4;
	if (pArray->m_numOfElements == 0 && index == 0 && length == 0)
	{
		TINYCLR_CHECK_HRESULT(stack.SetResult_String(""));
	}
	else
	{
		if (index < 0 || length < 0 || (unsigned int)index >= pArray->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
		if ((unsigned int)index + length > pArray->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

		BYTE* p;
		p  = pArray->GetFirstElement();
		char* pOutput = ByteArrayToHex(p, index, length);
		TINYCLR_CHECK_HRESULT(stack.SetResult_String(pOutput));
		delete[] pOutput;
	}

	TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Hardware_SystemInfo::GetSystemVersion___STATIC__VOID__BYREF_I4__BYREF_I4__BYREF_I4__BYREF_I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();
    {
        CLR_RT_HeapBlock hbMajor;
        CLR_RT_HeapBlock hbMinor;
        CLR_RT_HeapBlock hbBuild;
        CLR_RT_HeapBlock hbRevision;

        MfReleaseInfo releaseInfo;

        Solution_GetReleaseInfo( releaseInfo );

        hbMajor.SetInteger( releaseInfo.version.usMajor );
        TINYCLR_CHECK_HRESULT(hbMajor.StoreToReference( stack.Arg0(), 0 ));

        hbMinor.SetInteger( releaseInfo.version.usMinor );
        TINYCLR_CHECK_HRESULT(hbMinor.StoreToReference( stack.Arg1(), 0 ));

        hbBuild.SetInteger( releaseInfo.version.usBuild );
        TINYCLR_CHECK_HRESULT(hbBuild.StoreToReference( stack.Arg2(), 0 ));

        hbRevision.SetInteger( releaseInfo.version.usRevision );
        TINYCLR_CHECK_HRESULT(hbRevision.StoreToReference( stack.Arg3(), 0 ));
    }
    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::AddPacket___STATIC__BOOLEAN__I4__I4__SZARRAY_U1__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

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

    FAULT_ON_NULL(pPacket);

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

    stack.SetResult_Boolean(TRUE == MFUpdate_AddPacket(handle, pktIndex, pPacket->GetFirstElement(), pPacket->m_numOfElements, pValidData, validLen));

    TINYCLR_NOCLEANUP();
}
// TODO: Make common functions for transformBlock for encrypt/decrypt when async logic is in place
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Decryptor::TransformBlockInternal___I4__SZARRAY_U1__I4__I4__SZARRAY_U1__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis      = stack.This();
    CLR_RT_HeapBlock_Array* pData      = stack.Arg1().DereferenceArray(); 
    CLR_INT32               dataOffset = stack.Arg2().NumericByRef().s4;
    CLR_INT32               dataLen    = stack.Arg3().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* pOutput    = stack.Arg4().DereferenceArray(); 
    CLR_INT32               outOffset  = stack.Arg5().NumericByRef().s4;
    CLR_RT_HeapBlock*       pSession   = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference();
    CK_SESSION_HANDLE       hSession;
    CLR_UINT32              decrSize;   

    FAULT_ON_NULL_ARG(pData);
    FAULT_ON_NULL_ARG(pOutput);
    FAULT_ON_NULL_ARG(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);

    if((dataOffset + dataLen) > (CLR_INT32)pData->m_numOfElements  ) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
    if((outOffset           ) > (CLR_INT32)pOutput->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    decrSize = pOutput->m_numOfElements - outOffset;

    CRYPTOKI_CHECK_RESULT(stack, C_DecryptUpdate(hSession, pData->GetElement(dataOffset), dataLen, pOutput->GetElement(outOffset), (CK_ULONG_PTR)&decrSize));

    stack.SetResult_I4(decrSize);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_SPI::InternalWriteRead___VOID__SZARRAY_U2__I4__I4__SZARRAY_U2__I4__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();
    {
        CLR_RT_HeapBlock*       pThis           = stack.This();                    FAULT_ON_NULL(pThis);
        CLR_RT_HeapBlock_Array* writeBuffer     = stack.Arg1().DereferenceArray(); FAULT_ON_NULL(writeBuffer);
        CLR_INT32               writeOffset     = stack.Arg2().NumericByRef().s4;
        CLR_INT32               writeCount      = stack.Arg3().NumericByRef().s4;
        CLR_RT_HeapBlock_Array* readBuffer      = stack.Arg4().DereferenceArray(); 
        CLR_INT32               readOffset      = stack.Arg5().NumericByRef().s4;
        CLR_INT32               readCount       = stack.Arg6().NumericByRef().s4;
        CLR_UINT32              startReadOffset = stack.Arg7().NumericByRef().s4;
        
        SPI_CONFIGURATION       config;
        TINYCLR_CHECK_HRESULT(Library_spot_hardware_native_Microsoft_SPOT_Hardware_SPI__Configuration::GetInitialConfig( pThis[ FIELD__m_config ], config ));

        config.MD_16bits = TRUE;

        CPU_SPI_Initialize();
        
        if(!::CPU_SPI_nWrite16_nRead16(
                                    config,
                                    (CLR_UINT16*)writeBuffer->GetElement(writeOffset), 
                                    writeCount,
                                    readBuffer == NULL ? NULL : (CLR_UINT16*)readBuffer ->GetElement(readOffset), 
                                    readBuffer == NULL ? 0    : readCount,
                                    startReadOffset
                                  ))
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION);
        }
    }
    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_Assembly::GetVersion___VOID__BYREF_I4__BYREF_I4__BYREF_I4__BYREF_I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_StackFrame* caller = stack.Caller(); 
    if(caller == NULL) 
    {
        TINYCLR_SET_AND_LEAVE(S_OK);
    }
    else
    {
        CLR_RT_Assembly_Instance assm;
        
        TINYCLR_CHECK_HRESULT(GetTypeDescriptor( stack.Arg0(), assm ));

        const CLR_RECORD_VERSION& version = assm.m_assm->m_header->version;

        // we do not check for the reference not to be NULL because this is an internal method
        stack.Arg1().Dereference()->NumericByRef().s4 = version.iMajorVersion;
        stack.Arg2().Dereference()->NumericByRef().s4 = version.iMinorVersion;
        stack.Arg3().Dereference()->NumericByRef().s4 = version.iBuildNumber;
        stack.Arg4().Dereference()->NumericByRef().s4 = version.iRevisionNumber;
    }
    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Text_UTF8Encoding::GetBytes___I4__STRING__I4__I4__SZARRAY_U1__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    size_t                  cMaxBytes;
    LPCSTR                  str         = stack.Arg1().RecoverString();
    CLR_INT32               strIdx      = stack.Arg2().NumericByRef().s4;
    CLR_INT32               strCnt      = stack.Arg3().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* pArrayBytes = stack.Arg4().DereferenceArray();
    CLR_INT32               byteIdx     = stack.Arg5().NumericByRef().s4;

    FAULT_ON_NULL(str);
    FAULT_ON_NULL(pArrayBytes);

    cMaxBytes = hal_strlen_s(str);

    if((strIdx  + strCnt) > (CLR_INT32)cMaxBytes                   ) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
    if((byteIdx + strCnt) > (CLR_INT32)pArrayBytes->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    memcpy(pArrayBytes->GetElement(byteIdx), &str[strIdx], strCnt);

    stack.SetResult_I4(strCnt);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiSign::SignUpdateInternal___VOID__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis      = stack.This();
    CLR_RT_HeapBlock_Array* pData      = stack.Arg1().DereferenceArray();
    CLR_INT32               offset     = stack.Arg2().NumericByRef().s4;
    CLR_INT32               len        = stack.Arg3().NumericByRef().s4;
    CLR_RT_HeapBlock*       pSession   = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference();
    CLR_INT32               sigLen     = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiSign::FIELD__m_signatureLength].NumericByRef().s4;
    CK_SESSION_HANDLE       hSession;

    FAULT_ON_NULL_ARG(pData);
    FAULT_ON_NULL(pSession);

    if((offset + len) > (CLR_INT32)pData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

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

    // TODO: add code for processing chunks at a time if size is too big
    //maxProcessingBytes = pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_maxProcessingBytes].NumericByRef().s4;

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

    CRYPTOKI_CHECK_RESULT(stack, C_SignUpdate(hSession, pData->GetElement(offset), len));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbStream::nativeWrite___I4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32               retVal = 0;
    CLR_INT32               controllerIndex, streamIndex, stream;
    CLR_UINT32              offset, count;
    CLR_RT_HeapBlock*       pThis;
    CLR_RT_HeapBlock_Array* array;

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

    controllerIndex = pThis[ Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbStream::FIELD__m_controllerIndex ].NumericByRef().s4;
    streamIndex     = pThis[ Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbStream::FIELD__m_streamIndex     ].NumericByRef().s4;
    array           = stack.Arg1().DereferenceArray(); FAULT_ON_NULL( array );
    offset          = stack.Arg2().NumericByRef().u4;
    count           = stack.Arg3().NumericByRef().u4;

    stream = (controllerIndex << USB_CONTROLLER_SHIFT) + streamIndex;
    if( array->m_numOfElements < (offset + count) )
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }
    else
    {
        retVal = USB_Write( stream, (char*)array->GetFirstElement()+offset, count );
    }
    stack.SetResult_I4( retVal );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbStream::nativeOpen___I4__I4__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32         streamIndex, controllerIndex, writeEndpoint, readEndpoint;
    CLR_RT_HeapBlock* pThis;

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

    controllerIndex = pThis[ Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbStream::FIELD__m_controllerIndex ].NumericByRef().s4;
    writeEndpoint   = stack.Arg1().NumericByRef().s4;
    readEndpoint    = stack.Arg2().NumericByRef().s4;

    for( streamIndex = 0; streamIndex < USB_MAX_QUEUES; streamIndex++ )
    {
        CLR_INT32 stream = (controllerIndex << USB_CONTROLLER_SHIFT) + streamIndex;
        if( USB_OpenStream( stream, writeEndpoint, readEndpoint ) )  break;
    }
    if( streamIndex >= USB_MAX_QUEUES )
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }
    stack.SetResult_I4( streamIndex );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_NativeEventDispatcher::_ctor___VOID__STRING__U8( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER(); 

    CLR_RT_DriverInterruptMethods*          pDriverMethods;
    const CLR_RT_NativeAssemblyData*        pNativeDriverData;
    CLR_RT_HeapBlock_NativeEventDispatcher* pNativeDisp = NULL;
    
    LPCSTR                                  lpszDriverName;    
    UINT64                                  driverData;
    
    CLR_RT_HeapBlock*  pThis = stack.This();  FAULT_ON_NULL(pThis);
    
    // Retrieve paramenters; 
    if (stack.Arg1().DataType() != DATATYPE_OBJECT) 
    {   TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);                      
    }
    lpszDriverName = stack.Arg1().RecoverString();  FAULT_ON_NULL(lpszDriverName);

    driverData = stack.Arg2().NumericByRef().u8;

    // Throw NULL exception if string is empty. 
    if(hal_strlen_s( lpszDriverName ) == 0)
    {  
        TINYCLR_CHECK_HRESULT(CLR_E_ARGUMENT_NULL);
    }
    
    // Retrives pointers to driver implemented functions.
    pNativeDriverData = GetAssemblyNativeData( lpszDriverName );
    
    // Validates check sum and presence of the structure.
    if(pNativeDriverData == NULL || pNativeDriverData->m_checkSum != DRIVER_INTERRUPT_METHODS_CHECKSUM)
    {
       TINYCLR_CHECK_HRESULT(CLR_E_DRIVER_NOT_REGISTERED);
    }

    // Get pointer to CLR_RT_DriverInterruptMethods
    pDriverMethods = (CLR_RT_DriverInterruptMethods *)pNativeDriverData->m_pNativeMethods;
    // Check that all methods are present:
    if(pDriverMethods->m_InitProc == NULL || pDriverMethods->m_EnableProc == NULL || pDriverMethods->m_CleanupProc == NULL)
    {
       TINYCLR_CHECK_HRESULT(CLR_E_DRIVER_NOT_REGISTERED);
    }

    // So we found driver by name and now we create instance of CLR_RT_HeapBlock_NativeEventDispatcher
    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_NativeEventDispatcher::CreateInstance( *pThis, pThis[ FIELD__m_NativeEventDispatcher ] ));

    // Initialize the driver with and provide the instance of CLR_RT_HeapBlock_NativeEventDispatcher 
    TINYCLR_CHECK_HRESULT(GetEventDispatcher( stack, pNativeDisp ));

    // Now call the driver. First save pointer to driver data.
    pNativeDisp->m_DriverMethods = pDriverMethods;
    TINYCLR_CHECK_HRESULT(pDriverMethods->m_InitProc( pNativeDisp, driverData ));
    
    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Threading_WaitHandle::WaitOne___BOOLEAN__I4__BOOLEAN( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    TINYCLR_CHECK_HRESULT(Wait( stack, stack.Arg1(), stack.Arg2(), &stack.ThisRef(), 1, false ));

    stack.SetResult_Boolean( stack.m_owningThread->m_waitForObject_Result != CLR_RT_Thread::TH_WAIT_RESULT_TIMEOUT );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::poll___STATIC__BOOLEAN__OBJECT__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock* socket = stack.Arg0().Dereference();
    CLR_INT32 handle;
    CLR_INT32 mode       = stack.Arg1().NumericByRef().s4;    
    CLR_INT32 timeout_us = stack.Arg2().NumericByRef().s4;
    
    CLR_RT_HeapBlock hbTimeout;
    CLR_INT32 timeout_ms;

    CLR_INT32 res = 0;
    bool fRes     = true;

    CLR_INT64* timeout;

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

    /* Because we could have been a rescheduled call due to a prior call that would have blocked, we need to see
     * if our handle has been shutdown before continuing. */
    if (handle == DISPOSED_HANDLE)
    {
        ThrowError( stack, CLR_E_OBJECT_DISPOSED );
        TINYCLR_SET_AND_LEAVE (CLR_E_PROCESS_EXCEPTION);
    }


    if(timeout_us < 0) timeout_ms = -1;
    else               timeout_ms = timeout_us / 1000;

    hbTimeout.SetInteger( timeout_ms );

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

    while(fRes)
    {
        res = Helper__SelectSocket( handle, mode );

        if(res != 0) break;

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

    stack.PopValue(); //timer

    TINYCLR_CHECK_HRESULT(ThrowOnError( stack, res ));

    stack.SetResult_Boolean( res == 1 );   

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_Port::_ctor___VOID__MicrosoftSPOTHardwareCpuPin__BOOLEAN( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();
    {
        CLR_RT_HeapBlock* pThis = stack.This();  FAULT_ON_NULL(pThis);
        CLR_UINT32 portId       = stack.Arg1().NumericByRef().u4;
        bool       initialState = stack.Arg2().NumericByRef().u1 != 0;
    
        TINYCLR_CHECK_HRESULT(Microsoft_SPOT_Hardware_Port_Construct( pThis, portId, false, RESISTOR_DISABLED, GPIO_INT_NONE, initialState, true )); 
    }
    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_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Decryptor::TransformFinalBlockInternal___SZARRAY_U1__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis     = stack.This();
    CLR_RT_HeapBlock_Array* pData     = stack.Arg1().DereferenceArray(); 
    CLR_INT32               offset    = stack.Arg2().NumericByRef().s4;
    CLR_INT32               len       = stack.Arg3().NumericByRef().s4;
    CLR_RT_HeapBlock*       pSession  = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference();
    CLR_UINT32              decrSize  = 0;
    CK_SESSION_HANDLE       hSession;
    CLR_RT_HeapBlock        hbRef;
    CLR_RT_HeapBlock*       pRet;
    CLR_UINT32              maxOut;

    FAULT_ON_NULL_ARG(pData);
    FAULT_ON_NULL_ARG(pSession);

    if((offset + len) > (CLR_INT32)pData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    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);

    CRYPTOKI_CHECK_RESULT(stack, C_Decrypt(hSession, pData->GetElement(offset), len, NULL, (CK_ULONG_PTR)&decrSize));

    maxOut = decrSize;

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

    CRYPTOKI_CHECK_RESULT(stack, C_Decrypt(hSession, pData->GetElement(offset), len, hbRef.DereferenceArray()->GetFirstElement(), (CK_ULONG_PTR)&decrSize));

    if(decrSize < maxOut)
    {
        CLR_RT_HeapBlock refSmall;
        
        TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(refSmall, decrSize, g_CLR_RT_WellKnownTypes.m_UInt8));

        memcpy(refSmall.DereferenceArray()->GetFirstElement(), hbRef.DereferenceArray()->GetFirstElement(), decrSize);

        pRet = refSmall.Dereference();
    }
    else
    {
        pRet = hbRef.Dereference();
    }

    stack.SetResult_Object(pRet);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_Port::_ctor___VOID__MicrosoftSPOTHardwareCpuPin__BOOLEAN__BOOLEAN__MicrosoftSPOTHardwarePortResistorMode( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();
    {
        CLR_RT_HeapBlock* pThis = stack.This();  FAULT_ON_NULL(pThis);
        CLR_UINT32    portId       =                stack.Arg1().NumericByRef().u4;
        bool          initialState =                stack.Arg2().NumericByRef().u1 != 0;
        bool          glitchFilter =                stack.Arg3().NumericByRef().u1 != 0;
        GPIO_RESISTOR resistorMode = (GPIO_RESISTOR)stack.Arg4().NumericByRef().u4;

        TINYCLR_CHECK_HRESULT(Microsoft_SPOT_Hardware_Port_Construct( pThis, portId, glitchFilter, resistorMode, GPIO_INT_NONE, initialState, false ));
    }
    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_HardwareProvider::NativeIsSupportedBaudRate___BOOLEAN__I4__BYREF_U4( CLR_RT_StackFrame& stack )
{
	TINYCLR_HEADER();
    CLR_RT_HeapBlock  hbBR;
    CLR_UINT32        port;
   
    CLR_UINT32        SupportedBaudrate;

    port              = stack.Arg1().NumericByRef().u4;

    TINYCLR_CHECK_HRESULT(hbBR.LoadFromReference( stack.Arg2() ));
    SupportedBaudrate = hbBR.NumericByRef().u4;

    if (CPU_USART_IsBaudrateSupported(port,SupportedBaudrate) == TRUE)
        stack.SetResult_Boolean( true );
    else
        stack.SetResult_Boolean( false );

    hbBR.SetInteger( (CLR_UINT32)SupportedBaudrate );
    TINYCLR_CHECK_HRESULT(hbBR.StoreToReference( stack.Arg2(), 0 ));        

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_Port::_ctor___VOID__MicrosoftSPOTHardwareCpuPin__BOOLEAN__MicrosoftSPOTHardwarePortResistorMode__MicrosoftSPOTHardwarePortInterruptMode( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();
    {
        CLR_RT_HeapBlock*  pThis = stack.This();  FAULT_ON_NULL(pThis);
        CLR_UINT32     portId             =                stack.Arg1().NumericByRef().u4;
        bool           glitchFilterEnable =                stack.Arg2().NumericByRef().u1 != 0;
        GPIO_RESISTOR  resistorMode       = (GPIO_RESISTOR)stack.Arg3().NumericByRef().u4;
        GPIO_INT_EDGE  interruptMode      = (GPIO_INT_EDGE)stack.Arg4().NumericByRef().u4;

        TINYCLR_CHECK_HRESULT(Microsoft_SPOT_Hardware_Port_Construct( pThis, portId, glitchFilterEnable, resistorMode, interruptMode, false, false ));
    }
    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::ioctl___STATIC__VOID__OBJECT__U4__BYREF_U4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock* socket = stack.Arg0().Dereference();
    CLR_INT32 handle;
    CLR_INT32 cmd     = stack.Arg1().NumericByRef().s4;
    CLR_RT_HeapBlock blkArg;
    CLR_INT32 ret;

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

    _SIDE_ASSERTE(SUCCEEDED(blkArg.LoadFromReference( stack.Arg2() )));

    ret = SOCK_ioctl( handle, cmd, (CLR_INT32*)&blkArg.NumericByRef().s4 );
    
    TINYCLR_CHECK_HRESULT(ThrowOnError( stack, ret ));

    _SIDE_ASSERTE(SUCCEEDED(blkArg.StoreToReference( stack.Arg2(), 0 )));

    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_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiRNG::GenerateRandom___VOID__SZARRAY_U1__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*       pThis    = stack.This();
    CLR_RT_HeapBlock*       pSession;
    CLR_RT_HeapBlock_Array* pData    = stack.Arg1().DereferenceArray();
    CLR_INT32               offset   = stack.Arg2().NumericByRef().s4;
    CLR_INT32               len      = stack.Arg3().NumericByRef().s4;
    bool                    fNonZero = stack.Arg4().NumericByRef().s4 == 1;
    CK_SESSION_HANDLE       hSession;
    CLR_UINT8*              pDataElem;

    FAULT_ON_NULL_ARG(pData);

    if(len+offset > (CLR_INT32)pData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    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;

    pDataElem = pData->GetElement(offset);
    
    CRYPTOKI_CHECK_RESULT(stack, C_GenerateRandom(hSession, pDataElem, len));

    if(fNonZero)
    {
        int i,idx = -1;
        CLR_UINT8 replacements[20];

        for(i=0; i<len; i++)
        {
            if(*pDataElem == 0)
            {
                if(idx == -1 || idx >= ARRAYSIZE(replacements))
                {
                    CRYPTOKI_CHECK_RESULT(stack, C_GenerateRandom(hSession, replacements, ARRAYSIZE(replacements)));
                    idx = 0;
                }

                *pDataElem = replacements[idx++];
            }
        }
    }

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

    CLR_INT32               handle = stack.Arg0().NumericByRef().s4;
    CLR_INT32               cmd    = stack.Arg1().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* paArgs = stack.Arg2().DereferenceArray();
    CLR_RT_HeapBlock_Array* paResp = stack.Arg3().Dereference()->DereferenceArray();    
    CLR_UINT8*              pResp   = paResp == NULL ? NULL : paResp->GetFirstElement();
    CLR_INT32               respLen = paResp == NULL ? 0    : paResp->m_numOfElements;

    FAULT_ON_NULL_ARG(paArgs);

    stack.SetResult_Boolean(TRUE == MFUpdate_AuthCommand(handle, cmd, paArgs->GetFirstElement(), paArgs->m_numOfElements, pResp, respLen));

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

    CLR_INT32               sslContext = stack.Arg0().NumericByRef().s4;
    CLR_RT_HeapBlock*       hbCert     = stack.Arg1().Dereference(); 
    CLR_RT_HeapBlock_Array* arrCA      = stack.Arg2().DereferenceArray(); 
    CLR_RT_HeapBlock_Array* arrCert;
    CLR_UINT8* sslCert;
    int        i;
    CLR_RT_HeapBlock*       hbPwd;
    LPCSTR  szPwd;

    FAULT_ON_NULL(hbCert);
    FAULT_ON_NULL(arrCA);

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

    sslCert    = arrCert->GetFirstElement();

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

    szPwd      = hbPwd->StringText();
    
    SSL_ClearCertificateAuthority( sslContext );

    if(!SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, szPwd )) TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);

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

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

        sslCert = arrCert->GetFirstElement();

        hbPwd      = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_password ].Dereference();
        
        szPwd      = hbPwd->StringText();
        
        if(!SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, szPwd )) TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Hardware_Utility::InsertOrExtractValueFromArray( CLR_RT_StackFrame& stack, bool fInsert )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* array;
    CLR_INT32               offset;
    CLR_INT32               size;
    CLR_UINT32              res;

    array  = stack.Arg0().DereferenceArray(); FAULT_ON_NULL(array);
    offset = stack.Arg1().NumericByRefConst().s4;
    size   = stack.Arg2().NumericByRefConst().s4;
    res    = 0;

    switch(size)
    {
    case 1:
    case 2:
    case 4:
        if(offset >= 0 && (CLR_UINT32)(offset + size) <= array->m_numOfElements)
        {
            CLR_UINT8* ptr = array->GetElement( offset );

            if(fInsert)
            {
                res = stack.Arg3().NumericByRef().u4;

                memcpy( ptr, &res, size );
            }
            else
            {
                memcpy( &res, ptr, size );

                stack.SetResult( res, DATATYPE_U4 );
            }

            TINYCLR_SET_AND_LEAVE(S_OK);
        }
        break;
    }

    TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    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_native_Microsoft_SPOT_Messaging_EndPoint::_ctor___VOID__mscorlibSystemType__U4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_MESSAGING();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*               pThis = stack.This(); FAULT_ON_NULL(pThis);
    CLR_RT_HeapBlock_EndPoint::Port port;
    CLR_RT_HeapBlock_EndPoint*      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;

    ep = CLR_RT_HeapBlock_EndPoint::FindEndPoint( port ); if(ep) TINYCLR_SET_AND_LEAVE(CLR_E_BUSY);

    TINYCLR_SET_AND_LEAVE(CLR_RT_HeapBlock_EndPoint::CreateInstance( port, *pThis, pThis[ FIELD__m_handle ] ));

    TINYCLR_NOCLEANUP();
}