Skip to content
This repository has been archived by the owner on Nov 18, 2023. It is now read-only.

Start10: Revised the method of fixing Pin to Start/Unpin from Start #43

Merged
merged 3 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ExplorerPatcher/ExplorerPatcher.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
Expand Down
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 (dwStartShowClassicMode && 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