Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

508 lines
17 KiB

  1. //
  2. // marshal.h
  3. //
  4. #ifndef MARSHAL_H
  5. #define MARSHAL_H
  6. #include "private.h"
  7. #include "globals.h"
  8. #include "cicmutex.h"
  9. #include "winuserp.h"
  10. #include "systhrd.h"
  11. #include "smblock.h"
  12. #include "cregkey.h"
  13. #define DEFAULTMARSHALTIMEOUT 30000
  14. #define DEFAULTMARSHALCONNECTIONTIMEOUT 2000
  15. #ifdef QS_RAWINPUT
  16. #define QS_ALLINPUT400 (QS_ALLINPUT & ~QS_RAWINPUT)
  17. #else
  18. #define QS_ALLINPUT400 (QS_ALLINPUT)
  19. #endif
  20. #define QS_DEFAULTWAITFLAG (QS_ALLINPUT400 | QS_TRANSFER | QS_ALLPOSTMESSAGE)
  21. #ifdef DEBUG
  22. extern ULONG g_ulMarshalTimeOut;
  23. #define MARSHALTIMEOUT g_ulMarshalTimeOut
  24. const TCHAR c_szMarshal[] = TEXT("SOFTWARE\\Microsoft\\CTF\\Marshal\\");
  25. const TCHAR c_szTimeOut[] = TEXT("TimeOut");
  26. __inline void dbg_InitMarshalTimeOut()
  27. {
  28. CMyRegKey key;
  29. DWORD dw;
  30. if (key.Open(HKEY_CURRENT_USER, c_szMarshal, KEY_READ) != S_OK)
  31. return;
  32. if (key.QueryValue(dw, c_szTimeOut) != S_OK)
  33. return;
  34. g_ulMarshalTimeOut = (ULONG)dw;
  35. }
  36. #else
  37. #define MARSHALTIMEOUT DEFAULTMARSHALTIMEOUT
  38. #define dbg_InitMarshalTimeOut()
  39. #endif
  40. #define SZMARSHALINTERFACEFILEMAP __TEXT("MSCTF.MarshalInterface.FileMap.")
  41. #define SZRPCSENDRECEIVEEVENT __TEXT("MSCTF.SendReceive.Event.")
  42. #define SZRPCSENDRECEIVECONNECTIONEVENT __TEXT("MSCTF.SendReceiveConection.Event.")
  43. HRESULT CicCoMarshalInterface(REFIID riid, IUnknown *punk, ULONG *pulStubId, DWORD *pdwStubTime, DWORD dwSrcThreadId);
  44. HRESULT CicCoUnmarshalInterface(REFIID riid, DWORD dwStubThreadId, ULONG ulStubId, DWORD dwStubTIme, void **ppv);
  45. void HandleSendReceiveMsg(DWORD dwSrcThreadId, ULONG ulCnt);
  46. void FreeMarshaledStubs(SYSTHREAD *psfn);
  47. void FreeMarshaledStubsForThread(SYSTHREAD *psfn, DWORD dwThread);
  48. void StubCleanUp(ULONG ulStubId);
  49. //////////////////////////////////////////////////////////////////////////////
  50. //
  51. // MARSHALINTERFACE structure
  52. //
  53. //////////////////////////////////////////////////////////////////////////////
  54. typedef struct tag_MARSHALINTERFACE
  55. {
  56. IID iid;
  57. DWORD dwStubTime;
  58. } MARSHALINTERFACE;
  59. //////////////////////////////////////////////////////////////////////////////
  60. //
  61. // MARSHALPARAM structure
  62. //
  63. //////////////////////////////////////////////////////////////////////////////
  64. #define MPARAM_IN 0x000000001
  65. #define MPARAM_OUT 0x000000002
  66. #define MPARAM_INTERFACE 0x000010000
  67. #define MPARAM_POINTER 0x000020000
  68. #define MPARAM_ULONG 0x000040000
  69. #define MPARAM_BSTR 0x000080000
  70. #define MPARAM_STRUCT 0x000100000
  71. #define MPARAM_HBITMAP 0x000200000
  72. #define MPARAM_TF_LBBALLOONINFO 0x000400000
  73. #define MPARAM_HICON 0x000800000
  74. #define MPARAM_IN_POINTER (MPARAM_IN | MPARAM_POINTER)
  75. #define MPARAM_IN_INTERFACE (MPARAM_IN | MPARAM_INTERFACE)
  76. #define MPARAM_IN_ULONG (MPARAM_IN | MPARAM_ULONG)
  77. #define MPARAM_IN_STRUCT (MPARAM_IN | MPARAM_STRUCT)
  78. #define MPARAM_IN_HBITMAP (MPARAM_IN | MPARAM_HBITMAP)
  79. #define MPARAM_IN_HICON (MPARAM_IN | MPARAM_HICON)
  80. #define MPARAM_OUT_POINTER (MPARAM_OUT | MPARAM_POINTER)
  81. #define MPARAM_OUT_INTERFACE (MPARAM_OUT | MPARAM_INTERFACE)
  82. #define MPARAM_OUT_BSTR (MPARAM_OUT | MPARAM_BSTR)
  83. #define MPARAM_OUT_HBITMAP (MPARAM_OUT | MPARAM_HBITMAP)
  84. #define MPARAM_OUT_TF_LBBALLOONINFO (MPARAM_OUT | MPARAM_TF_LBBALLOONINFO)
  85. #define MPARAM_OUT_HICON (MPARAM_OUT | MPARAM_HICON)
  86. #define MPARAM_IN_OUT_INTERFACE (MPARAM_IN | MPARAM_OUT | MPARAM_INTERFACE)
  87. typedef struct tag_MARSHALPARAM
  88. {
  89. ULONG cbBufSize;
  90. DWORD dwFlags;
  91. // DWORD buf[1];
  92. } MARSHALPARAM;
  93. typedef struct tag_MARSHALMSG
  94. {
  95. ULONG cbSize;
  96. ULONG cbBufSize;
  97. IID iid;
  98. ULONG ulMethodId;
  99. ULONG ulParamNum;
  100. union {
  101. HRESULT hrRet;
  102. ULONG ulRet;
  103. };
  104. DWORD dwSrcThreadId;
  105. DWORD dwSrcProcessId;
  106. ULONG ulStubId;
  107. DWORD dwStubTime;
  108. HRESULT hrMarshalOutParam;
  109. ULONG ulParamOffset[1];
  110. } MARSHALMSG;
  111. __inline MARSHALPARAM *GetMarshalParam(MARSHALMSG *pMsg, ULONG ulParam)
  112. {
  113. return (MARSHALPARAM *)(((BYTE *)pMsg) + pMsg->ulParamOffset[ulParam]);
  114. }
  115. //////////////////////////////////////////////////////////////////////////////
  116. //
  117. // ParamExtractor
  118. //
  119. //////////////////////////////////////////////////////////////////////////////
  120. __inline void *ParamToBufferPointer(MARSHALPARAM *pParam)
  121. {
  122. return (void *)((BYTE *)pParam + sizeof(MARSHALPARAM));
  123. }
  124. __inline void *ParamToBufferPointer(MARSHALMSG *pMsg, ULONG ulParam)
  125. {
  126. MARSHALPARAM *pParam = GetMarshalParam(pMsg, ulParam);
  127. return (void *)((BYTE *)pParam + sizeof(MARSHALPARAM));
  128. }
  129. __inline void *ParamToPointer(MARSHALPARAM *pParam)
  130. {
  131. return *(void **)((BYTE *)pParam + sizeof(MARSHALPARAM));
  132. }
  133. __inline void *ParamToPointer(MARSHALMSG *pMsg , ULONG ulParam)
  134. {
  135. MARSHALPARAM *pParam = GetMarshalParam(pMsg, ulParam);
  136. return *(void **)((BYTE *)pParam + sizeof(MARSHALPARAM));
  137. }
  138. __inline ULONG ParamToULONG(MARSHALMSG *pMsg , ULONG ulParam)
  139. {
  140. MARSHALPARAM *pParam = GetMarshalParam(pMsg, ulParam);
  141. return *(ULONG *)((BYTE *)pParam + sizeof(MARSHALPARAM));
  142. }
  143. HBITMAP ParamToHBITMAP(MARSHALMSG *pMsg , ULONG ulParam);
  144. //////////////////////////////////////////////////////////////////////////////
  145. //
  146. // CModalLoop
  147. //
  148. //////////////////////////////////////////////////////////////////////////////
  149. class CModalLoop : public CSysThreadRef
  150. {
  151. public:
  152. CModalLoop(SYSTHREAD *psfn);
  153. ~CModalLoop();
  154. HRESULT BlockFn(CCicEvent *pevent, DWORD dwWaitingThreadId, DWORD &dwWaitFlags);
  155. private:
  156. void WaitHandleWndMessages(DWORD dwQueueFlags);
  157. BOOL WaitRemoveMessage(UINT uMsgFirst, UINT uMsgLast, DWORD dwFlags);
  158. BOOL MyPeekMessage(MSG *pMsg, HWND hwnd, UINT min, UINT max, WORD wFlag);
  159. ULONG _wQuitCode;
  160. BOOL _fQuitReceived;
  161. };
  162. //////////////////////////////////////////////////////////////////////////////
  163. //
  164. // CThreadMarshalWnd
  165. //
  166. //////////////////////////////////////////////////////////////////////////////
  167. class CThreadMarshalWnd
  168. {
  169. public:
  170. CThreadMarshalWnd();
  171. ~CThreadMarshalWnd();
  172. BOOL Init(DWORD dwThreadId);
  173. BOOL PostMarshalThreadMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
  174. static BOOL DestroyAll();
  175. static BOOL DestroyThreadMarshalWnd(DWORD dwThread);
  176. static HWND GetThreadMarshalWnd(DWORD dwThread);
  177. static void ClearMarshalWndProc(DWORD dwProcessId);
  178. BOOL IsWindow()
  179. {
  180. return ::IsWindow(_hwnd);
  181. }
  182. BOOL IsThreadWindow();
  183. void SetMarshalWindow(HWND hwndMarshal)
  184. {
  185. _hwnd = hwndMarshal;
  186. }
  187. private:
  188. static BOOL EnumThreadWndProc(HWND hwnd, LPARAM lParam);
  189. DWORD _dwThreadId;
  190. HWND _hwnd;
  191. };
  192. void RegisterMarshalWndClass();
  193. HWND EnsureMarshalWnd();
  194. //////////////////////////////////////////////////////////////////////////////
  195. //
  196. // CProxy
  197. //
  198. //////////////////////////////////////////////////////////////////////////////
  199. #define CPROXY_PARAM_START() CPROXY_PARAM param[] = {
  200. #define CPROXY_PARAM_ULONG_IN(ul) \
  201. {MPARAM_IN_ULONG, NULL, ul, NULL, sizeof(ULONG), 1},
  202. #define CPROXY_PARAM_WCHAR_IN(pch, cch) \
  203. {MPARAM_IN_POINTER, (void *)(pch), 0, NULL, cch * sizeof(WCHAR), 1},
  204. #define CPROXY_PARAM_POINTER_IN(p) \
  205. {MPARAM_IN_POINTER, (void *)(p), 0, NULL, sizeof(*p), 1},
  206. #define CPROXY_PARAM_POINTER_ARRAY_IN(p, nCnt) \
  207. {MPARAM_IN_POINTER, (void *)(p), 0, NULL, sizeof(*p), nCnt},
  208. #define CPROXY_PARAM_INTERFACE_IN(p, iid) \
  209. {MPARAM_IN_INTERFACE, p, 0, &iid, sizeof(void *), 1},
  210. #define CPROXY_PARAM_INTERFACE_ARRAY_IN(p, iid, nCnt) \
  211. {MPARAM_IN_INTERFACE, p, 0, &iid, sizeof(void *), nCnt},
  212. #define CPROXY_PARAM_POINTER_OUT(p) \
  213. {MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), 1},
  214. #define CPROXY_PARAM_POINTER_ARRAY_OUT(p, nCnt) \
  215. {MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), nCnt},
  216. #define CPROXY_PARAM_INTERFACE_OUT(p, iid) \
  217. {MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), 1},
  218. #define CPROXY_PARAM_INTERFACE_ARRAY_OUT(p, iid, nCnt) \
  219. {MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), nCnt},
  220. #define CPROXY_PARAM_INTERFACE_IN_OUT(p, iid) \
  221. {MPARAM_IN_OUT_INTERFACE, p, 0, &iid, sizeof(void *), 1},
  222. #define CPROXY_PARAM_INTERFACE_ARRAY_IN_OUT(p, iid, nCnt) \
  223. {MPARAM_IN_OUT_INTERFACE, p, 0, &iid, sizeof(void *), nCnt},
  224. #define CPROXY_PARAM_BSTR_OUT(p) \
  225. {MPARAM_OUT_BSTR, p, 0, NULL, 0, 1},
  226. #define CPROXY_PARAM_HBITMAP_OUT(p) \
  227. {MPARAM_OUT_HBITMAP, p, 0, NULL, 0, 1},
  228. #define CPROXY_PARAM_HICON_OUT(p) \
  229. {MPARAM_OUT_HICON, p, 0, NULL, 0, 1},
  230. #define CPROXY_PARAM_HBITMAP_IN(hbmp) \
  231. {MPARAM_IN_HBITMAP, &hbmp, 0, NULL, 0, 1},
  232. #define CPROXY_PARAM_HICON_IN(hicon) \
  233. {MPARAM_IN_HICON, &hicon, 0, NULL, 0, 1},
  234. #define CPROXY_PARAM_TF_LBBALLOONINFO_OUT(p) \
  235. {MPARAM_OUT_TF_LBBALLOONINFO, (void *)p, 0, NULL, sizeof(*p), 1},
  236. #define CPROXY_PARAM_STRUCT_IN(s) \
  237. {MPARAM_IN_STRUCT, &s, 0, NULL, sizeof(s), 1},
  238. #define CPROXY_PARAM_CALL(uMethodId) \
  239. }; \
  240. return proxy_Param(uMethodId, ARRAYSIZE(param), param);
  241. #define CPROXY_PARAM_CALL_NOPARAM(x) return proxy_Param(x, 0, NULL);
  242. typedef struct {
  243. DWORD dwFlags;
  244. void *pv;
  245. ULONG ul;
  246. const IID *piid;
  247. ULONG cbUnitSize;
  248. ULONG ulCount; // if this is array, the number of unit.
  249. ULONG GetBufSize() {return cbUnitSize * ulCount;}
  250. } CPROXY_PARAM;
  251. class CProxy : public CSysThreadRef
  252. {
  253. public:
  254. CProxy(SYSTHREAD *psfn);
  255. virtual ~CProxy();
  256. ULONG InternalAddRef();
  257. ULONG InternalRelease();
  258. void Init(REFIID riid,
  259. ULONG ulProxyId,
  260. ULONG ulIdStubId,
  261. DWORD dwStubTime,
  262. DWORD dwStubThreadId,
  263. DWORD dwCurThreadId,
  264. DWORD dwCurProcessId);
  265. //
  266. // IRpcChannelBuffer
  267. //
  268. HRESULT SendReceive( MARSHALMSG *pMsg , ULONG ulBlockId);
  269. ULONG GetStubId() {return _ulStubId;}
  270. DWORD GetStubThreadId() {return _dwStubThreadId;}
  271. protected:
  272. HRESULT proxy_Param(ULONG ulMethodId, ULONG ulParamNum, CPROXY_PARAM *pProsyParam);
  273. protected:
  274. IID _iid; // interface id for this proxy.
  275. ULONG _cRef;
  276. private:
  277. CThreadMarshalWnd _tmw;
  278. ULONG _ulProxyId; // unique proxy id in src thread.
  279. ULONG _ulStubId; // unique stub id in stub thread.
  280. DWORD _dwStubTime; // stub created time stamp.
  281. DWORD _dwStubThreadId; // stub thread id.
  282. DWORD _dwSrcThreadId; // src thread id.
  283. DWORD _dwSrcProcessId; // src process id.
  284. #ifdef DEBUG
  285. BOOL _fInLoop;
  286. #endif
  287. };
  288. //////////////////////////////////////////////////////////////////////////////
  289. //
  290. // CMarshalInterfaceFileMapping
  291. //
  292. //////////////////////////////////////////////////////////////////////////////
  293. class CMarshalInterfaceFileMapping : public CCicFileMapping
  294. {
  295. public:
  296. CMarshalInterfaceFileMapping(DWORD dwThreadId, ULONG ulStubId, ULONG ulStubTime) : CCicFileMapping()
  297. {
  298. if (SetName2(szFileMap, ARRAYSIZE(szFileMap), SZMARSHALINTERFACEFILEMAP, dwThreadId, ulStubId, ulStubTime))
  299. _pszFile = szFileMap;
  300. }
  301. private:
  302. char szFileMap[MAX_PATH];
  303. };
  304. //////////////////////////////////////////////////////////////////////////////
  305. //
  306. // CStub
  307. //
  308. //////////////////////////////////////////////////////////////////////////////
  309. #define CSTUB_PARAM_START() CPROXY_PARAM param[] = {
  310. #define CSTUB_PARAM_ULONG_IN(ul) \
  311. {MPARAM_IN_ULONG, NULL, ul, NULL, 0 /*sizeof(ULONG)*/, 1},
  312. #define CSTUB_PARAM_POINTER_IN(p) \
  313. {MPARAM_IN_POINTER, (void *)(p), 0, NULL, 0 /*sizeof(*p)*/, 1},
  314. #define CSTUB_PARAM_POINTER_ARRAY_IN(p, nCnt) \
  315. {MPARAM_IN_POINTER, (void *)(p), 0, NULL, 0 /*sizeof(*p)*/, nCnt},
  316. #define CSTUB_PARAM_INTERFACE_IN(p, iid) \
  317. {MPARAM_IN_INTERFACE, p, 0, &iid, 0 /*sizeof(void *)*/, 1},
  318. #define CSTUB_PARAM_INTERFACE_ARRAY_IN(p, iid, cnt) \
  319. {MPARAM_IN_INTERFACE, p, 0, &iid, 0 /*sizeof(void *)*/, cnt},
  320. #define CSTUB_PARAM_POINTER_OUT(p) \
  321. {MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), 1},
  322. #define CSTUB_PARAM_POINTER_ARRAY_OUT(p, nCnt) \
  323. {MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), nCnt},
  324. #define CSTUB_PARAM_INTERFACE_OUT(p, iid) \
  325. {MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), 1},
  326. #define CSTUB_PARAM_INTERFACE_ARRAY_OUT(p, iid, cnt) \
  327. {MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), cnt},
  328. #define CSTUB_PARAM_BSTR_OUT(p) \
  329. {MPARAM_OUT_BSTR, p, 0, NULL, 0, 1},
  330. #define CSTUB_PARAM_HBITMAP_OUT(p) \
  331. {MPARAM_OUT_HBITMAP, p, 0, NULL, 0, 1},
  332. #define CSTUB_PARAM_HICON_OUT(p) \
  333. {MPARAM_OUT_HICON, p, 0, NULL, 0, 1},
  334. #define CSTUB_PARAM_TF_LBBALLOONINFO_OUT(p) \
  335. {MPARAM_OUT_TF_LBBALLOONINFO, (void *)p, 0, NULL, sizeof(*p), 1},
  336. #define CSTUB_PARAM_HBITMAP_IN(hbmp) \
  337. {MPARAM_IN_HBITMAP, &hbmp, 0, NULL, 0, 1},
  338. #define CSTUB_PARAM_HICON_IN(hicon) \
  339. {MPARAM_IN_HICON, &hicon, 0, NULL, 0, 1},
  340. #define CSTUB_PARAM_END() \
  341. };
  342. #define CSTUB_PARAM_INTERFACE_OUT_RELEASE(p) \
  343. if (p) ((IUnknown *)p)->Release();
  344. #define CSTUB_PARAM_INTERFACE_ARRAY_OUT_RELEASE(p, ulCnt) \
  345. for (ULONG __ul = 0; __ul < ulCnt; __ul++) \
  346. if (p[__ul]) ((IUnknown *)p[__ul])->Release();
  347. #define CSTUB_PARAM_CALL(pMsg, hrRet, psb) \
  348. stub_OutParam(_this, pMsg, pMsg->ulMethodId, ARRAYSIZE(param), param, psb); \
  349. pMsg->hrRet = hrRet;
  350. #define CSTUB_PARAM_RETURN() \
  351. return S_OK;
  352. #define CSTUB_NOT_IMPL() \
  353. Assert(0); \
  354. return S_OK;
  355. class CStub
  356. {
  357. public:
  358. CStub();
  359. virtual ~CStub();
  360. ULONG _AddRef();
  361. ULONG _Release();
  362. ULONG GetStubId() {return _ulStubId;}
  363. virtual HRESULT Invoke(MARSHALMSG *pMsg, CSharedBlock *psb) = 0;
  364. void ClearFileMap()
  365. {
  366. if (_pfm)
  367. {
  368. _pfm->Close();
  369. delete _pfm;
  370. _pfm = NULL;
  371. }
  372. }
  373. static HRESULT stub_OutParam(CStub *_this,
  374. MARSHALMSG *pMsg,
  375. ULONG ulMethodId,
  376. ULONG ulParamNum,
  377. CPROXY_PARAM *pProxyParam,
  378. CSharedBlock *psb);
  379. CMarshalInterfaceFileMapping *_pfm;
  380. IID _iid; // interface id for this stub.
  381. IUnknown *_punk; // actual object.
  382. ULONG _ulStubId; // unique stubid of this thread.
  383. DWORD _dwStubTime; // stub created time stamp.
  384. DWORD _dwStubThreadId; // stub thread id.
  385. DWORD _dwStubProcessId; // stub process id.
  386. DWORD _dwSrcThreadId; // src thread id.
  387. BOOL _fNoRemoveInDtor; // this stub has been removed from list.
  388. // so don't try at dtor.
  389. ULONG _cRef;
  390. };
  391. #endif // MARSHAL_H