I’m trying to intercept calls to the taskbar buttons, for this I’m hooking the CoCreateInstance function to detect when it creates the ItaskbarList4 .
I would like to find another way to hook these functions as this way I need to start the explorer suspended
CoCreateInstance_H
is getting called and I’m getting the ItaskbarList4 pointer and returning a subclass of it,
however, the functions on MyTaskbarList aren’t getting called, the taskbar ain’t crashing and “looks” to continue working properly.
I’m trying to figure out what’s wrong.
inline HRESULT(WINAPI* CoCreateInstance_O)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv) = CoCreateInstance;
class MyTaskbarList : public ITaskbarList4 {
public:
MyTaskbarList(ITaskbarList4* original) : m_original(original) {}
// IUnknown methods
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override {
if (riid == __uuidof(IUnknown) || riid == __uuidof(ITaskbarList4)) {
*ppvObject = static_cast<ITaskbarList4*>(this);
AddRef();
return S_OK;
}
*ppvObject = nullptr;
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE AddRef() override {
return InterlockedIncrement(&m_refCount);
}
ULONG STDMETHODCALLTYPE Release() override {
ULONG refCount = InterlockedDecrement(&m_refCount);
if (refCount == 0) {
delete this;
}
return refCount;
}
HRESULT STDMETHODCALLTYPE HrInit() override {
return m_original->HrInit();
}
HRESULT STDMETHODCALLTYPE AddTab(HWND hwnd) override {
return m_original->AddTab(hwnd);
}
HRESULT STDMETHODCALLTYPE DeleteTab(HWND hwnd) override {
return m_original->DeleteTab(hwnd);
}
HRESULT STDMETHODCALLTYPE ActivateTab(HWND hwnd) override {
return m_original->ActivateTab(hwnd);
}
HRESULT STDMETHODCALLTYPE SetActiveAlt(HWND hwnd) override {
return m_original->SetActiveAlt(hwnd);
}
HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) override {
return m_original->MarkFullscreenWindow(hwnd, fFullscreen);
}
HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) override {
return m_original->SetProgressValue(hwnd, ullCompleted, ullTotal);
}
HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags) override {
return m_original->SetProgressState(hwnd, tbpFlags);
}
HRESULT STDMETHODCALLTYPE RegisterTab(HWND hwndTab, HWND hwndMDI) override {
OutputDebugStringW(L"RegisterTab");
return m_original->RegisterTab(hwndTab, hwndMDI);
}
HRESULT STDMETHODCALLTYPE UnregisterTab(HWND hwndTab) override {
return m_original->UnregisterTab(hwndTab);
}
HRESULT STDMETHODCALLTYPE SetTabOrder(HWND hwndTab, HWND hwndInsertBefore) override {
return m_original->SetTabOrder(hwndTab, hwndInsertBefore);
}
HRESULT STDMETHODCALLTYPE SetTabActive(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) override {
return m_original->SetTabActive(hwndTab, hwndMDI, dwReserved);
}
HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) override {
return m_original->ThumbBarAddButtons(hwnd, cButtons, pButton);
}
HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) override {
return m_original->ThumbBarUpdateButtons(hwnd, cButtons, pButton);
}
HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(HWND hwnd, HIMAGELIST himl) override {
return m_original->ThumbBarSetImageList(hwnd, himl);
}
HRESULT STDMETHODCALLTYPE SetOverlayIcon(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) override {
return m_original->SetOverlayIcon(hwnd, hIcon, pszDescription);
}
HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(HWND hwnd, LPCWSTR pszTip) override {
return m_original->SetThumbnailTooltip(hwnd, pszTip);
}
HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT* prcClip) override {
return m_original->SetThumbnailClip(hwnd, prcClip);
}
HRESULT STDMETHODCALLTYPE SetTabProperties(HWND hwndTab, STPFLAG stpFlags) override {
return m_original->SetTabProperties(hwndTab, stpFlags);
}
private:
ITaskbarList4* m_original;
LONG m_refCount;
};
MyTaskbarList* myTaskbarList = nullptr;
HRESULT WINAPI CoCreateInstance_H(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv)
{
if (rclsid == CLSID_TaskbarList)
{
if (riid == IID_ITaskbarList4)
{
ITaskbarList4* original;
HRESULT hr = CoCreateInstance_O(rclsid, pUnkOuter, dwClsContext, riid, (void**)&original);
OutputDebugStringW(L"CoCreateInstance_H");
if (SUCCEEDED(hr))
{
myTaskbarList = new MyTaskbarList(original);
*ppv = myTaskbarList;
OutputDebugStringW(L"success");
}
return hr;
}
}
return CoCreateInstance_O(rclsid, pUnkOuter, dwClsContext, riid, ppv);
}
#include "stdafx.h"
#include "Detours.h"
#pragma comment(lib, "detours.lib")
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)CoCreateInstance_O, CoCreateInstance_H);
DetourTransactionCommit();
}
}
return TRUE;
}