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
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: defsrv.cpp
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 10-19-95 JohannP (Johann Posch) Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <le2int.h>
  18. #ifdef SERVER_HANDLER
  19. #include <scode.h>
  20. #include <objerror.h>
  21. #include <olerem.h>
  22. #include "defhndlr.h"
  23. #include "defutil.h"
  24. #include "ole1cls.h"
  25. #ifdef _DEBUG
  26. #include <dbgdump.h>
  27. #endif // _DEBUG
  28. ASSERTDATA
  29. //+---------------------------------------------------------------------------
  30. //
  31. // Method: CDefObject::SrvInitialize
  32. //
  33. // Synopsis:
  34. //
  35. // Arguments: [void] --
  36. //
  37. // Returns:
  38. //
  39. // History: 10-19-95 JohannP (Johann Posch) Created
  40. //
  41. // Notes:
  42. //
  43. //----------------------------------------------------------------------------
  44. HRESULT CDefObject::SrvInitialize(void)
  45. {
  46. HRESULT hresult = NOERROR;
  47. VDATEHEAP();
  48. HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::Initialize\n", this));
  49. CLSID clsidsrv = CLSID_ServerHandler;
  50. Assert (( CanUseServerHandler() ));
  51. Assert((m_pProxyMgr != NULL));
  52. if (CanUseClientSiteHandler())
  53. {
  54. hresult = CreateClientSiteHandler(m_pAppClientSite, &_pClientSiteHandler);
  55. if (FAILED(hresult))
  56. {
  57. _pClientSiteHandler = NULL;
  58. }
  59. Assert((_pClientSiteHandler != NULL));
  60. }
  61. hresult = m_pProxyMgr->CreateServerWithHandler(m_clsidServer,
  62. CLSCTX_LOCAL_SERVER, NULL,clsidsrv,
  63. IID_IServerHandler, (void **) &_pSrvHndlr,
  64. IID_IClientSiteHandler, _pClientSiteHandler);
  65. if (SUCCEEDED(hresult))
  66. {
  67. // set up the server handler and call InitializeAndRun on it
  68. Assert((_pSrvHndlr != NULL));
  69. }
  70. else
  71. {
  72. // try to get server without server handler object
  73. _dwClientSiteHandler = 0;
  74. _dwServerHandler = 0;
  75. // release the client handler
  76. if (_pClientSiteHandler)
  77. {
  78. _pClientSiteHandler->Release();
  79. _pClientSiteHandler = NULL;
  80. }
  81. // Note: do not try to launch the server without handler here
  82. // this will be done by the default handler
  83. }
  84. HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvInitialize\n", this));
  85. return hresult;
  86. }
  87. //+---------------------------------------------------------------------------
  88. //
  89. // Method: CDefObject::SrvRun
  90. //
  91. // Synopsis:
  92. //
  93. // Arguments: [void] --
  94. //
  95. // Returns:
  96. //
  97. // History: 10-19-95 JohannP (Johann Posch) Created
  98. //
  99. // Notes:
  100. //
  101. //----------------------------------------------------------------------------
  102. HRESULT CDefObject::SrvRun(void)
  103. {
  104. HRESULT hresult = NOERROR;
  105. VDATEHEAP();
  106. HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvRun\n", this));
  107. INSRVRUN InSrvRun;
  108. OUTSRVRUN *pOutSrvRun = NULL;
  109. BOOL fLockedContainer;
  110. IMoniker *pmk;
  111. memset((void*)&InSrvRun, 0, sizeof(InSrvRun));
  112. Assert((_pSrvHndlr));
  113. // get the Container and lock it
  114. // NOTE: the lock state of the proxy mgr is not changed; it remembers
  115. // the state and sets up the connection correctly.
  116. // server is running; normally this coincides with locking the
  117. // container, but we keep a separate flag since locking the container
  118. // may fail.
  119. m_flags |= DH_FORCED_RUNNING;
  120. // Lock the container
  121. fLockedContainer = m_flags & DH_LOCKED_CONTAINER;
  122. DuLockContainer(m_pAppClientSite, TRUE, &fLockedContainer );
  123. if( fLockedContainer )
  124. {
  125. m_flags |= DH_LOCKED_CONTAINER;
  126. }
  127. else
  128. {
  129. m_flags &= ~DH_LOCKED_CONTAINER;
  130. }
  131. // PStgDelegate Load or InitNew
  132. InSrvRun.dwInFlags = m_flags;
  133. InSrvRun.pStg = m_pStg;
  134. if (NULL == m_pPSDelegate)
  135. {
  136. InSrvRun.dwOperation |= OP_NeedPersistStorage;
  137. }
  138. if (NULL == m_pDataDelegate)
  139. {
  140. InSrvRun.dwOperation |= OP_NeedDataObject;
  141. }
  142. if (NULL == m_pOleDelegate)
  143. {
  144. InSrvRun.dwOperation |= OP_NeedOleObject;
  145. InSrvRun.dwOperation |= OP_NeedUserClassID;
  146. }
  147. // Set the clientsite
  148. if (m_pAppClientSite)
  149. {
  150. InSrvRun.dwOperation |= OP_GotClientSite;
  151. }
  152. // set the hostname
  153. InSrvRun.pszContainerApp = (LPOLESTR)m_pHostNames;
  154. InSrvRun.pszContainerObj = (LPOLESTR)(m_pHostNames + m_ibCntrObj);
  155. // adivse sink
  156. Assert((m_dwConnOle == 0L));
  157. InSrvRun.pAS = (IAdviseSink *) &m_AdviseSink;
  158. InSrvRun.dwConnOle = m_dwConnOle;
  159. // Get the Moniker and call
  160. if(m_pAppClientSite != NULL)
  161. {
  162. if (m_pAppClientSite->GetMoniker
  163. (OLEGETMONIKER_ONLYIFTHERE,OLEWHICHMK_OBJREL, &pmk) == NOERROR)
  164. {
  165. AssertOutPtrIface(NOERROR, pmk);
  166. InSrvRun.pMnk = pmk;
  167. }
  168. else
  169. {
  170. InSrvRun.pMnk = NULL;
  171. }
  172. // QI for IMsoDocumentSite
  173. IUnknown *pMsoDS = NULL;
  174. hresult = m_pAppClientSite->QueryInterface(
  175. IID_IMsoDocumentSite,
  176. (void **)&pMsoDS);
  177. if (hresult == NOERROR)
  178. {
  179. // indicate we have MsoDocumentSite
  180. InSrvRun.dwOperation |= OP_HaveMsoDocumentSite;
  181. pMsoDS->Release();
  182. }
  183. }
  184. // MAKE CALL TO SERVERHANDLER
  185. hresult = _pSrvHndlr->RunAndInitialize(&InSrvRun, &pOutSrvRun);
  186. if (SUCCEEDED(hresult))
  187. {
  188. if (InSrvRun.dwOperation & OP_NeedPersistStorage)
  189. {
  190. Assert(NULL != pOutSrvRun->pPStg);
  191. m_pPSDelegate = pOutSrvRun->pPStg;
  192. }
  193. if (InSrvRun.dwOperation & OP_NeedDataObject)
  194. {
  195. Assert(NULL != pOutSrvRun->pDO);
  196. m_pDataDelegate = pOutSrvRun->pDO;
  197. // inform cache that we are running
  198. Assert(NULL != m_pCOleCache);
  199. m_pCOleCache->OnRun(m_pDataDelegate);
  200. // Enumerate all the advises we stored while we were either not
  201. // running or running the previous time, and send them to the
  202. // now-running object.
  203. Assert(NULL != m_pDataAdvCache);
  204. m_pDataAdvCache->EnumAndAdvise(m_pDataDelegate, TRUE);
  205. }
  206. if (InSrvRun.dwOperation & OP_NeedOleObject)
  207. {
  208. Assert(NULL != pOutSrvRun->pOO);
  209. m_pOleDelegate = pOutSrvRun->pOO;
  210. }
  211. if (InSrvRun.dwOperation & OP_NeedUserClassID)
  212. {
  213. Assert(NULL != pOutSrvRun->pUserClassID);
  214. m_clsidUser = *(pOutSrvRun->pUserClassID);
  215. }
  216. m_dwConnOle = pOutSrvRun->dwOutFlag;
  217. if (InSrvRun.pMnk != NULL)
  218. {
  219. InSrvRun.pMnk->Release();
  220. }
  221. // release the pUnkOuter for all marshald pointers
  222. if (m_pPSDelegate && m_pUnkOuter)
  223. {
  224. m_pUnkOuter->Release();
  225. }
  226. if (m_pOleDelegate && m_pUnkOuter)
  227. {
  228. m_pUnkOuter->Release();
  229. }
  230. if (m_pDataDelegate && m_pUnkOuter)
  231. {
  232. m_pUnkOuter->Release();
  233. }
  234. }
  235. else // Server Handler RunAndInitialize has failed... now clean up.
  236. {
  237. Stop();
  238. // if for some reason we did not unlock the container by now,
  239. // do it (e.g., app crashed or failed during InitNew).
  240. fLockedContainer = (m_flags & DH_LOCKED_CONTAINER);
  241. DuLockContainer(m_pAppClientSite, FALSE, &fLockedContainer );
  242. if( fLockedContainer )
  243. {
  244. m_flags |= DH_LOCKED_CONTAINER;
  245. }
  246. else
  247. {
  248. m_flags &= ~DH_LOCKED_CONTAINER;
  249. }
  250. if (InSrvRun.pMnk != NULL)
  251. {
  252. InSrvRun.pMnk->Release();
  253. }
  254. }
  255. if (pOutSrvRun != NULL)
  256. {
  257. PubMemFree(pOutSrvRun->pUserClassID); // OK to free NULL;
  258. PubMemFree(pOutSrvRun);
  259. }
  260. HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvRun( %lx )\n", this, hresult));
  261. return hresult;
  262. }
  263. //+---------------------------------------------------------------------------
  264. //
  265. // Method: CDefObject::SrvRunAndDoVerb
  266. //
  267. // Synopsis:
  268. //
  269. // Arguments: [iVerb] --
  270. // [lpmsg] --
  271. // [pActiveSite] --
  272. // [lindex] --
  273. // [hwndParent] --
  274. // [lprcPosRect] --
  275. //
  276. // Returns:
  277. //
  278. // History: 10-19-95 JohannP (Johann Posch) Created
  279. //
  280. // Notes: This is not implemented yet.
  281. //
  282. //----------------------------------------------------------------------------
  283. HRESULT CDefObject::SrvRunAndDoVerb( LONG iVerb, LPMSG lpmsg,
  284. LPOLECLIENTSITE pActiveSite, LONG lindex,
  285. HWND hwndParent, const RECT * lprcPosRect)
  286. {
  287. HRESULT hresult = NOERROR;
  288. VDATEHEAP();
  289. HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvRunAndDoVerb\n", this));
  290. HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvRunAndDoVerb\n", this));
  291. return hresult;
  292. }
  293. //+---------------------------------------------------------------------------
  294. //
  295. // Method: CDefObject::SrvDoVerb
  296. //
  297. // Synopsis: 1. gathers information on the client site
  298. // 2. calls the serverhandler with SrvDoverb with collected information
  299. // 3. serverhandler sets up connections and calls
  300. // OleObject::DoVerb on reall object
  301. // 4. release objects which did not get used
  302. //
  303. // Arguments: [iVerb] -- OleObject DoVerb parameter
  304. // [lpmsg] -- detto
  305. // [pActiveSite] -- detto
  306. // [lindex] -- detto
  307. // [hwndParent] -- detto
  308. // [lprcPosRect] -- detto
  309. //
  310. // Returns:
  311. //
  312. // History: 10-19-95 JohannP (Johann Posch) Created
  313. //
  314. // Notes:
  315. //
  316. //----------------------------------------------------------------------------
  317. HRESULT CDefObject::SrvDoVerb( LONG iVerb, LPMSG lpmsg,
  318. LPOLECLIENTSITE pActiveSite, LONG lindex,
  319. HWND hwndParent, const RECT * lprcPosRect)
  320. {
  321. HRESULT hresult = NOERROR;
  322. VDATEHEAP();
  323. HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvDoVerb\n", this));
  324. CInSrvRun InSrvRun;
  325. OUTSRVRUN *pOutSrvRun = NULL;
  326. IOleContainer *pOCont = NULL;
  327. IOleObject *pOOCont = NULL;
  328. IOleClientSite *pOContCS;
  329. IOleInPlaceSite *pOIPS;
  330. // set up the DoVerb parametes
  331. InSrvRun.dwOperation = 0;
  332. InSrvRun.iVerb = iVerb;
  333. InSrvRun.lpmsg = lpmsg;
  334. InSrvRun.lindex = lindex;
  335. InSrvRun.hwndParent = hwndParent;
  336. InSrvRun.lprcPosRect = (RECT *)lprcPosRect;
  337. // Step 1: set up OleClientSiteActive
  338. if (pActiveSite)
  339. {
  340. // Currently this Assert goes off with LE test = deflink-1854 (bchapman Mar'96)
  341. Assert(NULL != _pClientSiteHandler);
  342. _pClientSiteHandler->SetClientSiteDelegate(ID_ClientSiteActive, pActiveSite);
  343. InSrvRun.dwOperation |= OP_GotClientSiteActive;
  344. }
  345. // Step 2: IOleClientSite::GetContainer
  346. // Note: this call might cause a GetUserClassID call
  347. // to the server
  348. hresult = m_pAppClientSite->GetContainer(&pOCont);
  349. if (hresult == NOERROR)
  350. {
  351. HdlAssert((_pClientSiteHandler->_pOCont == NULL));
  352. _pClientSiteHandler->_pOCont = pOCont;
  353. InSrvRun.dwOperation |= OP_GotContainer;
  354. // Step 3: QI on OleContainer for the OleObject
  355. hresult = pOCont->QueryInterface(IID_IOleObject, (void **)&pOOCont);
  356. if (hresult == NOERROR)
  357. {
  358. InSrvRun.dwOperation |= OP_GotOleObjectOfContainer;
  359. // release OleObject of container
  360. pOOCont->Release();
  361. }
  362. }
  363. // Step 6: OI for IOleInPlaceSite
  364. hresult = m_pAppClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&pOIPS);
  365. if (hresult == NOERROR)
  366. {
  367. // set up OleInPlaceSite on the clientsitehandler
  368. HdlAssert((_pClientSiteHandler != NULL));
  369. // release the old OleInPlaceSite
  370. if (_pClientSiteHandler->_pOIPS)
  371. {
  372. _pClientSiteHandler->_pOIPS->Release();
  373. }
  374. _pClientSiteHandler->_pOIPS = pOIPS;
  375. // Step 7: IOleInPlaceSite::CanInPlaceActivate
  376. InSrvRun.dwInPlace = pOIPS->CanInPlaceActivate();
  377. // indicate we have OleInPlaceSite
  378. InSrvRun.dwOperation |= OP_GotInPlaceSite;
  379. }
  380. // call the ServerHandler
  381. HdlDebugOut((DEB_SERVERHANDLER, "%p In CDefObject::SrvDoVerb calling DoVerb on ServerHandler!\n",this));
  382. hresult = _pSrvHndlr->DoVerb(&InSrvRun, &pOutSrvRun);
  383. HdlDebugOut((DEB_SERVERHANDLER, "%p In CDefObject::SrvDoVerb return from DoVerb on ServerHandler!\n",this));
  384. Assert(NULL != _pClientSiteHandler);
  385. if (FAILED(hresult))
  386. {
  387. HdlDebugOut((DEB_ERROR, "OO::DoVerb failed !"));
  388. goto errRtn;
  389. }
  390. // Release the active OleClientSite if not used by server
  391. if ( (InSrvRun.dwOperation & OP_GotClientSiteActive)
  392. && !(pOutSrvRun->dwOperation & OP_GotClientSiteActive) )
  393. {
  394. // release the active clientsite if not used by the server app.
  395. Assert(NULL != _pClientSiteHandler);
  396. _pClientSiteHandler->SetClientSiteDelegate(ID_ClientSiteActive, NULL);
  397. }
  398. // Release OleInPlaceSite if not used by server
  399. if ( (InSrvRun.dwOperation & OP_GotInPlaceSite)
  400. && !(pOutSrvRun->dwOperation & OP_GotInPlaceSite) )
  401. {
  402. _pClientSiteHandler->SetClientSiteDelegate(ID_InPlaceSite,NULL);
  403. }
  404. // Release the container if not used by server
  405. if ( (InSrvRun.dwOperation & OP_GotContainer)
  406. && !(pOutSrvRun->dwOperation & OP_GotContainer) )
  407. {
  408. _pClientSiteHandler->SetClientSiteDelegate(ID_Container,NULL);
  409. }
  410. errRtn:
  411. // delete the out parameter
  412. if (pOutSrvRun)
  413. {
  414. PubMemFree(pOutSrvRun);
  415. }
  416. HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvDoVerb\n",this));
  417. return hresult;
  418. }
  419. //+---------------------------------------------------------------------------
  420. //
  421. // Method: CDefObject::SrvRelease
  422. //
  423. // Synopsis:
  424. //
  425. // Arguments: [void] --
  426. //
  427. // Returns:
  428. //
  429. // History: 10-19-95 JohannP (Johann Posch) Created
  430. //
  431. // Notes:
  432. //
  433. //----------------------------------------------------------------------------
  434. DWORD CDefObject::SrvRelease(void)
  435. {
  436. VDATEHEAP();
  437. HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvRelease\n", this));
  438. Assert((_pSrvHndlr != NULL));
  439. DWORD dwRet = _pSrvHndlr->Release();
  440. #if DBG==1
  441. if (dwRet)
  442. {
  443. HdlDebugOut((DEB_ERROR, "Last IServerHandler::Release() return %ld\n", dwRet));
  444. }
  445. #endif
  446. _pSrvHndlr = NULL;
  447. HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvRelease\n", this));
  448. return dwRet;
  449. }
  450. //+---------------------------------------------------------------------------
  451. //
  452. // Method: CDefObject::SrvCloseAndRelease
  453. //
  454. // Synopsis:
  455. //
  456. // Arguments: [dwFlag] --
  457. //
  458. // Returns:
  459. //
  460. // History: 11-17-95 JohannP (Johann Posch) Created
  461. //
  462. // Notes:
  463. //
  464. //----------------------------------------------------------------------------
  465. HRESULT CDefObject::SrvCloseAndRelease(DWORD dwFlag)
  466. {
  467. HRESULT hresult;
  468. VDATEHEAP();
  469. HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvCloseAndRelease\n", this));
  470. HdlAssert((_pSrvHndlr != NULL));
  471. hresult = _pSrvHndlr->CloseAndRelease(dwFlag);
  472. HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvSrvCloseAndRelease hr:%lx\n",this,hresult));
  473. return hresult;
  474. }
  475. //+---------------------------------------------------------------------------
  476. //
  477. // Method: CDefObject::InitializeServerHandlerOptions
  478. //
  479. // Synopsis:
  480. //
  481. // Arguments: [clsidSrv] --
  482. //
  483. // Returns:
  484. //
  485. // History: 11-17-95 JohannP (Johann Posch) Created
  486. //
  487. // Notes: determines server application specifics which can be used
  488. // to make serverhandler operations more efficient
  489. // Review: (JohannP) we would need a flag in the registery or so
  490. //
  491. //----------------------------------------------------------------------------
  492. void CDefObject::InitializeServerHandlerOptions(REFCLSID clsidSrv)
  493. {
  494. VDATEHEAP();
  495. HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::InitializeServerHandlerOptions\n",this));
  496. //
  497. // this method should retrieve server application specific informantion
  498. //
  499. HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::InitializeServerHandlerOptions\n",this));
  500. }
  501. #endif // SERVER_HANDLER