summaryrefslogtreecommitdiff
path: root/src/inc/mscorpesxswrapper.h
blob: 52656f6711364c35ae9e146ec602dca4101cdf50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// 
// File: MscorpeSxSWrapper.h
// 

// 
// This file defines a wrapper for SxS version of mscorpe.dll (dynamically loaded via shim).
// 

#pragma once

#include "utilcode.h"

#include "iceefilegen.h"

// 
// Wrapper for calls into mscorpehost.dll (SxS version of mscorpe.dll).
// Template parameter will load the DLL as it is required in the context.
// 
// Note that _LoadMscorpeDll method can be called more than once and in parallel from more threads if race 
// happens.
// 
template <HRESULT (* _LoadMscorpeDll)(HMODULE * phModule)>
class MscorpeSxSWrapper
{
private:
    // mscorpehost.dll module, if not NULL, entry points are already initialized
    static Volatile<HMODULE>                s_hModule;
    // mscorpehost.dll entry points
    static Volatile<PFN_CreateICeeFileGen>  s_pfnCreateICeeFileGen;
    static Volatile<PFN_DestroyICeeFileGen> s_pfnDestroyICeeFileGen;
    
    // Loads the DLL and sets all statics
    static HRESULT Init();
    
public:
    
    // Wrapper of file:ICeeFileGen.cpp#CreateICeeFileGen from mscorpehost.dll
    static HRESULT CreateICeeFileGen(ICeeFileGen ** ppCeeFileGen)
    {
        HRESULT hr = S_OK;
        IfFailGo(Init());
        hr = s_pfnCreateICeeFileGen(ppCeeFileGen);
    ErrExit:
        return hr;
    }
    
    // Wrapper of file:ICeeFileGen.cpp#DestroyICeeFileGen from mscorpehost.dll
    static HRESULT DestroyICeeFileGen(ICeeFileGen ** ppCeeFileGen)
    {
        HRESULT hr = S_OK;
        IfFailGo(Init());
        hr = s_pfnDestroyICeeFileGen(ppCeeFileGen);
    ErrExit:
        return hr;
    }
    
#ifdef _DEBUG
    // Returns TRUE if the DLL has been already loaded
    static BOOL Debug_IsLoaded()
    {
        return (s_hModule != (HMODULE)NULL);
    }
#endif //_DEBUG
};  // class MscorpeSxS

template <HRESULT (* _LoadMscorpeDll)(HMODULE * phModule)>
// code:MscorpeSxS statics initialization
Volatile<HMODULE> MscorpeSxSWrapper<_LoadMscorpeDll>::s_hModule = NULL;

template <HRESULT (* _LoadMscorpeDll)(HMODULE * phModule)>
Volatile<PFN_CreateICeeFileGen> MscorpeSxSWrapper<_LoadMscorpeDll>::s_pfnCreateICeeFileGen = NULL;

template <HRESULT (* _LoadMscorpeDll)(HMODULE * phModule)>
Volatile<PFN_DestroyICeeFileGen> MscorpeSxSWrapper<_LoadMscorpeDll>::s_pfnDestroyICeeFileGen = NULL;

// Loads the DLL and sets all statics
//static 
template <HRESULT (* _LoadMscorpeDll)(HMODULE * phModule)>
HRESULT 
MscorpeSxSWrapper<_LoadMscorpeDll>::Init()
{
    HRESULT hr = S_OK;
    
    if (s_hModule != (HMODULE)NULL)
    {
        return S_OK;
    }
    
    // Local mscorpehost.dll module
    HMODULE hModule = NULL;
    // Local mscorpehost.dll entry points
    PFN_CreateICeeFileGen  pfnCreateICeeFileGen = NULL;
    PFN_DestroyICeeFileGen pfnDestroyICeeFileGen = NULL;
    
    // Load mscorpehost.dll and initialize it
    IfFailGo(_LoadMscorpeDll(&hModule));
    _ASSERTE(hModule != NULL);
    
    pfnCreateICeeFileGen = (PFN_CreateICeeFileGen)GetProcAddress(hModule, "CreateICeeFileGen");
    if (pfnCreateICeeFileGen == NULL)
    {
        IfFailGo(COR_E_EXECUTIONENGINE);
    }
    
    pfnDestroyICeeFileGen = (PFN_DestroyICeeFileGen)GetProcAddress(hModule, "DestroyICeeFileGen");
    if (pfnDestroyICeeFileGen == NULL)
    {
        IfFailGo(COR_E_EXECUTIONENGINE);
    }
    
ErrExit:
    if (SUCCEEDED(hr))
    {
        // First publish mscorpehost.dll entry points
        s_pfnCreateICeeFileGen = pfnCreateICeeFileGen;
        s_pfnDestroyICeeFileGen = pfnDestroyICeeFileGen;
        // Then we can publish/initialize the mscorpehost.dll module
        s_hModule = hModule;
    }
    
    return hr;
} // MscorpeSxSWrapper::Init