aboutsummaryrefslogtreecommitdiff
path: root/src/ca/scaexec.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2018-12-16 13:53:48 -0600
committerSean Hall <r.sean.hall@gmail.com>2018-12-16 13:54:52 -0600
commit7d813eaad8eaca04a687d1bb942316232d1c54fd (patch)
tree8f5adb9da22b1f9fb79892fb6cf2de23fac32c71 /src/ca/scaexec.cpp
parent1b7a9d3734119e658c91ebd9742ab5a3ce94cce4 (diff)
downloadwix-7d813eaad8eaca04a687d1bb942316232d1c54fd.tar.gz
wix-7d813eaad8eaca04a687d1bb942316232d1c54fd.tar.bz2
wix-7d813eaad8eaca04a687d1bb942316232d1c54fd.zip
Import implementation of SqlCA from old repo's scasched/scaexec.
Diffstat (limited to 'src/ca/scaexec.cpp')
-rw-r--r--src/ca/scaexec.cpp393
1 files changed, 393 insertions, 0 deletions
diff --git a/src/ca/scaexec.cpp b/src/ca/scaexec.cpp
new file mode 100644
index 00000000..7a30f52a
--- /dev/null
+++ b/src/ca/scaexec.cpp
@@ -0,0 +1,393 @@
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
6/********************************************************************
7 * CreateDatabase - CUSTOM ACTION ENTRY POINT for creating databases
8 *
9 * Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword
10 * ****************************************************************/
11extern "C" UINT __stdcall CreateDatabase(MSIHANDLE hInstall)
12{
13//AssertSz(FALSE, "debug CreateDatabase here");
14 UINT er = ERROR_SUCCESS;
15 HRESULT hr = S_OK;
16
17 LPWSTR pwzData = NULL;
18 IDBCreateSession* pidbSession = NULL;
19 BSTR bstrErrorDescription = NULL;
20 LPWSTR pwz = NULL;
21 LPWSTR pwzDatabaseKey = NULL;
22 LPWSTR pwzServer = NULL;
23 LPWSTR pwzInstance = NULL;
24 LPWSTR pwzDatabase = NULL;
25 LPWSTR pwzTemp = NULL;
26 int iAttributes;
27 BOOL fIntegratedAuth;
28 LPWSTR pwzUser = NULL;
29 LPWSTR pwzPassword = NULL;
30 BOOL fHaveDbFileSpec = FALSE;
31 SQL_FILESPEC sfDb;
32 BOOL fHaveLogFileSpec = FALSE;
33 SQL_FILESPEC sfLog;
34 BOOL fInitializedCom = FALSE;
35
36 memset(&sfDb, 0, sizeof(sfDb));
37 memset(&sfLog, 0, sizeof(sfLog));
38
39 hr = WcaInitialize(hInstall, "CreateDatabase");
40 ExitOnFailure(hr, "failed to initialize");
41
42 hr = ::CoInitialize(NULL);
43 ExitOnFailure(hr, "failed to intialize COM");
44 fInitializedCom = TRUE;
45
46 hr = WcaGetProperty( L"CustomActionData", &pwzData);
47 ExitOnFailure(hr, "failed to get CustomActionData");
48
49 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData);
50
51 pwz = pwzData;
52 hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey); // SQL Server
53 ExitOnFailure(hr, "failed to read database key from custom action data: %ls", pwz);
54 hr = WcaReadStringFromCaData(&pwz, &pwzServer); // SQL Server
55 ExitOnFailure(hr, "failed to read server from custom action data: %ls", pwz);
56 hr = WcaReadStringFromCaData(&pwz, &pwzInstance); // SQL Server Instance
57 ExitOnFailure(hr, "failed to read server instance from custom action data: %ls", pwz);
58 hr = WcaReadStringFromCaData(&pwz, &pwzDatabase); // SQL Database
59 ExitOnFailure(hr, "failed to read server instance from custom action data: %ls", pwz);
60 hr = WcaReadIntegerFromCaData(&pwz, &iAttributes);
61 ExitOnFailure(hr, "failed to read attributes from custom action data: %ls", pwz);
62 hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int *>(&fIntegratedAuth)); // Integrated Windows Authentication?
63 ExitOnFailure(hr, "failed to read integrated auth flag from custom action data: %ls", pwz);
64 hr = WcaReadStringFromCaData(&pwz, &pwzUser); // SQL User
65 ExitOnFailure(hr, "failed to read user from custom action data: %ls", pwz);
66 hr = WcaReadStringFromCaData(&pwz, &pwzPassword); // SQL User Password
67 ExitOnFailure(hr, "failed to read user from custom action data: %ls", pwz);
68
69 // db file spec
70 hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int *>(&fHaveDbFileSpec));
71 ExitOnFailure(hr, "failed to read db file spec from custom action data: %ls", pwz);
72
73 if (fHaveDbFileSpec)
74 {
75 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
76 ExitOnFailure(hr, "failed to read db file spec name from custom action data: %ls", pwz);
77 hr = ::StringCchCopyW(sfDb.wzName, countof(sfDb.wzName), pwzTemp);
78 ExitOnFailure(hr, "failed to copy db file spec name: %ls", pwzTemp);
79
80 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
81 ExitOnFailure(hr, "failed to read db file spec filename from custom action data: %ls", pwz);
82 hr = ::StringCchCopyW(sfDb.wzFilename, countof(sfDb.wzFilename), pwzTemp);
83 ExitOnFailure(hr, "failed to copy db file spec filename: %ls", pwzTemp);
84
85 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
86 ExitOnFailure(hr, "failed to read db file spec size from custom action data: %ls", pwz);
87 hr = ::StringCchCopyW(sfDb.wzSize, countof(sfDb.wzSize), pwzTemp);
88 ExitOnFailure(hr, "failed to copy db file spec size value: %ls", pwzTemp);
89
90 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
91 ExitOnFailure(hr, "failed to read db file spec max size from custom action data: %ls", pwz);
92 hr = ::StringCchCopyW(sfDb.wzMaxSize, countof(sfDb.wzMaxSize), pwzTemp);
93 ExitOnFailure(hr, "failed to copy db file spec max size: %ls", pwzTemp);
94
95 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
96 ExitOnFailure(hr, "failed to read db file spec grow from custom action data: %ls", pwz);
97 hr = ::StringCchCopyW(sfDb.wzGrow, countof(sfDb.wzGrow), pwzTemp);
98 ExitOnFailure(hr, "failed to copy db file spec grow value: %ls", pwzTemp);
99 }
100
101 // log file spec
102 hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int *>(&fHaveLogFileSpec));
103 ExitOnFailure(hr, "failed to read log file spec from custom action data: %ls", pwz);
104 if (fHaveLogFileSpec)
105 {
106 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
107 ExitOnFailure(hr, "failed to read log file spec name from custom action data: %ls", pwz);
108 hr = ::StringCchCopyW(sfLog.wzName, countof(sfDb.wzName), pwzTemp);
109 ExitOnFailure(hr, "failed to copy log file spec name: %ls", pwzTemp);
110
111 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
112 ExitOnFailure(hr, "failed to read log file spec filename from custom action data: %ls", pwz);
113 hr = ::StringCchCopyW(sfLog.wzFilename, countof(sfDb.wzFilename), pwzTemp);
114 ExitOnFailure(hr, "failed to copy log file spec filename: %ls", pwzTemp);
115
116 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
117 ExitOnFailure(hr, "failed to read log file spec size from custom action data: %ls", pwz);
118 hr = ::StringCchCopyW(sfLog.wzSize, countof(sfDb.wzSize), pwzTemp);
119 ExitOnFailure(hr, "failed to copy log file spec size value: %ls", pwzTemp);
120
121 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
122 ExitOnFailure(hr, "failed to read log file spec max size from custom action data: %ls", pwz);
123 hr = ::StringCchCopyW(sfLog.wzMaxSize, countof(sfDb.wzMaxSize), pwzTemp);
124 ExitOnFailure(hr, "failed to copy log file spec max size: %ls", pwzTemp);
125
126 hr = WcaReadStringFromCaData(&pwz, &pwzTemp);
127 ExitOnFailure(hr, "failed to read log file spec grow from custom action data: %ls", pwz);
128 hr = ::StringCchCopyW(sfLog.wzGrow, countof(sfDb.wzGrow), pwzTemp);
129 ExitOnFailure(hr, "failed to copy log file spec grow value: %ls", pwzTemp);
130 }
131
132 if (iAttributes & SCADB_CONFIRM_OVERWRITE)
133 {
134 // Check if the database already exists
135 hr = SqlDatabaseExists(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &bstrErrorDescription);
136 MessageExitOnFailure(hr, msierrSQLFailedCreateDatabase, "failed to check if database exists: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription);
137
138 if (S_OK == hr) // found an existing database, confirm that they don't want to stop before it gets trampled, in no UI case just continue anyways
139 {
140 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
141 if (IDNO == WcaErrorMessage(msierrSQLDatabaseAlreadyExists, hr, MB_YESNO, 1, pwzDatabase))
142 ExitOnFailure(hr, "failed to initialize");
143 }
144 }
145
146 hr = SqlDatabaseEnsureExists(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, fHaveDbFileSpec ? &sfDb : NULL, fHaveLogFileSpec ? &sfLog : NULL, &bstrErrorDescription);
147 if ((iAttributes & SCADB_CONTINUE_ON_ERROR) && FAILED(hr))
148 {
149 WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to create SQL database but continuing, error: %ls, Database: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzDatabase);
150 hr = S_OK;
151 }
152 MessageExitOnFailure(hr, msierrSQLFailedCreateDatabase, "failed to create to database: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription);
153
154 hr = WcaProgressMessage(COST_SQL_CONNECTDB, FALSE);
155LExit:
156 ReleaseStr(pwzDatabaseKey);
157 ReleaseStr(pwzServer);
158 ReleaseStr(pwzInstance);
159 ReleaseStr(pwzDatabase);
160 ReleaseStr(pwzUser);
161 ReleaseStr(pwzPassword);
162 ReleaseObject(pidbSession);
163 ReleaseBSTR(bstrErrorDescription);
164
165 if (fInitializedCom)
166 {
167 ::CoUninitialize();
168 }
169
170 if (FAILED(hr))
171 {
172 er = ERROR_INSTALL_FAILURE;
173 }
174 return WcaFinalize(er);
175}
176
177
178/********************************************************************
179 DropDatabase - CUSTOM ACTION ENTRY POINT for removing databases
180
181 Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword
182 * ****************************************************************/
183extern "C" UINT __stdcall DropDatabase(MSIHANDLE hInstall)
184{
185//Assert(FALSE);
186 UINT er = ERROR_SUCCESS;
187 HRESULT hr = S_OK;
188
189 LPWSTR pwzData = NULL;
190 IDBCreateSession* pidbSession = NULL;
191 BSTR bstrErrorDescription = NULL;
192 LPWSTR pwz = NULL;
193 LPWSTR pwzDatabaseKey = NULL;
194 LPWSTR pwzServer = NULL;
195 LPWSTR pwzInstance = NULL;
196 LPWSTR pwzDatabase = NULL;
197 long lAttributes;
198 BOOL fIntegratedAuth;
199 LPWSTR pwzUser = NULL;
200 LPWSTR pwzPassword = NULL;
201 BOOL fInitializedCom = TRUE;
202
203 hr = WcaInitialize(hInstall, "DropDatabase");
204 ExitOnFailure(hr, "failed to initialize");
205
206 hr = ::CoInitialize(NULL);
207 ExitOnFailure(hr, "failed to intialize COM");
208 fInitializedCom = TRUE;
209
210 hr = WcaGetProperty( L"CustomActionData", &pwzData);
211 ExitOnFailure(hr, "failed to get CustomActionData");
212
213 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData);
214
215 pwz = pwzData;
216 hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey);
217 ExitOnFailure(hr, "failed to read database key");
218 hr = WcaReadStringFromCaData(&pwz, &pwzServer);
219 ExitOnFailure(hr, "failed to read server");
220 hr = WcaReadStringFromCaData(&pwz, &pwzInstance);
221 ExitOnFailure(hr, "failed to read instance");
222 hr = WcaReadStringFromCaData(&pwz, &pwzDatabase);
223 ExitOnFailure(hr, "failed to read database");
224 hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int *>(&lAttributes));
225 ExitOnFailure(hr, "failed to read attributes");
226 hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int *>(&fIntegratedAuth)); // Integrated Windows Authentication?
227 ExitOnFailure(hr, "failed to read integrated auth flag");
228 hr = WcaReadStringFromCaData(&pwz, &pwzUser);
229 ExitOnFailure(hr, "failed to read user");
230 hr = WcaReadStringFromCaData(&pwz, &pwzPassword);
231 ExitOnFailure(hr, "failed to read password");
232
233 hr = SqlDropDatabase(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &bstrErrorDescription);
234 if ((lAttributes & SCADB_CONTINUE_ON_ERROR) && FAILED(hr))
235 {
236 WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to drop SQL database but continuing, error: %ls, Database: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzDatabase);
237 hr = S_OK;
238 }
239 MessageExitOnFailure(hr, msierrSQLFailedDropDatabase, "failed to drop to database: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription);
240
241 hr = WcaProgressMessage(COST_SQL_CONNECTDB, FALSE);
242
243LExit:
244 ReleaseStr(pwzDatabaseKey);
245 ReleaseStr(pwzServer);
246 ReleaseStr(pwzInstance);
247 ReleaseStr(pwzDatabase);
248 ReleaseStr(pwzUser);
249 ReleaseStr(pwzPassword);
250 ReleaseStr(pwzData);
251 ReleaseObject(pidbSession);
252 ReleaseBSTR(bstrErrorDescription);
253
254 if (fInitializedCom)
255 {
256 ::CoUninitialize();
257 }
258
259 if (FAILED(hr))
260 {
261 er = ERROR_INSTALL_FAILURE;
262 }
263 return WcaFinalize(er);
264}
265
266
267/********************************************************************
268 ExecuteSqlStrings - CUSTOM ACTION ENTRY POINT for running SQL strings
269
270 Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword\tSQLKey1\tSQLString1\tSQLKey2\tSQLString2\tSQLKey3\tSQLString3\t...
271 rollback CustomActionData - same as above
272 * ****************************************************************/
273extern "C" UINT __stdcall ExecuteSqlStrings(MSIHANDLE hInstall)
274{
275//Assert(FALSE);
276 UINT er = ERROR_SUCCESS;
277 HRESULT hr = S_OK;
278 HRESULT hrDB = S_OK;
279
280 LPWSTR pwzData = NULL;
281 IDBCreateSession* pidbSession = NULL;
282 BSTR bstrErrorDescription = NULL;
283
284 LPWSTR pwz = NULL;
285 LPWSTR pwzDatabaseKey = NULL;
286 LPWSTR pwzServer = NULL;
287 LPWSTR pwzInstance = NULL;
288 LPWSTR pwzDatabase = NULL;
289 int iAttributesDB;
290 int iAttributesSQL;
291 BOOL fIntegratedAuth;
292 LPWSTR pwzUser = NULL;
293 LPWSTR pwzPassword = NULL;
294 LPWSTR pwzSqlKey = NULL;
295 LPWSTR pwzSql = NULL;
296 BOOL fInitializedCom = FALSE;
297
298 hr = WcaInitialize(hInstall, "ExecuteSqlStrings");
299 ExitOnFailure(hr, "failed to initialize");
300
301 hr = ::CoInitialize(NULL);
302 ExitOnFailure(hr, "failed to intialize COM");
303 fInitializedCom = TRUE;
304
305 hr = WcaGetProperty( L"CustomActionData", &pwzData);
306 ExitOnFailure(hr, "failed to get CustomActionData");
307
308 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData);
309
310 pwz = pwzData;
311 hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey);
312 ExitOnFailure(hr, "failed to read database key");
313 hr = WcaReadStringFromCaData(&pwz, &pwzServer);
314 ExitOnFailure(hr, "failed to read server");
315 hr = WcaReadStringFromCaData(&pwz, &pwzInstance);
316 ExitOnFailure(hr, "failed to read instance");
317 hr = WcaReadStringFromCaData(&pwz, &pwzDatabase);
318 ExitOnFailure(hr, "failed to read database");
319 hr = WcaReadIntegerFromCaData(&pwz, &iAttributesDB);
320 ExitOnFailure(hr, "failed to read attributes");
321 hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int *>(&fIntegratedAuth)); // Integrated Windows Authentication?
322 ExitOnFailure(hr, "failed to read integrated auth flag");
323 hr = WcaReadStringFromCaData(&pwz, &pwzUser);
324 ExitOnFailure(hr, "failed to read user");
325 hr = WcaReadStringFromCaData(&pwz, &pwzPassword);
326 ExitOnFailure(hr, "failed to read password");
327
328 // Store off the result of the connect, only exit if we don't care if the database connection succeeds
329 // Wait to fail until later to see if we actually have work to do that is not set to continue on error
330 hrDB = SqlConnectDatabase(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &pidbSession);
331 if ((iAttributesDB & SCADB_CONTINUE_ON_ERROR) && FAILED(hrDB))
332 {
333 WcaLog(LOGMSG_STANDARD, "Error 0x%x: continuing after failure to connect to database: %ls", hrDB, pwzDatabase);
334 ExitFunction1(hr = S_OK);
335 }
336
337 while (S_OK == hr && S_OK == (hr = WcaReadStringFromCaData(&pwz, &pwzSqlKey)))
338 {
339 hr = WcaReadIntegerFromCaData(&pwz, &iAttributesSQL);
340 ExitOnFailure(hr, "failed to read attributes for SQL string: %ls", pwzSqlKey);
341
342 hr = WcaReadStringFromCaData(&pwz, &pwzSql);
343 ExitOnFailure(hr, "failed to read SQL string for key: %ls", pwzSqlKey);
344
345 // If the SqlString row is set to continue on error and the DB connection failed, skip attempting to execute
346 if ((iAttributesSQL & SCASQL_CONTINUE_ON_ERROR) && FAILED(hrDB))
347 {
348 WcaLog(LOGMSG_STANDARD, "Error 0x%x: continuing after failure to connect to database: %ls", hrDB, pwzDatabase);
349 continue;
350 }
351
352 // Now check if the DB connection succeeded
353 MessageExitOnFailure(hr = hrDB, msierrSQLFailedConnectDatabase, "failed to connect to database: '%ls'", pwzDatabase);
354
355 WcaLog(LOGMSG_VERBOSE, "Executing SQL string: %ls", pwzSql);
356 hr = SqlSessionExecuteQuery(pidbSession, pwzSql, NULL, NULL, &bstrErrorDescription);
357 if ((iAttributesSQL & SCASQL_CONTINUE_ON_ERROR) && FAILED(hr))
358 {
359 WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to execute SQL string but continuing, error: %ls, SQL key: %ls SQL string: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzSqlKey, pwzSql);
360 hr = S_OK;
361 }
362 MessageExitOnFailure(hr, msierrSQLFailedExecString, "failed to execute SQL string, error: %ls, SQL key: %ls SQL string: %ls", NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzSqlKey, pwzSql);
363
364 WcaProgressMessage(COST_SQL_STRING, FALSE);
365 }
366 if (E_NOMOREITEMS == hr)
367 {
368 hr = S_OK;
369 }
370
371LExit:
372 ReleaseStr(pwzDatabaseKey);
373 ReleaseStr(pwzServer);
374 ReleaseStr(pwzInstance);
375 ReleaseStr(pwzDatabase);
376 ReleaseStr(pwzUser);
377 ReleaseStr(pwzPassword);
378 ReleaseStr(pwzData);
379
380 ReleaseBSTR(bstrErrorDescription);
381 ReleaseObject(pidbSession);
382
383 if (fInitializedCom)
384 {
385 ::CoUninitialize();
386 }
387
388 if (FAILED(hr))
389 {
390 er = ERROR_INSTALL_FAILURE;
391 }
392 return WcaFinalize(er);
393}