| 16 | } |
| 17 | |
| 18 | HRESULT InjectExplorerTAP(HWND window, REFIID riid, LPVOID* ppv) try |
| 19 | { |
| 20 | TaskbarAppearanceService::InstallProxyStub(); |
| 21 | |
| 22 | DWORD pid = 0; |
| 23 | const DWORD tid = GetWindowThreadProcessId(window, &pid); |
| 24 | |
| 25 | wil::unique_process_handle proc(OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid)); |
| 26 | if (!proc) [[unlikely]] |
| 27 | { |
| 28 | return HRESULT_FROM_WIN32(GetLastError()); |
| 29 | } |
| 30 | |
| 31 | if (!DetourFindRemotePayload(proc.get(), EXPLORER_PAYLOAD, nullptr)) |
| 32 | { |
| 33 | proc.reset(OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid)); |
| 34 | if (!proc) [[unlikely]] |
| 35 | { |
| 36 | return HRESULT_FROM_WIN32(GetLastError()); |
| 37 | } |
| 38 | |
| 39 | static constexpr uint32_t content = 0xDEADBEEF; |
| 40 | if (!DetourCopyPayloadToProcess(proc.get(), EXPLORER_PAYLOAD, &content, sizeof(content))) [[unlikely]] |
| 41 | { |
| 42 | return HRESULT_FROM_WIN32(GetLastError()); |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | { |
| 47 | const auto event = TAPSite::GetReadyEvent(); |
| 48 | |
| 49 | // InitializeXamlDiagnosticsEx pins the DLL forever in the target process - so we can discard the hook once it happens |
| 50 | // this has the bonus effect that if InitializeXamlDiagnosticsEx fails, the DLL gets unloaded. |
| 51 | wil::unique_hhook hook(SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, wil::GetModuleInstanceHandle(), tid)); |
| 52 | if (!hook) |
| 53 | { |
| 54 | return HRESULT_FROM_WIN32(GetLastError()); |
| 55 | } |
| 56 | |
| 57 | static constexpr DWORD READY_TIMEOUT = |
| 58 | #ifdef _DEBUG |
| 59 | // do not timeout on debug builds, to allow debugging the DLL while it's loading in explorer |
| 60 | INFINITE; |
| 61 | #else |
| 62 | 35000; |
| 63 | #endif |
| 64 | |
| 65 | if (!event.wait(READY_TIMEOUT)) [[unlikely]] |
| 66 | { |
| 67 | return HRESULT_FROM_WIN32(WAIT_TIMEOUT); |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | winrt::com_ptr<IUnknown> service; |
| 72 | HRESULT hr = GetActiveObject(CLSID_TaskbarAppearanceService, nullptr, service.put()); |
| 73 | if (FAILED(hr)) [[unlikely]] |
| 74 | { |
| 75 | return hr; |
nothing calls this directly
no test coverage detected