diff options
Diffstat (limited to 'src/ext/NetFx/ca/netfxca.cpp')
| -rw-r--r-- | src/ext/NetFx/ca/netfxca.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/ext/NetFx/ca/netfxca.cpp b/src/ext/NetFx/ca/netfxca.cpp index f0704790..cd086c53 100644 --- a/src/ext/NetFx/ca/netfxca.cpp +++ b/src/ext/NetFx/ca/netfxca.cpp | |||
| @@ -36,6 +36,10 @@ LPCWSTR vcsNgenStrongName = | |||
| 36 | L"SELECT `Name`,`Value` FROM `MsiAssemblyName` WHERE `Component_`=?"; | 36 | L"SELECT `Name`,`Value` FROM `MsiAssemblyName` WHERE `Component_`=?"; |
| 37 | enum eNgenStrongName { ngsnName = 1, ngsnValue }; | 37 | enum eNgenStrongName { ngsnName = 1, ngsnValue }; |
| 38 | 38 | ||
| 39 | LPCWSTR vscDotNetCompatibilityCheckQuery = | ||
| 40 | L"SELECT `Platform`, `RuntimeType`, `Version`, `RollForward`, `Property` FROM `Wix4NetFxDotNetCheck`"; | ||
| 41 | enum eDotNetCompatibilityCheckQuery { platform = 1, runtimeType, version, rollForward, property }; | ||
| 42 | |||
| 39 | // Searches subdirectories of the given path for the highest version of ngen.exe available | 43 | // Searches subdirectories of the given path for the highest version of ngen.exe available |
| 40 | static HRESULT GetNgenVersion( | 44 | static HRESULT GetNgenVersion( |
| 41 | __in LPWSTR pwzParentPath, | 45 | __in LPWSTR pwzParentPath, |
| @@ -500,6 +504,15 @@ extern "C" UINT __stdcall SchedNetFx( | |||
| 500 | hr = WcaInitialize(hInstall, "SchedNetFx"); | 504 | hr = WcaInitialize(hInstall, "SchedNetFx"); |
| 501 | ExitOnFailure(hr, "failed to initialize"); | 505 | ExitOnFailure(hr, "failed to initialize"); |
| 502 | 506 | ||
| 507 | // If Wix4NetFxNativeImage table doesn't exist skip the rest of this custom action | ||
| 508 | hr = WcaTableExists(L"Wix4NetFxNativeImage"); | ||
| 509 | if (S_FALSE == hr) | ||
| 510 | { | ||
| 511 | hr = S_OK; | ||
| 512 | ExitFunction(); | ||
| 513 | } | ||
| 514 | ExitOnFailure(hr, "failed to check if table Wix4NetFxNativeImage exists"); | ||
| 515 | |||
| 503 | hr = GetNgenPath(&pwz32Ngen, FALSE); | 516 | hr = GetNgenPath(&pwz32Ngen, FALSE); |
| 504 | f32NgenExeExists = SUCCEEDED(hr); | 517 | f32NgenExeExists = SUCCEEDED(hr); |
| 505 | if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) | 518 | if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) |
| @@ -879,3 +892,134 @@ LExit: | |||
| 879 | return WcaFinalize(er); | 892 | return WcaFinalize(er); |
| 880 | } | 893 | } |
| 881 | 894 | ||
| 895 | /****************************************************************** | ||
| 896 | DotNetCompatibilityCheck - entry point for NetFx Custom Action | ||
| 897 | |||
| 898 | *******************************************************************/ | ||
| 899 | extern "C" UINT __stdcall DotNetCompatibilityCheck( | ||
| 900 | __in MSIHANDLE hInstall | ||
| 901 | ) | ||
| 902 | { | ||
| 903 | // AssertSz(FALSE, "debug DotNetCompatibilityCheck"); | ||
| 904 | |||
| 905 | HRESULT hr = S_OK; | ||
| 906 | UINT er = ERROR_SUCCESS; | ||
| 907 | |||
| 908 | PMSIHANDLE hView = NULL; | ||
| 909 | PMSIHANDLE hRec = NULL; | ||
| 910 | LPWSTR pwzPlatform = NULL; | ||
| 911 | LPWSTR pwzNetCoreCheckBinaryId = NULL; | ||
| 912 | LPWSTR pwzNetCoreCheckDirectoryName = NULL; | ||
| 913 | LPWSTR pwzNetCoreCheckDirectoryPath = NULL; | ||
| 914 | LPWSTR pwzNetCoreCheckFilePath = NULL; | ||
| 915 | LPWSTR pwzRuntimeType = NULL; | ||
| 916 | LPWSTR pwzVersion = NULL; | ||
| 917 | LPWSTR pwzRollForward = NULL; | ||
| 918 | LPWSTR pwzProperty = NULL; | ||
| 919 | LPWSTR pwzCommandLine = NULL; | ||
| 920 | HANDLE hProcess = NULL; | ||
| 921 | DWORD dwExitCode = 0; | ||
| 922 | |||
| 923 | // Initialize | ||
| 924 | hr = WcaInitialize(hInstall, "DotNetCompatibilityCheck"); | ||
| 925 | ExitOnFailure(hr, "failed to initialize"); | ||
| 926 | |||
| 927 | // If Wix4NetFxDotNetCheck table doesn't exist skip the rest of this custom action | ||
| 928 | hr = WcaTableExists(L"Wix4NetFxDotNetCheck"); | ||
| 929 | if (S_FALSE == hr) | ||
| 930 | { | ||
| 931 | hr = S_OK; | ||
| 932 | ExitFunction(); | ||
| 933 | } | ||
| 934 | ExitOnFailure(hr, "failed to check if table Wix4NetFxDotNetCheck exists"); | ||
| 935 | |||
| 936 | // Open view on .NET compatibility check table | ||
| 937 | hr = WcaOpenExecuteView(vscDotNetCompatibilityCheckQuery, &hView); | ||
| 938 | ExitOnFailure(hr, "failed to open view on Wix4NetFxDotNetCheck table"); | ||
| 939 | |||
| 940 | // Go through all records and run NetCorCheck.exe for each | ||
| 941 | while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) | ||
| 942 | { | ||
| 943 | // Extract NetCoreCheck.exe for platform to temp directory | ||
| 944 | hr = WcaGetRecordString(hRec, platform, &pwzPlatform); | ||
| 945 | ExitOnFailure(hr, "failed to get Wix4NetFxDotNetCheck.Platform"); | ||
| 946 | |||
| 947 | hr = StrAllocFormatted(&pwzNetCoreCheckBinaryId, L"Wix4NetCheck_%ls", pwzPlatform); | ||
| 948 | ExitOnFailure(hr, "failed to get NetCoreCheck binary id for platform %ls", pwzPlatform); | ||
| 949 | |||
| 950 | hr = GuidCreate(&pwzNetCoreCheckDirectoryName); | ||
| 951 | ExitOnFailure(hr, "failed to set NetCoreCheck directory name"); | ||
| 952 | |||
| 953 | hr = PathCreateTempDirectory(NULL, pwzNetCoreCheckDirectoryName, 1, &pwzNetCoreCheckDirectoryPath); | ||
| 954 | ExitOnFailure(hr, "failed to make NetCoreCheck directory path for name %ls", pwzNetCoreCheckDirectoryName); | ||
| 955 | |||
| 956 | hr = StrAllocFormatted(&pwzNetCoreCheckFilePath, L"%lsNetCoreCheck.exe", pwzNetCoreCheckDirectoryPath); | ||
| 957 | ExitOnFailure(hr, "failed to set NetCoreCheck file path for directory %ls", pwzNetCoreCheckDirectoryPath); | ||
| 958 | |||
| 959 | hr = WcaExtractBinaryToFile(pwzNetCoreCheckBinaryId, pwzNetCoreCheckFilePath); | ||
| 960 | ExitOnFailure(hr, "failed to extract NetCoreCheck from binary '%ls' to file %ls", pwzNetCoreCheckBinaryId, pwzNetCoreCheckFilePath); | ||
| 961 | |||
| 962 | // Read all NetCoreCheck.exe parameters and property | ||
| 963 | hr = WcaGetRecordString(hRec, runtimeType, &pwzRuntimeType); | ||
| 964 | ExitOnFailure(hr, "failed to get Wix4NetFxDotNetCheck.RuntimeType"); | ||
| 965 | |||
| 966 | hr = WcaGetRecordString(hRec, version, &pwzVersion); | ||
| 967 | ExitOnFailure(hr, "failed to get Wix4NetFxDotNetCheck.Version"); | ||
| 968 | |||
| 969 | hr = WcaGetRecordString(hRec, rollForward, &pwzRollForward); | ||
| 970 | ExitOnFailure(hr, "failed to get Wix4NetFxDotNetCheck.RollForward"); | ||
| 971 | |||
| 972 | hr = WcaGetRecordString(hRec, property, &pwzProperty); | ||
| 973 | ExitOnFailure(hr, "failed to get Wix4NetFxDotNetCheck.Property"); | ||
| 974 | |||
| 975 | // Run NetCoreCheck.exe and store its result in property | ||
| 976 | hr = StrAllocFormatted(&pwzCommandLine, L"-n %ls -v %ls -r %ls", pwzRuntimeType, pwzVersion, pwzRollForward); | ||
| 977 | ExitOnFailure(hr, "failed to set NetCoreCheck command line"); | ||
| 978 | WcaLog(LOGMSG_VERBOSE, "Command: %ls %ls", pwzNetCoreCheckFilePath, pwzCommandLine); | ||
| 979 | |||
| 980 | hr = ProcExec(pwzNetCoreCheckFilePath, pwzCommandLine, SW_HIDE, &hProcess); | ||
| 981 | ExitOnFailure(hr, "failed to run NetCoreCheck from binary '%ls' with command line: %ls %ls", pwzNetCoreCheckBinaryId, pwzNetCoreCheckFilePath, pwzCommandLine); | ||
| 982 | |||
| 983 | hr = ProcWaitForCompletion(hProcess, INFINITE, &dwExitCode); | ||
| 984 | ExitOnFailure(hr, "failed to finish NetCoreCheck from binary '%ls' with command line: %ls %ls", pwzNetCoreCheckBinaryId, pwzNetCoreCheckFilePath, pwzCommandLine); | ||
| 985 | WcaLog(LOGMSG_VERBOSE, "Exit code: %lu", dwExitCode); | ||
| 986 | ReleaseHandle(hProcess); | ||
| 987 | |||
| 988 | hr = WcaSetIntProperty(pwzProperty, dwExitCode); | ||
| 989 | ExitOnFailure(hr, "failed to set NetCoreCheck result in %ls", pwzProperty); | ||
| 990 | |||
| 991 | // Delete extracted NetCoreCheck.exe | ||
| 992 | DirEnsureDelete(pwzNetCoreCheckDirectoryPath, TRUE, TRUE); | ||
| 993 | } | ||
| 994 | if (E_NOMOREITEMS == hr) | ||
| 995 | { | ||
| 996 | hr = S_OK; | ||
| 997 | } | ||
| 998 | ExitOnFailure(hr, "failed while looping through all dot net compatibility checks"); | ||
| 999 | |||
| 1000 | LExit: | ||
| 1001 | // Delete extracted NetCoreCheck.exe | ||
| 1002 | if (NULL != pwzNetCoreCheckDirectoryPath) | ||
| 1003 | { | ||
| 1004 | DirEnsureDelete(pwzNetCoreCheckDirectoryPath, TRUE, TRUE); | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | // Release allocated resources | ||
| 1008 | ReleaseStr(pwzPlatform); | ||
| 1009 | ReleaseStr(pwzNetCoreCheckBinaryId); | ||
| 1010 | ReleaseStr(pwzNetCoreCheckDirectoryName); | ||
| 1011 | ReleaseStr(pwzNetCoreCheckDirectoryPath); | ||
| 1012 | ReleaseStr(pwzNetCoreCheckFilePath); | ||
| 1013 | ReleaseStr(pwzRuntimeType); | ||
| 1014 | ReleaseStr(pwzVersion); | ||
| 1015 | ReleaseStr(pwzRollForward); | ||
| 1016 | ReleaseStr(pwzProperty); | ||
| 1017 | ReleaseStr(pwzCommandLine); | ||
| 1018 | ReleaseHandle(hProcess); | ||
| 1019 | |||
| 1020 | if (FAILED(hr)) | ||
| 1021 | { | ||
| 1022 | er = ERROR_INSTALL_FAILURE; | ||
| 1023 | } | ||
| 1024 | return WcaFinalize(er); | ||
| 1025 | } | ||
