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.

2598 lines
71 KiB

  1. //
  2. // marshal.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "marshal.h"
  7. #include "thdutil.h"
  8. #include "cicmutex.h"
  9. #include "helpers.h"
  10. #include "mstub.h"
  11. #include "mproxy.h"
  12. #include "ithdmshl.h"
  13. #include "transmit.h"
  14. #include "smblock.h"
  15. #include "utb.h"
  16. #include "nuimgr.h"
  17. #include "timlist.h"
  18. #define WIN9X_SRCTHREADID 0x0001
  19. inline HRESULT MAKE_WIN32( HRESULT status )
  20. {
  21. return MAKE_HRESULT( SEVERITY_ERROR, FACILITY_WIN32, status );
  22. }
  23. #ifdef DEBUG
  24. ULONG g_ulMarshalTimeOut = DEFAULTMARSHALTIMEOUT;
  25. #endif
  26. //////////////////////////////////////////////////////////////////////////////
  27. //
  28. // CSendReceiveEvent
  29. //
  30. //////////////////////////////////////////////////////////////////////////////
  31. class CSendReceiveEvent : public CCicEvent
  32. {
  33. public:
  34. CSendReceiveEvent(DWORD dwThreadId, ULONG ulBlockId) : CCicEvent()
  35. {
  36. if (SetName2(sz, ARRAYSIZE(sz), SZRPCSENDRECEIVEEVENT, dwThreadId, ulBlockId))
  37. _psz = sz;
  38. }
  39. private:
  40. char sz[MAX_PATH];
  41. };
  42. //////////////////////////////////////////////////////////////////////////////
  43. //
  44. // CSendReceiveConnectionEvent
  45. //
  46. //////////////////////////////////////////////////////////////////////////////
  47. class CSendReceiveConnectionEvent : public CCicEvent
  48. {
  49. public:
  50. CSendReceiveConnectionEvent(DWORD dwThreadId, ULONG ulBlockId) : CCicEvent()
  51. {
  52. if (SetName2(sz, ARRAYSIZE(sz), SZRPCSENDRECEIVECONNECTIONEVENT, dwThreadId, ulBlockId))
  53. _psz = sz;
  54. }
  55. private:
  56. char sz[MAX_PATH];
  57. };
  58. //////////////////////////////////////////////////////////////////////////////
  59. //
  60. // CCheckThreadInputIdle
  61. //
  62. //////////////////////////////////////////////////////////////////////////////
  63. #define SZCHECKTHREADINPUTIDLE __TEXT("MSCTF.CheckThreadInptIdle.Event.")
  64. class CCheckThreadInputIdle : public CCicEvent
  65. {
  66. public:
  67. CCheckThreadInputIdle(DWORD dwThreadId, DWORD dw) : CCicEvent()
  68. {
  69. if (SetName2(sz, ARRAYSIZE(sz), SZCHECKTHREADINPUTIDLE, dwThreadId, dw))
  70. _psz = sz;
  71. }
  72. private:
  73. char sz[MAX_PATH];
  74. };
  75. //--------------------------------------------------------------------------
  76. //
  77. // GetOleMainThreadWindow
  78. //
  79. //--------------------------------------------------------------------------
  80. BOOL IsOleMainThreadWindow(HWND hwnd)
  81. {
  82. char szClassName[32];
  83. if (!GetClassName(hwnd, szClassName, ARRAYSIZE(szClassName)))
  84. return FALSE;
  85. if (!lstrcmp(szClassName, TEXT("OleMainThreadWndClass")))
  86. return TRUE;
  87. return FALSE;
  88. }
  89. HWND FindOleMainThredWindow(DWORD dwThreadId)
  90. {
  91. HWND hwnd = FindWindowEx(IsOnNT5() ? HWND_MESSAGE : NULL,
  92. NULL,
  93. TEXT("OleMainThreadWndClass"), NULL);
  94. while (hwnd)
  95. {
  96. if (dwThreadId == GetWindowThreadProcessId(hwnd, NULL))
  97. {
  98. if (IsOleMainThreadWindow(hwnd))
  99. return hwnd;
  100. }
  101. hwnd = GetWindow(hwnd, GW_HWNDNEXT);
  102. }
  103. return NULL;
  104. }
  105. HWND GetOleMainThreadWindow(SYSTHREAD *psfn)
  106. {
  107. HWND hwndOle = NULL;
  108. if (psfn->hwndOleMainThread)
  109. {
  110. if (IsWindow(psfn->hwndOleMainThread) &&
  111. IsOleMainThreadWindow(psfn->hwndOleMainThread))
  112. return psfn->hwndOleMainThread;
  113. psfn->hwndOleMainThread = NULL;
  114. }
  115. hwndOle = FindOleMainThredWindow(GetCurrentThreadId());
  116. psfn->hwndOleMainThread = hwndOle;
  117. return hwndOle;
  118. }
  119. //--------------------------------------------------------------------------
  120. //
  121. // FindStub
  122. //
  123. //--------------------------------------------------------------------------
  124. int FindStub(CPtrArray<CStub> *prgStub, ULONG ulStubId)
  125. {
  126. int nMin = 0;
  127. int nMax = prgStub->Count();
  128. int nMid = -1;
  129. while (nMin < nMax)
  130. {
  131. ULONG ulMidStubId;
  132. nMid = (nMin + nMax) / 2;
  133. ulMidStubId = prgStub->Get(nMid)->_ulStubId;
  134. if (ulMidStubId > ulStubId)
  135. nMax = nMid;
  136. else if (ulMidStubId < ulStubId)
  137. nMin = nMid + 1;
  138. else
  139. return nMid;
  140. }
  141. return -1;
  142. }
  143. //--------------------------------------------------------------------------
  144. //
  145. // FindStubId
  146. //
  147. //--------------------------------------------------------------------------
  148. BOOL FindStubId(SYSTHREAD *psfn, ULONG *pulStubId, ULONG *pulInsert)
  149. {
  150. Assert(psfn->prgStub);
  151. int i;
  152. int nCnt = psfn->prgStub->Count();
  153. BOOL fFound;
  154. if (nCnt >= 0x7fffffff)
  155. {
  156. Assert(0);
  157. return FALSE;
  158. }
  159. *pulStubId = 0;
  160. *pulInsert = 0;
  161. if (!nCnt)
  162. return TRUE;
  163. //
  164. // max is 0x7ffffffff....
  165. //
  166. *pulStubId = 0x7fffffff;
  167. fFound = FALSE;
  168. for (i = nCnt - 1; i >= 0; i--)
  169. {
  170. CStub *pStub = psfn->prgStub->Get(i);
  171. if (*pulStubId > pStub->_ulStubId)
  172. {
  173. i++;
  174. *pulStubId = pStub->_ulStubId + 1;
  175. fFound = TRUE;
  176. break;
  177. }
  178. *pulStubId = pStub->_ulStubId - 1;
  179. }
  180. //
  181. // we should be able to find any number in 32bit value.
  182. //
  183. Assert(fFound);
  184. Assert(*pulStubId <= 0x7fffffff);
  185. #ifdef DEBUG
  186. Assert(FindStub(psfn->prgStub, *pulStubId) == -1);
  187. #endif
  188. *pulInsert = i;
  189. return fFound;
  190. }
  191. #ifdef DEBUG
  192. void dbg_CheckStubIds(SYSTHREAD *psfn)
  193. {
  194. Assert(psfn->prgStub);
  195. int i;
  196. int nCnt = psfn->prgStub->Count();
  197. CStub *pStubPrev = psfn->prgStub->Get(0);
  198. for (i = 1; i < nCnt; i++)
  199. {
  200. CStub *pStub = psfn->prgStub->Get(i);
  201. Assert(pStubPrev->_ulStubId < pStub->_ulStubId);
  202. pStubPrev = pStub;
  203. }
  204. }
  205. #else
  206. #define dbg_CheckStubIds(psfn)
  207. #endif
  208. //--------------------------------------------------------------------------
  209. //
  210. // CicCoMarshalInterface
  211. //
  212. //--------------------------------------------------------------------------
  213. HRESULT CicCoMarshalInterface(REFIID riid, IUnknown *punk, ULONG *pulStubId, DWORD *pdwStubTime, DWORD dwSrcThreadId)
  214. {
  215. HRESULT hr = E_OUTOFMEMORY;
  216. SYSTHREAD *psfn = GetSYSTHREAD();
  217. CStub *pStub = NULL;
  218. DWORD dwThreadId = GetCurrentThreadId();
  219. MARSHALINTERFACE *pmi = NULL;
  220. ULONG ulStubId;
  221. ULONG ulInsert;
  222. DWORD dwStubTime;
  223. CCicSecAttr sa;
  224. if (!psfn)
  225. return E_FAIL;
  226. if (!psfn->prgStub)
  227. {
  228. psfn->prgStub = new CPtrArray<CStub>;
  229. if (!psfn->prgStub)
  230. {
  231. goto Exit;
  232. }
  233. }
  234. if (!FindStubId(psfn, &ulStubId, &ulInsert))
  235. {
  236. Assert(0);
  237. hr = E_FAIL;
  238. goto Exit;
  239. }
  240. dwStubTime = GetTickCount();
  241. pStub = StubCreator(riid, punk, ulStubId, dwStubTime, psfn->dwThreadId, psfn->dwProcessId, dwSrcThreadId);
  242. if (!pStub)
  243. {
  244. Assert(0);
  245. goto Exit;
  246. }
  247. if (!psfn->prgStub->Insert(ulInsert, 1))
  248. {
  249. goto Exit;
  250. }
  251. psfn->prgStub->Set(ulInsert, pStub);
  252. dbg_CheckStubIds(psfn);
  253. pStub->_pfm = new CMarshalInterfaceFileMapping(dwThreadId, ulStubId, dwStubTime);
  254. if (pStub->_pfm == NULL)
  255. {
  256. goto Exit;
  257. }
  258. pmi = (MARSHALINTERFACE *)pStub->_pfm->Create(sa, sizeof(MARSHALINTERFACE), NULL);
  259. if (!pmi)
  260. {
  261. goto Exit;
  262. }
  263. pmi->iid = riid;
  264. pmi->dwStubTime = dwStubTime;
  265. *pulStubId = ulStubId;
  266. *pdwStubTime = dwStubTime;
  267. hr = S_OK;
  268. Exit:
  269. if (hr != S_OK && pStub != NULL)
  270. {
  271. // pStub dtor will remove stub from psfn->prgStub
  272. pStub->_Release();
  273. }
  274. return hr;
  275. }
  276. //--------------------------------------------------------------------------
  277. //
  278. // CicCoUnmarshalInterface
  279. //
  280. //--------------------------------------------------------------------------
  281. HRESULT CicCoUnmarshalInterface(REFIID riid, DWORD dwStubThreadId, ULONG ulStubId, DWORD dwStubTime, void **ppv)
  282. {
  283. HRESULT hr = E_FAIL;
  284. SYSTHREAD *psfn = GetSYSTHREAD();
  285. IUnknown *punkProxy = NULL;
  286. MARSHALINTERFACE *pmi;
  287. CMarshalInterfaceFileMapping fm(dwStubThreadId, ulStubId, dwStubTime);
  288. *ppv = NULL;
  289. if (!psfn)
  290. {
  291. hr = E_OUTOFMEMORY;
  292. goto Exit;
  293. }
  294. pmi = (MARSHALINTERFACE *)fm.Open();
  295. if (!pmi)
  296. {
  297. // Assert(0);
  298. hr = MAKE_WIN32(RPC_S_SERVER_UNAVAILABLE);
  299. goto Exit;
  300. }
  301. if (!IsEqualIID(pmi->iid, riid))
  302. {
  303. // Assert(0);
  304. hr = E_FAIL;
  305. goto Exit;
  306. }
  307. punkProxy = ProxyCreator(psfn,
  308. pmi->iid,
  309. ulStubId,
  310. dwStubTime,
  311. dwStubThreadId,
  312. psfn->dwThreadId,
  313. psfn->dwProcessId);
  314. if (!punkProxy)
  315. {
  316. Assert(0);
  317. hr = E_OUTOFMEMORY;
  318. goto Exit;
  319. }
  320. *ppv = punkProxy;
  321. hr = S_OK;
  322. Exit:
  323. fm.Close();
  324. return hr;
  325. }
  326. //--------------------------------------------------------------------------
  327. //
  328. // HandleSendReceive
  329. //
  330. //--------------------------------------------------------------------------
  331. void HandleSendReceiveMsg(DWORD dwSrcThreadId, ULONG ulBlockId)
  332. {
  333. MARSHALMSG *pMsg = NULL;
  334. SYSTHREAD *psfn = GetSYSTHREAD();
  335. int nTarget;
  336. CStub *pStub = NULL;
  337. HRESULT hr;
  338. CSharedBlock *psb;
  339. if (!psfn)
  340. {
  341. Assert(0);
  342. return;
  343. }
  344. Assert(IsOnNT() || (dwSrcThreadId == WIN9X_SRCTHREADID));
  345. CSendReceiveEvent event(dwSrcThreadId, ulBlockId);
  346. CSendReceiveConnectionEvent eventc(dwSrcThreadId, ulBlockId);
  347. if (eventc.Open())
  348. eventc.Set();
  349. if (psfn->pti && (psfn->dwThreadId == psfn->pti->dwThreadId))
  350. psfn->pti->ulInMarshal++;
  351. else
  352. Assert(0);
  353. psb = EnsureSharedBlockForThread(psfn, dwSrcThreadId);
  354. if (!psb)
  355. {
  356. TraceMsg(TF_EVENT, "HandleSendReceive no Shared Block Ptr");
  357. goto Exit;
  358. }
  359. pMsg = (MARSHALMSG *)psb->GetPtrFromBlockId(ulBlockId);
  360. if (!pMsg)
  361. {
  362. TraceMsg(TF_EVENT, "HandleSendReceive no Msg Ptr");
  363. goto Exit;
  364. }
  365. if (!psfn->prgStub)
  366. {
  367. TraceMsg(TF_EVENT, "HandleSendReceive no more sink");
  368. goto Exit;
  369. }
  370. nTarget = FindStub(psfn->prgStub, pMsg->ulStubId);
  371. if (nTarget == -1)
  372. {
  373. TraceMsg(TF_EVENT, "HandleSendReceive no Stub");
  374. goto Exit;
  375. }
  376. pStub = psfn->prgStub->Get(nTarget);
  377. if (!pStub)
  378. {
  379. TraceMsg(TF_EVENT, "HandleSendReceive no Stub Ptr");
  380. goto Exit;
  381. }
  382. if (pStub->_dwStubTime != pMsg->dwStubTime)
  383. {
  384. TraceMsg(TF_EVENT, "HandleSendReceive old proxy was used");
  385. goto Exit;
  386. }
  387. Assert(IsEqualIID(pStub->_iid, pMsg->iid));
  388. #ifdef DEBUG
  389. TCHAR _szModule[MAX_PATH];
  390. ::GetModuleFileName(NULL, _szModule, sizeof(_szModule)/sizeof(TCHAR));
  391. TraceMsg(TF_EVENT, "%s HandleSendReceive Invoke", _szModule);
  392. #endif
  393. //
  394. // we check the file map handle to marshal this interface itself.
  395. //
  396. pStub->ClearFileMap();
  397. _try
  398. {
  399. hr = pStub->Invoke(pMsg, psb);
  400. }
  401. _except(1)
  402. {
  403. #ifdef DEBUG
  404. TraceMsg(TF_EVENT, "%s HandleSendReceive Except", _szModule);
  405. #endif
  406. Assert(0);
  407. goto Exit;
  408. }
  409. if (FAILED(hr))
  410. {
  411. #ifdef DEBUG
  412. TraceMsg(TF_EVENT, "%s HandleSendReceive Error", _szModule);
  413. #endif
  414. Assert(0);
  415. goto Exit;
  416. }
  417. #ifdef DEBUG
  418. TraceMsg(TF_EVENT, "%s HandleSendReceive OK", _szModule);
  419. #endif
  420. #if 0
  421. if (IsOnNT5())
  422. {
  423. //
  424. // for Office10 beta.
  425. //
  426. // we want to allow SetForegroundWindow always when marshalling
  427. // call happens. Thus we may have non-necessary calls here.
  428. // Needs to find a good place to call this.
  429. //
  430. ALLOWSETFOREGROUNDWINDOW fnAllowSetForeground;
  431. fnAllowSetForeground = EnsureAllowSetForeground();
  432. if (fnAllowSetForeground)
  433. fnAllowSetForeground(pMsg->dwSrcProcessId);
  434. }
  435. #endif
  436. Exit:
  437. if (psfn->pti && (psfn->dwThreadId == psfn->pti->dwThreadId))
  438. psfn->pti->ulInMarshal--;
  439. else
  440. Assert(0);
  441. if (event.Open())
  442. event.Set();
  443. }
  444. //////////////////////////////////////////////////////////////////////////////
  445. //
  446. // CModalLoop
  447. //
  448. //////////////////////////////////////////////////////////////////////////////
  449. //--------------------------------------------------------------------------
  450. //
  451. // ctor
  452. //
  453. //--------------------------------------------------------------------------
  454. CModalLoop::CModalLoop(SYSTHREAD *psfn) : CSysThreadRef(psfn)
  455. {
  456. _wQuitCode = 0;
  457. _fQuitReceived = FALSE;
  458. }
  459. //--------------------------------------------------------------------------
  460. //
  461. // dtor
  462. //
  463. //--------------------------------------------------------------------------
  464. CModalLoop::~CModalLoop()
  465. {
  466. if (_fQuitReceived)
  467. PostQuitMessage(_wQuitCode);
  468. }
  469. //--------------------------------------------------------------------------
  470. //
  471. // WaitHandleWndMessage
  472. //
  473. //--------------------------------------------------------------------------
  474. #define WRM_MARSHALWND 0x0001
  475. #define WRM_DISPATCH 0x0002
  476. #define WRM_OLEWINDOW 0x0004
  477. #define WRM_MARSHALWNDDISPATCH (WRM_DISPATCH | WRM_MARSHALWND)
  478. void CModalLoop::WaitHandleWndMessages(DWORD dwQueueFlags)
  479. {
  480. // Try to clear the queue as best we can of any messages that
  481. // might be holding off some other modal loop from executing.
  482. // So we eat all mouse and key events.
  483. if (dwQueueFlags & QS_KEY)
  484. {
  485. WaitRemoveMessage(WM_KEYFIRST, WM_KEYLAST, 0);
  486. }
  487. // Clear mouse releated messages if there are any
  488. if (dwQueueFlags & QS_MOUSE)
  489. {
  490. WaitRemoveMessage(WM_MOUSEMOVE, WM_MOUSEMOVE, 0);
  491. WaitRemoveMessage(WM_NCMOUSEFIRST, WM_NCMOUSELAST, 0);
  492. WaitRemoveMessage(WM_QUEUESYNC, WM_QUEUESYNC, 0);
  493. }
  494. if (dwQueueFlags & QS_POSTMESSAGE)
  495. {
  496. WaitRemoveMessage(WM_DDE_FIRST, WM_DDE_LAST, WRM_DISPATCH);
  497. WaitRemoveMessage(g_msgThreadMarshal,
  498. g_msgThreadMarshal,
  499. WRM_MARSHALWNDDISPATCH);
  500. WaitRemoveMessage(g_msgCheckThreadInputIdel,
  501. g_msgCheckThreadInputIdel,
  502. WRM_MARSHALWNDDISPATCH);
  503. #ifdef POINTER_MARSHAL
  504. WaitRemoveMessage(g_msgPointerMarshal,
  505. g_msgPointerMarshal,
  506. WRM_MARSHALWNDDISPATCH);
  507. #endif
  508. #ifdef DEBUG
  509. TCHAR _szModule[MAX_PATH];
  510. ::GetModuleFileName(NULL, _szModule, sizeof(_szModule)/sizeof(TCHAR));
  511. TraceMsg(TF_EVENT, "%s CModalLoop::WaitHandleWndMessage:: MSUIM.Msg.RpcSendReceive", _szModule);
  512. #endif
  513. WaitRemoveMessage(g_msgRpcSendReceive,
  514. g_msgRpcSendReceive,
  515. WRM_MARSHALWNDDISPATCH);
  516. // WaitRemoveMessage(g_msgPrivate, g_msgPrivate, WRM_DISPATCH);
  517. WaitRemoveMessage(g_msgPrivate, g_msgPrivate, 0);
  518. if (!_psfn->fInmsgSetFocus)
  519. WaitRemoveMessage(g_msgSetFocus, g_msgSetFocus, 0);
  520. if (!_psfn->fInmsgThreadItemChange)
  521. WaitRemoveMessage(g_msgThreadItemChange, g_msgThreadItemChange, 0);
  522. if (!_psfn->fInmsgThreadTerminate)
  523. WaitRemoveMessage(g_msgThreadTerminate, g_msgThreadTerminate, 0);
  524. WaitRemoveMessage(g_msgLBarModal, g_msgLBarModal, 0);
  525. WaitRemoveMessage(WM_USER, (UINT)(-1), WRM_OLEWINDOW | WRM_DISPATCH);
  526. }
  527. // Get rid of paint message if we can as well -- this makes
  528. // the screen look so much better.
  529. if (dwQueueFlags & QS_PAINT)
  530. {
  531. WaitRemoveMessage(WM_PAINT, WM_PAINT, WRM_DISPATCH);
  532. }
  533. }
  534. //--------------------------------------------------------------------------
  535. //
  536. // MyPeekMessage
  537. //
  538. //--------------------------------------------------------------------------
  539. BOOL CModalLoop::MyPeekMessage(MSG *pMsg, HWND hwnd, UINT min, UINT max, WORD wFlag)
  540. {
  541. BOOL fRet = PeekMessage(pMsg, hwnd, min, max, wFlag);
  542. while (fRet)
  543. {
  544. if (pMsg->message != WM_QUIT)
  545. {
  546. break;
  547. }
  548. _wQuitCode = (ULONG)(pMsg->wParam);
  549. _fQuitReceived = TRUE;
  550. if (!(wFlag & PM_REMOVE))
  551. {
  552. // quit message is still on queue so pull it off
  553. PeekMessage(pMsg, hwnd, WM_QUIT, WM_QUIT, PM_REMOVE | PM_NOYIELD);
  554. }
  555. // peek again to see if there is another message
  556. fRet = PeekMessage(pMsg, hwnd, min, max, wFlag);
  557. }
  558. return fRet;
  559. }
  560. //--------------------------------------------------------------------------
  561. //
  562. // WaitRemoveMessage
  563. //
  564. //--------------------------------------------------------------------------
  565. BOOL CModalLoop::WaitRemoveMessage(UINT uMsgFirst, UINT uMsgLast, DWORD dwFlags)
  566. {
  567. MSG msg;
  568. HWND hwnd = NULL;
  569. BOOL fRet = FALSE;
  570. if (dwFlags & WRM_MARSHALWND)
  571. {
  572. hwnd = _psfn->hwndMarshal;
  573. }
  574. if (dwFlags & WRM_OLEWINDOW)
  575. {
  576. hwnd = GetOleMainThreadWindow(_psfn);
  577. if (!hwnd)
  578. return FALSE;
  579. }
  580. while (MyPeekMessage(&msg, hwnd, uMsgFirst, uMsgLast,
  581. PM_REMOVE | PM_NOYIELD))
  582. {
  583. if (dwFlags & WRM_DISPATCH)
  584. DispatchMessage(&msg);
  585. fRet = TRUE;
  586. }
  587. return fRet;
  588. }
  589. //--------------------------------------------------------------------------
  590. //
  591. // BlockFn
  592. //
  593. //--------------------------------------------------------------------------
  594. HRESULT CModalLoop::BlockFn(CCicEvent *pevent, DWORD dwWaitingThreadId, DWORD &dwWaitFlags)
  595. {
  596. DWORD dwReason;
  597. HRESULT hr = S_FALSE;
  598. //
  599. // if the event is already set, we don't need to wait.
  600. //
  601. dwReason = pevent->EventCheck();
  602. if (dwReason == WAIT_OBJECT_0)
  603. return S_OK;
  604. if (dwReason == WAIT_TIMEOUT)
  605. {
  606. //
  607. // we just check the our target send marshaling message to
  608. // our thread. If so, just handle it.
  609. //
  610. DWORD dwStatus = GetQueueStatus(QS_POSTMESSAGE);
  611. WORD wNew = (WORD)dwStatus | HIWORD(dwStatus);
  612. if (wNew & QS_POSTMESSAGE)
  613. {
  614. //
  615. // handle ThreadMarshaling.
  616. //
  617. if (WaitRemoveMessage(g_msgThreadMarshal,
  618. g_msgThreadMarshal,
  619. WRM_MARSHALWNDDISPATCH))
  620. return S_FALSE;
  621. //
  622. // handle another rpc cal.
  623. //
  624. #ifdef DEBUG
  625. TCHAR _szModule[MAX_PATH];
  626. ::GetModuleFileName(NULL, _szModule, sizeof(_szModule)/sizeof(TCHAR));
  627. TraceMsg(TF_EVENT, "%s CModalLoop::BlockFn:: MSUIM.Msg.RpcSendReceive", _szModule);
  628. #endif
  629. if (WaitRemoveMessage(g_msgRpcSendReceive,
  630. g_msgRpcSendReceive,
  631. WRM_MARSHALWNDDISPATCH))
  632. return S_FALSE;
  633. }
  634. dwReason = pevent->MsgWait(500, dwWaitFlags);
  635. }
  636. if (dwReason == WAIT_OBJECT_0)
  637. {
  638. return S_OK;
  639. }
  640. else if (dwReason == WAIT_OBJECT_0 + 1)
  641. {
  642. //
  643. // now we handle only new messages.
  644. //
  645. DWORD dwStatus = GetQueueStatus(dwWaitFlags);
  646. WORD wNew = (WORD)dwStatus | HIWORD(dwStatus);
  647. WaitHandleWndMessages((DWORD)wNew);
  648. //
  649. // need to review this later.
  650. // we want to check the thread was terminated or not.
  651. //
  652. goto CheckThread;
  653. }
  654. else
  655. {
  656. //
  657. // Cic#4516
  658. //
  659. // The target thread seems to be busy. Check the current queue to
  660. // see if we have a message sent. The target thread may be in
  661. // SendMessage() and waiting for the reply of this thread.
  662. //
  663. //
  664. DWORD dwStatus = GetQueueStatus(QS_SENDMESSAGE);
  665. WORD wNew = HIWORD(dwStatus);
  666. if (wNew & QS_SENDMESSAGE)
  667. {
  668. MSG msg;
  669. //
  670. // Maybe PeekMessage is better than ReplyMessage().
  671. //
  672. PeekMessage(&msg, NULL, 0, 0,
  673. ((IsOnNT5() || IsOn98()) ? PM_QS_SENDMESSAGE : 0) | PM_NOREMOVE);
  674. }
  675. CheckThread:
  676. if (!g_timlist.IsThreadId(dwWaitingThreadId))
  677. {
  678. TraceMsg(TF_EVENT, "CProxy::SendReceive No Thread");
  679. hr = MAKE_WIN32(RPC_S_SERVER_UNAVAILABLE);
  680. goto Exit;
  681. }
  682. }
  683. Exit:
  684. return hr;
  685. }
  686. //+---------------------------------------------------------------------------
  687. //
  688. // FreeStubs
  689. //
  690. //+---------------------------------------------------------------------------
  691. void FreeMarshaledStubs(SYSTHREAD *psfn)
  692. {
  693. if (psfn->prgStub)
  694. {
  695. int nCnt = psfn->prgStub->Count();
  696. int i = 0;
  697. for (i = 0; i < nCnt; i++)
  698. {
  699. CStub *pStub = psfn->prgStub->Get(i);
  700. pStub->_fNoRemoveInDtor = TRUE;
  701. delete pStub;
  702. }
  703. psfn->prgStub->Clear();
  704. delete psfn->prgStub;
  705. psfn->prgStub = NULL;
  706. }
  707. }
  708. //+---------------------------------------------------------------------------
  709. //
  710. // FreeStubsForThread
  711. //
  712. //+---------------------------------------------------------------------------
  713. void FreeMarshaledStubsForThread(SYSTHREAD *psfn, DWORD dwThread)
  714. {
  715. if (psfn->prgStub)
  716. {
  717. int nCnt = psfn->prgStub->Count();
  718. int i = 0;
  719. for (i = nCnt; i > 0; i--)
  720. {
  721. CStub *pStub = psfn->prgStub->Get(i - 1);
  722. if (!pStub)
  723. continue;
  724. if (pStub->_dwSrcThreadId == dwThread)
  725. delete pStub;
  726. }
  727. }
  728. }
  729. //--------------------------------------------------------------------------
  730. //
  731. // StubCleanUp
  732. //
  733. //--------------------------------------------------------------------------
  734. void StubCleanUp(DWORD dwStubTime, ULONG ulStubId)
  735. {
  736. SYSTHREAD *psfn = GetSYSTHREAD();
  737. CStub *pStub;
  738. int nRemove;
  739. if (psfn == NULL)
  740. return;
  741. // Assert(psfn->prgStub);
  742. if (!psfn->prgStub)
  743. return;
  744. dbg_CheckStubIds(psfn);
  745. nRemove = FindStub(psfn->prgStub, ulStubId);
  746. if (nRemove == -1)
  747. return;
  748. pStub = psfn->prgStub->Get(nRemove);
  749. //
  750. // check stub created time.
  751. //
  752. // Requested Stub ID seems to be destroyed long time ago and
  753. // newer stub is using same ID.
  754. //
  755. if (pStub->_dwStubTime != dwStubTime)
  756. return;
  757. psfn->prgStub->Remove(nRemove, 1);
  758. delete pStub;
  759. }
  760. //+---------------------------------------------------------------------------
  761. //
  762. // CicMarshalWndProc
  763. //
  764. //+---------------------------------------------------------------------------
  765. LRESULT CALLBACK CicMarshalWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  766. {
  767. SYSTHREAD *psfn;
  768. if (uMsg == WM_DESTROY)
  769. {
  770. g_timlist.SetMarshalWnd(GetCurrentThreadId(), NULL);
  771. if (psfn = GetSYSTHREAD())
  772. {
  773. Assert(!psfn->hwndMarshal || (psfn->hwndMarshal == hWnd));
  774. psfn->hwndMarshal = NULL;
  775. //
  776. // #507248
  777. //
  778. // need to reset the dirty flag.
  779. //
  780. if (psfn->plbim)
  781. psfn->plbim->ResetDirtyUpdate();
  782. }
  783. }
  784. else if ((uMsg == WM_CLOSE) || (uMsg == WM_QUERYENDSESSION))
  785. {
  786. if (psfn = GetSYSTHREAD())
  787. {
  788. Assert(!psfn->hwndMarshal || (psfn->hwndMarshal == hWnd));
  789. DestroyWindow(hWnd);
  790. psfn->hwndMarshal = NULL;
  791. }
  792. }
  793. else if (uMsg == g_msgNuiMgrDirtyUpdate)
  794. {
  795. goto CallOnUpdateHandler;
  796. }
  797. else if (uMsg == WM_TIMER)
  798. {
  799. if (wParam == MARSHALWND_TIMER_UPDATEKANACAPS)
  800. {
  801. KillTimer(hWnd, MARSHALWND_TIMER_UPDATEKANACAPS);
  802. if (psfn = GetSYSTHREAD())
  803. {
  804. KanaCapsUpdate(psfn);
  805. }
  806. }
  807. else if (wParam == MARSHALWND_TIMER_NUIMGRDIRTYUPDATE)
  808. {
  809. KillTimer(hWnd, MARSHALWND_TIMER_NUIMGRDIRTYUPDATE);
  810. CallOnUpdateHandler:
  811. if (IsCTFMONBusy() || IsInPopupMenuMode())
  812. {
  813. TryOnUpdatehandlerAgain:
  814. SetTimer(hWnd, MARSHALWND_TIMER_NUIMGRDIRTYUPDATE, 100, NULL);
  815. }
  816. else
  817. {
  818. if (psfn = GetSYSTHREAD())
  819. {
  820. if (psfn->plbim)
  821. {
  822. if (psfn->plbim->IsInOnUpdateHandler())
  823. goto TryOnUpdatehandlerAgain;
  824. psfn->plbim->OnUpdateHandler();
  825. }
  826. }
  827. }
  828. }
  829. else if (wParam == MARSHALWND_TIMER_WAITFORINPUTIDLEFORSETFOCUS)
  830. {
  831. KillTimer(hWnd, MARSHALWND_TIMER_WAITFORINPUTIDLEFORSETFOCUS);
  832. PostThreadMessage(GetCurrentThreadId(), g_msgSetFocus, 0, 0);
  833. }
  834. }
  835. else if (uMsg == g_msgRpcSendReceive)
  836. {
  837. HandleSendReceiveMsg((ULONG)wParam, (ULONG)lParam);
  838. }
  839. #ifdef POINTER_MARSHAL
  840. else if (uMsg == g_msgPointerMarshal)
  841. {
  842. switch (LOWORD(wParam))
  843. {
  844. case MP_MARSHALINTERFACE:
  845. PointerMarshalInterfaceHandler(lParam);
  846. break;
  847. case MP_UNMARSHALINTERFACEERROR:
  848. PointerUnMarshalInterfaceErrorHandler(lParam);
  849. break;
  850. }
  851. }
  852. #endif
  853. else if (uMsg == g_msgThreadMarshal)
  854. {
  855. switch (LOWORD(wParam))
  856. {
  857. case MP_MARSHALINTERFACE:
  858. ThreadMarshalInterfaceHandler((int)lParam);
  859. break;
  860. case MP_UNMARSHALINTERFACEERROR:
  861. ThreadUnMarshalInterfaceErrorHandler((int)lParam);
  862. break;
  863. }
  864. }
  865. else if (uMsg == g_msgStubCleanUp)
  866. {
  867. StubCleanUp((DWORD)wParam, (ULONG)lParam);
  868. }
  869. else if (uMsg == g_msgCheckThreadInputIdel)
  870. {
  871. DWORD dwThreadId = GetCurrentThreadId();
  872. CCheckThreadInputIdle event(dwThreadId, (DWORD)lParam);
  873. if (event.Open())
  874. event.Set();
  875. }
  876. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  877. }
  878. ATOM g_atomMarshalClass = 0;
  879. //+---------------------------------------------------------------------------
  880. //
  881. // EnsureMarshalWnd
  882. //
  883. //+---------------------------------------------------------------------------
  884. HWND EnsureMarshalWnd()
  885. {
  886. SYSTHREAD *psfn;
  887. if ((psfn = GetSYSTHREAD()) == NULL)
  888. return NULL;
  889. if (!EnsureTIMList(psfn))
  890. return NULL;
  891. if (IsWindow(psfn->hwndMarshal))
  892. {
  893. if (psfn->hwndMarshal != g_timlist.GetMarshalWnd(psfn->dwThreadId))
  894. {
  895. g_timlist.SetMarshalWnd(psfn->dwThreadId, psfn->hwndMarshal);
  896. }
  897. return psfn->hwndMarshal;
  898. }
  899. //
  900. // we can not support marshaling after process detach.
  901. //
  902. if (g_fDllProcessDetached)
  903. return NULL;
  904. //
  905. // Win98 has a bug in FindWindow() with HWND_MESSAGE, so we need to have
  906. // unique windiw text for each thread.
  907. //
  908. char sz[MAX_PATH];
  909. if (!SetName(sz, ARRAYSIZE(sz), c_szCicMarshalWnd, GetCurrentThreadId()))
  910. return NULL;
  911. //
  912. // We want to hide this window from EnumWindow() API.
  913. // So we use HWND_MESSAGE for Win98 and NT5.
  914. //
  915. // For Beta.
  916. //
  917. // Under NT4, we destroy every time the popup window is destroyed in
  918. // WndProcHook. However we should
  919. //
  920. psfn->hwndMarshal = CreateWindowEx(0,
  921. c_szCicMarshalClass,
  922. sz,
  923. WS_DISABLED | WS_POPUP,
  924. 0,
  925. 0,
  926. 0,
  927. 0,
  928. IsOn98orNT5() ? HWND_MESSAGE : NULL,
  929. 0,
  930. g_hInst,
  931. 0);
  932. g_timlist.SetMarshalWnd(psfn->dwThreadId, psfn->hwndMarshal);
  933. Assert(psfn->hwndMarshal);
  934. return psfn->hwndMarshal;
  935. }
  936. //+---------------------------------------------------------------------------
  937. //
  938. // RegisterMarshalWndClass
  939. //
  940. //+---------------------------------------------------------------------------
  941. void RegisterMarshalWndClass()
  942. {
  943. WNDCLASSEX wndclass;
  944. memset(&wndclass, 0, sizeof(wndclass));
  945. wndclass.cbSize = sizeof(wndclass);
  946. wndclass.style = CS_HREDRAW | CS_VREDRAW ;
  947. wndclass.hInstance = g_hInst;
  948. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  949. wndclass.lpfnWndProc = CicMarshalWndProc;
  950. wndclass.lpszClassName = c_szCicMarshalClass;
  951. g_atomMarshalClass = RegisterClassEx(&wndclass);
  952. }
  953. //////////////////////////////////////////////////////////////////////////////
  954. //
  955. // CThreadMarshalWnd
  956. //
  957. //////////////////////////////////////////////////////////////////////////////
  958. //--------------------------------------------------------------------------
  959. //
  960. // ctor
  961. //
  962. //--------------------------------------------------------------------------
  963. CThreadMarshalWnd::CThreadMarshalWnd()
  964. {
  965. _dwThreadId = 0;
  966. _hwnd = 0;
  967. }
  968. //--------------------------------------------------------------------------
  969. //
  970. // dtor
  971. //
  972. //--------------------------------------------------------------------------
  973. CThreadMarshalWnd::~CThreadMarshalWnd()
  974. {
  975. }
  976. //--------------------------------------------------------------------------
  977. //
  978. // Init
  979. //
  980. //--------------------------------------------------------------------------
  981. BOOL CThreadMarshalWnd::Init(DWORD dwThreadId)
  982. {
  983. HWND hwndTemp = NULL;
  984. _dwThreadId = dwThreadId;
  985. //
  986. // clear _hwnd out first.
  987. //
  988. _hwnd = NULL;
  989. if (hwndTemp = GetThreadMarshalWnd(dwThreadId))
  990. {
  991. if (GetWindowThreadProcessId(hwndTemp, NULL) == dwThreadId)
  992. {
  993. _hwnd = hwndTemp;
  994. }
  995. }
  996. return _hwnd ? TRUE : FALSE;
  997. }
  998. //+---------------------------------------------------------------------------
  999. //
  1000. // PostMarshalThreadMessage
  1001. //
  1002. //+---------------------------------------------------------------------------
  1003. BOOL CThreadMarshalWnd::PostMarshalThreadMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1004. {
  1005. Assert(g_atomMarshalClass);
  1006. if (!_hwnd || !IsWindow())
  1007. {
  1008. //
  1009. // Was the window destroyed?
  1010. //
  1011. TraceMsg(TF_GENERAL, "CThreadmarshalWnd::PostMarshalThreadMessage marshal window could not be found");
  1012. return FALSE;
  1013. }
  1014. #ifdef DEBUG
  1015. TCHAR _szModule[MAX_PATH];
  1016. ::GetModuleFileName(NULL, _szModule, sizeof(_szModule)/sizeof(TCHAR));
  1017. TraceMsg(TF_EVENT, "%s CThreadMarshalWnd::PostMarshalThreadMessage hWnd - %x uMsg - %x wParam - %x lParam - %x", _szModule, _hwnd, uMsg, wParam, lParam);
  1018. #endif
  1019. return PostMessage(_hwnd, uMsg, wParam, lParam);
  1020. }
  1021. //--------------------------------------------------------------------------
  1022. //
  1023. // DestroyAll
  1024. //
  1025. //--------------------------------------------------------------------------
  1026. BOOL CThreadMarshalWnd::DestroyAll()
  1027. {
  1028. ULONG ulNum;
  1029. SYSTHREAD *psfn = GetSYSTHREAD();
  1030. if (!psfn)
  1031. return FALSE;
  1032. EnsureTIMList(psfn);
  1033. ulNum = g_timlist.GetNum();
  1034. if (ulNum)
  1035. {
  1036. DWORD *pdw = new DWORD[ulNum + 1];
  1037. if (pdw)
  1038. {
  1039. if (g_timlist.GetList(pdw, ulNum+1, &ulNum, 0, 0, FALSE))
  1040. {
  1041. ULONG ul;
  1042. for (ul = 0; ul < ulNum; ul++)
  1043. {
  1044. if (pdw[ul])
  1045. DestroyThreadMarshalWnd(pdw[ul]);
  1046. }
  1047. }
  1048. delete [] pdw;
  1049. }
  1050. }
  1051. return TRUE;
  1052. }
  1053. //+---------------------------------------------------------------------------
  1054. //
  1055. // DestroyThreadMarshalWnd
  1056. //
  1057. //+---------------------------------------------------------------------------
  1058. BOOL CThreadMarshalWnd::DestroyThreadMarshalWnd(DWORD dwThread)
  1059. {
  1060. HWND hwndTemp;
  1061. if (hwndTemp = GetThreadMarshalWnd(dwThread))
  1062. {
  1063. //
  1064. // #425375.
  1065. //
  1066. // SendMessageTimeout() makes shut-down slower.
  1067. // instead, we use SendNotifyMessage() and this is safer since
  1068. // the queue of the thread does not miss WM_CLOSE message for the
  1069. // window.
  1070. //
  1071. SendNotifyMessage(hwndTemp, WM_CLOSE, 0, 0);
  1072. }
  1073. return TRUE;
  1074. }
  1075. //+---------------------------------------------------------------------------
  1076. //
  1077. // ClearMarshalWndProc
  1078. //
  1079. //+---------------------------------------------------------------------------
  1080. void CThreadMarshalWnd::ClearMarshalWndProc(DWORD dwProcessId)
  1081. {
  1082. ULONG ulNum;
  1083. if (!g_timlist.IsInitialized())
  1084. return;
  1085. ulNum = g_timlist.GetNum();
  1086. //
  1087. // MSCTF.DLL will be unloaded so we may need to make all existing marshal
  1088. // windows in the current process a ghost. We wanted to destroy them
  1089. // but we missed a chance to destroy them.
  1090. //
  1091. // It may be ok to call DestroyWindow() in process detach since
  1092. // it is known window. But making them a ghost seems to be safer.
  1093. //
  1094. if (ulNum)
  1095. {
  1096. DWORD *pdw = new DWORD[ulNum + 1];
  1097. if (pdw)
  1098. {
  1099. if (g_timlist.GetListInProcess(pdw, &ulNum, dwProcessId))
  1100. {
  1101. ULONG ul;
  1102. for (ul = 0; ul < ulNum; ul++)
  1103. {
  1104. if (pdw[ul])
  1105. {
  1106. HWND hwnd = GetThreadMarshalWnd(pdw[ul]);
  1107. if (hwnd)
  1108. {
  1109. SetWindowLongPtr(hwnd,
  1110. GWLP_WNDPROC,
  1111. (LONG_PTR)DefWindowProc);
  1112. }
  1113. }
  1114. }
  1115. }
  1116. delete [] pdw;
  1117. }
  1118. }
  1119. }
  1120. //+---------------------------------------------------------------------------
  1121. //
  1122. // GetThreadMarshalWnd
  1123. //
  1124. //+---------------------------------------------------------------------------
  1125. HWND CThreadMarshalWnd::GetThreadMarshalWnd(DWORD dwThread)
  1126. {
  1127. HWND hwnd = g_timlist.GetMarshalWnd(dwThread);
  1128. if (::IsWindow(hwnd))
  1129. {
  1130. if (dwThread == GetWindowThreadProcessId(hwnd, NULL))
  1131. {
  1132. ATOM atomClass = (ATOM)GetClassLongPtr(hwnd, GCW_ATOM);
  1133. if (g_atomMarshalClass == atomClass)
  1134. return hwnd;
  1135. }
  1136. g_timlist.SetMarshalWnd(dwThread, NULL);
  1137. }
  1138. return NULL;
  1139. }
  1140. //+---------------------------------------------------------------------------
  1141. //
  1142. // EnumThreadWndProc
  1143. //
  1144. //+---------------------------------------------------------------------------
  1145. BOOL CThreadMarshalWnd::EnumThreadWndProc(HWND hwnd, LPARAM lParam)
  1146. {
  1147. *(BOOL *)lParam = TRUE;
  1148. return FALSE;
  1149. }
  1150. //+---------------------------------------------------------------------------
  1151. //
  1152. // IsThreadWindow
  1153. //
  1154. //+---------------------------------------------------------------------------
  1155. BOOL CThreadMarshalWnd::IsThreadWindow()
  1156. {
  1157. BOOL fFound = FALSE;
  1158. EnumThreadWindows(_dwThreadId,
  1159. EnumThreadWndProc,
  1160. (LPARAM)&fFound);
  1161. return fFound;
  1162. }
  1163. //////////////////////////////////////////////////////////////////////////////
  1164. //
  1165. // CProxy
  1166. //
  1167. //////////////////////////////////////////////////////////////////////////////
  1168. //--------------------------------------------------------------------------
  1169. //
  1170. // ctor
  1171. //
  1172. //--------------------------------------------------------------------------
  1173. CProxy::CProxy(SYSTHREAD *psfn) : CSysThreadRef(psfn)
  1174. {
  1175. _ulProxyId = 0;
  1176. _ulStubId = (ULONG)(-1);
  1177. _dwStubThreadId = 0;
  1178. _dwSrcThreadId = 0;
  1179. _dwSrcProcessId = 0;
  1180. _cRef = 1;
  1181. #ifdef DEBUG
  1182. _fInLoop = FALSE;
  1183. #endif
  1184. }
  1185. //--------------------------------------------------------------------------
  1186. //
  1187. // dtor
  1188. //
  1189. //--------------------------------------------------------------------------
  1190. CProxy::~CProxy()
  1191. {
  1192. #ifdef DEBUG
  1193. Assert(!_fInLoop);
  1194. #endif
  1195. if (g_timlist.IsThreadId(_dwStubThreadId))
  1196. _tmw.PostMarshalThreadMessage(g_msgStubCleanUp, _dwStubTime, _ulStubId);
  1197. }
  1198. ULONG CProxy::InternalAddRef()
  1199. {
  1200. _cRef++;
  1201. return _cRef;
  1202. }
  1203. ULONG CProxy::InternalRelease()
  1204. {
  1205. _cRef--;
  1206. if (!_cRef)
  1207. {
  1208. delete this;
  1209. return 0;
  1210. }
  1211. return _cRef;
  1212. }
  1213. //--------------------------------------------------------------------------
  1214. //
  1215. // Init
  1216. //
  1217. //--------------------------------------------------------------------------
  1218. void CProxy::Init(REFIID riid, ULONG ulProxyId, ULONG ulStubId, DWORD dwStubTime, DWORD dwStubThreadId, DWORD dwCurThreadId, DWORD dwCurProcessId)
  1219. {
  1220. _iid = riid;
  1221. _ulProxyId = ulProxyId;
  1222. _ulStubId = ulStubId;
  1223. _dwStubTime = dwStubTime;
  1224. _dwStubThreadId = dwStubThreadId;
  1225. _dwSrcThreadId = dwCurThreadId;
  1226. _dwSrcProcessId = dwCurProcessId;
  1227. _tmw.Init(_dwStubThreadId);
  1228. }
  1229. //--------------------------------------------------------------------------
  1230. //
  1231. // SendReceive
  1232. //
  1233. //--------------------------------------------------------------------------
  1234. HRESULT CProxy::SendReceive(MARSHALMSG *pMsg, ULONG ulBlockId)
  1235. {
  1236. HRESULT hr = E_FAIL;
  1237. CCicTimer timer(MARSHALTIMEOUT, FALSE);
  1238. DWORD dwWaitFlags;
  1239. DWORD dwThreadId = _dwStubThreadId;
  1240. CModalLoop modalloop(_psfn);
  1241. DWORD dwSrcThreadId;
  1242. TL_THREADINFO *pti;
  1243. DWORD dwPrevWaitingThread;
  1244. CCicSecAttr sa;
  1245. #ifdef DEBUG
  1246. TCHAR _szModule[MAX_PATH];
  1247. ::GetModuleFileName(NULL, _szModule, sizeof(_szModule)/sizeof(TCHAR));
  1248. TraceMsg(TF_EVENT, "%s CProxy::SendReceive Start _ThreadId - %x _uStubId - %x, msg size - %x", _szModule, _dwStubThreadId, _ulStubId, pMsg->cbSize);
  1249. #endif
  1250. pti = g_timlist.IsThreadId(_dwStubThreadId);
  1251. if (!pti)
  1252. {
  1253. TraceMsg(TF_EVENT, "CProxy::SendReceive Invalid ThreadId %x", _dwStubThreadId);
  1254. return E_FAIL;
  1255. }
  1256. Assert(pti->dwThreadId == _dwStubThreadId);
  1257. if (pti->dwFlags & TLF_INSFW)
  1258. {
  1259. TraceMsg(TF_EVENT, "CProxy::SendReceive Thread is in SetForegroundWindow %08x", _dwStubThreadId);
  1260. return E_FAIL;
  1261. }
  1262. //
  1263. // for Win9x, we can identify the event and shared block by ulBlockId.
  1264. //
  1265. if (IsOnNT())
  1266. dwSrcThreadId = pMsg->dwSrcThreadId;
  1267. else
  1268. dwSrcThreadId = WIN9X_SRCTHREADID;
  1269. //
  1270. // Event for marshaling
  1271. //
  1272. CSendReceiveEvent event(dwSrcThreadId, ulBlockId);
  1273. if (!event.Create(sa))
  1274. return E_FAIL;
  1275. CSendReceiveConnectionEvent eventc(dwSrcThreadId, ulBlockId);
  1276. BOOL fSendReceiveConnection = FALSE;
  1277. if (!eventc.Create(sa))
  1278. return E_FAIL;
  1279. // Win98 QS_EVENT hack.
  1280. // Win98's Event QueueItem could cause inter thread sendmessage
  1281. // We want to clean up Event QueueItem before Marshaling happens.
  1282. //
  1283. // because CTFMON.EXE may call AttatchThreadInput() and this event
  1284. // could be handled in CTFMON's thread and this make the event queue item
  1285. // to do inter thread SendMessage.
  1286. //
  1287. if (!IsOnNT())
  1288. {
  1289. MSG msg;
  1290. PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD);
  1291. }
  1292. //
  1293. // save previous waiting thread.
  1294. //
  1295. if (_psfn->pti)
  1296. {
  1297. dwPrevWaitingThread = _psfn->pti->dwMarshalWaitingThread;
  1298. _psfn->pti->dwMarshalWaitingThread = _dwStubThreadId;
  1299. }
  1300. //
  1301. // update marshal window handle from PTI.
  1302. // the window handle in _tmw may be destroyed on NT4.
  1303. //
  1304. _tmw.SetMarshalWindow(pti->hwndMarshal);
  1305. if (!_tmw.PostMarshalThreadMessage(g_msgRpcSendReceive,
  1306. dwSrcThreadId,
  1307. ulBlockId))
  1308. {
  1309. TraceMsg(TF_EVENT, "CProxy::SendReceive PostThreadMessage failed");
  1310. goto Exit;
  1311. }
  1312. #ifdef DEBUG
  1313. _fInLoop = TRUE;
  1314. #endif
  1315. timer.Start();
  1316. dwWaitFlags = QS_DEFAULTWAITFLAG;
  1317. while (!timer.IsTimerAtZero())
  1318. {
  1319. if (!fSendReceiveConnection &&
  1320. timer.IsTimerPass(DEFAULTMARSHALCONNECTIONTIMEOUT))
  1321. {
  1322. DWORD dwReason = eventc.EventCheck();
  1323. if (dwReason != WAIT_OBJECT_0)
  1324. {
  1325. hr = E_FAIL;
  1326. break;
  1327. }
  1328. fSendReceiveConnection = TRUE;
  1329. }
  1330. hr = modalloop.BlockFn(&event, dwThreadId, dwWaitFlags);
  1331. if (hr == S_OK)
  1332. goto EventOK;
  1333. if (FAILED(hr))
  1334. break;
  1335. if (!_tmw.IsWindow())
  1336. {
  1337. hr = E_FAIL;
  1338. break;
  1339. }
  1340. if (!_tmw.IsThreadWindow())
  1341. {
  1342. CThreadMarshalWnd::DestroyThreadMarshalWnd(_dwStubThreadId);
  1343. hr = E_FAIL;
  1344. break;
  1345. }
  1346. }
  1347. #ifdef DEBUG
  1348. TraceMsg(TF_EVENT, "%s CProxy::SendReceive Time Out", _szModule);
  1349. #endif
  1350. goto Exit;
  1351. EventOK:
  1352. #ifdef DEBUG
  1353. TraceMsg(TF_EVENT, "%s CProxy::SendReceive OK", _szModule);
  1354. #endif
  1355. hr = S_OK;
  1356. Exit:
  1357. #ifdef DEBUG
  1358. _fInLoop = FALSE;
  1359. #endif
  1360. //
  1361. // restore previous waiting thread.
  1362. //
  1363. if (_psfn->pti)
  1364. _psfn->pti->dwMarshalWaitingThread = dwPrevWaitingThread;
  1365. return hr;
  1366. }
  1367. //--------------------------------------------------------------------------
  1368. //
  1369. // proxy_Param
  1370. //
  1371. //--------------------------------------------------------------------------
  1372. HRESULT CProxy::proxy_Param(ULONG ulMethodId, ULONG ulParamNum, CPROXY_PARAM *pProxyParam)
  1373. {
  1374. HRESULT hr = E_FAIL;
  1375. ULONG i;
  1376. MARSHALMSG *pMsgMap = NULL;
  1377. ULONG cbBufSize;
  1378. CMarshalParamCreator cparam;
  1379. ULONG ulBlockId;
  1380. HRESULT hrMarshalOutParam = S_OK;
  1381. ULONG cbPadMemSize = 0;
  1382. CSharedHeap *psheap = EnsureSharedHeap(_psfn);
  1383. if (!psheap)
  1384. return hr;
  1385. InternalAddRef();
  1386. TryAgain:
  1387. cbBufSize = sizeof(MARSHALMSG) + ulParamNum * sizeof(MARSHALPARAM);
  1388. LENGTH_ALIGN(cbBufSize, CIC_ALIGNMENT);
  1389. cbBufSize += cbPadMemSize;
  1390. LENGTH_ALIGN(cbBufSize, CIC_ALIGNMENT);
  1391. for (i = 0; i < ulParamNum; i++)
  1392. {
  1393. ULONG cbUnitSize = sizeof(ULONG_PTR);
  1394. LENGTH_ALIGN(cbUnitSize, CIC_ALIGNMENT);
  1395. if (pProxyParam[i].dwFlags & MPARAM_INTERFACE)
  1396. cbUnitSize += sizeof(MARSHALINTERFACEPARAM);
  1397. else if (pProxyParam[i].dwFlags & MPARAM_HICON)
  1398. {
  1399. if (!(pProxyParam[i].dwFlags & MPARAM_IN))
  1400. {
  1401. cbUnitSize += 0x2000;
  1402. }
  1403. else
  1404. {
  1405. Assert(pProxyParam[i].ulCount == 1);
  1406. HICON *picon = (HICON *)pProxyParam[i].pv;
  1407. cbUnitSize += Cic_HICON_UserSize(picon);
  1408. }
  1409. }
  1410. else if (pProxyParam[i].dwFlags & MPARAM_HBITMAP)
  1411. {
  1412. if (!(pProxyParam[i].dwFlags & MPARAM_IN))
  1413. {
  1414. cbUnitSize += 0x1000;
  1415. }
  1416. else
  1417. {
  1418. Assert(pProxyParam[i].ulCount == 1);
  1419. HBITMAP *pbmp = (HBITMAP *)pProxyParam[i].pv;
  1420. cbUnitSize += Cic_HBITMAP_UserSize(pbmp);
  1421. }
  1422. }
  1423. else if (pProxyParam[i].dwFlags & MPARAM_BSTR)
  1424. cbUnitSize += 0x1000;
  1425. // else if (pProxyParam[i].dwFlags & MPARAM_POINTER)
  1426. // cbUnitSize += 0x1000;
  1427. else if (pProxyParam[i].dwFlags & MPARAM_TF_LBBALLOONINFO)
  1428. cbUnitSize += 0x1000;
  1429. else
  1430. cbUnitSize += pProxyParam[i].cbUnitSize;
  1431. LENGTH_ALIGN(cbUnitSize, CIC_ALIGNMENT);
  1432. cbBufSize += (cbUnitSize * pProxyParam[i].ulCount);
  1433. LENGTH_ALIGN(cbBufSize, CIC_ALIGNMENT);
  1434. }
  1435. if (!psheap->GetBlock()->GetMutex()->Enter())
  1436. {
  1437. hr = E_FAIL;
  1438. goto Exit;
  1439. }
  1440. pMsgMap = (MARSHALMSG *)psheap->Alloc(cbBufSize);
  1441. if (!pMsgMap)
  1442. {
  1443. hr = E_OUTOFMEMORY;
  1444. goto FinishParamCreation;
  1445. }
  1446. ulBlockId = psheap->GetBlockId(pMsgMap);
  1447. cparam.Set(pMsgMap, cbBufSize);
  1448. cparam.Init(_dwSrcThreadId,
  1449. _dwSrcProcessId,
  1450. _iid,
  1451. ulMethodId,
  1452. ulParamNum,
  1453. _ulStubId,
  1454. _dwStubTime);
  1455. hr = S_OK;
  1456. for (i = 0; i < ulParamNum; i++)
  1457. {
  1458. if (!(pProxyParam[i].dwFlags & MPARAM_IN))
  1459. {
  1460. hr = cparam.Add(pProxyParam[i].GetBufSize(),
  1461. pProxyParam[i].dwFlags,
  1462. NULL);
  1463. if (FAILED(hr))
  1464. goto FinishParamCreation;
  1465. continue;
  1466. }
  1467. if (pProxyParam[i].dwFlags & MPARAM_INTERFACE)
  1468. {
  1469. if (pProxyParam[i].ulCount == 1)
  1470. {
  1471. MARSHALINTERFACEPARAM miparam;
  1472. if ((IUnknown **)pProxyParam[i].pv &&
  1473. (*(IUnknown **)pProxyParam[i].pv))
  1474. {
  1475. CicCoMarshalInterface(*pProxyParam[i].piid,
  1476. *(IUnknown **)pProxyParam[i].pv,
  1477. &miparam.ulStubId,
  1478. &miparam.dwStubTime,
  1479. _dwStubThreadId);
  1480. miparam.fNULLPointer = FALSE;
  1481. miparam.fNULLStack = FALSE;
  1482. }
  1483. else
  1484. {
  1485. miparam.ulStubId = 0;
  1486. miparam.fNULLPointer = TRUE;
  1487. if (!(IUnknown **)pProxyParam[i].pv)
  1488. miparam.fNULLStack = TRUE;
  1489. else
  1490. miparam.fNULLStack = FALSE;
  1491. }
  1492. hr = cparam.Add(sizeof(miparam),
  1493. pProxyParam[i].dwFlags,
  1494. &miparam);
  1495. }
  1496. else
  1497. {
  1498. MARSHALINTERFACEPARAM *pmiparam;
  1499. pmiparam = new MARSHALINTERFACEPARAM[pProxyParam[i].ulCount];
  1500. if (pmiparam)
  1501. {
  1502. ULONG ul;
  1503. for (ul = 0; ul < pProxyParam[i].ulCount; ul++)
  1504. {
  1505. IUnknown **ppunk = (IUnknown **)pProxyParam[i].pv;
  1506. if (ppunk && ppunk[ul])
  1507. {
  1508. CicCoMarshalInterface(*pProxyParam[i].piid,
  1509. ppunk[ul],
  1510. &pmiparam[ul].ulStubId,
  1511. &pmiparam[ul].dwStubTime,
  1512. _dwStubThreadId);
  1513. pmiparam[ul].fNULLPointer = FALSE;
  1514. pmiparam[ul].fNULLStack = FALSE;
  1515. }
  1516. else
  1517. {
  1518. pmiparam[ul].ulStubId = 0;
  1519. pmiparam[ul].fNULLPointer = TRUE;
  1520. if (!ppunk)
  1521. pmiparam[ul].fNULLStack = TRUE;
  1522. else
  1523. pmiparam[ul].fNULLStack = FALSE;
  1524. }
  1525. }
  1526. hr = cparam.Add(sizeof(*pmiparam) * pProxyParam[i].ulCount,
  1527. pProxyParam[i].dwFlags,
  1528. pmiparam);
  1529. delete [] pmiparam;
  1530. }
  1531. }
  1532. }
  1533. else if (pProxyParam[i].dwFlags & MPARAM_POINTER)
  1534. {
  1535. hr = cparam.Add(pProxyParam[i].GetBufSize(),
  1536. pProxyParam[i].dwFlags,
  1537. pProxyParam[i].pv);
  1538. }
  1539. else if (pProxyParam[i].dwFlags & MPARAM_ULONG)
  1540. {
  1541. Assert(pProxyParam[i].ulCount == 1);
  1542. hr = cparam.Add(pProxyParam[i].cbUnitSize,
  1543. pProxyParam[i].dwFlags,
  1544. &pProxyParam[i].ul);
  1545. }
  1546. else if (pProxyParam[i].dwFlags & MPARAM_BSTR)
  1547. {
  1548. Assert(pProxyParam[i].ulCount == 1);
  1549. hr = cparam.Add(pProxyParam[i].cbUnitSize,
  1550. pProxyParam[i].dwFlags,
  1551. pProxyParam[i].pv);
  1552. }
  1553. else if (pProxyParam[i].dwFlags & MPARAM_STRUCT)
  1554. {
  1555. hr = cparam.Add(pProxyParam[i].GetBufSize(),
  1556. pProxyParam[i].dwFlags,
  1557. pProxyParam[i].pv);
  1558. }
  1559. else if (pProxyParam[i].dwFlags & MPARAM_HICON)
  1560. {
  1561. Assert(pProxyParam[i].ulCount == 1);
  1562. HICON *picon = (HICON *)pProxyParam[i].pv;
  1563. ULONG cbSize = Cic_HICON_UserSize(picon);
  1564. BYTE *pBufOrg = NULL;
  1565. BYTE *pBuf = NULL;
  1566. BYTE *pBufEnd = NULL;
  1567. if (cbSize)
  1568. {
  1569. pBufOrg = (BYTE *)cicMemAlloc(cbSize + CIC_ALIGNMENT + 1);
  1570. pBuf = pBufOrg;
  1571. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  1572. pBufEnd = pBuf + cbSize;
  1573. }
  1574. if (pBuf && Cic_HICON_UserMarshal(pBuf, pBufEnd, picon))
  1575. {
  1576. hr = cparam.Add(cbSize,
  1577. pProxyParam[i].dwFlags,
  1578. pBuf);
  1579. Cic_HICON_UserFree(picon);
  1580. }
  1581. else
  1582. {
  1583. hr = cparam.Add(0,
  1584. pProxyParam[i].dwFlags,
  1585. NULL);
  1586. }
  1587. if (pBufOrg)
  1588. cicMemFree(pBufOrg);
  1589. }
  1590. else if (pProxyParam[i].dwFlags & MPARAM_HBITMAP)
  1591. {
  1592. Assert(pProxyParam[i].ulCount == 1);
  1593. HBITMAP *pbmp = (HBITMAP *)pProxyParam[i].pv;
  1594. ULONG cbSize = Cic_HBITMAP_UserSize(pbmp);
  1595. BYTE *pBufOrg = NULL;
  1596. BYTE *pBuf = NULL;
  1597. BYTE *pBufEnd = NULL;
  1598. if (cbSize)
  1599. {
  1600. pBufOrg = (BYTE *)cicMemAlloc(cbSize + CIC_ALIGNMENT + 1);
  1601. pBuf = pBufOrg;
  1602. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  1603. pBufEnd = pBuf + cbSize;
  1604. }
  1605. if (pBuf && Cic_HBITMAP_UserMarshal(pBuf, pBufEnd, pbmp))
  1606. {
  1607. hr = cparam.Add(cbSize,
  1608. pProxyParam[i].dwFlags,
  1609. pBuf);
  1610. Cic_HBITMAP_UserFree(pbmp);
  1611. }
  1612. else
  1613. {
  1614. hr = cparam.Add(0,
  1615. pProxyParam[i].dwFlags,
  1616. NULL);
  1617. }
  1618. if (pBufOrg)
  1619. cicMemFree(pBufOrg);
  1620. }
  1621. else if (pProxyParam[i].dwFlags & MPARAM_TF_LBBALLOONINFO)
  1622. {
  1623. Assert(pProxyParam[i].ulCount == 1);
  1624. TF_LBBALLOONINFO *pInfo = (TF_LBBALLOONINFO *)pProxyParam[i].pv;
  1625. BYTE *pBufOrg = NULL;
  1626. BYTE *pBuf = NULL;
  1627. ULONG cbSize = Cic_TF_LBBALLOONINFO_UserSize(pInfo);
  1628. if (cbSize)
  1629. {
  1630. pBufOrg = (BYTE *)cicMemAlloc(cbSize + CIC_ALIGNMENT + 1);
  1631. pBuf = pBufOrg;
  1632. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  1633. }
  1634. if (pBuf && Cic_TF_LBBALLOONINFO_UserMarshal(pBuf, pInfo))
  1635. {
  1636. hr = cparam.Add(cbSize,
  1637. pProxyParam[i].dwFlags,
  1638. pBuf);
  1639. Cic_TF_LBBALLOONINFO_UserFree(pInfo);
  1640. }
  1641. else
  1642. {
  1643. hr = cparam.Add(0,
  1644. pProxyParam[i].dwFlags,
  1645. NULL);
  1646. }
  1647. if (pBufOrg)
  1648. cicMemFree(pBufOrg);
  1649. }
  1650. else
  1651. {
  1652. Assert(0);
  1653. hr = E_FAIL;
  1654. }
  1655. if (FAILED(hr))
  1656. {
  1657. Assert(0);
  1658. goto FinishParamCreation;
  1659. }
  1660. }
  1661. FinishParamCreation:
  1662. psheap->GetBlock()->GetMutex()->Leave();
  1663. if (FAILED(hr))
  1664. {
  1665. Assert(0);
  1666. goto Exit;
  1667. }
  1668. hr = cparam.SendReceive(this, ulBlockId);
  1669. if (FAILED(hr))
  1670. goto Exit;
  1671. hrMarshalOutParam = pMsgMap->hrMarshalOutParam;
  1672. if (hrMarshalOutParam != S_OK)
  1673. {
  1674. hr = E_FAIL;
  1675. goto Exit;
  1676. }
  1677. if (!psheap->GetBlock()->GetMutex()->Enter())
  1678. {
  1679. hr = E_FAIL;
  1680. goto Exit;
  1681. }
  1682. for (i = 0; i < ulParamNum; i++)
  1683. {
  1684. MARSHALPARAM *pParam;
  1685. if (!(pProxyParam[i].dwFlags & MPARAM_OUT))
  1686. continue;
  1687. if (!pProxyParam[i].pv)
  1688. continue;
  1689. pParam = cparam.GetMarshalParam(i);
  1690. hr = S_OK;
  1691. if (pProxyParam[i].dwFlags & MPARAM_POINTER)
  1692. {
  1693. if (pParam->cbBufSize)
  1694. {
  1695. memcpy(pProxyParam[i].pv,
  1696. ParamToBufferPointer(pParam),
  1697. pProxyParam[i].GetBufSize());
  1698. }
  1699. else
  1700. {
  1701. memset(pProxyParam[i].pv, 0, pProxyParam[i].GetBufSize());
  1702. }
  1703. }
  1704. else if (pProxyParam[i].dwFlags & MPARAM_INTERFACE)
  1705. {
  1706. MARSHALMSG *pMsg = cparam.Get();
  1707. MARSHALINTERFACEPARAM *pmiparam = (MARSHALINTERFACEPARAM *)ParamToBufferPointer(pParam);
  1708. ULONG ul;
  1709. IUnknown **ppunk = (IUnknown **)pProxyParam[i].pv;
  1710. if (ppunk)
  1711. {
  1712. for (ul = 0; ul < pProxyParam[i].ulCount; ul++)
  1713. {
  1714. if (pmiparam->fNULLPointer)
  1715. {
  1716. *ppunk = NULL;
  1717. }
  1718. else
  1719. {
  1720. hr = CicCoUnmarshalInterface(*pProxyParam[i].piid,
  1721. pMsg->dwSrcThreadId,
  1722. pmiparam->ulStubId,
  1723. pmiparam->dwStubTime,
  1724. (void **)ppunk);
  1725. }
  1726. ppunk++;
  1727. pmiparam++;
  1728. }
  1729. }
  1730. }
  1731. else if (pProxyParam[i].dwFlags & MPARAM_BSTR)
  1732. {
  1733. Assert(pProxyParam[i].ulCount == 1);
  1734. if (pParam->cbBufSize)
  1735. {
  1736. void *pv = ParamToBufferPointer(pParam);
  1737. if ((*(BSTR *)pProxyParam[i].pv = SysAllocString((BSTR)pv)) == NULL)
  1738. {
  1739. hr = E_OUTOFMEMORY;
  1740. }
  1741. }
  1742. else
  1743. {
  1744. *(BSTR *)pProxyParam[i].pv = NULL;
  1745. }
  1746. }
  1747. else if (pProxyParam[i].dwFlags & MPARAM_STRUCT)
  1748. {
  1749. if (pParam->cbBufSize)
  1750. {
  1751. memcpy(pProxyParam[i].pv,
  1752. ParamToBufferPointer(pParam),
  1753. pProxyParam[i].GetBufSize());
  1754. }
  1755. else
  1756. {
  1757. memset(pProxyParam[i].pv, 0, pProxyParam[i].GetBufSize());
  1758. }
  1759. }
  1760. else if (pProxyParam[i].dwFlags & MPARAM_HICON)
  1761. {
  1762. Assert(pProxyParam[i].ulCount == 1);
  1763. HICON hicon = NULL;
  1764. if (pParam->cbBufSize)
  1765. {
  1766. BYTE *pBuf = (BYTE *)ParamToBufferPointer(pParam);
  1767. Cic_HICON_UserUnmarshal(pBuf, &hicon);
  1768. }
  1769. *(HICON *)pProxyParam[i].pv = hicon;
  1770. }
  1771. else if (pProxyParam[i].dwFlags & MPARAM_HBITMAP)
  1772. {
  1773. Assert(pProxyParam[i].ulCount == 1);
  1774. HBITMAP hbmp = NULL;
  1775. if (pParam->cbBufSize)
  1776. {
  1777. BYTE *pBuf = (BYTE *)ParamToBufferPointer(pParam);
  1778. Cic_HBITMAP_UserUnmarshal(pBuf, &hbmp);
  1779. }
  1780. *(HBITMAP *)pProxyParam[i].pv = hbmp;
  1781. }
  1782. else if (pProxyParam[i].dwFlags & MPARAM_TF_LBBALLOONINFO)
  1783. {
  1784. Assert(pProxyParam[i].ulCount == 1);
  1785. if (pParam->cbBufSize)
  1786. {
  1787. BYTE *pBuf = (BYTE *)ParamToBufferPointer(pParam);
  1788. hr = Cic_TF_LBBALLOONINFO_UserUnmarshal(pBuf, (TF_LBBALLOONINFO *)pProxyParam[i].pv);
  1789. }
  1790. }
  1791. else
  1792. {
  1793. Assert(0);
  1794. hr = E_FAIL;
  1795. }
  1796. if (FAILED(hr))
  1797. break;
  1798. }
  1799. if (SUCCEEDED(hr))
  1800. hr = cparam.GetHresult();
  1801. psheap->GetBlock()->GetMutex()->Leave();
  1802. Exit:
  1803. if (pMsgMap)
  1804. psheap->Free(pMsgMap);
  1805. if ((cbPadMemSize == 0) && (hrMarshalOutParam == E_OUTOFMEMORY))
  1806. {
  1807. cbPadMemSize = cbBufSize * 2;
  1808. cparam.Clear();
  1809. goto TryAgain;
  1810. }
  1811. InternalRelease();
  1812. return hr;
  1813. }
  1814. //////////////////////////////////////////////////////////////////////////////
  1815. //
  1816. // CStub
  1817. //
  1818. //////////////////////////////////////////////////////////////////////////////
  1819. //--------------------------------------------------------------------------
  1820. //
  1821. // ctor
  1822. //
  1823. //--------------------------------------------------------------------------
  1824. CStub::CStub()
  1825. {
  1826. _pfm = NULL;
  1827. _fNoRemoveInDtor = FALSE;
  1828. _cRef = 1;
  1829. }
  1830. //--------------------------------------------------------------------------
  1831. //
  1832. // dtor
  1833. //
  1834. //--------------------------------------------------------------------------
  1835. CStub::~CStub()
  1836. {
  1837. //
  1838. // #489905
  1839. //
  1840. // we can not call sink anymore after DLL_PROCESS_DETACH.
  1841. //
  1842. if (!DllShutdownInProgress())
  1843. {
  1844. if (_punk && !IsBadReadPtr(_punk, 1))
  1845. {
  1846. _try {
  1847. _punk->Release();
  1848. _punk = NULL;
  1849. }
  1850. _except(1)
  1851. {
  1852. //
  1853. // Tips may not do DllAddRef() for LangBarItems so
  1854. // _punk could be bad pointer. We need to have a
  1855. // way to clean up CStub.
  1856. //
  1857. ; // TraceMsg(TF_GENERAL, "CStub punk is gone.");
  1858. }
  1859. }
  1860. }
  1861. ClearFileMap();
  1862. if (_fNoRemoveInDtor)
  1863. {
  1864. //
  1865. // we're in FreeMarshaledStubs() so we don't have to
  1866. // remove itself. GetSYSTEMTHREAD() may not work when it is called
  1867. // in UninitProcess().
  1868. //
  1869. return;
  1870. }
  1871. SYSTHREAD *psfn = GetSYSTHREAD();
  1872. Assert(psfn != NULL && psfn->prgStub != NULL);
  1873. if (psfn == NULL || psfn->prgStub == NULL)
  1874. return;
  1875. dbg_CheckStubIds(psfn);
  1876. int i;
  1877. int nCnt = psfn->prgStub->Count();
  1878. for (i = 0; i < nCnt; i++)
  1879. {
  1880. if (this == psfn->prgStub->Get(i))
  1881. {
  1882. psfn->prgStub->Remove(i, 1);
  1883. break;
  1884. }
  1885. }
  1886. }
  1887. //--------------------------------------------------------------------------
  1888. //
  1889. // _AddRef
  1890. //
  1891. //--------------------------------------------------------------------------
  1892. ULONG CStub::_AddRef()
  1893. {
  1894. _cRef++;
  1895. return _cRef;
  1896. }
  1897. //--------------------------------------------------------------------------
  1898. //
  1899. // _Release
  1900. //
  1901. //--------------------------------------------------------------------------
  1902. ULONG CStub::_Release()
  1903. {
  1904. _cRef--;
  1905. if (!_cRef)
  1906. {
  1907. delete this;
  1908. return 0;
  1909. }
  1910. return _cRef;
  1911. }
  1912. //--------------------------------------------------------------------------
  1913. //
  1914. // stub_OutParam
  1915. //
  1916. //--------------------------------------------------------------------------
  1917. HRESULT CStub::stub_OutParam(CStub *_this, MARSHALMSG *pMsg, ULONG ulMethodId, ULONG ulParamNum, CPROXY_PARAM *pProxyParam, CSharedBlock *psb)
  1918. {
  1919. ULONG i;
  1920. HRESULT hr = E_FAIL;
  1921. CMarshalParamCreator cparam;
  1922. if (!psb->GetMutex()->Enter())
  1923. {
  1924. Assert(0);
  1925. return E_FAIL;
  1926. }
  1927. if (!CSharedHeap::IsValidBlock(psb, pMsg))
  1928. {
  1929. Assert(0);
  1930. goto Exit;
  1931. }
  1932. if (!IsEqualIID(pMsg->iid, _this->_iid))
  1933. {
  1934. Assert(0);
  1935. goto Exit;
  1936. }
  1937. if (pMsg->ulMethodId != ulMethodId)
  1938. {
  1939. Assert(0);
  1940. goto Exit;
  1941. }
  1942. if (pMsg->ulParamNum != ulParamNum)
  1943. {
  1944. Assert(0);
  1945. goto Exit;
  1946. }
  1947. if (pMsg->ulStubId != _this->_ulStubId)
  1948. {
  1949. Assert(0);
  1950. goto Exit;
  1951. }
  1952. if (pMsg->dwStubTime != _this->_dwStubTime)
  1953. {
  1954. Assert(0);
  1955. goto Exit;
  1956. }
  1957. hr = S_OK;
  1958. cparam.Set(pMsg, pMsg->cbBufSize);
  1959. cparam.Init(_this->_dwStubThreadId,
  1960. _this->_dwStubProcessId,
  1961. _this->_iid,
  1962. ulMethodId,
  1963. ulParamNum,
  1964. _this->_ulStubId,
  1965. _this->_dwStubTime);
  1966. for (i = 0; i < ulParamNum; i++)
  1967. {
  1968. if (!(pProxyParam[i].dwFlags & MPARAM_OUT))
  1969. {
  1970. cparam.Add(0, pProxyParam[i].dwFlags, NULL);
  1971. continue;
  1972. }
  1973. if (!pProxyParam[i].pv && !(pProxyParam[i].dwFlags & MPARAM_INTERFACE))
  1974. {
  1975. cparam.Add(0, pProxyParam[i].dwFlags, NULL);
  1976. continue;
  1977. }
  1978. if (pProxyParam[i].dwFlags & MPARAM_INTERFACE)
  1979. {
  1980. #if 0
  1981. MARSHALINTERFACEPARAM miparam;
  1982. if (pProxyParam[i].pv)
  1983. {
  1984. CicCoMarshalInterface(*pProxyParam[i].piid,
  1985. *(IUnknown **)pProxyParam[i].pv,
  1986. &miparam.ulStubId,
  1987. &miparam.dwStubTime,
  1988. _this->_dwSrcThreadId);
  1989. miparam.fNULLPointer = FALSE;
  1990. }
  1991. else
  1992. {
  1993. miparam.ulStubId = 0;
  1994. miparam.fNULLPointer = TRUE;
  1995. }
  1996. hr = cparam.Add(sizeof(miparam),
  1997. pProxyParam[i].dwFlags,
  1998. &miparam);
  1999. #else
  2000. if (pProxyParam[i].ulCount == 1)
  2001. {
  2002. MARSHALINTERFACEPARAM miparam;
  2003. if ((IUnknown **)pProxyParam[i].pv &&
  2004. (*(IUnknown **)pProxyParam[i].pv))
  2005. {
  2006. CicCoMarshalInterface(*pProxyParam[i].piid,
  2007. *(IUnknown **)pProxyParam[i].pv,
  2008. &miparam.ulStubId,
  2009. &miparam.dwStubTime,
  2010. _this->_dwSrcThreadId);
  2011. miparam.fNULLPointer = FALSE;
  2012. miparam.fNULLStack = FALSE;
  2013. }
  2014. else
  2015. {
  2016. miparam.ulStubId = 0;
  2017. miparam.fNULLPointer = TRUE;
  2018. if (!(IUnknown **)pProxyParam[i].pv)
  2019. miparam.fNULLStack = TRUE;
  2020. else
  2021. miparam.fNULLStack = FALSE;
  2022. }
  2023. hr = cparam.Add(sizeof(miparam),
  2024. pProxyParam[i].dwFlags,
  2025. &miparam);
  2026. }
  2027. else
  2028. {
  2029. MARSHALINTERFACEPARAM *pmiparam;
  2030. pmiparam = new MARSHALINTERFACEPARAM[pProxyParam[i].ulCount];
  2031. if (pmiparam)
  2032. {
  2033. ULONG ul;
  2034. for (ul = 0; ul < pProxyParam[i].ulCount; ul++)
  2035. {
  2036. IUnknown **ppunk = (IUnknown **)pProxyParam[i].pv;
  2037. if (ppunk && ppunk[ul])
  2038. {
  2039. CicCoMarshalInterface(*pProxyParam[i].piid,
  2040. ppunk[ul],
  2041. &pmiparam[ul].ulStubId,
  2042. &pmiparam[ul].dwStubTime,
  2043. _this->_dwSrcThreadId);
  2044. pmiparam[ul].fNULLPointer = FALSE;
  2045. pmiparam[ul].fNULLStack = FALSE;
  2046. }
  2047. else
  2048. {
  2049. pmiparam[ul].ulStubId = 0;
  2050. pmiparam[ul].fNULLPointer = TRUE;
  2051. if (!ppunk)
  2052. pmiparam[ul].fNULLStack = TRUE;
  2053. else
  2054. pmiparam[ul].fNULLStack = FALSE;
  2055. }
  2056. }
  2057. hr = cparam.Add(sizeof(*pmiparam) * pProxyParam[i].ulCount,
  2058. pProxyParam[i].dwFlags,
  2059. pmiparam);
  2060. delete [] pmiparam;
  2061. }
  2062. }
  2063. #endif
  2064. }
  2065. else if (pProxyParam[i].dwFlags & MPARAM_POINTER)
  2066. {
  2067. hr = cparam.Add(pProxyParam[i].GetBufSize(),
  2068. pProxyParam[i].dwFlags,
  2069. pProxyParam[i].pv);
  2070. }
  2071. else if (pProxyParam[i].dwFlags & MPARAM_ULONG)
  2072. {
  2073. Assert(pProxyParam[i].ulCount == 1);
  2074. hr = cparam.Add(pProxyParam[i].cbUnitSize,
  2075. pProxyParam[i].dwFlags,
  2076. &pProxyParam[i].ul);
  2077. }
  2078. else if (pProxyParam[i].dwFlags & MPARAM_BSTR)
  2079. {
  2080. Assert(pProxyParam[i].ulCount == 1);
  2081. if (pProxyParam[i].pv)
  2082. {
  2083. hr = cparam.Add(SysStringByteLen((BSTR)pProxyParam[i].pv) + 2,
  2084. pProxyParam[i].dwFlags,
  2085. pProxyParam[i].pv);
  2086. SysFreeString((BSTR)pProxyParam[i].pv);
  2087. }
  2088. else
  2089. {
  2090. hr = cparam.Add(0,
  2091. pProxyParam[i].dwFlags,
  2092. NULL);
  2093. }
  2094. }
  2095. else if (pProxyParam[i].dwFlags & MPARAM_HICON)
  2096. {
  2097. Assert(pProxyParam[i].ulCount == 1);
  2098. HICON *picon = (HICON *)pProxyParam[i].pv;
  2099. ULONG cbSize = Cic_HICON_UserSize(picon);
  2100. BYTE *pBuf = NULL;
  2101. BYTE *pBufOrg = NULL;
  2102. BYTE *pBufEnd = NULL;
  2103. if (cbSize)
  2104. {
  2105. pBufOrg = (BYTE *)cicMemAlloc(cbSize + CIC_ALIGNMENT + 1);
  2106. pBuf = pBufOrg;
  2107. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  2108. pBufEnd = pBuf + cbSize;
  2109. }
  2110. if (pBuf && Cic_HICON_UserMarshal(pBuf, pBufEnd, picon))
  2111. {
  2112. hr = cparam.Add(cbSize,
  2113. pProxyParam[i].dwFlags,
  2114. pBuf);
  2115. Cic_HICON_UserFree(picon);
  2116. }
  2117. else
  2118. {
  2119. hr = cparam.Add(0,
  2120. pProxyParam[i].dwFlags,
  2121. NULL);
  2122. }
  2123. if (pBufOrg)
  2124. cicMemFree(pBufOrg);
  2125. }
  2126. else if (pProxyParam[i].dwFlags & MPARAM_HBITMAP)
  2127. {
  2128. Assert(pProxyParam[i].ulCount == 1);
  2129. HBITMAP *pbmp = (HBITMAP *)pProxyParam[i].pv;
  2130. ULONG cbSize = Cic_HBITMAP_UserSize(pbmp);
  2131. BYTE *pBuf = NULL;
  2132. BYTE *pBufOrg = NULL;
  2133. BYTE *pBufEnd = NULL;
  2134. if (cbSize)
  2135. {
  2136. pBufOrg = (BYTE *)cicMemAlloc(cbSize + CIC_ALIGNMENT + 1);
  2137. pBuf = pBufOrg;
  2138. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  2139. pBufEnd = pBuf + cbSize;
  2140. }
  2141. if (pBuf && Cic_HBITMAP_UserMarshal(pBuf, pBufEnd, pbmp))
  2142. {
  2143. hr = cparam.Add(cbSize,
  2144. pProxyParam[i].dwFlags,
  2145. pBuf);
  2146. Cic_HBITMAP_UserFree(pbmp);
  2147. }
  2148. else
  2149. {
  2150. hr = cparam.Add(0,
  2151. pProxyParam[i].dwFlags,
  2152. NULL);
  2153. }
  2154. if (pBufOrg)
  2155. cicMemFree(pBufOrg);
  2156. }
  2157. else if (pProxyParam[i].dwFlags & MPARAM_TF_LBBALLOONINFO)
  2158. {
  2159. Assert(pProxyParam[i].ulCount == 1);
  2160. TF_LBBALLOONINFO *pInfo = (TF_LBBALLOONINFO *)pProxyParam[i].pv;
  2161. ULONG cbSize = Cic_TF_LBBALLOONINFO_UserSize(pInfo);
  2162. BYTE *pBuf = NULL;
  2163. BYTE *pBufOrg = NULL;
  2164. if (cbSize)
  2165. {
  2166. pBufOrg = (BYTE *)cicMemAlloc(cbSize + CIC_ALIGNMENT + 1);
  2167. pBuf = pBufOrg;
  2168. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  2169. }
  2170. if (pBuf && Cic_TF_LBBALLOONINFO_UserMarshal(pBuf, pInfo))
  2171. {
  2172. hr = cparam.Add(cbSize,
  2173. pProxyParam[i].dwFlags,
  2174. pBuf);
  2175. Cic_TF_LBBALLOONINFO_UserFree(pInfo);
  2176. }
  2177. else
  2178. {
  2179. hr = cparam.Add(0,
  2180. pProxyParam[i].dwFlags,
  2181. NULL);
  2182. }
  2183. if (pBufOrg)
  2184. cicMemFree(pBufOrg);
  2185. }
  2186. else
  2187. Assert(0);
  2188. if (hr != S_OK)
  2189. {
  2190. break;
  2191. }
  2192. }
  2193. Exit:
  2194. pMsg->hrMarshalOutParam = hr;
  2195. psb->GetMutex()->Leave();
  2196. return hr;
  2197. }
  2198. //////////////////////////////////////////////////////////////////////////////
  2199. //
  2200. // TF_CCheckThreadInputIdle
  2201. //
  2202. //////////////////////////////////////////////////////////////////////////////
  2203. extern "C" DWORD WINAPI TF_CheckThreadInputIdle(DWORD dwThreadId, DWORD dwTimeOut)
  2204. {
  2205. if (dwThreadId == GetCurrentThreadId())
  2206. return 0;
  2207. HWND hwndTemp = CThreadMarshalWnd::GetThreadMarshalWnd(dwThreadId);
  2208. if (!hwndTemp)
  2209. {
  2210. return WAIT_FAILED;
  2211. }
  2212. DWORD dwTime = GetTickCount();
  2213. CCheckThreadInputIdle event(dwThreadId, dwTime);
  2214. CCicSecAttr sa;
  2215. if (!event.Create(sa))
  2216. {
  2217. Assert(0);
  2218. return WAIT_FAILED;
  2219. }
  2220. PostMessage(hwndTemp, g_msgCheckThreadInputIdel, 0, (LPARAM)dwTime);
  2221. DWORD dwReason = event.EventCheck();
  2222. if (dwReason == WAIT_OBJECT_0)
  2223. return 0;
  2224. if (event.Wait(dwTimeOut))
  2225. return 0;
  2226. return WAIT_TIMEOUT;
  2227. }