| 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. |
| 4 | // |
| 5 | |
| 6 | // |
| 7 | //***************************************************************************** |
| 8 | // CorHost.h |
| 9 | // |
| 10 | // Class factories are used by the pluming in COM to activate new objects. |
| 11 | // This module contains the class factory code to instantiate the debugger |
| 12 | // objects described in <cordb.h>. |
| 13 | // |
| 14 | //***************************************************************************** |
| 15 | |
| 16 | #ifndef __CorHost__h__ |
| 17 | #define __CorHost__h__ |
| 18 | |
| 19 | |
| 20 | #include "windows.h" // worth to include before mscoree.h so we are guaranteed to pick few definitions |
| 21 | #ifdef CreateSemaphore |
| 22 | #undef CreateSemaphore |
| 23 | #endif |
| 24 | |
| 25 | #include "mscoree.h" |
| 26 | |
| 27 | #include "clrinternal.h" |
| 28 | |
| 29 | #include "holder.h" |
| 30 | |
| 31 | #include "clrprivhosting.h" |
| 32 | |
| 33 | #ifdef FEATURE_COMINTEROP |
| 34 | #include "activation.h" // WinRT activation. |
| 35 | #endif |
| 36 | |
| 37 | class DangerousNonHostedSpinLock; |
| 38 | |
| 39 | #define INVALID_STACK_BASE_MARKER_FOR_CHECK_STATE 2 |
| 40 | |
| 41 | class AppDomain; |
| 42 | class Assembly; |
| 43 | |
| 44 | |
| 45 | class CorExecutionManager |
| 46 | : public ICLRExecutionManager |
| 47 | { |
| 48 | public: |
| 49 | CorExecutionManager(); |
| 50 | |
| 51 | STDMETHODIMP STDMETHODCALLTYPE Pause(DWORD dwAppDomainId, DWORD dwFlags); |
| 52 | STDMETHODIMP STDMETHODCALLTYPE Resume(DWORD dwAppDomainId); |
| 53 | |
| 54 | private: |
| 55 | DWORD m_dwFlags; //flags passed to the last Pause call. |
| 56 | INT64 m_pauseStartTime; |
| 57 | }; |
| 58 | |
| 59 | class CorRuntimeHostBase |
| 60 | { |
| 61 | protected: |
| 62 | CorRuntimeHostBase() |
| 63 | :m_Started(FALSE), |
| 64 | m_cRef(0) |
| 65 | {LIMITED_METHOD_CONTRACT;} |
| 66 | |
| 67 | STDMETHODIMP_(ULONG) AddRef(void); |
| 68 | |
| 69 | // Starts the runtime. This is equivalent to CoInitializeCor() |
| 70 | STDMETHODIMP Start(); |
| 71 | |
| 72 | #ifdef FEATURE_COMINTEROP |
| 73 | // Creates a domain in the runtime. The identity array is |
| 74 | // a pointer to an array TYPE containing IIdentity objects defining |
| 75 | // the security identity. |
| 76 | STDMETHODIMP CreateDomain(LPCWSTR pwzFriendlyName, // Optional |
| 77 | IUnknown* pIdentityArray, // Optional |
| 78 | IUnknown ** pAppDomain); |
| 79 | |
| 80 | // Returns the default domain. |
| 81 | STDMETHODIMP GetDefaultDomain(IUnknown ** pAppDomain); |
| 82 | |
| 83 | // Enumerate currently existing domains. |
| 84 | STDMETHODIMP EnumDomains(HDOMAINENUM *hEnum); |
| 85 | |
| 86 | // Returns S_FALSE when there are no more domains. A domain |
| 87 | // is passed out only when S_OK is returned. |
| 88 | STDMETHODIMP NextDomain(HDOMAINENUM hEnum, |
| 89 | IUnknown** pAppDomain); |
| 90 | |
| 91 | // Close the enumeration releasing resources |
| 92 | STDMETHODIMP CloseEnum(HDOMAINENUM hEnum); |
| 93 | |
| 94 | STDMETHODIMP CreateDomainEx(LPCWSTR pwzFriendlyName, |
| 95 | IUnknown* pSetup, // Optional |
| 96 | IUnknown* pEvidence, // Optional |
| 97 | IUnknown ** pAppDomain); |
| 98 | |
| 99 | // Create appdomain setup object that can be passed into CreateDomainEx |
| 100 | STDMETHODIMP CreateDomainSetup(IUnknown** pAppDomainSetup); |
| 101 | |
| 102 | // Create Evidence object that can be passed into CreateDomainEx |
| 103 | STDMETHODIMP CreateEvidence(IUnknown** pEvidence); |
| 104 | |
| 105 | // Unload a domain, releasing the reference will only release the |
| 106 | // the wrapper to the domain not unload the domain. |
| 107 | STDMETHODIMP UnloadDomain(IUnknown* pAppDomain); |
| 108 | |
| 109 | // Returns the threads domain if there is one. |
| 110 | STDMETHODIMP CurrentDomain(IUnknown ** pAppDomain); |
| 111 | #endif // FEATURE_COMINTEROP |
| 112 | |
| 113 | STDMETHODIMP MapFile( // Return code. |
| 114 | HANDLE hFile, // [in] Handle for file |
| 115 | HMODULE *hMapAddress // [out] HINSTANCE for mapped file |
| 116 | ); |
| 117 | |
| 118 | STDMETHODIMP LocksHeldByLogicalThread( // Return code. |
| 119 | DWORD *pCount // [out] Number of locks that the current thread holds. |
| 120 | ); |
| 121 | |
| 122 | protected: |
| 123 | BOOL m_Started; // Has START been called? |
| 124 | |
| 125 | LONG m_cRef; // Ref count. |
| 126 | |
| 127 | static ULONG m_Version; // Version of ICorRuntimeHost. |
| 128 | // Some functions are only available in ICLRRuntimeHost. |
| 129 | // Some functions are no-op in ICLRRuntimeHost. |
| 130 | |
| 131 | STDMETHODIMP UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone); |
| 132 | |
| 133 | STDMETHODIMP UnloadAppDomain2(DWORD dwDomainId, BOOL fWaitUntilDone, int *pLatchedExitCode); |
| 134 | public: |
| 135 | static ULONG GetHostVersion() |
| 136 | { |
| 137 | LIMITED_METHOD_CONTRACT; |
| 138 | _ASSERTE (m_Version != 0); |
| 139 | return m_Version; |
| 140 | } |
| 141 | |
| 142 | }; |
| 143 | |
| 144 | |
| 145 | class ConnectionNameTable; |
| 146 | typedef DPTR(class ConnectionNameTable) PTR_ConnectionNameTable; |
| 147 | |
| 148 | class CrstStatic; |
| 149 | |
| 150 | // Defines the precedence (in increading oder) of the two symbol reading knobs |
| 151 | enum ESymbolReadingSetBy |
| 152 | { |
| 153 | eSymbolReadingSetByDefault, |
| 154 | eSymbolReadingSetByConfig, // EEConfig - config file, env var, etc. |
| 155 | eSymbolReadingSetByHost, // Hosting API - highest precedence |
| 156 | eSymbolReadingSetBy_COUNT |
| 157 | }; |
| 158 | |
| 159 | |
| 160 | #if defined(FEATURE_WINDOWSPHONE) |
| 161 | class CCLRErrorReportingManager : |
| 162 | #ifdef FEATURE_WINDOWSPHONE |
| 163 | public ICLRErrorReportingManager2 |
| 164 | #else |
| 165 | public ICLRErrorReportingManager |
| 166 | #endif // FEATURE_WINDOWSPHONE |
| 167 | { |
| 168 | friend class ClrDataAccess; |
| 169 | friend struct _DacGlobals; |
| 170 | |
| 171 | SVAL_DECL(ECustomDumpFlavor, g_ECustomDumpFlavor); |
| 172 | |
| 173 | #ifdef FEATURE_WINDOWSPHONE |
| 174 | WCHAR* m_pApplicationId; |
| 175 | WCHAR* m_pInstanceId; |
| 176 | |
| 177 | class BucketParamsCache |
| 178 | { |
| 179 | private: |
| 180 | WCHAR** m_pParams; |
| 181 | DWORD const m_cMaxParams; |
| 182 | public: |
| 183 | BucketParamsCache(DWORD maxNumParams); |
| 184 | ~BucketParamsCache(); |
| 185 | |
| 186 | WCHAR const* GetAt(BucketParameterIndex index); |
| 187 | HRESULT SetAt(BucketParameterIndex index, WCHAR const* val); |
| 188 | }; |
| 189 | |
| 190 | BucketParamsCache* m_pBucketParamsCache; |
| 191 | |
| 192 | HRESULT CopyToDataCache(_In_ WCHAR** pTarget, WCHAR const* pSource); |
| 193 | #endif // FEATURE_WINDOWSPHONE |
| 194 | |
| 195 | public: |
| 196 | CCLRErrorReportingManager(); |
| 197 | ~CCLRErrorReportingManager(); |
| 198 | |
| 199 | STDMETHODIMP QueryInterface(REFIID riid, void** ppv); |
| 200 | STDMETHODIMP_(ULONG) AddRef(void); |
| 201 | STDMETHODIMP_(ULONG) Release(void); |
| 202 | |
| 203 | // ICLRErrorReportingManager APIs // |
| 204 | |
| 205 | // Get Watson bucket parameters for "current" exception (on calling thread). |
| 206 | STDMETHODIMP GetBucketParametersForCurrentException(BucketParameters *pParams); |
| 207 | STDMETHODIMP BeginCustomDump( ECustomDumpFlavor dwFlavor, |
| 208 | DWORD dwNumItems, |
| 209 | CustomDumpItem items[], |
| 210 | DWORD dwReserved); |
| 211 | STDMETHODIMP EndCustomDump(); |
| 212 | |
| 213 | #ifdef FEATURE_WINDOWSPHONE |
| 214 | // ICLRErrorReportingManager2 APIs // |
| 215 | |
| 216 | STDMETHODIMP SetApplicationData(ApplicationDataKey key, WCHAR const* pValue); |
| 217 | STDMETHODIMP SetBucketParametersForUnhandledException(BucketParameters const* pBucketParams, DWORD* pCountParams); |
| 218 | |
| 219 | // internal APIs |
| 220 | |
| 221 | // returns the application data for the specified key if available, else returns NULL. |
| 222 | WCHAR const* GetApplicationData(ApplicationDataKey key); |
| 223 | |
| 224 | // returns bucket parameter override data if available, else returns NULL. |
| 225 | WCHAR const* GetBucketParamOverride(BucketParameterIndex bucketParamId); |
| 226 | #endif // FEATURE_WINDOWSPHONE |
| 227 | }; |
| 228 | |
| 229 | extern CCLRErrorReportingManager g_CLRErrorReportingManager; |
| 230 | #endif // defined(FEATURE_WINDOWSPHONE) |
| 231 | |
| 232 | class CorHost2 : |
| 233 | public CorRuntimeHostBase |
| 234 | #ifndef FEATURE_PAL |
| 235 | , public IPrivateManagedExceptionReporting /* This interface is for internal Watson testing only*/ |
| 236 | #endif // FEATURE_PAL |
| 237 | , public ICLRRuntimeHost4 |
| 238 | , public CorExecutionManager |
| 239 | { |
| 240 | friend struct _DacGlobals; |
| 241 | |
| 242 | public: |
| 243 | CorHost2(); |
| 244 | virtual ~CorHost2() {} |
| 245 | |
| 246 | // *** IUnknown methods *** |
| 247 | STDMETHODIMP QueryInterface(REFIID riid, void** ppv); |
| 248 | STDMETHODIMP_(ULONG) AddRef(void) |
| 249 | { |
| 250 | WRAPPER_NO_CONTRACT; |
| 251 | return CorRuntimeHostBase::AddRef(); |
| 252 | } |
| 253 | STDMETHODIMP_(ULONG) Release(void); |
| 254 | |
| 255 | |
| 256 | // *** ICorRuntimeHost methods *** |
| 257 | |
| 258 | #ifndef FEATURE_PAL |
| 259 | // defined in IPrivateManagedExceptionReporting interface for internal Watson testing only |
| 260 | STDMETHODIMP GetBucketParametersForCurrentException(BucketParameters *pParams); |
| 261 | #endif // FEATURE_PAL |
| 262 | |
| 263 | // Starts the runtime. This is equivalent to CoInitializeCor(). |
| 264 | STDMETHODIMP Start(); |
| 265 | STDMETHODIMP Stop(); |
| 266 | |
| 267 | STDMETHODIMP ExecuteInAppDomain(DWORD dwAppDomainId, |
| 268 | FExecuteInAppDomainCallback pCallback, |
| 269 | void * cookie); |
| 270 | |
| 271 | STDMETHODIMP LocksHeldByLogicalThread( // Return code. |
| 272 | DWORD *pCount // [out] Number of locks that the current thread holds. |
| 273 | ) |
| 274 | { |
| 275 | WRAPPER_NO_CONTRACT; |
| 276 | return CorRuntimeHostBase::LocksHeldByLogicalThread(pCount); |
| 277 | } |
| 278 | |
| 279 | // Class factory hook-up. |
| 280 | static HRESULT CreateObject(REFIID riid, void **ppUnk); |
| 281 | |
| 282 | STDMETHODIMP MapFile( // Return code. |
| 283 | HANDLE hFile, // [in] Handle for file |
| 284 | HMODULE *hMapAddress // [out] HINSTANCE for mapped file |
| 285 | ) |
| 286 | { |
| 287 | WRAPPER_NO_CONTRACT; |
| 288 | return CorRuntimeHostBase::MapFile(hFile,hMapAddress); |
| 289 | } |
| 290 | |
| 291 | STDMETHODIMP STDMETHODCALLTYPE SetHostControl( |
| 292 | IHostControl* pHostControl); |
| 293 | |
| 294 | STDMETHODIMP STDMETHODCALLTYPE GetCLRControl( |
| 295 | ICLRControl** pCLRControl); |
| 296 | |
| 297 | STDMETHODIMP UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone); |
| 298 | |
| 299 | STDMETHODIMP UnloadAppDomain2(DWORD dwDomainId, BOOL fWaitUntilDone, int *pLatchedExitCode); |
| 300 | |
| 301 | STDMETHODIMP GetCurrentAppDomainId(DWORD *pdwAppDomainId); |
| 302 | |
| 303 | STDMETHODIMP ExecuteApplication(LPCWSTR pwzAppFullName, |
| 304 | DWORD dwManifestPaths, |
| 305 | LPCWSTR *ppwzManifestPaths, |
| 306 | DWORD dwActivationData, |
| 307 | LPCWSTR *ppwzActivationData, |
| 308 | int *pReturnValue); |
| 309 | |
| 310 | STDMETHODIMP ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath, |
| 311 | LPCWSTR pwzTypeName, |
| 312 | LPCWSTR pwzMethodName, |
| 313 | LPCWSTR pwzArgument, |
| 314 | DWORD *pReturnValue); |
| 315 | |
| 316 | // *** ICLRRuntimeHost2 methods *** |
| 317 | STDMETHODIMP CreateAppDomainWithManager( |
| 318 | LPCWSTR wszFriendlyName, |
| 319 | DWORD dwSecurityFlags, |
| 320 | LPCWSTR wszAppDomainManagerAssemblyName, |
| 321 | LPCWSTR wszAppDomainManagerTypeName, |
| 322 | int nProperties, |
| 323 | LPCWSTR* pPropertyNames, |
| 324 | LPCWSTR* pPropertyValues, |
| 325 | DWORD* pAppDomainID); |
| 326 | |
| 327 | STDMETHODIMP CreateDelegate( |
| 328 | DWORD appDomainID, |
| 329 | LPCWSTR wszAssemblyName, |
| 330 | LPCWSTR wszClassName, |
| 331 | LPCWSTR wszMethodName, |
| 332 | INT_PTR* fnPtr); |
| 333 | |
| 334 | STDMETHODIMP Authenticate(ULONGLONG authKey); |
| 335 | |
| 336 | STDMETHODIMP RegisterMacEHPort(); |
| 337 | STDMETHODIMP SetStartupFlags(STARTUP_FLAGS flag); |
| 338 | STDMETHODIMP DllGetActivationFactory( |
| 339 | DWORD appDomainID, |
| 340 | LPCWSTR wszTypeName, |
| 341 | IActivationFactory ** factory); |
| 342 | |
| 343 | STDMETHODIMP ExecuteAssembly( |
| 344 | DWORD dwAppDomainId, |
| 345 | LPCWSTR pwzAssemblyPath, |
| 346 | int argc, |
| 347 | LPCWSTR* argv, |
| 348 | DWORD* pReturnValue); |
| 349 | |
| 350 | static STARTUP_FLAGS GetStartupFlags(); |
| 351 | |
| 352 | static EInitializeNewDomainFlags GetAppDomainManagerInitializeNewDomainFlags(); |
| 353 | |
| 354 | static BOOL HasStarted() |
| 355 | { |
| 356 | return m_RefCount != 0; |
| 357 | } |
| 358 | |
| 359 | private: |
| 360 | // This flag indicates if this instance was the first to load and start CoreCLR |
| 361 | BOOL m_fFirstToLoadCLR; |
| 362 | |
| 363 | // This flag will be used to ensure that a CoreCLR host can invoke Start/Stop in pairs only. |
| 364 | BOOL m_fStarted; |
| 365 | BOOL m_fAppDomainCreated; // this flag is used when an appdomain can only create a single appdomain |
| 366 | |
| 367 | // Helpers for both ICLRRuntimeHost2 and ICLRPrivRuntime |
| 368 | HRESULT _CreateAppDomain( |
| 369 | LPCWSTR wszFriendlyName, |
| 370 | DWORD dwFlags, |
| 371 | LPCWSTR wszAppDomainManagerAssemblyName, |
| 372 | LPCWSTR wszAppDomainManagerTypeName, |
| 373 | int nProperties, |
| 374 | LPCWSTR* pPropertyNames, |
| 375 | LPCWSTR* pPropertyValues, |
| 376 | DWORD* pAppDomainID); |
| 377 | |
| 378 | HRESULT _CreateDelegate( |
| 379 | DWORD appDomainID, |
| 380 | LPCWSTR wszAssemblyName, |
| 381 | LPCWSTR wszClassName, |
| 382 | LPCWSTR wszMethodName, |
| 383 | INT_PTR* fnPtr); |
| 384 | |
| 385 | // entrypoint helper to be wrapped in a filter to process unhandled exceptions |
| 386 | VOID ExecuteMainInner(Assembly* pRootAssembly); |
| 387 | |
| 388 | static LONG m_RefCount; |
| 389 | |
| 390 | static IHostControl *m_HostControl; |
| 391 | |
| 392 | SVAL_DECL(STARTUP_FLAGS, m_dwStartupFlags); |
| 393 | }; |
| 394 | |
| 395 | class CorHostProtectionManager |
| 396 | { |
| 397 | private: |
| 398 | EApiCategories m_eProtectedCategories; |
| 399 | bool m_fEagerSerializeGrantSet; |
| 400 | bool m_fFrozen; |
| 401 | |
| 402 | public: |
| 403 | CorHostProtectionManager(); |
| 404 | |
| 405 | // IUnknown methods |
| 406 | HRESULT STDMETHODCALLTYPE QueryInterface( |
| 407 | REFIID id, |
| 408 | void **pInterface); |
| 409 | ULONG STDMETHODCALLTYPE AddRef(); |
| 410 | ULONG STDMETHODCALLTYPE Release(); |
| 411 | |
| 412 | // Interface methods |
| 413 | virtual HRESULT STDMETHODCALLTYPE SetProtectedCategories(/* [in] */ EApiCategories eFullTrustOnlyResources); |
| 414 | virtual HRESULT STDMETHODCALLTYPE SetEagerSerializeGrantSets(); |
| 415 | |
| 416 | // Getters |
| 417 | EApiCategories GetProtectedCategories(); |
| 418 | bool GetEagerSerializeGrantSets() const; |
| 419 | |
| 420 | void Freeze(); |
| 421 | }; |
| 422 | |
| 423 | #ifdef FEATURE_COMINTEROP |
| 424 | extern "C" |
| 425 | HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl( |
| 426 | LPCWSTR wszAssemblyName, |
| 427 | LPCWSTR wszTypeName, |
| 428 | LPCWSTR wszCodeBase, |
| 429 | IActivationFactory ** factory); |
| 430 | |
| 431 | #endif // defined(FEATURE_COMINTEROP) |
| 432 | |
| 433 | extern SIZE_T Host_SegmentSize; |
| 434 | extern SIZE_T Host_MaxGen0Size; |
| 435 | extern BOOL Host_fSegmentSizeSet; |
| 436 | extern BOOL Host_fMaxGen0SizeSet; |
| 437 | |
| 438 | #define PARTIAL_TRUST_VISIBLE_ASSEMBLIES_PROPERTY W("PARTIAL_TRUST_VISIBLE_ASSEMBLIES") |
| 439 | #endif // __CorHost__h__ |
| 440 | |