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