1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
7 // Contains convenience functionality for lazily loading modules
8 // and getting entrypoints within them.
18 #include "delayloadhelpers.h"
22 //=================================================================================================================
23 // Used to synchronize initialization. Is not used when initialization has already taken place.
25 static CRITSEC_COOKIE g_pLock = nullptr;
27 //=================================================================================================================
28 // Creates and initializes g_pLock when first used.
30 static HRESULT InitializeLock()
32 STATIC_CONTRACT_LIMITED_METHOD;
35 CRITSEC_COOKIE pLock = ClrCreateCriticalSection(CrstLeafLock, CRST_REENTRANCY);
37 if (InterlockedCompareExchangeT<CRITSEC_COOKIE>(&g_pLock, pLock, nullptr) != nullptr)
39 ClrDeleteCriticalSection(pLock);
45 //=================================================================================================================
46 HRESULT Module::GetValue(HMODULE *pHMODULE)
48 STATIC_CONTRACT_LIMITED_METHOD;
51 if (pHMODULE == nullptr)
58 IfFailRet(InitializeLock());
60 HModuleHolder hMod = ::LoadLibraryW(m_wzDllName);
61 hr = (hMod == nullptr) ? HRESULT_FROM_GetLastError() : S_OK;
62 _ASSERTE(FAILED(hr) == (hMod == nullptr));
65 CRITSEC_Holder lock(g_pLock);
69 m_hMod = hMod.Extract();
70 m_fInitialized = true;
75 _ASSERTE(m_fInitialized);
80 //=================================================================================================================
81 HRESULT Function::GetValue(LPVOID * ppvFunc)
83 STATIC_CONTRACT_LIMITED_METHOD;
86 if (ppvFunc == nullptr)
93 HMODULE hMod = nullptr;
94 IfFailRet(m_pModule->GetValue(&hMod));
96 LPVOID pvFunc = reinterpret_cast<LPVOID>(::GetProcAddress(hMod, m_szFunctionName));
97 hr = (pvFunc == nullptr) ? HRESULT_FROM_GetLastError() : S_OK;
100 CRITSEC_Holder lock(g_pLock);
104 m_pvFunction = pvFunc;
105 m_fInitialized = true;
110 _ASSERTE(m_fInitialized);
111 *ppvFunc = m_pvFunction;