Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/installer-ca/wcalog.cpp

Issue 11521026: initial custom action library, "hello, world" quality (Closed)
Patch Set: Created Sept. 3, 2013, 12:48 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //------------------------------------------------------------------------------ -------------------
2 // <copyright file="wcalog.cpp" company="Outercurve Foundation">
3 // Copyright (c) 2004, Outercurve Foundation.
4 // This software is released under Microsoft Reciprocal License (MS-RL).
5 // The license and further copyright text can be found in the file
6 // LICENSE.TXT at the root directory of the distribution.
7 // </copyright>
8 //
9 // <summary>
10 // Windows Installer XML CustomAction utility library logging functions
11 // </summary>
12 //------------------------------------------------------------------------------ -------------------
13
14 #include "precomp.h"
15
16 /********************************************************************
17 IsVerboseLoggingPolicy() - internal helper function to detect if
18 policy is set for verbose logging. Does
19 not require database access.
20 ********************************************************************/
21 static BOOL IsVerboseLoggingPolicy()
22 {
23 BOOL fVerbose = FALSE;
24 HKEY hkey = NULL;
25 WCHAR rgwc[16] = { 0 };
26 DWORD cb = sizeof(rgwc);
27 if (ERROR_SUCCESS == ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Policie s\\Microsoft\\Windows\\Installer", 0, KEY_QUERY_VALUE, &hkey))
28 {
29 if (ERROR_SUCCESS == ::RegQueryValueExW(hkey, L"Logging", 0, NULL, reint erpret_cast<BYTE*>(rgwc), &cb))
30 {
31 for (LPCWSTR pwc = rgwc; (cb / sizeof(WCHAR)) > static_cast<DWORD>(p wc - rgwc) && *pwc; pwc++)
32 {
33 if (L'v' == *pwc || L'V' == *pwc)
34 {
35 fVerbose = TRUE;
36 break;
37 }
38 }
39 }
40
41 ::RegCloseKey(hkey);
42 }
43 return fVerbose;
44 }
45
46 /********************************************************************
47 IsVerboseLogging() - internal helper function to detect if doing
48 verbose logging. Checks:
49 1. LOGVERBOSE property.
50 2. MsiLogging property contains 'v'
51 3. Policy from registry.
52
53 Requires database access.
54 ********************************************************************/
55 BOOL WIXAPI IsVerboseLogging()
56 {
57 static int iVerbose = -1;
58 LPWSTR pwzMsiLogging = NULL;
59
60 if (0 > iVerbose)
61 {
62 iVerbose = WcaIsPropertySet("LOGVERBOSE");
63 if (0 == iVerbose)
64 {
65 // if the property wasn't set, check the MsiLogging property (MSI 4. 0+)
66 HRESULT hr = WcaGetProperty(L"MsiLogging", &pwzMsiLogging);
67 ExitOnFailure(hr, "failed to get MsiLogging property");
68 int cchMsiLogging = lstrlenW(pwzMsiLogging);
69 if (0 < cchMsiLogging)
70 {
71 for (int i = 0; i < cchMsiLogging; i++)
72 {
73 if (L'v' == pwzMsiLogging[i] || L'V' == pwzMsiLogging[i])
74 {
75 iVerbose = 1;
76 break;
77 }
78 }
79 }
80
81 // last chance: Check the registry to see if the logging policy was turned on
82 if (0 == iVerbose && IsVerboseLoggingPolicy())
83 {
84 iVerbose = 1;
85 }
86 }
87 }
88
89 LExit:
90 ReleaseStr(pwzMsiLogging);
91 Assert(iVerbose >= 0);
92 return (BOOL)iVerbose;
93 }
94
95 /********************************************************************
96 SetVerboseLoggingAtom() - Sets one of two global Atoms to specify
97 if the install should do verbose logging.
98 Communicates the verbose setting to
99 deferred CAs.
100 Set a negative case atom so that we can
101 distinguish between an unset atom and the
102 non-verbose case. This helps prevent the
103 expensive regkey lookup for non-verbose.
104 ********************************************************************/
105 HRESULT WIXAPI SetVerboseLoggingAtom(BOOL bValue)
106 {
107 HRESULT hr = S_OK;
108 ATOM atomVerbose = 0;
109
110 atomVerbose = ::GlobalFindAtomW(L"WcaVerboseLogging");
111 if (0 == atomVerbose && bValue)
112 {
113 atomVerbose = ::GlobalAddAtomW(L"WcaVerboseLogging");
114 ExitOnNullWithLastError(atomVerbose, hr, "Failed to create WcaVerboseLog ging global atom.");
115 }
116 else if (0 != atomVerbose && !bValue)
117 {
118 ::SetLastError(ERROR_SUCCESS);
119 ::GlobalDeleteAtom(atomVerbose);
120 ExitOnLastError(hr, "Failed to delete WcaVerboseLogging global atom.");
121 }
122
123 atomVerbose = ::GlobalFindAtomW(L"WcaNotVerboseLogging");
124 if (0 == atomVerbose && !bValue)
125 {
126 atomVerbose = ::GlobalAddAtomW(L"WcaNotVerboseLogging");
127 ExitOnNullWithLastError(atomVerbose, hr, "Failed to create WcaNotVerbose Logging global atom.");
128 }
129 else if (0 != atomVerbose && bValue)
130 {
131 ::SetLastError(ERROR_SUCCESS);
132 ::GlobalDeleteAtom(atomVerbose);
133 ExitOnLastError(hr, "Failed to delete WcaNotVerboseLogging global atom." );
134 }
135
136 LExit:
137 return hr;
138 }
139
140 /********************************************************************
141 IsVerboseLoggingLite() - internal helper function to detect if atom was
142 previously set to specify verbose logging.
143 Falls back on policy for an installer that is
144 unable to set the atom (no immediate CAs).
145
146 Does not require database access.
147 ********************************************************************/
148 static BOOL IsVerboseLoggingLite()
149 {
150 ATOM atomVerbose = ::GlobalFindAtomW(L"WcaVerboseLogging");
151 if (0 != atomVerbose)
152 {
153 return TRUE;
154 }
155
156 atomVerbose = ::GlobalFindAtomW(L"WcaNotVerboseLogging");
157 if (0 != atomVerbose)
158 {
159 return FALSE;
160 }
161
162 return IsVerboseLoggingPolicy();
163 }
164
165 /********************************************************************
166 WcaLog() - outputs trace and log info
167
168 *******************************************************************/
169 extern "C" void __cdecl WcaLog(
170 __in LOGLEVEL llv,
171 __in_z __format_string PCSTR fmt,
172 ...
173 )
174 {
175 static char szFmt[LOG_BUFFER];
176 static char szBuf[LOG_BUFFER];
177 static bool fInLogPrint = false;
178
179 // prevent re-entrant logprints. (recursion issues between assert/logging c ode)
180 if (fInLogPrint)
181 return;
182 fInLogPrint = true;
183
184 if (LOGMSG_STANDARD == llv ||
185 (LOGMSG_VERBOSE == llv && IsVerboseLoggingLite())
186 #ifdef DEBUG
187 || LOGMSG_TRACEONLY == llv
188 #endif
189 )
190 {
191 va_list args;
192 va_start(args, fmt);
193
194 LPCSTR szLogName = WcaGetLogName();
195 if (szLogName[0] != 0)
196 StringCchPrintfA(szFmt, countof(szFmt), "%s: %s", szLogName, fmt);
197 else
198 StringCchCopyA(szFmt, countof(szFmt), fmt);
199
200 StringCchVPrintfA(szBuf, countof(szBuf), szFmt, args);
201 va_end(args);
202
203 #ifdef DEBUG
204 // always write to the log in debug
205 #else
206 if (llv == LOGMSG_STANDARD || (llv == LOGMSG_VERBOSE && IsVerboseLogging Lite()))
207 #endif
208 {
209 PMSIHANDLE hrec = MsiCreateRecord(1);
210
211 ::MsiRecordSetStringA(hrec, 0, szBuf);
212 // TODO: Recursion on failure. May not be safe to assert from here .
213 WcaProcessMessage(INSTALLMESSAGE_INFO, hrec);
214 }
215
216 #if DEBUG
217 StringCchCatA(szBuf, countof(szBuf), "\n");
218 OutputDebugStringA(szBuf);
219 #endif
220 }
221
222 fInLogPrint = false;
223 return;
224 }
225
226
227 /********************************************************************
228 WcaDisplayAssert() - called before Assert() dialog shows
229
230 NOTE: writes the assert string to the MSI log
231 ********************************************************************/
232 extern "C" BOOL WIXAPI WcaDisplayAssert(
233 __in LPCSTR sz
234 )
235 {
236 WcaLog(LOGMSG_STANDARD, "Debug Assert Message: %s", sz);
237 return TRUE;
238 }
239
240
241 /********************************************************************
242 WcaLogError() - called before ExitOnXXX() macro exists the function
243
244 NOTE: writes the hresult and error string to the MSI log
245 ********************************************************************/
246 extern "C" void WcaLogError(
247 __in HRESULT hr,
248 __in LPCSTR szMessage,
249 ...
250 )
251 {
252 char szBuffer[LOG_BUFFER];
253 va_list dots;
254
255 va_start(dots, szMessage);
256 StringCchVPrintfA(szBuffer, countof(szBuffer), szMessage, dots);
257 va_end(dots);
258
259 // log the message if using Wca common layer
260 if (WcaIsInitialized())
261 WcaLog(LOGMSG_STANDARD, "Error 0x%x: %s", hr, szBuffer);
262 }
OLDNEW

Powered by Google App Engine
This is Rietveld