diff options
Diffstat (limited to '')
| -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 |
