Skip to content

Commit ac92302

Browse files
committed
Included support for .NET 4.0. Refactored a few items.
1 parent 07cd5f8 commit ac92302

File tree

11 files changed

+213
-131
lines changed

11 files changed

+213
-131
lines changed

clr_host/ClrHost.cpp

Lines changed: 127 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@ const wchar_t *CClrHost::AppDomainManagerType = L"mysql_managed_interface.MySQLH
66

77
bool g_CLRHasBeenLoaded = false;
88

9+
910
/// <summary>
1011
/// Initialize the host
1112
/// </summary>
1213

14+
class CADMHostModule : public CAtlExeModuleT < CADMHostModule > { };
15+
CADMHostModule _AtlModule;
1316

14-
CClrHost::CClrHost() : m_started(false), m_pClr(NULL), m_pClrControl(NULL)
17+
CClrHost::CClrHost() : m_started(false), m_pClrControl(NULL)
1518
{
19+
20+
1621
return;
1722
}
1823

@@ -21,16 +26,13 @@ CClrHost::CClrHost() : m_started(false), m_pClr(NULL), m_pClrControl(NULL)
2126
/// </summary>
2227
CClrHost::~CClrHost()
2328
{
24-
// free the AppDomainManagers
25-
for (AppDomainManagerMap::iterator iAdm = m_appDomainManagers.begin(); iAdm != m_appDomainManagers.end(); iAdm++)
26-
iAdm->second->Release();
27-
28-
// release the CLR
29-
if (m_pClrControl != NULL)
30-
m_pClrControl->Release();
31-
if (m_pClr != NULL)
32-
m_pClr->Release();
29+
//// free the AppDomainManagers
30+
//for (AppDomainManagerMap::iterator iAdm = m_appDomainManagers.begin(); iAdm != m_appDomainManagers.end(); iAdm++)
31+
// iAdm->second->Release();
3332

33+
//// release the CLR
34+
//if (m_pClrControl != NULL)
35+
// m_pClrControl->Release();
3436
return;
3537
}
3638

