diff options
author | Rob Mensching <rob@firegiant.com> | 2021-04-22 17:06:54 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-04-29 16:36:06 -0700 |
commit | af10c45d7b3a44af0b461a557847fe03263dcc10 (patch) | |
tree | 6a5c1532304782c36ffe4200b38f3afb76789a43 /src/burn/engine/logging.cpp | |
parent | 9c2aed97299fb96aeee3f1471ce40225437aaecf (diff) | |
download | wix-af10c45d7b3a44af0b461a557847fe03263dcc10.tar.gz wix-af10c45d7b3a44af0b461a557847fe03263dcc10.tar.bz2 wix-af10c45d7b3a44af0b461a557847fe03263dcc10.zip |
Move burn into burn
Diffstat (limited to 'src/burn/engine/logging.cpp')
-rw-r--r-- | src/burn/engine/logging.cpp | 754 |
1 files changed, 754 insertions, 0 deletions
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp new file mode 100644 index 00000000..065ef907 --- /dev/null +++ b/src/burn/engine/logging.cpp | |||
@@ -0,0 +1,754 @@ | |||
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 | static DWORD vdwPackageSequence = 0; | ||
7 | static const DWORD LOG_OPEN_RETRY_COUNT = 3; | ||
8 | static const DWORD LOG_OPEN_RETRY_WAIT = 2000; | ||
9 | static CONST LPWSTR LOG_FAILED_EVENT_LOG_MESSAGE = L"Burn Engine Fatal Error: failed to open log file."; | ||
10 | |||
11 | // structs | ||
12 | |||
13 | |||
14 | |||
15 | // internal function declarations | ||
16 | |||
17 | static void CheckLoggingPolicy( | ||
18 | __out DWORD *pdwAttributes | ||
19 | ); | ||
20 | static HRESULT GetNonSessionSpecificTempFolder( | ||
21 | __deref_out_z LPWSTR* psczNonSessionTempFolder | ||
22 | ); | ||
23 | |||
24 | |||
25 | // function definitions | ||
26 | |||
27 | extern "C" HRESULT LoggingOpen( | ||
28 | __in BURN_LOGGING* pLog, | ||
29 | __in BURN_VARIABLES* pVariables, | ||
30 | __in BOOTSTRAPPER_DISPLAY display, | ||
31 | __in_z LPCWSTR wzBundleName | ||
32 | ) | ||
33 | { | ||
34 | HRESULT hr = S_OK; | ||
35 | LPWSTR sczLoggingBaseFolder = NULL; | ||
36 | LPWSTR sczPrefixFormatted = NULL; | ||
37 | |||
38 | // Check if the logging policy is set and configure the logging appropriately. | ||
39 | CheckLoggingPolicy(&pLog->dwAttributes); | ||
40 | |||
41 | if (pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_VERBOSE || pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_EXTRADEBUG) | ||
42 | { | ||
43 | if (pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_EXTRADEBUG) | ||
44 | { | ||
45 | LogSetLevel(REPORT_DEBUG, FALSE); | ||
46 | } | ||
47 | else if (pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_VERBOSE) | ||
48 | { | ||
49 | LogSetLevel(REPORT_VERBOSE, FALSE); | ||
50 | } | ||
51 | |||
52 | if ((!pLog->sczPath || !*pLog->sczPath) && (!pLog->sczPrefix || !*pLog->sczPrefix)) | ||
53 | { | ||
54 | PathCreateTimeBasedTempFile(NULL, L"Setup", NULL, L"log", &pLog->sczPath, NULL); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | // Open the log approriately. | ||
59 | if (pLog->sczPath && *pLog->sczPath) | ||
60 | { | ||
61 | DWORD cRetry = 0; | ||
62 | |||
63 | hr = DirGetCurrent(&sczLoggingBaseFolder); | ||
64 | ExitOnFailure(hr, "Failed to get current directory."); | ||
65 | |||
66 | // Try pretty hard to open the log file when appending. | ||
67 | do | ||
68 | { | ||
69 | if (0 < cRetry) | ||
70 | { | ||
71 | ::Sleep(LOG_OPEN_RETRY_WAIT); | ||
72 | } | ||
73 | |||
74 | hr = LogOpen(sczLoggingBaseFolder, pLog->sczPath, NULL, NULL, pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_APPEND, FALSE, &pLog->sczPath); | ||
75 | if (pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_APPEND && HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) == hr) | ||
76 | { | ||
77 | ++cRetry; | ||
78 | } | ||
79 | } while (cRetry > 0 && cRetry <= LOG_OPEN_RETRY_COUNT); | ||
80 | |||
81 | if (FAILED(hr)) | ||
82 | { | ||
83 | // Log is not open, so note that. | ||
84 | LogDisable(); | ||
85 | pLog->state = BURN_LOGGING_STATE_DISABLED; | ||
86 | |||
87 | if (pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_APPEND) | ||
88 | { | ||
89 | // If appending, ignore the failure and continue. | ||
90 | hr = S_OK; | ||
91 | } | ||
92 | else // specifically tried to create a log file so show an error if appropriate and bail. | ||
93 | { | ||
94 | HRESULT hrOriginal = hr; | ||
95 | |||
96 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_LOG_FAILURE); | ||
97 | SplashScreenDisplayError(display, wzBundleName, hr); | ||
98 | |||
99 | ExitOnFailure(hrOriginal, "Failed to open log: %ls", pLog->sczPath); | ||
100 | } | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | pLog->state = BURN_LOGGING_STATE_OPEN; | ||
105 | } | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | if (pLog->sczPrefix && *pLog->sczPrefix) | ||
110 | { | ||
111 | hr = VariableFormatString(pVariables, pLog->sczPrefix, &sczPrefixFormatted, NULL); | ||
112 | } | ||
113 | |||
114 | if (sczPrefixFormatted && *sczPrefixFormatted) | ||
115 | { | ||
116 | LPCWSTR wzPrefix = sczPrefixFormatted; | ||
117 | |||
118 | // Best effort to open default logging. | ||
119 | if (PathIsAbsolute(sczPrefixFormatted)) | ||
120 | { | ||
121 | hr = PathGetDirectory(sczPrefixFormatted, &sczLoggingBaseFolder); | ||
122 | ExitOnFailure(hr, "Failed to get parent directory from '%ls'.", sczPrefixFormatted); | ||
123 | |||
124 | wzPrefix = PathFile(sczPrefixFormatted); | ||
125 | } | ||
126 | else | ||
127 | { | ||
128 | hr = GetNonSessionSpecificTempFolder(&sczLoggingBaseFolder); | ||
129 | ExitOnFailure(hr, "Failed to get non-session specific TEMP folder."); | ||
130 | } | ||
131 | |||
132 | hr = LogOpen(sczLoggingBaseFolder, wzPrefix, NULL, pLog->sczExtension, FALSE, FALSE, &pLog->sczPath); | ||
133 | if (FAILED(hr)) | ||
134 | { | ||
135 | LogDisable(); | ||
136 | pLog->state = BURN_LOGGING_STATE_DISABLED; | ||
137 | |||
138 | hr = S_OK; | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | pLog->state = BURN_LOGGING_STATE_OPEN; | ||
143 | } | ||
144 | } | ||
145 | else // no logging enabled. | ||
146 | { | ||
147 | LogDisable(); | ||
148 | pLog->state = BURN_LOGGING_STATE_DISABLED; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | // If the log was opened, write the header info and update the prefix and extension to match | ||
153 | // the log name so future logs are opened with the same pattern. | ||
154 | if (BURN_LOGGING_STATE_OPEN == pLog->state) | ||
155 | { | ||
156 | LPCWSTR wzExtension = PathExtension(pLog->sczPath); | ||
157 | if (wzExtension && *wzExtension) | ||
158 | { | ||
159 | hr = StrAllocString(&pLog->sczPrefix, pLog->sczPath, wzExtension - pLog->sczPath); | ||
160 | ExitOnFailure(hr, "Failed to copy log path to prefix."); | ||
161 | |||
162 | hr = StrAllocString(&pLog->sczExtension, wzExtension + 1, 0); | ||
163 | ExitOnFailure(hr, "Failed to copy log extension to extension."); | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | hr = StrAllocString(&pLog->sczPrefix, pLog->sczPath, 0); | ||
168 | ExitOnFailure(hr, "Failed to copy full log path to prefix."); | ||
169 | } | ||
170 | |||
171 | if (pLog->sczPathVariable && *pLog->sczPathVariable) | ||
172 | { | ||
173 | VariableSetString(pVariables, pLog->sczPathVariable, pLog->sczPath, FALSE, FALSE); // Ignore failure. | ||
174 | } | ||
175 | } | ||
176 | |||
177 | LExit: | ||
178 | ReleaseStr(sczLoggingBaseFolder); | ||
179 | StrSecureZeroFreeString(sczPrefixFormatted); | ||
180 | |||
181 | return hr; | ||
182 | } | ||
183 | |||
184 | extern "C" void LoggingOpenFailed() | ||
185 | { | ||
186 | HRESULT hr = S_OK; | ||
187 | HANDLE hEventLog = NULL; | ||
188 | LPCWSTR* lpStrings = const_cast<LPCWSTR*>(&LOG_FAILED_EVENT_LOG_MESSAGE); | ||
189 | WORD wNumStrings = 1; | ||
190 | |||
191 | hr = LogOpen(NULL, L"Setup", L"_Failed", L"txt", FALSE, FALSE, NULL); | ||
192 | if (SUCCEEDED(hr)) | ||
193 | { | ||
194 | ExitFunction(); | ||
195 | } | ||
196 | |||
197 | // If opening the "failure" log failed, then attempt to record that in the Application event log. | ||
198 | hEventLog = ::OpenEventLogW(NULL, L"Application"); | ||
199 | ExitOnNullWithLastError(hEventLog, hr, "Failed to open Application event log"); | ||
200 | |||
201 | hr = ::ReportEventW(hEventLog, EVENTLOG_ERROR_TYPE, 1, 1, NULL, wNumStrings, 0, lpStrings, NULL); | ||
202 | ExitOnNullWithLastError(hEventLog, hr, "Failed to write event log entry"); | ||
203 | |||
204 | LExit: | ||
205 | if (hEventLog) | ||
206 | { | ||
207 | ::CloseEventLog(hEventLog); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | extern "C" void LoggingIncrementPackageSequence() | ||
212 | { | ||
213 | ++vdwPackageSequence; | ||
214 | } | ||
215 | |||
216 | extern "C" HRESULT LoggingSetPackageVariable( | ||
217 | __in BURN_PACKAGE* pPackage, | ||
218 | __in_z_opt LPCWSTR wzSuffix, | ||
219 | __in BOOL fRollback, | ||
220 | __in BURN_LOGGING* pLog, | ||
221 | __in BURN_VARIABLES* pVariables, | ||
222 | __out_opt LPWSTR* psczLogPath | ||
223 | ) | ||
224 | { | ||
225 | HRESULT hr = S_OK; | ||
226 | LPWSTR sczLogPath = NULL; | ||
227 | |||
228 | // Make sure that no package log files are created when logging has been disabled via Log element. | ||
229 | if (BURN_LOGGING_STATE_DISABLED == pLog->state) | ||
230 | { | ||
231 | if (psczLogPath) | ||
232 | { | ||
233 | *psczLogPath = NULL; | ||
234 | } | ||
235 | |||
236 | ExitFunction(); | ||
237 | } | ||
238 | |||
239 | if ((!fRollback && pPackage->sczLogPathVariable && *pPackage->sczLogPathVariable) || | ||
240 | (fRollback && pPackage->sczRollbackLogPathVariable && *pPackage->sczRollbackLogPathVariable)) | ||
241 | { | ||
242 | hr = StrAllocFormatted(&sczLogPath, L"%ls%hs%ls_%03u_%ls%ls.%ls", pLog->sczPrefix, wzSuffix && *wzSuffix ? "_" : "", wzSuffix && *wzSuffix ? wzSuffix : L"", vdwPackageSequence, pPackage->sczId, fRollback ? L"_rollback" : L"", pLog->sczExtension); | ||
243 | ExitOnFailure(hr, "Failed to allocate path for package log."); | ||
244 | |||
245 | hr = VariableSetString(pVariables, fRollback ? pPackage->sczRollbackLogPathVariable : pPackage->sczLogPathVariable, sczLogPath, FALSE, FALSE); | ||
246 | ExitOnFailure(hr, "Failed to set log path into variable."); | ||
247 | |||
248 | if (psczLogPath) | ||
249 | { | ||
250 | hr = StrAllocString(psczLogPath, sczLogPath, 0); | ||
251 | ExitOnFailure(hr, "Failed to copy package log path."); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | LExit: | ||
256 | ReleaseStr(sczLogPath); | ||
257 | |||
258 | return hr; | ||
259 | } | ||
260 | |||
261 | extern "C" LPCSTR LoggingBurnActionToString( | ||
262 | __in BOOTSTRAPPER_ACTION action | ||
263 | ) | ||
264 | { | ||
265 | switch (action) | ||
266 | { | ||
267 | case BOOTSTRAPPER_ACTION_UNKNOWN: | ||
268 | return "Unknown"; | ||
269 | case BOOTSTRAPPER_ACTION_HELP: | ||
270 | return "Help"; | ||
271 | case BOOTSTRAPPER_ACTION_LAYOUT: | ||
272 | return "Layout"; | ||
273 | case BOOTSTRAPPER_ACTION_CACHE: | ||
274 | return "Cache"; | ||
275 | case BOOTSTRAPPER_ACTION_UNINSTALL: | ||
276 | return "Uninstall"; | ||
277 | case BOOTSTRAPPER_ACTION_INSTALL: | ||
278 | return "Install"; | ||
279 | case BOOTSTRAPPER_ACTION_MODIFY: | ||
280 | return "Modify"; | ||
281 | case BOOTSTRAPPER_ACTION_REPAIR: | ||
282 | return "Repair"; | ||
283 | case BOOTSTRAPPER_ACTION_UPDATE_REPLACE: | ||
284 | return "UpdateReplace"; | ||
285 | case BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED: | ||
286 | return "UpdateReplaceEmbedded"; | ||
287 | default: | ||
288 | return "Invalid"; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | LPCSTR LoggingBurnMessageToString( | ||
293 | __in UINT message | ||
294 | ) | ||
295 | { | ||
296 | switch (message) | ||
297 | { | ||
298 | case WM_BURN_APPLY: | ||
299 | return "Apply"; | ||
300 | case WM_BURN_DETECT: | ||
301 | return "Detect"; | ||
302 | case WM_BURN_ELEVATE: | ||
303 | return "Elevate"; | ||
304 | case WM_BURN_LAUNCH_APPROVED_EXE: | ||
305 | return "LaunchApprovedExe"; | ||
306 | case WM_BURN_PLAN: | ||
307 | return "Plan"; | ||
308 | case WM_BURN_QUIT: | ||
309 | return "Quit"; | ||
310 | default: | ||
311 | return "Invalid"; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | extern "C" LPCSTR LoggingActionStateToString( | ||
316 | __in BOOTSTRAPPER_ACTION_STATE actionState | ||
317 | ) | ||
318 | { | ||
319 | switch (actionState) | ||
320 | { | ||
321 | case BOOTSTRAPPER_ACTION_STATE_NONE: | ||
322 | return "None"; | ||
323 | case BOOTSTRAPPER_ACTION_STATE_UNINSTALL: | ||
324 | return "Uninstall"; | ||
325 | case BOOTSTRAPPER_ACTION_STATE_INSTALL: | ||
326 | return "Install"; | ||
327 | case BOOTSTRAPPER_ACTION_STATE_MODIFY: | ||
328 | return "Modify"; | ||
329 | case BOOTSTRAPPER_ACTION_STATE_MEND: | ||
330 | return "Mend"; | ||
331 | case BOOTSTRAPPER_ACTION_STATE_REPAIR: | ||
332 | return "Repair"; | ||
333 | case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE: | ||
334 | return "MinorUpgrade"; | ||
335 | default: | ||
336 | return "Invalid"; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | extern "C" LPCSTR LoggingDependencyActionToString( | ||
341 | BURN_DEPENDENCY_ACTION action | ||
342 | ) | ||
343 | { | ||
344 | switch (action) | ||
345 | { | ||
346 | case BURN_DEPENDENCY_ACTION_NONE: | ||
347 | return "None"; | ||
348 | case BURN_DEPENDENCY_ACTION_REGISTER: | ||
349 | return "Register"; | ||
350 | case BURN_DEPENDENCY_ACTION_UNREGISTER: | ||
351 | return "Unregister"; | ||
352 | default: | ||
353 | return "Invalid"; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | extern "C" LPCSTR LoggingBoolToString( | ||
358 | __in BOOL f | ||
359 | ) | ||
360 | { | ||
361 | if (f) | ||
362 | { | ||
363 | return "Yes"; | ||
364 | } | ||
365 | |||
366 | return "No"; | ||
367 | } | ||
368 | |||
369 | extern "C" LPCSTR LoggingTrueFalseToString( | ||
370 | __in BOOL f | ||
371 | ) | ||
372 | { | ||
373 | if (f) | ||
374 | { | ||
375 | return "true"; | ||
376 | } | ||
377 | |||
378 | return "false"; | ||
379 | } | ||
380 | |||
381 | extern "C" LPCSTR LoggingPackageStateToString( | ||
382 | __in BOOTSTRAPPER_PACKAGE_STATE packageState | ||
383 | ) | ||
384 | { | ||
385 | switch (packageState) | ||
386 | { | ||
387 | case BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN: | ||
388 | return "Unknown"; | ||
389 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: | ||
390 | return "Obsolete"; | ||
391 | case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: | ||
392 | return "Absent"; | ||
393 | case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: | ||
394 | return "Present"; | ||
395 | case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: | ||
396 | return "Superseded"; | ||
397 | default: | ||
398 | return "Invalid"; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | extern "C" LPCSTR LoggingPackageRegistrationStateToString( | ||
403 | __in BOOL fCanAffectRegistration, | ||
404 | __in BURN_PACKAGE_REGISTRATION_STATE registrationState | ||
405 | ) | ||
406 | { | ||
407 | if (!fCanAffectRegistration) | ||
408 | { | ||
409 | return "(permanent)"; | ||
410 | } | ||
411 | |||
412 | switch (registrationState) | ||
413 | { | ||
414 | case BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN: | ||
415 | return "Unknown"; | ||
416 | case BURN_PACKAGE_REGISTRATION_STATE_IGNORED: | ||
417 | return "Ignored"; | ||
418 | case BURN_PACKAGE_REGISTRATION_STATE_ABSENT: | ||
419 | return "Absent"; | ||
420 | case BURN_PACKAGE_REGISTRATION_STATE_PRESENT: | ||
421 | return "Present"; | ||
422 | default: | ||
423 | return "Invalid"; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | extern "C" LPCSTR LoggingMsiFeatureStateToString( | ||
428 | __in BOOTSTRAPPER_FEATURE_STATE featureState | ||
429 | ) | ||
430 | { | ||
431 | switch (featureState) | ||
432 | { | ||
433 | case BOOTSTRAPPER_FEATURE_STATE_UNKNOWN: | ||
434 | return "Unknown"; | ||
435 | case BOOTSTRAPPER_FEATURE_STATE_ABSENT: | ||
436 | return "Absent"; | ||
437 | case BOOTSTRAPPER_FEATURE_STATE_ADVERTISED: | ||
438 | return "Advertised"; | ||
439 | case BOOTSTRAPPER_FEATURE_STATE_LOCAL: | ||
440 | return "Local"; | ||
441 | case BOOTSTRAPPER_FEATURE_STATE_SOURCE: | ||
442 | return "Source"; | ||
443 | default: | ||
444 | return "Invalid"; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | extern "C" LPCSTR LoggingMsiFeatureActionToString( | ||
449 | __in BOOTSTRAPPER_FEATURE_ACTION featureAction | ||
450 | ) | ||
451 | { | ||
452 | switch (featureAction) | ||
453 | { | ||
454 | case BOOTSTRAPPER_FEATURE_ACTION_NONE: | ||
455 | return "None"; | ||
456 | case BOOTSTRAPPER_FEATURE_ACTION_ADDLOCAL: | ||
457 | return "AddLocal"; | ||
458 | case BOOTSTRAPPER_FEATURE_ACTION_ADDSOURCE: | ||
459 | return "AddSource"; | ||
460 | case BOOTSTRAPPER_FEATURE_ACTION_ADDDEFAULT: | ||
461 | return "AddDefault"; | ||
462 | case BOOTSTRAPPER_FEATURE_ACTION_REINSTALL: | ||
463 | return "Reinstall"; | ||
464 | case BOOTSTRAPPER_FEATURE_ACTION_ADVERTISE: | ||
465 | return "Advertise"; | ||
466 | case BOOTSTRAPPER_FEATURE_ACTION_REMOVE: | ||
467 | return "Remove"; | ||
468 | default: | ||
469 | return "Invalid"; | ||
470 | } | ||
471 | } | ||
472 | |||
473 | extern "C" LPCSTR LoggingMsiInstallContext( | ||
474 | __in MSIINSTALLCONTEXT context | ||
475 | ) | ||
476 | { | ||
477 | switch (context) | ||
478 | { | ||
479 | case MSIINSTALLCONTEXT_ALL: | ||
480 | return "All"; | ||
481 | case MSIINSTALLCONTEXT_ALLUSERMANAGED: | ||
482 | return "AllUserManaged"; | ||
483 | case MSIINSTALLCONTEXT_MACHINE: | ||
484 | return "Machine"; | ||
485 | case MSIINSTALLCONTEXT_NONE: | ||
486 | return "None"; | ||
487 | case MSIINSTALLCONTEXT_USERMANAGED: | ||
488 | return "UserManaged"; | ||
489 | case MSIINSTALLCONTEXT_USERUNMANAGED: | ||
490 | return "UserUnmanaged"; | ||
491 | default: | ||
492 | return "Invalid"; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | extern "C" LPCWSTR LoggingBurnMsiPropertyToString( | ||
497 | __in BURN_MSI_PROPERTY burnMsiProperty | ||
498 | ) | ||
499 | { | ||
500 | switch (burnMsiProperty) | ||
501 | { | ||
502 | case BURN_MSI_PROPERTY_INSTALL: | ||
503 | return BURNMSIINSTALL_PROPERTY_NAME; | ||
504 | case BURN_MSI_PROPERTY_MODIFY: | ||
505 | return BURNMSIMODIFY_PROPERTY_NAME; | ||
506 | case BURN_MSI_PROPERTY_NONE: | ||
507 | return L"(none)"; | ||
508 | case BURN_MSI_PROPERTY_REPAIR: | ||
509 | return BURNMSIREPAIR_PROPERTY_NAME; | ||
510 | case BURN_MSI_PROPERTY_UNINSTALL: | ||
511 | return BURNMSIUNINSTALL_PROPERTY_NAME; | ||
512 | default: | ||
513 | return L"Invalid"; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | extern "C" LPCSTR LoggingMspTargetActionToString( | ||
518 | __in BOOTSTRAPPER_ACTION_STATE action, | ||
519 | __in BURN_PATCH_SKIP_STATE skipState | ||
520 | ) | ||
521 | { | ||
522 | switch (skipState) | ||
523 | { | ||
524 | case BURN_PATCH_SKIP_STATE_NONE: | ||
525 | return LoggingActionStateToString(action); | ||
526 | case BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL: | ||
527 | return "Skipped (target uninstall)"; | ||
528 | case BURN_PATCH_SKIP_STATE_SLIPSTREAM: | ||
529 | return "Skipped (slipstream)"; | ||
530 | default: | ||
531 | return "Invalid"; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | extern "C" LPCSTR LoggingPerMachineToString( | ||
536 | __in BOOL fPerMachine | ||
537 | ) | ||
538 | { | ||
539 | if (fPerMachine) | ||
540 | { | ||
541 | return "PerMachine"; | ||
542 | } | ||
543 | |||
544 | return "PerUser"; | ||
545 | } | ||
546 | |||
547 | extern "C" LPCSTR LoggingRestartToString( | ||
548 | __in BOOTSTRAPPER_APPLY_RESTART restart | ||
549 | ) | ||
550 | { | ||
551 | switch (restart) | ||
552 | { | ||
553 | case BOOTSTRAPPER_APPLY_RESTART_NONE: | ||
554 | return "None"; | ||
555 | case BOOTSTRAPPER_APPLY_RESTART_REQUIRED: | ||
556 | return "Required"; | ||
557 | case BOOTSTRAPPER_APPLY_RESTART_INITIATED: | ||
558 | return "Initiated"; | ||
559 | default: | ||
560 | return "Invalid"; | ||
561 | } | ||
562 | } | ||
563 | |||
564 | extern "C" LPCSTR LoggingResumeModeToString( | ||
565 | __in BURN_RESUME_MODE resumeMode | ||
566 | ) | ||
567 | { | ||
568 | switch (resumeMode) | ||
569 | { | ||
570 | case BURN_RESUME_MODE_NONE: | ||
571 | return "None"; | ||
572 | case BURN_RESUME_MODE_ACTIVE: | ||
573 | return "Active"; | ||
574 | case BURN_RESUME_MODE_SUSPEND: | ||
575 | return "Suspend"; | ||
576 | case BURN_RESUME_MODE_ARP: | ||
577 | return "ARP"; | ||
578 | case BURN_RESUME_MODE_REBOOT_PENDING: | ||
579 | return "Reboot Pending"; | ||
580 | default: | ||
581 | return "Invalid"; | ||
582 | } | ||
583 | } | ||
584 | |||
585 | extern "C" LPCSTR LoggingRelationTypeToString( | ||
586 | __in BOOTSTRAPPER_RELATION_TYPE type | ||
587 | ) | ||
588 | { | ||
589 | switch (type) | ||
590 | { | ||
591 | case BOOTSTRAPPER_RELATION_NONE: | ||
592 | return "None"; | ||
593 | case BOOTSTRAPPER_RELATION_DETECT: | ||
594 | return "Detect"; | ||
595 | case BOOTSTRAPPER_RELATION_UPGRADE: | ||
596 | return "Upgrade"; | ||
597 | case BOOTSTRAPPER_RELATION_ADDON: | ||
598 | return "Addon"; | ||
599 | case BOOTSTRAPPER_RELATION_PATCH: | ||
600 | return "Patch"; | ||
601 | case BOOTSTRAPPER_RELATION_DEPENDENT: | ||
602 | return "Dependent"; | ||
603 | case BOOTSTRAPPER_RELATION_UPDATE: | ||
604 | return "Update"; | ||
605 | default: | ||
606 | return "Invalid"; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | extern "C" LPCSTR LoggingRelatedOperationToString( | ||
611 | __in BOOTSTRAPPER_RELATED_OPERATION operation | ||
612 | ) | ||
613 | { | ||
614 | switch (operation) | ||
615 | { | ||
616 | case BOOTSTRAPPER_RELATED_OPERATION_NONE: | ||
617 | return "None"; | ||
618 | case BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE: | ||
619 | return "Downgrade"; | ||
620 | case BOOTSTRAPPER_RELATED_OPERATION_MINOR_UPDATE: | ||
621 | return "MinorUpdate"; | ||
622 | case BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE: | ||
623 | return "MajorUpgrade"; | ||
624 | case BOOTSTRAPPER_RELATED_OPERATION_REMOVE: | ||
625 | return "Remove"; | ||
626 | case BOOTSTRAPPER_RELATED_OPERATION_INSTALL: | ||
627 | return "Install"; | ||
628 | case BOOTSTRAPPER_RELATED_OPERATION_REPAIR: | ||
629 | return "Repair"; | ||
630 | default: | ||
631 | return "Invalid"; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | extern "C" LPCSTR LoggingRequestStateToString( | ||
636 | __in BOOTSTRAPPER_REQUEST_STATE requestState | ||
637 | ) | ||
638 | { | ||
639 | switch (requestState) | ||
640 | { | ||
641 | case BOOTSTRAPPER_REQUEST_STATE_NONE: | ||
642 | return "None"; | ||
643 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: | ||
644 | return "ForceAbsent"; | ||
645 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: | ||
646 | return "Absent"; | ||
647 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: | ||
648 | return "Cache"; | ||
649 | case BOOTSTRAPPER_REQUEST_STATE_PRESENT: | ||
650 | return "Present"; | ||
651 | case BOOTSTRAPPER_REQUEST_STATE_MEND: | ||
652 | return "Mend"; | ||
653 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
654 | return "Repair"; | ||
655 | default: | ||
656 | return "Invalid"; | ||
657 | } | ||
658 | } | ||
659 | |||
660 | extern "C" LPCSTR LoggingRollbackOrExecute( | ||
661 | __in BOOL fRollback | ||
662 | ) | ||
663 | { | ||
664 | return fRollback ? "rollback" : "execute"; | ||
665 | } | ||
666 | |||
667 | extern "C" LPWSTR LoggingStringOrUnknownIfNull( | ||
668 | __in LPCWSTR wz | ||
669 | ) | ||
670 | { | ||
671 | return wz ? wz : L"Unknown"; | ||
672 | } | ||
673 | |||
674 | |||
675 | // internal function declarations | ||
676 | |||
677 | static void CheckLoggingPolicy( | ||
678 | __out DWORD *pdwAttributes | ||
679 | ) | ||
680 | { | ||
681 | HRESULT hr = S_OK; | ||
682 | HKEY hk = NULL; | ||
683 | LPWSTR sczLoggingPolicy = NULL; | ||
684 | |||
685 | hr = RegOpen(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Installer", KEY_READ, &hk); | ||
686 | if (SUCCEEDED(hr)) | ||
687 | { | ||
688 | hr = RegReadString(hk, L"Logging", &sczLoggingPolicy); | ||
689 | if (SUCCEEDED(hr)) | ||
690 | { | ||
691 | LPCWSTR wz = sczLoggingPolicy; | ||
692 | while (*wz) | ||
693 | { | ||
694 | if (L'v' == *wz || L'V' == *wz) | ||
695 | { | ||
696 | *pdwAttributes |= BURN_LOGGING_ATTRIBUTE_VERBOSE; | ||
697 | } | ||
698 | else if (L'x' == *wz || L'X' == *wz) | ||
699 | { | ||
700 | *pdwAttributes |= BURN_LOGGING_ATTRIBUTE_EXTRADEBUG; | ||
701 | } | ||
702 | |||
703 | ++wz; | ||
704 | } | ||
705 | } | ||
706 | } | ||
707 | |||
708 | ReleaseStr(sczLoggingPolicy); | ||
709 | ReleaseRegKey(hk); | ||
710 | } | ||
711 | |||
712 | static HRESULT GetNonSessionSpecificTempFolder( | ||
713 | __deref_out_z LPWSTR* psczNonSessionTempFolder | ||
714 | ) | ||
715 | { | ||
716 | HRESULT hr = S_OK; | ||
717 | WCHAR wzTempFolder[MAX_PATH] = { }; | ||
718 | SIZE_T cchTempFolder = 0; | ||
719 | DWORD dwSessionId = 0; | ||
720 | LPWSTR sczSessionId = 0; | ||
721 | SIZE_T cchSessionId = 0; | ||
722 | |||
723 | if (!::GetTempPathW(countof(wzTempFolder), wzTempFolder)) | ||
724 | { | ||
725 | ExitWithLastError(hr, "Failed to get temp folder."); | ||
726 | } | ||
727 | |||
728 | hr = ::StringCchLengthW(wzTempFolder, countof(wzTempFolder), reinterpret_cast<size_t*>(&cchTempFolder)); | ||
729 | ExitOnFailure(hr, "Failed to get length of temp folder."); | ||
730 | |||
731 | // If our session id is in the TEMP path then remove that part so we get the non-session | ||
732 | // specific temporary folder. | ||
733 | if (::ProcessIdToSessionId(::GetCurrentProcessId(), &dwSessionId)) | ||
734 | { | ||
735 | hr = StrAllocFormatted(&sczSessionId, L"%u\\", dwSessionId); | ||
736 | ExitOnFailure(hr, "Failed to format session id as a string."); | ||
737 | |||
738 | hr = ::StringCchLengthW(sczSessionId, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchSessionId)); | ||
739 | ExitOnFailure(hr, "Failed to get length of session id string."); | ||
740 | |||
741 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzTempFolder + cchTempFolder - cchSessionId, static_cast<DWORD>(cchSessionId), sczSessionId, static_cast<DWORD>(cchSessionId))) | ||
742 | { | ||
743 | cchTempFolder -= cchSessionId; | ||
744 | } | ||
745 | } | ||
746 | |||
747 | hr = StrAllocString(psczNonSessionTempFolder, wzTempFolder, cchTempFolder); | ||
748 | ExitOnFailure(hr, "Failed to copy temp folder."); | ||
749 | |||
750 | LExit: | ||
751 | ReleaseStr(sczSessionId); | ||
752 | |||
753 | return hr; | ||
754 | } | ||