/*
* 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
#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))
{
g_ShimDebugLevel = NewLevel;
}
+
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
switch (reason)
return FALSE; /* prefer native version */
#endif
case DLL_PROCESS_ATTACH:
+ g_hInstance = hinst;
DisableThreadLibraryCalls( hinst );
SdbpHeapInit();
break;
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.
*
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;
+}
+
+