@@ -41,66 +43,73 @@ CClrHost::~CClrHost()
4143
HRESULT CClrHost::FinalConstruct()
4244
{
4345
//load the CLR into the process
44-
return CorBindToRuntimeEx(NULL,
46+
/*return CorBindToRuntimeEx(NULL,
4547
NULL,
4648
0,
4749
CLSID_CLRRuntimeHost,
4850
IID_ICLRRuntimeHost,
49-
reinterpret_cast<LPVOID *>(&m_pClr));
50-
51-
// load the CLR into the process
52-
//ICLRMetaHost *pMetaHost = NULL;
53-
//ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
54-
//ICLRDebugging *pCLRDebugging = NULL;
55-
//HRESULT hr;
56-
//hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,
57-
// (LPVOID*)&pMetaHost);
58-
//hr = CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy,
59-
// (LPVOID*)&pMetaHostPolicy);
60-
//hr = CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging,
61-
// (LPVOID*)&pCLRDebugging);
62-
63-
//// Enumeration example from COM books.
64-
//IEnumUnknown * pRtEnum = NULL;
65-
//ICLRRuntimeInfo *info = NULL;
66-
//ULONG fetched = 0;
67-
//pMetaHost->EnumerateLoadedRuntimes(GetCurrentProcess(), &pRtEnum);
68-
//while ((hr = pRtEnum->Next(1, (IUnknown **)&info, &fetched)) == S_OK && fetched > 0)
69-
//{
70-
// WCHAR strName[128];
71-
// ZeroMemory(strName, sizeof(strName));
72-
// DWORD len = 128;
73-
// info->GetVersionString(strName, &len);
74-
// hr = info->GetInterface(CLSID_CLRRuntimeHost,
75-
// IID_ICLRRuntimeHost,
76-
// reinterpret_cast<LPVOID *>(&m_pClr));
77-
// if (!SUCCEEDED(hr))
78-
// printf("hr failed....");
79-
80-
//}
81-
//pRtEnum->Release();
82-
//pRtEnum = NULL;
83-
84-
//pMetaHost->EnumerateInstalledRuntimes(&pRtEnum);
85-
//while ((hr = pRtEnum->Next(1, (IUnknown **)&info, &fetched)) == S_OK && fetched > 0)
86-
//{
87-
// WCHAR strName[128];
88-
// ZeroMemory(strName, sizeof(strName));
89-
// DWORD len = 128;
90-
// info->GetVersionString(strName, &len);
91-
// hr = info->GetInterface(CLSID_CLRRuntimeHost,
92-
// IID_ICLRRuntimeHost,
93-
// reinterpret_cast<LPVOID *>(&m_pClr));
94-
// if (!SUCCEEDED(hr))
95-
// printf("hr failed....");
96-
97-
//}
98-
//pRtEnum->Release();
99-
51+
reinterpret_cast<LPVOID *>(&m_pClr));*/
10052

53+
//load the CLR into the process
54+
ICLRMetaHost *pMetaHost = NULL;
55+
ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
56+
ICLRDebugging *pCLRDebugging = NULL;
57+
HRESULT hr;
58+
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,
59+
(LPVOID*)&pMetaHost);
60+
/*hr = CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy,
61+
(LPVOID*)&pMetaHostPolicy);*/
62+
/*hr = CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging,
63+
(LPVOID*)&pCLRDebugging);*/
64+
65+
// Enumeration example from COM books.
66+
IEnumUnknown * pRtEnum = NULL;
67+
ICLRRuntimeInfo *info = NULL;
68+
ULONG fetched = 0;
69+
ICLRRuntimeHost *m_pClr = NULL;
70+
bool runtimesLoaded = false;
71+
pMetaHost->EnumerateLoadedRuntimes(GetCurrentProcess(), &pRtEnum);
72+
WCHAR strName[128];
73+
DWORD len = 128;
74+
75+
while ((hr = pRtEnum->Next(1, (IUnknown **)&info, &fetched)) == S_OK && fetched > 0)
76+
{
77+
ZeroMemory(strName, sizeof(strName));
78+
info->GetVersionString(strName, &len);
79+
hr = info->GetInterface(CLSID_CLRRuntimeHost,
80+
IID_ICLRRuntimeHost,
81+
reinterpret_cast<LPVOID *>(&m_pClr));
82+
if (!SUCCEEDED(hr))
83+
printf("hr failed....");
84+
runtimesLoaded = true;
85+
this->m_lastCLR.assign(strName);
86+
}
87+
pRtEnum->Release();
88+
pRtEnum = NULL;
89+
if (!runtimesLoaded)
90+
{
91+
pMetaHost->EnumerateInstalledRuntimes(&pRtEnum);
92+
while ((hr = pRtEnum->Next(1, (IUnknown **)&info, &fetched)) == S_OK && fetched > 0)
93+
{
94+
ZeroMemory(strName, sizeof(strName));
95+
96+
info->GetVersionString(strName, &len);
97+
hr = info->GetInterface(CLSID_CLRRuntimeHost,
98+
IID_ICLRRuntimeHost,
99+
reinterpret_cast<LPVOID *>(&m_pClr));
100+
if (!SUCCEEDED(hr))
101+
printf("hr failed....");
102+
m_CLRRuntimeMap[std::wstring(strName)] = m_pClr;
103+
this->m_lastCLR.assign(strName);
104+
}
105+
pRtEnum->Release();
106+
}
107+
pMetaHost->Release();
101108
return S_OK;
102109
}
103110

111+
112+
104113
/// <summary>
105114
/// Create a host object, and bind to the CLR
106115
/// </summary>
@@ -154,14 +163,14 @@ STDMETHODIMP CClrHost::SetAppDomainManager(DWORD dwAppDomainId, __in IUnknown *p
154163
_ASSERTE(!"AppDomainManager does not implement IManagedHost");
155164
return E_NOINTERFACE;
156165
}
157-
158166
// register ourselves as the unmanaged host
159167
HRESULT hrSetUnmanagedHost = pAppDomainManager->raw_SetUnmanagedHost(static_cast<IUnmanagedHost *>(this));
160168
if (FAILED(hrSetUnmanagedHost))
161169
return hrSetUnmanagedHost;
162170

171+
auto clr = std::wstring(pAppDomainManager->GetCLR());
163172
// save a copy
164-
m_appDomainManagers[dwAppDomainId] = pAppDomainManager;
173+
m_appDomainManagers[clr] = pAppDomainManager;
165174
return S_OK;
166175
}
167176

