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.

608 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1996.
  5. //
  6. // File: astgconn.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 03-Apr-96 PhilipLa Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "exphead.cxx"
  18. #pragma hdrstop
  19. #include "astgconn.hxx"
  20. #include <filllkb.hxx>
  21. #include <asyncerr.hxx>
  22. SCODE CAsyncConnection::Init(IConnectionPointContainer *pCPC,
  23. CAsyncConnection *pacParent)
  24. {
  25. SCODE sc = S_OK;
  26. CConnectionPoint *pcpoint;
  27. olAssert(_pdacp == NULL);
  28. if (pacParent)
  29. _dwAsyncFlags = pacParent->_dwAsyncFlags;
  30. olMem(pcpoint = new CConnectionPoint());
  31. olChk(pcpoint->Init());
  32. if ((pacParent) && (_dwAsyncFlags & ASYNC_MODE_COMPATIBILITY))
  33. {
  34. pcpoint->SetParent(pacParent->_pdacp);
  35. }
  36. else
  37. {
  38. pcpoint->SetParent(NULL);
  39. }
  40. _pCPC = pCPC;
  41. _pdacp = pcpoint;
  42. EH_Err:
  43. return sc;
  44. }
  45. SCODE CAsyncConnection::InitClone(IConnectionPointContainer *pCPC,
  46. CAsyncConnection *pac)
  47. {
  48. SCODE sc = S_OK;
  49. CConnectionPoint *pcpoint;
  50. olAssert(pac != NULL);
  51. _dwAsyncFlags = pac->_dwAsyncFlags;
  52. olMem(pcpoint = new CConnectionPoint());
  53. olChk(pcpoint->Init());
  54. if (_dwAsyncFlags & ASYNC_MODE_COMPATIBILITY)
  55. {
  56. IDocfileAsyncConnectionPoint *pdacp;
  57. if (FAILED(sc = pac->_pdacp->GetParent(&pdacp)))
  58. {
  59. delete pcpoint;
  60. return sc;
  61. }
  62. pcpoint->SetParent(pdacp);
  63. }
  64. else
  65. {
  66. pcpoint->SetParent(NULL);
  67. }
  68. _pCPC = pCPC;
  69. _pdacp = pcpoint;
  70. EH_Err:
  71. return sc;
  72. }
  73. SCODE CAsyncConnection::InitMarshal(IConnectionPointContainer *pCPC,
  74. DWORD dwAsyncFlags,
  75. IDocfileAsyncConnectionPoint *pdacp)
  76. {
  77. SCODE sc = S_OK;
  78. _dwAsyncFlags = dwAsyncFlags;
  79. _pCPC = pCPC;
  80. _pdacp = pdacp;
  81. if (_pdacp)
  82. _pdacp->AddRef();
  83. return sc;
  84. }
  85. //+---------------------------------------------------------------------------
  86. //
  87. // Member: CAsyncConnection::~CAsyncConnection, public
  88. //
  89. // Synopsis: Destructor
  90. //
  91. // Returns: Appropriate status code
  92. //
  93. // History: 03-Apr-96 PhilipLa Created
  94. //
  95. //----------------------------------------------------------------------------
  96. CAsyncConnection::~CAsyncConnection()
  97. {
  98. olDebugOut((DEB_ITRACE,
  99. "In CAsyncConnection::~CAsyncConnection:%p()\n", this));
  100. //Note: _pdacp must be released outside of the tree mutex, which
  101. // means we need to extract the pointer and release it elsewhere.
  102. #if 0
  103. if (_pdacp != NULL)
  104. {
  105. _pdacp->Release();
  106. }
  107. #endif
  108. olDebugOut((DEB_ITRACE,
  109. "Out CAsyncConnection::~CAsyncConnection\n"));
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CAsyncConnection::QueryInterface, public
  114. //
  115. // Synopsis:
  116. //
  117. // Arguments:
  118. //
  119. // Returns: Appropriate status code
  120. //
  121. // Modifies:
  122. //
  123. // History: 01-Jan-96 SusiA Created
  124. //
  125. // Notes:
  126. //
  127. //----------------------------------------------------------------------------
  128. STDMETHODIMP CAsyncConnection::QueryInterface(REFIID iid, void **ppvObj)
  129. {
  130. SCODE sc = S_OK;
  131. olDebugOut((DEB_TRACE,
  132. "In CAsyncConnection::QueryInterface:%p()\n",
  133. this));
  134. *ppvObj = NULL;
  135. if ((IsEqualIID(iid, IID_IUnknown)) ||
  136. (IsEqualIID(iid, IID_IConnectionPoint)))
  137. {
  138. *ppvObj = (IConnectionPoint *)this;
  139. CAsyncConnection::AddRef();
  140. }
  141. else
  142. {
  143. return E_NOINTERFACE;
  144. }
  145. olDebugOut((DEB_TRACE, "Out CAsyncConnection::QueryInterface\n"));
  146. return ResultFromScode(sc);
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Member: CAsyncConnection::AddRef, public
  151. //
  152. // Synopsis:
  153. //
  154. // Arguments:
  155. //
  156. // Returns: Appropriate status code
  157. //
  158. // Modifies:
  159. //
  160. // History: 29-Dec-95 SusiA Created
  161. //
  162. // Notes:
  163. //
  164. //----------------------------------------------------------------------------
  165. STDMETHODIMP_(ULONG) CAsyncConnection::AddRef(void)
  166. {
  167. ULONG ulRet;
  168. olDebugOut((DEB_TRACE,
  169. "In CAsyncConnection::AddRef:%p()\n",
  170. this));
  171. InterlockedIncrement(&_cReferences);
  172. ulRet = _cReferences;
  173. olDebugOut((DEB_TRACE, "Out CAsyncConnection::AddRef\n"));
  174. return ulRet;
  175. }
  176. //+---------------------------------------------------------------------------
  177. //
  178. // Member: CAsyncConnection::Release, public
  179. //
  180. // Synopsis:
  181. //
  182. // Arguments:
  183. //
  184. // Returns: Appropriate status code
  185. //
  186. // Modifies:
  187. //
  188. // History: 30-Dec-95 SusiA Created
  189. //
  190. // Notes:
  191. //
  192. //----------------------------------------------------------------------------
  193. STDMETHODIMP_(ULONG) CAsyncConnection::Release(void)
  194. {
  195. LONG lRet;
  196. olDebugOut((DEB_TRACE,
  197. "In CAsyncConnection::Release:%p()\n",
  198. this));
  199. olAssert(_cReferences > 0);
  200. lRet = InterlockedDecrement(&_cReferences);
  201. if (lRet == 0)
  202. {
  203. delete this;
  204. }
  205. else if (lRet < 0)
  206. {
  207. olAssert((lRet > 0) && "Connection point released too many times.");
  208. lRet = 0;
  209. }
  210. olDebugOut((DEB_TRACE, "Out CAsyncConnection::Release\n"));
  211. return (ULONG)lRet;
  212. }
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Member: CAsyncConnection::Notify, public
  216. //
  217. // Synopsis:
  218. //
  219. // Returns: Appropriate status code
  220. //
  221. // History: 14-Jan-96 SusiA Created
  222. // 27-Feb-96 SusiA Moved from Async wrappers
  223. //
  224. //----------------------------------------------------------------------------
  225. SCODE CAsyncConnection::Notify(SCODE scFailure,
  226. ILockBytes *pilb,
  227. CPerContext *ppc,
  228. CSafeSem *pss)
  229. {
  230. SCODE sc = S_OK;
  231. BOOL fAccurate = (scFailure == E_PENDING);
  232. IFillInfo *pfi = ppc->GetFillInfo();
  233. ULONG ulWaterMark;
  234. ULONG ulFailurePoint;
  235. HANDLE hNotifyEvent;
  236. if (pfi != NULL)
  237. {
  238. pfi->GetFailureInfo(&ulWaterMark,
  239. &ulFailurePoint);
  240. pss->Release();
  241. while (((sc = _pdacp->NotifySinks(ulWaterMark,
  242. ulFailurePoint,
  243. fAccurate,
  244. STG_S_MONITORING)) == STG_S_BLOCK) ||
  245. (sc == STG_S_MONITORING) ||
  246. // S_OK is a synonym for STG_S_MONITORING
  247. (sc == S_OK))
  248. {
  249. DWORD dwFlags;
  250. // wait for an event to signal
  251. hNotifyEvent = ppc->GetNotificationEvent();
  252. WaitForSingleObject(hNotifyEvent, INFINITE);
  253. pfi->GetTerminationStatus(&dwFlags);
  254. // client terminated call?
  255. if (dwFlags == TERMINATED_ABNORMAL)
  256. {
  257. return STG_E_INCOMPLETE;
  258. }
  259. // download is complete
  260. else if (dwFlags == TERMINATED_NORMAL)
  261. {
  262. return S_OK;
  263. }
  264. else
  265. {
  266. //Note: Don't overwrite the failure point we recorded
  267. // before, since it may have been changed by some
  268. // other thread.
  269. //Don't need to take the critical section here, since
  270. //we don't care about the current failure point.
  271. ULONG ulFailurePointCurrent;
  272. pfi->GetFailureInfo(&ulWaterMark,
  273. &ulFailurePointCurrent);
  274. // all the data is available now
  275. if (ulWaterMark >= ulFailurePoint)
  276. {
  277. //We don't care what the return value is, so send
  278. //STG_S_BLOCK and all sinks will have fOwner == FALSE
  279. _pdacp->NotifySinks(ulWaterMark,
  280. ulFailurePoint,
  281. fAccurate,
  282. STG_S_BLOCK);
  283. break;
  284. }
  285. }
  286. }
  287. }
  288. if ((sc == STG_S_RETRYNOW) ||
  289. (sc == STG_S_BLOCK) ||
  290. (sc == STG_S_MONITORING))
  291. {
  292. return S_OK;
  293. }
  294. else return sc;
  295. }
  296. //+---------------------------------------------------------------------------
  297. //
  298. // Member: CAsyncConnection::GetConnectionInterface, public
  299. //
  300. // Synopsis:
  301. //
  302. // Arguments:
  303. //
  304. // Returns: Appropriate status code
  305. //
  306. // Modifies:
  307. //
  308. // History: 30-Dec-95 SusiA Created
  309. //
  310. // Notes:
  311. //
  312. //----------------------------------------------------------------------------
  313. STDMETHODIMP CAsyncConnection::GetConnectionInterface(IID *pIID)
  314. {
  315. olDebugOut((DEB_ITRACE,
  316. "In CAsyncConnection::GetConnectionInterface:%p()\n",
  317. this));
  318. *pIID = IID_IProgressNotify;
  319. olDebugOut((DEB_ITRACE, "Out CAsyncConnection::GetConnectionInterface\n"));
  320. return S_OK;
  321. }
  322. //+---------------------------------------------------------------------------
  323. //
  324. // Member: CAsyncConnection::GetConnectionPointContainer, public
  325. //
  326. // Synopsis:
  327. //
  328. // Arguments:
  329. //
  330. // Returns: Appropriate status code
  331. //
  332. // Modifies:
  333. //
  334. // History: 30-Dec-95 SusiA Created
  335. //
  336. // Notes:
  337. //
  338. //----------------------------------------------------------------------------
  339. STDMETHODIMP CAsyncConnection::GetConnectionPointContainer(
  340. IConnectionPointContainer ** ppCPC)
  341. {
  342. olDebugOut((DEB_ITRACE,
  343. "In CAsyncConnection::GetConnectionPointContainer:%p()\n",
  344. this));
  345. *ppCPC = _pCPC;
  346. _pCPC->AddRef();
  347. olDebugOut((DEB_ITRACE,
  348. "Out CAsyncConnection::GetConnectionPointContainer\n"));
  349. return S_OK;
  350. }
  351. //+---------------------------------------------------------------------------
  352. //
  353. // Member: CAsyncConnection::EnumConnections, public
  354. //
  355. // Synopsis:
  356. //
  357. // Arguments:
  358. //
  359. // Returns: Appropriate status code
  360. //
  361. // Modifies:
  362. //
  363. // History: 30-Dec-95 SusiA Created
  364. //
  365. // Notes:
  366. //
  367. //----------------------------------------------------------------------------
  368. STDMETHODIMP CAsyncConnection::EnumConnections(
  369. IEnumConnections **ppEnum)
  370. {
  371. olDebugOut((DEB_ITRACE, "In CAsyncConnection::EnumConnections:%p()\n", this));
  372. olDebugOut((DEB_ITRACE, "Out CAsyncConnection::EnumConnections\n"));
  373. return E_NOTIMPL;
  374. }
  375. //+---------------------------------------------------------------------------
  376. //
  377. // Member: CAsyncConnection:: Advise, public
  378. //
  379. // Synopsis:
  380. //
  381. // Arguments:
  382. //
  383. // Returns: Appropriate status code
  384. //
  385. // Modifies:
  386. //
  387. // History: 29-Dec-95 SusiA Created
  388. //
  389. // Notes:
  390. //
  391. //----------------------------------------------------------------------------
  392. STDMETHODIMP CAsyncConnection::Advise(IUnknown *pUnkSink,
  393. DWORD *pdwCookie)
  394. {
  395. SCODE sc;
  396. IProgressNotify *ppnSink;
  397. olDebugOut((DEB_ITRACE, "In CAsyncConnection::Advise:%p()\n", this));
  398. olChk(pUnkSink->QueryInterface(IID_IProgressNotify, (void **)&ppnSink));
  399. sc = _pdacp->AddConnection(ppnSink, pdwCookie);
  400. ppnSink->Release();
  401. olDebugOut((DEB_ITRACE, "Out CAsyncConnection::Advise\n"));
  402. EH_Err:
  403. return sc;
  404. }
  405. //+---------------------------------------------------------------------------
  406. //
  407. // Member: CAsyncConnection::Unadvise, public
  408. //
  409. // Synopsis:
  410. //
  411. // Arguments:
  412. //
  413. // Returns: Appropriate status code
  414. //
  415. // Modifies:
  416. //
  417. // History: 30-Dec-95 SusiA Created
  418. //
  419. // Notes:
  420. //
  421. //----------------------------------------------------------------------------
  422. STDMETHODIMP CAsyncConnection::Unadvise(DWORD dwCookie)
  423. {
  424. SCODE sc;
  425. olDebugOut((DEB_ITRACE, "In CAsyncConnection::Unadvise:%p()\n", this));
  426. sc = _pdacp->RemoveConnection(dwCookie);
  427. olDebugOut((DEB_ITRACE, "Out CAsyncConnection::Unadvise\n"));
  428. return sc;
  429. }
  430. //+---------------------------------------------------------------------------
  431. //
  432. // Member: CAsyncConnectionContainer::EnumConnectionPoints, public
  433. //
  434. // Synopsis: Return enumerator on connection points
  435. //
  436. // Arguments: [ppEnum] -- Return pointer of enumerator
  437. //
  438. // Returns: Appropriate status code
  439. //
  440. // History: 28-Dec-95 SusiA Created
  441. //
  442. //----------------------------------------------------------------------------
  443. STDMETHODIMP CAsyncConnectionContainer::EnumConnectionPoints(
  444. IEnumConnectionPoints **ppEnum)
  445. {
  446. olDebugOut((DEB_ITRACE,
  447. "In CAsyncConnectionContainer::EnumConnectionPoints:%p()\n",
  448. this));
  449. olDebugOut((DEB_ITRACE,
  450. "Out CAsyncConnectionContainer::EnumConnectionPoints\n"));
  451. return E_NOTIMPL;
  452. }
  453. //+---------------------------------------------------------------------------
  454. //
  455. // Member: CAsyncConnectionContainer::FindConnectionPoint, public
  456. //
  457. // Synopsis: Return a connection point given an IID
  458. //
  459. // Arguments: [iid] -- IID to return connection point for
  460. // [ppCP] -- Return location for pointer
  461. //
  462. // Returns: Appropriate status code
  463. //
  464. // History: 28-Dec-95 SusiA Created
  465. //
  466. //----------------------------------------------------------------------------
  467. STDMETHODIMP CAsyncConnectionContainer::FindConnectionPoint(
  468. REFIID iid,
  469. IConnectionPoint **ppCP)
  470. {
  471. olDebugOut((DEB_ITRACE,
  472. "In CAsyncConnectionContainer::FindConnectionPoint:%p()\n",
  473. this));
  474. CAsyncConnection *pcp;
  475. if (IsEqualIID(iid, IID_IProgressNotify))
  476. {
  477. pcp = &_cpoint;
  478. }
  479. else
  480. {
  481. *ppCP = NULL;
  482. return E_NOINTERFACE;
  483. }
  484. pcp->AddRef();
  485. *ppCP = pcp;
  486. olDebugOut((DEB_ITRACE,
  487. "Out CAsyncConnectionContainer::FindConnectionPoint\n"));
  488. return S_OK;
  489. }
  490. //+---------------------------------------------------------------------------
  491. //
  492. // Member: CAsyncConnectionContainer::InitConnection, public
  493. //
  494. // Synopsis:
  495. //
  496. // Arguments:
  497. //
  498. // Returns: Appropriate status code
  499. //
  500. // History: 10-Apr-96 PhilipLa Created
  501. //
  502. // Notes:
  503. //
  504. //----------------------------------------------------------------------------
  505. SCODE CAsyncConnectionContainer::InitConnection(CAsyncConnection *pacParent)
  506. {
  507. return _cpoint.Init(this, pacParent);
  508. }
  509. //+---------------------------------------------------------------------------
  510. //
  511. // Member: CAsyncConnectionContainer::InitClone, public
  512. //
  513. // Synopsis:
  514. //
  515. // Arguments:
  516. //
  517. // Returns: Appropriate status code
  518. //
  519. // History: 10-Apr-96 PhilipLa Created
  520. //
  521. // Notes:
  522. //
  523. //----------------------------------------------------------------------------
  524. SCODE CAsyncConnectionContainer::InitClone(CAsyncConnection *pac)
  525. {
  526. return _cpoint.InitClone(this, pac);
  527. }