CoreWindowX Fix (#80)

* winrt_x no more needs to put *too many* dll in the game folder

* Implement FrameworkView and FrameworkViewSource Wrappers to fix CoreWindowX Leaking
This commit is contained in:
AleBlbl
2025-01-03 00:37:16 +01:00
committed by GitHub
parent 71e45dc8f4
commit bcca557c6e
11 changed files with 310 additions and 67 deletions

View File

@@ -1,5 +1,6 @@
#include "pch.h"
#include "CoreApplicationWrapperX.h"
#include "FrameworkViewSourceWrapper.h"
HRESULT CoreApplicationWrapperX::GetIids(ULONG* iidCount, IID** iids)
{
@@ -22,7 +23,8 @@ HRESULT CoreApplicationWrapperX::GetTrustLevel(TrustLevel* trustLevel)
INT32 CoreApplicationWrapperX::_abi_add_Resuming(__FIEventHandler_1_IInspectable* handler, EventRegistrationToken* token)
{
printf("_abi_add_Resuming\n");
return m_realCoreApplication->add_Resuming(handler, token);
//return m_realCoreApplication->add_Resuming(handler, token);
return S_OK;
}
INT32 CoreApplicationWrapperX::_abi_remove_Resuming(EventRegistrationToken token)
@@ -34,7 +36,8 @@ INT32 CoreApplicationWrapperX::_abi_remove_Resuming(EventRegistrationToken token
INT32 CoreApplicationWrapperX::_abi_add_Suspending(__FIEventHandler_1_Windows__CApplicationModel__CSuspendingEventArgs* handler, EventRegistrationToken* token)
{
printf("_abi_add_Suspending\n");
return m_realCoreApplication->add_Suspending(handler, token);
//return m_realCoreApplication->add_Suspending(handler, token);
return S_OK;
}
INT32 CoreApplicationWrapperX::_abi_remove_Suspending(EventRegistrationToken token)
@@ -67,14 +70,17 @@ HRESULT CoreApplicationWrapperX::_abi_remove_ResourceAvailabilityChanged(EventRe
INT32 CoreApplicationWrapperX::_abi_GetCurrentView(ABI::Windows::ApplicationModel::Core::ICoreApplicationView** value)
{
printf("_abi_GetCurrentView\n");
printf("[CoreApplicationWrapperX] ---> _abi_GetCurrentView\n");
return m_realCoreApplication->GetCurrentView(value);
}
INT32 CoreApplicationWrapperX::_abi_Run(ABI::Windows::ApplicationModel::Core::IFrameworkViewSource* viewSource)
{
printf("_abi_Run\n");
return m_realCoreApplication->Run(viewSource);
// Wrap the ViewSource and pass it to the original function
FrameworkViewSourceWrapper* wrappedViewSource = new FrameworkViewSourceWrapper(viewSource);
return m_realCoreApplication->Run(wrappedViewSource);
}
INT32 CoreApplicationWrapperX::_abi_get_Id(HSTRING* value)
@@ -109,9 +115,21 @@ HRESULT CoreApplicationWrapperX::QueryInterface(const IID& riid, void** ppvObjec
*ppvObject = static_cast<ICoreApplicationResourceAvailabilityX*>(this);
AddRef();
return S_OK;
}
// DEBUG
HRESULT hr = m_realFactory->QueryInterface(riid, ppvObject);
if(FAILED(hr))
{
char iidstr[sizeof("{AAAAAAAA-BBBB-CCCC-DDEE-FFGGHHIIJJKK}")];
OLECHAR iidwstr[sizeof(iidstr)];
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
MessageBoxA(nullptr, iidstr, typeid(*this).name(), MB_OK);
}
return m_realFactory->QueryInterface(riid, ppvObject);
*ppvObject = nullptr;
return E_NOINTERFACE;
}
ULONG CoreApplicationWrapperX::AddRef()

View File

@@ -1,10 +1,10 @@
#pragma once
#include "ICoreApplicationX.h"
class CoreApplicationWrapperX : public RuntimeClass<ICoreApplicationX, IActivationFactory, ICoreApplicationResourceAvailabilityX>
class CoreApplicationWrapperX : public RuntimeClass<IActivationFactory, ICoreApplicationResourceAvailabilityX, ICoreApplicationX>
{
public:
CoreApplicationWrapperX(ComPtr<IActivationFactory> realFactory)
: m_realFactory(realFactory)
{
@@ -20,7 +20,7 @@ public:
return m_realFactory->ActivateInstance(instance);
}
public:
// ICoreApplicationX
INT32 _abi_get_Id(HSTRING* value) override;
INT32 _abi_add_Suspending(__FIEventHandler_1_Windows__CApplicationModel__CSuspendingEventArgs* handler, EventRegistrationToken* token) override;
@@ -49,5 +49,5 @@ private:
long m_refCount = 1;
ComPtr<IActivationFactory> m_realFactory;
ComPtr<ICoreApplication> m_realCoreApplication; // ICoreApplication to forward the calls
};

View File

@@ -3,16 +3,19 @@
HRESULT CoreWindowWrapperX::GetIids(ULONG* iidCount, IID** iids)
{
printf("[CoreWindowWrapperX] --> GetIids\n");
return m_realWindow->GetIids(iidCount, iids);
}
HRESULT CoreWindowWrapperX::GetRuntimeClassName(HSTRING* className)
{
printf("[CoreWindowWrapperX] --> GetRuntimeClassName\n");
return m_realWindow->GetRuntimeClassName(className);
}
HRESULT CoreWindowWrapperX::GetTrustLevel(TrustLevel* trustLevel)
{
printf("[CoreWindowWrapperX] --> GetTrustLevel\n");
return m_realWindow->GetTrustLevel(trustLevel);
}
@@ -87,7 +90,12 @@ INT32 CoreWindowWrapperX::_abi_add_CharacterReceived(ITypedEventHandler<CoreWind
EventRegistrationToken* token)
{
printf("[CoreWindowWrapperX] --> _abi_add_CharacterReceived\n");
return m_realWindow->add_CharacterReceived(handler, token);
// STUB
*token = EventRegistrationToken();
return S_OK;
//return m_realWindow->add_CharacterReceived(handler, token);
}
INT32 CoreWindowWrapperX::_abi_remove_CharacterReceived(EventRegistrationToken token)
@@ -100,7 +108,12 @@ INT32 CoreWindowWrapperX::_abi_add_Closed(ITypedEventHandler<CoreWindow*, CoreWi
EventRegistrationToken* token)
{
printf("[CoreWindowWrapperX] --> _abi_add_Closed\n");
return m_realWindow->add_Closed(handler, token);
// STUB
*token = EventRegistrationToken();
return S_OK;
//return m_realWindow->add_Closed(handler, token);
}
INT32 CoreWindowWrapperX::_abi_remove_Closed(EventRegistrationToken token)
@@ -126,7 +139,12 @@ INT32 CoreWindowWrapperX::_abi_add_KeyDown(ITypedEventHandler<CoreWindow*, KeyEv
EventRegistrationToken* token)
{
printf("[CoreWindowWrapperX] --> _abi_add_KeyDown\n");
return m_realWindow->add_KeyDown(handler, token);
// STUB
*token = EventRegistrationToken();
return S_OK;
//return m_realWindow->add_KeyDown(handler, token);
}
INT32 CoreWindowWrapperX::_abi_remove_KeyDown(EventRegistrationToken token)
@@ -139,7 +157,12 @@ INT32 CoreWindowWrapperX::_abi_add_KeyUp(ITypedEventHandler<CoreWindow*, KeyEven
EventRegistrationToken* token)
{
printf("[CoreWindowWrapperX] --> _abi_add_KeyUp\n");
return m_realWindow->add_KeyUp(handler, token);
// STUB
*token = EventRegistrationToken();
return S_OK;
//return m_realWindow->add_KeyUp(handler, token);
}
INT32 CoreWindowWrapperX::_abi_remove_KeyUp(EventRegistrationToken token)
@@ -215,22 +238,32 @@ INT32 CoreWindowWrapperX::_abi_remove_VisibilityChanged(EventRegistrationToken t
HRESULT CoreWindowWrapperX::QueryInterface(const IID& riid, void** ppvObject)
{
if (riid == __uuidof(ICoreWindow) || true)
printf("[CoreWindowWrapperX] --> QueryInterface\n");
if (riid == __uuidof(IUnknown) ||
riid == __uuidof(IInspectable) ||
riid == __uuidof(ICoreWindow) ||
riid == __uuidof(IAgileObject))
{
*ppvObject = static_cast<ICoreWindowX*>(this);
*ppvObject = this;
AddRef();
return S_OK;
}
return m_realWindow->QueryInterface(riid, ppvObject);
*ppvObject = nullptr;
return E_NOINTERFACE;
//return m_realWindow->QueryInterface(riid, ppvObject);
}
ULONG CoreWindowWrapperX::AddRef()
{
printf("[CoreWindowWrapperX] --> AddRef\n");
return InterlockedIncrement(&m_refCount);
}
ULONG CoreWindowWrapperX::Release()
{
printf("[CoreWindowWrapperX] --> Release\n");
ULONG refCount = InterlockedDecrement(&m_refCount);
if (refCount == 0) delete this;
return refCount;

View File

@@ -0,0 +1,65 @@
#include "pch.h"
#include "FrameworkViewSourceWrapper.h"
#include "FrameworkViewWrapper.h"
HRESULT __stdcall FrameworkViewSourceWrapper::CreateView(ABI::Windows::ApplicationModel::Core::IFrameworkView** viewProvider)
{
auto hr = m_realViewSource->CreateView(viewProvider);
if (SUCCEEDED(hr))
*viewProvider = new FrameworkViewWrapper(*viewProvider);
return hr;
}
HRESULT FrameworkViewSourceWrapper::QueryInterface(const IID& riid, void** ppvObject)
{
if (riid == __uuidof(IFrameworkViewSource))
{
*ppvObject = this;
AddRef();
return S_OK;
}
else
{
// DEBUG
char iidstr[sizeof("{AAAAAAAA-BBBB-CCCC-DDEE-FFGGHHIIJJKK}")];
OLECHAR iidwstr[sizeof(iidstr)];
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
MessageBoxA(nullptr, iidstr, typeid(*this).name(), MB_OK);
}
return m_realViewSource->QueryInterface(riid, ppvObject);
}
ULONG FrameworkViewSourceWrapper::AddRef()
{
return InterlockedIncrement(&m_refCount);
}
ULONG FrameworkViewSourceWrapper::Release()
{
ULONG refCount = InterlockedDecrement(&m_refCount);
if (refCount == 0)
delete this;
return refCount;
}
HRESULT FrameworkViewSourceWrapper::GetIids(ULONG* iidCount, IID** iids)
{
return m_realViewSource->GetIids(iidCount, iids);
}
HRESULT FrameworkViewSourceWrapper::GetRuntimeClassName(HSTRING* className)
{
return m_realViewSource->GetRuntimeClassName(className);
}
HRESULT FrameworkViewSourceWrapper::GetTrustLevel(TrustLevel* trustLevel)
{
return m_realViewSource->GetTrustLevel(trustLevel);
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "ICoreApplicationX.h"
class FrameworkViewSourceWrapper : public IFrameworkViewSource
{
public:
FrameworkViewSourceWrapper(IFrameworkViewSource* windowViewSource)
: m_realViewSource(windowViewSource)
{
}
HRESULT STDMETHODCALLTYPE CreateView(ABI::Windows::ApplicationModel::Core::IFrameworkView** viewProvider) override;
// IActivationFactory (IInspectable + IUnknown)
HRESULT QueryInterface(const IID& riid, void** ppvObject) override;
ULONG AddRef() override;
ULONG Release() override;
HRESULT GetIids(ULONG* iidCount, IID** iids) override;
HRESULT GetRuntimeClassName(HSTRING* className) override;
HRESULT GetTrustLevel(TrustLevel* trustLevel) override;
private:
long m_refCount = 1;
IFrameworkViewSource* m_realViewSource;
};

View File

@@ -0,0 +1,83 @@
#include "pch.h"
#include "FrameworkViewWrapper.h"
HRESULT __stdcall FrameworkViewWrapper::Initialize(ABI::Windows::ApplicationModel::Core::ICoreApplicationView* applicationView)
{
return m_realView->Initialize(applicationView);
}
HRESULT __stdcall FrameworkViewWrapper::SetWindow(ABI::Windows::UI::Core::ICoreWindow* window)
{
// Finally Wraps the coreWindow with xbox CoreWindow
window = reinterpret_cast<ICoreWindow*>(new CoreWindowWrapperX((CoreWindow*)window));
return m_realView->SetWindow(window);
}
HRESULT __stdcall FrameworkViewWrapper::Load(HSTRING entryPoint)
{
return m_realView->Load(entryPoint);
}
HRESULT __stdcall FrameworkViewWrapper::Run(void)
{
return m_realView->Run();
}
HRESULT __stdcall FrameworkViewWrapper::Uninitialize(void)
{
return m_realView->Uninitialize();
}
HRESULT FrameworkViewWrapper::QueryInterface(const IID& riid, void** ppvObject)
{
if (riid == __uuidof(IFrameworkView) ||
riid == __uuidof(IUnknown) ||
riid == __uuidof(IInspectable))
{
*ppvObject = this;
AddRef();
return S_OK;
}
else
{
/*/ DEBUG
char iidstr[sizeof("{AAAAAAAA-BBBB-CCCC-DDEE-FFGGHHIIJJKK}")];
OLECHAR iidwstr[sizeof(iidstr)];
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
MessageBoxA(nullptr, iidstr, typeid(*this).name(), MB_OK);*/
}
return m_realView->QueryInterface(riid, ppvObject);
}
ULONG FrameworkViewWrapper::AddRef()
{
return InterlockedIncrement(&m_refCount);
}
ULONG FrameworkViewWrapper::Release()
{
ULONG refCount = InterlockedDecrement(&m_refCount);
if (refCount == 0)
delete this;
return refCount;
}
HRESULT FrameworkViewWrapper::GetIids(ULONG* iidCount, IID** iids)
{
return m_realView->GetIids(iidCount, iids);
}
HRESULT FrameworkViewWrapper::GetRuntimeClassName(HSTRING* className)
{
return m_realView->GetRuntimeClassName(className);
}
HRESULT FrameworkViewWrapper::GetTrustLevel(TrustLevel* trustLevel)
{
return m_realView->GetTrustLevel(trustLevel);
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include "ICoreApplicationX.h"
class FrameworkViewWrapper : public IFrameworkView
{
public:
FrameworkViewWrapper(IFrameworkView* windowView)
: m_realView(windowView)
{
}
HRESULT STDMETHODCALLTYPE Initialize(ABI::Windows::ApplicationModel::Core::ICoreApplicationView* applicationView) override;
HRESULT STDMETHODCALLTYPE SetWindow(ABI::Windows::UI::Core::ICoreWindow* window) override;
HRESULT STDMETHODCALLTYPE Load(HSTRING entryPoint) override;
HRESULT STDMETHODCALLTYPE Run(void) override;
HRESULT STDMETHODCALLTYPE Uninitialize(void) override;
// IActivationFactory (IInspectable + IUnknown)
HRESULT QueryInterface(const IID& riid, void** ppvObject) override;
ULONG AddRef() override;
ULONG Release() override;
HRESULT GetIids(ULONG* iidCount, IID** iids) override;
HRESULT GetRuntimeClassName(HSTRING* className) override;
HRESULT GetTrustLevel(TrustLevel* trustLevel) override;
private:
long m_refCount = 1;
IFrameworkView* m_realView;
};

View File

@@ -1,10 +1,14 @@
#pragma once
#include <winrt/Windows.ApplicationModel.h>
#include "utils.h"
#include "CoreApplicationWrapperX.h"
#include <windows.applicationmodel.core.h>
#define IsXboxCallee() IsXboxAddress(_ReturnAddress())
/* This function is used to compare the class name of the classId with the classIdName. */
inline bool IsClassName(HSTRING classId, const char* classIdName)
{
@@ -28,44 +32,6 @@ DllGetActivationFactoryFunc pDllGetActivationFactory = nullptr;
/* Function pointers for the WinRT RoGetActivationFactory function. */
HRESULT(WINAPI* TrueRoGetActivationFactory)(HSTRING classId, REFIID iid, void** factory) = RoGetActivationFactory;
BOOL IsXboxModule(HMODULE module)
{
wchar_t moduleFilePath[MAX_PATH];
if (GetModuleFileNameW(module, moduleFilePath, MAX_PATH) > 0)
{
std::wstring moduleFileName(moduleFilePath);
wprintf(L"%ls\n", moduleFileName.c_str());
wchar_t exeFilePath[MAX_PATH];
if (GetModuleFileNameW(NULL, exeFilePath, MAX_PATH) > 0)
{
std::wstring exeDir(exeFilePath);
size_t pos = exeDir.find_last_of(L"\\/");
if (pos != std::wstring::npos) {
exeDir = exeDir.substr(0, pos);
}
if (moduleFileName.find(exeDir) == 0) {
return TRUE;
}
}
}
return FALSE;
}
BOOL IsXboxAddress(PVOID Address)
{
HMODULE Module;
// Technically this should also use 'GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT'
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)Address, &Module))
return FALSE;
return IsXboxModule(Module);
}
// The hook function for GetForCurrentThread
HRESULT STDMETHODCALLTYPE GetForCurrentThread_Hook(ICoreWindowStatic* pThis, CoreWindow** ppWindow)
@@ -75,17 +41,15 @@ HRESULT STDMETHODCALLTYPE GetForCurrentThread_Hook(ICoreWindowStatic* pThis, Cor
{
return hr;
}
if (*ppWindow == NULL)
return hr;
// if GetForCurrentThread is called from xbox code we wrap it with the xbox ICoreWindow
if (IsXboxAddress(_ReturnAddress()))
{
if (IsXboxCallee())
*reinterpret_cast<ICoreWindowX**>(ppWindow) = new CoreWindowWrapperX(*ppWindow);
return S_OK;
}
return hr;
}
@@ -102,7 +66,7 @@ inline HRESULT WINAPI RoGetActivationFactory_Hook(HSTRING classId, REFIID iid, v
wprintf(L"%ls\n", rawString);
}
auto hr = 0;
if (IsClassName(classId, "Windows.ApplicationModel.Core.CoreApplication"))
{
ComPtr<IActivationFactory> realFactory;
@@ -113,11 +77,10 @@ inline HRESULT WINAPI RoGetActivationFactory_Hook(HSTRING classId, REFIID iid, v
return hr;
ComPtr<CoreApplicationWrapperX> wrappedFactory = Make<CoreApplicationWrapperX>(realFactory);
return wrappedFactory.CopyTo(iid, factory);
}
if (IsClassName(classId, "Windows.UI.Core.CoreWindow"))
else if (IsClassName(classId, "Windows.UI.Core.CoreWindow"))
{
//
// for now we just hook GetForCurrentThread to get the CoreWindow but i'll change it later to

View File

@@ -96,6 +96,8 @@
<ClInclude Include="CoreApplicationWrapperX.h" />
<ClInclude Include="CoreWindowWrapperX.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="FrameworkViewSourceWrapper.h" />
<ClInclude Include="FrameworkViewWrapper.h" />
<ClInclude Include="hooks.h" />
<ClInclude Include="ICoreApplicationResourceAvailabilityX.h" />
<ClInclude Include="ICoreApplicationX.h" />
@@ -108,6 +110,8 @@
<ClCompile Include="CoreApplicationWrapperX.cpp" />
<ClCompile Include="CoreWindowWrapperX.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="FrameworkViewSourceWrapper.cpp" />
<ClCompile Include="FrameworkViewWrapper.cpp" />
<ClCompile Include="kernelx.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>

View File

@@ -10,6 +10,12 @@
<ClCompile Include="CoreApplicationWrapperX.cpp">
<Filter>Windows.ApplicationModel.Core\CoreApplication</Filter>
</ClCompile>
<ClCompile Include="FrameworkViewWrapper.cpp">
<Filter>Windows.ApplicationModel.Core\FrameworkView</Filter>
</ClCompile>
<ClCompile Include="FrameworkViewSourceWrapper.cpp">
<Filter>Windows.ApplicationModel.Core\FrameworkViewSource</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
@@ -32,6 +38,12 @@
<ClInclude Include="ICoreApplicationResourceAvailabilityX.h">
<Filter>Windows.ApplicationModel.Core</Filter>
</ClInclude>
<ClInclude Include="FrameworkViewWrapper.h">
<Filter>Windows.ApplicationModel.Core\FrameworkView</Filter>
</ClInclude>
<ClInclude Include="FrameworkViewSourceWrapper.h">
<Filter>Windows.ApplicationModel.Core\FrameworkViewSource</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Exports.def" />
@@ -51,5 +63,11 @@
<Filter Include="Windows.ApplicationModel.Core\CoreApplication">
<UniqueIdentifier>{ee124397-8dbc-48c3-869f-10201a7d04fd}</UniqueIdentifier>
</Filter>
<Filter Include="Windows.ApplicationModel.Core\FrameworkView">
<UniqueIdentifier>{1dfef95c-7e52-4c34-862d-18e9cd60a9de}</UniqueIdentifier>
</Filter>
<Filter Include="Windows.ApplicationModel.Core\FrameworkViewSource">
<UniqueIdentifier>{c767c192-a92b-4536-b8a9-51f27fa78800}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@@ -12,8 +12,6 @@
<RootNamespace>winrt_x</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.22621.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>