[APPHELP] Use DbgPrint instead of OutputDebugString + fix SDBAPI_DEBUG_ALLOC
[reactos.git] / reactos / dll / appcompat / apphelp / apphelp.c
index 158433b..bcc14da 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2011 André Hentschel
  * Copyright 2013 Mislav Blažević
- * Copyright 2015 Mark Jansen
+ * Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -24,8 +24,9 @@
 #include "winver.h"
 #include "strsafe.h"
 #include "apphelp.h"
+#include "ndk/rtlfuncs.h"
+#include "ndk/kdtypes.h"
 
-#include "wine/winternl.h"
 
 /* from dpfilter.h */
 #define DPFLTR_APPCOMPAT_ID 123
 #endif
 
 ULONG g_ShimDebugLevel = 0xffffffff;
+HMODULE g_hInstance;
 
 void ApphelppInitDebugLevel(void)
 {
-    UNICODE_STRING DebugKey, DebugValue;
+    static const UNICODE_STRING DebugKey = RTL_CONSTANT_STRING(L"SHIM_DEBUG_LEVEL");
+    UNICODE_STRING DebugValue;
     NTSTATUS Status;
     ULONG NewLevel = SHIM_ERR;
     WCHAR Buffer[40];
 
-    RtlInitUnicodeString(&DebugKey, L"SHIM_DEBUG_LEVEL");
-    DebugValue.MaximumLength = sizeof(Buffer);
-    DebugValue.Buffer = Buffer;
-    DebugValue.Length = 0;
+    RtlInitEmptyUnicodeString(&DebugValue, Buffer, sizeof(Buffer));
 
-    /* Hold the lock as short as possible. */
-    RtlAcquirePebLock();
     Status = RtlQueryEnvironmentVariable_U(NULL, &DebugKey, &DebugValue);
-    RtlReleasePebLock();
 
     if (NT_SUCCESS(Status))
     {
@@ -61,6 +58,7 @@ void ApphelppInitDebugLevel(void)
     g_ShimDebugLevel = NewLevel;
 }
 
+
 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
 {
     switch (reason)
@@ -70,6 +68,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
             return FALSE;    /* prefer native version */
 #endif
         case DLL_PROCESS_ATTACH:
+            g_hInstance = hinst;
             DisableThreadLibraryCalls( hinst );
             SdbpHeapInit();
             break;
@@ -82,11 +81,24 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
 
 BOOL WINAPI ApphelpCheckInstallShieldPackage(void* ptr, LPCWSTR path)
 {
-    SHIM_WARN("stub: ptr=%p path='%S'\r\n", ptr, path);
+    SHIM_WARN("stub: ptr=%p, path='%S'\r\n", ptr, path);
     return TRUE;
 }
 
 
+BOOL WINAPI ApphelpCheckShellObject(REFCLSID ObjectCLSID, BOOL bShimIfNecessary, ULONGLONG *pullFlags)
+{
+    WCHAR GuidString[100];
+    if (!ObjectCLSID || !SdbGUIDToString(ObjectCLSID, GuidString, 100))
+        GuidString[0] = L'\0';
+    SHIM_WARN("stub: ObjectCLSID='%S', bShimIfNecessary=%d, pullFlags=%p)\n", GuidString, bShimIfNecessary, pullFlags);
+
+    if (pullFlags)
+        *pullFlags = 0;
+
+    return TRUE;
+}
+
 /**
  * Outputs diagnostic info.
  *
@@ -132,14 +144,115 @@ BOOL WINAPIV ShimDbgPrint(SHIM_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format
         break;
     }
     StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s][%-20s] ", LevelStr, FunctionName);
+
     va_start(ArgList, Format);
     StringCchVPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, Format, ArgList);
     va_end(ArgList);
+
 #if defined(APPCOMPAT_USE_DBGPRINTEX) && APPCOMPAT_USE_DBGPRINTEX
     return NT_SUCCESS(DbgPrintEx(DPFLTR_APPCOMPAT_ID, Level, "%s", Buffer));
 #else
-    OutputDebugStringA(Buffer);
+    DbgPrint("%s", Buffer);
     return TRUE;
 #endif
 }
 
+
+#define APPHELP_DONTWRITE_REASON    2
+#define APPHELP_CLEARBITS           0x100   /* TODO: Investigate */
+#define APPHELP_IGNORE_ENVIRONMENT  0x400
+
+#define APPHELP_VALID_RESULT        0x10000
+#define APPHELP_RESULT_NOTFOUND     0x20000
+#define APPHELP_RESULT_FOUND        0x40000
+
+/**
+ * Lookup Shims / Fixes for the specified application
+ *
+ * @param [in]  FileHandle                  Handle to the file to check.
+ * @param [in]  Unk1
+ * @param [in]  Unk2
+ * @param [in]  ApplicationName             Exe to check
+ * @param [in]  Environment                 The environment variables to use, or NULL to use the current environment.
+ * @param [in]  ExeType                     Exe type (MACHINE_TYPE_XXXX)
+ * @param [in,out]  Reason                  Input/output flags
+ * @param [in]  SdbQueryAppCompatData       The resulting data.
+ * @param [in]  SdbQueryAppCompatDataSize   The resulting data size.
+ * @param [in]  SxsData                     TODO
+ * @param [in]  SxsDataSize                 TODO
+ * @param [in]  FusionFlags                 TODO
+ * @param [in]  SomeFlag1                   TODO
+ * @param [in]  SomeFlag2                   TODO
+ *
+ * @return  TRUE if the application is allowed to run.
+ */
+BOOL
+WINAPI
+ApphelpCheckRunAppEx(
+    _In_ HANDLE FileHandle,
+    _In_opt_ PVOID Unk1,
+    _In_opt_ PVOID Unk2,
+    _In_opt_z_ PWCHAR ApplicationName,
+    _In_opt_ PVOID Environment,
+    _In_opt_ USHORT ExeType,
+    _Inout_opt_ PULONG Reason,
+    _Out_opt_ PVOID* SdbQueryAppCompatData,
+    _Out_opt_ PULONG SdbQueryAppCompatDataSize,
+    _Out_opt_ PVOID* SxsData,
+    _Out_opt_ PULONG SxsDataSize,
+    _Out_opt_ PULONG FusionFlags,
+    _Out_opt_ PULONG64 SomeFlag1,
+    _Out_opt_ PULONG SomeFlag2)
+{
+    SDBQUERYRESULT* result = NULL;
+    HSDB hsdb = NULL;
+    DWORD dwFlags = 0;
+
+    if (SxsData)
+        *SxsData = NULL;
+    if (SxsDataSize)
+        *SxsDataSize = 0;
+    if (FusionFlags)
+        *FusionFlags = 0;
+    if (SomeFlag1)
+        *SomeFlag1 = 0;
+    if (SomeFlag2)
+        *SomeFlag2 = 0;
+    if (Reason)
+        dwFlags = *Reason;
+
+    dwFlags &= ~APPHELP_CLEARBITS;
+
+    *SdbQueryAppCompatData = result = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SDBQUERYRESULT));
+    if (SdbQueryAppCompatDataSize)
+        *SdbQueryAppCompatDataSize = sizeof(*result);
+
+
+    hsdb = SdbInitDatabase(HID_DOS_PATHS | SDB_DATABASE_MAIN_SHIM, NULL);
+    if (hsdb)
+    {
+        BOOL FoundMatch;
+        DWORD MatchingExeFlags = 0;
+
+        if (dwFlags & APPHELP_IGNORE_ENVIRONMENT)
+            MatchingExeFlags |= SDBGMEF_IGNORE_ENVIRONMENT;
+
+        FoundMatch = SdbGetMatchingExe(hsdb, ApplicationName, NULL, Environment, MatchingExeFlags, result);
+        if (FileHandle != INVALID_HANDLE_VALUE)
+        {
+            dwFlags |= APPHELP_VALID_RESULT;
+            dwFlags |= (FoundMatch ? APPHELP_RESULT_FOUND : APPHELP_RESULT_NOTFOUND);
+        }
+
+        SdbReleaseDatabase(hsdb);
+    }
+
+    if (Reason && !(dwFlags & APPHELP_DONTWRITE_REASON))
+        *Reason = dwFlags;
+
+
+    /* We should _ALWAYS_ return TRUE here, unless we want to block an application from starting! */
+    return TRUE;
+}
+
+