From 29fda7935dae4b5fb3c5360df4710bed9c0dd34a Mon Sep 17 00:00:00 2001 From: Amrsatrio Date: Fri, 6 Oct 2023 16:34:50 +0700 Subject: [PATCH] Start10: Revised the method of fixing Pin to Start/Unpin from Start --- ExplorerPatcher/StartMenuSettings.cpp | 56 ++++++++++++++++++-- ExplorerPatcher/dllmain.c | 75 ++------------------------- 2 files changed, 56 insertions(+), 75 deletions(-) diff --git a/ExplorerPatcher/StartMenuSettings.cpp b/ExplorerPatcher/StartMenuSettings.cpp index ab4acb3..0da5c99 100644 --- a/ExplorerPatcher/StartMenuSettings.cpp +++ b/ExplorerPatcher/StartMenuSettings.cpp @@ -155,6 +155,53 @@ extern "C" BOOL NeedsRo_SyncSettingsFromRegToCDS() return TRUE; } +namespace ABI::WindowsUdk::ApplicationModel::AppExtensions +{ + enum AppExtensionOptions {}; + + MIDL_INTERFACE("836da1ed-5be8-5365-8452-6af327aa427b") + IExtensionFactoryStatics : public IInspectable + { + virtual HRESULT STDMETHODCALLTYPE IsExtensionAvailable(HSTRING, HSTRING, bool*) = 0; + virtual HRESULT STDMETHODCALLTYPE IsExtensionAvailableWithOptions(HSTRING, HSTRING, AppExtensionOptions, bool*) = 0; + virtual HRESULT STDMETHODCALLTYPE GetInstance(HSTRING, HSTRING, IInspectable**) = 0; + virtual HRESULT STDMETHODCALLTYPE GetInstanceWithOptions(HSTRING, HSTRING, AppExtensionOptions, IInspectable**) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFactory(HSTRING, HSTRING, IInspectable**) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFactoryWithOptions(HSTRING, HSTRING, AppExtensionOptions, IInspectable**) = 0; + }; +} + +class DummyExtensionFactory : ABI::WindowsUdk::ApplicationModel::AppExtensions::IExtensionFactoryStatics +{ +public: + HRESULT QueryInterface(REFIID riid, void** ppvObject) override { return E_NOINTERFACE; } + ULONG AddRef() override { return 1; } + ULONG Release() override { return 1; } + HRESULT GetIids(ULONG* iidCount, IID** iids) override { return E_NOTIMPL; } + HRESULT GetRuntimeClassName(HSTRING* className) override { return E_NOTIMPL; } + HRESULT GetTrustLevel(TrustLevel* trustLevel) override { return E_NOTIMPL; } + + // Keep the value of result as zero (set by the caller) and return S_OK to make the Windows 10 code run + HRESULT IsExtensionAvailable(HSTRING, HSTRING, bool*) override { return S_OK; } + HRESULT IsExtensionAvailableWithOptions(HSTRING, HSTRING, ABI::WindowsUdk::ApplicationModel::AppExtensions::AppExtensionOptions, bool*) override { return S_OK; } + HRESULT GetInstance(HSTRING, HSTRING, IInspectable**) override { return S_OK; } + HRESULT GetInstanceWithOptions(HSTRING, HSTRING, ABI::WindowsUdk::ApplicationModel::AppExtensions::AppExtensionOptions, IInspectable**) override { return S_OK; } + HRESULT GetFactory(HSTRING, HSTRING, IInspectable**) override { return S_OK; } + HRESULT GetFactoryWithOptions(HSTRING, HSTRING, ABI::WindowsUdk::ApplicationModel::AppExtensions::AppExtensionOptions, IInspectable**) override { return S_OK; } +}; + +static const DummyExtensionFactory instanceof_WindowsUdk_ApplicationModel_AppExtensions_IExtensionFactoryStatics; + +extern "C" HRESULT AppResolver_StartTileData_RoGetActivationFactory(HSTRING activatableClassId, REFIID iid, void** factory) +{ + if (IsEqualGUID(iid, __uuidof(ABI::WindowsUdk::ApplicationModel::AppExtensions::IExtensionFactoryStatics))) + { + *factory = const_cast(&instanceof_WindowsUdk_ApplicationModel_AppExtensions_IExtensionFactoryStatics); + return S_OK; + } + return RoGetActivationFactory(activatableClassId, iid, factory); +} + namespace ABI::WindowsInternal::Shell::UnifiedTile { MIDL_INTERFACE("d3653510-4fff-4bfa-905b-ea038b142fa5") @@ -284,18 +331,17 @@ namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections struct CCacheShortcut { -public: const wchar_t* GetAppID(const void* a2) const { - DWORD dwOffset = *((DWORD*)this + 11); // Same offset in Windows 10 and 11 + DWORD dwOffset = *(DWORD*)((PBYTE)this + 44); // Same offset in Windows 10 and 11 return dwOffset != -1 ? (wchar_t*)((char*)a2 + dwOffset) : nullptr; } }; extern "C" { -HRESULT(*AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc)(const CCacheShortcut* a2, const void* a3); -HRESULT AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart(const CCacheShortcut* a2, const void* a3) +HRESULT(*AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc)(void* _this, const CCacheShortcut* a2, const void* a3); +HRESULT AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart(void* _this, const CCacheShortcut* a2, const void* a3) { using namespace ABI::WindowsInternal::Shell::UnifiedTile; using namespace ABI::WindowsInternal::Shell::UnifiedTile::Private; @@ -303,7 +349,7 @@ HRESULT AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart(const if (!dwStartShowClassicMode) { - return AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc(a2, a3); + return AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc(_this, a2, a3); } Microsoft::WRL::ComPtr pTileIdentifierFactory; diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c index 89f832c..1af3d82 100644 --- a/ExplorerPatcher/dllmain.c +++ b/ExplorerPatcher/dllmain.c @@ -10602,37 +10602,11 @@ cleanup: #pragma region "Fix Pin to Start from Explorer not working when using Windows 10 start menu" #ifdef _WIN64 -HRESULT(*AppResolver_StartDocked_GetStartScreenManagerExtensionStaticsFunc)(void** out); -HRESULT(*StartTileData_StartDocked_GetStartScreenManagerExtensionStaticsFunc)(void** out); -HRESULT StartDocked_GetStartScreenManagerExtensionStaticsHook(void** out) -{ - if (dwStartShowClassicMode) - { - // Keep the value of out as NULL and return S_OK to execute the old code - return S_OK; - } - return AppResolver_StartDocked_GetStartScreenManagerExtensionStaticsFunc(out); -} +extern HRESULT AppResolver_StartTileData_RoGetActivationFactory(HSTRING activatableClassId, REFIID iid, void** factory); typedef struct CCacheShortcut CCacheShortcut; -extern HRESULT(*AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc)(const CCacheShortcut* a2, const void* a3); -extern HRESULT AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart(const CCacheShortcut* a2, const void* a3); - -static void FindGetStartScreenManagerExtensionStatics(const MODULEINFO* pModuleInfo, HRESULT(**ppfnOut)(void**)) -{ - // StartDocked::GetStartScreenManagerExtensionStatics - // 48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 37 ?? 8B F1 48 83 21 00 - PBYTE match = FindPattern( - pModuleInfo->lpBaseOfDll, - pModuleInfo->SizeOfImage, - "\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x55\x57\x41\x56\x48\x8D\x6C\x24\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x45\x37\x00\x8B\xF1\x48\x83\x21\x00", - "xxxx?xxxx?xxxxxxxx?xxx????xxx????xxxxxxx?xxxxxx" - ); - if (match) - { - *ppfnOut = match; - } -} +extern HRESULT(*AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc)(void* _this, const CCacheShortcut* a2, const void* a3); +extern HRESULT AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart(void* _this, const CCacheShortcut* a2, const void* a3); static void PatchAppResolver() { @@ -10640,11 +10614,7 @@ static void PatchAppResolver() MODULEINFO miAppResolver; GetModuleInformation(GetCurrentProcess(), hAppResolver, &miAppResolver, sizeof(MODULEINFO)); - FindGetStartScreenManagerExtensionStatics(&miAppResolver, &AppResolver_StartDocked_GetStartScreenManagerExtensionStaticsFunc); - if (AppResolver_StartDocked_GetStartScreenManagerExtensionStaticsFunc) - { - printf("AppResolver.dll!StartDocked::GetStartScreenManagerExtensionStatics() = %llX\n", (PBYTE)AppResolver_StartDocked_GetStartScreenManagerExtensionStaticsFunc - (PBYTE)hAppResolver); - } + VnPatchDelayIAT(hAppResolver, "api-ms-win-core-winrt-l1-1-0.dll", "RoGetActivationFactory", AppResolver_StartTileData_RoGetActivationFactory); // CAppResolverCacheBuilder::_AddUserPinnedShortcutToStart() // 8B ? 48 8B D3 E8 ? ? ? ? 48 8B 8D @@ -10675,49 +10645,14 @@ static void PatchAppResolver() if (rv != 0) { printf("Failed to hook CAppResolverCacheBuilder::_AddUserPinnedShortcutToStart(). rv = %d\n", rv); - return; // Must be hooked properly otherwise our GetStartScreenManagerExtensionStatics hook will make it crash - } - - rv = -1; - if (AppResolver_StartDocked_GetStartScreenManagerExtensionStaticsFunc) - { - rv = funchook_prepare( - funchook, - (void**)&AppResolver_StartDocked_GetStartScreenManagerExtensionStaticsFunc, - StartDocked_GetStartScreenManagerExtensionStaticsHook - ); - } - if (rv != 0) - { - printf("Failed to hook AppResolver.dll!StartDocked::GetStartScreenManagerExtensionStatics(). rv = %d\n", rv); } } static void PatchStartTileData() { HANDLE hStartTileData = LoadLibraryW(L"StartTileData.dll"); - MODULEINFO miStartTileData; - GetModuleInformation(GetCurrentProcess(), hStartTileData, &miStartTileData, sizeof(MODULEINFO)); - FindGetStartScreenManagerExtensionStatics(&miStartTileData, &StartTileData_StartDocked_GetStartScreenManagerExtensionStaticsFunc); - if (StartTileData_StartDocked_GetStartScreenManagerExtensionStaticsFunc) - { - printf("StartTileData.dll!StartDocked::GetStartScreenManagerExtensionStatics() = %llX\n", (PBYTE)StartTileData_StartDocked_GetStartScreenManagerExtensionStaticsFunc - (PBYTE)hStartTileData); - } - - int rv = -1; - if (StartTileData_StartDocked_GetStartScreenManagerExtensionStaticsFunc) - { - rv = funchook_prepare( - funchook, - (void**)&StartTileData_StartDocked_GetStartScreenManagerExtensionStaticsFunc, - StartDocked_GetStartScreenManagerExtensionStaticsHook - ); - } - if (rv != 0) - { - printf("Failed to hook StartTileData.dll!StartDocked::GetStartScreenManagerExtensionStatics(). rv = %d\n", rv); - } + VnPatchIAT(hStartTileData, "api-ms-win-core-winrt-l1-1-0.dll", "RoGetActivationFactory", AppResolver_StartTileData_RoGetActivationFactory); } #endif #pragma endregion