Skip to content

Commit

Permalink
Start10: Revised the method of fixing Pin to Start/Unpin from Start
Browse files Browse the repository at this point in the history
  • Loading branch information
Amrsatrio committed Oct 6, 2023
1 parent dca4057 commit 29fda79
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 75 deletions.
56 changes: 51 additions & 5 deletions ExplorerPatcher/StartMenuSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<DummyExtensionFactory*>(&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")
Expand Down Expand Up @@ -284,26 +331,25 @@ 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;
using namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections;

if (!dwStartShowClassicMode)
{
return AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc(a2, a3);
return AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc(_this, a2, a3);
}

Microsoft::WRL::ComPtr<IWin32UnifiedTileIdentifierFactory> pTileIdentifierFactory;
Expand Down
75 changes: 5 additions & 70 deletions ExplorerPatcher/dllmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -10602,49 +10602,19 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)

#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()
{
HANDLE hAppResolver = LoadLibraryW(L"AppResolver.dll");
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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 29fda79

Please sign in to comment.