Source code of Windows XP (NT5)
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.

585 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: Callback.cpp
  7. //
  8. // Contents: Calback implementation
  9. //
  10. // Classes: COfflineSynchronizeCallback
  11. //
  12. // Notes:
  13. //
  14. // History: 05-Nov-97 rogerg Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "precomp.h"
  18. //+---------------------------------------------------------------------------
  19. //
  20. // Member: COfflineSynchronizeCallback::COfflineSynchronizeCallback, public
  21. //
  22. // Synopsis: Constructor
  23. //
  24. // Arguments: [pHndlrMsg] - pointer to CHndlrMsg class this callback belongs too.
  25. //
  26. // Returns:
  27. //
  28. // Modifies:
  29. //
  30. // History: 05-Nov-97 rogerg Created.
  31. //
  32. //----------------------------------------------------------------------------
  33. COfflineSynchronizeCallback::COfflineSynchronizeCallback(CHndlrMsg *pHndlrMsg
  34. ,CLSID CLSIDServer
  35. ,DWORD dwSyncFlags
  36. ,BOOL fAllowModeless)
  37. {
  38. Assert(NULL != pHndlrMsg);
  39. m_pHndlrMsg = pHndlrMsg;
  40. m_CLSIDServer = CLSIDServer;
  41. m_dwSyncFlags = dwSyncFlags;
  42. m_cRef = 1;
  43. m_fSynchronizeCompleted = FALSE;
  44. m_fAllowModeless = fAllowModeless;
  45. m_fForceKilled = FALSE;
  46. }
  47. //+---------------------------------------------------------------------------
  48. //
  49. // Member: COfflineSynchronizeCallback::~COfflineSynchronizeCallback, public
  50. //
  51. // Synopsis: Destructor
  52. //
  53. // Arguments:
  54. //
  55. // Returns:
  56. //
  57. // Modifies:
  58. //
  59. // History: 05-Nov-97 rogerg Created.
  60. //
  61. //----------------------------------------------------------------------------
  62. COfflineSynchronizeCallback::~COfflineSynchronizeCallback()
  63. {
  64. Assert(FALSE == m_fForceKilled); // should never get cleaned up of force killed.
  65. Assert(NULL == m_pHndlrMsg);
  66. Assert(0 == m_cRef);
  67. }
  68. //+---------------------------------------------------------------------------
  69. //
  70. // Member: COfflineSynchronizeCallback::QueryInterface, public
  71. //
  72. // Synopsis: Standard QueryInterface
  73. //
  74. // Arguments: [iid] - Interface ID
  75. // [ppvObj] - Object return
  76. //
  77. // Returns: Appropriate status code
  78. //
  79. // Modifies: [ppvObj]
  80. //
  81. // History: 05-Nov-97 rogerg Created.
  82. //
  83. //----------------------------------------------------------------------------
  84. STDMETHODIMP COfflineSynchronizeCallback::QueryInterface (REFIID riid, LPVOID * ppvObj)
  85. {
  86. *ppvObj = NULL;
  87. if( IsEqualIID( riid, IID_IUnknown ) )
  88. *ppvObj = (LPVOID) this;
  89. else if ( IsEqualIID( riid, IID_ISyncMgrSynchronizeCallback ) )
  90. *ppvObj = (LPVOID)(LPSYNCMGRSYNCHRONIZECALLBACK) this;
  91. else if ( IsEqualIID( riid, IID_IOldSyncMgrSynchronizeCallback ) )
  92. {
  93. // This is for the Old IDL This is the old IE 5.0 Beta1 interface
  94. // no one shipped using it so it can safely be removed.
  95. *ppvObj = (LPVOID)(LPOLDSYNCMGRSYNCHRONIZECALLBACK) this;
  96. }
  97. else
  98. return E_NOINTERFACE;
  99. AddRef();
  100. return NOERROR;
  101. }
  102. //+---------------------------------------------------------------------------
  103. //
  104. // Member: COfflineSynchronizeCallback::AddRef, public
  105. //
  106. // Synopsis: Add reference
  107. //
  108. // History: 05-Nov-97 rogerg Created.
  109. //
  110. //----------------------------------------------------------------------------
  111. DWORD COfflineSynchronizeCallback::AddRef()
  112. {
  113. ULONG cRefs;
  114. cRefs = InterlockedIncrement((LONG *)& m_cRef);
  115. return cRefs;
  116. }
  117. //+---------------------------------------------------------------------------
  118. //
  119. // Member: COfflineSynchronizeCallback::Release, public
  120. //
  121. // Synopsis: Release reference
  122. //
  123. // History: 05-Nov-97 rogerg Created.
  124. //
  125. //----------------------------------------------------------------------------
  126. DWORD COfflineSynchronizeCallback::Release()
  127. {
  128. ULONG cRefs;
  129. cRefs = InterlockedDecrement( (LONG *) &m_cRef);
  130. if (0 == cRefs)
  131. {
  132. delete this;
  133. }
  134. return cRefs;
  135. }
  136. //+---------------------------------------------------------------------------
  137. //
  138. // Member: COfflineSynchronizeCallback::EnableModeless, public
  139. //
  140. // Synopsis: EnableModeless method - Currently always returns NOERROR
  141. //
  142. // Arguments: [fEnable] - Boolean (TRUE == request to bring up dialog,
  143. // FALSE == the dialog has been dismissed.
  144. //
  145. // Returns: S_OK if handler can perform the request
  146. // S_FALSE if dialog shouldn't be displayed.
  147. //
  148. // Modifies:
  149. //
  150. // History: 05-Nov-97 rogerg Created.
  151. //
  152. //----------------------------------------------------------------------------
  153. STDMETHODIMP COfflineSynchronizeCallback::EnableModeless(BOOL fEnable)
  154. {
  155. HRESULT hr = S_OK;
  156. if (m_fForceKilled)
  157. {
  158. return S_FALSE;
  159. }
  160. if (!m_fAllowModeless && fEnable)
  161. {
  162. hr = S_FALSE;
  163. }
  164. if (m_pHndlrMsg)
  165. {
  166. BOOL fAttach = FALSE;
  167. if (fEnable && (S_OK == hr)) // Attach Thread input if want dialog and it was granted.
  168. {
  169. fAttach = TRUE;
  170. }
  171. m_pHndlrMsg->AttachThreadInput(fAttach);
  172. }
  173. return hr;
  174. }
  175. //+---------------------------------------------------------------------------
  176. //
  177. // Member: COfflineSynchronizeCallback::Progress, public
  178. //
  179. // Synopsis: Called by Handlers to update progress information.
  180. //
  181. // Arguments: [ItemID] - Identifies Item Progress information pertains to
  182. // [lpSyncProgressItem] - Pointer to ProgressItem Structure.
  183. //
  184. // Returns: Appropriate status code
  185. //
  186. // Modifies:
  187. //
  188. // History: 05-Nov-97 rogerg Created.
  189. //
  190. //----------------------------------------------------------------------------
  191. STDMETHODIMP COfflineSynchronizeCallback::Progress(REFSYNCMGRITEMID ItemID,
  192. LPSYNCMGRPROGRESSITEM lpSyncProgressItem)
  193. {
  194. HRESULT hr = E_UNEXPECTED;
  195. CHndlrQueue *pHndlrQueue = NULL;
  196. HANDLERINFO *pHandlerID = 0;
  197. DWORD dwProxyThreadId;
  198. CLock clockCallback(this);
  199. if (m_fForceKilled)
  200. {
  201. return S_SYNCMGR_CANCELALL;
  202. }
  203. clockCallback.Enter();
  204. Assert(NULL != m_pHndlrMsg);
  205. if (m_pHndlrMsg)
  206. {
  207. m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
  208. }
  209. clockCallback.Leave();
  210. if (pHndlrQueue)
  211. {
  212. hr = pHndlrQueue->Progress(pHandlerID,
  213. ItemID,lpSyncProgressItem);
  214. pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
  215. }
  216. return hr;
  217. }
  218. STDMETHODIMP COfflineSynchronizeCallback::PrepareForSyncCompleted(HRESULT hCallResult)
  219. {
  220. CallCompletionRoutine(ThreadMsg_PrepareForSync,hCallResult,0,NULL);
  221. return NOERROR;
  222. }
  223. STDMETHODIMP COfflineSynchronizeCallback::SynchronizeCompleted(HRESULT hCallResult)
  224. {
  225. CallCompletionRoutine(ThreadMsg_Synchronize,hCallResult,0,NULL);
  226. return NOERROR;
  227. }
  228. STDMETHODIMP COfflineSynchronizeCallback::ShowPropertiesCompleted(HRESULT hCallResult)
  229. {
  230. CallCompletionRoutine(ThreadMsg_ShowProperties,hCallResult,0,NULL);
  231. return NOERROR;
  232. }
  233. STDMETHODIMP COfflineSynchronizeCallback::ShowErrorCompleted(HRESULT hCallResult,ULONG cbNumItems,SYNCMGRITEMID *pItemIDs)
  234. {
  235. CallCompletionRoutine(ThreadMsg_ShowError,hCallResult,cbNumItems,pItemIDs);
  236. return NOERROR;
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // Member: COfflineSynchronizeCallback::LogError, public
  241. //
  242. // Synopsis: Called by Handlers to log and Error.
  243. //
  244. // Arguments: [dwErrorLevel] - ErrorLevel of the Log
  245. // [lpcErrorText] - Text Associated with the error.
  246. // [lpSyncLogError] - Additional Error information.
  247. //
  248. // Returns: Appropriate status code
  249. //
  250. // Modifies:
  251. //
  252. // History: 05-Nov-97 rogerg Created.
  253. //
  254. //----------------------------------------------------------------------------
  255. STDMETHODIMP COfflineSynchronizeCallback::LogError(DWORD dwErrorLevel,
  256. const WCHAR *lpcErrorText,LPSYNCMGRLOGERRORINFO lpSyncLogError)
  257. {
  258. HRESULT hr = E_UNEXPECTED;
  259. CHndlrQueue *pHndlrQueue = NULL;
  260. HANDLERINFO *pHandlerID = 0;
  261. DWORD dwProxyThreadId;
  262. CLock clockCallback(this);
  263. if (m_fForceKilled)
  264. {
  265. return NOERROR;
  266. }
  267. clockCallback.Enter();
  268. Assert(NULL != m_pHndlrMsg);
  269. if (m_pHndlrMsg)
  270. {
  271. m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
  272. }
  273. clockCallback.Leave();
  274. if (pHndlrQueue)
  275. {
  276. hr = pHndlrQueue->LogError(pHandlerID,
  277. dwErrorLevel, lpcErrorText,lpSyncLogError);
  278. pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
  279. }
  280. return hr;
  281. }
  282. //+---------------------------------------------------------------------------
  283. //
  284. // Member: COfflineSynchronizeCallback::LogError, public
  285. //
  286. // Synopsis: Called by Handlers to delete an error that
  287. // was previously logged.
  288. //
  289. // Arguments:
  290. //
  291. // Returns: Appropriate status code
  292. //
  293. // Modifies:
  294. //
  295. // History: 13-Mar-98 rogerg Created.
  296. //
  297. //----------------------------------------------------------------------------
  298. STDMETHODIMP COfflineSynchronizeCallback::DeleteLogError(REFSYNCMGRERRORID ErrorID,DWORD dwReserved)
  299. {
  300. HRESULT hr = E_UNEXPECTED;
  301. CHndlrQueue *pHndlrQueue = NULL;
  302. HANDLERINFO *pHandlerID = 0;
  303. DWORD dwProxyThreadId;
  304. CLock clockCallback(this);
  305. if (m_fForceKilled)
  306. {
  307. return NOERROR;
  308. }
  309. if (dwReserved)
  310. {
  311. AssertSz(0,"DeleteLogError Reserved must be zero");
  312. return E_INVALIDARG;
  313. }
  314. clockCallback.Enter();
  315. Assert(NULL != m_pHndlrMsg);
  316. if (m_pHndlrMsg)
  317. {
  318. m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
  319. }
  320. clockCallback.Leave();
  321. if (pHndlrQueue)
  322. {
  323. hr = pHndlrQueue->DeleteLogError(pHandlerID,ErrorID,dwReserved);
  324. pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
  325. }
  326. return hr;
  327. }
  328. //+---------------------------------------------------------------------------
  329. //
  330. // Member: COfflineSynchronizeCallback::EstablishConnection
  331. //
  332. // Synopsis: Called by Handlers to establish a net connection
  333. //
  334. // Arguments: [lpwszConnection] -- Connection string
  335. // [dwReserved] -- Must be zero for now
  336. //
  337. // History: 28-Jul-98 SitaramR Created
  338. //
  339. //----------------------------------------------------------------------------
  340. STDMETHODIMP COfflineSynchronizeCallback::EstablishConnection( WCHAR const * lpwszConnection,
  341. DWORD dwReserved)
  342. {
  343. if (m_fForceKilled)
  344. {
  345. return S_FALSE;
  346. }
  347. if ( dwReserved != 0 )
  348. {
  349. Assert( dwReserved == 0 );
  350. return E_INVALIDARG;
  351. }
  352. HRESULT hr = E_UNEXPECTED;
  353. CHndlrQueue *pHndlrQueue = NULL;
  354. HANDLERINFO *pHandlerID = 0;
  355. DWORD dwProxyThreadId;
  356. CLock clockCallback(this);
  357. clockCallback.Enter();
  358. Assert(NULL != m_pHndlrMsg);
  359. if (m_pHndlrMsg)
  360. {
  361. m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
  362. }
  363. clockCallback.Leave();
  364. if (pHndlrQueue)
  365. {
  366. hr = pHndlrQueue->EstablishConnection( pHandlerID,
  367. lpwszConnection,
  368. dwReserved);
  369. pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
  370. }
  371. return hr;
  372. }
  373. //+---------------------------------------------------------------------------
  374. //
  375. // Member: COfflineSynchronizeCallback::SetHndlrMsg, public
  376. //
  377. // Synopsis: Called by CHndlrMsg to update the CHndlrMsg that owns the
  378. // callback. This currently should only be called with a paramater
  379. // of NULL for when the HndlrMsg is being destroyed.
  380. //
  381. // Arguments: [pHndlrMsg] - New CHndlrMsg the Callback belongs too.
  382. // [fForceKilled] - Set to True if HndlrMsg is removed because of a forcekill
  383. //
  384. // Returns:
  385. //
  386. // Modifies:
  387. //
  388. // History: 05-Nov-97 rogerg Created.
  389. //
  390. //----------------------------------------------------------------------------
  391. void COfflineSynchronizeCallback::SetHndlrMsg(CHndlrMsg *pHndlrMsg,BOOL fForceKilled)
  392. {
  393. CLock clockCallback(this);
  394. Assert(NULL == pHndlrMsg);
  395. Assert(FALSE == m_fForceKilled); // shouldn't get force killed twice
  396. clockCallback.Enter();
  397. m_pHndlrMsg = pHndlrMsg;
  398. m_fForceKilled = fForceKilled;
  399. clockCallback.Leave();
  400. }
  401. //+---------------------------------------------------------------------------
  402. //
  403. // Member: COfflineSynchronizeCallback::SetEnableModeless, private
  404. //
  405. // Synopsis: Called by CHndlrMsg to update inform the callback if
  406. // it is allowed to enablemodelsss.
  407. //
  408. // Arguments:
  409. //
  410. // Returns:
  411. //
  412. // Modifies:
  413. //
  414. // History: 05-Nov-97 rogerg Created.
  415. //
  416. //----------------------------------------------------------------------------
  417. void COfflineSynchronizeCallback::SetEnableModeless(BOOL fAllowModeless)
  418. {
  419. CLock clockCallback(this);
  420. clockCallback.Enter();
  421. m_fAllowModeless = fAllowModeless;
  422. clockCallback.Leave();
  423. }
  424. //+---------------------------------------------------------------------------
  425. //
  426. // Member: COfflineSynchronizeCallback::CallCompletionRoutine, private
  427. //
  428. // Synopsis: Private helper method for calling completion routine.
  429. //
  430. // Arguments:
  431. // DWORD dwThreadMsg - Identifies message belongs too.
  432. // HRESULT hCallResult - result of call
  433. // ULONG *pcbNumItems - only applies to ShowError
  434. // SYNCMGRITEMID **pItemIDs - only applies to ShowError
  435. //
  436. // Returns:
  437. //
  438. // Modifies:
  439. //
  440. // History: 02-Jun-98 rogerg Created.
  441. //
  442. //----------------------------------------------------------------------------
  443. void COfflineSynchronizeCallback::CallCompletionRoutine(DWORD dwThreadMsg,HRESULT hCallResult,ULONG cbNumItems,SYNCMGRITEMID *pItemIDs)
  444. {
  445. CHndlrQueue *pHndlrQueue = NULL;
  446. HANDLERINFO *pHandlerID = 0;
  447. DWORD dwProxyThreadId;
  448. SYNCMGRITEMID itemIDShowProperties;
  449. CLock clockCallback(this);
  450. if (m_fForceKilled)
  451. {
  452. return;
  453. }
  454. clockCallback.Enter();
  455. Assert(NULL != m_pHndlrMsg);
  456. if (m_pHndlrMsg)
  457. {
  458. // if this is a ShowProperties, fix up the item
  459. if (ThreadMsg_ShowProperties == dwThreadMsg)
  460. {
  461. cbNumItems = 1;
  462. itemIDShowProperties = m_pHndlrMsg->m_itemIDShowProperties;
  463. pItemIDs = &itemIDShowProperties;
  464. m_pHndlrMsg->m_itemIDShowProperties = GUID_NULL;
  465. }
  466. m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
  467. m_pHndlrMsg->AttachThreadInput(FALSE); // release any thread input that was set.
  468. }
  469. clockCallback.Leave();
  470. if (pHndlrQueue)
  471. {
  472. pHndlrQueue->CallCompletionRoutine(pHandlerID,dwThreadMsg,hCallResult,cbNumItems,pItemIDs);
  473. pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
  474. }
  475. }