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

Side by Side Diff: src/installer-ca/dutil/dutil.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="dutil.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 // Utility layer that provides standard support for asserts, exit macros
11 // </summary>
12 //------------------------------------------------------------------------------ -------------------
13
14 #include "../precomp.h"
15
16 // No need for OACR to warn us about using non-unicode APIs in this file.
17 #pragma prefast(disable:25068)
18
19 // Asserts & Tracing
20
21 const int DUTIL_STRING_BUFFER = 1024;
22 static HMODULE Dutil_hAssertModule = NULL;
23 static DUTIL_ASSERTDISPLAYFUNCTION Dutil_pfnDisplayAssert = NULL;
24 static BOOL Dutil_fNoAsserts = FALSE;
25 static REPORT_LEVEL Dutil_rlCurrentTrace = REPORT_STANDARD;
26 static BOOL Dutil_fTraceFilenames = FALSE;
27
28
29 /*******************************************************************
30 Dutil_SetAssertModule
31
32 *******************************************************************/
33 extern "C" void DAPI Dutil_SetAssertModule(
34 __in HMODULE hAssertModule
35 )
36 {
37 Dutil_hAssertModule = hAssertModule;
38 }
39
40
41 /*******************************************************************
42 Dutil_SetAssertDisplayFunction
43
44 *******************************************************************/
45 extern "C" void DAPI Dutil_SetAssertDisplayFunction(
46 __in DUTIL_ASSERTDISPLAYFUNCTION pfn
47 )
48 {
49 Dutil_pfnDisplayAssert = pfn;
50 }
51
52
53 /*******************************************************************
54 Dutil_AssertMsg
55
56 *******************************************************************/
57 extern "C" void DAPI Dutil_AssertMsg(
58 __in_z LPCSTR szMessage
59 )
60 {
61 static BOOL fInAssert = FALSE; // TODO: make this thread safe (this is a che ap hack to prevent re-entrant Asserts)
62
63 HRESULT hr = S_OK;
64 DWORD er = ERROR_SUCCESS;
65
66 int id = IDRETRY;
67 HKEY hkDebug = NULL;
68 HANDLE hAssertFile = INVALID_HANDLE_VALUE;
69 char szPath[MAX_PATH] = { };
70 DWORD cch = 0;
71
72 if (fInAssert)
73 {
74 return;
75 }
76 fInAssert = TRUE;
77
78 char szMsg[DUTIL_STRING_BUFFER];
79 hr = ::StringCchCopyA(szMsg, countof(szMsg), szMessage);
80 ExitOnFailure(hr, "failed to copy message while building assert message");
81
82 if (Dutil_pfnDisplayAssert)
83 {
84 // call custom function to display the assert string
85 if (!Dutil_pfnDisplayAssert(szMsg))
86 {
87 ExitFunction();
88 }
89 }
90 else
91 {
92 OutputDebugStringA(szMsg);
93 }
94
95 if (!Dutil_fNoAsserts)
96 {
97 er = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Delivery \\Debug", 0, KEY_QUERY_VALUE, &hkDebug);
98 if (ERROR_SUCCESS == er)
99 {
100 cch = countof(szPath);
101 er = ::RegQueryValueExA(hkDebug, "DeliveryAssertsLog", NULL, NULL, r einterpret_cast<BYTE*>(szPath), &cch);
102 szPath[countof(szPath) - 1] = '\0'; // ensure string is null termina ted since registry won't guarantee that.
103 if (ERROR_SUCCESS == er)
104 {
105 hAssertFile = ::CreateFileA(szPath, GENERIC_WRITE, FILE_SHARE_RE AD | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
106 if (INVALID_HANDLE_VALUE != hAssertFile)
107 {
108 ::SetFilePointer(hAssertFile, 0, 0, FILE_END);
109 ::StringCchCatA(szMsg, countof(szMsg), "\r\n");
110 ::WriteFile(hAssertFile, szMsg, lstrlenA(szMsg), &cch, NULL) ;
111 }
112 }
113 }
114
115 // if anything went wrong while fooling around with the registry, just s how the usual assert dialog box
116 if (ERROR_SUCCESS != er)
117 {
118 hr = ::StringCchCatA(szMsg, countof(szMsg), "\nAbort=Debug, Retry=Sk ip, Ignore=Skip all");
119 ExitOnFailure(hr, "failed to concat string while building assert mes sage");
120
121 id = ::MessageBoxA(0, szMsg, "Debug Assert Message",
122 MB_SERVICE_NOTIFICATION | MB_TOPMOST |
123 MB_DEFBUTTON2 | MB_ABORTRETRYIGNORE);
124 }
125 }
126
127 if (id == IDABORT)
128 {
129 if (Dutil_hAssertModule)
130 {
131 ::GetModuleFileNameA(Dutil_hAssertModule, szPath, countof(szPath));
132
133 hr = ::StringCchPrintfA(szMsg, countof(szMsg), "Module is running fr om: %s\nIf you are not using pdb-stamping, place your PDB near the module and at tach to process id: %d (0x%x)", szPath, ::GetCurrentProcessId(), ::GetCurrentPro cessId());
134 if (SUCCEEDED(hr))
135 {
136 ::MessageBoxA(0, szMsg, "Debug Assert Message", MB_SERVICE_NOTIF ICATION | MB_TOPMOST | MB_OK);
137 }
138 }
139
140 ::DebugBreak();
141 }
142 else if (id == IDIGNORE)
143 {
144 Dutil_fNoAsserts = TRUE;
145 }
146
147 LExit:
148 ReleaseFileHandle(hAssertFile);
149 ReleaseRegKey(hkDebug);
150 fInAssert = FALSE;
151 }
152
153
154 /*******************************************************************
155 Dutil_Assert
156
157 *******************************************************************/
158 extern "C" void DAPI Dutil_Assert(
159 __in_z LPCSTR szFile,
160 __in int iLine
161 )
162 {
163 HRESULT hr = S_OK;
164 char szMessage[DUTIL_STRING_BUFFER] = { };
165 hr = ::StringCchPrintfA(szMessage, countof(szMessage), "Assertion failed in %s, %i", szFile, iLine);
166 if (SUCCEEDED(hr))
167 {
168 Dutil_AssertMsg(szMessage);
169 }
170 else
171 {
172 Dutil_AssertMsg("Assert failed to build string");
173 }
174 }
175
176
177 /*******************************************************************
178 Dutil_AssertSz
179
180 *******************************************************************/
181 extern "C" void DAPI Dutil_AssertSz(
182 __in_z LPCSTR szFile,
183 __in int iLine,
184 __in_z __format_string LPCSTR szMsg
185 )
186 {
187 HRESULT hr = S_OK;
188 char szMessage[DUTIL_STRING_BUFFER] = { };
189
190 hr = ::StringCchPrintfA(szMessage, countof(szMessage), "Assertion failed in %s, %i\n%s", szFile, iLine, szMsg);
191 if (SUCCEEDED(hr))
192 {
193 Dutil_AssertMsg(szMessage);
194 }
195 else
196 {
197 Dutil_AssertMsg("Assert failed to build string");
198 }
199 }
200
201
202 /*******************************************************************
203 Dutil_TraceSetLevel
204
205 *******************************************************************/
206 extern "C" void DAPI Dutil_TraceSetLevel(
207 __in REPORT_LEVEL rl,
208 __in BOOL fTraceFilenames
209 )
210 {
211 Dutil_rlCurrentTrace = rl;
212 Dutil_fTraceFilenames = fTraceFilenames;
213 }
214
215
216 /*******************************************************************
217 Dutil_TraceGetLevel
218
219 *******************************************************************/
220 extern "C" REPORT_LEVEL DAPI Dutil_TraceGetLevel()
221 {
222 return Dutil_rlCurrentTrace;
223 }
224
225
226 /*******************************************************************
227 Dutil_Trace
228
229 *******************************************************************/
230 extern "C" void DAPI Dutil_Trace(
231 __in_z LPCSTR szFile,
232 __in int iLine,
233 __in REPORT_LEVEL rl,
234 __in_z __format_string LPCSTR szFormat,
235 ...
236 )
237 {
238 AssertSz(REPORT_NONE != rl, "REPORT_NONE is not a valid tracing level");
239
240 HRESULT hr = S_OK;
241 char szOutput[DUTIL_STRING_BUFFER] = { };
242 char szMsg[DUTIL_STRING_BUFFER] = { };
243
244 if (Dutil_rlCurrentTrace < rl)
245 {
246 return;
247 }
248
249 va_list args;
250 va_start(args, szFormat);
251 hr = ::StringCchVPrintfA(szOutput, countof(szOutput), szFormat, args);
252 va_end(args);
253
254 if (SUCCEEDED(hr))
255 {
256 LPCSTR szPrefix = "Trace/u";
257 switch (rl)
258 {
259 case REPORT_STANDARD:
260 szPrefix = "Trace/s";
261 break;
262 case REPORT_VERBOSE:
263 szPrefix = "Trace/v";
264 break;
265 case REPORT_DEBUG:
266 szPrefix = "Trace/d";
267 break;
268 }
269
270 if (Dutil_fTraceFilenames)
271 {
272 hr = ::StringCchPrintfA(szMsg, countof(szMsg), "%s [%s,%d]: %s\r\n", szPrefix, szFile, iLine, szOutput);
273 }
274 else
275 {
276 hr = ::StringCchPrintfA(szMsg, countof(szMsg), "%s: %s\r\n", szPrefi x, szOutput);
277 }
278
279 if (SUCCEEDED(hr))
280 {
281 OutputDebugStringA(szMsg);
282 }
283 // else fall through to the case below
284 }
285
286 if (FAILED(hr))
287 {
288 if (Dutil_fTraceFilenames)
289 {
290 ::StringCchPrintfA(szMsg, countof(szMsg), "Trace [%s,%d]: message to o long, skipping\r\n", szFile, iLine);
291 }
292 else
293 {
294 ::StringCchPrintfA(szMsg, countof(szMsg), "Trace: message too long, skipping\r\n");
295 }
296
297 szMsg[countof(szMsg)-1] = '\0';
298 OutputDebugStringA(szMsg);
299 }
300 }
301
302
303 /*******************************************************************
304 Dutil_TraceError
305
306 *******************************************************************/
307 extern "C" void DAPI Dutil_TraceError(
308 __in_z LPCSTR szFile,
309 __in int iLine,
310 __in REPORT_LEVEL rl,
311 __in HRESULT hrError,
312 __in_z __format_string LPCSTR szFormat,
313 ...
314 )
315 {
316 HRESULT hr = S_OK;
317 char szOutput[DUTIL_STRING_BUFFER] = { };
318 char szMsg[DUTIL_STRING_BUFFER] = { };
319
320 // if this is NOT an error report and we're not logging at this level, bail
321 if (REPORT_ERROR != rl && Dutil_rlCurrentTrace < rl)
322 {
323 return;
324 }
325
326 va_list args;
327 va_start(args, szFormat);
328 hr = ::StringCchVPrintfA(szOutput, countof(szOutput), szFormat, args);
329 va_end(args);
330
331 if (SUCCEEDED(hr))
332 {
333 if (Dutil_fTraceFilenames)
334 {
335 if (FAILED(hrError))
336 {
337 hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x [%s,%d]: %s\r\n", hrError, szFile, iLine, szOutput);
338 }
339 else
340 {
341 hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError [%s,% d]: %s\r\n", szFile, iLine, szOutput);
342 }
343 }
344 else
345 {
346 if (FAILED(hrError))
347 {
348 hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x: %s\r\n", hrError, szOutput);
349 }
350 else
351 {
352 hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError: %s\r \n", szOutput);
353 }
354 }
355
356 if (SUCCEEDED(hr))
357 {
358 OutputDebugStringA(szMsg);
359 }
360 // else fall through to the failure case below
361 }
362
363 if (FAILED(hr))
364 {
365 if (Dutil_fTraceFilenames)
366 {
367 if (FAILED(hrError))
368 {
369 ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x [%s,% d]: message too long, skipping\r\n", hrError, szFile, iLine);
370 }
371 else
372 {
373 ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError [%s,%d]: m essage too long, skipping\r\n", szFile, iLine);
374 }
375 }
376 else
377 {
378 if (FAILED(hrError))
379 {
380 ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x: mess age too long, skipping\r\n", hrError);
381 }
382 else
383 {
384 ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError: message t oo long, skipping\r\n");
385 }
386 }
387
388 szMsg[countof(szMsg)-1] = '\0';
389 OutputDebugStringA(szMsg);
390 }
391 }
392
393
394
395 /*******************************************************************
396 Dutil_RootFailure
397
398 *******************************************************************/
399 extern "C" void DAPI Dutil_RootFailure(
400 __in_z LPCSTR szFile,
401 __in int iLine,
402 __in HRESULT hrError
403 )
404 {
405 #ifndef DEBUG
406 UNREFERENCED_PARAMETER(szFile);
407 UNREFERENCED_PARAMETER(iLine);
408 UNREFERENCED_PARAMETER(hrError);
409 #endif // DEBUG
410
411 TraceError2(hrError, "Root failure at %s:%d", szFile, iLine);
412 }
413
414 /*******************************************************************
415 LoadSystemLibrary - Fully qualifies the path to a module in the
416 Windows system directory and loads it.
417
418 Returns
419 E_MODNOTFOUND - The module could not be found.
420 * - Another error occured.
421 ********************************************************************/
422 extern "C" HRESULT DAPI LoadSystemLibrary(
423 __in_z LPCWSTR wzModuleName,
424 __out HMODULE *phModule
425 )
426 {
427 HRESULT hr = S_OK;
428 DWORD cch = 0;
429 WCHAR wzPath[MAX_PATH] = { };
430
431 cch = ::GetSystemDirectoryW(wzPath, MAX_PATH);
432 ExitOnNullWithLastError(cch, hr, "Failed to get the Windows system directory .");
433
434 if (L'\\' != wzPath[cch - 1])
435 {
436 hr = ::StringCchCatNW(wzPath, MAX_PATH, L"\\", 1);
437 ExitOnRootFailure(hr, "Failed to terminate the string with a backslash." );
438 }
439
440 hr = ::StringCchCatW(wzPath, MAX_PATH, wzModuleName);
441 ExitOnRootFailure1(hr, "Failed to create the fully-qualified path to %ls.", wzModuleName);
442
443 *phModule = ::LoadLibraryW(wzPath);
444 ExitOnNullWithLastError1(*phModule, hr, "Failed to load the library %ls.", w zModuleName);
445
446 LExit:
447 return hr;
448 }
OLDNEW

Powered by Google App Engine
This is Rietveld