aboutsummaryrefslogtreecommitdiff
path: root/src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp')
-rw-r--r--src/libs/wcautil/WixToolset.WcaUtil/wcautil.cpp243
1 files changed, 243 insertions, 0 deletions
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 @@
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
3#include "precomp.h"
4
5// globals
6HMODULE g_hInstCADLL;
7
8// statics
9static BOOL s_fInitialized;
10static MSIHANDLE s_hInstall;
11static MSIHANDLE s_hDatabase;
12static char s_szCustomActionLogName[32];
13static UINT s_iRetVal;
14
15static void CALLBACK WcaTraceError(
16 __in_z LPCSTR szFile,
17 __in int iLine,
18 __in REPORT_LEVEL rl,
19 __in UINT source,
20 __in HRESULT hrError,
21 __in_z __format_string LPCSTR szFormat,
22 __in va_list args
23 );
24
25/********************************************************************
26 WcaGlobalInitialize() - initializes the Wca library, should be
27 called once per custom action Dll during
28 DllMain on DLL_PROCESS_ATTACH
29
30********************************************************************/
31extern "C" void WIXAPI WcaGlobalInitialize(
32 __in HINSTANCE hInst
33 )
34{
35 g_hInstCADLL = hInst;
36 DutilInitialize(&WcaTraceError);
37 MemInitialize();
38
39 AssertSetModule(g_hInstCADLL);
40 AssertSetDisplayFunction(WcaDisplayAssert);
41}
42
43
44/********************************************************************
45 WcaGlobalFinalize() - finalizes the Wca library, should be the
46 called once per custom action Dll during
47 DllMain on DLL_PROCESS_DETACH
48
49********************************************************************/
50extern "C" void WIXAPI WcaGlobalFinalize()
51{
52#ifdef DEBUG
53 if (WcaIsInitialized())
54 {
55 CHAR szBuf[2048];
56 StringCchPrintfA(szBuf, countof(szBuf), "CustomAction %s called WcaInitialize() but not WcaFinalize()", WcaGetLogName());
57
58 AssertSz(FALSE, szBuf);
59 }
60#endif
61 MemUninitialize();
62 DutilUninitialize();
63 g_hInstCADLL = NULL;
64}
65
66
67/********************************************************************
68 WcaInitialize() - initializes the Wca framework, should be the first
69 thing called by all CustomActions
70
71********************************************************************/
72extern "C" HRESULT WIXAPI WcaInitialize(
73 __in MSIHANDLE hInstall,
74 __in_z PCSTR szCustomActionLogName
75 )
76{
77 WCHAR wzCAFileName[MAX_PATH] = {0};
78 DWORD dwMajorVersion = 0;
79 DWORD dwMinorVersion = 0;
80
81 // these statics should be called once per CustomAction invocation.
82 // Darwin does doesn't preserve DLL state across CustomAction calls so
83 // these should always be initialized to NULL. If that behavior changes
84 // we would need to do a careful review of all of our module/global data.
85 AssertSz(!s_fInitialized, "WcaInitialize() should only be called once per CustomAction");
86 Assert(NULL == s_hInstall);
87 Assert(NULL == s_hDatabase);
88 Assert(0 == *s_szCustomActionLogName);
89
90 HRESULT hr = S_OK;
91
92 s_fInitialized = TRUE;
93 s_iRetVal = ERROR_SUCCESS; // assume all will go well
94
95 s_hInstall = hInstall;
96 s_hDatabase = ::MsiGetActiveDatabase(s_hInstall); // may return null if deferred CustomAction
97
98 hr = ::StringCchCopy(s_szCustomActionLogName, countof(s_szCustomActionLogName), szCustomActionLogName);
99 ExitOnFailure(hr, "Failed to copy CustomAction log name: %s", szCustomActionLogName);
100
101 // If we got the database handle IE: immediate CA
102 if (s_hDatabase)
103 {
104 hr = SetVerboseLoggingAtom(IsVerboseLogging());
105 ExitOnFailure(hr, "Failed to set verbose logging global atom");
106 }
107
108 if (!::GetModuleFileNameW(g_hInstCADLL, wzCAFileName, countof(wzCAFileName)))
109 {
110 ExitWithLastError(hr, "Failed to get module filename");
111 }
112
113 FileVersion(wzCAFileName, &dwMajorVersion, &dwMinorVersion); // Ignore failure, just log 0.0.0.0
114
115 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));
116
117 Assert(s_hInstall);
118LExit:
119 if (FAILED(hr))
120 {
121 if (s_hDatabase)
122 {
123 ::MsiCloseHandle(s_hDatabase);
124 s_hDatabase = NULL;
125 }
126
127 s_hInstall = NULL;
128 s_fInitialized = FALSE;
129 }
130
131 return hr;
132}
133
134
135/********************************************************************
136 WcaFinalize() - cleans up after the Wca framework, should be the last
137 thing called by all CustomActions
138
139********************************************************************/
140extern "C" UINT WIXAPI WcaFinalize(
141 __in UINT iReturnValue
142 )
143{
144 AssertSz(!WcaIsWow64Initialized(), "WcaFinalizeWow64() should be called before calling WcaFinalize()");
145
146 // clean up after our initialization
147 if (s_hDatabase)
148 {
149 ::MsiCloseHandle(s_hDatabase);
150 s_hDatabase = NULL;
151 }
152
153 s_hInstall = NULL;
154 s_fInitialized = FALSE;
155
156 // if no error occurred during the processing of the CusotmAction return the passed in return value
157 // otherwise return the previous failure
158 return (ERROR_SUCCESS == s_iRetVal) ? iReturnValue : s_iRetVal;
159}
160
161
162/********************************************************************
163 WcaIsInitialized() - determines if WcaInitialize() has been called
164
165********************************************************************/
166extern "C" BOOL WIXAPI WcaIsInitialized()
167{
168 return s_fInitialized;
169}
170
171
172/********************************************************************
173 WcaGetInstallHandle() - gets the handle to the active install session
174
175********************************************************************/
176extern "C" MSIHANDLE WIXAPI WcaGetInstallHandle()
177{
178 AssertSz(s_hInstall, "WcaInitialize() should be called before attempting to access the install handle.");
179 return s_hInstall;
180}
181
182
183/********************************************************************
184 WcaGetDatabaseHandle() - gets the handle to the active database
185
186 NOTE: this function can only be used in immediate CustomActions.
187 Deferred CustomActions do not have access to the active
188 database.
189********************************************************************/
190extern "C" MSIHANDLE WIXAPI WcaGetDatabaseHandle()
191{
192 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.");
193 return s_hDatabase;
194}
195
196
197/********************************************************************
198 WcaGetLogName() - gets the name of the CustomAction used in logging
199
200********************************************************************/
201extern "C" const char* WIXAPI WcaGetLogName()
202{
203 return s_szCustomActionLogName;
204}
205
206
207/********************************************************************
208 WcaSetReturnValue() - sets the value to return from the CustomAction
209
210********************************************************************/
211extern "C" void WIXAPI WcaSetReturnValue(
212 __in UINT iReturnValue
213 )
214{
215 s_iRetVal = iReturnValue;
216}
217
218
219/********************************************************************
220 WcaCancelDetected() - determines if the user has canceled yet
221
222 NOTE: returns true when WcaSetReturnValue() is set to ERROR_INSTALL_USEREXIT
223********************************************************************/
224extern "C" BOOL WIXAPI WcaCancelDetected()
225{
226 return ERROR_INSTALL_USEREXIT == s_iRetVal;
227}
228
229static void CALLBACK WcaTraceError(
230 __in_z LPCSTR /*szFile*/,
231 __in int /*iLine*/,
232 __in REPORT_LEVEL /*rl*/,
233 __in UINT source,
234 __in HRESULT hrError,
235 __in_z __format_string LPCSTR szFormat,
236 __in va_list args
237 )
238{
239 if (DUTIL_SOURCE_DEFAULT == source)
240 {
241 WcaLogErrorArgs(hrError, szFormat, args);
242 }
243}