@@ -171,50 +180,57 @@ STDMETHODIMP CClrHost::SetAppDomainManager(DWORD dwAppDomainId, __in IUnknown *p
171180
STDMETHODIMP CClrHost::raw_Start()
172181
{
173182
// we should have bound to the runtime, but not yet started it upon entry
174-
_ASSERTE(m_pClr != NULL);
175-
_ASSERTE(!m_started);
183+
//_ASSERTE(m_pClr != NULL
184+
if (!m_started)
185+
{
186+
_ASSERTE(!m_started);
187+
//if (m_pClr == NULL)
188+
// return E_FAIL;
176189

177-
if (m_pClr == NULL)
178-
return E_FAIL;
190+
for (auto &x : m_CLRRuntimeMap)
191+
{
179192

180-
// get the CLR control object
181-
HRESULT hrClrControl = m_pClr->GetCLRControl(&m_pClrControl);
182-
if (FAILED(hrClrControl))
183-
return hrClrControl;
193+
ICLRRuntimeHost *m_pClr = x.second;
194+
// get the CLR control object
195+
HRESULT hrClrControl = m_pClr->GetCLRControl(&m_pClrControl);
196+
if (FAILED(hrClrControl))
197+
return hrClrControl;
184198

185-
// set ourselves up as the host control
186-
HRESULT hrHostControl = m_pClr->SetHostControl(static_cast<IHostControl *>(this));
199+
// set ourselves up as the host control
200+
HRESULT hrHostControl = m_pClr->SetHostControl(static_cast<IHostControl *>(this));
187201

188-
// get the host protection manager
189-
ICLRHostProtectionManager *pHostProtectionManager = NULL;
190-
HRESULT hrGetProtectionManager = m_pClrControl->GetCLRManager(
191-
IID_ICLRHostProtectionManager,
192-
reinterpret_cast<void **>(&pHostProtectionManager));
193-
if (FAILED(hrGetProtectionManager))
194-
return hrGetProtectionManager;
202+
// get the host protection manager
203+
ICLRHostProtectionManager *pHostProtectionManager = NULL;
204+
HRESULT hrGetProtectionManager = m_pClrControl->GetCLRManager(
205+
IID_ICLRHostProtectionManager,
206+
reinterpret_cast<void **>(&pHostProtectionManager));
207+
if (FAILED(hrGetProtectionManager))
208+
return hrGetProtectionManager;
195209

196-
// setup host proctection
197-
HRESULT hrHostProtection = pHostProtectionManager->SetProtectedCategories(
198-
(EApiCategories)(eSynchronization | eSelfAffectingThreading));
199-
pHostProtectionManager->Release();
210+
// setup host proctection
211+
HRESULT hrHostProtection = pHostProtectionManager->SetProtectedCategories(
212+
(EApiCategories)(eSynchronization | eSelfAffectingThreading));
213+
pHostProtectionManager->Release();
200214

201-
if (FAILED(hrHostProtection))
202-
return hrHostProtection;
215+
if (FAILED(hrHostProtection))
216+
return hrHostProtection;
203217

204218

205-
// setup the AppDomainManager
206-
HRESULT hrSetAdm = m_pClrControl->SetAppDomainManagerType(AppDomainManagerAssembly, AppDomainManagerType);
207-
if (FAILED(hrSetAdm))
208-
return hrSetAdm;
219+
// setup the AppDomainManager
220+
HRESULT hrSetAdm = m_pClrControl->SetAppDomainManagerType(AppDomainManagerAssembly, AppDomainManagerType);
221+
if (FAILED(hrSetAdm))
222+
return hrSetAdm;
209223

210-
// mark as started
211-
m_started = true;
212224

213-
// finally, start the runtime
214-
HRESULT hrStart = m_pClr->Start();
215-
if (FAILED(hrStart))
216-
return hrStart;
225+
// finally, start the runtime
226+
HRESULT hrStart = m_pClr->Start();
227+
if (FAILED(hrStart))
228+
return hrStart;
229+
}
217230

231+
// mark as started
232+
m_started = true;
233+
}
218234
return S_OK;
219235
}
220236

@@ -230,7 +246,7 @@ STDMETHODIMP CClrHost::raw_Stop()
230246
iAdm->second->raw_Dispose();
231247

232248
// then, shut down the CLR
233-
return m_pClr->Stop();
249+
return S_OK; // m_pClr->Stop();
234250
}
235251

236252
/// <summary>
@@ -239,31 +255,31 @@ STDMETHODIMP CClrHost::raw_Stop()
239255
STDMETHODIMP CClrHost::get_DefaultManagedHost(__out IManagedHost **ppHost)
240256
{
241257
// just get the AppDomainManager for the default AppDomain
242-
return raw_GetManagedHost(1, ppHost);
258+
return raw_GetManagedHost(1, BSTR(m_lastCLR.c_str()), ppHost);
243259
}
244260

