From 30827588eb0c189b7e2d04693d116080d333200e Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 22 Apr 2021 15:43:19 -0700 Subject: Move wcautil into libs/wcautil --- src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp | 243 ++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp (limited to 'src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp') diff --git a/src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp b/src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp new file mode 100644 index 00000000..11867d10 --- /dev/null +++ b/src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp @@ -0,0 +1,243 @@ +// 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. + +#include "precomp.h" + +// globals +HMODULE g_hInstCADLL; + +// statics +static BOOL s_fInitialized; +static MSIHANDLE s_hInstall; +static MSIHANDLE s_hDatabase; +static char s_szCustomActionLogName[32]; +static UINT s_iRetVal; + +static void CALLBACK WcaTraceError( + __in_z LPCSTR szFile, + __in int iLine, + __in REPORT_LEVEL rl, + __in UINT source, + __in HRESULT hrError, + __in_z __format_string LPCSTR szFormat, + __in va_list args + ); + +/******************************************************************** + WcaGlobalInitialize() - initializes the Wca library, should be + called once per custom action Dll during + DllMain on DLL_PROCESS_ATTACH + +********************************************************************/ +extern "C" void WIXAPI WcaGlobalInitialize( + __in HINSTANCE hInst + ) +{ + g_hInstCADLL = hInst; + DutilInitialize(&WcaTraceError); + MemInitialize(); + + AssertSetModule(g_hInstCADLL); + AssertSetDisplayFunction(WcaDisplayAssert); +} + + +/******************************************************************** + WcaGlobalFinalize() - finalizes the Wca library, should be the + called once per custom action Dll during + DllMain on DLL_PROCESS_DETACH + +********************************************************************/ +extern "C" void WIXAPI WcaGlobalFinalize() +{ +#ifdef DEBUG + if (WcaIsInitialized()) + { + CHAR szBuf[2048]; + StringCchPrintfA(szBuf, countof(szBuf), "CustomAction %s called WcaInitialize() but not WcaFinalize()", WcaGetLogName()); + + AssertSz(FALSE, szBuf); + } +#endif + MemUninitialize(); + DutilUninitialize(); + g_hInstCADLL = NULL; +} + + +/******************************************************************** + WcaInitialize() - initializes the Wca framework, should be the first + thing called by all CustomActions + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaInitialize( + __in MSIHANDLE hInstall, + __in_z PCSTR szCustomActionLogName + ) +{ + WCHAR wzCAFileName[MAX_PATH] = {0}; + DWORD dwMajorVersion = 0; + DWORD dwMinorVersion = 0; + + // these statics should be called once per CustomAction invocation. + // Darwin does doesn't preserve DLL state across CustomAction calls so + // these should always be initialized to NULL. If that behavior changes + // we would need to do a careful review of all of our module/global data. + AssertSz(!s_fInitialized, "WcaInitialize() should only be called once per CustomAction"); + Assert(NULL == s_hInstall); + Assert(NULL == s_hDatabase); + Assert(0 == *s_szCustomActionLogName); + + HRESULT hr = S_OK; + + s_fInitialized = TRUE; + s_iRetVal = ERROR_SUCCESS; // assume all will go well + + s_hInstall = hInstall; + s_hDatabase = ::MsiGetActiveDatabase(s_hInstall); // may return null if deferred CustomAction + + hr = ::StringCchCopy(s_szCustomActionLogName, countof(s_szCustomActionLogName), szCustomActionLogName); + ExitOnFailure(hr, "Failed to copy CustomAction log name: %s", szCustomActionLogName); + + // If we got the database handle IE: immediate CA + if (s_hDatabase) + { + hr = SetVerboseLoggingAtom(IsVerboseLogging()); + ExitOnFailure(hr, "Failed to set verbose logging global atom"); + } + + if (!::GetModuleFileNameW(g_hInstCADLL, wzCAFileName, countof(wzCAFileName))) + { + ExitWithLastError(hr, "Failed to get module filename"); + } + + FileVersion(wzCAFileName, &dwMajorVersion, &dwMinorVersion); // Ignore failure, just log 0.0.0.0 + + WcaLog(LOGMSG_VERBOSE, "Entering %s in %ls, version %u.%u.%u.%u", szCustomActionLogName, wzCAFileName, (DWORD)HIWORD(dwMajorVersion), (DWORD)LOWORD(dwMajorVersion), (DWORD)HIWORD(dwMinorVersion), (DWORD)LOWORD(dwMinorVersion)); + + Assert(s_hInstall); +LExit: + if (FAILED(hr)) + { + if (s_hDatabase) + { + ::MsiCloseHandle(s_hDatabase); + s_hDatabase = NULL; + } + + s_hInstall = NULL; + s_fInitialized = FALSE; + } + + return hr; +} + + +/******************************************************************** + WcaFinalize() - cleans up after the Wca framework, should be the last + thing called by all CustomActions + +********************************************************************/ +extern "C" UINT WIXAPI WcaFinalize( + __in UINT iReturnValue + ) +{ + AssertSz(!WcaIsWow64Initialized(), "WcaFinalizeWow64() should be called before calling WcaFinalize()"); + + // clean up after our initialization + if (s_hDatabase) + { + ::MsiCloseHandle(s_hDatabase); + s_hDatabase = NULL; + } + + s_hInstall = NULL; + s_fInitialized = FALSE; + + // if no error occurred during the processing of the CusotmAction return the passed in return value + // otherwise return the previous failure + return (ERROR_SUCCESS == s_iRetVal) ? iReturnValue : s_iRetVal; +} + + +/******************************************************************** + WcaIsInitialized() - determines if WcaInitialize() has been called + +********************************************************************/ +extern "C" BOOL WIXAPI WcaIsInitialized() +{ + return s_fInitialized; +} + + +/******************************************************************** + WcaGetInstallHandle() - gets the handle to the active install session + +********************************************************************/ +extern "C" MSIHANDLE WIXAPI WcaGetInstallHandle() +{ + AssertSz(s_hInstall, "WcaInitialize() should be called before attempting to access the install handle."); + return s_hInstall; +} + + +/******************************************************************** + WcaGetDatabaseHandle() - gets the handle to the active database + + NOTE: this function can only be used in immediate CustomActions. + Deferred CustomActions do not have access to the active + database. +********************************************************************/ +extern "C" MSIHANDLE WIXAPI WcaGetDatabaseHandle() +{ + AssertSz(s_hDatabase, "WcaInitialize() should be called before attempting to access the install handle. Also note that deferred CustomActions do not have access to the active database."); + return s_hDatabase; +} + + +/******************************************************************** + WcaGetLogName() - gets the name of the CustomAction used in logging + +********************************************************************/ +extern "C" const char* WIXAPI WcaGetLogName() +{ + return s_szCustomActionLogName; +} + + +/******************************************************************** + WcaSetReturnValue() - sets the value to return from the CustomAction + +********************************************************************/ +extern "C" void WIXAPI WcaSetReturnValue( + __in UINT iReturnValue + ) +{ + s_iRetVal = iReturnValue; +} + + +/******************************************************************** + WcaCancelDetected() - determines if the user has canceled yet + + NOTE: returns true when WcaSetReturnValue() is set to ERROR_INSTALL_USEREXIT +********************************************************************/ +extern "C" BOOL WIXAPI WcaCancelDetected() +{ + return ERROR_INSTALL_USEREXIT == s_iRetVal; +} + +static void CALLBACK WcaTraceError( + __in_z LPCSTR /*szFile*/, + __in int /*iLine*/, + __in REPORT_LEVEL /*rl*/, + __in UINT source, + __in HRESULT hrError, + __in_z __format_string LPCSTR szFormat, + __in va_list args + ) +{ + if (DUTIL_SOURCE_DEFAULT == source) + { + WcaLogErrorArgs(hrError, szFormat, args); + } +} -- cgit v1.2.3-55-g6feb