@@ -948,18 +948,29 @@ interface ITaskGroup
948948 CONST_VTBL struct ITaskGroupVtbl * lpVtbl ;
949949};
950950
951- HRESULT (* CTaskGroup_DoesWindowMatchFunc )(LONG_PTR * task_group , HWND hCompareWnd , ITEMIDLIST * pCompareItemIdList ,
952- WCHAR * pCompareAppId , int * pnMatch , LONG_PTR * * p_task_item ) = NULL ;
953- HRESULT __stdcall CTaskGroup_DoesWindowMatchHook (LONG_PTR * task_group , HWND hCompareWnd , ITEMIDLIST * pCompareItemIdList ,
954- WCHAR * pCompareAppId , int * pnMatch , LONG_PTR * * p_task_item )
955- {
956- HRESULT hr = CTaskGroup_DoesWindowMatchFunc (task_group , hCompareWnd , pCompareItemIdList , pCompareAppId , pnMatch , p_task_item );
957- BOOL bDontGroup = FALSE;
958- BOOL bPinned = FALSE;
959- if (bPinnedItemsActAsQuickLaunch && SUCCEEDED (hr ) && * pnMatch >= 1 && * pnMatch <= 3 ) // itemlist or appid match
960- {
961- bDontGroup = FALSE;
962- bPinned = (!task_group [4 ] || (int )((LONG_PTR * )task_group [4 ])[0 ] == 0 );
951+ typedef enum tagWINDOWMATCHCONFIDENCE
952+ {
953+ WMC_None ,
954+ WMC_MatchAppID ,
955+ WMC_MatchShortcutIDListByAppID ,
956+ WMC_MatchShortcutIDList ,
957+ WMC_MatchWindow ,
958+ } WINDOWMATCHCONFIDENCE ;
959+
960+ HRESULT (STDMETHODCALLTYPE * CTaskGroup_DoesWindowMatchFunc )(ITaskGroup * pTaskGroup , HWND hCompareWnd , ITEMIDLIST * pCompareItemIdList ,
961+ WCHAR * pCompareAppId , WINDOWMATCHCONFIDENCE * pnMatch , LONG_PTR * * p_task_item ) = NULL ;
962+ HRESULT STDMETHODCALLTYPE CTaskGroup_DoesWindowMatchHook (ITaskGroup * pTaskGroup , HWND hCompareWnd , ITEMIDLIST * pCompareItemIdList ,
963+ WCHAR * pCompareAppId , WINDOWMATCHCONFIDENCE * pnMatch , LONG_PTR * * p_task_item )
964+ {
965+ wprintf (L"CTaskGroup_DoesWindowMatchHook called for hwnd 0x%p\n" , hCompareWnd );
966+ HRESULT hr = CTaskGroup_DoesWindowMatchFunc (pTaskGroup , hCompareWnd , pCompareItemIdList , pCompareAppId , pnMatch , p_task_item );
967+ if (bPinnedItemsActAsQuickLaunch && SUCCEEDED (hr )
968+ && (* pnMatch == WMC_MatchAppID || * pnMatch == WMC_MatchShortcutIDListByAppID || * pnMatch == WMC_MatchShortcutIDList ))
969+ {
970+ BOOL bDontGroup = FALSE;
971+ PBYTE _this = (PBYTE )pTaskGroup - 16 /*sizeof(CTaskUnknown)*/ ;
972+ HDPA hdpaItems = * (HDPA * )(_this + 48 /*offsetof(CTaskGroup, m_hdpaItems)*/ );
973+ BOOL bPinned = !hdpaItems || !DPA_GetPtrCount (hdpaItems );
963974 if (bPinned )
964975 {
965976 bDontGroup = TRUE;
@@ -1023,13 +1034,13 @@ typedef struct ITaskBtnGroupVtbl
10231034 HRESULT (STDMETHODCALLTYPE * CancelRemoveItem )(
10241035 ITaskBtnGroup * This );
10251036
1026- LONG_PTR (STDMETHODCALLTYPE * GetIdealSpan )(
1037+ int (STDMETHODCALLTYPE * GetIdealSpan )(
10271038 ITaskBtnGroup * This ,
1028- LONG_PTR var2 ,
1029- LONG_PTR var3 ,
1030- LONG_PTR var4 ,
1031- LONG_PTR var5 ,
1032- LONG_PTR var6 );
1039+ int var2 ,
1040+ int var3 ,
1041+ int var4 ,
1042+ int var5 ,
1043+ int var6 );
10331044 // ...
10341045
10351046 END_INTERFACE
@@ -1040,60 +1051,104 @@ interface ITaskBtnGroup
10401051 CONST_VTBL struct ITaskBtnGroupVtbl * lpVtbl ;
10411052};
10421053
1043- LONG_PTR (* CTaskBtnGroup_GetIdealSpanFunc )(ITaskBtnGroup * _this , LONG_PTR var2 , LONG_PTR var3 ,
1044- LONG_PTR var4 , LONG_PTR var5 , LONG_PTR var6 ) = NULL ;
1045- LONG_PTR __stdcall CTaskBtnGroup_GetIdealSpanHook (ITaskBtnGroup * _this , LONG_PTR var2 , LONG_PTR var3 ,
1046- LONG_PTR var4 , LONG_PTR var5 , LONG_PTR var6 )
1054+ typedef enum eTBGROUPTYPE
1055+ {
1056+ TBGROUPTYPE_Unknown ,
1057+ TBGROUPTYPE_Normal ,
1058+ TBGROUPTYPE_Pinned ,
1059+ TBGROUPTYPE_Stacked ,
1060+ TBGROUPTYPE_Invisible ,
1061+ } TBGROUPTYPE ;
1062+
1063+ int (STDMETHODCALLTYPE * CTaskBtnGroup_GetIdealSpanFunc )(ITaskBtnGroup * pTaskBtnGroup , int var2 , int var3 ,
1064+ int var4 , int var5 , int * var6 ) = NULL ;
1065+ int STDMETHODCALLTYPE CTaskBtnGroup_GetIdealSpanHook (ITaskBtnGroup * pTaskBtnGroup , int var2 , int var3 ,
1066+ int var4 , int var5 , int * var6 )
10471067{
1048- LONG_PTR ret = NULL ;
10491068 BOOL bTypeModified = FALSE;
1050- int button_group_type = * (unsigned int * )((INT64 )_this + 64 );
1051- if (bRemoveExtraGapAroundPinnedItems && button_group_type == 2 )
1069+ PBYTE _this = (PBYTE )pTaskBtnGroup - 16 /*sizeof(CTaskUnknown)*/ ;
1070+ TBGROUPTYPE * pGroupType = (TBGROUPTYPE * )(_this + 80 /*offsetof(CTaskBtnGroup, m_groupType)*/ );
1071+ TBGROUPTYPE lastGroupType = * pGroupType ;
1072+ if (bRemoveExtraGapAroundPinnedItems && lastGroupType == TBGROUPTYPE_Pinned )
10521073 {
1053- * ( unsigned int * )(( INT64 ) _this + 64 ) = 4 ;
1074+ * pGroupType = TBGROUPTYPE_Invisible ;
10541075 bTypeModified = TRUE;
10551076 }
1056- ret = CTaskBtnGroup_GetIdealSpanFunc (_this , var2 , var3 , var4 , var5 , var6 );
1077+ int ret = CTaskBtnGroup_GetIdealSpanFunc (pTaskBtnGroup , var2 , var3 , var4 , var5 , var6 );
10571078 if (bRemoveExtraGapAroundPinnedItems && bTypeModified )
10581079 {
1059- * ( unsigned int * )(( INT64 ) _this + 64 ) = button_group_type ;
1080+ * pGroupType = lastGroupType ;
10601081 }
10611082 return ret ;
10621083}
10631084
1064- HRESULT explorer_QISearch ( void * that , LPCQITAB pqit , REFIID riid , void * * ppv )
1085+ void Win10TaskbarHooks_ConditionalPatchITaskGroupVtbl ( ITaskGroupVtbl * pVtbl )
10651086{
1066- HRESULT hr = QISearch (that , pqit , riid , ppv );
1067- if (SUCCEEDED (hr ) && IsEqualGUID (pqit [0 ].piid , & IID_ITaskGroup ) && bPinnedItemsActAsQuickLaunch )
1087+ if (bPinnedItemsActAsQuickLaunch )
10681088 {
1069- ITaskGroup * pTaskGroup = (char * )that + pqit [0 ].dwOffset ;
10701089 DWORD flOldProtect = 0 ;
1071- if (VirtualProtect (pTaskGroup -> lpVtbl , sizeof (ITaskGroupVtbl ), PAGE_EXECUTE_READWRITE , & flOldProtect ))
1090+ if (VirtualProtect (pVtbl , sizeof (ITaskGroupVtbl ), PAGE_EXECUTE_READWRITE , & flOldProtect ))
10721091 {
10731092 if (!CTaskGroup_DoesWindowMatchFunc )
10741093 {
1075- CTaskGroup_DoesWindowMatchFunc = pTaskGroup -> lpVtbl -> DoesWindowMatch ;
1094+ CTaskGroup_DoesWindowMatchFunc = pVtbl -> DoesWindowMatch ;
10761095 }
1077- pTaskGroup -> lpVtbl -> DoesWindowMatch = CTaskGroup_DoesWindowMatchHook ;
1078- VirtualProtect (pTaskGroup -> lpVtbl , sizeof (ITaskGroupVtbl ), flOldProtect , & flOldProtect );
1096+ pVtbl -> DoesWindowMatch = CTaskGroup_DoesWindowMatchHook ;
1097+ VirtualProtect (pVtbl , sizeof (ITaskGroupVtbl ), flOldProtect , & flOldProtect );
10791098 }
10801099 }
1081- else if (SUCCEEDED (hr ) && IsEqualGUID (pqit [0 ].piid , & IID_ITaskBtnGroup ) && bRemoveExtraGapAroundPinnedItems )
1100+ }
1101+
1102+ void Win10TaskbarHooks_ConditionalPatchITaskBtnGroupVtbl (ITaskBtnGroupVtbl * pVtbl )
1103+ {
1104+ if (bRemoveExtraGapAroundPinnedItems )
10821105 {
1083- ITaskBtnGroup * pTaskBtnGroup = (char * )that + pqit [0 ].dwOffset ;
10841106 DWORD flOldProtect = 0 ;
1085- if (VirtualProtect (pTaskBtnGroup -> lpVtbl , sizeof (ITaskBtnGroupVtbl ), PAGE_EXECUTE_READWRITE , & flOldProtect ))
1107+ if (VirtualProtect (pVtbl , sizeof (ITaskBtnGroupVtbl ), PAGE_EXECUTE_READWRITE , & flOldProtect ))
10861108 {
10871109 if (!CTaskBtnGroup_GetIdealSpanFunc )
10881110 {
1089- CTaskBtnGroup_GetIdealSpanFunc = pTaskBtnGroup -> lpVtbl -> GetIdealSpan ;
1111+ CTaskBtnGroup_GetIdealSpanFunc = pVtbl -> GetIdealSpan ;
10901112 }
1091- pTaskBtnGroup -> lpVtbl -> GetIdealSpan = CTaskBtnGroup_GetIdealSpanHook ;
1092- VirtualProtect (pTaskBtnGroup -> lpVtbl , sizeof (ITaskBtnGroupVtbl ), flOldProtect , & flOldProtect );
1113+ pVtbl -> GetIdealSpan = CTaskBtnGroup_GetIdealSpanHook ;
1114+ VirtualProtect (pVtbl , sizeof (ITaskBtnGroupVtbl ), flOldProtect , & flOldProtect );
1115+ }
1116+ }
1117+ }
1118+
1119+ HRESULT explorer_QISearch (void * that , LPCQITAB pqit , REFIID riid , void * * ppv )
1120+ {
1121+ HRESULT hr = QISearch (that , pqit , riid , ppv );
1122+ if (SUCCEEDED (hr ))
1123+ {
1124+ if (IsEqualGUID (pqit [0 ].piid , & IID_ITaskGroup ))
1125+ {
1126+ ITaskGroup * pTaskGroup = (char * )that + pqit [0 ].dwOffset ;
1127+ Win10TaskbarHooks_ConditionalPatchITaskGroupVtbl (pTaskGroup -> lpVtbl );
1128+ }
1129+ else if (IsEqualGUID (pqit [0 ].piid , & IID_ITaskBtnGroup ))
1130+ {
1131+ ITaskBtnGroup * pTaskBtnGroup = (char * )that + pqit [0 ].dwOffset ;
1132+ Win10TaskbarHooks_ConditionalPatchITaskBtnGroupVtbl (pTaskBtnGroup -> lpVtbl );
10931133 }
10941134 }
10951135 return hr ;
10961136}
1137+
1138+ void Win10TaskbarHooks_PatchEPTaskbarVtables (HMODULE hModule )
1139+ {
1140+ ITaskGroupVtbl * pTaskGroupVtbl = (ITaskGroupVtbl * )GetProcAddress (hModule , "??_7CTaskGroup@@6BITaskGroup@@@" );
1141+ if (pTaskGroupVtbl )
1142+ {
1143+ Win10TaskbarHooks_ConditionalPatchITaskGroupVtbl (pTaskGroupVtbl );
1144+ }
1145+
1146+ ITaskBtnGroupVtbl * pTaskBtnGroupVtbl = (ITaskBtnGroupVtbl * )GetProcAddress (hModule , "??_7CTaskBtnGroup@@6BITaskBtnGroup@@@" );
1147+ if (pTaskBtnGroupVtbl )
1148+ {
1149+ Win10TaskbarHooks_ConditionalPatchITaskBtnGroupVtbl (pTaskBtnGroupVtbl );
1150+ }
1151+ }
10971152#endif
10981153#pragma endregion
10991154
@@ -8389,12 +8444,6 @@ __declspec(dllexport) HRESULT explorer_CoCreateInstanceHook(REFCLSID rclsid, LPU
83898444 }
83908445 return CoCreateInstance (rclsid , pUnkOuter , dwClsContext , riid , ppv );
83918446}
8392-
8393- bool (* DisableWin10TaskbarIsEnabledFunc )(void * _this );
8394- bool DisableWin10TaskbarIsEnabledHook (void * _this )
8395- {
8396- return false;
8397- }
83988447#endif
83998448#pragma endregion
84008449
@@ -10823,45 +10872,6 @@ DWORD Inject(BOOL bIsExplorer)
1082310872 if (IsWindows11Version22H2OrHigher ())
1082410873 {
1082510874 TryToFindExplorerOffsets (hExplorer , & miExplorer , symbols_PTRS .explorer_PTRS );
10826-
10827- #if 0
10828- if (global_rovi .dwBuildNumber >= 26002 )
10829- {
10830- #if defined(_M_X64 )
10831- // Please Microsoft 🙏
10832- // 48 8B ?? 78 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 84 C0 0F 85
10833- // ^^^^^^^^^^^
10834- // 26040.1000: C28AE
10835- // 26052.1000: BF052
10836- // 26058.1000: BEFA2
10837- // 26080.1 : 11795C
10838- PBYTE match = FindPattern (
10839- hExplorer ,
10840- miExplorer .SizeOfImage ,
10841- "\x48\x8B\x00\x78\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0\x0F\x85" ,
10842- "xx?xxxx????x????xxxx"
10843- );
10844- if (match )
10845- {
10846- match += 11 ;
10847- match += 5 + * (int * )(match + 1 );
10848- }
10849- #elif defined(_M_ARM64 )
10850- PBYTE match = NULL ;
10851- #endif
10852- if (match )
10853- {
10854- DisableWin10TaskbarIsEnabledFunc = match ;
10855- printf ("wil::details::FeatureImpl<__WilFeatureTraits_Feature_DisableWin10Taskbar>::__private_IsEnabled() = %llX\n" , match - (PBYTE )hExplorer );
10856-
10857- funchook_prepare (
10858- funchook ,
10859- (void * * )& DisableWin10TaskbarIsEnabledFunc ,
10860- DisableWin10TaskbarIsEnabledHook
10861- );
10862- }
10863- }
10864- #endif
1086510875 }
1086610876
1086710877 const WCHAR * pszTaskbarDll = GetTaskbarDllChecked (& symbols_PTRS );
@@ -10883,7 +10893,10 @@ DWORD Inject(BOOL bIsExplorer)
1088310893 VnPatchIAT (hExplorer , "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL" , "RegCreateKeyExW" , explorer_RegCreateKeyExW );
1088410894 VnPatchIAT (hExplorer , "API-MS-WIN-SHCORE-REGISTRY-L1-1-0.DLL" , "SHGetValueW" , explorer_SHGetValueW );
1088510895 VnPatchIAT (hExplorer , "user32.dll" , "LoadMenuW" , explorer_LoadMenuW );
10886- VnPatchIAT (hExplorer , "api-ms-win-core-shlwapi-obsolete-l1-1-0.dll" , "QISearch" , explorer_QISearch );
10896+ if (bOldTaskbar == 1 )
10897+ {
10898+ VnPatchIAT (hExplorer , "api-ms-win-core-shlwapi-obsolete-l1-1-0.dll" , "QISearch" , explorer_QISearch );
10899+ }
1088710900 if (IsOS (OS_ANYSERVER )) VnPatchIAT (hExplorer , "api-ms-win-shcore-sysinfo-l1-1-0.dll" , "IsOS" , explorer_IsOS );
1088810901 if (IsWindows11Version22H2OrHigher ()) VnPatchDelayIAT (hExplorer , "ext-ms-win-rtcore-ntuser-window-ext-l1-1-0.dll" , "CreateWindowExW" , Windows11v22H2_explorer_CreateWindowExW );
1088910902 }
@@ -11078,6 +11091,8 @@ DWORD Inject(BOOL bIsExplorer)
1107811091 VnPatchIAT (hMyTaskbar , "user32.dll" , MAKEINTRESOURCEA (2005 ), explorer_SetChildWindowNoActivateHook );
1107911092
1108011093 VnPatchIAT (hMyTaskbar , "uxtheme.dll" , MAKEINTRESOURCEA (126 ), PeopleBand_DrawTextWithGlowHook );
11094+
11095+ Win10TaskbarHooks_PatchEPTaskbarVtables (hMyTaskbar );
1108111096 }
1108211097
1108311098 HANDLE hCombase = LoadLibraryW (L"combase.dll" );
0 commit comments