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