├── .gitignore ├── README.md ├── UNLICENSE ├── build.ps1 ├── uwpspy.cpp └── vcvarsall17.ps1 /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.obj 3 | *.dll 4 | *.swp 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | dll that hooks various uwp interfaces for debugging and reverse engineering 2 | 3 | # compiling 4 | install visual c++ build tools 2017 and the windows 10 sdk 5 | 6 | open powershell and navigate to uwpspy 7 | 8 | ```ps1 9 | .\vcvarsall17.ps1 10 | .\build.ps1 11 | ``` 12 | 13 | # usage 14 | use an injector that can fix permissions for uwp apps like 15 | https://github.com/Francesco149/uwpinject 16 | 17 | a console should pop up and start logging on injection 18 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | $invocation = (Get-Variable MyInvocation).Value 2 | $dir = Split-Path $invocation.MyCommand.Path 3 | Write-Output "working dir: $dir" 4 | 5 | function Write-Header { 6 | param ([string]$Message) 7 | $oldcolor = $host.UI.RawUI.ForegroundColor 8 | $host.UI.RawUI.ForegroundColor = "Green" 9 | Write-Output ":: $Message" 10 | $host.UI.RawUI.ForegroundColor = $oldcolor 11 | } 12 | 13 | Push-Location $dir 14 | $res = $null 15 | try { 16 | Write-Header "linting" 17 | $hasAnalyzer = Get-Command "Invoke-ScriptAnalyzer" ` 18 | -ErrorAction SilentlyContinue 19 | if (-not $hasAnalyzer) { 20 | Write-Warning "you're missing PSScriptAnalyzer, skipping lint step" 21 | return 22 | } 23 | $results = Invoke-ScriptAnalyzer -Path . -Recurse 24 | foreach ($result in $results) { 25 | Write-Output ($result | Format-Table | Out-String) 26 | } 27 | if ($results.Count -ne 0) { 28 | Throw "did not pass ps1 linting" 29 | } 30 | Get-ChildItem -file -Recurse . | 31 | Where-Object { $_.Name -match ".*\.cpp" } | 32 | ForEach-Object -Process { 33 | $target = (Get-Item $_).Basename 34 | Write-Header "cleaning $target" 35 | Remove-Item "$target.obj", "$target.dll", "$target.exp", ` 36 | "$target.lib", "$target.winmd" -ErrorAction SilentlyContinue 37 | Write-Header "compiling $_" 38 | cl /nologo /EHsc /Gm- /GR- /W4 /LD ` 39 | /D_CRT_SECURE_NO_WARNINGS=1 $_ 40 | if (-not $?) { 41 | Throw "cl failed: $LastExitCode" 42 | } 43 | } 44 | } catch { 45 | $res = $_ 46 | } 47 | Pop-Location 48 | if ($null -ne $res) { 49 | Throw $res 50 | } 51 | -------------------------------------------------------------------------------- /uwpspy.cpp: -------------------------------------------------------------------------------- 1 | // stubs for some uwp api's and interfaces 2 | // useful for debugging and reverse engineering 3 | // also a nice base to copypaste for hooking 4 | 5 | #define WIN32_LEAN_AND_MEAN 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #pragma comment (lib, "ole32.lib") 14 | 15 | namespace abi { 16 | using namespace ABI::Windows::UI::Core; 17 | using namespace ABI::Windows::ApplicationModel; 18 | using namespace ABI::Windows::ApplicationModel::Core; 19 | using namespace ABI::Windows::Foundation; 20 | using namespace ABI::Windows::Foundation::Collections; 21 | using namespace ABI::Windows::Foundation::Diagnostics; 22 | } 23 | 24 | #include 25 | #pragma intrinsic(_ReturnAddress) 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #define dbg \ 32 | wprintf(L"[%hs:%d] %hs: ", __FILE__, __LINE__, __FUNCTION__), \ 33 | wprintln 34 | 35 | int wprintln(WCHAR* fmt, ...) { 36 | int res = 0; 37 | va_list va; 38 | va_start(va, fmt); 39 | res += vwprintf(fmt, va); 40 | va_end(va); 41 | res += wprintf(L"\n"); 42 | return res; 43 | } 44 | 45 | // ------------------------------------------------------------------------ 46 | 47 | void log_init() { 48 | COORD bufsize; 49 | int success = ( 50 | AttachConsole(ATTACH_PARENT_PROCESS) || 51 | AttachConsole(GetCurrentProcessId()) || 52 | AllocConsole() 53 | ); 54 | if (success) { 55 | freopen("CONOUT$", "w", stdout); 56 | setvbuf(stdout, 0, _IONBF, 0); 57 | dbg(L"initialized console"); 58 | } else { 59 | dbg(L"running in console mode"); 60 | } 61 | bufsize.X = 80; 62 | bufsize.Y = 999; 63 | SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), bufsize); 64 | } 65 | 66 | typedef struct { 67 | void* addr; 68 | size_t n; 69 | DWORD fl; 70 | } spy_protection_t; 71 | 72 | int spy_protpush(spy_protection_t* prot, void* addr, size_t n) { 73 | DWORD oldprot; 74 | DWORD* poldprot; 75 | if (prot) { 76 | prot->addr = addr; 77 | prot->n = n; 78 | poldprot = &prot->fl; 79 | } else { 80 | poldprot = &oldprot; 81 | } 82 | if (!VirtualProtect(addr, n, PAGE_EXECUTE_READWRITE, poldprot)) { 83 | dbg(L"VirtualProtect %p failed: %08X", addr, GetLastError()); 84 | return 0; 85 | } 86 | return 1; 87 | } 88 | 89 | int spy_protpop(spy_protection_t* prot) { 90 | DWORD dummy; 91 | if (!VirtualProtect(prot->addr, prot->n, prot->fl, &dummy)) { 92 | dbg(L"VirtualProtect failed: %08X", GetLastError()); 93 | return 0; 94 | } 95 | return 1; 96 | } 97 | 98 | int spy_rva(void* base, DWORD* rva, void* hook) { 99 | spy_protection_t p; 100 | if (spy_protpush(&p, rva, sizeof(*rva))) { 101 | *rva = (DWORD)((char*)hook - (char*)base); 102 | return spy_protpop(&p); 103 | } 104 | return 0; 105 | } 106 | 107 | #if defined(_M_X64) && _M_X64 == 100 108 | #define JMPABS_SIZE 12 109 | #define JMPREL_SIZE 5 110 | 111 | void jmpabs(void* p, void* dst) { 112 | unsigned char* code = (unsigned char*)p; 113 | code = (unsigned char*)p; 114 | code[0] = 0x4E; /* mov rax,imm64 */ 115 | code[1] = 0xB8; 116 | *(UINT64*)&code[2] = (UINT64)dst; 117 | code[10] = 0xFF; /* jmp rax */ 118 | code[11] = 0xE0; 119 | } 120 | 121 | void jmprel(void* p, void* dst) { 122 | unsigned char* code = (unsigned char*)p; 123 | code = (unsigned char*)p; 124 | code[0] = 0xE9; 125 | *(INT32*)&code[1] = (INT32)((char*)dst - (char*)p - 5); 126 | } 127 | 128 | void* rel_alloc(void* base, size_t n) { 129 | ULONG_PTR scan_addr; 130 | SYSTEM_INFO si; 131 | ULONG_PTR min_addr; 132 | ULONG_PTR max_addr; 133 | /* scan for unused memory blocks in rel32 range */ 134 | GetSystemInfo(&si); 135 | min_addr = max((ULONG_PTR)si.lpMinimumApplicationAddress, 136 | (ULONG_PTR)base - 0x40000000); 137 | max_addr = min((ULONG_PTR)si.lpMaximumApplicationAddress, 138 | (ULONG_PTR)base + 0x40000000); 139 | scan_addr = min_addr; 140 | scan_addr -= scan_addr % si.dwAllocationGranularity; 141 | while (scan_addr < max_addr) { 142 | MEMORY_BASIC_INFORMATION mbi; 143 | if (!VirtualQuery((void*)scan_addr, &mbi, sizeof(mbi))) { 144 | dbg(L"VirtualQuery failed: %08X", GetLastError()); 145 | break; 146 | } 147 | if (mbi.State == MEM_FREE) { 148 | void* p = VirtualAlloc((void*)scan_addr, n, 149 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 150 | if (p) { 151 | return p; 152 | } else { 153 | dbg(L"VirtualAlloc failed: %08X", GetLastError()); 154 | } 155 | } 156 | scan_addr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize; 157 | scan_addr += si.dwAllocationGranularity - 1; 158 | scan_addr -= scan_addr % si.dwAllocationGranularity; 159 | } 160 | return 0; 161 | } 162 | #else 163 | #error "arch not supported" 164 | #endif 165 | 166 | /* 167 | * using a short jump makes it easier to hook because it overwrites a lot 168 | * less code, which means I almost never have to hand-fix the trampoline 169 | * 170 | * target: 171 | * jmp rel -> relay 172 | * ... 173 | * target_ret: 174 | * ... 175 | * 176 | * relay: 177 | * mov rax,hook 178 | * jmp rax 179 | * 180 | * trampoline: 181 | * (orig code) 182 | * mov rax,target_ret 183 | * jmp rax 184 | */ 185 | 186 | int spy_hook(void* func, void* hook, size_t nops, void** ptrampoline) { 187 | spy_protection_t p; 188 | char* relay = 0; 189 | size_t hook_size = JMPREL_SIZE + nops; 190 | if (!spy_protpush(&p, func, hook_size)) { 191 | return 0; 192 | } 193 | relay = (char*)rel_alloc(func, JMPABS_SIZE); 194 | if (!relay) { 195 | dbg(L"couldn't find free memory in rel range for %p", func); 196 | return 0; 197 | } 198 | if (!ptrampoline || !*ptrampoline) { 199 | size_t trampoline_size = hook_size + JMPABS_SIZE; 200 | char* trampoline = (char*)malloc(trampoline_size); 201 | if (!spy_protpush(0, trampoline, trampoline_size)) { 202 | return 0; 203 | } 204 | memcpy(trampoline, func, hook_size); 205 | jmpabs(&trampoline[hook_size], (char*)func + hook_size); 206 | if (ptrampoline) { 207 | *ptrampoline = trampoline; 208 | } 209 | } 210 | jmpabs(relay, hook); 211 | jmprel(func, relay); 212 | memset((char*)func + JMPREL_SIZE, 0x90, nops); 213 | return spy_protpop(&p); 214 | } 215 | 216 | typedef struct { 217 | char* name; 218 | void* hook; 219 | void** trampoline; 220 | int nops; 221 | } spy_export_t; 222 | 223 | int spy_exports(char* module_name, int n_hooks, spy_export_t* hooks) { 224 | char* module; 225 | IMAGE_NT_HEADERS* nt; 226 | IMAGE_DATA_DIRECTORY* dir; 227 | IMAGE_EXPORT_DIRECTORY* exports; 228 | DWORD i; 229 | DWORD* name_off; 230 | DWORD* function_off; 231 | WORD* ordinals; 232 | 233 | module = (char*)GetModuleHandleA(module_name); 234 | if (!module) { 235 | dbg(L"%hs not found", module_name); 236 | return 0; 237 | } 238 | 239 | nt = (IMAGE_NT_HEADERS*)(module + PIMAGE_DOS_HEADER(module)->e_lfanew); 240 | dir = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 241 | exports = (IMAGE_EXPORT_DIRECTORY*)(module + dir->VirtualAddress); 242 | name_off = (DWORD*)(module + exports->AddressOfNames); 243 | function_off = (DWORD*)(module + exports->AddressOfFunctions); 244 | ordinals = (WORD*)(module + exports->AddressOfNameOrdinals); 245 | 246 | dbg(L":: %hs", module_name); 247 | 248 | for (i = 0; i < exports->NumberOfNames; ++i) { 249 | char* name = module + name_off[i]; 250 | int ordinal = (int)ordinals[i]; 251 | unsigned char* func = (unsigned char*)module + function_off[ordinal]; 252 | int j; 253 | for (j = 0; j < n_hooks; ++j) { 254 | spy_export_t* hook = &hooks[j]; 255 | if (!_stricmp(hook->name, name)) { 256 | LONG_PTR distance = (char*)hook->hook - module; 257 | if (!hook->hook) { 258 | if (hook->trampoline) { 259 | *hook->trampoline = func; 260 | } 261 | break; 262 | } 263 | dbg(L"%p -> %hs @%d", func, name, ordinal); 264 | if (distance & ~(LONG_PTR)0xFFFFFFFF) { 265 | spy_hook(func, hook->hook, hook->nops, hook->trampoline); 266 | } else { 267 | dbg(L"function is nearby, using simple iat hook"); 268 | spy_rva(module, &function_off[ordinal], hook->hook); 269 | if (hook->trampoline) { 270 | *hook->trampoline = func; 271 | } 272 | } 273 | break; 274 | } 275 | } 276 | } 277 | 278 | return 1; 279 | } 280 | 281 | // ------------------------------------------------------------------------ 282 | 283 | PCWSTR (STDMETHODCALLTYPE* _WindowsGetStringRawBuffer) 284 | (HSTRING s, UINT32* len); 285 | 286 | // ------------------------------------------------------------------------ 287 | 288 | #define dumpstr(x) dbg(L"" #x L"=%s", _WindowsGetStringRawBuffer(x, 0)) 289 | #define dumpptr(fmt, x) dbg(L"" #x L"=%p -> " fmt, (x), (x) ? *(x) : 0) 290 | #define dumpiid(x) { \ 291 | LPOLESTR iidstr; \ 292 | if (StringFromIID(x, &iidstr) == S_OK) { \ 293 | dbg(L"" #x L"=%s", iidstr); \ 294 | CoTaskMemFree(iidstr); \ 295 | } \ 296 | } 297 | #define dump(fmt, x) dbg(L"" #x L"=" fmt, x) 298 | 299 | // ------------------------------------------------------------------------ 300 | 301 | struct __declspec(uuid("00000035-0000-0000-C000-000000000046")) 302 | _IActivationFactory : public IActivationFactory { 303 | IActivationFactory* orig; 304 | 305 | explicit _IActivationFactory(IActivationFactory* orig) 306 | : orig(orig) 307 | { 308 | dump("%p", orig); 309 | } 310 | 311 | // IUnknown 312 | 313 | virtual HRESULT STDMETHODCALLTYPE 314 | QueryInterface(REFIID riid, void** obj) override 315 | { 316 | dbg(L"called from %p", _ReturnAddress()); 317 | dumpiid(riid); 318 | HRESULT hr = orig->QueryInterface(riid, obj); 319 | dump("%08X", hr); 320 | if (SUCCEEDED(hr)) { 321 | dumpptr(L"%p", obj); 322 | } 323 | return hr; 324 | } 325 | 326 | virtual ULONG STDMETHODCALLTYPE AddRef() override { 327 | dbg(L"called from %p", _ReturnAddress()); 328 | ULONG refcount = orig->AddRef(); 329 | dump(L"%u", refcount); 330 | return refcount; 331 | } 332 | 333 | virtual ULONG STDMETHODCALLTYPE Release() override { 334 | dbg(L"called from %p", _ReturnAddress()); 335 | ULONG refcount = orig->Release(); 336 | dump(L"%u", refcount); 337 | if (!refcount) { 338 | delete this; 339 | } 340 | return refcount; 341 | } 342 | 343 | // IInspectable 344 | 345 | virtual HRESULT STDMETHODCALLTYPE 346 | GetIids(ULONG* n_iids, IID** iids) override 347 | { 348 | dbg(L"called from %p", _ReturnAddress()); 349 | HRESULT hr = orig->GetIids(n_iids, iids); 350 | dump("%08X", hr); 351 | if (SUCCEEDED(hr)) { 352 | for (ULONG i = 0; i < *n_iids; ++i) { 353 | dumpiid((*iids)[i]); 354 | } 355 | } 356 | return hr; 357 | } 358 | 359 | virtual HRESULT STDMETHODCALLTYPE 360 | GetRuntimeClassName(HSTRING* name) override 361 | { 362 | dbg(L"called from %p", _ReturnAddress()); 363 | HRESULT hr = orig->GetRuntimeClassName(name); 364 | dump("%08X", hr); 365 | if (SUCCEEDED(hr)) { 366 | dumpstr(*name); 367 | } 368 | return hr; 369 | } 370 | 371 | virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel* l) override { 372 | dbg(L"called from %p", _ReturnAddress()); 373 | HRESULT hr = orig->GetTrustLevel(l); 374 | dump("%08X", hr); 375 | if (SUCCEEDED(hr)) { 376 | char* level = "Unknown"; 377 | switch (*l) { 378 | #define c(x) case x: level = #x; break 379 | c(BaseTrust); 380 | c(PartialTrust); 381 | c(FullTrust); 382 | #undef c 383 | } 384 | dump(L"%hs", level); 385 | } 386 | return hr; 387 | } 388 | 389 | // IActivationFactory 390 | 391 | virtual HRESULT STDMETHODCALLTYPE 392 | ActivateInstance(IInspectable** instance) override 393 | { 394 | dbg(L"called from %p", _ReturnAddress()); 395 | HRESULT hr = orig->ActivateInstance(instance); 396 | dump("%08X", hr); 397 | if (SUCCEEDED(hr)) { 398 | dumpptr("%p", instance); 399 | } 400 | return hr; 401 | } 402 | }; 403 | 404 | // ------------------------------------------------------------------------ 405 | 406 | struct __declspec(uuid("CF86461D-261E-4B72-9ACD-44ED2ACE6A29")) 407 | _ICoreApplicationExit : public abi::ICoreApplicationExit { 408 | abi::ICoreApplicationExit* orig; 409 | 410 | explicit _ICoreApplicationExit(abi::ICoreApplicationExit* orig) 411 | : orig(orig) 412 | { 413 | dump("%p", orig); 414 | } 415 | 416 | // IUnknown 417 | 418 | virtual HRESULT STDMETHODCALLTYPE 419 | QueryInterface(REFIID riid, void** obj) override 420 | { 421 | dbg(L"called from %p", _ReturnAddress()); 422 | dumpiid(riid); 423 | HRESULT hr = orig->QueryInterface(riid, obj); 424 | dump("%08X", hr); 425 | if (SUCCEEDED(hr)) { 426 | dumpptr(L"%p", obj); 427 | } 428 | return hr; 429 | } 430 | 431 | virtual ULONG STDMETHODCALLTYPE AddRef() override { 432 | dbg(L"called from %p", _ReturnAddress()); 433 | ULONG refcount = orig->AddRef(); 434 | dump(L"%u", refcount); 435 | return refcount; 436 | } 437 | 438 | virtual ULONG STDMETHODCALLTYPE Release() override { 439 | dbg(L"called from %p", _ReturnAddress()); 440 | ULONG refcount = orig->Release(); 441 | dump(L"%u", refcount); 442 | if (!refcount) { 443 | delete this; 444 | } 445 | return refcount; 446 | } 447 | 448 | // IInspectable 449 | 450 | virtual HRESULT STDMETHODCALLTYPE 451 | GetIids(ULONG* n_iids, IID** iids) override 452 | { 453 | dbg(L"called from %p", _ReturnAddress()); 454 | HRESULT hr = orig->GetIids(n_iids, iids); 455 | dump("%08X", hr); 456 | if (SUCCEEDED(hr)) { 457 | for (ULONG i = 0; i < *n_iids; ++i) { 458 | dumpiid((*iids)[i]); 459 | } 460 | } 461 | return hr; 462 | } 463 | 464 | virtual HRESULT STDMETHODCALLTYPE 465 | GetRuntimeClassName(HSTRING* name) override 466 | { 467 | dbg(L"called from %p", _ReturnAddress()); 468 | HRESULT hr = orig->GetRuntimeClassName(name); 469 | dump("%08X", hr); 470 | if (SUCCEEDED(hr)) { 471 | dumpstr(*name); 472 | } 473 | return hr; 474 | } 475 | 476 | virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel* l) override { 477 | dbg(L"called from %p", _ReturnAddress()); 478 | HRESULT hr = orig->GetTrustLevel(l); 479 | dump("%08X", hr); 480 | if (SUCCEEDED(hr)) { 481 | char* level = "Unknown"; 482 | switch (*l) { 483 | #define c(x) case x: level = #x; break 484 | c(BaseTrust); 485 | c(PartialTrust); 486 | c(FullTrust); 487 | #undef c 488 | } 489 | dump(L"%hs", level); 490 | } 491 | return hr; 492 | } 493 | 494 | // ICoreApplicationExit 495 | 496 | virtual HRESULT STDMETHODCALLTYPE Exit() override { 497 | dbg(L"called from %p", _ReturnAddress()); 498 | HRESULT hr = orig->Exit(); 499 | dump("%08X", hr); 500 | return hr; 501 | } 502 | 503 | virtual HRESULT STDMETHODCALLTYPE add_Exiting( 504 | abi::IEventHandler* handler, 505 | EventRegistrationToken* token) override 506 | { 507 | dbg(L"called from %p", _ReturnAddress()); 508 | HRESULT hr = orig->add_Exiting(handler, token); 509 | dump("%08X", hr); 510 | return hr; 511 | } 512 | 513 | virtual HRESULT STDMETHODCALLTYPE remove_Exiting( 514 | EventRegistrationToken token) override 515 | { 516 | dbg(L"called from %p", _ReturnAddress()); 517 | HRESULT hr = orig->remove_Exiting(token); 518 | dump("%08X", hr); 519 | return hr; 520 | } 521 | }; 522 | 523 | // ------------------------------------------------------------------------ 524 | 525 | 526 | struct __declspec(uuid("0AACF7A4-5E1D-49DF-8034-FB6A68BC5ED1")) 527 | _ICoreApplication : public abi::ICoreApplication 528 | { 529 | abi::ICoreApplication* orig; 530 | 531 | explicit _ICoreApplication(abi::ICoreApplication* orig) 532 | : orig(orig) 533 | { 534 | dump("%p", orig); 535 | } 536 | 537 | // IUnknown 538 | 539 | virtual HRESULT STDMETHODCALLTYPE 540 | QueryInterface(REFIID riid, void** obj) override 541 | { 542 | void* res; 543 | dbg(L"called from %p", _ReturnAddress()); 544 | dumpiid(riid); 545 | HRESULT hr = orig->QueryInterface(riid, &res); 546 | dump("%08X", hr); 547 | if (FAILED(hr)) { 548 | *obj = res; 549 | } else if (riid == __uuidof(abi::ICoreApplicationExit)) { 550 | *obj = new _ICoreApplicationExit((abi::ICoreApplicationExit*)res); 551 | } else { 552 | *obj = res; 553 | } 554 | if (SUCCEEDED(hr)) { 555 | dumpptr(L"%p", obj); 556 | } 557 | return hr; 558 | } 559 | 560 | virtual ULONG STDMETHODCALLTYPE AddRef() override { 561 | dbg(L"called from %p", _ReturnAddress()); 562 | ULONG refcount = orig->AddRef(); 563 | dump(L"%u", refcount); 564 | return refcount; 565 | } 566 | 567 | virtual ULONG STDMETHODCALLTYPE Release() override { 568 | dbg(L"called from %p", _ReturnAddress()); 569 | ULONG refcount = orig->Release(); 570 | dump(L"%u", refcount); 571 | if (!refcount) { 572 | delete this; 573 | } 574 | return refcount; 575 | } 576 | 577 | // IInspectable 578 | 579 | virtual HRESULT STDMETHODCALLTYPE 580 | GetIids(ULONG* n_iids, IID** iids) override 581 | { 582 | dbg(L"called from %p", _ReturnAddress()); 583 | HRESULT hr = orig->GetIids(n_iids, iids); 584 | dump("%08X", hr); 585 | if (SUCCEEDED(hr)) { 586 | for (ULONG i = 0; i < *n_iids; ++i) { 587 | dumpiid((*iids)[i]); 588 | } 589 | } 590 | return hr; 591 | } 592 | 593 | virtual HRESULT STDMETHODCALLTYPE 594 | GetRuntimeClassName(HSTRING* name) override 595 | { 596 | dbg(L"called from %p", _ReturnAddress()); 597 | HRESULT hr = orig->GetRuntimeClassName(name); 598 | dump("%08X", hr); 599 | if (SUCCEEDED(hr)) { 600 | dumpstr(*name); 601 | } 602 | return hr; 603 | } 604 | 605 | virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel* l) override { 606 | dbg(L"called from %p", _ReturnAddress()); 607 | HRESULT hr = orig->GetTrustLevel(l); 608 | dump("%08X", hr); 609 | if (SUCCEEDED(hr)) { 610 | char* level = "Unknown"; 611 | switch (*l) { 612 | #define c(x) case x: level = #x; break 613 | c(BaseTrust); 614 | c(PartialTrust); 615 | c(FullTrust); 616 | #undef c 617 | } 618 | dump(L"%hs", level); 619 | } 620 | return hr; 621 | } 622 | 623 | // ICoreApplication 624 | 625 | virtual HRESULT STDMETHODCALLTYPE get_Id(HSTRING* value) override { 626 | dbg(L"called from %p", _ReturnAddress()); 627 | HRESULT hr = orig->get_Id(value); 628 | dump("%08X", hr); 629 | if (SUCCEEDED(hr)) { 630 | dumpstr(*value); 631 | } 632 | return hr; 633 | } 634 | 635 | virtual HRESULT STDMETHODCALLTYPE add_Suspending( 636 | abi::IEventHandler* h, 637 | EventRegistrationToken* token) override 638 | { 639 | dbg(L"called from %p", _ReturnAddress()); 640 | HRESULT hr = orig->add_Suspending(h, token); 641 | dump("%08X", hr); 642 | return hr; 643 | } 644 | 645 | virtual HRESULT STDMETHODCALLTYPE remove_Suspending( 646 | EventRegistrationToken token) override 647 | { 648 | dbg(L"called from %p", _ReturnAddress()); 649 | HRESULT hr = orig->remove_Suspending(token); 650 | dump("%08X", hr); 651 | return hr; 652 | } 653 | 654 | virtual HRESULT STDMETHODCALLTYPE add_Resuming( 655 | abi::IEventHandler* handler, 656 | EventRegistrationToken* token) override 657 | { 658 | dbg(L"called from %p", _ReturnAddress()); 659 | HRESULT hr = orig->add_Resuming(handler, token); 660 | dump("%08X", hr); 661 | return hr; 662 | } 663 | 664 | virtual HRESULT STDMETHODCALLTYPE remove_Resuming( 665 | EventRegistrationToken token) override 666 | { 667 | dbg(L"called from %p", _ReturnAddress()); 668 | HRESULT hr = orig->remove_Resuming(token); 669 | dump("%08X", hr); 670 | return hr; 671 | } 672 | 673 | virtual HRESULT STDMETHODCALLTYPE get_Properties( 674 | abi::IPropertySet** value) override 675 | { 676 | dbg(L"called from %p", _ReturnAddress()); 677 | HRESULT hr = orig->get_Properties(value); 678 | dump("%08X", hr); 679 | return hr; 680 | } 681 | 682 | virtual HRESULT STDMETHODCALLTYPE GetCurrentView( 683 | abi::ICoreApplicationView** value) override 684 | { 685 | dbg(L"called from %p", _ReturnAddress()); 686 | HRESULT hr = orig->GetCurrentView(value); 687 | dump("%08X", hr); 688 | return hr; 689 | } 690 | 691 | virtual HRESULT STDMETHODCALLTYPE Run( 692 | abi::IFrameworkViewSource* s) override 693 | { 694 | dbg(L"called from %p", _ReturnAddress()); 695 | HRESULT hr = orig->Run(s); 696 | dump("%08X", hr); 697 | return hr; 698 | } 699 | 700 | virtual HRESULT STDMETHODCALLTYPE RunWithActivationFactories( 701 | abi::IGetActivationFactory* callback) override 702 | { 703 | dbg(L"called from %p", _ReturnAddress()); 704 | HRESULT hr = orig->RunWithActivationFactories(callback); 705 | dump("%08X", hr); 706 | return hr; 707 | } 708 | }; 709 | 710 | // ------------------------------------------------------------------------ 711 | 712 | struct __declspec(uuid("8A43ED9F-F4E6-4421-ACF9-1DAB2986820C")) 713 | _IPropertySet : public abi::IPropertySet { 714 | IPropertySet* orig; 715 | 716 | explicit _IPropertySet(abi::IPropertySet* orig) 717 | : orig(orig) 718 | { 719 | dump("%p", orig); 720 | } 721 | 722 | // IUnknown 723 | 724 | virtual HRESULT STDMETHODCALLTYPE 725 | QueryInterface(REFIID riid, void** obj) override 726 | { 727 | dbg(L"called from %p", _ReturnAddress()); 728 | dumpiid(riid); 729 | HRESULT hr = orig->QueryInterface(riid, obj); 730 | dump("%08X", hr); 731 | if (SUCCEEDED(hr)) { 732 | dumpptr(L"%p", obj); 733 | } 734 | return hr; 735 | } 736 | 737 | virtual ULONG STDMETHODCALLTYPE AddRef() override { 738 | dbg(L"called from %p", _ReturnAddress()); 739 | ULONG refcount = orig->AddRef(); 740 | dump(L"%u", refcount); 741 | return refcount; 742 | } 743 | 744 | virtual ULONG STDMETHODCALLTYPE Release() override { 745 | dbg(L"called from %p", _ReturnAddress()); 746 | ULONG refcount = orig->Release(); 747 | dump(L"%u", refcount); 748 | if (!refcount) { 749 | delete this; 750 | } 751 | return refcount; 752 | } 753 | 754 | // IInspectable 755 | 756 | virtual HRESULT STDMETHODCALLTYPE 757 | GetIids(ULONG* n_iids, IID** iids) override 758 | { 759 | dbg(L"called from %p", _ReturnAddress()); 760 | HRESULT hr = orig->GetIids(n_iids, iids); 761 | dump("%08X", hr); 762 | if (SUCCEEDED(hr)) { 763 | for (ULONG i = 0; i < *n_iids; ++i) { 764 | dumpiid((*iids)[i]); 765 | } 766 | } 767 | return hr; 768 | } 769 | 770 | virtual HRESULT STDMETHODCALLTYPE 771 | GetRuntimeClassName(HSTRING* name) override 772 | { 773 | dbg(L"called from %p", _ReturnAddress()); 774 | HRESULT hr = orig->GetRuntimeClassName(name); 775 | dump("%08X", hr); 776 | if (SUCCEEDED(hr)) { 777 | dumpstr(*name); 778 | } 779 | return hr; 780 | } 781 | 782 | virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel* l) override { 783 | dbg(L"called from %p", _ReturnAddress()); 784 | HRESULT hr = orig->GetTrustLevel(l); 785 | dump("%08X", hr); 786 | if (SUCCEEDED(hr)) { 787 | char* level = "Unknown"; 788 | switch (*l) { 789 | #define c(x) case x: level = #x; break 790 | c(BaseTrust); 791 | c(PartialTrust); 792 | c(FullTrust); 793 | #undef c 794 | } 795 | dump(L"%hs", level); 796 | } 797 | return hr; 798 | } 799 | }; 800 | 801 | // ------------------------------------------------------------------------ 802 | 803 | struct __declspec(uuid("4D239005-3C2A-41B1-9022-536BB9CF93B1")) 804 | _ICoreWindowStatic : public abi::ICoreWindowStatic { 805 | abi::ICoreWindowStatic* orig; 806 | 807 | explicit _ICoreWindowStatic(abi::ICoreWindowStatic* orig) 808 | : orig(orig) 809 | { 810 | dump("%p", orig); 811 | } 812 | 813 | // IUnknown 814 | 815 | virtual HRESULT STDMETHODCALLTYPE 816 | QueryInterface(REFIID riid, void** obj) override 817 | { 818 | dbg(L"called from %p", _ReturnAddress()); 819 | dumpiid(riid); 820 | HRESULT hr = orig->QueryInterface(riid, obj); 821 | dump("%08X", hr); 822 | if (SUCCEEDED(hr)) { 823 | dumpptr(L"%p", obj); 824 | } 825 | return hr; 826 | } 827 | 828 | virtual ULONG STDMETHODCALLTYPE AddRef() override { 829 | dbg(L"called from %p", _ReturnAddress()); 830 | ULONG refcount = orig->AddRef(); 831 | dump(L"%u", refcount); 832 | return refcount; 833 | } 834 | 835 | virtual ULONG STDMETHODCALLTYPE Release() override { 836 | dbg(L"called from %p", _ReturnAddress()); 837 | ULONG refcount = orig->Release(); 838 | dump(L"%u", refcount); 839 | if (!refcount) { 840 | delete this; 841 | } 842 | return refcount; 843 | } 844 | 845 | // IInspectable 846 | 847 | virtual HRESULT STDMETHODCALLTYPE 848 | GetIids(ULONG* n_iids, IID** iids) override 849 | { 850 | dbg(L"called from %p", _ReturnAddress()); 851 | HRESULT hr = orig->GetIids(n_iids, iids); 852 | dump("%08X", hr); 853 | if (SUCCEEDED(hr)) { 854 | for (ULONG i = 0; i < *n_iids; ++i) { 855 | dumpiid((*iids)[i]); 856 | } 857 | } 858 | return hr; 859 | } 860 | 861 | virtual HRESULT STDMETHODCALLTYPE 862 | GetRuntimeClassName(HSTRING* name) override 863 | { 864 | dbg(L"called from %p", _ReturnAddress()); 865 | HRESULT hr = orig->GetRuntimeClassName(name); 866 | dump("%08X", hr); 867 | if (SUCCEEDED(hr)) { 868 | dumpstr(*name); 869 | } 870 | return hr; 871 | } 872 | 873 | virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel* l) override { 874 | dbg(L"called from %p", _ReturnAddress()); 875 | HRESULT hr = orig->GetTrustLevel(l); 876 | dump("%08X", hr); 877 | if (SUCCEEDED(hr)) { 878 | char* level = "Unknown"; 879 | switch (*l) { 880 | #define c(x) case x: level = #x; break 881 | c(BaseTrust); 882 | c(PartialTrust); 883 | c(FullTrust); 884 | #undef c 885 | } 886 | dump(L"%hs", level); 887 | } 888 | return hr; 889 | } 890 | 891 | // ICoreWindowStatic 892 | 893 | virtual HRESULT STDMETHODCALLTYPE GetForCurrentThread( 894 | abi::ICoreWindow** pwindow) override 895 | { 896 | dbg(L"called from %p", _ReturnAddress()); 897 | HRESULT hr = orig->GetForCurrentThread(pwindow); 898 | if (SUCCEEDED(hr)) { 899 | dumpptr("%p", pwindow); 900 | } 901 | dump("%08X", hr); 902 | return hr; 903 | } 904 | }; 905 | 906 | // ------------------------------------------------------------------------ 907 | 908 | struct __declspec(uuid("65A1ECC5-3FB5-4832-8CA9-F061B281D13A")) 909 | _IDeferralFactory : public abi::IDeferralFactory { 910 | abi::IDeferralFactory* orig; 911 | 912 | explicit _IDeferralFactory(abi::IDeferralFactory* orig) 913 | : orig(orig) 914 | { 915 | dump("%p", orig); 916 | } 917 | 918 | // IUnknown 919 | 920 | virtual HRESULT STDMETHODCALLTYPE 921 | QueryInterface(REFIID riid, void** obj) override 922 | { 923 | dbg(L"called from %p", _ReturnAddress()); 924 | dumpiid(riid); 925 | HRESULT hr = orig->QueryInterface(riid, obj); 926 | dump("%08X", hr); 927 | if (SUCCEEDED(hr)) { 928 | dumpptr(L"%p", obj); 929 | } 930 | return hr; 931 | } 932 | 933 | virtual ULONG STDMETHODCALLTYPE AddRef() override { 934 | dbg(L"called from %p", _ReturnAddress()); 935 | ULONG refcount = orig->AddRef(); 936 | dump(L"%u", refcount); 937 | return refcount; 938 | } 939 | 940 | virtual ULONG STDMETHODCALLTYPE Release() override { 941 | dbg(L"called from %p", _ReturnAddress()); 942 | ULONG refcount = orig->Release(); 943 | dump(L"%u", refcount); 944 | if (!refcount) { 945 | delete this; 946 | } 947 | return refcount; 948 | } 949 | 950 | // IInspectable 951 | 952 | virtual HRESULT STDMETHODCALLTYPE 953 | GetIids(ULONG* n_iids, IID** iids) override 954 | { 955 | dbg(L"called from %p", _ReturnAddress()); 956 | HRESULT hr = orig->GetIids(n_iids, iids); 957 | dump("%08X", hr); 958 | if (SUCCEEDED(hr)) { 959 | for (ULONG i = 0; i < *n_iids; ++i) { 960 | dumpiid((*iids)[i]); 961 | } 962 | } 963 | return hr; 964 | } 965 | 966 | virtual HRESULT STDMETHODCALLTYPE 967 | GetRuntimeClassName(HSTRING* name) override 968 | { 969 | dbg(L"called from %p", _ReturnAddress()); 970 | HRESULT hr = orig->GetRuntimeClassName(name); 971 | dump("%08X", hr); 972 | if (SUCCEEDED(hr)) { 973 | dumpstr(*name); 974 | } 975 | return hr; 976 | } 977 | 978 | virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel* l) override { 979 | dbg(L"called from %p", _ReturnAddress()); 980 | HRESULT hr = orig->GetTrustLevel(l); 981 | dump("%08X", hr); 982 | if (SUCCEEDED(hr)) { 983 | char* level = "Unknown"; 984 | switch (*l) { 985 | #define c(x) case x: level = #x; break 986 | c(BaseTrust); 987 | c(PartialTrust); 988 | c(FullTrust); 989 | #undef c 990 | } 991 | dump(L"%hs", level); 992 | } 993 | return hr; 994 | } 995 | 996 | // IDeferralFactory 997 | 998 | virtual HRESULT STDMETHODCALLTYPE Create( 999 | abi::IDeferralCompletedHandler* handler, abi::IDeferral** result) 1000 | override 1001 | { 1002 | dbg(L"called from %p", _ReturnAddress()); 1003 | HRESULT hr = orig->Create(handler, result); 1004 | dump("%08X", hr); 1005 | if (SUCCEEDED(hr)) { 1006 | dumpptr("%p", result); 1007 | } 1008 | return hr; 1009 | } 1010 | }; 1011 | 1012 | // ------------------------------------------------------------------------ 1013 | 1014 | struct __declspec(uuid("50850B26-267E-451B-A890-AB6A370245EE")) 1015 | _IAsyncCausalityTracerStatics : public abi::IAsyncCausalityTracerStatics { 1016 | abi::IAsyncCausalityTracerStatics* orig; 1017 | 1018 | explicit _IAsyncCausalityTracerStatics(abi::IAsyncCausalityTracerStatics* orig) 1019 | : orig(orig) 1020 | { 1021 | dump("%p", orig); 1022 | } 1023 | 1024 | // IUnknown 1025 | 1026 | virtual HRESULT STDMETHODCALLTYPE 1027 | QueryInterface(REFIID riid, void** obj) override 1028 | { 1029 | dbg(L"called from %p", _ReturnAddress()); 1030 | dumpiid(riid); 1031 | HRESULT hr = orig->QueryInterface(riid, obj); 1032 | dump("%08X", hr); 1033 | if (SUCCEEDED(hr)) { 1034 | dumpptr(L"%p", obj); 1035 | } 1036 | return hr; 1037 | } 1038 | 1039 | virtual ULONG STDMETHODCALLTYPE AddRef() override { 1040 | dbg(L"called from %p", _ReturnAddress()); 1041 | ULONG refcount = orig->AddRef(); 1042 | dump(L"%u", refcount); 1043 | return refcount; 1044 | } 1045 | 1046 | virtual ULONG STDMETHODCALLTYPE Release() override { 1047 | dbg(L"called from %p", _ReturnAddress()); 1048 | ULONG refcount = orig->Release(); 1049 | dump(L"%u", refcount); 1050 | if (!refcount) { 1051 | delete this; 1052 | } 1053 | return refcount; 1054 | } 1055 | 1056 | // IInspectable 1057 | 1058 | virtual HRESULT STDMETHODCALLTYPE 1059 | GetIids(ULONG* n_iids, IID** iids) override 1060 | { 1061 | dbg(L"called from %p", _ReturnAddress()); 1062 | HRESULT hr = orig->GetIids(n_iids, iids); 1063 | dump("%08X", hr); 1064 | if (SUCCEEDED(hr)) { 1065 | for (ULONG i = 0; i < *n_iids; ++i) { 1066 | dumpiid((*iids)[i]); 1067 | } 1068 | } 1069 | return hr; 1070 | } 1071 | 1072 | virtual HRESULT STDMETHODCALLTYPE 1073 | GetRuntimeClassName(HSTRING* name) override 1074 | { 1075 | dbg(L"called from %p", _ReturnAddress()); 1076 | HRESULT hr = orig->GetRuntimeClassName(name); 1077 | dump("%08X", hr); 1078 | if (SUCCEEDED(hr)) { 1079 | dumpstr(*name); 1080 | } 1081 | return hr; 1082 | } 1083 | 1084 | virtual HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel* l) override { 1085 | dbg(L"called from %p", _ReturnAddress()); 1086 | HRESULT hr = orig->GetTrustLevel(l); 1087 | dump("%08X", hr); 1088 | if (SUCCEEDED(hr)) { 1089 | char* level = "Unknown"; 1090 | switch (*l) { 1091 | #define c(x) case x: level = #x; break 1092 | c(BaseTrust); 1093 | c(PartialTrust); 1094 | c(FullTrust); 1095 | #undef c 1096 | } 1097 | dump(L"%hs", level); 1098 | } 1099 | return hr; 1100 | } 1101 | 1102 | // IAsyncCausalityTracerStatics 1103 | 1104 | static char const* TraceLevelStr(abi::CausalityTraceLevel trace_level) { 1105 | #define c(x) case x: return #x; 1106 | switch (trace_level) { 1107 | c(abi::CausalityTraceLevel_Required); 1108 | c(abi::CausalityTraceLevel_Important); 1109 | c(abi::CausalityTraceLevel_Verbose); 1110 | } 1111 | #undef c 1112 | return "?"; 1113 | } 1114 | 1115 | static char const* SourceStr(abi::CausalitySource source) { 1116 | #define c(x) case x: return #x; 1117 | switch (source) { 1118 | c(abi::CausalitySource_Application); 1119 | c(abi::CausalitySource_Library); 1120 | c(abi::CausalitySource_System); 1121 | } 1122 | #undef c 1123 | return "?"; 1124 | } 1125 | 1126 | static char const* AsyncStatusStr(AsyncStatus status) { 1127 | #define c(x) case x: return #x; 1128 | switch (status) { 1129 | c(Canceled); 1130 | c(Completed); 1131 | c(Error); 1132 | c(Started); 1133 | } 1134 | #undef c 1135 | return "?"; 1136 | } 1137 | 1138 | static char const* CausalityRelationStr(abi::CausalityRelation rel) { 1139 | #define c(x) case x: return #x; 1140 | switch (rel) { 1141 | c(abi::CausalityRelation_AssignDelegate); 1142 | c(abi::CausalityRelation_Join); 1143 | c(abi::CausalityRelation_Choice); 1144 | c(abi::CausalityRelation_Cancel); 1145 | c(abi::CausalityRelation_Error); 1146 | } 1147 | #undef c 1148 | return "?"; 1149 | } 1150 | 1151 | static char const* CausalitySynchronousWorkStr( 1152 | abi::CausalitySynchronousWork work) { 1153 | #define c(x) case x: return #x; 1154 | switch (work) { 1155 | c(abi::CausalitySynchronousWork_CompletionNotification); 1156 | c(abi::CausalitySynchronousWork_ProgressNotification); 1157 | c(abi::CausalitySynchronousWork_Execution); 1158 | } 1159 | #undef c 1160 | return "?"; 1161 | } 1162 | 1163 | virtual HRESULT STDMETHODCALLTYPE TraceOperationCreation( 1164 | abi::CausalityTraceLevel trace_level, abi::CausalitySource source, 1165 | GUID platform_id, UINT64 operation_id, 1166 | HSTRING operation_name, UINT64 related_context) override 1167 | { 1168 | dbg(L"called from %p", _ReturnAddress()); 1169 | dump(L"%hs", TraceLevelStr(trace_level)); 1170 | dump(L"%hs", SourceStr(source)); 1171 | dumpiid(platform_id); 1172 | dump("%I64d", operation_id); 1173 | dumpstr(operation_name); 1174 | dump("%I64u", related_context); 1175 | HRESULT hr = orig->TraceOperationCreation(trace_level, source, 1176 | platform_id, operation_id, operation_name, related_context); 1177 | dump("%08X", hr); 1178 | return hr; 1179 | } 1180 | 1181 | virtual HRESULT STDMETHODCALLTYPE TraceOperationCompletion( 1182 | abi::CausalityTraceLevel trace_level, abi::CausalitySource source, 1183 | GUID platform_id, UINT64 operation_id, AsyncStatus status) override 1184 | { 1185 | dbg(L"called from %p", _ReturnAddress()); 1186 | dump(L"%hs", TraceLevelStr(trace_level)); 1187 | dump(L"%hs", SourceStr(source)); 1188 | dumpiid(platform_id); 1189 | dump("%I64d", operation_id); 1190 | dump(L"%hs", AsyncStatusStr(status)); 1191 | HRESULT hr = orig->TraceOperationCompletion(trace_level, source, 1192 | platform_id, operation_id, status); 1193 | dump("%08X", hr); 1194 | return hr; 1195 | } 1196 | 1197 | virtual HRESULT STDMETHODCALLTYPE TraceOperationRelation( 1198 | abi::CausalityTraceLevel trace_level, abi::CausalitySource source, 1199 | GUID platform_id, UINT64 operation_id, abi::CausalityRelation relation) 1200 | override 1201 | { 1202 | dbg(L"called from %p", _ReturnAddress()); 1203 | dump(L"%hs", TraceLevelStr(trace_level)); 1204 | dump(L"%hs", SourceStr(source)); 1205 | dumpiid(platform_id); 1206 | dump("%I64d", operation_id); 1207 | dump(L"%hs", CausalityRelationStr(relation)); 1208 | HRESULT hr = orig->TraceOperationRelation(trace_level, source, 1209 | platform_id, operation_id, relation); 1210 | dump("%08X", hr); 1211 | return hr; 1212 | } 1213 | 1214 | virtual HRESULT STDMETHODCALLTYPE TraceSynchronousWorkStart( 1215 | abi::CausalityTraceLevel trace_level, abi::CausalitySource source, 1216 | GUID platform_id, UINT64 operation_id, 1217 | abi::CausalitySynchronousWork work) override 1218 | { 1219 | dbg(L"called from %p", _ReturnAddress()); 1220 | dump(L"%hs", TraceLevelStr(trace_level)); 1221 | dump(L"%hs", SourceStr(source)); 1222 | dumpiid(platform_id); 1223 | dump("%I64d", operation_id); 1224 | dump(L"%hs", CausalitySynchronousWorkStr(work)); 1225 | HRESULT hr = orig->TraceSynchronousWorkStart(trace_level, source, 1226 | platform_id, operation_id, work); 1227 | dump("%08X", hr); 1228 | return hr; 1229 | } 1230 | 1231 | virtual HRESULT STDMETHODCALLTYPE TraceSynchronousWorkCompletion( 1232 | abi::CausalityTraceLevel trace_level, abi::CausalitySource source, 1233 | abi::CausalitySynchronousWork work) override 1234 | { 1235 | dbg(L"called from %p", _ReturnAddress()); 1236 | dump(L"%hs", TraceLevelStr(trace_level)); 1237 | dump(L"%hs", SourceStr(source)); 1238 | dump(L"%hs", CausalitySynchronousWorkStr(work)); 1239 | HRESULT hr = 1240 | orig->TraceSynchronousWorkCompletion(trace_level, source, work); 1241 | dump("%08X", hr); 1242 | return hr; 1243 | } 1244 | 1245 | virtual HRESULT STDMETHODCALLTYPE add_TracingStatusChanged( 1246 | abi::IEventHandler* handler, 1247 | EventRegistrationToken* cookie) override 1248 | { 1249 | dbg(L"called from %p", _ReturnAddress()); 1250 | HRESULT hr = orig->add_TracingStatusChanged(handler, cookie); 1251 | dump("%08X", hr); 1252 | return hr; 1253 | } 1254 | 1255 | virtual HRESULT STDMETHODCALLTYPE remove_TracingStatusChanged( 1256 | EventRegistrationToken cookie) override 1257 | { 1258 | dbg(L"called from %p", _ReturnAddress()); 1259 | HRESULT hr = orig->remove_TracingStatusChanged(cookie); 1260 | dump("%08X", hr); 1261 | return hr; 1262 | } 1263 | }; 1264 | 1265 | // ------------------------------------------------------------------------ 1266 | 1267 | HRESULT (STDMETHODCALLTYPE* orig_RoGetActivationFactory)( 1268 | HSTRING id, REFIID iid, void** pfactory); 1269 | 1270 | STDAPI _RoGetActivationFactory(HSTRING id, REFIID iid, void** pfactory) { 1271 | HRESULT hr; 1272 | void* res; 1273 | dbg(L"called from %p", _ReturnAddress()); 1274 | dumpstr(id); 1275 | dumpiid(iid); 1276 | hr = orig_RoGetActivationFactory(id, iid, &res); 1277 | dump("%08X", hr); 1278 | if (FAILED(hr)) { 1279 | *pfactory = res; 1280 | } else if (iid == __uuidof(IActivationFactory)) { 1281 | *pfactory = new _IActivationFactory((IActivationFactory*)res); 1282 | } else if (iid == __uuidof(abi::ICoreApplication)) { 1283 | *pfactory = new _ICoreApplication((abi::ICoreApplication*)res); 1284 | } else if (iid == __uuidof(abi::ICoreWindowStatic)) { 1285 | *pfactory = new _ICoreWindowStatic((abi::ICoreWindowStatic*)res); 1286 | } else if (iid == __uuidof(abi::IDeferralFactory)) { 1287 | *pfactory = new _IDeferralFactory((abi::IDeferralFactory*)res); 1288 | } else if (iid == __uuidof(abi::IAsyncCausalityTracerStatics)) { 1289 | *pfactory = new _IAsyncCausalityTracerStatics( 1290 | (abi::IAsyncCausalityTracerStatics*)res); 1291 | } else { 1292 | *pfactory = res; 1293 | } 1294 | return hr; 1295 | } 1296 | 1297 | // ------------------------------------------------------------------------ 1298 | 1299 | HRESULT (STDMETHODCALLTYPE* orig_RoActivateInstance) 1300 | (HSTRING id, IInspectable** instance); 1301 | 1302 | STDAPI _RoActivateInstance(HSTRING id, IInspectable** instance) { 1303 | IInspectable* res; 1304 | HRESULT hr; 1305 | PCWSTR s; 1306 | dbg(L"called from %p", _ReturnAddress()); 1307 | dumpstr(id); 1308 | hr = orig_RoActivateInstance(id, &res); 1309 | dump("%08X", hr); 1310 | s = _WindowsGetStringRawBuffer(id, 0); 1311 | if (FAILED(hr)) { 1312 | *instance = res; 1313 | } else if (!wcscmp(s, L"Windows.Foundation.Collections.PropertySet")) { 1314 | *instance = new _IPropertySet((abi::IPropertySet*)res); 1315 | } else { 1316 | *instance = res; 1317 | } 1318 | if (SUCCEEDED(hr)) { 1319 | dumpptr("%p", instance); 1320 | } 1321 | return hr; 1322 | } 1323 | 1324 | // ------------------------------------------------------------------------ 1325 | 1326 | HRESULT (STDMETHODCALLTYPE* orig_RoGetApartmentIdentifier) 1327 | (UINT64* identifier); 1328 | 1329 | STDAPI _RoGetApartmentIdentifier(UINT64* identifier) { 1330 | HRESULT hr; 1331 | dbg(L"called from %p", _ReturnAddress()); 1332 | hr = orig_RoGetApartmentIdentifier(identifier); 1333 | dump("%08X", hr); 1334 | if (SUCCEEDED(hr)) { 1335 | dumpptr("%I64d", identifier); 1336 | } 1337 | return hr; 1338 | } 1339 | 1340 | // ------------------------------------------------------------------------ 1341 | 1342 | HRESULT (STDMETHODCALLTYPE* orig_RoInitialize)(RO_INIT_TYPE t); 1343 | 1344 | STDAPI _RoInitialize(RO_INIT_TYPE t) { 1345 | HRESULT hr; 1346 | dbg(L"called from %p", _ReturnAddress()); 1347 | #define c(x) case x: dbg(L"" #x) 1348 | switch (t) { 1349 | c(RO_INIT_SINGLETHREADED); break; 1350 | c(RO_INIT_MULTITHREADED); break; 1351 | } 1352 | #undef c 1353 | hr = orig_RoInitialize(t); 1354 | dump("%08X", hr); 1355 | return hr; 1356 | } 1357 | 1358 | // ------------------------------------------------------------------------ 1359 | 1360 | HRESULT (STDMETHODCALLTYPE* orig_RoRegisterActivationFactories)( 1361 | HSTRING* ids, PFNGETACTIVATIONFACTORY* callbacks, UINT32 count, 1362 | RO_REGISTRATION_COOKIE* cookie); 1363 | 1364 | STDAPI _RoRegisterActivationFactories(HSTRING* ids, 1365 | PFNGETACTIVATIONFACTORY* callbacks, UINT32 count, 1366 | RO_REGISTRATION_COOKIE* cookie) 1367 | { 1368 | HRESULT hr; 1369 | UINT32 i; 1370 | dbg(L"called from %p", _ReturnAddress()); 1371 | for (i = 0; i < count; ++i) { 1372 | dumpstr(ids[i]); 1373 | dump("%p", callbacks[i]); 1374 | } 1375 | dump("%p", cookie); 1376 | hr = orig_RoRegisterActivationFactories(ids, callbacks, count, cookie); 1377 | dump("%08X", hr); 1378 | return hr; 1379 | } 1380 | 1381 | // ------------------------------------------------------------------------ 1382 | 1383 | HRESULT (STDMETHODCALLTYPE* orig_RoRegisterForApartmentShutdown)( 1384 | IApartmentShutdown* obj, UINT64* identifier, 1385 | APARTMENT_SHUTDOWN_REGISTRATION_COOKIE* cookie); 1386 | 1387 | STDAPI _RoRegisterForApartmentShutdown(IApartmentShutdown* obj, 1388 | UINT64* identifier, APARTMENT_SHUTDOWN_REGISTRATION_COOKIE* cookie) 1389 | { 1390 | HRESULT hr; 1391 | dbg(L"called from %p", _ReturnAddress()); 1392 | dump("%p", obj); 1393 | hr = orig_RoRegisterForApartmentShutdown(obj, identifier, cookie); 1394 | dump("%08X", hr); 1395 | if (SUCCEEDED(hr)) { 1396 | dumpptr("%I64d", identifier); 1397 | dump("%p", cookie); 1398 | } 1399 | return hr; 1400 | } 1401 | 1402 | // ------------------------------------------------------------------------ 1403 | 1404 | void (STDMETHODCALLTYPE* orig_RoRevokeActivationFactories) 1405 | (RO_REGISTRATION_COOKIE cookie); 1406 | 1407 | STDAPI_(void) _RoRevokeActivationFactories(RO_REGISTRATION_COOKIE cookie) { 1408 | dbg(L"called from %p", _ReturnAddress()); 1409 | dump("%p", cookie); 1410 | orig_RoRevokeActivationFactories(cookie); 1411 | } 1412 | 1413 | // ------------------------------------------------------------------------ 1414 | 1415 | void (STDMETHODCALLTYPE* orig_RoUninitialize)(); 1416 | 1417 | STDAPI_(void) _RoUninitialize() { 1418 | dbg(L"called from %p", _ReturnAddress()); 1419 | orig_RoUninitialize(); 1420 | } 1421 | 1422 | // ------------------------------------------------------------------------ 1423 | 1424 | HRESULT (STDMETHODCALLTYPE* orig_RoUnregisterForApartmentShutdown) 1425 | (APARTMENT_SHUTDOWN_REGISTRATION_COOKIE cookie); 1426 | 1427 | STDAPI _RoUnregisterForApartmentShutdown( 1428 | APARTMENT_SHUTDOWN_REGISTRATION_COOKIE cookie) 1429 | { 1430 | HRESULT hr; 1431 | dbg(L"called from %p", _ReturnAddress()); 1432 | dump("%p", cookie); 1433 | hr = orig_RoUnregisterForApartmentShutdown(cookie); 1434 | dump("%08X", hr); 1435 | return hr; 1436 | } 1437 | 1438 | // ------------------------------------------------------------------------ 1439 | 1440 | #define h(x, nops) { #x, _##x, (void**)&orig_##x, nops } 1441 | #define t(x) { #x, 0, (void**)&_##x, 0 } 1442 | spy_export_t hooks[] = { 1443 | t(WindowsGetStringRawBuffer), 1444 | h(RoActivateInstance, 0), 1445 | h(RoGetActivationFactory, 1), 1446 | h(RoGetApartmentIdentifier, 0), 1447 | h(RoInitialize, 1), 1448 | h(RoRegisterActivationFactories, 0), 1449 | h(RoRegisterForApartmentShutdown, 0), 1450 | h(RoRevokeActivationFactories, 1), 1451 | h(RoUninitialize, 0), 1452 | h(RoUnregisterForApartmentShutdown, 1), 1453 | }; 1454 | #undef h 1455 | 1456 | void spy_init() { 1457 | log_init(); 1458 | spy_exports("api-ms-win-core-winrt-l1-1-0.dll", _countof(hooks), hooks); 1459 | } 1460 | 1461 | /* 1462 | * NOTE: it's not a good idea to do complex init in DllMain but I don't 1463 | * wanna have spinlocks in every hook to wait in case the init thread 1464 | * hasn't finished 1465 | */ 1466 | 1467 | BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { 1468 | (void)reserved; 1469 | (void)hinst; 1470 | if (reason == DLL_PROCESS_ATTACH) { 1471 | spy_init(); 1472 | } 1473 | return TRUE; 1474 | } 1475 | -------------------------------------------------------------------------------- /vcvarsall17.ps1: -------------------------------------------------------------------------------- 1 | # https://stackoverflow.com/questions/2124753/how-can-i-use-powershell-with-the-visual-studio-command-prompt 2 | 3 | param ([string]$arch = "amd64") 4 | 5 | Push-Location "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools" 6 | cmd /c "VsDevCmd.bat -arch=$arch&set" | 7 | ForEach-Object { 8 | if ($_ -match "=") { 9 | $v = $_.Split("=") 10 | Set-Item -Force -Path "ENV:\$($v[0])" -Value "$($v[1])" 11 | } 12 | } 13 | Pop-Location 14 | $oldcolor = $host.UI.RawUI.ForegroundColor 15 | $host.UI.RawUI.ForegroundColor = "Green" 16 | Write-Output ":: Visual Studio 2017 Command Prompt variables set" 17 | $host.UI.RawUI.ForegroundColor = $oldcolor 18 | --------------------------------------------------------------------------------