diff options
Diffstat (limited to 'src/ext/ComPlus/ca/cpasmexec.cpp')
-rw-r--r-- | src/ext/ComPlus/ca/cpasmexec.cpp | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/src/ext/ComPlus/ca/cpasmexec.cpp b/src/ext/ComPlus/ca/cpasmexec.cpp index 3d140027..af6c7eff 100644 --- a/src/ext/ComPlus/ca/cpasmexec.cpp +++ b/src/ext/ComPlus/ca/cpasmexec.cpp | |||
@@ -1,7 +1,7 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. |
2 | 2 | ||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | #include <mscoree.h> | |
5 | 5 | ||
6 | // GAC related declarations | 6 | // GAC related declarations |
7 | 7 | ||
@@ -61,13 +61,11 @@ public: | |||
61 | 61 | ||
62 | typedef HRESULT (__stdcall *LoadLibraryShimFunc)(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll); | 62 | typedef HRESULT (__stdcall *LoadLibraryShimFunc)(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll); |
63 | typedef HRESULT (__stdcall *CreateAssemblyCacheFunc)(IAssemblyCache **ppAsmCache, DWORD dwReserved); | 63 | typedef HRESULT (__stdcall *CreateAssemblyCacheFunc)(IAssemblyCache **ppAsmCache, DWORD dwReserved); |
64 | typedef HRESULT (__stdcall *GetFileVersionFnPtr)(LPCWSTR szFilename, _Out_writes_to_opt_(cchBuffer, *dwLength) LPWSTR szBuffer, DWORD cchBuffer, DWORD* dwLength); | ||
65 | typedef HRESULT (__stdcall *CorBindToRuntimeExFnPtr)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv); | ||
64 | 66 | ||
65 | 67 | ||
66 | // RegistrationHelper related declarations | 68 | // RegistrationHelper related declarations |
67 | |||
68 | static const GUID CLSID_RegistrationHelper = | ||
69 | { 0x89a86e7b, 0xc229, 0x4008, { 0x9b, 0xaa, 0x2f, 0x5c, 0x84, 0x11, 0xd7, 0xe0 } }; | ||
70 | |||
71 | enum eInstallationFlags { | 69 | enum eInstallationFlags { |
72 | ifConfigureComponentsOnly = 16, | 70 | ifConfigureComponentsOnly = 16, |
73 | ifFindOrCreateTargetApplication = 4, | 71 | ifFindOrCreateTargetApplication = 4, |
@@ -156,7 +154,8 @@ static HRESULT UnregisterAssembly( | |||
156 | static void InitAssemblyExec(); | 154 | static void InitAssemblyExec(); |
157 | static void UninitAssemblyExec(); | 155 | static void UninitAssemblyExec(); |
158 | static HRESULT GetRegistrationHelper( | 156 | static HRESULT GetRegistrationHelper( |
159 | IDispatch** ppiRegHlp | 157 | IDispatch** ppiRegHlp, |
158 | LPCWSTR pwzAssemblyPath | ||
160 | ); | 159 | ); |
161 | static HRESULT GetAssemblyCacheObject( | 160 | static HRESULT GetAssemblyCacheObject( |
162 | IAssemblyCache** ppAssemblyCache | 161 | IAssemblyCache** ppAssemblyCache |
@@ -722,15 +721,44 @@ static void UninitAssemblyExec() | |||
722 | } | 721 | } |
723 | 722 | ||
724 | static HRESULT GetRegistrationHelper( | 723 | static HRESULT GetRegistrationHelper( |
725 | IDispatch** ppiRegHlp | 724 | IDispatch** ppiRegHlp, |
725 | LPCWSTR pwzAssemblyPath | ||
726 | ) | 726 | ) |
727 | { | 727 | { |
728 | HRESULT hr = S_OK; | 728 | HRESULT hr = S_OK; |
729 | wchar_t pwzVersion[MAX_PATH]; | ||
730 | DWORD pcchVersionLen = MAX_PATH; | ||
731 | ICLRRuntimeHost* runtimeHost = NULL; | ||
732 | |||
733 | if (!ghMscoree) | ||
734 | { | ||
735 | ghMscoree = ::LoadLibraryW(L"mscoree.dll"); | ||
736 | ExitOnNull(ghMscoree, hr, E_FAIL, "Failed to load mscoree.dll"); | ||
737 | } | ||
738 | GetFileVersionFnPtr GetFileVersion = (GetFileVersionFnPtr)::GetProcAddress(ghMscoree, "GetFileVersion"); | ||
739 | ExitOnNull(GetFileVersion, hr, E_FAIL, "Failed to GetProcAddress for 'GetFileVersion' from 'mscoree.dll'"); | ||
740 | hr = GetFileVersion(pwzAssemblyPath, pwzVersion, pcchVersionLen, &pcchVersionLen); | ||
729 | 741 | ||
730 | if (!gpiRegHlp) | 742 | if (!gpiRegHlp) |
731 | { | 743 | { |
744 | CLSID CLSID_RegistrationHelper{}; | ||
745 | hr = ::CLSIDFromProgID(OLESTR("System.EnterpriseServices.RegistrationHelper"), &CLSID_RegistrationHelper); | ||
746 | ExitOnFailure(hr, "Failed to identify CLSID for 'System.EnterpriseServices.RegistrationHelper'"); | ||
747 | |||
748 | // NOTE: The 'CoreBindToRuntimeEx' method is DEPRECATED in .NET v4. | ||
749 | // HOWEVER, we might be running in an earlier context at this point so we don't want to rely upon stuff that is particularly v4 dependent. | ||
750 | // Even if we are about to try to fire up a v4 runtime. | ||
751 | // The .NET v4 runtime with STARTUP_LOADER_SAFEMODE flag (to disable version checking of loaded assemblies) is what lets us launch the | ||
752 | // RegistrationHelper. The v4 RegistrationHelper is able to register both v4 and v3 assemblies however, so if we can get it, we most as well | ||
753 | // use it. | ||
754 | CorBindToRuntimeExFnPtr CorBindToRuntimeEx = (CorBindToRuntimeExFnPtr)::GetProcAddress(ghMscoree, "CorBindToRuntimeEx"); | ||
755 | hr = CorBindToRuntimeEx(L"v4.0.30319", L"wks", STARTUP_LOADER_SAFEMODE, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&runtimeHost); | ||
756 | // we ignore the HRESULT here. If it worked, great, we'll use it moving forward. If it didn't work, we'll end up trying to resort to legacy .NET FW | ||
757 | // when we just try the COM Create below | ||
758 | |||
732 | // create registration helper object | 759 | // create registration helper object |
733 | hr = ::CoCreateInstance(CLSID_RegistrationHelper, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&gpiRegHlp); | 760 | // This will be created in the .NET FW 4 version if we managed to launch it above, or in the .NET FW <4 version based on the COM dispatch otherwise |
761 | hr = ::CoCreateInstance(CLSID_RegistrationHelper, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&gpiRegHlp); | ||
734 | ExitOnFailure(hr, "Failed to create registration helper object"); | 762 | ExitOnFailure(hr, "Failed to create registration helper object"); |
735 | } | 763 | } |
736 | 764 | ||
@@ -883,7 +911,7 @@ static HRESULT RegisterDotNetAssembly( | |||
883 | } | 911 | } |
884 | 912 | ||
885 | // get registration helper object | 913 | // get registration helper object |
886 | hr = GetRegistrationHelper(&piRegHlp); | 914 | hr = GetRegistrationHelper(&piRegHlp, pAttrs->pwzDllPath); |
887 | ExitOnFailure(hr, "Failed to get registration helper object"); | 915 | ExitOnFailure(hr, "Failed to get registration helper object"); |
888 | 916 | ||
889 | // get dispatch id of InstallAssembly() method | 917 | // get dispatch id of InstallAssembly() method |
@@ -979,7 +1007,7 @@ static HRESULT RegisterNativeAssembly( | |||
979 | ExitOnNull(bstrTlbPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path"); | 1007 | ExitOnNull(bstrTlbPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path"); |
980 | 1008 | ||
981 | bstrPSDllPath = ::SysAllocString(pAttrs->pwzPSDllPath ? pAttrs->pwzPSDllPath : L""); | 1009 | bstrPSDllPath = ::SysAllocString(pAttrs->pwzPSDllPath ? pAttrs->pwzPSDllPath : L""); |
982 | ExitOnNull(bstrPSDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path"); | 1010 | ExitOnNull(bstrPSDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for proxy/stub dll path"); |
983 | 1011 | ||
984 | // get catalog | 1012 | // get catalog |
985 | hr = CpiExecGetAdminCatalog(&piCatalog); | 1013 | hr = CpiExecGetAdminCatalog(&piCatalog); |
@@ -1089,7 +1117,7 @@ static HRESULT UnregisterDotNetAssembly( | |||
1089 | ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path"); | 1117 | ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path"); |
1090 | 1118 | ||
1091 | // get registration helper object | 1119 | // get registration helper object |
1092 | hr = GetRegistrationHelper(&piRegHlp); | 1120 | hr = GetRegistrationHelper(&piRegHlp, pAttrs->pwzDllPath); |
1093 | ExitOnFailure(hr, "Failed to get registration helper object"); | 1121 | ExitOnFailure(hr, "Failed to get registration helper object"); |
1094 | 1122 | ||
1095 | // get dispatch id of UninstallAssembly() method | 1123 | // get dispatch id of UninstallAssembly() method |