https://bugs.winehq.org/show_bug.cgi?id=35884
--- Comment #6 from Nikolay Sivov bunglehead@gmail.com --- Improved layout with more fields matching on x64 would be something like this:
--- struct oletls { struct apartment *apt; IErrorInfo *errorinfo; /* see errorinfo.c */ DWORD thread_seqid;/* (+8h/+10h) returned with CoGetCurrentProcess */ DWORD apt_mask; /* (+Ch/+14h) apartment mask */ DWORD inits; DWORD_PTR unknown1; DWORD ole_inits; DWORD unknown2; DWORD_PTR unknown3[5]; DWORD caller_tid; /* (+34h/+58h) CoGetCallerTID() */ DWORD_PTR unknown4; IObjContext *context_token; /* (+38h/+68h on x86) */ IUnknown *call_state; /* current call context (+3Ch on x86) */ DWORD unknown5[12]; GUID causality_id; /* (+80h/+d8h) */ DWORD unknown6[18]; IUnknown *cancel_object; /* cancel object set by CoSetCancelObject (+F8h on x86) */ IUnknown *state; /* see CoSetState */ struct list spies; /* Spies installed with CoRegisterInitializeSpy */ DWORD spies_lock; LONG pending_call_count_client; /* number of client calls pending */ LONG pending_call_count_server; /* number of server calls pending */ }; ---
So caller tid is at 0x58. Function seems to simply return this field value.
Regarding actually implementing this, I think it could about the same as causality id being set/restored around RPC_ExecuteCall(), which real question being how this TID is communicated through RPC_MESSAGE. (This is probably limited to same machine case, or even for certain local protocols)