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.

1459 lines
37 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: srvhndlr.cpp
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 9-18-95 JohannP Created
  15. // 10-30-96 rogerg Changed to New Embed ServerHandler Model.
  16. //
  17. //----------------------------------------------------------------------------
  18. #include <le2int.h>
  19. #include <ole2int.h>
  20. #include <stdid.hxx> // CStdIdentity
  21. #include <marshal.hxx> // CStdMarshal
  22. #include <idtable.hxx> // Indentity Table
  23. #include <ipidtbl.hxx> // IpidTable.
  24. #include "xmit.hxx"
  25. #include "srvhndlr.h"
  26. #include "clthndlr.h"
  27. #include "defhndlr.h"
  28. extern HRESULT UnMarshalHelper(MInterfacePointer *pIFP, REFIID riid, void **ppv);
  29. extern INTERNAL_(BOOL) ChkIfLocalOID(OBJREF &objref, CStdIdentity **ppStdId);
  30. // TODO: All Marshaling and set up for Run, DoVerb, SetClientSite should be moved
  31. // Into the EmbHelper so all DefHndlr has to do is call the Function as normal.
  32. //+---------------------------------------------------------------------------
  33. //
  34. // Method: CreateEmbeddingServerHandler
  35. //
  36. // Synopsis: Creates a New Instance of the Embedded Server Handler.
  37. //
  38. // Arguments:
  39. // pStdId - Pointer to StandardIdentity for Object
  40. // ppunkESHandler - PlaceHolder to Return the New serverHandler.
  41. //
  42. // Returns: HRESULT
  43. //
  44. // History: 10-30-96 rogerg Created
  45. //
  46. // Notes:
  47. //
  48. //----------------------------------------------------------------------------
  49. HRESULT CreateEmbeddingServerHandler(CStdIdentity *pStdId,IUnknown **ppunkESHandler)
  50. {
  51. *ppunkESHandler = new CServerHandler(pStdId);
  52. return *ppunkESHandler ? NOERROR : E_FAIL;
  53. }
  54. //+---------------------------------------------------------------------------
  55. //
  56. // Method: CServerHandler::CServerHandler
  57. //
  58. // Synopsis: Constructor
  59. //
  60. // Arguments:
  61. // pStdId - Pointer to StandardIdentity for Object
  62. //
  63. // Returns:
  64. //
  65. // History: 10-30-96 rogerg Created
  66. //
  67. // Notes:
  68. //
  69. //----------------------------------------------------------------------------
  70. CServerHandler::CServerHandler(CStdIdentity *pStdid)
  71. {
  72. _cRefs = 1; // this is the first addref for the serverhandler interface
  73. m_pStdId = pStdid;
  74. if (m_pStdId)
  75. m_pStdId->AddRef();
  76. m_pOleEmbServerClientSite = NULL;
  77. m_pCEmbServerClientSite = NULL;
  78. return;
  79. }
  80. //+---------------------------------------------------------------------------
  81. //
  82. // Method: CServerHandler::~CServerHandler
  83. //
  84. // Synopsis: Destructor
  85. //
  86. // Arguments: (none)
  87. //
  88. // Returns:
  89. //
  90. // History: 10-30-96 rogerg Created
  91. //
  92. // Notes:
  93. //
  94. //----------------------------------------------------------------------------
  95. CServerHandler::~CServerHandler()
  96. {
  97. Win4Assert(NULL == m_pStdId);
  98. Win4Assert(NULL == m_pOleEmbServerClientSite);
  99. Win4Assert(NULL == m_pCEmbServerClientSite);
  100. }
  101. //+---------------------------------------------------------------------------
  102. //
  103. // Method: CServerHandler::QueryInterface
  104. //
  105. // Synopsis:
  106. //
  107. // Arguments: [riid] --
  108. // [ppv] --
  109. //
  110. // Returns:
  111. //
  112. // History: 9-18-95 JohannP (Johann Posch) Created
  113. //
  114. // Notes:
  115. //
  116. //----------------------------------------------------------------------------
  117. STDMETHODIMP CServerHandler::QueryInterface( REFIID riid, void **ppv )
  118. {
  119. HRESULT hresult = NOERROR;
  120. VDATEHEAP();
  121. LEDebugOut((DEB_TRACE,
  122. "%p _IN CServerHandler::QueryInterface "
  123. "( %p , %p )\n", this, riid, ppv));
  124. if ( IsEqualIID(riid, IID_IUnknown)
  125. || IsEqualIID(riid, IID_IServerHandler) )
  126. {
  127. *ppv = (void FAR *)this;
  128. AddRef();
  129. }
  130. else
  131. {
  132. hresult = E_NOINTERFACE;
  133. *ppv = NULL;
  134. }
  135. LEDebugOut((DEB_TRACE, "%p OUT CServerHandler::QueryInterface ( %lx ) "
  136. "[ %p ]\n", this, hresult, *ppv));
  137. return hresult;
  138. }
  139. //+---------------------------------------------------------------------------
  140. //
  141. // Method: CServerHandler::AddRef
  142. //
  143. // Synopsis:
  144. //
  145. // Arguments: [void] --
  146. //
  147. // Returns:
  148. //
  149. // History: 9-18-95 JohannP (Johann Posch) Created
  150. //
  151. // Notes:
  152. //
  153. //----------------------------------------------------------------------------
  154. STDMETHODIMP_(ULONG) CServerHandler::AddRef( void )
  155. {
  156. VDATEHEAP();
  157. LEDebugOut((DEB_TRACE, "%p _IN CServerHandler::AddRef ( )\n", this));
  158. InterlockedIncrement((long *)&_cRefs);
  159. LEDebugOut((DEB_TRACE, "%p OUT CServerHandler::AddRef ( %ld ) ", this,
  160. _cRefs));
  161. return _cRefs;
  162. }
  163. //+---------------------------------------------------------------------------
  164. //
  165. // Method: CServerHandler::Release
  166. //
  167. // Synopsis:
  168. //
  169. // Arguments: [void] --
  170. //
  171. // Returns:
  172. //
  173. // History: 9-18-95 JohannP (Johann Posch) Created
  174. //
  175. // Notes:
  176. //
  177. //----------------------------------------------------------------------------
  178. STDMETHODIMP_(ULONG) CServerHandler::Release( void )
  179. {
  180. ULONG cRefs;
  181. VDATEHEAP();
  182. LEDebugOut((DEB_TRACE, "%p _IN CServerHandler::Release ( )\n", this));
  183. if (0 == (cRefs = InterlockedDecrement( (long*) &_cRefs)) )
  184. {
  185. ReleaseObject();
  186. delete this;
  187. return 0;
  188. }
  189. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Release ( %ld ) ", this,
  190. cRefs));
  191. return cRefs;
  192. }
  193. //+---------------------------------------------------------------------------
  194. //
  195. // Method: CServerHandler::ReleaseObject
  196. //
  197. // Synopsis: Releases any references on StdIdentity or Real Object.
  198. //
  199. // Arguments: (none)
  200. //
  201. //
  202. // Returns:
  203. //
  204. // History: 10-30-96 rogerg Created
  205. //
  206. // Notes:
  207. //
  208. //----------------------------------------------------------------------------
  209. STDMETHODIMP_(void) CServerHandler::ReleaseObject()
  210. {
  211. LPUNKNOWN lpUnkForSafeRelease;
  212. LEDebugOut((DEB_TRACE, "%p _IN CServerHandler::ReleaseObject ( )\n", this));
  213. if (m_pOleEmbServerClientSite)
  214. {
  215. lpUnkForSafeRelease = (LPUNKNOWN) m_pOleEmbServerClientSite;
  216. m_pOleEmbServerClientSite = NULL;
  217. lpUnkForSafeRelease->Release();
  218. }
  219. if (m_pCEmbServerClientSite)
  220. {
  221. CEmbServerClientSite *pEmbServerClientSite = m_pCEmbServerClientSite;
  222. m_pCEmbServerClientSite = NULL;
  223. pEmbServerClientSite->Release();
  224. }
  225. if (m_pStdId)
  226. {
  227. CStdIdentity* pUnkObj = m_pStdId;
  228. m_pStdId = NULL;
  229. pUnkObj->Release();
  230. }
  231. LEDebugOut((DEB_TRACE, "%p _Out CServerHandler::ReleaseObject ( )\n", this));
  232. }
  233. //+---------------------------------------------------------------------------
  234. //
  235. // Method: CServerHandler::QueryServerInterface
  236. //
  237. // Synopsis: Gets Requested Interface from the Server.
  238. //
  239. // Arguments:
  240. //
  241. //
  242. // Returns:
  243. //
  244. // History: 10-30-96 rogerg Created
  245. //
  246. // Notes:
  247. //
  248. //----------------------------------------------------------------------------
  249. INTERNAL CServerHandler::QueryServerInterface(REFIID riid,void ** ppInterface)
  250. {
  251. IPIDEntry *pIPIDEntry;
  252. HRESULT hrDisconnect;
  253. HRESULT hr = E_NOINTERFACE;
  254. // TODO: Other option is for Stdid to hold onto EmbServerHandler and then has the Stdid
  255. // Call ReleaseObject, Release on the EmbServerHandler in its when the real server object
  256. // is being released or Disconnected. This option should be tried and if it works would
  257. // be preferred.
  258. if (m_pStdId)
  259. {
  260. LOCK(gComLock);
  261. m_pStdId->LockServer();
  262. if (SUCCEEDED(hr = m_pStdId->FindIPIDEntry(riid,&pIPIDEntry)) )
  263. {
  264. UNLOCK(gComLock);
  265. }
  266. else
  267. {
  268. hrDisconnect = m_pStdId->PreventDisconnect();
  269. if (SUCCEEDED(hrDisconnect))
  270. {
  271. hr = m_pStdId->MarshalIPID(riid,1 /*cRefs */,MSHLFLAGS_NORMAL, &pIPIDEntry);
  272. if (SUCCEEDED(hr))
  273. {
  274. m_pStdId->DecSrvIPIDCnt(pIPIDEntry,1, 0, NULL, MSHLFLAGS_NORMAL); // release Marshaled Ipid.
  275. }
  276. }
  277. UNLOCK(gComLock);
  278. m_pStdId->HandlePendingDisconnect(hrDisconnect);
  279. }
  280. if ( FAILED(hr) || (IPIDF_DISCONNECTED & pIPIDEntry->dwFlags) )
  281. {
  282. m_pStdId->UnLockServer();
  283. hr = (NOERROR == hr) ? RPC_E_DISCONNECTED : E_NOINTERFACE;
  284. *ppInterface = NULL;
  285. }
  286. else
  287. {
  288. *ppInterface = pIPIDEntry->pv;
  289. }
  290. }
  291. ASSERT_LOCK_NOT_HELD(gComLock);
  292. return hr;
  293. }
  294. //+---------------------------------------------------------------------------
  295. //
  296. // Method: CServerHandler::ReleaseServerInterface
  297. //
  298. // Synopsis: Releases Lock in Interface obtained from QueryServerInterface
  299. //
  300. // Arguments:
  301. //
  302. //
  303. // Returns:
  304. //
  305. // History: 10-30-96 rogerg Created
  306. //
  307. // Notes:
  308. //
  309. //----------------------------------------------------------------------------
  310. INTERNAL CServerHandler::ReleaseServerInterface(void * pInterface)
  311. {
  312. if (m_pStdId)
  313. {
  314. m_pStdId->UnLockServer();
  315. }
  316. return NOERROR;
  317. }
  318. //+---------------------------------------------------------------------------
  319. //
  320. // Method: CServerHandler::Run
  321. //
  322. // Synopsis: Server Handler side of invoked when ::Run is Called.
  323. //
  324. // Arguments:
  325. //
  326. //
  327. // Returns:
  328. //
  329. // Comments: To be as identical to the ::Run in the Defhndlr as possible
  330. // ::Run ignores errors if it fails to get the Interfaces and also
  331. // any error value that is returned from ::SetClientSite.
  332. //
  333. // History: 10-30-96 rogerg Created
  334. //
  335. // Notes:
  336. //
  337. //----------------------------------------------------------------------------
  338. STDMETHODIMP CServerHandler::Run(DWORD dwDHFlags,
  339. REFIID riidClientInterface,
  340. MInterfacePointer* pIRDClientInterface,
  341. BOOL fHasIPSite,
  342. LPOLESTR szContainerApp,
  343. LPOLESTR szContainerObj,
  344. IStorage * pStg,
  345. IAdviseSink* pAdvSink,
  346. DWORD *pdwConnection,
  347. HRESULT *hresultClsidUser,
  348. CLSID *pContClassID,
  349. HRESULT *hresultContentMiscStatus,
  350. DWORD *pdwMiscStatus)
  351. {
  352. IPersistStorage *pIStorage = NULL;
  353. IOleObject *pIOleObject = NULL;
  354. HRESULT hresult = NOERROR;
  355. LEDebugOut((DEB_TRACE, "%p _IN CServerHandler::Run\n", this));
  356. *pdwConnection = 0; // make sure dwConnection is 0 on an error.
  357. QueryServerInterface(IID_IOleObject,(void **) &pIOleObject);
  358. if (pStg && (NOERROR == QueryServerInterface(IID_IPersistStorage,(void **) &pIStorage)) )
  359. {
  360. Win4Assert(pIStorage);
  361. if (DH_INIT_NEW & dwDHFlags)
  362. {
  363. hresult = pIStorage->InitNew(pStg);
  364. }
  365. else
  366. {
  367. hresult = pIStorage->Load(pStg);
  368. }
  369. }
  370. Win4Assert(NULL == m_pOleEmbServerClientSite);
  371. if ( (NOERROR == hresult) && pIRDClientInterface && pIOleObject)
  372. {
  373. hresult = GetClientSiteFromMInterfacePtr(riidClientInterface,pIRDClientInterface,fHasIPSite,&m_pOleEmbServerClientSite);
  374. if (SUCCEEDED(hresult))
  375. {
  376. hresult = pIOleObject->SetClientSite(m_pOleEmbServerClientSite);
  377. }
  378. hresult = NOERROR; // !!! don't fail on SetClientSite Failure.
  379. }
  380. if ((NOERROR == hresult) && (NULL != szContainerApp) && pIOleObject)
  381. {
  382. hresult = pIOleObject->SetHostNames(szContainerApp,szContainerObj);
  383. }
  384. if ( (NOERROR == hresult) && pAdvSink && pIOleObject )
  385. {
  386. hresult = pIOleObject->Advise(pAdvSink,pdwConnection);
  387. }
  388. if ( (NOERROR == hresult) && pIOleObject )
  389. {
  390. *hresultClsidUser = pIOleObject->GetUserClassID(pContClassID);
  391. *hresultContentMiscStatus = pIOleObject->GetMiscStatus(DVASPECT_CONTENT,pdwMiscStatus);
  392. }
  393. // m_pOleEmbServerClientSite gets set by SetClientSite called above.
  394. if ( (NOERROR == hresult) && (m_pOleEmbServerClientSite) && pIOleObject)
  395. {
  396. LPMONIKER pmk = NULL;
  397. if( m_pOleEmbServerClientSite->GetMoniker
  398. (OLEGETMONIKER_ONLYIFTHERE,
  399. OLEWHICHMK_OBJREL, &pmk) == NOERROR)
  400. {
  401. AssertOutPtrIface(NOERROR, pmk);
  402. // SetMoniker Failure doesn't result in a ::Run Failure
  403. pIOleObject->SetMoniker(OLEWHICHMK_OBJREL, pmk);
  404. pmk->Release();
  405. }
  406. }
  407. if (pIStorage)
  408. ReleaseServerInterface((void *) pIStorage);
  409. if (pIOleObject)
  410. ReleaseServerInterface((void *) pIOleObject);
  411. LEDebugOut((DEB_TRACE, "%p OUT CServerHandler::Run "
  412. "( %lx )\n", this, hresult));
  413. return hresult;
  414. }
  415. //+---------------------------------------------------------------------------
  416. //
  417. // Method: CServerHandler::DoVerb
  418. //
  419. // Synopsis: Server Handler side of invoked when ::DoVerb is Called.
  420. //
  421. // Arguments:
  422. //
  423. //
  424. // Returns:
  425. //
  426. // History: 10-30-96 rogerg Created
  427. //
  428. // Notes:
  429. //
  430. //----------------------------------------------------------------------------
  431. STDMETHODIMP CServerHandler::DoVerb (LONG iVerb, LPMSG lpmsg,BOOL fUseRunClientSite, IOleClientSite* pIOleClientSite,
  432. LONG lindex,HWND hwndParent,LPCRECT lprcPosRect)
  433. {
  434. IOleObject *pIOleObject = NULL;
  435. IOleClientSite *pDoVerbClientSite = NULL;
  436. HRESULT hr = NOERROR;
  437. LEDebugOut((DEB_TRACE, "%p _IN CServerHandler::DoVerb "
  438. "( %ld , %p , %p , %ld , %lx , %p )\n", this,
  439. iVerb, lpmsg, pIOleClientSite, lindex, hwndParent, lprcPosRect));
  440. if (NOERROR == (hr = QueryServerInterface(IID_IOleObject,(void **) &pIOleObject)) )
  441. {
  442. Win4Assert(pIOleObject);
  443. if (fUseRunClientSite)
  444. {
  445. pDoVerbClientSite = m_pOleEmbServerClientSite;
  446. // inform client site of operation what interfaces to support
  447. // Todo: Send in Prefetched info for DoVerb here.
  448. if (m_pCEmbServerClientSite)
  449. {
  450. m_pCEmbServerClientSite->SetDoVerbState(TRUE);
  451. }
  452. // put addref on Clientsite so liveness is the same as if marshaled by DoVerb
  453. // TODO: This isn't really necessayr since Handler also holds a ref.
  454. if (m_pOleEmbServerClientSite)
  455. {
  456. m_pOleEmbServerClientSite->AddRef();
  457. }
  458. }
  459. else
  460. {
  461. pDoVerbClientSite = pIOleClientSite;
  462. }
  463. hr = pIOleObject->DoVerb(iVerb,lpmsg,pDoVerbClientSite,lindex,hwndParent,lprcPosRect);
  464. if (fUseRunClientSite)
  465. {
  466. if (m_pCEmbServerClientSite)
  467. {
  468. m_pCEmbServerClientSite->SetDoVerbState(FALSE);
  469. }
  470. if (m_pOleEmbServerClientSite)
  471. {
  472. m_pOleEmbServerClientSite->Release();
  473. }
  474. }
  475. }
  476. if (pIOleObject)
  477. ReleaseServerInterface((void *) pIOleObject);
  478. LEDebugOut((DEB_TRACE, "%p OUT CServerHandler::Run "
  479. "( %lx )\n", this, hr));
  480. return hr;
  481. }
  482. // helper function for creating ClientSite Handler
  483. INTERNAL CServerHandler::GetClientSiteFromMInterfacePtr(REFIID riidClientInterface,
  484. MInterfacePointer* pIRDClientSite, BOOL fHasIPSite, LPOLECLIENTSITE* ppOleClientSite)
  485. {
  486. HRESULT hr = E_UNEXPECTED;
  487. *ppOleClientSite = NULL;
  488. Win4Assert(NULL != pIRDClientSite);
  489. if (pIRDClientSite)
  490. {
  491. CXmitRpcStream Stm( (InterfaceData *) pIRDClientSite);
  492. if (IsEqualIID(IID_IClientSiteHandler,riidClientInterface))
  493. {
  494. OBJREF objref;
  495. CEmbServerClientSite *pCEmbServerClientSite;
  496. // If there is a ClientSide Handler, set up server side.
  497. if (SUCCEEDED(hr = ReadObjRef(&Stm, objref)))
  498. {
  499. Win4Assert(IsEqualIID(objref.iid, IID_IClientSiteHandler));
  500. pCEmbServerClientSite = new CEmbServerClientSite(NULL);
  501. if (pCEmbServerClientSite)
  502. {
  503. if (NOERROR == (hr = pCEmbServerClientSite->Initialize(objref,fHasIPSite)))
  504. {
  505. m_pCEmbServerClientSite = pCEmbServerClientSite; // set up member variable.
  506. // TODO: should be a QI for the ClientSite.
  507. *ppOleClientSite = (LPOLECLIENTSITE) pCEmbServerClientSite;
  508. (*ppOleClientSite)->AddRef();
  509. }
  510. else
  511. {
  512. pCEmbServerClientSite->Release();
  513. }
  514. }
  515. FreeObjRef(objref);
  516. }
  517. }
  518. else
  519. {
  520. m_pCEmbServerClientSite = NULL; // make sure EmbClientSite member var is NULL.
  521. // Didn't wrap ClientSite with ClientSiteHandler, just UnMarshal and hand back.
  522. hr = CoUnmarshalInterface(&Stm,IID_IOleClientSite, (void **) ppOleClientSite);
  523. if (FAILED(hr))
  524. {
  525. *ppOleClientSite = NULL;
  526. }
  527. }
  528. }
  529. return hr;
  530. }
  531. //+-------------------------------------------------------------------------
  532. //
  533. // Member: CServerHandler::SetClientSite
  534. //
  535. // Synopsis: Sets the client site for the object
  536. //
  537. // Effects:
  538. //
  539. // Arguments: [pClientSite] -- pointer to the client site
  540. //
  541. // Requires:
  542. //
  543. // Returns: HRESULT
  544. //
  545. //--------------------------------------------------------------------------
  546. STDMETHODIMP CServerHandler::SetClientSite(IOleClientSite* pOleClientSite)
  547. {
  548. HRESULT hresult = NOERROR;
  549. IOleObject *pIOleObject = NULL;
  550. if (NOERROR == (hresult = QueryServerInterface(IID_IOleObject,(void **) &pIOleObject)) )
  551. {
  552. if (NOERROR == hresult)
  553. {
  554. hresult = pIOleObject->SetClientSite(pOleClientSite);
  555. }
  556. }
  557. if (pIOleObject)
  558. ReleaseServerInterface(pIOleObject);
  559. return hresult;
  560. }
  561. //+---------------------------------------------------------------------------
  562. //
  563. // Function: Delagatory IDataObject impl facing container
  564. //
  565. // Synopsis:
  566. //
  567. // Arguments:
  568. //
  569. // Returns:
  570. //
  571. // History: 11-17-95 JohannP (Johann Posch) Created
  572. //
  573. // Notes:
  574. //
  575. //+---------------------------------------------------------------------------
  576. STDMETHODIMP CServerHandler::GetData(FORMATETC *pformatetcIn,STGMEDIUM *pmedium)
  577. {
  578. LPDATAOBJECT pDataObject = NULL;
  579. HRESULT hr;
  580. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  581. {
  582. hr = pDataObject->GetData(pformatetcIn,pmedium);
  583. ReleaseServerInterface(pDataObject);
  584. }
  585. return hr;
  586. }
  587. STDMETHODIMP CServerHandler::GetDataHere(FORMATETC *pformatetc,STGMEDIUM *pmedium)
  588. {
  589. LPDATAOBJECT pDataObject = NULL;
  590. HRESULT hr;
  591. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  592. {
  593. hr = pDataObject->GetDataHere(pformatetc,pmedium);
  594. ReleaseServerInterface(pDataObject);
  595. }
  596. return hr;
  597. }
  598. STDMETHODIMP CServerHandler::QueryGetData(FORMATETC *pformatetc)
  599. {
  600. LPDATAOBJECT pDataObject = NULL;
  601. HRESULT hr;
  602. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  603. {
  604. hr = pDataObject->QueryGetData(pformatetc);
  605. ReleaseServerInterface(pDataObject);
  606. }
  607. return hr;
  608. }
  609. STDMETHODIMP CServerHandler::GetCanonicalFormatEtc(FORMATETC *pformatetcIn,FORMATETC *pformatetcOut)
  610. {
  611. LPDATAOBJECT pDataObject = NULL;
  612. HRESULT hr;
  613. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  614. {
  615. hr = pDataObject->GetCanonicalFormatEtc(pformatetcIn,pformatetcOut);
  616. ReleaseServerInterface(pDataObject);
  617. }
  618. return hr;
  619. }
  620. STDMETHODIMP CServerHandler::SetData(FORMATETC *pformatetc,STGMEDIUM *pmedium,BOOL fRelease)
  621. {
  622. LPDATAOBJECT pDataObject = NULL;
  623. HRESULT hr;
  624. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  625. {
  626. hr = pDataObject->SetData(pformatetc,pmedium,fRelease);
  627. ReleaseServerInterface(pDataObject);
  628. }
  629. return hr;
  630. }
  631. STDMETHODIMP CServerHandler::EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC **ppenumFormatEtc)
  632. {
  633. LPDATAOBJECT pDataObject = NULL;
  634. HRESULT hr;
  635. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  636. {
  637. hr = pDataObject->EnumFormatEtc(dwDirection,ppenumFormatEtc);
  638. ReleaseServerInterface(pDataObject);
  639. }
  640. return hr;
  641. }
  642. STDMETHODIMP CServerHandler::DAdvise(FORMATETC *pformatetc,DWORD advf, IAdviseSink *pAdvSink,
  643. DWORD *pdwConnection)
  644. {
  645. LPDATAOBJECT pDataObject = NULL;
  646. HRESULT hr;
  647. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  648. {
  649. hr = pDataObject->DAdvise(pformatetc,
  650. advf, (IAdviseSink *)
  651. pAdvSink,pdwConnection);
  652. ReleaseServerInterface(pDataObject);
  653. }
  654. return hr;
  655. }
  656. STDMETHODIMP CServerHandler::DUnadvise(DWORD dwConnection)
  657. {
  658. LPDATAOBJECT pDataObject = NULL;
  659. HRESULT hr;
  660. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  661. {
  662. hr = pDataObject->DUnadvise(dwConnection);
  663. ReleaseServerInterface(pDataObject);
  664. }
  665. return hr;
  666. }
  667. STDMETHODIMP CServerHandler::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
  668. {
  669. LPDATAOBJECT pDataObject = NULL;
  670. HRESULT hr;
  671. if (NOERROR == (hr = QueryServerInterface(IID_IDataObject,(void **) &pDataObject)) )
  672. {
  673. hr = pDataObject->EnumDAdvise(ppenumAdvise);
  674. ReleaseServerInterface(pDataObject);
  675. }
  676. return hr;
  677. }
  678. //////////////////////
  679. // rogerg, wrapper object for ServerHandler on the ClientSide.
  680. //////////////////////
  681. // CEmbServerWrapper implementation for Server Handler.
  682. CEmbServerWrapper* CreateEmbServerWrapper(IUnknown *pUnkOuter,IServerHandler *ServerHandler)
  683. {
  684. return new CEmbServerWrapper(pUnkOuter,ServerHandler);
  685. }
  686. //+---------------------------------------------------------------------------
  687. //
  688. // Method: CEmbServerWrapper::CEmbServerWrapper
  689. //
  690. // Synopsis: Constructor
  691. //
  692. // Arguments:
  693. // pStdId - Pointer to StandardIdentity for Object
  694. //
  695. // Returns:
  696. //
  697. // History: 10-30-96 rogerg Created
  698. //
  699. // Notes:
  700. //
  701. //----------------------------------------------------------------------------
  702. CEmbServerWrapper::CEmbServerWrapper (IUnknown *pUnkOuter,IServerHandler *pServerHandler)
  703. {
  704. VDATEHEAP();
  705. Win4Assert(pServerHandler);
  706. if (!pUnkOuter)
  707. {
  708. pUnkOuter = &m_Unknown;
  709. }
  710. m_pUnkOuter = pUnkOuter;
  711. m_Unknown.m_EmbServerWrapper = this;
  712. if(pServerHandler)
  713. {
  714. m_ServerHandler = pServerHandler;
  715. m_ServerHandler->AddRef();
  716. }
  717. m_cRefs = 1;
  718. }
  719. //+---------------------------------------------------------------------------
  720. //
  721. // Method: CServerHandler::~CServerHandler
  722. //
  723. // Synopsis: Destructor
  724. //
  725. // Arguments: (none)
  726. //
  727. // Returns:
  728. //
  729. // History: 10-30-96 rogerg Created
  730. //
  731. // Notes:
  732. //
  733. //----------------------------------------------------------------------------
  734. CEmbServerWrapper::~CEmbServerWrapper()
  735. {
  736. Win4Assert(NULL == m_ServerHandler);
  737. }
  738. //+-------------------------------------------------------------------------
  739. //
  740. // Member: CEmbServerWrapper::CPrivUnknown::QueryInterface
  741. //
  742. // Synopsis: Returns a pointer to one of the supported interfaces.
  743. //
  744. // Effects:
  745. //
  746. // Arguments: [iid] -- the requested interface ID
  747. // [ppv] -- where to put the iface pointer
  748. //
  749. // Requires:
  750. //
  751. // Returns: HRESULT
  752. //
  753. // History: 10-30-96 rogerg Created
  754. //
  755. // Notes:
  756. //
  757. //--------------------------------------------------------------------------
  758. STDMETHODIMP CEmbServerWrapper::CPrivUnknown::QueryInterface(REFIID iid,
  759. LPLPVOID ppv)
  760. {
  761. HRESULT hresult;
  762. VDATEHEAP();
  763. Win4Assert(m_EmbServerWrapper);
  764. LEDebugOut((DEB_TRACE,
  765. "%p _IN CDefObject::CUnknownImpl::QueryInterface "
  766. "( %p , %p )\n", m_EmbServerWrapper, iid, ppv));
  767. if (IsEqualIID(iid, IID_IUnknown))
  768. {
  769. *ppv = (void FAR *)this;
  770. }
  771. else if (IsEqualIID(iid, IID_IDataObject))
  772. {
  773. *ppv = (void FAR *)(IDataObject *) m_EmbServerWrapper;
  774. }
  775. else if(m_EmbServerWrapper->m_ServerHandler)
  776. {
  777. Win4Assert(0 && "QI for non-Wrapped interface");
  778. hresult = m_EmbServerWrapper->m_ServerHandler->QueryInterface(iid,(void **) ppv);
  779. LEDebugOut((DEB_TRACE,
  780. "%p OUT CDefObject::CUnknownImpl::QueryInterface "
  781. "( %lx ) [ %p ]\n", m_EmbServerWrapper, hresult,
  782. (ppv) ? *ppv : 0 ));
  783. return hresult;
  784. }
  785. else
  786. {
  787. // Don't have a ServerHandler.
  788. *ppv = NULL;
  789. LEDebugOut((DEB_TRACE,
  790. "%p OUT CDefObject::CUnkownImpl::QueryInterface "
  791. "( %lx ) [ %p ]\n", m_EmbServerWrapper, CO_E_OBJNOTCONNECTED,
  792. 0 ));
  793. return E_NOINTERFACE;
  794. }
  795. // this indirection is important since there are different
  796. // implementationsof AddRef (this unk and the others).
  797. ((IUnknown FAR*) *ppv)->AddRef();
  798. LEDebugOut((DEB_TRACE,
  799. "%p OUT CDefObject::CUnknownImpl::QueryInterface "
  800. "( %lx ) [ %p ]\n", m_EmbServerWrapper, NOERROR, *ppv));
  801. return NOERROR;
  802. }
  803. //+-------------------------------------------------------------------------
  804. //
  805. // Member: CEmbServerWrapper::CPrivUnknown::AddRef
  806. //
  807. // Synopsis: Increments the reference count.
  808. //
  809. // Effects:
  810. //
  811. // Arguments: void
  812. //
  813. // Requires:
  814. //
  815. // Returns: ULONG (the new reference count)
  816. //
  817. // Signals:
  818. //
  819. // Modifies:
  820. //
  821. // Derivation: IUnkown
  822. //
  823. // Algorithm:
  824. //
  825. // History: dd-mmm-yy Author Comment
  826. // 03-Nov-93 alexgo 32bit port
  827. //
  828. // Notes:
  829. //
  830. //--------------------------------------------------------------------------
  831. STDMETHODIMP_(ULONG) CEmbServerWrapper::CPrivUnknown::AddRef( void )
  832. {
  833. ULONG cRefs;
  834. VDATEHEAP();
  835. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CPrivUnknown::AddRef "
  836. "( )\n", m_EmbServerWrapper));
  837. Win4Assert(m_EmbServerWrapper->m_cRefs != 0);
  838. Win4Assert(m_EmbServerWrapper);
  839. // we need to keep track of the hander's reference count separately
  840. // from the handler/advise sink combination in order to handle
  841. // our running/stopped state transitions.
  842. cRefs = InterlockedIncrement((long *) &(m_EmbServerWrapper->m_cRefs));
  843. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CPrivUnknown::AddRef "
  844. "( %lu )\n", m_EmbServerWrapper, m_EmbServerWrapper->m_cRefs));
  845. return cRefs;
  846. }
  847. //+-------------------------------------------------------------------------
  848. //
  849. // Member: CEmbServerWrapper::CPrivUnknown::Release
  850. //
  851. // Synopsis: Decrements the ref count, cleaning up and deleting the
  852. // object if necessary
  853. //
  854. // Effects: May delete the object (and potentially objects to which the
  855. // handler has pointer)
  856. //
  857. // Arguments: void
  858. //
  859. // Requires:
  860. //
  861. // Returns: ULONG--the new ref count
  862. //
  863. // Signals:
  864. //
  865. // Modifies:
  866. //
  867. // Derivation:
  868. //
  869. // Algorithm:
  870. //
  871. // History: dd-mmm-yy Author Comment
  872. // 03-Nov-93 alexgo 32bit port
  873. //
  874. // Notes:
  875. //
  876. //--------------------------------------------------------------------------
  877. STDMETHODIMP_(ULONG) CEmbServerWrapper::CPrivUnknown::Release( void )
  878. {
  879. VDATEHEAP();
  880. ULONG refcount;
  881. Win4Assert(m_EmbServerWrapper);
  882. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CPrivUnknown::Release "
  883. "( )\n", m_EmbServerWrapper));
  884. refcount = InterlockedDecrement((long *) &(m_EmbServerWrapper->m_cRefs));
  885. if (0 == refcount)
  886. {
  887. if (m_EmbServerWrapper->m_ServerHandler)
  888. {
  889. IServerHandler *pServerHandler = m_EmbServerWrapper->m_ServerHandler;
  890. m_EmbServerWrapper->m_ServerHandler = NULL;
  891. pServerHandler->Release();
  892. }
  893. delete m_EmbServerWrapper;
  894. }
  895. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CPrivUnknown::Release "
  896. "( %lu )\n", m_EmbServerWrapper, refcount));
  897. return refcount;
  898. }
  899. //+---------------------------------------------------------------------------
  900. //
  901. // Method: CEmbServerWrapper::QueryInterface
  902. //
  903. // Synopsis:
  904. //
  905. // Arguments: [riid] --
  906. // [ppv] --
  907. //
  908. // Returns:
  909. //
  910. // History: 9-18-95 JohannP (Johann Posch) Created
  911. //
  912. // Notes:
  913. //
  914. //----------------------------------------------------------------------------
  915. STDMETHODIMP CEmbServerWrapper::QueryInterface( REFIID riid, void **ppv )
  916. {
  917. HRESULT hresult;
  918. VDATEHEAP();
  919. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::QueryInterface ( %lx , "
  920. "%p )\n", this, riid, ppv));
  921. Assert(m_pUnkOuter);
  922. hresult = m_pUnkOuter->QueryInterface(riid, ppv);
  923. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::QueryInterface ( %lx ) "
  924. "[ %p ]\n", this, hresult, *ppv));
  925. return hresult;
  926. }
  927. //+---------------------------------------------------------------------------
  928. //
  929. // Method: CEmbServerWrapper::AddRef
  930. //
  931. // Synopsis:
  932. //
  933. // Arguments: [void] --
  934. //
  935. // Returns:
  936. //
  937. // History: 9-18-95 JohannP (Johann Posch) Created
  938. //
  939. // Notes:
  940. //
  941. //----------------------------------------------------------------------------
  942. STDMETHODIMP_(ULONG) CEmbServerWrapper::AddRef( void )
  943. {
  944. ULONG crefs;;
  945. VDATEHEAP();
  946. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::AddRef ( )\n", this));
  947. Assert(m_pUnkOuter);
  948. crefs = m_pUnkOuter->AddRef();
  949. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::AddRef ( %ld ) ", this,
  950. crefs));
  951. return crefs;
  952. }
  953. //+---------------------------------------------------------------------------
  954. //
  955. // Method: CEmbServerClientSite::Release
  956. //
  957. // Synopsis:
  958. //
  959. // Arguments: [void] --
  960. //
  961. // Returns:
  962. //
  963. // History: 9-18-95 JohannP (Johann Posch) Created
  964. //
  965. // Notes:
  966. //
  967. //----------------------------------------------------------------------------
  968. STDMETHODIMP_(ULONG) CEmbServerWrapper::Release( void )
  969. {
  970. ULONG crefs;;
  971. VDATEHEAP();
  972. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Release ( )\n", this));
  973. Assert(m_pUnkOuter);
  974. crefs = m_pUnkOuter->Release();
  975. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Release ( %ld ) ", this,
  976. crefs));
  977. return crefs;
  978. }
  979. // IServerHandler Implementation
  980. //+---------------------------------------------------------------------------
  981. //
  982. // Method: CServerHandler::Run
  983. //
  984. // Synopsis: Server Handler side of invoked when ::Run is Called.
  985. //
  986. // Arguments:
  987. //
  988. //
  989. // Returns:
  990. //
  991. // History: 10-30-96 rogerg Created
  992. //
  993. // Notes:
  994. //
  995. //----------------------------------------------------------------------------
  996. STDMETHODIMP CEmbServerWrapper::Run(DWORD dwDHFlags,
  997. REFIID riidClientInterface,
  998. MInterfacePointer* pIRDClientInterface,
  999. BOOL fHasIPSite,
  1000. LPOLESTR szContainerApp,
  1001. LPOLESTR szContainerObj,
  1002. IStorage * pStg,
  1003. IAdviseSink* pAdvSink,
  1004. DWORD *pdwConnection,
  1005. HRESULT *hresultClsidUser,
  1006. CLSID *pContClassID,
  1007. HRESULT *hresultContentMiscStatus,
  1008. DWORD *pdwMiscStatus)
  1009. {
  1010. HRESULT hresult = RPC_E_DISCONNECTED;
  1011. Win4Assert(m_ServerHandler);
  1012. if (m_ServerHandler)
  1013. {
  1014. hresult = m_ServerHandler->Run(dwDHFlags,riidClientInterface,pIRDClientInterface, fHasIPSite, szContainerApp,
  1015. szContainerObj,pStg,pAdvSink,pdwConnection,
  1016. hresultClsidUser,pContClassID,hresultContentMiscStatus,
  1017. pdwMiscStatus);
  1018. }
  1019. return hresult;
  1020. }
  1021. //+---------------------------------------------------------------------------
  1022. //
  1023. // Method: CServerHandler::DoVerb
  1024. //
  1025. // Synopsis: Server Handler side of invoked when ::DoVerb is Called.
  1026. //
  1027. // Arguments:
  1028. //
  1029. //
  1030. // Returns:
  1031. //
  1032. // History: 10-30-96 rogerg Created
  1033. //
  1034. // Notes:
  1035. //
  1036. //----------------------------------------------------------------------------
  1037. STDMETHODIMP CEmbServerWrapper::DoVerb (LONG iVerb, LPMSG lpmsg,BOOL fUseRunClientSite,
  1038. IOleClientSite* pIRDClientSite,LONG lindex,HWND hwndParent,
  1039. LPCRECT lprcPosRect)
  1040. {
  1041. HRESULT hresult = RPC_E_DISCONNECTED;
  1042. Win4Assert(m_ServerHandler);
  1043. if (m_ServerHandler)
  1044. {
  1045. hresult = m_ServerHandler->DoVerb(iVerb,lpmsg,fUseRunClientSite,pIRDClientSite,
  1046. lindex,hwndParent,lprcPosRect);
  1047. }
  1048. return hresult;
  1049. }
  1050. //+-------------------------------------------------------------------------
  1051. //
  1052. // Member: CServerHandler::SetClientSite
  1053. //
  1054. // Synopsis: Sets the client site for the object
  1055. //
  1056. // Effects:
  1057. //
  1058. // Arguments: [pClientSite] -- pointer to the client site
  1059. //
  1060. // Requires:
  1061. //
  1062. // Returns: HRESULT
  1063. //
  1064. //--------------------------------------------------------------------------
  1065. STDMETHODIMP CEmbServerWrapper::SetClientSite(IOleClientSite* pOleClientSite)
  1066. {
  1067. HRESULT hresult = RPC_E_DISCONNECTED;
  1068. Win4Assert(m_ServerHandler);
  1069. if (m_ServerHandler)
  1070. {
  1071. hresult = m_ServerHandler->SetClientSite(pOleClientSite);
  1072. }
  1073. return hresult;
  1074. }
  1075. // IDataObject implementation.
  1076. STDMETHODIMP CEmbServerWrapper::GetData(FORMATETC *pformatetcIn,STGMEDIUM *pmedium)
  1077. {
  1078. HRESULT hresult = RPC_E_DISCONNECTED;
  1079. Win4Assert(m_ServerHandler);
  1080. if (m_ServerHandler)
  1081. {
  1082. hresult = m_ServerHandler->GetData(pformatetcIn,pmedium);
  1083. }
  1084. return hresult;
  1085. }
  1086. STDMETHODIMP CEmbServerWrapper::GetDataHere(FORMATETC *pformatetc,STGMEDIUM *pmedium)
  1087. {
  1088. HRESULT hresult = RPC_E_DISCONNECTED;
  1089. Win4Assert(m_ServerHandler);
  1090. if (m_ServerHandler)
  1091. {
  1092. hresult = m_ServerHandler->GetDataHere(pformatetc,pmedium);
  1093. }
  1094. return hresult;
  1095. }
  1096. STDMETHODIMP CEmbServerWrapper::QueryGetData(FORMATETC *pformatetc)
  1097. {
  1098. HRESULT hresult = RPC_E_DISCONNECTED;
  1099. Win4Assert(m_ServerHandler);
  1100. if (m_ServerHandler)
  1101. {
  1102. hresult = m_ServerHandler->QueryGetData(pformatetc);
  1103. }
  1104. return hresult;
  1105. }
  1106. STDMETHODIMP CEmbServerWrapper::GetCanonicalFormatEtc(FORMATETC *pformatetcIn,FORMATETC *pformatetcOut)
  1107. {
  1108. HRESULT hresult = RPC_E_DISCONNECTED;
  1109. Win4Assert(m_ServerHandler);
  1110. return m_ServerHandler->GetCanonicalFormatEtc(pformatetcIn,pformatetcOut);
  1111. }
  1112. STDMETHODIMP CEmbServerWrapper::SetData(FORMATETC *pformatetc,STGMEDIUM *pmedium,BOOL fRelease)
  1113. {
  1114. HRESULT hresult = RPC_E_DISCONNECTED;
  1115. Win4Assert(m_ServerHandler);
  1116. if (m_ServerHandler)
  1117. {
  1118. hresult = m_ServerHandler->SetData(pformatetc,pmedium,fRelease);
  1119. }
  1120. return hresult;
  1121. }
  1122. STDMETHODIMP CEmbServerWrapper::EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC **ppenumFormatEtc)
  1123. {
  1124. HRESULT hresult = RPC_E_DISCONNECTED;
  1125. Win4Assert(m_ServerHandler);
  1126. if (m_ServerHandler)
  1127. {
  1128. hresult = m_ServerHandler->EnumFormatEtc(dwDirection,ppenumFormatEtc);
  1129. }
  1130. return hresult;
  1131. }
  1132. STDMETHODIMP CEmbServerWrapper::DAdvise(FORMATETC *pformatetc,DWORD advf,
  1133. IAdviseSink *pAdvSink,DWORD *pdwConnection)
  1134. {
  1135. HRESULT hresult = RPC_E_DISCONNECTED;
  1136. Win4Assert(m_ServerHandler);
  1137. if (m_ServerHandler)
  1138. {
  1139. hresult = m_ServerHandler->DAdvise(pformatetc,
  1140. advf, (IAdviseSink *)
  1141. pAdvSink,pdwConnection);
  1142. }
  1143. return hresult;
  1144. }
  1145. STDMETHODIMP CEmbServerWrapper::DUnadvise(DWORD dwConnection)
  1146. {
  1147. HRESULT hresult = RPC_E_DISCONNECTED;
  1148. Win4Assert(m_ServerHandler);
  1149. if (m_ServerHandler)
  1150. {
  1151. hresult = m_ServerHandler->DUnadvise(dwConnection);
  1152. }
  1153. return hresult;
  1154. }
  1155. STDMETHODIMP CEmbServerWrapper::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
  1156. {
  1157. HRESULT hresult = RPC_E_DISCONNECTED;
  1158. Win4Assert(m_ServerHandler);
  1159. if (m_ServerHandler)
  1160. {
  1161. hresult = m_ServerHandler->EnumDAdvise(ppenumAdvise);
  1162. }
  1163. return hresult;
  1164. }