Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/installer-ca/wcautil.cpp

Issue 11521026: initial custom action library, "hello, world" quality (Closed)
Patch Set: Created Sept. 3, 2013, 12:48 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/installer-ca/wcautil.cpp
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/installer-ca/wcautil.cpp
@@ -0,0 +1,227 @@
+//-------------------------------------------------------------------------------------------------
+// <copyright file="wcautil.cpp" company="Outercurve Foundation">
+// Copyright (c) 2004, Outercurve Foundation.
+// This software is released under Microsoft Reciprocal License (MS-RL).
+// The license and further copyright text can be found in the file
+// LICENSE.TXT at the root directory of the distribution.
+// </copyright>
+//
+// <summary>
+// Windows Installer XML CustomAction utility library.
+// </summary>
+//-------------------------------------------------------------------------------------------------
+
+#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;
+
+
+/********************************************************************
+ 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;
+ 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();
+ 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 = ::StringCchCopyA(s_szCustomActionLogName, countof(s_szCustomActionLogName), szCustomActionLogName);
+ ExitOnFailure1(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;
+}

Powered by Google App Engine
This is Rietveld