Detect and warn reshade w/o addon support

This commit is contained in:
Soreepeong 2024-07-23 17:48:11 +09:00
parent 3598ea443e
commit 97069dff27
2 changed files with 75 additions and 14 deletions

View file

@ -8,6 +8,8 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using CheapLoc;
using Dalamud.Configuration.Internal;
using Dalamud.Game;
using Dalamud.Game.ClientState.GamePad;
@ -15,6 +17,7 @@ using Dalamud.Game.ClientState.Keys;
using Dalamud.Hooking;
using Dalamud.Hooking.Internal;
using Dalamud.Hooking.WndProcHook;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.ImGuiNotification.Internal;
using Dalamud.Interface.Internal.ManagedAsserts;
using Dalamud.Interface.Internal.ReShadeHandling;
@ -746,6 +749,9 @@ internal partial class InterfaceManager : IInternalDisposableService
_ = this.dalamudAtlas.BuildFontsAsync();
SwapChainHelper.BusyWaitForGameDeviceSwapChain();
var swapChainDesc = default(DXGI_SWAP_CHAIN_DESC);
if (SwapChainHelper.GameDeviceSwapChain->GetDesc(&swapChainDesc).SUCCEEDED)
this.gameWindowHandle = swapChainDesc.OutputWindow;
try
{
@ -765,6 +771,28 @@ internal partial class InterfaceManager : IInternalDisposableService
0,
this.SetCursorDetour);
if (ReShadeAddonInterface.ReShadeHasSignature)
{
Log.Warning("Signed ReShade binary detected.");
Service<NotificationManager>
.GetAsync()
.ContinueWith(
nmt => nmt.Result.AddNotification(
new()
{
MinimizedText = Loc.Localize(
"ReShadeNoAddonSupportNotificationMinimizedText",
"Wrong ReShade installation"),
Content = Loc.Localize(
"ReShadeNoAddonSupportNotificationContent",
"Your installation of ReShade does not have full addon support, and may not work with Dalamud and/or the game.\n" +
"Download and install ReShade with full addon-support."),
Type = NotificationType.Warning,
InitialDuration = TimeSpan.MaxValue,
ShowIndeterminateIfNoExpiry = false,
}));
}
Log.Verbose("===== S W A P C H A I N =====");
if (this.dalamudConfiguration.ReShadeHandlingMode == ReShadeHandlingMode.UnwrapReShade)
{
@ -772,23 +800,25 @@ internal partial class InterfaceManager : IInternalDisposableService
Log.Verbose("Unwrapped ReShade.");
}
ResizeBuffersDelegate resizeBuffersDelegate;
DxgiPresentDelegate? dxgiPresentDelegate;
if (this.dalamudConfiguration.ReShadeHandlingMode == ReShadeHandlingMode.ReShadeAddon &&
ReShadeAddonInterface.TryRegisterAddon(out this.reShadeAddonInterface))
ResizeBuffersDelegate? resizeBuffersDelegate = null;
DxgiPresentDelegate? dxgiPresentDelegate = null;
if (this.dalamudConfiguration.ReShadeHandlingMode == ReShadeHandlingMode.ReShadeAddon)
{
resizeBuffersDelegate = this.AsReShadeAddonResizeBuffersDetour;
dxgiPresentDelegate = null;
if (ReShadeAddonInterface.TryRegisterAddon(out this.reShadeAddonInterface))
{
resizeBuffersDelegate = this.AsReShadeAddonResizeBuffersDetour;
Log.Verbose(
"Registered as a ReShade({name}: 0x{addr:X}) addon.",
ReShadeAddonInterface.ReShadeModule!.FileName,
ReShadeAddonInterface.ReShadeModule!.BaseAddress);
this.reShadeAddonInterface.InitSwapChain += this.ReShadeAddonInterfaceOnInitSwapChain;
this.reShadeAddonInterface.DestroySwapChain += this.ReShadeAddonInterfaceOnDestroySwapChain;
this.reShadeAddonInterface.ReShadeOverlay += this.ReShadeAddonInterfaceOnReShadeOverlay;
Log.Verbose(
"Registered as a ReShade({name}: 0x{addr:X}) addon.",
ReShadeAddonInterface.ReShadeModule!.FileName,
ReShadeAddonInterface.ReShadeModule!.BaseAddress);
this.reShadeAddonInterface.InitSwapChain += this.ReShadeAddonInterfaceOnInitSwapChain;
this.reShadeAddonInterface.DestroySwapChain += this.ReShadeAddonInterfaceOnDestroySwapChain;
this.reShadeAddonInterface.ReShadeOverlay += this.ReShadeAddonInterfaceOnReShadeOverlay;
}
}
else
if (resizeBuffersDelegate is null)
{
resizeBuffersDelegate = this.AsHookResizeBuffersDetour;
dxgiPresentDelegate = this.PresentDetour;

View file

@ -30,8 +30,35 @@ internal sealed unsafe partial class ReShadeAddonInterface
!GetProcAddressInto(m, nameof(e.ReShadeUnregisterEvent), &e.ReShadeUnregisterEvent))
continue;
fixed (void* pwszFile = m.FileName)
fixed (Guid* pguid = &WINTRUST_ACTION_GENERIC_VERIFY_V2)
{
var wtfi = new WINTRUST_FILE_INFO
{
cbStruct = (uint)sizeof(WINTRUST_FILE_INFO),
pcwszFilePath = (ushort*)pwszFile,
hFile = default,
pgKnownSubject = null,
};
var wtd = new WINTRUST_DATA
{
cbStruct = (uint)sizeof(WINTRUST_DATA),
pPolicyCallbackData = null,
pSIPClientData = null,
dwUIChoice = WTD.WTD_UI_NONE,
fdwRevocationChecks = WTD.WTD_REVOKE_NONE,
dwUnionChoice = WTD.WTD_STATEACTION_VERIFY,
hWVTStateData = default,
pwszURLReference = null,
dwUIContext = 0,
pFile = &wtfi,
};
ReShadeHasSignature = WinVerifyTrust(default, pguid, &wtd) != TRUST.TRUST_E_NOSIGNATURE;
}
ReShadeModule = m;
Exports = e;
return;
}
@ -49,6 +76,10 @@ internal sealed unsafe partial class ReShadeAddonInterface
/// <summary>Gets the active ReShade module.</summary>
public static ProcessModule? ReShadeModule { get; private set; }
/// <summary>Gets a value indicating whether the loaded ReShade has signatures.</summary>
/// <remarks>ReShade without addon support is signed, but may not pass signature verification.</remarks>
public static bool ReShadeHasSignature { get; private set; }
private struct ExportsStruct
{
public delegate* unmanaged<HMODULE, uint, bool> ReShadeRegisterAddon;