245261
/// <summary>
246262
/// Get the AppDomainManager for a specific AppDomain
247263
/// </summary>
248-
STDMETHODIMP CClrHost::raw_GetManagedHost(long appDomain, IManagedHost **ppHost)
264+
STDMETHODIMP CClrHost::raw_GetManagedHost(long appDomain, BSTR clr, IManagedHost **ppHost)
249265
{
250266
_ASSERTE(m_started);
251267

252268
if (ppHost == NULL)
253269
return E_POINTER;
254270

255271
// get the AppDomainManager for the specified domain
256-
AppDomainManagerMap::const_iterator iHost = m_appDomainManagers.find(appDomain);
272+
auto iHost = m_appDomainManagers[clr];
257273

258274
// see if we've got a host
259-
if (iHost == m_appDomainManagers.end())
275+
if (iHost == NULL)
260276
{
261277
*ppHost = NULL;
262278
return E_NOMANAGEDHOST;
263279
}
264280
else
265281
{
266-
*ppHost = iHost->second;
282+
*ppHost = iHost;
267283
(*ppHost)->AddRef();
268284
return S_OK;
269285
}
@@ -272,4 +288,11 @@ STDMETHODIMP CClrHost::raw_GetManagedHost(long appDomain, IManagedHost **ppHost)
272288
// IHostGCManager
273289
STDMETHODIMP CClrHost::SuspensionEnding(DWORD generation){ return S_OK; }
274290
STDMETHODIMP CClrHost::SuspensionStarting(){ return S_OK; }
275-
STDMETHODIMP CClrHost::ThreadIsBlockingForSuspension(){ return S_OK; }
291+
STDMETHODIMP CClrHost::ThreadIsBlockingForSuspension(){ return S_OK; }
292+
293+
STDMETHODIMP CClrHost::CreateAppDomainForQuery(std::string FnName)
294+
{
295+
IManagedHostPtr pAppMgr = this->GetDefaultManagedHost();
296+
_bstr_t retString = pAppMgr->CreateAppDomain(_bstr_t(FnName.c_str()));
297+
return S_OK;
298+
}

clr_host/ClrHost.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,21 @@ class ATL_NO_VTABLE CClrHost : public CComObjectRootEx<CComSingleThreadModel>,
2020
END_COM_MAP()
2121

2222
private:
23-
typedef map<DWORD, IManagedHost *> AppDomainManagerMap;
23+
typedef map<const std::wstring, IManagedHost *> AppDomainManagerMap;
24+
typedef map<const std::wstring, ICLRRuntimeHost *> CLRRunTimeMap;
2425

2526
bool m_started;
26-
ICLRRuntimeHost *m_pClr;
27+
2728
ICLRControl *m_pClrControl;
2829
AppDomainManagerMap m_appDomainManagers;
30+
AppDomainManagerMap m_NewlyCreatedAppDomains;
31+
CLRRunTimeMap m_CLRRuntimeMap;
2932

3033
private:
3134
static const wchar_t *AppDomainManagerAssembly;
3235
static const wchar_t *AppDomainManagerType;
36+
std::wstring m_lastCLR;
37+
3338

3439
public:
3540
CClrHost();
@@ -40,6 +45,7 @@ class ATL_NO_VTABLE CClrHost : public CComObjectRootEx<CComSingleThreadModel>,
4045

4146
public:
4247
static HRESULT BindToRuntime(IUnmanagedHost **pHost);
48+
STDMETHODIMP CreateAppDomainForQuery(std::string FnName);
4349

4450
// IHostControl
4551
public:
@@ -51,7 +57,7 @@ class ATL_NO_VTABLE CClrHost : public CComObjectRootEx<CComSingleThreadModel>,
5157
STDMETHODIMP raw_Start();
5258
STDMETHODIMP raw_Stop();
5359
STDMETHODIMP get_DefaultManagedHost(IManagedHost **ppHost);
54-
STDMETHODIMP raw_GetManagedHost(long appDomain, IManagedHost **ppHost);
60+
STDMETHODIMP raw_GetManagedHost(long appDomain, BSTR clr, IManagedHost **ppHost);
5561

5662
// IHostGCManager
5763
public:

mysql_managed_interface/IManagedHost.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public interface IManagedHost
1313
/// </summary>
1414
/// <param name="name">name of the AppDomain to create</param>
1515
/// <returns>ID of the new AppDomain</returns>
16-
int CreateAppDomain([MarshalAs(UnmanagedType.BStr)]string name);
16+
string CreateAppDomain([MarshalAs(UnmanagedType.BStr)]string name);
1717

1818
/// <summary>
1919
/// Clean up the AppDomianManager
@@ -40,6 +40,9 @@ public interface IManagedHost
4040
///
4141
[return: MarshalAs(UnmanagedType.I8)]
4242
Int64 Run([MarshalAs(UnmanagedType.I8)]Int64 path);
43+
44+
[return: MarshalAs(UnmanagedType.BStr)]
45+
string GetCLR();
4346
}
4447

4548
}

0 commit comments

Comments
 (0)