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.

1382 lines
38 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: Hndlrmsg.cpp
  7. //
  8. // Contents: Takes care of handler specific messages
  9. //
  10. // Classes: CHndlrMsg
  11. //
  12. // Notes:
  13. //
  14. // History: 05-Nov-97 rogerg Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "precomp.h"
  18. //+---------------------------------------------------------------------------
  19. //
  20. // Member: CHndlrMsg::CHndlrMsg, public
  21. //
  22. // Synopsis: Constructor
  23. //
  24. // Arguments:
  25. //
  26. // Returns:
  27. //
  28. // Modifies:
  29. //
  30. // History: 05-Nov-97 rogerg Created.
  31. //
  32. //----------------------------------------------------------------------------
  33. CHndlrMsg::CHndlrMsg()
  34. {
  35. m_pOneStopHandler = NULL;
  36. m_pOldOneStopHandler = NULL;
  37. m_dwSyncFlags = 0;
  38. m_pCallBack = NULL;
  39. m_cRef = 1;
  40. m_fDead = FALSE;
  41. m_fForceKilled = FALSE;
  42. m_dwNestCount = 0;
  43. m_fThreadInputAttached = FALSE;
  44. m_itemIDShowProperties = GUID_NULL;
  45. m_dwProxyThreadId = -1;
  46. m_dwThreadId = GetCurrentThreadId();
  47. }
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Member: CHndlrMsg::~CHndlrMsg, public
  51. //
  52. // Synopsis: Destructor
  53. //
  54. // Arguments:
  55. //
  56. // Returns:
  57. //
  58. // Modifies:
  59. //
  60. // History: 05-Nov-97 rogerg Created.
  61. //
  62. //----------------------------------------------------------------------------
  63. CHndlrMsg::~CHndlrMsg()
  64. {
  65. Assert(m_dwThreadId == GetCurrentThreadId() || m_fForceKilled);
  66. Assert(0 == m_dwNestCount || m_fForceKilled);
  67. Assert(0 == m_cRef || m_fForceKilled);
  68. }
  69. //+---------------------------------------------------------------------------
  70. //
  71. // Member: CHndlrMsg::QueryInterface, public
  72. //
  73. // Synopsis: Standard QueryInterface
  74. //
  75. // Arguments: [iid] - Interface ID
  76. // [ppvObj] - Object return
  77. //
  78. // Returns: Appropriate status code
  79. //
  80. // Modifies: [ppvObj]
  81. //
  82. // History: 05-Nov-97 rogerg Created.
  83. //
  84. //----------------------------------------------------------------------------
  85. STDMETHODIMP CHndlrMsg::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  86. {
  87. Assert(m_dwThreadId == GetCurrentThreadId());
  88. Assert(0 == m_dwNestCount);
  89. return E_NOINTERFACE;
  90. }
  91. //+---------------------------------------------------------------------------
  92. //
  93. // Member: CHndlrMsg::AddRef, public
  94. //
  95. // Synopsis: Add reference
  96. //
  97. // History: 05-Nov-97 rogerg Created.
  98. //
  99. //----------------------------------------------------------------------------
  100. STDMETHODIMP_(ULONG) CHndlrMsg::AddRef()
  101. {
  102. ULONG cRefs;
  103. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  104. Assert(m_dwThreadId == GetCurrentThreadId());
  105. Assert(0 == m_dwNestCount);
  106. m_dwNestCount++;
  107. cRefs = InterlockedIncrement((LONG *)& m_cRef);
  108. m_dwNestCount--;
  109. return cRefs;
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CHndlrMsg::Release, public
  114. //
  115. // Synopsis: Release reference
  116. //
  117. // History: 05-Nov-97 rogerg Created.
  118. //
  119. //----------------------------------------------------------------------------
  120. STDMETHODIMP_(ULONG) CHndlrMsg::Release()
  121. {
  122. ULONG cRefs;
  123. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  124. Assert(m_dwThreadId == GetCurrentThreadId());
  125. Assert(0 == m_dwNestCount);
  126. m_dwNestCount++;
  127. cRefs = InterlockedDecrement( (LONG *) &m_cRef);
  128. if (0 == cRefs)
  129. {
  130. if (m_pCallBack)
  131. {
  132. SetupCallback(FALSE);
  133. }
  134. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  135. if (m_pOneStopHandler)
  136. {
  137. LPSYNCMGRSYNCHRONIZE OneStopHandler = m_pOneStopHandler;
  138. m_pOneStopHandler = NULL;
  139. // if have a callback then revoke it
  140. // CODE REVIEW : NOTENOTE :
  141. // This is a valid use of try/except, but this would mask real refcounting errors in the handler callbacks,
  142. // or elsewhere in our code where m_pOneStopHandler was overwritten..
  143. __try
  144. {
  145. OneStopHandler->Release();
  146. }
  147. __except(QueryHandleException())
  148. {
  149. AssertSz(0,"Exception in Handler's release method.");
  150. }
  151. }
  152. if (m_pOldOneStopHandler)
  153. {
  154. LPOLDSYNCMGRSYNCHRONIZE pOldOneStopHandler = m_pOldOneStopHandler;
  155. m_pOldOneStopHandler = NULL;
  156. // if have a callback then revoke it
  157. __try
  158. {
  159. pOldOneStopHandler->Release();
  160. }
  161. __except(QueryHandleException())
  162. {
  163. AssertSz(0,"Exception in Handler's release method.");
  164. }
  165. }
  166. if (m_pHndlrQueue)
  167. {
  168. m_pHndlrQueue->Release();
  169. m_pHndlrQueue = NULL;
  170. }
  171. m_fDead = TRUE;
  172. m_dwNestCount--;
  173. delete this;
  174. }
  175. else
  176. {
  177. m_dwNestCount--;
  178. }
  179. return cRefs;
  180. }
  181. //+---------------------------------------------------------------------------
  182. //
  183. // Member: CHndlrMsg::Initialize, public
  184. //
  185. // Synopsis: Calls Initialize method of the Handler
  186. //
  187. // Arguments: [dwReserved] - Reserved for now is NULL
  188. // [dwSyncFlags] - SyncFlags
  189. // [cbCookie] - Size of Cookie data if any
  190. // [lpCookie] - Pointer to Cookie data
  191. //
  192. // Returns: Whatever the handler tells us too.
  193. //
  194. // Modifies:
  195. //
  196. // History: 05-Nov-97 rogerg Created.
  197. //
  198. //----------------------------------------------------------------------------
  199. STDMETHODIMP CHndlrMsg::Initialize(DWORD dwReserved,
  200. DWORD dwSyncFlags,
  201. DWORD cbCookie,
  202. BYTE const* lpCookie)
  203. {
  204. HRESULT hr = E_UNEXPECTED;
  205. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  206. Assert(m_dwThreadId == GetCurrentThreadId());
  207. Assert(0 == m_dwNestCount);
  208. m_dwNestCount++;
  209. m_dwSyncFlags = dwSyncFlags;
  210. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  211. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  212. if (m_pOneStopHandler)
  213. {
  214. // CODE REVIEW : NOTENOTE:
  215. // QueryHandleException() catches all exceptions - do we want to limit out exception handling code ?
  216. __try
  217. {
  218. hr = m_pOneStopHandler->Initialize(dwReserved,dwSyncFlags,cbCookie,lpCookie);
  219. }
  220. __except(QueryHandleException())
  221. {
  222. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  223. AssertSz(0,"Exception in Handler's Initialize method.");
  224. }
  225. }
  226. if (m_pOldOneStopHandler)
  227. {
  228. // old handlers can't handle cookie data unless it is their own
  229. if (SYNCMGRFLAG_INVOKE != (dwSyncFlags & SYNCMGRFLAG_EVENTMASK))
  230. {
  231. cbCookie = 0;
  232. lpCookie = NULL;
  233. }
  234. __try
  235. {
  236. hr = m_pOldOneStopHandler->Initialize(dwReserved,dwSyncFlags,cbCookie,lpCookie);
  237. }
  238. __except(QueryHandleException())
  239. {
  240. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  241. AssertSz(0,"Exception in Handler's Initialize method.");
  242. }
  243. }
  244. m_dwNestCount--;
  245. return hr;
  246. }
  247. //+---------------------------------------------------------------------------
  248. //
  249. // Member: CHndlrMsg::GetHandlerInfo, public
  250. //
  251. // Synopsis: Calls GetHandlerInfo method of the Handler
  252. //
  253. // Arguments: [ppSyncMgrHandlerInfo] -
  254. //
  255. // Returns: Whatever the handler tells us too.
  256. //
  257. // Modifies:
  258. //
  259. // History: 05-Nov-97 rogerg Created.
  260. //
  261. //----------------------------------------------------------------------------
  262. STDMETHODIMP CHndlrMsg::GetHandlerInfo(LPSYNCMGRHANDLERINFO *ppSyncMgrHandlerInfo)
  263. {
  264. HRESULT hr = E_UNEXPECTED;
  265. Assert(m_dwThreadId == GetCurrentThreadId());
  266. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  267. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  268. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  269. if (m_pOneStopHandler)
  270. {
  271. __try
  272. {
  273. hr = m_pOneStopHandler->GetHandlerInfo(ppSyncMgrHandlerInfo);
  274. }
  275. __except(QueryHandleException())
  276. {
  277. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  278. AssertSz(0,"Exception in Handler's GetHandlerInfo method.");
  279. }
  280. }
  281. if (m_pOldOneStopHandler)
  282. {
  283. __try
  284. {
  285. hr = m_pOldOneStopHandler->GetHandlerInfo(ppSyncMgrHandlerInfo);
  286. }
  287. __except(QueryHandleException())
  288. {
  289. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  290. AssertSz(0,"Exception in Handler's GetHandlerInfo method.");
  291. }
  292. }
  293. return hr;
  294. }
  295. //+---------------------------------------------------------------------------
  296. //
  297. // Member: CHndlrMsg::EnumOfflineItems, public
  298. //
  299. // Synopsis: PlaceHolder for IOfflineSynchronize Enum method.
  300. // This shouldn't be called. AddHandlerItems should be
  301. // called instead
  302. //
  303. // Arguments: [ppenumOfflineItems] - returned enumerator
  304. //
  305. // Returns: Whatever the handler tells us too.
  306. //
  307. // Modifies:
  308. //
  309. // History: 05-Nov-97 rogerg Created.
  310. //
  311. //----------------------------------------------------------------------------
  312. STDMETHODIMP CHndlrMsg::EnumSyncMgrItems(ISyncMgrEnumItems** ppenumOffineItems)
  313. {
  314. Assert(m_dwThreadId == GetCurrentThreadId());
  315. Assert(0 == m_dwNestCount);
  316. m_dwNestCount++;
  317. AssertSz(0,"Shouldn't call this Method");
  318. *ppenumOffineItems = NULL;
  319. m_dwNestCount--;
  320. return E_NOTIMPL;
  321. }
  322. //+---------------------------------------------------------------------------
  323. //
  324. // Member: CHndlrMsg::GetItemObject, public
  325. //
  326. // Synopsis: Calls Handler's GetItemObject method
  327. //
  328. // Arguments: [ItemID] - Id of the item
  329. // [riid] - requested interface
  330. // [ppv] - out pointer for object
  331. //
  332. // Returns: Whatever the handler tells us too.
  333. //
  334. // Modifies:
  335. //
  336. // History: 05-Nov-97 rogerg Created.
  337. //
  338. //----------------------------------------------------------------------------
  339. STDMETHODIMP CHndlrMsg::GetItemObject(REFSYNCMGRITEMID ItemID, REFIID riid, void** ppv)
  340. {
  341. HRESULT hr = E_UNEXPECTED;
  342. Assert(m_dwThreadId == GetCurrentThreadId());
  343. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  344. Assert(0 == m_dwNestCount);
  345. m_dwNestCount++;
  346. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  347. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  348. // CODE REVIEW: NOTENOTE
  349. // MSDN documents that this GetItemObject method is for future use, and that no client
  350. // should be implementing it. Notice the ASSERT below
  351. if (m_pOneStopHandler)
  352. {
  353. __try
  354. {
  355. hr = m_pOneStopHandler->GetItemObject(ItemID,riid,ppv);
  356. }
  357. __except(QueryHandleException())
  358. {
  359. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  360. AssertSz(0,"Exception in Handler's GetItemObject method.");
  361. }
  362. Assert(E_NOTIMPL == hr); // currently no one should be implementing this.
  363. }
  364. if (m_pOldOneStopHandler)
  365. {
  366. __try
  367. {
  368. hr = m_pOldOneStopHandler->GetItemObject(ItemID,riid,ppv);
  369. }
  370. __except(QueryHandleException())
  371. {
  372. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  373. AssertSz(0,"Exception in Handler's GetItemObject method.");
  374. }
  375. Assert(E_NOTIMPL == hr); // currently noone should be implementing this.
  376. }
  377. m_dwNestCount--;
  378. return hr;
  379. }
  380. //+---------------------------------------------------------------------------
  381. //
  382. // Member: CHndlrMsg::ShowProperties, public
  383. //
  384. // Synopsis: Calls Handler's ShowProperties method
  385. //
  386. // Arguments: [hwnd] - hwnd to use as parent to dialog
  387. // [itemID] - Identifies the Item
  388. //
  389. // Returns: Whatever the handler tells us.
  390. //
  391. // Modifies:
  392. //
  393. // History: 05-Nov-97 rogerg Created.
  394. //
  395. //----------------------------------------------------------------------------
  396. STDMETHODIMP CHndlrMsg::ShowProperties(HWND hwnd,REFSYNCMGRITEMID ItemID)
  397. {
  398. HRESULT hr = E_UNEXPECTED;
  399. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  400. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  401. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  402. // need to setup calback if showProperties is called
  403. // if can't setup callback then fail the ShowProperties call.
  404. // Review, ShowPropertiesCompleted doesn't give us the ItemID back so we
  405. // have to store it. This is fine but limits us to one ShowPropertiesCall
  406. // at a time on the handler. if update main interfaces change
  407. // ShowPropertiesCompleted to return the ItemID
  408. Assert(GUID_NULL == m_itemIDShowProperties);
  409. m_itemIDShowProperties = ItemID;
  410. hr = SetupCallback(TRUE); // set up the callback.
  411. if (S_OK != hr)
  412. return hr;
  413. Assert(0 == m_dwNestCount);
  414. m_dwNestCount++;
  415. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  416. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  417. AttachThreadInput(TRUE);
  418. if (m_pOneStopHandler)
  419. {
  420. __try
  421. {
  422. hr = m_pOneStopHandler->ShowProperties(hwnd,ItemID);
  423. }
  424. __except(QueryHandleException())
  425. {
  426. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  427. AssertSz(0,"Exception in Handler's ShowProperties method.");
  428. }
  429. }
  430. if (m_pOldOneStopHandler)
  431. {
  432. __try
  433. {
  434. hr = m_pOldOneStopHandler->ShowProperties(hwnd,ItemID);
  435. }
  436. __except(QueryHandleException())
  437. {
  438. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  439. AssertSz(0,"Exception in Handler's ShowProperties method.");
  440. }
  441. }
  442. m_dwNestCount--;
  443. // if old interface need to make the callback ourselves
  444. if ( m_pOldOneStopHandler )
  445. {
  446. Assert(m_pCallBack);
  447. if (m_pCallBack && (S_OK == hr))
  448. {
  449. m_pCallBack->ShowPropertiesCompleted(S_OK);
  450. }
  451. }
  452. // if an error is returned set the showProperties guid back
  453. if (S_OK != hr)
  454. {
  455. m_itemIDShowProperties = GUID_NULL;
  456. }
  457. return hr;
  458. }
  459. //+---------------------------------------------------------------------------
  460. //
  461. // Member: CHndlrMsg::SetProgressCallback, public
  462. //
  463. // Synopsis: PlaceHolder for SetProgressCallback. This member is currently
  464. // not used. Instead the SetupCallback method is called
  465. //
  466. // Arguments: [lpCallBack] - Pointer to Callback object
  467. //
  468. // Returns: Whatever the handler tells us.
  469. //
  470. // Modifies:
  471. //
  472. // History: 05-Nov-97 rogerg Created.
  473. //
  474. //----------------------------------------------------------------------------
  475. STDMETHODIMP CHndlrMsg::SetProgressCallback(ISyncMgrSynchronizeCallback *lpCallBack)
  476. {
  477. Assert(m_dwThreadId == GetCurrentThreadId());
  478. Assert(0 == m_dwNestCount);
  479. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  480. m_dwNestCount++;
  481. AssertSz(0,"Shouldn't call this method");
  482. m_dwNestCount--;
  483. return E_NOTIMPL;
  484. }
  485. //+---------------------------------------------------------------------------
  486. //
  487. // Member: CHndlrMsg::PrepareForSync, public
  488. //
  489. // Synopsis: Calls Handler's ShowProperties method
  490. //
  491. // Arguments: [cbNumItems] - number of items so sync
  492. // [pItemIDs] - Array of Items
  493. // [hwnd] - Hwnd to use as the Parent of any dialogs
  494. // [dwReserved] - Just a reserved parameter
  495. //
  496. // Returns: Whatever the handler tells us.
  497. //
  498. // Modifies:
  499. //
  500. // History: 05-Nov-97 rogerg Created.
  501. //
  502. //----------------------------------------------------------------------------
  503. STDMETHODIMP CHndlrMsg::PrepareForSync(ULONG cbNumItems,SYNCMGRITEMID *pItemIDs,
  504. HWND hwnd,DWORD dwReserved)
  505. {
  506. HRESULT hr = E_UNEXPECTED;
  507. Assert(m_dwThreadId == GetCurrentThreadId());
  508. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  509. // Assert(0 == m_dwNestCount);// may not be zero if handler has yielded
  510. hr = SetupCallback(TRUE); // set up the callback.
  511. if (S_OK != hr)
  512. return hr;
  513. m_dwNestCount++;
  514. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  515. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  516. if (m_pOneStopHandler)
  517. {
  518. __try
  519. {
  520. hr = m_pOneStopHandler->PrepareForSync(cbNumItems,pItemIDs,hwnd,dwReserved);
  521. }
  522. __except(QueryHandleException())
  523. {
  524. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  525. AssertSz(0,"Exception in Handler's PrepareForSync method.");
  526. }
  527. }
  528. if (m_pOldOneStopHandler)
  529. {
  530. __try
  531. {
  532. hr = m_pOldOneStopHandler->PrepareForSync(cbNumItems,pItemIDs,hwnd,dwReserved);
  533. }
  534. __except(QueryHandleException())
  535. {
  536. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  537. AssertSz(0,"Exception in Handler's PrepareForSync method.");
  538. }
  539. }
  540. m_dwNestCount--;
  541. return hr;
  542. }
  543. //+---------------------------------------------------------------------------
  544. //
  545. // Member: CHndlrMsg::Sychronize, public
  546. //
  547. // Synopsis: Calls Handler's Synchronize method
  548. //
  549. // Arguments: [hwnd] - hwnd to use as parent to dialog
  550. //
  551. // Returns: Whatever the handler tells us.
  552. //
  553. // Modifies:
  554. //
  555. // History: 05-Nov-97 rogerg Created.
  556. //
  557. //----------------------------------------------------------------------------
  558. STDMETHODIMP CHndlrMsg::Synchronize(HWND hwnd)
  559. {
  560. HRESULT hr = E_UNEXPECTED;
  561. Assert(m_dwThreadId == GetCurrentThreadId());
  562. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  563. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  564. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  565. // Assert(0 == m_dwNestCount);
  566. m_dwNestCount++;
  567. if (m_pOneStopHandler)
  568. {
  569. __try
  570. {
  571. hr = m_pOneStopHandler->Synchronize(hwnd);
  572. }
  573. __except(QueryHandleException())
  574. {
  575. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  576. AssertSz(0,"Exception in Handler's Synchronize method.");
  577. }
  578. }
  579. if (m_pOldOneStopHandler)
  580. {
  581. __try
  582. {
  583. hr = m_pOldOneStopHandler->Synchronize(hwnd);
  584. }
  585. __except(QueryHandleException())
  586. {
  587. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  588. AssertSz(0,"Exception in Handler's Synchronize method.");
  589. }
  590. }
  591. m_dwNestCount--;
  592. return hr;
  593. }
  594. //+---------------------------------------------------------------------------
  595. //
  596. // Member: CHndlrMsg::SetItemStatus, public
  597. //
  598. // Synopsis: Calls Handler's SetItemStatus method
  599. //
  600. // Arguments:
  601. //
  602. // Returns: Whatever the handler tells us.
  603. //
  604. // Modifies:
  605. //
  606. // History: 05-Nov-97 rogerg Created.
  607. //
  608. //----------------------------------------------------------------------------
  609. STDMETHODIMP CHndlrMsg::SetItemStatus(REFSYNCMGRITEMID ItemID,DWORD dwSyncMgrStatus)
  610. {
  611. HRESULT hr = S_OK;
  612. Assert(m_dwThreadId == GetCurrentThreadId());
  613. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  614. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  615. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  616. m_dwNestCount++; // valid for this to come in when in sync call.
  617. if (m_pOneStopHandler)
  618. {
  619. __try
  620. {
  621. hr = m_pOneStopHandler->SetItemStatus(ItemID,dwSyncMgrStatus);
  622. }
  623. __except(QueryHandleException())
  624. {
  625. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  626. AssertSz(0,"Exception in Handler's SetItemStatus method.");
  627. }
  628. }
  629. if (m_pOldOneStopHandler)
  630. {
  631. __try
  632. {
  633. hr = m_pOldOneStopHandler->SetItemStatus(ItemID,dwSyncMgrStatus);
  634. }
  635. __except(QueryHandleException())
  636. {
  637. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  638. AssertSz(0,"Exception in Handler's SetItemStatus method.");
  639. }
  640. }
  641. m_dwNestCount--;
  642. return hr;
  643. }
  644. //+---------------------------------------------------------------------------
  645. //
  646. // Member: CHndlrMsg::ShowError, public
  647. //
  648. // Synopsis: Calls Handler's ShowError method
  649. //
  650. // Arguments: [hwnd] - hwnd to use as parent to dialog
  651. // [dwErrorID] - ErrorID passed in LogError
  652. //
  653. // Returns: Whatever the handler tells us.
  654. //
  655. // Modifies:
  656. //
  657. // History: 05-Nov-97 rogerg Created.
  658. //
  659. //----------------------------------------------------------------------------
  660. STDMETHODIMP CHndlrMsg::ShowError(HWND hWndParent,REFSYNCMGRERRORID ErrorID)
  661. {
  662. HRESULT hr = E_UNEXPECTED;
  663. ULONG cbNumItems;
  664. SYNCMGRITEMID *pItemIDs;
  665. Assert(m_dwThreadId == GetCurrentThreadId());
  666. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  667. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  668. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  669. m_dwNestCount++;
  670. // on a ShowError enablemodeless in the callback can
  671. // return true since user has shown an interest
  672. if (m_pCallBack)
  673. {
  674. m_pCallBack->SetEnableModeless(TRUE);
  675. }
  676. AttachThreadInput(TRUE);
  677. if (m_pOneStopHandler)
  678. {
  679. __try
  680. {
  681. hr = m_pOneStopHandler->ShowError(hWndParent,ErrorID);
  682. }
  683. __except(QueryHandleException())
  684. {
  685. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  686. AssertSz(0,"Exception in Handler's ShowError method.");
  687. }
  688. }
  689. if (m_pOldOneStopHandler)
  690. {
  691. __try
  692. {
  693. hr = m_pOldOneStopHandler->ShowError(hWndParent,ErrorID,&cbNumItems,&pItemIDs);
  694. }
  695. __except(QueryHandleException())
  696. {
  697. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  698. AssertSz(0,"Exception in Handler's ShowError method.");
  699. }
  700. }
  701. m_dwNestCount--;
  702. // if old interface need to make the callback ourselves
  703. if ( m_pOldOneStopHandler )
  704. {
  705. Assert(m_pCallBack);
  706. if (m_pCallBack && SUCCEEDED(hr))
  707. {
  708. m_pCallBack->ShowErrorCompleted(hr,cbNumItems,pItemIDs);
  709. if ( (S_SYNCMGR_RETRYSYNC == hr) && pItemIDs) // after completion routine free the pItems since [in] param.
  710. {
  711. CoTaskMemFree(pItemIDs);
  712. }
  713. }
  714. return SUCCEEDED(hr) ? S_OK : hr;
  715. }
  716. // New interface won't have the numItems and Items Enum
  717. // on new interface ShowError should only return S_OK so if retry or
  718. // other success is returned then return S_OK;
  719. return hr;
  720. }
  721. //+---------------------------------------------------------------------------
  722. //
  723. // Member: CHndlrMsg::SetupCallback, private
  724. //
  725. // Synopsis: Sets up the callback for the handler
  726. //
  727. // Arguments: [fSet] - TRUE sets the Callbac, FALSE removes it
  728. //
  729. // Returns: S_OK on Success
  730. //
  731. // Modifies:
  732. //
  733. // History: 05-Nov-97 rogerg Created.
  734. //
  735. //----------------------------------------------------------------------------
  736. STDMETHODIMP CHndlrMsg::SetupCallback(BOOL fSet)
  737. {
  738. HRESULT hr = E_UNEXPECTED;
  739. Assert(m_dwThreadId == GetCurrentThreadId());
  740. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  741. Assert(m_dwNestCount <= 1); // 1 since valid to be called from Release method.
  742. m_dwNestCount++;
  743. // possible to get called with fSet twice of true in the case
  744. // a retrysync occurs. If we already have a callback set
  745. // when a new request to set one comes in the just return.
  746. if ( m_pCallBack && (TRUE == fSet))
  747. {
  748. hr = S_OK;
  749. }
  750. else
  751. {
  752. Assert( ( (m_pCallBack) && (FALSE == fSet) )
  753. || (TRUE == fSet)); // catch case OneStop calls this twice when already set
  754. if (m_pCallBack)
  755. {
  756. // set the callbacks CHndlrMsg pointer to NULL in case
  757. // object tries to call through after the release.
  758. m_pCallBack->SetHndlrMsg(NULL,FALSE);
  759. m_pCallBack->Release();
  760. m_pCallBack = NULL;
  761. }
  762. if (TRUE == fSet)
  763. {
  764. // if allocation fails, progress just gets set to NULL
  765. m_pCallBack = new COfflineSynchronizeCallback( this,
  766. m_CLSIDServer,m_dwSyncFlags,
  767. (SYNCMGRFLAG_MAYBOTHERUSER & m_dwSyncFlags) /* fAllowModeless */ );
  768. }
  769. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  770. if (m_pOneStopHandler)
  771. {
  772. __try
  773. {
  774. hr = m_pOneStopHandler->SetProgressCallback( (LPSYNCMGRSYNCHRONIZECALLBACK) m_pCallBack );
  775. }
  776. __except(QueryHandleException())
  777. {
  778. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  779. AssertSz(0,"Exception in Handler's SetProgressCallback method.");
  780. }
  781. }
  782. if (m_pOldOneStopHandler)
  783. {
  784. __try
  785. {
  786. hr = m_pOldOneStopHandler->SetProgressCallback( (LPOLDSYNCMGRSYNCHRONIZECALLBACK) m_pCallBack );
  787. }
  788. __except(QueryHandleException())
  789. {
  790. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  791. AssertSz(0,"Exception in Handler's SetProgressCallback method.");
  792. }
  793. }
  794. if ( (S_OK != hr) && (m_pCallBack) )
  795. {
  796. m_pCallBack->SetHndlrMsg(NULL,FALSE);
  797. m_pCallBack->Release(); // on an error go ahead and release our copy too.
  798. m_pCallBack = NULL;
  799. }
  800. }
  801. m_dwNestCount--;
  802. return hr;
  803. }
  804. //+---------------------------------------------------------------------------
  805. //
  806. // Member: CHndlrMsg::SetHandlerInfo, private
  807. //
  808. // Synopsis: sets up the Handler info
  809. //
  810. // Arguments:
  811. //
  812. // Returns: S_OK on Success
  813. //
  814. // Modifies:
  815. //
  816. // History: 28-Jul-98 rogerg Created.
  817. //
  818. //----------------------------------------------------------------------------
  819. STDMETHODIMP CHndlrMsg::SetHandlerInfo()
  820. {
  821. LPSYNCMGRHANDLERINFO pSyncMgrHandlerInfo = NULL;
  822. HRESULT hr = E_UNEXPECTED;
  823. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  824. hr = GetHandlerInfo(&pSyncMgrHandlerInfo);
  825. if (S_OK != hr || (NULL == pSyncMgrHandlerInfo))
  826. {
  827. return hr;
  828. }
  829. if (!IsValidSyncMgrHandlerInfo(pSyncMgrHandlerInfo))
  830. {
  831. CoTaskMemFree(pSyncMgrHandlerInfo);
  832. return E_INVALIDARG;
  833. }
  834. Assert(m_pHndlrQueue);
  835. if (m_pHndlrQueue)
  836. {
  837. hr = m_pHndlrQueue->SetHandlerInfo(m_pHandlerId,pSyncMgrHandlerInfo);
  838. }
  839. if (pSyncMgrHandlerInfo)
  840. {
  841. CoTaskMemFree(pSyncMgrHandlerInfo);
  842. }
  843. return hr;
  844. }
  845. //+---------------------------------------------------------------------------
  846. //
  847. // Member: CHndlrMsg::AddtoItemList, private
  848. //
  849. // Synopsis: Adds a single Items to the queue
  850. //
  851. // Arguments: [poffItem] - Pointer to Item to add
  852. //
  853. // Returns: S_OK on Success
  854. //
  855. // Modifies:
  856. //
  857. // History: 05-Nov-97 rogerg Created.
  858. //
  859. //----------------------------------------------------------------------------
  860. HRESULT CHndlrMsg::AddToItemList(LPSYNCMGRITEM poffItem)
  861. {
  862. HRESULT hr = E_UNEXPECTED;
  863. Assert(m_dwThreadId == GetCurrentThreadId());
  864. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  865. Assert(m_pHndlrQueue);
  866. if (!IsValidSyncMgrItem(poffItem))
  867. {
  868. return E_INVALIDARG;
  869. }
  870. if (m_pHndlrQueue)
  871. {
  872. hr = m_pHndlrQueue->AddItemToHandler(m_pHandlerId,poffItem);
  873. }
  874. return hr;
  875. }
  876. //+---------------------------------------------------------------------------
  877. //
  878. // Member: CHndlrMsg::AddHandlerItems, private
  879. //
  880. // Synopsis: Calls the handlers enumerator and adds each returned item
  881. // to the queue
  882. //
  883. // Arguments: [hwndList] - hwnd of ListView to add items too. (Not Used)
  884. //
  885. // Returns: Appropriate status code
  886. //
  887. // Modifies:
  888. //
  889. // History: 05-Nov-97 rogerg Created.
  890. //
  891. //----------------------------------------------------------------------------
  892. STDMETHODIMP CHndlrMsg::AddHandlerItems(HWND hwndList, DWORD *pcbNumItems)
  893. {
  894. HRESULT hr = E_UNEXPECTED;
  895. LPSYNCMGRENUMITEMS pEnumOffline = NULL;
  896. Assert(m_dwThreadId == GetCurrentThreadId());
  897. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  898. Assert(pcbNumItems);
  899. *pcbNumItems = 0;
  900. Assert(0 == m_dwNestCount);
  901. m_dwNestCount++;
  902. SetHandlerInfo(); // setup the toplevel handler info
  903. Assert(m_pOneStopHandler || m_pOldOneStopHandler);
  904. Assert( !(m_pOneStopHandler && m_pOldOneStopHandler) );
  905. if (m_pOneStopHandler || m_pOldOneStopHandler)
  906. {
  907. if ( m_pOneStopHandler )
  908. {
  909. __try
  910. {
  911. hr = m_pOneStopHandler->EnumSyncMgrItems(&pEnumOffline);
  912. }
  913. __except(QueryHandleException())
  914. {
  915. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  916. AssertSz(0,"Exception in Handler's EnumSyncMgrItems method.");
  917. }
  918. }
  919. if ( m_pOldOneStopHandler )
  920. {
  921. __try
  922. {
  923. hr = m_pOldOneStopHandler->EnumSyncMgrItems(&pEnumOffline);
  924. }
  925. __except(QueryHandleException())
  926. {
  927. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  928. AssertSz(0,"Exception in Handler's EnumSyncMgrItems method.");
  929. }
  930. }
  931. // Review - Make sure preferences aren't deleted
  932. // in missing items case.
  933. if ( (S_OK == hr || S_SYNCMGR_MISSINGITEMS == hr) && pEnumOffline)
  934. {
  935. SYNCMGRITEMNT5B2 offItem; // temporarily use NT5B2 structure since its bigger
  936. ULONG pceltFetched;
  937. Assert(sizeof(SYNCMGRITEMNT5B2) > sizeof(SYNCMGRITEM));
  938. // sit in loop getting data of objects to fill list box.
  939. // should really set up list in memory for OneStop to fill in or
  940. // main thread could pass in a callback interface.
  941. if (pEnumOffline)
  942. {
  943. __try
  944. {
  945. while(S_OK == pEnumOffline->Next(1,(LPSYNCMGRITEM) &offItem,&pceltFetched))
  946. {
  947. if (S_OK == AddToItemList((LPSYNCMGRITEM) &offItem))
  948. {
  949. ++(*pcbNumItems);
  950. }
  951. }
  952. pEnumOffline->Release();
  953. }
  954. __except(QueryHandleException())
  955. {
  956. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  957. AssertSz(0,"Exception in Handler's EnumOffline::Next method.");
  958. }
  959. }
  960. else
  961. {
  962. hr = E_UNEXPECTED;
  963. }
  964. }
  965. }
  966. m_dwNestCount--;
  967. return hr;
  968. }
  969. //+---------------------------------------------------------------------------
  970. //
  971. // Member: CHndlrMsg::CreateServer, private
  972. //
  973. // Synopsis: Creates and Instance of the handle
  974. //
  975. // Arguments: [pCLSIDServer] - CLSID of Handler
  976. // [pHndlrQueue] - pointer to queue handler should be added too
  977. // [wHandlerID] - ID of Handler in the queue
  978. //
  979. // Returns: Appropriate status code
  980. //
  981. // Modifies:
  982. //
  983. // History: 05-Nov-97 rogerg Created.
  984. //
  985. //----------------------------------------------------------------------------
  986. STDMETHODIMP CHndlrMsg::CreateServer(const CLSID *pCLSIDServer,CHndlrQueue *pHndlrQueue,
  987. HANDLERINFO *pHandlerId,DWORD dwProxyThreadId)
  988. {
  989. HRESULT hr = S_OK;
  990. LPUNKNOWN pUnk;
  991. LPSYNCMGRENUMITEMS pEnumOffline = NULL;
  992. Assert(m_dwThreadId == GetCurrentThreadId());
  993. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  994. Assert(0 == m_dwNestCount);
  995. m_dwNestCount++;
  996. m_CLSIDServer = *pCLSIDServer;
  997. m_pHndlrQueue = pHndlrQueue;
  998. m_dwProxyThreadId = dwProxyThreadId;
  999. if (m_pHndlrQueue)
  1000. {
  1001. m_pHndlrQueue->AddRef();
  1002. }
  1003. m_pHandlerId = pHandlerId;
  1004. hr = CoCreateInstance(m_CLSIDServer, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **) &pUnk);
  1005. if (S_OK == hr)
  1006. {
  1007. __try
  1008. {
  1009. hr = pUnk->QueryInterface(IID_ISyncMgrSynchronize,(void **) &m_pOneStopHandler);
  1010. }
  1011. __except(QueryHandleException())
  1012. {
  1013. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  1014. AssertSz(0,"Exception in Handler's IUnknown::QI method.");
  1015. }
  1016. __try
  1017. {
  1018. pUnk->Release();
  1019. }
  1020. __except(QueryHandleException())
  1021. {
  1022. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  1023. AssertSz(0,"Exception in Handler's IUnknown::Release method.");
  1024. }
  1025. }
  1026. if (S_OK != hr)
  1027. {
  1028. m_pOneStopHandler = NULL;
  1029. m_pOldOneStopHandler = NULL;
  1030. }
  1031. m_dwNestCount--;
  1032. return hr;
  1033. }
  1034. //+---------------------------------------------------------------------------
  1035. //
  1036. // Member: CHndlrMsg::SetHndlrQueue, private
  1037. //
  1038. // Synopsis: Assigns a new HndlrQueue.
  1039. //
  1040. // Arguments: [pHndlrQueue] - Pointer to the Queue
  1041. // [wHandlerId] - Id assigned to handler in the new queue
  1042. //
  1043. // !!!Warning - this is on the callers thread
  1044. //
  1045. // Returns: Appropriate status code
  1046. //
  1047. // Modifies:
  1048. //
  1049. // History: 05-Nov-97 rogerg Created.
  1050. //
  1051. //----------------------------------------------------------------------------
  1052. STDMETHODIMP CHndlrMsg::SetHndlrQueue(CHndlrQueue *pHndlrQueue,HANDLERINFO *pHandlerId,DWORD dwProxyThreadId)
  1053. {
  1054. CLock clockCallback(this);
  1055. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  1056. clockCallback.Enter();
  1057. Assert(0 == m_dwNestCount);
  1058. m_dwNestCount++;
  1059. if (pHndlrQueue != m_pHndlrQueue)
  1060. {
  1061. if (m_pHndlrQueue)
  1062. {
  1063. m_pHndlrQueue->Release();
  1064. }
  1065. m_pHndlrQueue = pHndlrQueue;
  1066. if (m_pHndlrQueue)
  1067. {
  1068. m_pHndlrQueue->AddRef();
  1069. }
  1070. }
  1071. AttachThreadInput(FALSE); // make sure thread input isn't set
  1072. // update handlr id and proxy which can change even if queue is same
  1073. // which can happen first queue that gets set in choice.
  1074. m_pHandlerId = pHandlerId;
  1075. m_dwProxyThreadId = dwProxyThreadId;
  1076. m_dwNestCount--;
  1077. clockCallback.Leave();
  1078. return S_OK;
  1079. }
  1080. //+---------------------------------------------------------------------------
  1081. //
  1082. // Member: CHndlrMsg::GetHndlrQueue, private
  1083. //
  1084. // Synopsis: Gets current Queue,
  1085. // Can be called on any thread so progress callback
  1086. // gets this information.
  1087. //
  1088. // Arguments: [ppHndlrQueue] - Out param filled with Pointer to the Queue
  1089. // [pwHandlerId] - out param filled with Id assigned to handler
  1090. // in the new queue
  1091. //
  1092. // Returns: Appropriate status code
  1093. //
  1094. // Modifies:
  1095. //
  1096. // History: 05-Nov-97 rogerg Created.
  1097. //
  1098. //----------------------------------------------------------------------------
  1099. void CHndlrMsg::GetHndlrQueue(CHndlrQueue **ppHndlrQueue,HANDLERINFO **ppHandlerId,DWORD *pdwProxyThreadId)
  1100. {
  1101. CLock clockCallback(this);
  1102. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  1103. clockCallback.Enter();
  1104. *ppHndlrQueue = m_pHndlrQueue;
  1105. *ppHandlerId = m_pHandlerId;
  1106. *pdwProxyThreadId = m_dwProxyThreadId;
  1107. if (m_pHndlrQueue)
  1108. {
  1109. m_pHndlrQueue->AddRef();
  1110. }
  1111. clockCallback.Leave();
  1112. }
  1113. //+---------------------------------------------------------------------------
  1114. //
  1115. // Member: CHndlrMsg::AttachThreadInput, private
  1116. //
  1117. // Synopsis: Attaches the thread input of this thread
  1118. // with the calling proxy so UI works correctly.
  1119. //
  1120. // Arguments: [fAttach] - Bool to indicate if should attach or not.
  1121. //
  1122. // Returns: Appropriate status code
  1123. //
  1124. // Modifies:
  1125. //
  1126. // History: 05-Nov-97 rogerg Created.
  1127. //
  1128. //----------------------------------------------------------------------------
  1129. void CHndlrMsg::AttachThreadInput(BOOL fAttach)
  1130. {
  1131. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  1132. // if request is same as current state don't do anything.
  1133. if (m_fThreadInputAttached != fAttach )
  1134. {
  1135. m_fThreadInputAttached = fAttach;
  1136. ::AttachThreadInput(m_dwProxyThreadId,m_dwThreadId,fAttach);
  1137. }
  1138. }
  1139. //+---------------------------------------------------------------------------
  1140. //
  1141. // Member: CHndlrMsg::ForceKillHandler, private
  1142. //
  1143. // Synopsis: called directly by proxy when a thread is not
  1144. // responding. Does any necessary cleanup of classes in the handler
  1145. // thread before the proxy kills the thred
  1146. //
  1147. // Arguments:
  1148. //
  1149. // Returns: Appropriate status code
  1150. //
  1151. // Modifies:
  1152. //
  1153. // History: 17-Nov-98 rogerg Created.
  1154. //
  1155. //----------------------------------------------------------------------------
  1156. STDMETHODIMP CHndlrMsg::ForceKillHandler()
  1157. {
  1158. Assert(FALSE == m_fForceKilled && FALSE == m_fDead);
  1159. m_fForceKilled = TRUE;
  1160. // if have a callback tell it we terminated but don't
  1161. // release it in case the handler calls the callback later.
  1162. if (m_pCallBack)
  1163. {
  1164. COfflineSynchronizeCallback* pCallback = m_pCallBack;
  1165. m_pCallBack = NULL;
  1166. pCallback->SetHndlrMsg(NULL,TRUE);
  1167. }
  1168. // delete our instance since should never be called again.
  1169. delete this;
  1170. return S_OK;
  1171. }