| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "JITClientPch.h"
- _Must_inspect_result_
- _Ret_maybenull_ _Post_writable_byte_size_(size)
- void * __RPC_USER midl_user_allocate(
- #if defined(_WIN32_WINNT_WIN10)
- _In_ // starting win10, _In_ is in the signature
- #endif
- size_t size)
- {
- return (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size));
- }
- void __RPC_USER midl_user_free(_Pre_maybenull_ _Post_invalid_ void * ptr)
- {
- if (ptr != NULL)
- {
- HeapFree(GetProcessHeap(), NULL, ptr);
- }
- }
- JITManager JITManager::s_jitManager = JITManager();
- JITManager::JITManager() :
- m_rpcBindingHandle(nullptr),
- m_oopJitEnabled(false),
- m_isJITServer(false),
- m_failingHRESULT(S_OK),
- m_jitConnectionId()
- {
- }
- JITManager::~JITManager()
- {
- if (m_rpcBindingHandle)
- {
- RpcBindingFree(&m_rpcBindingHandle);
- }
- }
- /* static */
- JITManager *
- JITManager::GetJITManager()
- {
- return &s_jitManager;
- }
- typedef struct _CHAKRA_RPC_SECURITY_QOS_V5 {
- unsigned long Version;
- unsigned long Capabilities;
- unsigned long IdentityTracking;
- unsigned long ImpersonationType;
- unsigned long AdditionalSecurityInfoType;
- union
- {
- RPC_HTTP_TRANSPORT_CREDENTIALS_W* HttpCredentials;
- } u;
- void* Sid;
- unsigned int EffectiveOnly;
- void* ServerSecurityDescriptor;
- } CHAKRA_RPC_SECURITY_QOS_V5;
- // This routine creates a binding with the server.
- HRESULT
- JITManager::CreateBinding(
- __in HANDLE serverProcessHandle,
- __in_opt void * serverSecurityDescriptor,
- __in UUID * connectionUuid,
- __out RPC_BINDING_HANDLE * bindingHandle)
- {
- Assert(IsOOPJITEnabled());
- RPC_STATUS status;
- DWORD attemptCount = 0;
- DWORD sleepInterval = 100; // in milliseconds
- RPC_BINDING_HANDLE localBindingHandle;
- RPC_BINDING_HANDLE_TEMPLATE_V1 bindingTemplate;
- RPC_BINDING_HANDLE_SECURITY_V1_W bindingSecurity;
- CHAKRA_RPC_SECURITY_QOS_V5 securityQOS;
- ZeroMemory(&securityQOS, sizeof(CHAKRA_RPC_SECURITY_QOS_V5));
- securityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
- securityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
- securityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
- securityQOS.Version = AutoSystemInfo::Data.IsWin8OrLater() ? 5 : 4;
- securityQOS.ServerSecurityDescriptor = serverSecurityDescriptor;
- ZeroMemory(&bindingTemplate, sizeof(bindingTemplate));
- bindingTemplate.Version = 1;
- bindingTemplate.ProtocolSequence = RPC_PROTSEQ_LRPC;
- bindingTemplate.StringEndpoint = NULL;
- memcpy_s(&bindingTemplate.ObjectUuid, sizeof(UUID), connectionUuid, sizeof(UUID));
- bindingTemplate.Flags |= RPC_BHT_OBJECT_UUID_VALID;
- ZeroMemory(&bindingSecurity, sizeof(bindingSecurity));
- bindingSecurity.Version = 1;
- bindingSecurity.AuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
- bindingSecurity.AuthnSvc = RPC_C_AUTHN_KERNEL;
- bindingSecurity.SecurityQos = (RPC_SECURITY_QOS*)&securityQOS;
- status = RpcBindingCreate(&bindingTemplate, &bindingSecurity, NULL, &localBindingHandle);
- if (status != RPC_S_OK)
- {
- return HRESULT_FROM_WIN32(status);
- }
- // We keep attempting to connect to the server with increasing wait intervals in between.
- // This will wait close to 5 minutes before it finally gives up.
- do
- {
- DWORD waitStatus;
- status = RpcBindingBind(NULL, localBindingHandle, ClientIChakraJIT_v0_0_c_ifspec);
- if (status == RPC_S_OK)
- {
- break;
- }
- else if (status == EPT_S_NOT_REGISTERED)
- {
- // The Server side has not finished registering the RPC Server yet.
- // We should only breakout if we have reached the max attempt count.
- if (attemptCount > 600)
- {
- break;
- }
- }
- else
- {
- // Some unknown error occurred. We are not going to retry for arbitrary errors.
- break;
- }
- // When we come to this point, it means the server has not finished registration yet.
- // We should wait for a while and then reattempt to bind.
- waitStatus = WaitForSingleObject(serverProcessHandle, sleepInterval);
- if (waitStatus == WAIT_OBJECT_0)
- {
- // The server process died for some reason. No need to reattempt.
- status = RPC_S_SERVER_UNAVAILABLE;
- break;
- }
- else if (waitStatus == WAIT_TIMEOUT)
- {
- // Not an error. the server is still alive and we should reattempt.
- }
- else
- {
- Assert(waitStatus == WAIT_FAILED);
- #ifdef DBG
- LPWSTR messageBuffer = nullptr;
- DWORD errorNumber = GetLastError();
- FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, errorNumber, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
- Output::Print(_u("Last error was 0x%x (%s)"), errorNumber, messageBuffer);
- LocalFree(messageBuffer);
- #endif
- // wait operation failed for an unknown reason.
- Assert(false);
- status = HRESULT_FROM_WIN32(waitStatus);
- break;
- }
- attemptCount++;
- if (sleepInterval < 500)
- {
- sleepInterval += 100;
- }
- } while (status != RPC_S_OK); // redundant check, but compiler would not allow true here.
- *bindingHandle = localBindingHandle;
- return HRESULT_FROM_WIN32(status);
- }
- bool
- JITManager::IsJITServer() const
- {
- return m_isJITServer;
- }
- void
- JITManager::SetIsJITServer()
- {
- m_isJITServer = true;
- m_oopJitEnabled = true;
- }
- bool
- JITManager::IsConnected() const
- {
- Assert(IsOOPJITEnabled());
- return m_rpcBindingHandle != nullptr && !HasJITFailed();
- }
- void
- JITManager::EnableOOPJIT()
- {
- m_oopJitEnabled = true;
- if (CONFIG_FLAG(OOPCFGRegistration))
- {
- // Since this client has enabled OOPJIT, perform the one-way policy update
- // that will disable SetProcessValidCallTargets from being invoked.
- GlobalSecurityPolicy::DisableSetProcessValidCallTargets();
- }
- }
- void
- JITManager::SetJITFailed(HRESULT hr)
- {
- Assert(hr != S_OK);
- m_failingHRESULT = hr;
- }
- bool
- JITManager::HasJITFailed() const
- {
- return m_failingHRESULT != S_OK;
- }
- bool
- JITManager::IsOOPJITEnabled() const
- {
- return m_oopJitEnabled;
- }
- #pragma prefast(push)
- #pragma prefast(disable:__WARNING_RELEASING_UNHELD_LOCK_MEDIUM_CONFIDENCE, "Lock is correctly acquired and released by RAII class AutoCriticalSection")
- #pragma prefast(disable:__WARNING_CALLER_FAILING_TO_HOLD, "Lock is correctly acquired and released by RAII class AutoCriticalSection")
- HRESULT
- JITManager::ConnectRpcServer(__in HANDLE jitProcessHandle, __in_opt void* serverSecurityDescriptor, __in UUID connectionUuid)
- {
- // We might be trying to connect from multiple threads simultaneously
- AutoCriticalSection cs(&m_cs);
- Assert(IsOOPJITEnabled());
- if (m_rpcBindingHandle != nullptr)
- {
- return S_OK;
- }
- HRESULT hr = E_FAIL;
- RPC_BINDING_HANDLE bindingHandle;
- hr = CreateBinding(jitProcessHandle, serverSecurityDescriptor, &connectionUuid, &bindingHandle);
- if (FAILED(hr))
- {
- goto FailureCleanup;
- }
- hr = ConnectProcess(bindingHandle);
- HandleServerCallResult(hr, RemoteCallType::StateUpdate);
- // Only store the binding handle after JIT handshake, so other threads do not prematurely think we are ready to JIT
- m_rpcBindingHandle = bindingHandle;
- m_jitConnectionId = connectionUuid;
- return hr;
- FailureCleanup:
- if (m_rpcBindingHandle)
- {
- RpcBindingFree(&m_rpcBindingHandle);
- m_rpcBindingHandle = nullptr;
- }
- return hr;
- }
- #pragma prefast(pop)
- HRESULT
- JITManager::Shutdown()
- {
- // this is special case of shutdown called when runtime process is a parent of the server process
- // used for console host type scenarios
- HRESULT hr = S_OK;
- Assert(IsOOPJITEnabled());
- Assert(m_rpcBindingHandle != nullptr);
- RpcTryExcept
- {
- ClientShutdown(m_rpcBindingHandle);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- m_rpcBindingHandle = nullptr;
- return hr;
- }
- HRESULT
- JITManager::ConnectProcess(RPC_BINDING_HANDLE rpcBindingHandle)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- if (AutoSystemInfo::Data.IsWin8Point1OrLater())
- {
- HANDLE processHandle = nullptr;
- // RPC handle marshalling is only available on 8.1+
- if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &processHandle, 0, false, DUPLICATE_SAME_ACCESS))
- {
- return HRESULT_FROM_WIN32(GetLastError());
- }
- RpcTryExcept
- {
- hr = ClientConnectProcessWithProcessHandle(
- rpcBindingHandle,
- processHandle,
- (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
- (intptr_t)AutoSystemInfo::Data.GetCRTHandle());
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- if (processHandle)
- {
- CloseHandle(processHandle);
- }
- }
- else
- {
- #if (WINVER >= _WIN32_WINNT_WINBLUE)
- AssertOrFailFast(UNREACHED);
- #else
- RpcTryExcept
- {
- hr = ClientConnectProcess(
- rpcBindingHandle,
- (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
- (intptr_t)AutoSystemInfo::Data.GetCRTHandle());
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- #endif
- }
- return hr;
- }
- HRESULT
- JITManager::InitializeThreadContext(
- __in ThreadContextDataIDL * data,
- __out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __out intptr_t * prereservedRegionAddr,
- __out intptr_t * jitThunkAddr)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientInitializeThreadContext(
- m_rpcBindingHandle,
- data,
- threadContextInfoAddress,
- prereservedRegionAddr,
- jitThunkAddr);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::CleanupThreadContext(
- __inout PPTHREADCONTEXT_HANDLE threadContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientCleanupThreadContext(m_rpcBindingHandle, threadContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::SetIsPRNGSeeded(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in boolean value)
- {
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientSetIsPRNGSeeded(m_rpcBindingHandle, scriptContextInfoAddress, value);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::DecommitInterpreterBufferManager(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in boolean asmJsThunk)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientDecommitInterpreterBufferManager(m_rpcBindingHandle, scriptContextInfoAddress, asmJsThunk);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::NewInterpreterThunkBlock(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in InterpreterThunkInputIDL * thunkInput,
- __out InterpreterThunkOutputIDL * thunkOutput)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientNewInterpreterThunkBlock(m_rpcBindingHandle, scriptContextInfoAddress, thunkInput, thunkOutput);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::AddModuleRecordInfo(
- /* [in] */ PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ unsigned int moduleId,
- /* [in] */ intptr_t localExportSlotsAddr)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientAddModuleRecordInfo(m_rpcBindingHandle, scriptContextInfoAddress, moduleId, localExportSlotsAddr);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::SetWellKnownHostTypeId(
- __in PTHREADCONTEXT_HANDLE threadContextRoot,
- __in int typeId)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientSetWellKnownHostTypeId(m_rpcBindingHandle, threadContextRoot, typeId);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::UpdatePropertyRecordMap(
- __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __in_opt BVSparseNodeIDL * updatedPropsBVHead)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientUpdatePropertyRecordMap(m_rpcBindingHandle, threadContextInfoAddress, updatedPropsBVHead);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::InitializeScriptContext(
- __in ScriptContextDataIDL * data,
- __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __out PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientInitializeScriptContext(m_rpcBindingHandle, data, threadContextInfoAddress, scriptContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::CleanupScriptContext(
- __inout PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientCleanupScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::CloseScriptContext(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientCloseScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::FreeAllocation(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in intptr_t codeAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientFreeAllocation(m_rpcBindingHandle, scriptContextInfoAddress, codeAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::IsNativeAddr(
- __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __in intptr_t address,
- __out boolean * result)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientIsNativeAddr(m_rpcBindingHandle, threadContextInfoAddress, address, result);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::RemoteCodeGenCall(
- __in CodeGenWorkItemIDL *workItemData,
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __out JITOutputIDL *jitData)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientRemoteCodeGen(m_rpcBindingHandle, scriptContextInfoAddress, workItemData, jitData);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- #if DBG
- HRESULT
- JITManager::IsInterpreterThunkAddr(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in intptr_t address,
- __in boolean asmjsThunk,
- __out boolean * result)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientIsInterpreterThunkAddr(m_rpcBindingHandle, scriptContextInfoAddress, address, asmjsThunk, result);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- #endif
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- HRESULT
- JITManager::DeserializeRPCData(
- _In_reads_(bufferSize) const byte* buffer,
- _In_ uint bufferSize,
- _Out_ CodeGenWorkItemIDL **workItemData
- )
- {
- RPC_STATUS status = RPC_S_OK;
- handle_t marshalHandle = nullptr;
- *workItemData = nullptr;
- __try
- {
- RpcTryExcept
- {
- status = MesDecodeBufferHandleCreate((char*)buffer, bufferSize, &marshalHandle);
- if (status != RPC_S_OK)
- {
- return HRESULT_FROM_WIN32(status);
- }
- pCodeGenWorkItemIDL_Decode(
- marshalHandle,
- workItemData);
- }
- RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
- {
- status = RpcExceptionCode();
- }
- RpcEndExcept;
- }
- __finally
- {
- MesHandleFree(marshalHandle);
- }
- return HRESULT_FROM_WIN32(status);
- }
- HRESULT
- JITManager::SerializeRPCData(_In_ CodeGenWorkItemIDL *workItemData, _Out_ size_t* bufferSize, _Outptr_result_buffer_(*bufferSize) const byte** outBuffer)
- {
- handle_t marshalHandle = nullptr;
- *bufferSize = 0;
- *outBuffer = nullptr;
- RPC_STATUS status = RPC_S_OK;
- __try
- {
- RpcTryExcept
- {
- char* data = nullptr;
- unsigned long encodedSize;
- status = MesEncodeDynBufferHandleCreate(
- &data,
- &encodedSize,
- &marshalHandle);
- if (status != RPC_S_OK)
- {
- return HRESULT_FROM_WIN32(status);
- }
- MIDL_ES_CODE encodeType = MES_ENCODE;
- #if TARGET_64
- encodeType = MES_ENCODE_NDR64;
- // We only support encode syntax NDR64, however MesEncodeDynBufferHandleCreate doesn't allow to specify it
- status = MesBufferHandleReset(
- marshalHandle,
- MES_DYNAMIC_BUFFER_HANDLE,
- encodeType,
- &data,
- 0,
- &encodedSize
- );
- if (status != RPC_S_OK)
- {
- return HRESULT_FROM_WIN32(status);
- }
- #endif
- // Calculate how big we need to create the buffer
- size_t tmpBufSize = pCodeGenWorkItemIDL_AlignSize(marshalHandle, &workItemData);
- size_t alignedBufSize = Math::Align<size_t>(tmpBufSize, 16);
- data = HeapNewNoThrowArray(char, alignedBufSize);
- if (!data)
- {
- // Ran out of memory
- return E_OUTOFMEMORY;
- }
- // Reset the buffer handle to a fixed buffer
- status = MesBufferHandleReset(
- marshalHandle,
- MES_FIXED_BUFFER_HANDLE,
- encodeType,
- &data,
- (unsigned long)alignedBufSize,
- &encodedSize
- );
- if (status != RPC_S_OK)
- {
- return HRESULT_FROM_WIN32(status);
- }
- pCodeGenWorkItemIDL_Encode(
- marshalHandle,
- &workItemData);
- *bufferSize = alignedBufSize;
- *outBuffer = (byte*)data;
- }
- RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
- {
- status = RpcExceptionCode();
- }
- RpcEndExcept;
- }
- __finally
- {
- MesHandleFree(marshalHandle);
- }
- return HRESULT_FROM_WIN32(status);
- }
- #endif
|