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

Unified 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.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/installer-ca/dutil/dutil.cpp
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/installer-ca/dutil/dutil.cpp
@@ -0,0 +1,448 @@
+//-------------------------------------------------------------------------------------------------
+// <copyright file="dutil.cpp" company="Outercurve Foundation">
+// Copyright (c) 2004, Outercurve Foundation.
+// This software is released under Microsoft Reciprocal License (MS-RL).
+// The license and further copyright text can be found in the file
+// LICENSE.TXT at the root directory of the distribution.
+// </copyright>
+//
+// <summary>
+// Utility layer that provides standard support for asserts, exit macros
+// </summary>
+//-------------------------------------------------------------------------------------------------
+
+#include "../precomp.h"
+
+// No need for OACR to warn us about using non-unicode APIs in this file.
+#pragma prefast(disable:25068)
+
+// Asserts & Tracing
+
+const int DUTIL_STRING_BUFFER = 1024;
+static HMODULE Dutil_hAssertModule = NULL;
+static DUTIL_ASSERTDISPLAYFUNCTION Dutil_pfnDisplayAssert = NULL;
+static BOOL Dutil_fNoAsserts = FALSE;
+static REPORT_LEVEL Dutil_rlCurrentTrace = REPORT_STANDARD;
+static BOOL Dutil_fTraceFilenames = FALSE;
+
+
+/*******************************************************************
+Dutil_SetAssertModule
+
+*******************************************************************/
+extern "C" void DAPI Dutil_SetAssertModule(
+ __in HMODULE hAssertModule
+ )
+{
+ Dutil_hAssertModule = hAssertModule;
+}
+
+
+/*******************************************************************
+Dutil_SetAssertDisplayFunction
+
+*******************************************************************/
+extern "C" void DAPI Dutil_SetAssertDisplayFunction(
+ __in DUTIL_ASSERTDISPLAYFUNCTION pfn
+ )
+{
+ Dutil_pfnDisplayAssert = pfn;
+}
+
+
+/*******************************************************************
+Dutil_AssertMsg
+
+*******************************************************************/
+extern "C" void DAPI Dutil_AssertMsg(
+ __in_z LPCSTR szMessage
+ )
+{
+ static BOOL fInAssert = FALSE; // TODO: make this thread safe (this is a cheap hack to prevent re-entrant Asserts)
+
+ HRESULT hr = S_OK;
+ DWORD er = ERROR_SUCCESS;
+
+ int id = IDRETRY;
+ HKEY hkDebug = NULL;
+ HANDLE hAssertFile = INVALID_HANDLE_VALUE;
+ char szPath[MAX_PATH] = { };
+ DWORD cch = 0;
+
+ if (fInAssert)
+ {
+ return;
+ }
+ fInAssert = TRUE;
+
+ char szMsg[DUTIL_STRING_BUFFER];
+ hr = ::StringCchCopyA(szMsg, countof(szMsg), szMessage);
+ ExitOnFailure(hr, "failed to copy message while building assert message");
+
+ if (Dutil_pfnDisplayAssert)
+ {
+ // call custom function to display the assert string
+ if (!Dutil_pfnDisplayAssert(szMsg))
+ {
+ ExitFunction();
+ }
+ }
+ else
+ {
+ OutputDebugStringA(szMsg);
+ }
+
+ if (!Dutil_fNoAsserts)
+ {
+ er = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Delivery\\Debug", 0, KEY_QUERY_VALUE, &hkDebug);
+ if (ERROR_SUCCESS == er)
+ {
+ cch = countof(szPath);
+ er = ::RegQueryValueExA(hkDebug, "DeliveryAssertsLog", NULL, NULL, reinterpret_cast<BYTE*>(szPath), &cch);
+ szPath[countof(szPath) - 1] = '\0'; // ensure string is null terminated since registry won't guarantee that.
+ if (ERROR_SUCCESS == er)
+ {
+ hAssertFile = ::CreateFileA(szPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (INVALID_HANDLE_VALUE != hAssertFile)
+ {
+ ::SetFilePointer(hAssertFile, 0, 0, FILE_END);
+ ::StringCchCatA(szMsg, countof(szMsg), "\r\n");
+ ::WriteFile(hAssertFile, szMsg, lstrlenA(szMsg), &cch, NULL);
+ }
+ }
+ }
+
+ // if anything went wrong while fooling around with the registry, just show the usual assert dialog box
+ if (ERROR_SUCCESS != er)
+ {
+ hr = ::StringCchCatA(szMsg, countof(szMsg), "\nAbort=Debug, Retry=Skip, Ignore=Skip all");
+ ExitOnFailure(hr, "failed to concat string while building assert message");
+
+ id = ::MessageBoxA(0, szMsg, "Debug Assert Message",
+ MB_SERVICE_NOTIFICATION | MB_TOPMOST |
+ MB_DEFBUTTON2 | MB_ABORTRETRYIGNORE);
+ }
+ }
+
+ if (id == IDABORT)
+ {
+ if (Dutil_hAssertModule)
+ {
+ ::GetModuleFileNameA(Dutil_hAssertModule, szPath, countof(szPath));
+
+ hr = ::StringCchPrintfA(szMsg, countof(szMsg), "Module is running from: %s\nIf you are not using pdb-stamping, place your PDB near the module and attach to process id: %d (0x%x)", szPath, ::GetCurrentProcessId(), ::GetCurrentProcessId());
+ if (SUCCEEDED(hr))
+ {
+ ::MessageBoxA(0, szMsg, "Debug Assert Message", MB_SERVICE_NOTIFICATION | MB_TOPMOST | MB_OK);
+ }
+ }
+
+ ::DebugBreak();
+ }
+ else if (id == IDIGNORE)
+ {
+ Dutil_fNoAsserts = TRUE;
+ }
+
+LExit:
+ ReleaseFileHandle(hAssertFile);
+ ReleaseRegKey(hkDebug);
+ fInAssert = FALSE;
+}
+
+
+/*******************************************************************
+Dutil_Assert
+
+*******************************************************************/
+extern "C" void DAPI Dutil_Assert(
+ __in_z LPCSTR szFile,
+ __in int iLine
+ )
+{
+ HRESULT hr = S_OK;
+ char szMessage[DUTIL_STRING_BUFFER] = { };
+ hr = ::StringCchPrintfA(szMessage, countof(szMessage), "Assertion failed in %s, %i", szFile, iLine);
+ if (SUCCEEDED(hr))
+ {
+ Dutil_AssertMsg(szMessage);
+ }
+ else
+ {
+ Dutil_AssertMsg("Assert failed to build string");
+ }
+}
+
+
+/*******************************************************************
+Dutil_AssertSz
+
+*******************************************************************/
+extern "C" void DAPI Dutil_AssertSz(
+ __in_z LPCSTR szFile,
+ __in int iLine,
+ __in_z __format_string LPCSTR szMsg
+ )
+{
+ HRESULT hr = S_OK;
+ char szMessage[DUTIL_STRING_BUFFER] = { };
+
+ hr = ::StringCchPrintfA(szMessage, countof(szMessage), "Assertion failed in %s, %i\n%s", szFile, iLine, szMsg);
+ if (SUCCEEDED(hr))
+ {
+ Dutil_AssertMsg(szMessage);
+ }
+ else
+ {
+ Dutil_AssertMsg("Assert failed to build string");
+ }
+}
+
+
+/*******************************************************************
+Dutil_TraceSetLevel
+
+*******************************************************************/
+extern "C" void DAPI Dutil_TraceSetLevel(
+ __in REPORT_LEVEL rl,
+ __in BOOL fTraceFilenames
+ )
+{
+ Dutil_rlCurrentTrace = rl;
+ Dutil_fTraceFilenames = fTraceFilenames;
+}
+
+
+/*******************************************************************
+Dutil_TraceGetLevel
+
+*******************************************************************/
+extern "C" REPORT_LEVEL DAPI Dutil_TraceGetLevel()
+{
+ return Dutil_rlCurrentTrace;
+}
+
+
+/*******************************************************************
+Dutil_Trace
+
+*******************************************************************/
+extern "C" void DAPI Dutil_Trace(
+ __in_z LPCSTR szFile,
+ __in int iLine,
+ __in REPORT_LEVEL rl,
+ __in_z __format_string LPCSTR szFormat,
+ ...
+ )
+{
+ AssertSz(REPORT_NONE != rl, "REPORT_NONE is not a valid tracing level");
+
+ HRESULT hr = S_OK;
+ char szOutput[DUTIL_STRING_BUFFER] = { };
+ char szMsg[DUTIL_STRING_BUFFER] = { };
+
+ if (Dutil_rlCurrentTrace < rl)
+ {
+ return;
+ }
+
+ va_list args;
+ va_start(args, szFormat);
+ hr = ::StringCchVPrintfA(szOutput, countof(szOutput), szFormat, args);
+ va_end(args);
+
+ if (SUCCEEDED(hr))
+ {
+ LPCSTR szPrefix = "Trace/u";
+ switch (rl)
+ {
+ case REPORT_STANDARD:
+ szPrefix = "Trace/s";
+ break;
+ case REPORT_VERBOSE:
+ szPrefix = "Trace/v";
+ break;
+ case REPORT_DEBUG:
+ szPrefix = "Trace/d";
+ break;
+ }
+
+ if (Dutil_fTraceFilenames)
+ {
+ hr = ::StringCchPrintfA(szMsg, countof(szMsg), "%s [%s,%d]: %s\r\n", szPrefix, szFile, iLine, szOutput);
+ }
+ else
+ {
+ hr = ::StringCchPrintfA(szMsg, countof(szMsg), "%s: %s\r\n", szPrefix, szOutput);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ OutputDebugStringA(szMsg);
+ }
+ // else fall through to the case below
+ }
+
+ if (FAILED(hr))
+ {
+ if (Dutil_fTraceFilenames)
+ {
+ ::StringCchPrintfA(szMsg, countof(szMsg), "Trace [%s,%d]: message too long, skipping\r\n", szFile, iLine);
+ }
+ else
+ {
+ ::StringCchPrintfA(szMsg, countof(szMsg), "Trace: message too long, skipping\r\n");
+ }
+
+ szMsg[countof(szMsg)-1] = '\0';
+ OutputDebugStringA(szMsg);
+ }
+}
+
+
+/*******************************************************************
+Dutil_TraceError
+
+*******************************************************************/
+extern "C" void DAPI Dutil_TraceError(
+ __in_z LPCSTR szFile,
+ __in int iLine,
+ __in REPORT_LEVEL rl,
+ __in HRESULT hrError,
+ __in_z __format_string LPCSTR szFormat,
+ ...
+ )
+{
+ HRESULT hr = S_OK;
+ char szOutput[DUTIL_STRING_BUFFER] = { };
+ char szMsg[DUTIL_STRING_BUFFER] = { };
+
+ // if this is NOT an error report and we're not logging at this level, bail
+ if (REPORT_ERROR != rl && Dutil_rlCurrentTrace < rl)
+ {
+ return;
+ }
+
+ va_list args;
+ va_start(args, szFormat);
+ hr = ::StringCchVPrintfA(szOutput, countof(szOutput), szFormat, args);
+ va_end(args);
+
+ if (SUCCEEDED(hr))
+ {
+ if (Dutil_fTraceFilenames)
+ {
+ if (FAILED(hrError))
+ {
+ hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x [%s,%d]: %s\r\n", hrError, szFile, iLine, szOutput);
+ }
+ else
+ {
+ hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError [%s,%d]: %s\r\n", szFile, iLine, szOutput);
+ }
+ }
+ else
+ {
+ if (FAILED(hrError))
+ {
+ hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x: %s\r\n", hrError, szOutput);
+ }
+ else
+ {
+ hr = ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError: %s\r\n", szOutput);
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ OutputDebugStringA(szMsg);
+ }
+ // else fall through to the failure case below
+ }
+
+ if (FAILED(hr))
+ {
+ if (Dutil_fTraceFilenames)
+ {
+ if (FAILED(hrError))
+ {
+ ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x [%s,%d]: message too long, skipping\r\n", hrError, szFile, iLine);
+ }
+ else
+ {
+ ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError [%s,%d]: message too long, skipping\r\n", szFile, iLine);
+ }
+ }
+ else
+ {
+ if (FAILED(hrError))
+ {
+ ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError 0x%x: message too long, skipping\r\n", hrError);
+ }
+ else
+ {
+ ::StringCchPrintfA(szMsg, countof(szMsg), "TraceError: message too long, skipping\r\n");
+ }
+ }
+
+ szMsg[countof(szMsg)-1] = '\0';
+ OutputDebugStringA(szMsg);
+ }
+}
+
+
+
+/*******************************************************************
+Dutil_RootFailure
+
+*******************************************************************/
+extern "C" void DAPI Dutil_RootFailure(
+ __in_z LPCSTR szFile,
+ __in int iLine,
+ __in HRESULT hrError
+ )
+{
+#ifndef DEBUG
+ UNREFERENCED_PARAMETER(szFile);
+ UNREFERENCED_PARAMETER(iLine);
+ UNREFERENCED_PARAMETER(hrError);
+#endif // DEBUG
+
+ TraceError2(hrError, "Root failure at %s:%d", szFile, iLine);
+}
+
+/*******************************************************************
+ LoadSystemLibrary - Fully qualifies the path to a module in the
+ Windows system directory and loads it.
+
+ Returns
+ E_MODNOTFOUND - The module could not be found.
+ * - Another error occured.
+********************************************************************/
+extern "C" HRESULT DAPI LoadSystemLibrary(
+ __in_z LPCWSTR wzModuleName,
+ __out HMODULE *phModule
+ )
+{
+ HRESULT hr = S_OK;
+ DWORD cch = 0;
+ WCHAR wzPath[MAX_PATH] = { };
+
+ cch = ::GetSystemDirectoryW(wzPath, MAX_PATH);
+ ExitOnNullWithLastError(cch, hr, "Failed to get the Windows system directory.");
+
+ if (L'\\' != wzPath[cch - 1])
+ {
+ hr = ::StringCchCatNW(wzPath, MAX_PATH, L"\\", 1);
+ ExitOnRootFailure(hr, "Failed to terminate the string with a backslash.");
+ }
+
+ hr = ::StringCchCatW(wzPath, MAX_PATH, wzModuleName);
+ ExitOnRootFailure1(hr, "Failed to create the fully-qualified path to %ls.", wzModuleName);
+
+ *phModule = ::LoadLibraryW(wzPath);
+ ExitOnNullWithLastError1(*phModule, hr, "Failed to load the library %ls.", wzModuleName);
+
+LExit:
+ return hr;
+}

Powered by Google App Engine
This is Rietveld