[SHIMLIB] Add debug print functionality for shims. CORE-11329
authorMark Jansen <mark.jansen@reactos.org>
Sun, 16 Jul 2017 13:50:23 +0000 (13:50 +0000)
committerMark Jansen <mark.jansen@reactos.org>
Sun, 16 Jul 2017 13:50:23 +0000 (13:50 +0000)
svn path=/trunk/; revision=75358

reactos/dll/appcompat/apphelp/shimeng.c
reactos/dll/appcompat/shims/shimlib/shimlib.c
reactos/dll/appcompat/shims/shimlib/shimlib.h

index c04d5d3..b6bf2e8 100644 (file)
@@ -19,6 +19,7 @@
 #define WIN32_NO_STATUS
 #include "windows.h"
 #include "ntndk.h"
+#define IN_APPHELP
 #include "shimlib.h"
 #include <strsafe.h>
 /* Make sure we don't include apphelp logging */
index 65aed84..b5f04c2 100644 (file)
@@ -3,13 +3,15 @@
  * PROJECT:         ReactOS Shim library
  * FILE:            dll/appcompat/shims/shimlib/shimlib.c
  * PURPOSE:         Shim helper functions
- * PROGRAMMER:      Mark Jansen
+ * PROGRAMMER:      Mark Jansen (mark.jansen@reactos.org)
  */
 
+#define WIN32_NO_STATUS
 #include <windef.h>
 #include <winbase.h>
 #include <shimlib.h>
 #include <strsafe.h>
+#include <ndk/rtlfuncs.h>
 
 typedef struct UsedShim
 {
@@ -21,6 +23,7 @@ typedef struct UsedShim
 } UsedShim, *pUsedShim;
 
 
+ULONG g_ShimEngDebugLevel = 0xffffffff;
 static HANDLE g_ShimLib_Heap;
 static PSLIST_HEADER g_UsedShims;
 
@@ -146,3 +149,89 @@ BOOL WINAPI ShimLib_NotifyShims(DWORD fdwReason, PVOID ptr)
 
     return TRUE;
 }
+
+
+VOID SeiInitDebugSupport(VOID)
+{
+    static const UNICODE_STRING DebugKey = RTL_CONSTANT_STRING(L"SHIM_DEBUG_LEVEL");
+    UNICODE_STRING DebugValue;
+    NTSTATUS Status;
+    ULONG NewLevel = 0;
+    WCHAR Buffer[40];
+
+    RtlInitEmptyUnicodeString(&DebugValue, Buffer, sizeof(Buffer));
+
+    Status = RtlQueryEnvironmentVariable_U(NULL, &DebugKey, &DebugValue);
+
+    if (NT_SUCCESS(Status))
+    {
+        if (!NT_SUCCESS(RtlUnicodeStringToInteger(&DebugValue, 10, &NewLevel)))
+            NewLevel = 0;
+    }
+    g_ShimEngDebugLevel = NewLevel;
+}
+
+
+/**
+* Outputs diagnostic info.
+*
+* @param [in]  Level           The level to log this message with, choose any of [SHIM_ERR,
+*                              SHIM_WARN, SHIM_INFO].
+* @param [in]  FunctionName    The function this log should be attributed to.
+* @param [in]  Format          The format string.
+* @param   ...                 Variable arguments providing additional information.
+*
+* @return  Success: TRUE Failure: FALSE.
+*/
+BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR Function, PCSTR Format, ...)
+{
+    char Buffer[512];
+    char* Current = Buffer;
+    const char* LevelStr;
+    size_t Length = sizeof(Buffer);
+    va_list ArgList;
+    HRESULT hr;
+
+    if (g_ShimEngDebugLevel == 0xffffffff)
+        SeiInitDebugSupport();
+
+    if (Level > g_ShimEngDebugLevel)
+        return FALSE;
+
+    switch (Level)
+    {
+    case SEI_MSG:
+        LevelStr = "MSG ";
+        break;
+    case SEI_FAIL:
+        LevelStr = "FAIL";
+        break;
+    case SEI_WARN:
+        LevelStr = "WARN";
+        break;
+    case SEI_INFO:
+        LevelStr = "INFO";
+        break;
+    default:
+        LevelStr = "USER";
+        break;
+    }
+
+    if (Function)
+        hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] [%s] ", LevelStr, Function);
+    else
+        hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] ", LevelStr);
+
+    if (!SUCCEEDED(hr))
+        return FALSE;
+
+    va_start(ArgList, Format);
+    hr = StringCchVPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, Format, ArgList);
+    va_end(ArgList);
+    if (!SUCCEEDED(hr))
+        return FALSE;
+
+    DbgPrint("%s", Buffer);
+    return TRUE;
+}
+
index 6f1efd9..8372b05 100644 (file)
@@ -3,7 +3,7 @@
  * PROJECT:         ReactOS Shim Engine
  * FILE:            dll/appcompat/shims/shimlib/shimlib.h
  * PURPOSE:         ReactOS Shim Engine
- * PROGRAMMER:      Mark Jansen
+ * PROGRAMMER:      Mark Jansen (mark.jansen@reactos.org)
  */
 
 #pragma once
@@ -58,12 +58,19 @@ typedef enum _SEI_LOG_LEVEL {
 BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR Function, PCSTR Format, ...);
 extern ULONG g_ShimEngDebugLevel;
 
+#if defined(IN_APPHELP)
+/* Apphelp shimeng logging uses the function name */
 #define SHIMENG_MSG(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_MSG, __FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
 #define SHIMENG_FAIL(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_FAIL, __FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
 #define SHIMENG_WARN(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_WARN, __FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
 #define SHIMENG_INFO(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_INFO, __FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
-
-
+#else
+/* Shims use the shim name */
+#define SHIM_MSG(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_MSG, SHIM_OBJ_NAME(g_szModuleName), fmt, ##__VA_ARGS__ ); } while (0)
+#define SHIM_FAIL(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_FAIL, SHIM_OBJ_NAME(g_szModuleName), fmt, ##__VA_ARGS__ ); } while (0)
+#define SHIM_WARN(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_WARN, SHIM_OBJ_NAME(g_szModuleName), fmt, ##__VA_ARGS__ ); } while (0)
+#define SHIM_INFO(fmt, ...)  do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_INFO, SHIM_OBJ_NAME(g_szModuleName), fmt, ##__VA_ARGS__ ); } while (0)
+#endif
 
 typedef PHOOKAPI (WINAPI* _PVGetHookAPIs)(DWORD, PCSTR, PDWORD);
 typedef BOOL (WINAPI* _PVNotify)(DWORD, PVOID);