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.

6201 lines
162 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: defhndlr.cpp
  7. //
  8. // Contents: Implementation of the default handler
  9. //
  10. // Classes: CDefObject (see defhndlr.h)
  11. //
  12. // Functions: OleCreateDefaultHandler
  13. // OleCreateEmbeddingHelper
  14. //
  15. //
  16. // History: dd-mmm-yy Author Comment
  17. //
  18. // 11-17-95 JohannP (Johann Posch) Architectural change:
  19. // Default handler will talk to a handler object
  20. // on the server site (ServerHandler). The serverhandler
  21. // communicates with the default handler via the
  22. // clientsitehandler. See document: "The Ole Server Handler".
  23. //
  24. // 06-Sep-95 davidwor modified SetHostNames to avoid atoms
  25. // 01-Feb-95 t-ScottH add Dump method to CDefObject
  26. // add DumpCDefObject API
  27. // add DHFlag to indicate aggregation
  28. // initialize m_cConnections in constructor
  29. // 09-Jan-95 t-scotth changed VDATETHREAD to accept a pointer
  30. // 15-Nov-94 alexgo optimized, removed excess BOOLS and
  31. // now use multiple inheritance
  32. // 01-Aug-94 alexgo added object stabilization
  33. // 16-Jan-94 alexgo fixed bug in control flow for
  34. // advises
  35. // 11-Jan-94 alexgo added VDATEHEAP macro to every function
  36. // and method.
  37. // 10-Dec-93 alexgo added call tracing, ran through
  38. // tab filter program to eliminate
  39. // whitespace
  40. // 30-Nov-93 alexgo fixed bug with cache aggregation
  41. // 22-Nov-93 alexgo removed overloaded == for GUIDs
  42. // 09-Nov-93 ChrisWe changed COleCache::Update to
  43. // COleCache::UpdateCache, and COleCache::Discard to
  44. // COleCache::DiscardCache, which do the same as the
  45. // originals, but without the indirect function call
  46. // 02-Nov-93 alexgo 32bit port
  47. // srinik 09/15/92 Removed code for giving cfOwnerLink data through
  48. // GetData() method
  49. // srinik 09/11/92 Removed IOleCache implementation, as a result of
  50. // removing voncache.cpp, and moving IViewObject
  51. // implementation into olecache.cpp.
  52. // SriniK 06/04/92 Fixed problems in IPersistStorage methods
  53. // 04-Mar-92 srinik created
  54. //
  55. //--------------------------------------------------------------------------
  56. #include <le2int.h>
  57. #include <scode.h>
  58. #include <objerror.h>
  59. #include <olerem.h>
  60. #include "defhndlr.h"
  61. #include "defutil.h"
  62. #include "ole1cls.h"
  63. #ifdef _DEBUG
  64. #include <dbgdump.h>
  65. #endif // _DEBUG
  66. #include <ole2int.h>
  67. #include <stdid.hxx> // CStdIdentity
  68. #include <ipidtbl.hxx> // IpidTable.
  69. #include <aggid.hxx> // COM outer object
  70. #include "xmit.hxx"
  71. #ifdef SERVER_HANDLER
  72. #include "srvhndlr.h"
  73. #include "clthndlr.h"
  74. #endif // SERVER_HANDLER
  75. ASSERTDATA
  76. /*
  77. * IMPLEMENTATION of CDefObject
  78. *
  79. */
  80. FARINTERNAL_(LPUNKNOWN) CreateDdeProxy(IUnknown FAR* pUnkOuter,
  81. REFCLSID rclsid);
  82. //+-------------------------------------------------------------------------
  83. //
  84. // Function: CreateRemoteHandler
  85. //
  86. // Arguments: [rclsid] -- clsid of the remote object
  87. // [pUnkOuter] -- the controlling unknown
  88. // [iid] -- requested interface ID
  89. // [ppv] -- pointer to hold the returned interface
  90. //
  91. // Returns: HRESULT
  92. //
  93. // History: dd-mmm-yy Author Comment
  94. // 10-Jan-96 Gopalk Rewritten
  95. //--------------------------------------------------------------------------
  96. static INTERNAL CreateRemoteHandler(REFCLSID rclsid, IUnknown *pUnkOuter, REFIID iid,
  97. void **ppv, DWORD flags, BOOL *fComOuterObject, BOOL *fOle1Server)
  98. {
  99. LEDebugOut((DEB_ITRACE, "%p _IN CreateRemoteHandler (%p, %p, %p, %p, %p)\n",
  100. 0 /* this */, rclsid, pUnkOuter, iid, ppv, fComOuterObject));
  101. // Validation checks
  102. VDATEHEAP();
  103. // Local variables
  104. HRESULT hresult = NOERROR;
  105. // Initialize fComOuterObject and fOle1Server
  106. *fComOuterObject = FALSE;
  107. *fOle1Server = FALSE;
  108. // Check if the server is a OLE 1.0 object
  109. if(CoIsOle1Class(rclsid)) {
  110. IUnknown* pUnk;
  111. COleTls Tls;
  112. // Set fComOuterObject to TRUE
  113. *fOle1Server = TRUE;
  114. // Check if the container disabled OLE1 functinality
  115. if(Tls->dwFlags & OLETLS_DISABLE_OLE1DDE) {
  116. // Container is not interested in talking to OLE1 servers.
  117. // Fail the call
  118. hresult = CO_E_OLE1DDE_DISABLED;
  119. }
  120. else {
  121. LEDebugOut((DEB_ITRACE,
  122. "%p CreateRemoteHandler calling CreateDdeProxy(%p, %p)\n",
  123. 0 /* this */, pUnkOuter, rclsid));
  124. pUnk = CreateDdeProxy(pUnkOuter, rclsid);
  125. if(pUnk) {
  126. hresult = pUnk->QueryInterface(iid, ppv);
  127. pUnk->Release();
  128. }
  129. else {
  130. hresult = E_OUTOFMEMORY;
  131. }
  132. }
  133. }
  134. else {
  135. // Check for COM outer object
  136. CStdIdentity *pStdId;
  137. Win4Assert(pUnkOuter);
  138. // We do not want to QI a generic pUnkOuter for IID_IStdIdentity. Hence
  139. // we QI only if we put the pUnkOuter, either during OleCreateEmbeddingHelper
  140. // or during unmarshaling (CDefClassFactory::CreateInstance).
  141. // The DH_APICREATE flag is used to distinguish between the two cases.
  142. if ( flags & DH_COM_OUTEROBJECT ||
  143. ( !(flags & DH_COM_OUTEROBJECT)&&!(flags & DH_APICREATE) )) {
  144. hresult = pUnkOuter->QueryInterface(IID_IStdIdentity, (void **)&pStdId);
  145. if(SUCCEEDED(hresult)) {
  146. // Obtain the inner IUnknown on the COM outer object
  147. *ppv = pStdId->GetInternalUnk();
  148. ((IUnknown *) *ppv)->AddRef();
  149. // Inform the COM outer object that it is dealing with Default
  150. // Handler so that it enables access to IProxyManager methods
  151. pStdId->UpdateFlags(STDID_CLIENT_DEFHANDLER);
  152. // Release the StdId
  153. pStdId->Release();
  154. // Set fComOuterObject to TRUE
  155. *fComOuterObject = TRUE;
  156. }
  157. }
  158. else {
  159. // Create StdIdentity
  160. hresult = CreateIdentityHandler(pUnkOuter, STDID_CLIENT_DEFHANDLER,
  161. NULL, GetCurrentApartmentId(),
  162. iid, ppv);
  163. }
  164. }
  165. LEDebugOut((DEB_ITRACE, "%p OUT CreateRemoteHandler(%lx)\n",
  166. 0 /* this */, hresult));
  167. return hresult;
  168. }
  169. //+-------------------------------------------------------------------------
  170. //
  171. // Function: OleCreateDefaultHandler
  172. //
  173. // Synopsis: API to create the default handler. Simply calls
  174. // OleCreateEmbeddingHelper with more arguments
  175. //
  176. // Arguments: [clsid] -- the clsid of the remote exe
  177. // [pUnkOuter] -- the controlling unknown (so we can
  178. // be aggregated)
  179. // [iid] -- the requested interface
  180. // [ppv] -- where to put a pointer to the default
  181. // handler
  182. //
  183. // Requires:
  184. //
  185. // Returns: HRESULT
  186. //
  187. // Signals:
  188. //
  189. // Modifies:
  190. //
  191. // Algorithm:
  192. //
  193. // History: dd-mmm-yy Author Comment
  194. // 10-Dec-93 alexgo added call tracing
  195. // 02-Nov-93 alexgo 32bit port
  196. // 10-Jan-97 Gopalk Simplified
  197. //--------------------------------------------------------------------------
  198. #pragma SEG(OleCreateDefaultHandler)
  199. STDAPI OleCreateDefaultHandler(REFCLSID clsid, IUnknown *pUnkOuter,
  200. REFIID iid, void **ppv)
  201. {
  202. OLETRACEIN((API_OleCreateDefaultHandler,
  203. PARAMFMT("clsid=%I, pUnkOuter=%p, iid=%I, ppv=%p"),
  204. &clsid, pUnkOuter, &iid, ppv));
  205. LEDebugOut((DEB_TRACE, "%p _IN OleCreateDefaultHandler(%p, %p, %p, %p)\n",
  206. 0 /* this */, clsid, pUnkOuter, iid, ppv));
  207. // validation checks
  208. VDATEHEAP();
  209. // Local variable
  210. HRESULT hresult;
  211. // Call OleCreateEmbeddingHelper with the right parameters
  212. hresult = OleCreateEmbeddingHelper(clsid, pUnkOuter,
  213. EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
  214. NULL, iid, ppv);
  215. LEDebugOut((DEB_TRACE, "%p OUT OleCreateDefaultHandler(%lx)\n",
  216. 0 /* this */, hresult));
  217. OLETRACEOUT((API_OleCreateDefaultHandler, hresult));
  218. return hresult;
  219. }
  220. //+-------------------------------------------------------------------------
  221. //
  222. // Function: OleCreateEmbeddingHelper
  223. //
  224. // Synopsis: Creates an instance of CDefObject (the default handler)
  225. // Called by OleCreateDefaultHandler
  226. //
  227. // Arguments: [clsid] -- Server class id
  228. // [pUnkOuter] -- Controlling unkown for aggregation
  229. // [flags] -- Indiacte an inproc handler or
  230. // helper for an inproc server. The inproc
  231. // server case is useful for self embedding
  232. // [pCF] -- Server's class factory for inproc server
  233. // [iid] -- Requested interface
  234. // [ppv] -- pointer to hold the returned interface
  235. //
  236. // Returns: HRESULT
  237. //
  238. // History: dd-mmm-yy Author Comment
  239. // 10-Jan-96 Gopalk Rewritten
  240. //--------------------------------------------------------------------------
  241. #pragma SEG(OleCreateEmbeddingHelper)
  242. STDAPI OleCreateEmbeddingHelper(REFCLSID clsid, IUnknown *pUnkOuter,
  243. DWORD flags, IClassFactory *pCF,
  244. REFIID iid, void **ppv)
  245. {
  246. OLETRACEIN((API_OleCreateEmbeddingHelper,
  247. PARAMFMT("clsid=%I, pUnkOuter=%p, flags=%x, pCF=%p, iid=%I, ppv=%p"),
  248. &clsid, pUnkOuter, flags, pCF, &iid, ppv));
  249. LEDebugOut((DEB_TRACE, "%p _IN OleCreateEmbeddingHelper(%p, %p, %lu, %p, %p, %p)\n",
  250. 0 /* this */, clsid, pUnkOuter, flags, pCF, iid, ppv));
  251. // Local variables
  252. HRESULT hresult = NOERROR;
  253. IUnknown *pUnk;
  254. // Validation checks
  255. VDATEHEAP();
  256. // Initialize the out parameter
  257. if(IsValidPtrOut(ppv, sizeof(void *)))
  258. *ppv = NULL;
  259. else
  260. hresult = E_INVALIDARG;
  261. if(hresult == NOERROR) {
  262. // Check that only allowed flags are set
  263. if(flags & ~(EMBDHLP_INPROC_SERVER|EMBDHLP_DELAYCREATE)) {
  264. hresult = E_INVALIDARG;
  265. } // Ensure that aggregation rules are being followed
  266. else if(pUnkOuter && (iid!=IID_IUnknown || !IsValidInterface(pUnkOuter))) {
  267. hresult = E_INVALIDARG;
  268. }
  269. else {
  270. // Check whether Inproc Server or Inproc Handler is requested
  271. if(flags & EMBDHLP_INPROC_SERVER) {
  272. // InProc server requested
  273. if(!pCF || !IsValidInterface(pCF)) {
  274. // Inproc Server should be given a class factory
  275. hresult = E_INVALIDARG;
  276. }
  277. }
  278. else {
  279. // InProc Handler requested
  280. if(pCF || (flags & EMBDHLP_DELAYCREATE)) {
  281. // InProc Handler should not be given a class factory
  282. hresult = E_INVALIDARG;
  283. }
  284. }
  285. }
  286. }
  287. // Create the Default object
  288. if(hresult == NOERROR) {
  289. // We add the DH_APICREATE flag so that during CreateRemoteHandler we can
  290. // distinguish between creation through APIs v/s creation through unmarshaling.
  291. // Warning: Be careful! Do not use bits used by the EMBDHLP_xxx flags (ole2.h)
  292. pUnk = CDefObject::Create(pUnkOuter, clsid, flags|DH_APICREATE, pCF);
  293. if(pUnk) {
  294. // Check if IUnknown was requested
  295. if(IsEqualIID(iid, IID_IUnknown)) {
  296. *ppv = pUnk;
  297. }
  298. else {
  299. // QI for the desired interface
  300. hresult = pUnk->QueryInterface(iid, ppv);
  301. // Fixup the reference count
  302. pUnk->Release();
  303. }
  304. }
  305. else {
  306. hresult = E_OUTOFMEMORY;
  307. }
  308. }
  309. LEDebugOut((DEB_TRACE, "%p OUT OleCreateEmbeddingHelper(%lx)\n",
  310. 0 /* this */, hresult));
  311. OLETRACEOUT((API_OleCreateEmbeddingHelper, hresult));
  312. return hresult;
  313. }
  314. //+-------------------------------------------------------------------------
  315. //
  316. // Member: CDefObject::Create, static
  317. //
  318. // Synopsis: Static function used internally to create CDefObject
  319. //
  320. // Arguments: [pUnkOuter] -- Controlling unkown
  321. // [clsid] -- Server clsid
  322. // [flags] -- creation flags
  323. // [pCF] -- pointer to server object class factory for
  324. // inproc server
  325. //
  326. // Returns: pointer to the CDefObject's IUnkown interface
  327. //
  328. // History: dd-mmm-yy Author Comment
  329. // 10-Jan-96 Gopalk Rewritten
  330. // 07-Oct-98 SteveSw Fix bug in "new CAggID" failure case
  331. //--------------------------------------------------------------------------
  332. IUnknown *CDefObject::Create(IUnknown *pUnkOuter, REFCLSID clsid,
  333. DWORD flags, IClassFactory *pCF)
  334. {
  335. // Validation checks
  336. VDATEHEAP();
  337. // Local variables
  338. CDefObject *pDefObj = NULL;
  339. CAggId *pAID = NULL;
  340. HRESULT error = S_OK;
  341. // If the outer object is absent, create the standard
  342. // COM outer object to take care of race conditions
  343. // during unmarshaling. If the outer object is present,
  344. // we can only hope that either it handles the race
  345. // conditions (Unmarshaled handler case) or that
  346. // they are not encountered
  347. if(!(flags & EMBDHLP_INPROC_SERVER) && !pUnkOuter && !CoIsOle1Class(clsid)) {
  348. IUnknown *pUnkInternal = NULL;
  349. // Create the COM outer object
  350. pAID = new CAggId(clsid, error);
  351. if(SUCCEEDED(error) && pAID != NULL) {
  352. pUnkOuter = (IUnknown *) pAID;
  353. flags |= DH_COM_OUTEROBJECT;
  354. }
  355. else
  356. {
  357. // Release aggid if it was created
  358. if(pAID)
  359. pAID->Release();
  360. return NULL;
  361. }
  362. }
  363. // Create the Default Handler
  364. pDefObj = new CDefObject(pUnkOuter);
  365. if(!pDefObj) {
  366. // If COM outer object was created earlier, release it now
  367. if(flags & DH_COM_OUTEROBJECT)
  368. pAID->Release();
  369. return NULL;
  370. }
  371. // Make our ref count equal to 1
  372. pDefObj->m_Unknown.AddRef();
  373. // Check if COM outer object was created earlier
  374. if(flags & DH_COM_OUTEROBJECT) {
  375. // Set handler on the COM outer object
  376. error = pAID->SetHandler(&pDefObj->m_Unknown);
  377. // As OID has not yet been assigned to StdIdentity
  378. // of AggId, no other thread can get a pointer to it
  379. // and consequently, the above call should never fail
  380. Win4Assert(error == NOERROR);
  381. // Fix the reference count
  382. pDefObj->m_Unknown.Release();
  383. // Return if something has gone wrong
  384. if(error != NOERROR) {
  385. pAID->Release();
  386. return NULL;
  387. }
  388. }
  389. // Initialize member variables
  390. pDefObj->m_clsidServer = clsid;
  391. pDefObj->m_clsidBits = CLSID_NULL;
  392. #ifdef SERVER_HANDLER
  393. pDefObj->m_clsidUser = CLSID_NULL;
  394. pDefObj->m_ContentMiscStatusUser = 0;
  395. #endif // SERVER_HANDLER
  396. if(pCF) {
  397. pDefObj->m_pCFDelegate = pCF;
  398. pCF->AddRef();
  399. }
  400. // Update flags
  401. if(!(flags & EMBDHLP_INPROC_SERVER))
  402. pDefObj->m_flags |= DH_INPROC_HANDLER;
  403. if(flags & DH_COM_OUTEROBJECT)
  404. pDefObj->m_flags |= DH_COM_OUTEROBJECT;
  405. if (flags & DH_APICREATE)
  406. pDefObj->m_flags |= DH_APICREATE;
  407. if(IsEqualCLSID(clsid, CLSID_StaticMetafile) ||
  408. IsEqualCLSID(clsid, CLSID_StaticDib) ||
  409. IsEqualCLSID(clsid, CLSID_Picture_EnhMetafile))
  410. pDefObj->m_flags |= DH_STATIC;
  411. // Create sub objects starting with Ole Cache
  412. pDefObj->m_pCOleCache = new COleCache(pDefObj->m_pUnkOuter, clsid);
  413. if(pDefObj->m_pCOleCache) {
  414. // Create DataAdvise Cache
  415. error = CDataAdviseCache::CreateDataAdviseCache(&pDefObj->m_pDataAdvCache);
  416. if(error == NOERROR) {
  417. // Check flags and create the inner object if requested
  418. if(flags & EMBDHLP_DELAYCREATE) {
  419. Win4Assert(pCF);
  420. Win4Assert(flags & EMBDHLP_INPROC_SERVER);
  421. Win4Assert(pDefObj->m_pUnkDelegate == NULL);
  422. Win4Assert(pDefObj->m_pProxyMgr == NULL);
  423. Win4Assert(pDefObj->GetRefCount() == 1);
  424. pDefObj->m_flags |= DH_DELAY_CREATE;
  425. return &pDefObj->m_Unknown;
  426. }
  427. else {
  428. error = pDefObj->CreateDelegate();
  429. if(error == NOERROR) {
  430. Win4Assert(pDefObj->GetRefCount() == 1);
  431. if(flags & DH_COM_OUTEROBJECT)
  432. return (IUnknown *)pAID;
  433. else
  434. return &pDefObj->m_Unknown;
  435. }
  436. }
  437. }
  438. }
  439. // Something has gone wrong. Release the outer object
  440. // which will in turn release sub objects
  441. Win4Assert(pDefObj->GetRefCount() == 1);
  442. if(flags & DH_COM_OUTEROBJECT)
  443. pAID->Release();
  444. else
  445. pDefObj->m_Unknown.Release();
  446. return NULL;
  447. }
  448. //+-------------------------------------------------------------------------
  449. //
  450. // Member: CDefObject::CDefObject
  451. //
  452. // Synopsis: constructor, sets member variables to NULL
  453. //
  454. // Effects:
  455. //
  456. // Arguments: [pUnkOuter] -- the controlling unkown
  457. //
  458. // Requires:
  459. //
  460. // Returns: HRESULT
  461. //
  462. // Signals:
  463. //
  464. // Modifies:
  465. //
  466. // Derivation: none
  467. //
  468. // Algorithm:
  469. //
  470. // History: dd-mmm-yy Author Comment
  471. // 02-Nov-93 alexgo 32bit port
  472. // 10-Jan-97 Gopalk Intialize CRefExportCount
  473. //--------------------------------------------------------------------------
  474. CDefObject::CDefObject (IUnknown *pUnkOuter) :
  475. CRefExportCount(pUnkOuter)
  476. {
  477. VDATEHEAP();
  478. if (!pUnkOuter)
  479. {
  480. pUnkOuter = &m_Unknown;
  481. }
  482. //m_clsidServer
  483. //m_clsidBits are set in ::Create
  484. m_cConnections = 0;
  485. m_pCFDelegate = NULL;
  486. m_pUnkDelegate = NULL;
  487. m_pUnkOuter = pUnkOuter;
  488. m_pProxyMgr = NULL;
  489. m_pCOleCache = NULL;
  490. m_pOAHolder = NULL;
  491. m_dwConnOle = 0L;
  492. m_pAppClientSite = NULL;
  493. m_pStg = NULL;
  494. m_pDataAdvCache = NULL;
  495. m_flags = DH_INIT_NEW;
  496. m_dwObjFlags = 0;
  497. m_pHostNames = NULL;
  498. m_ibCntrObj = 0;
  499. m_pOleDelegate = NULL;
  500. m_pDataDelegate = NULL;
  501. m_pPSDelegate = NULL;
  502. #ifdef SERVER_HANDLER
  503. m_pEmbSrvHndlrWrapper = NULL;
  504. m_pRunClientSite = NULL;
  505. #endif // SERVER_HANDLER
  506. // Initialize member variables used for caching MiscStatus bits
  507. m_ContentSRVMSHResult = 0xFFFFFFFF;
  508. m_ContentSRVMSBits = 0;
  509. m_ContentREGMSHResult = 0xFFFFFFFF;
  510. m_ContentREGMSBits = 0;
  511. // Initialize member variables used for caching MiscStatus bits
  512. m_ContentSRVMSHResult = 0xFFFFFFFF;
  513. m_ContentSRVMSBits = 0;
  514. m_ContentREGMSHResult = 0xFFFFFFFF;
  515. m_ContentREGMSBits = 0;
  516. #if DBG==1
  517. if (pUnkOuter != &m_Unknown)
  518. {
  519. m_flags |= DH_AGGREGATED;
  520. }
  521. #endif
  522. }
  523. //+-------------------------------------------------------------------------
  524. //
  525. // Member: CDefObject::CleanupFn, private, virtual
  526. //
  527. // Synopsis: This function is called by CRefExportCount when the object
  528. // enters zombie state
  529. //
  530. // Arguments: None
  531. //
  532. // History: dd-mmm-yy Author Comment
  533. // 10-Jan-07 Gopalk Creation
  534. //--------------------------------------------------------------------------
  535. void CDefObject::CleanupFn(void)
  536. {
  537. LEDebugOut((DEB_ITRACE, "%p _IN CDefObject::CleanupFn()\n", this));
  538. // Validation check
  539. VDATEHEAP();
  540. // Ensure that the server is stopped thereby releasing all references on
  541. // it
  542. Stop();
  543. // Release all cached pointers following aggregation rules. For local
  544. // server case, the following calls simply release proxies maintained
  545. // by the proxy manager as they have already been disconnected above
  546. if(m_pProxyMgr) {
  547. m_pUnkOuter->AddRef();
  548. SafeReleaseAndNULL((IUnknown **)&m_pProxyMgr);
  549. }
  550. if(m_pDataDelegate) {
  551. m_pUnkOuter->AddRef();
  552. SafeReleaseAndNULL((IUnknown **)&m_pDataDelegate);
  553. }
  554. if(m_pOleDelegate) {
  555. m_pUnkOuter->AddRef();
  556. SafeReleaseAndNULL((IUnknown **)&m_pOleDelegate);
  557. }
  558. if(m_pPSDelegate) {
  559. m_pUnkOuter->AddRef();
  560. SafeReleaseAndNULL((IUnknown **)&m_pPSDelegate);
  561. }
  562. // Release server handler
  563. #ifdef SERVER_HANDLER
  564. if (m_pEmbSrvHndlrWrapper){
  565. CEmbServerWrapper* pWrapper = m_pEmbSrvHndlrWrapper;
  566. m_pEmbSrvHndlrWrapper = NULL;
  567. pWrapper->m_Unknown.Release();
  568. }
  569. #endif // SERVER_HANDLER
  570. // Release the inner objects
  571. if(m_pUnkDelegate) {
  572. SafeReleaseAndNULL((IUnknown **)&m_pUnkDelegate);
  573. }
  574. if(m_pCFDelegate) {
  575. SafeReleaseAndNULL((IUnknown **)&m_pCFDelegate);
  576. }
  577. if(m_pCOleCache) {
  578. COleCache *pcache = m_pCOleCache;
  579. m_pCOleCache = NULL;
  580. pcache->m_UnkPrivate.Release();
  581. }
  582. if(m_pOAHolder) {
  583. SafeReleaseAndNULL((IUnknown **)&m_pOAHolder);
  584. }
  585. if (m_pDataAdvCache) {
  586. LPDATAADVCACHE pcacheTemp = m_pDataAdvCache;
  587. m_pDataAdvCache = NULL;
  588. delete pcacheTemp;
  589. }
  590. // Release container side objects
  591. if(m_pAppClientSite) {
  592. SafeReleaseAndNULL((IUnknown **)&m_pAppClientSite);
  593. }
  594. if(m_pStg) {
  595. SafeReleaseAndNULL((IUnknown **)&m_pStg);
  596. }
  597. if(m_pHostNames) {
  598. PrivMemFree(m_pHostNames);
  599. m_pHostNames = NULL;
  600. }
  601. // Set DH_CLEANEDUP flag
  602. m_flags |= DH_CLEANEDUP;
  603. LEDebugOut((DEB_ITRACE, "%p OUT CDefObject::CleanupFn()\n", this));
  604. return;
  605. }
  606. //+-------------------------------------------------------------------------
  607. //
  608. // Member: CDefObject::~CDefObject
  609. //
  610. // Synopsis: Destructor
  611. //
  612. // Arguments: None
  613. //
  614. // History: dd-mmm-yy Author Comment
  615. // 10-Jan-07 Gopalk Rewritten
  616. //--------------------------------------------------------------------------
  617. #pragma SEG(CDefObject_dtor)
  618. CDefObject::~CDefObject(void)
  619. {
  620. VDATEHEAP();
  621. Win4Assert(m_flags & DH_CLEANEDUP);
  622. Win4Assert(m_pUnkDelegate == NULL);
  623. Win4Assert(m_pCFDelegate == NULL);
  624. Win4Assert(m_pProxyMgr == NULL);
  625. Win4Assert(m_pCOleCache == NULL);
  626. Win4Assert(m_pOAHolder == NULL);
  627. Win4Assert(m_pAppClientSite == NULL);
  628. Win4Assert(m_pHostNames == NULL);
  629. Win4Assert(m_pStg == NULL);
  630. Win4Assert(m_pDataAdvCache == NULL);
  631. }
  632. //+-------------------------------------------------------------------------
  633. //
  634. // Member: CDefObject::CreateDelegate, private
  635. //
  636. // Synopsis: Creates either a remote handler or a user supplied delegate
  637. // The remote handler must support IProxyManager
  638. //
  639. // Returns: HRESULT
  640. //
  641. // History: dd-mmm-yy Author Comment
  642. // 10-Jan-07 Gopalk Rewritten
  643. //--------------------------------------------------------------------------
  644. INTERNAL CDefObject::CreateDelegate(void)
  645. {
  646. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CreateDelegate()\n", this));
  647. // Validation checks
  648. VDATEHEAP();
  649. // Local variables
  650. HRESULT hresult = NOERROR;
  651. BOOL fComOuterObject, fOle1Server;
  652. // Check if inner object has not yet been created
  653. if(!m_pUnkDelegate) {
  654. // Check for the class factory for the inner object
  655. if(m_pCFDelegate) {
  656. // Create the inner object using its class factory
  657. Win4Assert(!(m_flags & DH_INPROC_HANDLER));
  658. Win4Assert(!(m_flags & DH_COM_OUTEROBJECT));
  659. hresult = m_pCFDelegate->CreateInstance(m_pUnkOuter, IID_IUnknown,
  660. (void **) &m_pUnkDelegate);
  661. // Assert that COM rules have been followed for out parameters
  662. AssertOutPtrIface(hresult, m_pUnkDelegate);
  663. // Release class factory if inner object has been
  664. // successfully created
  665. if(hresult == NOERROR) {
  666. m_pCFDelegate->Release();
  667. m_pCFDelegate = NULL;
  668. }
  669. else {
  670. // Win4Assert(!"CreateInstance failed"); // LeSuite Covers this case.
  671. }
  672. }
  673. else {
  674. // Create the COM/DDE Proxy Manager
  675. // Note that the proxy manager is intialized to obtain strong
  676. // references when the server is run. The conatiner can
  677. // modify this behavior by calling either
  678. // OleSetConatinedObject or IRunnableObject::LockRunning
  679. Win4Assert(m_flags & DH_INPROC_HANDLER);
  680. hresult = CreateRemoteHandler(m_clsidServer, m_pUnkOuter,
  681. IID_IUnknown, (void **) &m_pUnkDelegate,
  682. m_flags, &fComOuterObject, &fOle1Server);
  683. // Assert that COM rules have been followed for out parameters
  684. AssertOutPtrIface(hresult, m_pUnkDelegate);
  685. if(hresult == NOERROR) {
  686. // Determine if the Default Handler is being created due to
  687. // unmarshaling and update flags
  688. if(m_flags & DH_COM_OUTEROBJECT) {
  689. Win4Assert(fComOuterObject);
  690. }
  691. else if(fComOuterObject) {
  692. // DEFHANDLER obtained by unmarshaling.
  693. // This happens on the linking container side
  694. m_flags |= DH_UNMARSHALED;
  695. // Output a debug warning.
  696. LEDebugOut((DEB_WARN, "DEFHANDLER obtained by unmarshaling\n"));
  697. }
  698. if(fOle1Server) {
  699. // OLE 1.0 Server
  700. m_flags |= DH_OLE1SERVER;
  701. // Output a debug warning.
  702. LEDebugOut((DEB_WARN, "OLE 1.0 Server\n"));
  703. }
  704. // Obtain the IProxyManager interface
  705. hresult = m_pUnkDelegate->QueryInterface(IID_IProxyManager,
  706. (void **) &m_pProxyMgr);
  707. // Follow aggregation rules for caching interface
  708. // pointers on inner objects
  709. if(hresult == NOERROR) {
  710. Win4Assert(m_pProxyMgr);
  711. m_pUnkOuter->Release();
  712. }
  713. else {
  714. Win4Assert(!"Default handler failed to obtain Proxy Manager");
  715. Win4Assert(!m_pProxyMgr);
  716. m_pProxyMgr = NULL;
  717. }
  718. }
  719. else {
  720. Win4Assert(!"CreateRemoteHandler Failed");
  721. }
  722. }
  723. // Cleanup if something has gone wrong
  724. if(hresult != NOERROR) {
  725. if(m_pUnkDelegate)
  726. m_pUnkDelegate->Release();
  727. m_pUnkDelegate = NULL;
  728. }
  729. }
  730. // DEFHANDLER either has proxy manager as the inner object
  731. // for out of proc server objects or actual server as the
  732. // inner object for inproc server objects.
  733. // Assert that this is TRUE
  734. Win4Assert((m_pProxyMgr != NULL) == !!(m_flags & DH_INPROC_HANDLER));
  735. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CreateDelegate(%lx)\n",
  736. this , hresult));
  737. return hresult;
  738. }
  739. //+----------------------------------------------------------------------------
  740. //
  741. // Member:
  742. // CDefObject::CPrivUnknown::AddRef, private
  743. //
  744. // Synopsis:
  745. // implements IUnknown::AddRef
  746. //
  747. // Arguments:
  748. // none
  749. //
  750. // Returns:
  751. // the parent object's reference count
  752. //
  753. // History:
  754. // Gopalk Rewritten Jan 20, 97
  755. //-----------------------------------------------------------------------------
  756. STDMETHODIMP_(ULONG) CDefObject::CPrivUnknown::AddRef( void )
  757. {
  758. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CPrivUnknown::AddRef()\n",
  759. this));
  760. // Validation check
  761. VDATEHEAP();
  762. // Local variables
  763. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_Unknown);
  764. ULONG cRefs;
  765. // Addref the parent object
  766. cRefs = pDefObject->SafeAddRef();
  767. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CPrivUnknown::AddRef(%lu)\n",
  768. this, cRefs));
  769. return cRefs;
  770. }
  771. //+----------------------------------------------------------------------------
  772. //
  773. // Member:
  774. // CDefObject::CPrivUnknown::Release, private
  775. //
  776. // Synopsis:
  777. // implements IUnknown::Release
  778. //
  779. // Arguments:
  780. // none
  781. //
  782. // Returns:
  783. // the parent object's reference count
  784. //
  785. // History:
  786. // Gopalk Rewritten Jan 20, 97
  787. //-----------------------------------------------------------------------------
  788. STDMETHODIMP_(ULONG) CDefObject::CPrivUnknown::Release( void )
  789. {
  790. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CPrivUnknown::Release()\n",
  791. this));
  792. // Validation check
  793. VDATEHEAP();
  794. // Local variables
  795. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_Unknown);
  796. ULONG cRefs;
  797. // Release parent object
  798. cRefs = pDefObject->SafeRelease();
  799. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CPrivUnknown::Release(%lu)\n",
  800. this, cRefs));
  801. return cRefs;
  802. }
  803. //+-------------------------------------------------------------------------
  804. //
  805. // Member: CDefObject::CPrivUnknown::QueryInterface
  806. //
  807. // Synopsis: Returns a pointer to one of the supported interfaces.
  808. //
  809. // Effects:
  810. //
  811. // Arguments: [iid] -- the requested interface ID
  812. // [ppv] -- where to put the iface pointer
  813. //
  814. // Requires:
  815. //
  816. // Returns: HRESULT
  817. //
  818. // Signals:
  819. //
  820. // Modifies:
  821. //
  822. // Derivation:
  823. //
  824. // Algorithm:
  825. //
  826. // History: dd-mmm-yy Author Comment
  827. // 03-Nov-93 alexgo 32bit port
  828. //
  829. // Notes:
  830. //
  831. //--------------------------------------------------------------------------
  832. STDMETHODIMP CDefObject::CPrivUnknown::QueryInterface(REFIID iid,
  833. LPLPVOID ppv)
  834. {
  835. CDefObject * pDefObject = GETPPARENT(this, CDefObject, m_Unknown);
  836. HRESULT hresult;
  837. VDATEHEAP();
  838. LEDebugOut((DEB_TRACE,
  839. "%p _IN CDefObject::CUnknownImpl::QueryInterface "
  840. "( %p , %p )\n", pDefObject, iid, ppv));
  841. CRefStabilize stabilize(pDefObject);
  842. if (IsEqualIID(iid, IID_IUnknown))
  843. {
  844. *ppv = (void FAR *)this;
  845. }
  846. else if (IsEqualIID(iid, IID_IOleObject))
  847. {
  848. *ppv = (void FAR *)(IOleObject *)pDefObject;
  849. }
  850. else if (IsEqualIID(iid, IID_IDataObject))
  851. {
  852. *ppv = (void FAR *)(IDataObject *)pDefObject;
  853. }
  854. else if (IsEqualIID(iid, IID_IRunnableObject))
  855. {
  856. *ppv = (void FAR *)(IRunnableObject *)pDefObject;
  857. }
  858. else if (IsEqualIID(iid, IID_IPersist) ||
  859. IsEqualIID(iid, IID_IPersistStorage))
  860. {
  861. *ppv = (void FAR *)(IPersistStorage *)pDefObject;
  862. }
  863. else if( IsEqualIID(iid, IID_IViewObject) ||
  864. IsEqualIID(iid, IID_IViewObject2) ||
  865. IsEqualIID(iid, IID_IOleCache) ||
  866. IsEqualIID(iid, IID_IOleCache2) )
  867. {
  868. // m_pCOleCache is a pointer to the *public* IUnknown
  869. // (we want the private one)
  870. hresult =
  871. pDefObject->m_pCOleCache->m_UnkPrivate.QueryInterface(
  872. iid, ppv);
  873. LEDebugOut((DEB_TRACE,
  874. "%p OUT CDefObject::CUnknownImpl::QueryInterface "
  875. "( %lx ) [ %p ]\n", pDefObject, hresult,
  876. (ppv) ? *ppv : 0 ));
  877. return hresult;
  878. }
  879. else if( !(pDefObject->m_flags & DH_INPROC_HANDLER) &&
  880. IsEqualIID(iid, IID_IExternalConnection) )
  881. {
  882. // only allow IExternalConnection if inproc server. We
  883. // know we are an inproc server if we are *not* an inproc
  884. // handler (cute, huh? ;-)
  885. *ppv = (void FAR *)(IExternalConnection *)pDefObject;
  886. }
  887. else if( IsEqualIID(iid, IID_IOleLink) )
  888. {
  889. // this prevents a remote call for
  890. // a query which will almost always fail; the remote call
  891. // interfered with server notification messages.
  892. *ppv = NULL;
  893. LEDebugOut((DEB_TRACE,
  894. "%p OUT CDefObject::CUnknownImpl::QueryInterface "
  895. "( %lx ) [ %p ]\n", pDefObject, E_NOINTERFACE, 0));
  896. return E_NOINTERFACE;
  897. }
  898. else if( IsEqualIID(iid, IID_IInternalUnknown) )
  899. {
  900. // this interface is private between the handler and the
  901. // remoting layer and is never exposed by handlers.
  902. *ppv = NULL;
  903. return E_NOINTERFACE;
  904. }
  905. else if( pDefObject->CreateDelegate() == NOERROR)
  906. {
  907. hresult = pDefObject->m_pUnkDelegate->QueryInterface( iid,
  908. ppv);
  909. LEDebugOut((DEB_TRACE,
  910. "%p OUT CDefObject::CUnknownImpl::QueryInterface "
  911. "( %lx ) [ %p ]\n", pDefObject, hresult,
  912. (ppv) ? *ppv : 0 ));
  913. return hresult;
  914. }
  915. else
  916. {
  917. // no delegate and couldn't create one
  918. *ppv = NULL;
  919. LEDebugOut((DEB_TRACE,
  920. "%p OUT CDefObject::CUnkownImpl::QueryInterface "
  921. "( %lx ) [ %p ]\n", pDefObject, CO_E_OBJNOTCONNECTED,
  922. 0 ));
  923. return CO_E_OBJNOTCONNECTED;
  924. }
  925. // this indirection is important since there are different
  926. // implementationsof AddRef (this unk and the others).
  927. ((IUnknown FAR*) *ppv)->AddRef();
  928. LEDebugOut((DEB_TRACE,
  929. "%p OUT CDefObject::CUnknownImpl::QueryInterface "
  930. "( %lx ) [ %p ]\n", pDefObject, NOERROR, *ppv));
  931. return NOERROR;
  932. }
  933. /*
  934. * IMPLEMENTATION of IUnknown methods
  935. */
  936. //+-------------------------------------------------------------------------
  937. //
  938. // Member: CDefObject::QueryInterface
  939. //
  940. // Synopsis: QI's to the controlling IUnknown
  941. //
  942. // Effects:
  943. //
  944. // Arguments: [riid] -- the interface ID
  945. // [ppv] -- where to put it
  946. //
  947. // Requires:
  948. //
  949. // Returns: HRESULT
  950. //
  951. // Signals:
  952. //
  953. // Modifies:
  954. //
  955. // Derivation: IUnknown
  956. //
  957. // Algorithm:
  958. //
  959. // History: dd-mmm-yy Author Comment
  960. // 15-Nov-94 alexgo author
  961. //
  962. // Notes: We do *not* need to stabilize this method as only
  963. // one outgoing call is made and we do not use the
  964. // 'this' pointer afterwards
  965. //
  966. //--------------------------------------------------------------------------
  967. STDMETHODIMP CDefObject::QueryInterface( REFIID riid, void **ppv )
  968. {
  969. HRESULT hresult;
  970. VDATEHEAP();
  971. VDATETHREAD(this);
  972. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::QueryInterface ( %lx , "
  973. "%p )\n", this, riid, ppv));
  974. Assert(m_pUnkOuter);
  975. hresult = m_pUnkOuter->QueryInterface(riid, ppv);
  976. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::QueryInterface ( %lx ) "
  977. "[ %p ]\n", this, hresult, *ppv));
  978. return hresult;
  979. }
  980. //+-------------------------------------------------------------------------
  981. //
  982. // Member: CDefObject::AddRef
  983. //
  984. // Synopsis: delegates AddRef to the controlling IUnknown
  985. //
  986. // Effects:
  987. //
  988. // Arguments: void
  989. //
  990. // Requires:
  991. //
  992. // Returns: ULONG -- the new reference count
  993. //
  994. // Signals:
  995. //
  996. // Modifies:
  997. //
  998. // Derivation: IUnknown
  999. //
  1000. // Algorithm:
  1001. //
  1002. // History: dd-mmm-yy Author Comment
  1003. // 15-Nov-94 alexgo author
  1004. //
  1005. // Notes:
  1006. //
  1007. //--------------------------------------------------------------------------
  1008. STDMETHODIMP_(ULONG) CDefObject::AddRef( void )
  1009. {
  1010. ULONG crefs;;
  1011. VDATEHEAP();
  1012. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::AddRef ( )\n", this));
  1013. Assert(m_pUnkOuter);
  1014. crefs = m_pUnkOuter->AddRef();
  1015. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::AddRef ( %ld ) ", this,
  1016. crefs));
  1017. return crefs;
  1018. }
  1019. //+-------------------------------------------------------------------------
  1020. //
  1021. // Member: CDefObject::Release
  1022. //
  1023. // Synopsis: delegates Release to the controlling IUnknown
  1024. //
  1025. // Effects:
  1026. //
  1027. // Arguments: void
  1028. //
  1029. // Requires:
  1030. //
  1031. // Returns: ULONG -- the new reference count
  1032. //
  1033. // Signals:
  1034. //
  1035. // Modifies:
  1036. //
  1037. // Derivation: IUnknown
  1038. //
  1039. // Algorithm:
  1040. //
  1041. // History: dd-mmm-yy Author Comment
  1042. // 15-Nov-94 alexgo author
  1043. //
  1044. // Notes:
  1045. //
  1046. //--------------------------------------------------------------------------
  1047. STDMETHODIMP_(ULONG) CDefObject::Release( void )
  1048. {
  1049. ULONG crefs;;
  1050. VDATEHEAP();
  1051. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Release ( )\n", this));
  1052. Assert(m_pUnkOuter);
  1053. crefs = m_pUnkOuter->Release();
  1054. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Release ( %ld ) ", this,
  1055. crefs));
  1056. return crefs;
  1057. }
  1058. /*
  1059. * IMPLEMENTATION of CDataObjectImpl methods
  1060. */
  1061. //+-------------------------------------------------------------------------
  1062. //
  1063. // Member: CDefObject::GetDataDelegate
  1064. //
  1065. // Synopsis: Calls DuCacheDelegate (a glorified QueryInterface)
  1066. // for the IDataObject interface on the def handler's
  1067. // delegate
  1068. //
  1069. // Effects:
  1070. //
  1071. // Arguments: void
  1072. //
  1073. // Requires:
  1074. //
  1075. // Returns: IDataObject *
  1076. //
  1077. // Signals:
  1078. //
  1079. // Modifies:
  1080. //
  1081. // Derivation:
  1082. //
  1083. // Algorithm:
  1084. //
  1085. // History: dd-mmm-yy Author Comment
  1086. // 04-Nov-93 alexgo 32bit port
  1087. //
  1088. // Notes:
  1089. //
  1090. //--------------------------------------------------------------------------
  1091. INTERNAL_(IDataObject FAR*) CDefObject::GetDataDelegate(void)
  1092. {
  1093. VDATEHEAP();
  1094. if( IsZombie() )
  1095. {
  1096. return NULL;
  1097. }
  1098. if (m_pDataDelegate) {
  1099. return m_pDataDelegate;
  1100. }
  1101. return (IDataObject FAR*)DuCacheDelegate(
  1102. &m_pUnkDelegate,
  1103. IID_IDataObject, (LPLPVOID) &m_pDataDelegate,
  1104. m_pUnkOuter);
  1105. }
  1106. //+-------------------------------------------------------------------------
  1107. //
  1108. // Member: CDefObject::GetData
  1109. //
  1110. // Synopsis: calls IDO->GetData on the cache, if that fails, then the
  1111. // call is delegated
  1112. //
  1113. // Effects: Space for the data is allocated; caller is responsible for
  1114. // freeing.
  1115. //
  1116. // Arguments: [pformatetcIn] -- format of the data to get
  1117. // [pmedium] -- the medium to transmit the data
  1118. //
  1119. // Requires:
  1120. //
  1121. // Returns: HRESULT
  1122. //
  1123. // Signals:
  1124. //
  1125. // Modifies:
  1126. //
  1127. // Derivation: IDataObject
  1128. //
  1129. // Algorithm:
  1130. //
  1131. // History: dd-mmm-yy Author Comment
  1132. // 05-Nov-93 alexgo 32bit port
  1133. //
  1134. // Notes:
  1135. //
  1136. //--------------------------------------------------------------------------
  1137. STDMETHODIMP CDefObject::GetData( LPFORMATETC pformatetcIn,
  1138. LPSTGMEDIUM pmedium )
  1139. {
  1140. VDATEHEAP();
  1141. VDATETHREAD(this);
  1142. HRESULT hresult;
  1143. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetData ( %p , %p )\n",
  1144. this, pformatetcIn, pmedium));
  1145. VDATEPTROUT( pmedium, STGMEDIUM );
  1146. VDATEREADPTRIN( pformatetcIn, FORMATETC );
  1147. CRefStabilize stabilize(this);
  1148. if (!HasValidLINDEX(pformatetcIn))
  1149. {
  1150. return DV_E_LINDEX;
  1151. }
  1152. pmedium->tymed = TYMED_NULL;
  1153. pmedium->pUnkForRelease = NULL;
  1154. Assert(m_pCOleCache != NULL);
  1155. hresult = m_pCOleCache->m_Data.GetData(pformatetcIn, pmedium);
  1156. if( hresult != NOERROR )
  1157. {
  1158. if( IsRunning() && GetDataDelegate() )
  1159. {
  1160. hresult = m_pDataDelegate->GetData(pformatetcIn,
  1161. pmedium);
  1162. AssertOutStgmedium(hresult, pmedium);
  1163. }
  1164. else
  1165. {
  1166. hresult = OLE_E_NOTRUNNING;
  1167. }
  1168. }
  1169. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetData ( %lx )\n",
  1170. this, hresult));
  1171. return hresult;
  1172. }
  1173. //+-------------------------------------------------------------------------
  1174. //
  1175. // Member: CDefObject::GetDataHere
  1176. //
  1177. // Synopsis: Gets data and puts it into the medium specified in pmedium
  1178. //
  1179. // Effects:
  1180. //
  1181. // Arguments: [pformatetcIn] -- the format of the data
  1182. // [pmedium] -- the medium to put the data in
  1183. //
  1184. // Requires:
  1185. //
  1186. // Returns: HRESULT
  1187. //
  1188. // Signals:
  1189. //
  1190. // Modifies:
  1191. //
  1192. // Derivation: IDataObject
  1193. //
  1194. // Algorithm: Tries the cache first, if that fails, calls GetDataHere
  1195. // on the delegate.
  1196. //
  1197. // History: dd-mmm-yy Author Comment
  1198. // 05-Nov-93 alexgo 32bit port
  1199. //
  1200. // Notes:
  1201. //
  1202. //--------------------------------------------------------------------------
  1203. STDMETHODIMP CDefObject::GetDataHere( LPFORMATETC pformatetcIn,
  1204. LPSTGMEDIUM pmedium )
  1205. {
  1206. VDATEHEAP();
  1207. VDATETHREAD(this);
  1208. HRESULT hresult;
  1209. LEDebugOut((DEB_TRACE,
  1210. "%p _IN CDefObject::GetDataHere "
  1211. "( %p , %p )\n", this, pformatetcIn, pmedium));
  1212. VDATEREADPTRIN( pformatetcIn, FORMATETC );
  1213. VDATEREADPTRIN( pmedium, STGMEDIUM );
  1214. CRefStabilize stabilize(this);
  1215. if (!HasValidLINDEX(pformatetcIn))
  1216. {
  1217. return DV_E_LINDEX;
  1218. }
  1219. Assert((m_pCOleCache) != NULL);
  1220. hresult = m_pCOleCache->m_Data.GetDataHere(pformatetcIn,
  1221. pmedium);
  1222. if( hresult != NOERROR)
  1223. {
  1224. if( IsRunning() && GetDataDelegate() )
  1225. {
  1226. hresult = m_pDataDelegate->GetDataHere(pformatetcIn,
  1227. pmedium);
  1228. }
  1229. else
  1230. {
  1231. hresult = OLE_E_NOTRUNNING;
  1232. }
  1233. }
  1234. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetDataHere "
  1235. "( %lx )\n", this, hresult));
  1236. return hresult;
  1237. }
  1238. //+-------------------------------------------------------------------------
  1239. //
  1240. // Member: CDefObject::QueryGetData
  1241. //
  1242. // Synopsis: Determines whether or not a GetData call with [pformatetcIn]
  1243. // would succeed.
  1244. //
  1245. // Effects:
  1246. //
  1247. // Arguments: [pformatetcIn] -- the format of the data
  1248. //
  1249. // Requires:
  1250. //
  1251. // Returns: HRESULT
  1252. //
  1253. // Signals:
  1254. //
  1255. // Modifies:
  1256. //
  1257. // Derivation: IDataObject
  1258. //
  1259. // Algorithm: Tries the cache first, then the delegate.
  1260. //
  1261. // History: dd-mmm-yy Author Comment
  1262. // 05-Nov-93 alexgo 32bit port
  1263. //
  1264. // Notes:
  1265. //
  1266. //--------------------------------------------------------------------------
  1267. STDMETHODIMP CDefObject::QueryGetData( LPFORMATETC pformatetcIn )
  1268. {
  1269. VDATEHEAP();
  1270. VDATETHREAD(this);
  1271. HRESULT hresult;
  1272. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::QueryGetData "
  1273. "( %p )\n", this, pformatetcIn));
  1274. VDATEREADPTRIN( pformatetcIn, FORMATETC );
  1275. CRefStabilize stabilize(this);
  1276. if (!HasValidLINDEX(pformatetcIn))
  1277. {
  1278. return DV_E_LINDEX;
  1279. }
  1280. Assert((m_pCOleCache) != NULL);
  1281. hresult = m_pCOleCache->m_Data.QueryGetData(pformatetcIn);
  1282. if( hresult != NOERROR )
  1283. {
  1284. if( IsRunning() && GetDataDelegate() )
  1285. {
  1286. hresult = m_pDataDelegate->QueryGetData(pformatetcIn);
  1287. }
  1288. else
  1289. {
  1290. hresult = OLE_E_NOTRUNNING;
  1291. }
  1292. }
  1293. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::QueryGetData "
  1294. "( %lx )\n", this, hresult));
  1295. return hresult;
  1296. }
  1297. //+-------------------------------------------------------------------------
  1298. //
  1299. // Member: CDefObject::GetCanonicalFormatEtc
  1300. //
  1301. // Synopsis: Calls IDO->GetCanonicalFormatEtc on the delegate
  1302. //
  1303. // Effects:
  1304. //
  1305. // Arguments: [pformatetc] -- the reqested format
  1306. // [pformatetcOut] -- the canonical format
  1307. //
  1308. // Requires:
  1309. //
  1310. // Returns: HRESULT
  1311. //
  1312. // Signals:
  1313. //
  1314. // Modifies:
  1315. //
  1316. // Derivation: IDataObject
  1317. //
  1318. // Algorithm:
  1319. //
  1320. // History: dd-mmm-yy Author Comment
  1321. // 05-Nov-93 alexgo 32bit port
  1322. //
  1323. // Notes:
  1324. //
  1325. //--------------------------------------------------------------------------
  1326. STDMETHODIMP CDefObject::GetCanonicalFormatEtc( LPFORMATETC pformatetc,
  1327. LPFORMATETC pformatetcOut)
  1328. {
  1329. VDATEHEAP();
  1330. VDATETHREAD(this);
  1331. HRESULT hresult;
  1332. LEDebugOut((DEB_TRACE,
  1333. "%p _IN CDefObject::GetCanonicalFormatEtc "
  1334. "( %p , %p )\n", this, pformatetc, pformatetcOut));
  1335. VDATEPTROUT( pformatetcOut, FORMATETC );
  1336. VDATEREADPTRIN( pformatetc, FORMATETC );
  1337. CRefStabilize stabilize(this);
  1338. pformatetcOut->ptd = NULL;
  1339. pformatetcOut->tymed = TYMED_NULL;
  1340. if (!HasValidLINDEX(pformatetc))
  1341. {
  1342. return DV_E_LINDEX;
  1343. }
  1344. if( IsRunning() && GetDataDelegate() )
  1345. {
  1346. hresult = m_pDataDelegate->GetCanonicalFormatEtc( pformatetc,
  1347. pformatetcOut);
  1348. }
  1349. else
  1350. {
  1351. hresult = OLE_E_NOTRUNNING;
  1352. }
  1353. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetCanonicalFormatEtc "
  1354. "( %lx )\n", this, hresult));
  1355. return hresult;
  1356. }
  1357. //+-------------------------------------------------------------------------
  1358. //
  1359. // Member: CDefObject::SetData
  1360. //
  1361. // Synopsis: Calls IDO->SetData on the handler's delegate
  1362. //
  1363. // Effects:
  1364. //
  1365. // Arguments: [pformatetc] -- the format of the data
  1366. // [pmedium] -- the data's transmision medium
  1367. // [fRelease] -- if the delegate should release
  1368. // the data
  1369. //
  1370. // Requires:
  1371. //
  1372. // Returns: HRESULT
  1373. //
  1374. // Signals:
  1375. //
  1376. // Modifies:
  1377. //
  1378. // Derivation: IDataObject
  1379. //
  1380. // Algorithm:
  1381. //
  1382. // History: dd-mmm-yy Author Comment
  1383. // 05-Nov-93 alexgo 32bit port
  1384. //
  1385. // Notes:
  1386. //
  1387. //--------------------------------------------------------------------------
  1388. STDMETHODIMP CDefObject::SetData( LPFORMATETC pformatetc,
  1389. LPSTGMEDIUM pmedium, BOOL fRelease)
  1390. {
  1391. VDATEHEAP();
  1392. VDATETHREAD(this);
  1393. HRESULT hresult;
  1394. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetData "
  1395. "( %p , %p , %ld )\n", this, pformatetc, pmedium,
  1396. fRelease));
  1397. VDATEREADPTRIN( pformatetc, FORMATETC );
  1398. VDATEREADPTRIN( pmedium, STGMEDIUM );
  1399. CRefStabilize stabilize(this);
  1400. if (!HasValidLINDEX(pformatetc))
  1401. {
  1402. return DV_E_LINDEX;
  1403. }
  1404. if( IsRunning() && GetDataDelegate() )
  1405. {
  1406. hresult = m_pDataDelegate->SetData(pformatetc, pmedium,
  1407. fRelease);
  1408. }
  1409. else
  1410. {
  1411. hresult = OLE_E_NOTRUNNING;
  1412. }
  1413. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SetData "
  1414. "( %lx )\n", this, hresult));
  1415. return hresult;
  1416. }
  1417. //+-------------------------------------------------------------------------
  1418. //
  1419. // Member: CDefObject::EnumFormatEtc
  1420. //
  1421. // Synopsis: Enumerates the formats available from an object
  1422. //
  1423. // Effects:
  1424. //
  1425. // Arguments: [dwDirection] -- indicates which set of formats are
  1426. // desired (i.e. those that can be set or
  1427. // those that can be retrieved via GetData)
  1428. // [ppenumFormatEtc] -- where to put the pointer to the
  1429. // enumerator
  1430. //
  1431. // Requires:
  1432. //
  1433. // Returns: HRESULT
  1434. //
  1435. // Signals:
  1436. //
  1437. // Modifies:
  1438. //
  1439. // Derivation:
  1440. //
  1441. // Algorithm: Tries the delegate (if available). If the delegate is
  1442. // is not currently connected (or if it returns OLE_E_USEREG),
  1443. // then we attempt to build the enumerator from the reg database
  1444. //
  1445. // History: dd-mmm-yy Author Comment
  1446. // 05-Nov-93 alexgo 32bit port
  1447. //
  1448. // Notes:
  1449. //
  1450. //--------------------------------------------------------------------------
  1451. STDMETHODIMP CDefObject::EnumFormatEtc( DWORD dwDirection,
  1452. LPENUMFORMATETC FAR* ppenumFormatEtc)
  1453. {
  1454. VDATEHEAP();
  1455. VDATETHREAD(this);
  1456. HRESULT hresult;
  1457. LEDebugOut((DEB_TRACE,
  1458. "%p _IN CDefObject::EnumFormatEtc ( %lu , %p )\n", this,
  1459. dwDirection, ppenumFormatEtc));
  1460. VDATEPTROUT(ppenumFormatEtc, LPVOID);
  1461. CRefStabilize stabilize(this);
  1462. *ppenumFormatEtc = NULL;
  1463. if( IsRunning() && GetDataDelegate() )
  1464. {
  1465. hresult = m_pDataDelegate->EnumFormatEtc (dwDirection,
  1466. ppenumFormatEtc);
  1467. if (!GET_FROM_REGDB(hresult))
  1468. {
  1469. LEDebugOut((DEB_TRACE,
  1470. "%p OUT CDefObject::CDataObject::EnumFormatEtc "
  1471. "( %lx ) [ %p ]\n", this,
  1472. hresult, ppenumFormatEtc));
  1473. return hresult;
  1474. }
  1475. }
  1476. // Not running, or object wants to use reg db anyway
  1477. hresult = OleRegEnumFormatEtc (m_clsidServer, dwDirection,
  1478. ppenumFormatEtc);
  1479. LEDebugOut((DEB_TRACE,
  1480. "%p OUT CDefObject::EnumFormatEtc "
  1481. "( %lx ) [ %p ]\n", this, hresult, ppenumFormatEtc));
  1482. return hresult;
  1483. }
  1484. //+-------------------------------------------------------------------------
  1485. //
  1486. // Member: CDefObject::DAdvise
  1487. //
  1488. // Synopsis: Sets up a data advise connection
  1489. //
  1490. // Effects:
  1491. //
  1492. // Arguments: [pFormatetc] -- format to be advise'd on
  1493. // [advf] -- advise flags
  1494. // [pAdvSink] -- advise sink (whom to notify)
  1495. // [pdwConnection] -- where to put the connection ID
  1496. //
  1497. // Requires:
  1498. //
  1499. // Returns: HRESULT
  1500. //
  1501. // Signals:
  1502. //
  1503. // Modifies:
  1504. //
  1505. // Derivation: IDataObject
  1506. //
  1507. // Algorithm: calls Advise on the DataAdvise cache
  1508. //
  1509. // History: dd-mmm-yy Author Comment
  1510. // 05-Nov-93 alexgo 32bit port
  1511. //
  1512. // Notes:
  1513. // We should set up an data advise holder and add the entries to
  1514. // it. We should also create a new data advise sink and register
  1515. // it with server when it is run. On receiving OnDataChange
  1516. // notifications, the advise sink would turn around and send
  1517. // OnDataChange notifications to registered client advise sinks
  1518. // This should improve run time performance and also facilitates
  1519. // better cleanup when server crashes through CoDisconnectObject
  1520. // on the advise sink registered with the server. Gopalk
  1521. //
  1522. //--------------------------------------------------------------------------
  1523. STDMETHODIMP CDefObject::DAdvise(FORMATETC *pFormatetc, DWORD advf,
  1524. IAdviseSink * pAdvSink, DWORD * pdwConnection)
  1525. {
  1526. VDATEHEAP();
  1527. VDATETHREAD(this);
  1528. HRESULT hresult;
  1529. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::DAdvise "
  1530. "( %p , %lu , %p , %p )\n", this, pFormatetc, advf,
  1531. pAdvSink, pdwConnection));
  1532. VDATEREADPTRIN( pFormatetc, FORMATETC );
  1533. VDATEIFACE( pAdvSink );
  1534. CRefStabilize stabilize(this);
  1535. IDataObject * pDataDelegate = NULL;
  1536. if( pdwConnection )
  1537. {
  1538. VDATEPTROUT( pdwConnection, DWORD );
  1539. *pdwConnection = NULL;
  1540. }
  1541. if( !HasValidLINDEX(pFormatetc) )
  1542. {
  1543. return DV_E_LINDEX;
  1544. }
  1545. if( IsRunning() )
  1546. {
  1547. pDataDelegate = GetDataDelegate();
  1548. }
  1549. // setting up advises' changes state. Don't do this if we
  1550. // are in a zombie state
  1551. if( IsZombie() == FALSE )
  1552. {
  1553. hresult = m_pDataAdvCache->Advise(pDataDelegate, pFormatetc, advf,
  1554. pAdvSink, pdwConnection);
  1555. }
  1556. else
  1557. {
  1558. hresult = CO_E_RELEASED;
  1559. }
  1560. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::DAdvise "
  1561. "( %lx ) [ %lu ]\n", this, hresult,
  1562. (pdwConnection) ? *pdwConnection : 0));
  1563. return hresult;
  1564. }
  1565. //+-------------------------------------------------------------------------
  1566. //
  1567. // Member: CDefObject::DUnadvise
  1568. //
  1569. // Synopsis: Tears down a data advise connection
  1570. //
  1571. // Effects:
  1572. //
  1573. // Arguments: [dwConnection] -- the advise connection to remove
  1574. //
  1575. // Requires:
  1576. //
  1577. // Returns: HRESULT
  1578. //
  1579. // Signals:
  1580. //
  1581. // Modifies:
  1582. //
  1583. // Derivation: IDataObject
  1584. //
  1585. // Algorithm: delegates to the DataAdvise cache
  1586. //
  1587. // History: dd-mmm-yy Author Comment
  1588. // 05-Nov-93 alexgo 32bit port
  1589. //
  1590. // Notes:
  1591. //
  1592. //--------------------------------------------------------------------------
  1593. STDMETHODIMP CDefObject::DUnadvise(DWORD dwConnection)
  1594. {
  1595. VDATEHEAP();
  1596. VDATETHREAD(this);
  1597. HRESULT hresult;
  1598. LEDebugOut((DEB_TRACE,
  1599. "%p _IN CDefObject::DUnadvise ( %lu )\n", this, dwConnection));
  1600. CRefStabilize stabilize(this);
  1601. IDataObject * pDataDelegate = NULL;
  1602. if( IsRunning() )
  1603. {
  1604. pDataDelegate = GetDataDelegate();
  1605. }
  1606. hresult = m_pDataAdvCache->Unadvise(pDataDelegate, dwConnection);
  1607. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::DUnadvise "
  1608. "( %lx )\n", this, hresult));
  1609. return hresult;
  1610. }
  1611. //+-------------------------------------------------------------------------
  1612. //
  1613. // Member: CDefObject::EnumDAdvise
  1614. //
  1615. // Synopsis: Enumerates advise connection (delegates to data advise cache)
  1616. //
  1617. // Effects:
  1618. //
  1619. // Arguments: [ppenumAdvise] -- where to put a pointer to the enumerator
  1620. //
  1621. // Requires:
  1622. //
  1623. // Returns: HRESULT
  1624. //
  1625. // Signals:
  1626. //
  1627. // Modifies:
  1628. //
  1629. // Derivation: IDataObject
  1630. //
  1631. // Algorithm:
  1632. //
  1633. // History: dd-mmm-yy Author Comment
  1634. // 05-Nov-93 alexgo 32bit port
  1635. //
  1636. // Notes: We do NOT need to stabilize this method, as we make
  1637. // no outgoing calls (EnumAdvise on the data advise cache
  1638. // just allocates an advise enumerator which we implement)
  1639. //
  1640. //--------------------------------------------------------------------------
  1641. STDMETHODIMP CDefObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise )
  1642. {
  1643. VDATEHEAP();
  1644. VDATETHREAD(this);
  1645. HRESULT hresult;
  1646. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::EnumDAdvise "
  1647. "( %p )\n", this, ppenumAdvise));
  1648. VDATEPTROUT( ppenumAdvise, LPENUMSTATDATA );
  1649. *ppenumAdvise = NULL;
  1650. hresult = m_pDataAdvCache->EnumAdvise (ppenumAdvise);
  1651. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::EnumDAdvise "
  1652. "( %lx ) [ %p ]\n", this, hresult, *ppenumAdvise));
  1653. return hresult;
  1654. }
  1655. /*
  1656. * IMPLEMENTATION of COleObjectImpl methods
  1657. *
  1658. */
  1659. //+-------------------------------------------------------------------------
  1660. //
  1661. // Member: CDefObject::COleObjectImpl::GetOleDelegate
  1662. //
  1663. // Synopsis: Gets the IID_IOleObject interface from the delegate
  1664. //
  1665. // Effects:
  1666. //
  1667. // Arguments: void
  1668. //
  1669. // Requires:
  1670. //
  1671. // Returns: IOleObject *
  1672. //
  1673. // Signals:
  1674. //
  1675. // Modifies:
  1676. //
  1677. // Derivation:
  1678. //
  1679. // Algorithm:
  1680. //
  1681. // History: dd-mmm-yy Author Comment
  1682. // 05-Nov-93 alexgo 32bit port
  1683. //
  1684. // Notes:
  1685. //
  1686. //--------------------------------------------------------------------------
  1687. INTERNAL_(IOleObject FAR*) CDefObject::GetOleDelegate(void)
  1688. {
  1689. VDATEHEAP();
  1690. if( IsZombie() )
  1691. {
  1692. return NULL;
  1693. }
  1694. return (IOleObject FAR*)DuCacheDelegate(&m_pUnkDelegate,
  1695. IID_IOleObject, (LPLPVOID) &m_pOleDelegate, m_pUnkOuter);
  1696. }
  1697. //+-------------------------------------------------------------------------
  1698. //
  1699. // Member: CDefObject::COleObjectImpl::SetClientSite
  1700. //
  1701. // Synopsis: Sets the client site for the object
  1702. //
  1703. // Effects:
  1704. //
  1705. // Arguments: [pClientSite] -- pointer to the client site
  1706. //
  1707. // Requires:
  1708. //
  1709. // Returns: HRESULT
  1710. //
  1711. // Signals:
  1712. //
  1713. // Modifies:
  1714. //
  1715. // Derivation: IOleObject
  1716. //
  1717. // Algorithm: If running, set the client site in the server, if not
  1718. // running (or successfully set the server client site),
  1719. // save it in the handler as well
  1720. //
  1721. // History: dd-mmm-yy Author Comment
  1722. // 05-Nov-93 alexgo 32bit port
  1723. //
  1724. // Notes:
  1725. //
  1726. //--------------------------------------------------------------------------
  1727. STDMETHODIMP CDefObject::SetClientSite(IOleClientSite * pClientSite)
  1728. {
  1729. VDATEHEAP();
  1730. VDATETHREAD(this);
  1731. HRESULT hresult = S_OK;
  1732. IOleObject * pOleDelegate;
  1733. BOOL fIsRunning;
  1734. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetClientSite "
  1735. "( %p )\n", this, pClientSite));
  1736. CRefStabilize stabilize(this);
  1737. #if DBG==1
  1738. // In Debug builds, assert that the clientsite is in the same
  1739. // apartment. This assert is harmless but shows the deficiency
  1740. // of the current design in loading INPROC servers
  1741. CStdIdentity* pStdId = NULL;
  1742. // QI for IStdIdentity
  1743. if(pClientSite &&
  1744. pClientSite->QueryInterface(IID_IStdIdentity, (void **)&pStdId) ==
  1745. NOERROR) {
  1746. // Assert that DefHandler and ClientSite not in the same apartment
  1747. LEDebugOut((DEB_WARN,"Performance Alert: Default Handler and "
  1748. "ClientSite not in the same apartment. "
  1749. "You can avoid this performance problem "
  1750. "by making the Server Dll apartment aware"));
  1751. // Release the StdIdentity as it succeded
  1752. pStdId->Release();
  1753. }
  1754. #endif
  1755. fIsRunning=IsRunning();
  1756. if( (fIsRunning) && (pOleDelegate = GetOleDelegate()) != NULL)
  1757. {
  1758. #ifdef SERVER_HANDLER
  1759. if (m_pEmbSrvHndlrWrapper)
  1760. {
  1761. // Todo: Need to handle case ClientSite is the Wrapped one like DoVerb.
  1762. // Win4Assert(0 && "SetClientSite while running");
  1763. hresult = m_pEmbSrvHndlrWrapper->SetClientSite(pClientSite);
  1764. }
  1765. else
  1766. #endif // SERVER_HANDLER
  1767. {
  1768. hresult = pOleDelegate->SetClientSite(pClientSite);
  1769. }
  1770. if( hresult != NOERROR )
  1771. {
  1772. goto errRtn;
  1773. }
  1774. }
  1775. // we shouldn't set the client site if we are in a zombie state;
  1776. // it's possible that we're zombied and have already gotten
  1777. // to the point in our destructor where we release the client
  1778. // site. Resetting it here would cause an unbalanced addref.
  1779. if( IsZombie() == FALSE )
  1780. {
  1781. BOOL fLockedContainer = m_flags & DH_LOCKED_CONTAINER;
  1782. fIsRunning=IsRunning(); // I am chicken, maybe running state has changed!
  1783. hresult = DuSetClientSite(fIsRunning, pClientSite,
  1784. &m_pAppClientSite, &fLockedContainer);
  1785. if(fLockedContainer)
  1786. m_flags |= DH_LOCKED_CONTAINER;
  1787. else
  1788. m_flags &= ~DH_LOCKED_CONTAINER;
  1789. #if DBG==1
  1790. // In debug builds, update DH_LOCKFAILED flag
  1791. if(fIsRunning) {
  1792. if(fLockedContainer)
  1793. m_flags &= ~DH_LOCKFAILED;
  1794. else
  1795. m_flags |= DH_LOCKFAILED;
  1796. }
  1797. #endif
  1798. }
  1799. errRtn:
  1800. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SetClientSite "
  1801. "( %lx )\n", this, hresult));
  1802. return hresult;
  1803. }
  1804. //+-------------------------------------------------------------------------
  1805. //
  1806. // Member: CDefObject::GetClientSite
  1807. //
  1808. // Synopsis: returns the client site of the object
  1809. //
  1810. // Effects:
  1811. //
  1812. // Arguments: [ppClientSite] -- where to put the client site pointer
  1813. //
  1814. // Requires:
  1815. //
  1816. // Returns: NOERROR
  1817. //
  1818. // Signals:
  1819. //
  1820. // Modifies:
  1821. //
  1822. // Derivation: IOleObject
  1823. //
  1824. // Algorithm:
  1825. //
  1826. // History: dd-mmm-yy Author Comment
  1827. // 05-Nov-93 alexgo 32bit port
  1828. //
  1829. // Notes: We do NOT need to stabilize this call. The client
  1830. // site addref should simply addref the client site on this
  1831. // thread.
  1832. //
  1833. //--------------------------------------------------------------------------
  1834. STDMETHODIMP CDefObject::GetClientSite( IOleClientSite ** ppClientSite)
  1835. {
  1836. VDATEHEAP();
  1837. VDATETHREAD(this);
  1838. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetClientSite "
  1839. "( %p )\n", this, ppClientSite));
  1840. VDATEPTROUT(ppClientSite, IOleClientSite *);
  1841. *ppClientSite = m_pAppClientSite;
  1842. if( *ppClientSite )
  1843. {
  1844. (*ppClientSite)->AddRef();
  1845. }
  1846. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetClientSite "
  1847. "( %lx ) [ %p ]\n", this, NOERROR, *ppClientSite));
  1848. return NOERROR;
  1849. }
  1850. //+-------------------------------------------------------------------------
  1851. //
  1852. // Member: CDefObject::SetHostNames
  1853. //
  1854. // Synopsis: Sets the name that may appear in an object's window
  1855. //
  1856. // Effects: Turns the strings into atoms
  1857. //
  1858. // Arguments: [szContainerApp] -- name of the container
  1859. // [szContainerObj] -- name of the object
  1860. //
  1861. // Requires:
  1862. //
  1863. // Returns: HRESULT
  1864. //
  1865. // Signals:
  1866. //
  1867. // Modifies:
  1868. //
  1869. // Derivation: IOleObject
  1870. //
  1871. // Algorithm: turns the strings into atoms, calls IOO->SetHostNames
  1872. // on the delegate
  1873. //
  1874. // History: dd-mmm-yy Author Comment
  1875. // 05-Nov-93 alexgo 32bit port
  1876. //
  1877. // Notes:
  1878. //
  1879. //--------------------------------------------------------------------------
  1880. STDMETHODIMP CDefObject::SetHostNames( LPCOLESTR szContainerApp,
  1881. LPCOLESTR szContainerObj)
  1882. {
  1883. VDATEHEAP();
  1884. VDATETHREAD(this);
  1885. HRESULT hresult = NOERROR;
  1886. OLECHAR szNull[] = OLESTR("");
  1887. DWORD cbApp, cbObj;
  1888. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetHostNames "
  1889. "( \"%ws\" , \"%ws\" )\n", this, szContainerApp,
  1890. szContainerObj));
  1891. VDATEPTRIN( (LPVOID)szContainerApp, char );
  1892. CRefStabilize stabilize(this);
  1893. if( (m_flags & DH_STATIC) )
  1894. {
  1895. hresult = OLE_E_STATIC;
  1896. goto errRtn;
  1897. }
  1898. // Make sure both arguments point to a valid string; this
  1899. // simplifies the code that follows.
  1900. if (!szContainerApp)
  1901. {
  1902. szContainerApp = szNull;
  1903. }
  1904. if (!szContainerObj)
  1905. {
  1906. szContainerObj = szNull;
  1907. }
  1908. cbApp = (_xstrlen(szContainerApp) + 1) * sizeof(OLECHAR);
  1909. cbObj = (_xstrlen(szContainerObj) + 1) * sizeof(OLECHAR);
  1910. m_ibCntrObj = cbApp;
  1911. if (m_pHostNames)
  1912. {
  1913. PrivMemFree(m_pHostNames);
  1914. }
  1915. m_pHostNames = (char *)PrivMemAlloc(cbApp+cbObj);
  1916. // Store the two strings in the m_pHostNames pointer.
  1917. if (m_pHostNames)
  1918. {
  1919. memcpy(m_pHostNames, szContainerApp, cbApp);
  1920. memcpy(m_pHostNames + cbApp, szContainerObj, cbObj);
  1921. }
  1922. if( IsRunning() && GetOleDelegate() )
  1923. {
  1924. hresult = m_pOleDelegate->SetHostNames(szContainerApp,
  1925. szContainerObj);
  1926. }
  1927. errRtn:
  1928. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SetHostNames "
  1929. "( %lx )\n", this, hresult));
  1930. return hresult;
  1931. }
  1932. //+-------------------------------------------------------------------------
  1933. //
  1934. // Member: CDefObject::Close
  1935. //
  1936. // Synopsis: calls Close on the delegate and does cleanup
  1937. //
  1938. // Arguments: [dwFlags] -- close flags
  1939. //
  1940. // Returns: HRESULT
  1941. //
  1942. // History: dd-mmm-yy Author Comment
  1943. // 10-Jan-96 Gopalk Rewritten
  1944. //--------------------------------------------------------------------------
  1945. STDMETHODIMP CDefObject::Close(DWORD dwFlags)
  1946. {
  1947. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Close(%lu)\n", this, dwFlags));
  1948. // Validation checks
  1949. VDATEHEAP();
  1950. VDATETHREAD(this);
  1951. // Local variables
  1952. HRESULT hresult = NOERROR;
  1953. CRefStabilize stabilize(this);
  1954. // Check if the server is running
  1955. if(IsRunning()) {
  1956. // Call IOleObject::Close on the server
  1957. if(m_pOleDelegate || GetOleDelegate()) {
  1958. hresult = m_pOleDelegate->Close(dwFlags);
  1959. if(SUCCEEDED(hresult)) {
  1960. // Discard cache if requested
  1961. if(dwFlags == OLECLOSE_NOSAVE)
  1962. m_pCOleCache->DiscardCache(DISCARDCACHE_NOSAVE);
  1963. }
  1964. }
  1965. // Do not rely on server calling IAdviseSink::OnClose and
  1966. // stop the running server
  1967. Stop();
  1968. }
  1969. else {
  1970. // Check the save flags
  1971. if (dwFlags != OLECLOSE_NOSAVE) {
  1972. Win4Assert(dwFlags == OLECLOSE_SAVEIFDIRTY);
  1973. // Call IOleClientSite::SaveObject if dirty
  1974. if(IsDirty()==NOERROR && m_pAppClientSite)
  1975. hresult = m_pAppClientSite->SaveObject();
  1976. }
  1977. }
  1978. // Assert that the container is not locked
  1979. Win4Assert(!(m_flags & DH_LOCKED_CONTAINER) && !(m_flags & DH_LOCKFAILED));
  1980. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Close(%lx)\n", this, hresult));
  1981. return hresult;
  1982. }
  1983. //+-------------------------------------------------------------------------
  1984. //
  1985. // Member: CDefObject::SetMoniker
  1986. //
  1987. // Synopsis: Gives a moniker to the embedding (usually called by the
  1988. // container)
  1989. //
  1990. // Effects:
  1991. //
  1992. // Arguments: [dwWhichMoniker] -- flags to indicate the type of
  1993. // moniker
  1994. // [pmk] -- the moniker
  1995. //
  1996. // Requires:
  1997. //
  1998. // Returns: HRESULT
  1999. //
  2000. // Signals:
  2001. //
  2002. // Modifies:
  2003. //
  2004. // Derivation: IOleObject
  2005. //
  2006. // Algorithm: delegates to the server object
  2007. //
  2008. // History: dd-mmm-yy Author Comment
  2009. // 07-Nov-93 alexgo 32bit port
  2010. //
  2011. // Notes:
  2012. //
  2013. //--------------------------------------------------------------------------
  2014. STDMETHODIMP CDefObject::SetMoniker( DWORD dwWhichMoniker, LPMONIKER pmk )
  2015. {
  2016. VDATEHEAP();
  2017. VDATETHREAD(this);
  2018. HRESULT hresult = NOERROR;
  2019. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetMoniker "
  2020. "( %lu , %p )\n", this, dwWhichMoniker, pmk));
  2021. VDATEIFACE( pmk );
  2022. CRefStabilize stabilize(this);
  2023. if( IsRunning() && GetOleDelegate() )
  2024. {
  2025. hresult = m_pOleDelegate->SetMoniker(dwWhichMoniker, pmk);
  2026. }
  2027. // else case: return NOERROR
  2028. // this is not an error since we will call SetMoniker in Run().
  2029. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::COleObjectImpl::SetMoniker "
  2030. "( %lx )\n", this, hresult));
  2031. return hresult;
  2032. }
  2033. //+-------------------------------------------------------------------------
  2034. //
  2035. // Member: CDefObject::COleObjectImpl::GetMoniker
  2036. //
  2037. // Synopsis: Calls the client site to get the object's moniker
  2038. //
  2039. // Effects:
  2040. //
  2041. // Arguments: [dwAssign] -- controls whether a moniker should be
  2042. // assigned if not already present
  2043. // [dwWhichMoniker] -- the moniker type to get
  2044. // [ppmk] -- where to put a pointer to the moniker
  2045. //
  2046. // Requires:
  2047. //
  2048. // Returns: HRESULT
  2049. //
  2050. // Signals:
  2051. //
  2052. // Modifies:
  2053. //
  2054. // Derivation: IOleObject
  2055. //
  2056. // Algorithm:
  2057. //
  2058. // History: dd-mmm-yy Author Comment
  2059. // 07-Nov-93 alexgo 32bit port
  2060. //
  2061. // Notes:
  2062. //
  2063. //--------------------------------------------------------------------------
  2064. STDMETHODIMP CDefObject::GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker,
  2065. LPMONIKER FAR* ppmk)
  2066. {
  2067. VDATEHEAP();
  2068. VDATETHREAD(this);
  2069. HRESULT hresult;
  2070. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetMoniker "
  2071. "( %lu , %lu , %p )\n", this, dwAssign,
  2072. dwWhichMoniker, ppmk));
  2073. VDATEPTROUT( ppmk, LPMONIKER );
  2074. CRefStabilize stabilize(this);
  2075. *ppmk = NULL;
  2076. // the moniker is always accessible via the client site
  2077. if( m_pAppClientSite)
  2078. {
  2079. hresult = m_pAppClientSite->GetMoniker(dwAssign,
  2080. dwWhichMoniker, ppmk);
  2081. }
  2082. else
  2083. {
  2084. // not running and no client site
  2085. hresult = E_UNSPEC;
  2086. }
  2087. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetMoniker "
  2088. "( %lx ) [ %p ]\n", this, hresult, *ppmk));
  2089. return hresult;
  2090. }
  2091. //+-------------------------------------------------------------------------
  2092. //
  2093. // Member: CDefObject::InitFromData
  2094. //
  2095. // Synopsis: Initializes the object from the data in [pDataObject]
  2096. //
  2097. // Effects:
  2098. //
  2099. // Arguments: [pDataObject] -- the data
  2100. // [fCreation] -- TRUE on creation, FALSE for data transfer
  2101. // [dwReserved] -- unused
  2102. //
  2103. // Requires:
  2104. //
  2105. // Returns: HRESULT
  2106. //
  2107. // Signals:
  2108. //
  2109. // Modifies:
  2110. //
  2111. // Derivation: IOleObject
  2112. //
  2113. // Algorithm: delegates to the server
  2114. //
  2115. // History: dd-mmm-yy Author Comment
  2116. // 07-Nov-93 alexgo 32bit port
  2117. //
  2118. // Notes:
  2119. //
  2120. //--------------------------------------------------------------------------
  2121. STDMETHODIMP CDefObject::InitFromData(LPDATAOBJECT pDataObject,
  2122. BOOL fCreation, DWORD dwReserved)
  2123. {
  2124. VDATEHEAP();
  2125. VDATETHREAD(this);
  2126. HRESULT hresult;
  2127. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::InitFromData "
  2128. "( %p , %ld , %lu )\n", this, pDataObject,
  2129. fCreation, dwReserved ));
  2130. if( pDataObject )
  2131. {
  2132. VDATEIFACE(pDataObject);
  2133. }
  2134. CRefStabilize stabilize(this);
  2135. if( IsRunning() && GetOleDelegate() )
  2136. {
  2137. hresult = m_pOleDelegate->InitFromData(pDataObject,
  2138. fCreation, dwReserved);
  2139. }
  2140. else
  2141. {
  2142. hresult = OLE_E_NOTRUNNING;
  2143. }
  2144. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::InitFromData "
  2145. "( %lx )\n", this, hresult));
  2146. return hresult;
  2147. }
  2148. //+-------------------------------------------------------------------------
  2149. //
  2150. // Member: CDefObject::GetClipboardData
  2151. //
  2152. // Synopsis: Retrieves a data object that could be passed to the clipboard
  2153. //
  2154. // Effects:
  2155. //
  2156. // Arguments: [dwReserverd] -- unused
  2157. // [ppDataObject] -- where to put the pointer to the data object
  2158. //
  2159. // Requires:
  2160. //
  2161. // Returns: HRESULT
  2162. //
  2163. // Signals:
  2164. //
  2165. // Modifies:
  2166. //
  2167. // Derivation: IOleObject
  2168. //
  2169. // Algorithm: delegates to the server
  2170. //
  2171. // History: dd-mmm-yy Author Comment
  2172. // 07-Nov-93 alexgo 32bit port
  2173. //
  2174. // Notes:
  2175. //
  2176. //--------------------------------------------------------------------------
  2177. STDMETHODIMP CDefObject::GetClipboardData( DWORD dwReserved,
  2178. LPDATAOBJECT * ppDataObject)
  2179. {
  2180. VDATEHEAP();
  2181. VDATETHREAD(this);
  2182. HRESULT hresult;
  2183. LEDebugOut((DEB_TRACE,
  2184. "%p _IN CDefObject::GetClipboardData "
  2185. "( %lu , %p )\n", this, dwReserved, ppDataObject));
  2186. VDATEPTROUT( ppDataObject, LPDATAOBJECT );
  2187. CRefStabilize stabilize(this);
  2188. *ppDataObject = NULL;
  2189. if( IsRunning() && GetOleDelegate() )
  2190. {
  2191. hresult = m_pOleDelegate->GetClipboardData (dwReserved,
  2192. ppDataObject);
  2193. }
  2194. else
  2195. {
  2196. hresult = OLE_E_NOTRUNNING;
  2197. }
  2198. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetClipboardData "
  2199. "( %lx ) [ %p ]\n", this, hresult, *ppDataObject));
  2200. return hresult;
  2201. }
  2202. //+-------------------------------------------------------------------------
  2203. //
  2204. // Member: CDefObject::DoVerb
  2205. //
  2206. // Synopsis: Calls a verb on the object (such as Edit)
  2207. //
  2208. // Effects: The object may launch its app, go in place, etc
  2209. //
  2210. // Arguments: [iVerb] -- the verb number
  2211. // [lpmsg] -- the windows message that caused the verb
  2212. // to be invoked
  2213. // [pActiveSite] -- the client site in which the verb was
  2214. // invoked
  2215. // [lindex] -- reserved
  2216. // [hwndParent] -- the document window (containing the object)
  2217. // [lprcPosRect] -- the object's bounding rectangle
  2218. //
  2219. // Requires:
  2220. //
  2221. // Returns: HRESULT
  2222. //
  2223. // Signals:
  2224. //
  2225. // Modifies:
  2226. //
  2227. // Derivation: IOleObject
  2228. //
  2229. // Algorithm: delegates to the server (launching it if necessary)
  2230. //
  2231. // History: dd-mmm-yy Author Comment
  2232. // 07-Nov-93 alexgo 32bit port
  2233. //
  2234. // Notes:
  2235. //
  2236. //--------------------------------------------------------------------------
  2237. STDMETHODIMP CDefObject::DoVerb( LONG iVerb, LPMSG lpmsg,
  2238. LPOLECLIENTSITE pActiveSite, LONG lindex,
  2239. HWND hwndParent, const RECT * lprcPosRect)
  2240. {
  2241. VDATEHEAP();
  2242. VDATETHREAD(this);
  2243. BOOL bStartedNow = FALSE;
  2244. HRESULT hresult;
  2245. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::DoVerb "
  2246. "( %ld , %p , %p , %ld , %lx , %p )\n", this,
  2247. iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect));
  2248. if( lpmsg )
  2249. {
  2250. VDATEPTRIN( lpmsg, MSG );
  2251. }
  2252. if (pActiveSite)
  2253. {
  2254. VDATEIFACE( pActiveSite );
  2255. }
  2256. if( lprcPosRect )
  2257. {
  2258. VDATEPTRIN(lprcPosRect, RECT);
  2259. }
  2260. CRefStabilize stabilize(this);
  2261. if (lindex != 0 && lindex != -1)
  2262. {
  2263. hresult = DV_E_LINDEX;
  2264. goto errRtn;
  2265. }
  2266. if (!IsRunning())
  2267. {
  2268. if( FAILED(hresult = Run(NULL)) )
  2269. {
  2270. goto errRtn;
  2271. }
  2272. bStartedNow = TRUE;
  2273. }
  2274. #ifdef SERVER_HANDLER
  2275. if (m_pEmbSrvHndlrWrapper)
  2276. {
  2277. LPOLECLIENTSITE pOleClientSite = NULL;
  2278. BOOL fUseRunClientSite = FALSE;
  2279. // Marshal the ClientSite based on if same ClientSite passed in Run
  2280. if ( m_pRunClientSite && (m_pRunClientSite == pActiveSite))
  2281. {
  2282. pOleClientSite = NULL;
  2283. fUseRunClientSite = TRUE;
  2284. }
  2285. else
  2286. {
  2287. pOleClientSite = pActiveSite;
  2288. fUseRunClientSite = FALSE;
  2289. }
  2290. // Todo: Can prefetch information to pass along to ClientSiteHandler.
  2291. hresult = m_pEmbSrvHndlrWrapper->DoVerb(iVerb, lpmsg,
  2292. fUseRunClientSite, pOleClientSite, lindex, hwndParent, lprcPosRect);
  2293. }
  2294. else
  2295. #endif // SERVER_HANDLER
  2296. {
  2297. if( !GetOleDelegate() )
  2298. {
  2299. hresult = E_NOINTERFACE;
  2300. }
  2301. else
  2302. {
  2303. hresult = m_pOleDelegate->DoVerb(iVerb, lpmsg, pActiveSite,
  2304. lindex, hwndParent, lprcPosRect);
  2305. }
  2306. }
  2307. if (FAILED(hresult) && bStartedNow)
  2308. {
  2309. Close(OLECLOSE_NOSAVE);
  2310. }
  2311. errRtn:
  2312. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::DoVerb "
  2313. "( %lx )\n", this, hresult));
  2314. return hresult;
  2315. }
  2316. //+-------------------------------------------------------------------------
  2317. //
  2318. // Member: CDefObject::EnumVerbs
  2319. //
  2320. // Synopsis: Enumerates the verbs that an object supports
  2321. //
  2322. // Effects:
  2323. //
  2324. // Arguments: [ppenumOleVerb] -- where to put the verb enumerator
  2325. //
  2326. // Requires:
  2327. //
  2328. // Returns: HRESULT
  2329. //
  2330. // Signals:
  2331. //
  2332. // Modifies:
  2333. //
  2334. // Derivation: IOleObject
  2335. //
  2336. // Algorithm: delegates to the cache (if running), otherwise looks it up
  2337. // in the registration database
  2338. //
  2339. // History: dd-mmm-yy Author Comment
  2340. // 07-Nov-93 alexgo 32bit port
  2341. //
  2342. // Notes:
  2343. //
  2344. //--------------------------------------------------------------------------
  2345. STDMETHODIMP CDefObject::EnumVerbs( IEnumOLEVERB ** ppenumOleVerb)
  2346. {
  2347. VDATEHEAP();
  2348. VDATETHREAD(this);
  2349. HRESULT hresult;
  2350. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::EnumVerbs "
  2351. "( %p )\n", this, ppenumOleVerb));
  2352. VDATEPTROUT( ppenumOleVerb, IEnumOLEVERB FAR );
  2353. CRefStabilize stabilize(this);
  2354. *ppenumOleVerb = NULL;
  2355. if( IsRunning() && GetOleDelegate() )
  2356. {
  2357. hresult = m_pOleDelegate->EnumVerbs (ppenumOleVerb);
  2358. if (!GET_FROM_REGDB(hresult))
  2359. {
  2360. goto errRtn;
  2361. }
  2362. }
  2363. // Not running, or object deferred to us, so interrogate reg db
  2364. hresult = OleRegEnumVerbs( m_clsidServer, ppenumOleVerb);
  2365. errRtn:
  2366. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::EnumVerbs "
  2367. "( %lx ) [ %p ]\n", this, hresult, *ppenumOleVerb));
  2368. return hresult;
  2369. }
  2370. //+-------------------------------------------------------------------------
  2371. //
  2372. // Member: CDefObject::Update
  2373. //
  2374. // Synopsis: Brings any caches or views up-to-date
  2375. //
  2376. // Effects: may launch the server (if not already running)
  2377. //
  2378. // Arguments: void
  2379. //
  2380. // Requires:
  2381. //
  2382. // Returns: HRESULT
  2383. //
  2384. // Signals:
  2385. //
  2386. // Modifies:
  2387. //
  2388. // Derivation: IOleObject
  2389. //
  2390. // Algorithm: delegates to the server, launching it if it is not
  2391. // already running
  2392. //
  2393. // History: dd-mmm-yy Author Comment
  2394. // 07-Nov-93 alexgo 32bit port
  2395. //
  2396. // Notes:
  2397. //
  2398. //--------------------------------------------------------------------------
  2399. STDMETHODIMP CDefObject::Update( void )
  2400. {
  2401. VDATEHEAP();
  2402. VDATETHREAD(this);
  2403. BOOL bStartedNow = FALSE;
  2404. HRESULT hresult = NOERROR;
  2405. HRESULT hrLock;
  2406. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Update ( )\n", this ));
  2407. CRefStabilize stabilize(this);
  2408. if( (m_flags & DH_STATIC) )
  2409. {
  2410. hresult = OLE_E_STATIC;
  2411. goto errRtn;
  2412. }
  2413. if (!IsRunning())
  2414. {
  2415. if( FAILED(hresult = Run(NULL)))
  2416. {
  2417. goto errRtn;
  2418. }
  2419. bStartedNow = TRUE;
  2420. }
  2421. // as a convenience to the server, we make the connection strong
  2422. // for the duration of the update; thus, if lock container (of
  2423. // embedings of this server) is done with co lock obj external,
  2424. // nothing special need be done.
  2425. hrLock = LockRunning(TRUE, FALSE);
  2426. if( GetOleDelegate() )
  2427. {
  2428. hresult = m_pOleDelegate->Update();
  2429. }
  2430. if (hresult == NOERROR)
  2431. {
  2432. m_flags &= ~DH_INIT_NEW;
  2433. if (bStartedNow)
  2434. {
  2435. hresult = m_pCOleCache->UpdateCache(
  2436. GetDataDelegate(),
  2437. UPDFCACHE_ALLBUTNODATACACHE,
  2438. NULL);
  2439. }
  2440. else
  2441. {
  2442. // already running...
  2443. // normal caches would have got updated as a result
  2444. // of SendOnDataChange of the object.
  2445. hresult = m_pCOleCache->UpdateCache(
  2446. GetDataDelegate(),
  2447. UPDFCACHE_IFBLANKORONSAVECACHE,
  2448. NULL);
  2449. }
  2450. }
  2451. // balance lock above; do not release on last unlock; i.e., siliently
  2452. // restore to the state before this routine was called.
  2453. if( hrLock == NOERROR )
  2454. {
  2455. LockRunning(FALSE, FALSE);
  2456. }
  2457. if( bStartedNow )
  2458. {
  2459. Close(OLECLOSE_SAVEIFDIRTY);
  2460. }
  2461. errRtn:
  2462. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Update "
  2463. "( %lx )\n", this, hresult ));
  2464. return hresult;
  2465. }
  2466. //+-------------------------------------------------------------------------
  2467. //
  2468. // Member: CDefObject::IsUpToDate
  2469. //
  2470. // Synopsis: returns whether or not the embedding is up-to-date
  2471. //
  2472. // Effects:
  2473. //
  2474. // Arguments: void
  2475. //
  2476. // Requires:
  2477. //
  2478. // Returns: HRESULT (NOERROR == is up to date)
  2479. //
  2480. // Signals:
  2481. //
  2482. // Modifies:
  2483. //
  2484. // Derivation: IOleObject
  2485. //
  2486. // Algorithm: delegates to the server if it is running
  2487. //
  2488. // History: dd-mmm-yy Author Comment
  2489. // 07-Nov-93 alexgo 32bit port
  2490. //
  2491. // Notes:
  2492. //
  2493. //--------------------------------------------------------------------------
  2494. STDMETHODIMP CDefObject::IsUpToDate(void)
  2495. {
  2496. VDATEHEAP();
  2497. VDATETHREAD(this);
  2498. HRESULT hresult;
  2499. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::IsUpToDate ( )\n", this));
  2500. CRefStabilize stabilize(this);
  2501. if( (m_flags & DH_STATIC) )
  2502. {
  2503. hresult = NOERROR;
  2504. }
  2505. else if( IsRunning() && GetOleDelegate() )
  2506. {
  2507. // if running currently, propogate call; else fail
  2508. hresult = m_pOleDelegate->IsUpToDate();
  2509. }
  2510. else
  2511. {
  2512. hresult = OLE_E_NOTRUNNING;
  2513. }
  2514. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::IsUpToDate "
  2515. "( %lx )\n", this, hresult));
  2516. return hresult;
  2517. }
  2518. //+-------------------------------------------------------------------------
  2519. //
  2520. // Member: CDefObject::SetExtent
  2521. //
  2522. // Synopsis: Set's the size boundaries on an object
  2523. //
  2524. // Effects:
  2525. //
  2526. // Arguments: [dwDrawAspect] -- the drawing aspect (such as ICON, etc)
  2527. // [lpsizel] -- the new size (in HIMETRIC)
  2528. //
  2529. // Requires:
  2530. //
  2531. // Returns: HRESULT
  2532. //
  2533. // Signals:
  2534. //
  2535. // Modifies:
  2536. //
  2537. // Derivation: IOleObject
  2538. //
  2539. // Algorithm: delegates to the server if running
  2540. //
  2541. // History: dd-mmm-yy Author Comment
  2542. // 07-Nov-93 alexgo 32bit port
  2543. //
  2544. // Notes:
  2545. //
  2546. //--------------------------------------------------------------------------
  2547. STDMETHODIMP CDefObject::SetExtent( DWORD dwDrawAspect, LPSIZEL lpsizel )
  2548. {
  2549. VDATEHEAP();
  2550. VDATETHREAD(this);
  2551. HRESULT hresult;
  2552. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetExtent "
  2553. "( %lu , %p )\n", this, dwDrawAspect, lpsizel));
  2554. VDATEPTRIN( lpsizel, SIZEL );
  2555. CRefStabilize stabilize(this);
  2556. if( (m_flags & DH_STATIC) )
  2557. {
  2558. hresult = OLE_E_STATIC;
  2559. }
  2560. else if( IsRunning() && GetOleDelegate() )
  2561. {
  2562. hresult = m_pOleDelegate->SetExtent(dwDrawAspect, lpsizel);
  2563. }
  2564. else
  2565. {
  2566. hresult = OLE_E_NOTRUNNING;
  2567. }
  2568. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SetExtent "
  2569. "( %lx )\n", this, hresult));
  2570. return hresult;
  2571. }
  2572. //+-------------------------------------------------------------------------
  2573. //
  2574. // Member: CDefObject::GetExtent
  2575. //
  2576. // Synopsis: Retrieve the size of the object
  2577. //
  2578. // Effects:
  2579. //
  2580. // Arguments: [dwDrawAspect] -- the drawing aspect (such as icon)
  2581. // [lpsizel] -- where to put the size
  2582. //
  2583. // Requires:
  2584. //
  2585. // Returns: HRESULT
  2586. //
  2587. // Signals:
  2588. //
  2589. // Modifies:
  2590. //
  2591. // Derivation: IOleObject
  2592. //
  2593. // Algorithm: Tries the server first, the the cache if that fails
  2594. //
  2595. // History: dd-mmm-yy Author Comment
  2596. // 07-Nov-93 alexgo 32bit port
  2597. //
  2598. // Notes: Hacks for bogus WordArt2.0 app.
  2599. // REVIEW32: We may want to take them out for 32bit
  2600. //
  2601. //--------------------------------------------------------------------------
  2602. STDMETHODIMP CDefObject::GetExtent( DWORD dwDrawAspect, LPSIZEL lpsizel )
  2603. {
  2604. VDATEHEAP();
  2605. VDATETHREAD(this);
  2606. VDATEPTROUT(lpsizel, SIZEL);
  2607. HRESULT hresult = NOERROR;
  2608. BOOL fNoDelegate = TRUE;
  2609. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetExtent "
  2610. "( %lu , %p )\n", this, dwDrawAspect, lpsizel));
  2611. CRefStabilize stabilize(this);
  2612. lpsizel->cx = 0;
  2613. lpsizel->cy = 0;
  2614. // if server is running try to get extents from the server
  2615. if( IsRunning() && GetOleDelegate() )
  2616. {
  2617. fNoDelegate = FALSE;
  2618. hresult = m_pOleDelegate->GetExtent(dwDrawAspect, lpsizel);
  2619. }
  2620. // if there is error or object is not running or WordArt2 returns zero
  2621. // extents, then get extents from Cache
  2622. if (hresult != NOERROR || fNoDelegate || (0==lpsizel->cx &&
  2623. 0==lpsizel->cy))
  2624. {
  2625. // Otherwise try to get extents from cache
  2626. Assert(m_pCOleCache != NULL);
  2627. hresult = m_pCOleCache->GetExtent(dwDrawAspect,
  2628. lpsizel);
  2629. }
  2630. // WordArt2.0 is giving negative extents!!
  2631. if (SUCCEEDED(hresult)) {
  2632. lpsizel->cx = LONG_ABS(lpsizel->cx);
  2633. lpsizel->cy = LONG_ABS(lpsizel->cy);
  2634. }
  2635. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetExtent "
  2636. "( %lx )\n", this, hresult));
  2637. return hresult;
  2638. }
  2639. //+-------------------------------------------------------------------------
  2640. //
  2641. // Member: CDefObject::Advise
  2642. //
  2643. // Synopsis: Sets up an advise connection for things like close, save,
  2644. // rename, etc.
  2645. //
  2646. // Effects: Creates an OleAdviseHolder
  2647. //
  2648. // Arguments: [pAdvSink] -- whom to advise
  2649. // [pdwConnection] -- where to put the connection ID
  2650. //
  2651. // Requires:
  2652. //
  2653. // Returns: HRESULT
  2654. //
  2655. // Signals:
  2656. //
  2657. // Modifies:
  2658. //
  2659. // Derivation: IOleObject
  2660. //
  2661. // Algorithm: delegates to the server and creates a an OleAdviseHolder
  2662. // if one doesn't already exist
  2663. //
  2664. // History: dd-mmm-yy Author Comment
  2665. // 07-Nov-93 alexgo 32bit port
  2666. //
  2667. // Notes:
  2668. //
  2669. //--------------------------------------------------------------------------
  2670. STDMETHODIMP CDefObject::Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection)
  2671. {
  2672. VDATEHEAP();
  2673. VDATETHREAD(this);
  2674. HRESULT hresult;
  2675. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Advise "
  2676. "( %p , %p )\n", this, pAdvSink, pdwConnection));
  2677. VDATEIFACE( pAdvSink );
  2678. VDATEPTROUT( pdwConnection, DWORD );
  2679. CRefStabilize stabilize(this);
  2680. *pdwConnection = NULL;
  2681. if( (m_flags & DH_STATIC) )
  2682. {
  2683. hresult = OLE_E_STATIC;
  2684. goto errRtn;
  2685. }
  2686. // if defhndlr got running without going through run, setup advise.
  2687. // The call to run (via ProxyMgr::Connect) always comes before any
  2688. // other method call in the default handler. Thus it is safe to
  2689. // assume that there is no earlier point by which this advise (or any
  2690. // other of the calls) should have been done.
  2691. if( IsRunning() && m_dwConnOle == 0L && GetOleDelegate() )
  2692. {
  2693. if( IsZombie() )
  2694. {
  2695. hresult = CO_E_RELEASED;
  2696. goto errRtn;
  2697. }
  2698. // delegate to the server
  2699. hresult = m_pOleDelegate->Advise((IAdviseSink *)&m_AdviseSink,
  2700. &m_dwConnOle);
  2701. if( hresult != NOERROR )
  2702. {
  2703. goto errRtn;
  2704. }
  2705. }
  2706. // if we are in a zombie state, we shouldn't go allocate more
  2707. // memory.
  2708. if( IsZombie() )
  2709. {
  2710. hresult = CO_E_RELEASED;
  2711. }
  2712. if( m_pOAHolder == NULL )
  2713. {
  2714. hresult = CreateOleAdviseHolder((IOleAdviseHolder **)&m_pOAHolder);
  2715. if( hresult != NOERROR )
  2716. {
  2717. goto errRtn;
  2718. }
  2719. }
  2720. // stuff the advise notification in our advise holder
  2721. hresult = m_pOAHolder->Advise(pAdvSink, pdwConnection);
  2722. errRtn:
  2723. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Advise "
  2724. "( %lx ) [ %lu ]\n", this, hresult,
  2725. (pdwConnection)? *pdwConnection : 0));
  2726. return hresult;
  2727. }
  2728. //+-------------------------------------------------------------------------
  2729. //
  2730. // Member: CDefObject::COleObjectImpl::Unadvise
  2731. //
  2732. // Synopsis: Tears down an advise connection
  2733. //
  2734. // Effects:
  2735. //
  2736. // Arguments: [dwConnection] -- the connection to destroy
  2737. //
  2738. // Requires:
  2739. //
  2740. // Returns: HRESULT
  2741. //
  2742. // Signals:
  2743. //
  2744. // Modifies:
  2745. //
  2746. // Derivation: IOleObject
  2747. //
  2748. // Algorithm:
  2749. //
  2750. // History: dd-mmm-yy Author Comment
  2751. // 07-Nov-93 alexgo 32bit port
  2752. //
  2753. // Notes:
  2754. //
  2755. //--------------------------------------------------------------------------
  2756. STDMETHODIMP CDefObject::Unadvise(DWORD dwConnection)
  2757. {
  2758. VDATEHEAP();
  2759. VDATETHREAD(this);
  2760. HRESULT hresult;
  2761. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Unadvise "
  2762. "( %lu )\n", this, dwConnection));
  2763. CRefStabilize stabilize(this);
  2764. if( m_pOAHolder == NULL )
  2765. {
  2766. // no one registered
  2767. hresult = OLE_E_NOCONNECTION;
  2768. }
  2769. else
  2770. {
  2771. hresult = m_pOAHolder->Unadvise(dwConnection);
  2772. }
  2773. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Unadvise "
  2774. "( %lx )\n", this, hresult));
  2775. return hresult;
  2776. }
  2777. //+-------------------------------------------------------------------------
  2778. //
  2779. // Member: CDefObject::EnumAdvise
  2780. //
  2781. // Synopsis: Enumerate the advises currently established
  2782. //
  2783. // Effects:
  2784. //
  2785. // Arguments: [ppenumAdvise] -- where to put the advise enumerator
  2786. //
  2787. // Requires:
  2788. //
  2789. // Returns: HRESULT
  2790. //
  2791. // Signals:
  2792. //
  2793. // Modifies:
  2794. //
  2795. // Derivation: IOleObject
  2796. //
  2797. // Algorithm:
  2798. //
  2799. // History: dd-mmm-yy Author Comment
  2800. // 07-Nov-93 alexgo 32bit port
  2801. //
  2802. // Notes: We do NOT need to stabilize because EnumAdvise only
  2803. // allocates some memory for an enumerator and returns.
  2804. //
  2805. //--------------------------------------------------------------------------
  2806. STDMETHODIMP CDefObject::EnumAdvise( LPENUMSTATDATA *ppenumAdvise )
  2807. {
  2808. VDATEHEAP();
  2809. VDATETHREAD(this);
  2810. HRESULT hresult;
  2811. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::EnumAdvise "
  2812. "( *p )\n", this, ppenumAdvise));
  2813. VDATEPTROUT( ppenumAdvise, LPENUMSTATDATA );
  2814. *ppenumAdvise = NULL;
  2815. if( m_pOAHolder == NULL )
  2816. {
  2817. // no one registered
  2818. hresult = E_UNSPEC;
  2819. }
  2820. else
  2821. {
  2822. hresult = m_pOAHolder->EnumAdvise(ppenumAdvise);
  2823. }
  2824. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::EnumAdvise "
  2825. "( %lx ) [ %p ]\n", this, hresult, *ppenumAdvise));
  2826. return hresult;
  2827. }
  2828. //+-------------------------------------------------------------------------
  2829. //
  2830. // Member: CDefObject::GetMiscStatus
  2831. //
  2832. // Synopsis: Get misc status bits, such as OLEMISC_ONLYICONIC
  2833. //
  2834. // Effects:
  2835. //
  2836. // Arguments: [dwAspect] -- the drawing aspect we're concerned about
  2837. // [pdwStatus] -- where to put the status bits
  2838. //
  2839. // Requires:
  2840. //
  2841. // Returns: HRESULT
  2842. //
  2843. // Signals:
  2844. //
  2845. // Modifies:
  2846. //
  2847. // Derivation: IOleObject
  2848. //
  2849. // Algorithm: Delegates to the server. If not there, or if it returns
  2850. // OLE_E_USEREG, then lookup in the registration database
  2851. //
  2852. // History: dd-mmm-yy Author Comment
  2853. // 07-Nov-93 alexgo 32bit port
  2854. // 20-Nov-96 Gopalk Cache MiscStatus bits
  2855. // Notes:
  2856. //
  2857. //--------------------------------------------------------------------------
  2858. STDMETHODIMP CDefObject::GetMiscStatus( DWORD dwAspect, DWORD *pdwStatus)
  2859. {
  2860. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetMiscStatus(%lu, %p)\n",
  2861. this, dwAspect, pdwStatus));
  2862. // Validation checks
  2863. VDATEHEAP();
  2864. VDATETHREAD(this);
  2865. VDATEPTROUT(pdwStatus, DWORD);
  2866. // Local variables
  2867. HRESULT hresult;
  2868. // Stabilize
  2869. CRefStabilize stabilize(this);
  2870. // Initialize
  2871. *pdwStatus = 0;
  2872. hresult = OLE_S_USEREG;
  2873. if(IsRunning()) {
  2874. #ifdef SERVER_HANDLER
  2875. if(m_pEmbSrvHndlrWrapper && (DVASPECT_CONTENT == dwAspect)) {
  2876. *pdwStatus = m_ContentMiscStatusUser;
  2877. hresult = m_hresultContentMiscStatus;
  2878. }
  2879. else
  2880. #endif // SERVER_HANDLER
  2881. if(GetOleDelegate()) {
  2882. // Check if MiscStatus bits have been cached for this instance
  2883. // of server for DVASPECT_CONTENT
  2884. if(m_ContentSRVMSHResult != 0xFFFFFFFF &&
  2885. dwAspect == DVASPECT_CONTENT) {
  2886. *pdwStatus = m_ContentSRVMSBits;
  2887. hresult = m_ContentSRVMSHResult;
  2888. }
  2889. else {
  2890. // Ask the running server
  2891. hresult = m_pOleDelegate->GetMiscStatus(dwAspect, pdwStatus);
  2892. // Cache the server MiscStatus bits for DVASPECT_CONTENT
  2893. if(dwAspect == DVASPECT_CONTENT) {
  2894. m_ContentSRVMSBits = *pdwStatus;
  2895. m_ContentSRVMSHResult = hresult;
  2896. }
  2897. }
  2898. }
  2899. }
  2900. // Check if we have to obtain MiscStatus bits from the registry
  2901. if (GET_FROM_REGDB(hresult)) {
  2902. // Check if registry MiscStatus bits have been cached for DVASPECT_CONTENT
  2903. if(m_ContentREGMSHResult != 0xFFFFFFFF && dwAspect == DVASPECT_CONTENT) {
  2904. *pdwStatus = m_ContentREGMSBits;
  2905. hresult = m_ContentREGMSHResult;
  2906. }
  2907. else {
  2908. // Hit the registry
  2909. hresult = OleRegGetMiscStatus (m_clsidServer, dwAspect, pdwStatus);
  2910. if(hresult == NOERROR) {
  2911. // Update the MiscStatus flags
  2912. if((m_flags & DH_STATIC))
  2913. (*pdwStatus) |= (OLEMISC_STATIC | OLEMISC_CANTLINKINSIDE);
  2914. else if(CoIsOle1Class(m_clsidServer))
  2915. (*pdwStatus) |= OLEMISC_CANTLINKINSIDE;
  2916. // Cache the registry MiscStatus bits for DVASPECT_CONTENT
  2917. if(dwAspect == DVASPECT_CONTENT) {
  2918. m_ContentREGMSBits = *pdwStatus;
  2919. m_ContentREGMSHResult = hresult;
  2920. }
  2921. }
  2922. }
  2923. }
  2924. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetMiscStatus(%lx) [%lx]\n",
  2925. this, hresult, *pdwStatus));
  2926. return hresult;
  2927. }
  2928. //+-------------------------------------------------------------------------
  2929. //
  2930. // Member: CDefObject::SetColorScheme
  2931. //
  2932. // Synopsis: Sets the palette for an object
  2933. //
  2934. // Effects:
  2935. //
  2936. // Arguments: [lpLogpal] -- the palette
  2937. //
  2938. // Requires:
  2939. //
  2940. // Returns: HRESULT
  2941. //
  2942. // Signals:
  2943. //
  2944. // Modifies:
  2945. //
  2946. // Derivation: IOleObject
  2947. //
  2948. // Algorithm: Delegates to the server
  2949. //
  2950. // History: dd-mmm-yy Author Comment
  2951. // 07-Nov-93 alexgo 32bit
  2952. //
  2953. // Notes:
  2954. //
  2955. //--------------------------------------------------------------------------
  2956. STDMETHODIMP CDefObject::SetColorScheme( LPLOGPALETTE lpLogpal )
  2957. {
  2958. VDATEHEAP();
  2959. VDATETHREAD(this);
  2960. HRESULT hresult;
  2961. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetColorScheme "
  2962. "( %p )\n", this, lpLogpal));
  2963. CRefStabilize stabilize(this);
  2964. if( (m_flags & DH_STATIC) )
  2965. {
  2966. hresult = OLE_E_STATIC;
  2967. }
  2968. else if( lpLogpal == NULL || lpLogpal->palNumEntries == NULL)
  2969. {
  2970. hresult = E_INVALIDARG;
  2971. }
  2972. else if( IsRunning() && GetOleDelegate() )
  2973. {
  2974. hresult = m_pOleDelegate->SetColorScheme (lpLogpal);
  2975. }
  2976. else
  2977. {
  2978. hresult = OLE_E_NOTRUNNING;
  2979. }
  2980. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SetColorScheme "
  2981. "( %lx )\n", this, hresult));
  2982. return hresult;
  2983. }
  2984. //+-------------------------------------------------------------------------
  2985. //
  2986. // Member: CDefObject::GetUserClassID
  2987. //
  2988. // Synopsis: Retrieves the class ID for the object
  2989. //
  2990. // Effects:
  2991. //
  2992. // Arguments: [pClassID] -- where to put the class ID
  2993. //
  2994. // Requires:
  2995. //
  2996. // Returns: HRESULT
  2997. //
  2998. // Signals:
  2999. //
  3000. // Modifies:
  3001. //
  3002. // Derivation: IOleObject
  3003. //
  3004. // Algorithm: Delegates to the server, or if not running (or if it
  3005. // fails the delegated call), then we attempt
  3006. // to get the class id from the storage.
  3007. //
  3008. // History: dd-mmm-yy Author Comment
  3009. // 07-Nov-93 alexgo 32bit port
  3010. //
  3011. // Notes:
  3012. //
  3013. //--------------------------------------------------------------------------
  3014. STDMETHODIMP CDefObject::GetUserClassID( CLSID *pClassID )
  3015. {
  3016. VDATEHEAP();
  3017. VDATETHREAD(this);
  3018. HRESULT hresult;
  3019. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetUserClassID "
  3020. "( %p )\n", this, pClassID));
  3021. VDATEPTROUT(pClassID, CLSID);
  3022. CRefStabilize stabilize(this);
  3023. if( IsRunning() )
  3024. {
  3025. #ifdef SERVER_HANDLER
  3026. if (m_pEmbSrvHndlrWrapper )
  3027. {
  3028. *pClassID = m_clsidUser;
  3029. hresult = m_hresultClsidUser;
  3030. goto errRtn;
  3031. }
  3032. else
  3033. #endif // SERVER_HANDLER
  3034. if ( GetOleDelegate() )
  3035. {
  3036. hresult = m_pOleDelegate->GetUserClassID(pClassID);
  3037. // success! We don't have to figure it out ourselves, so
  3038. // skip to the end and exit
  3039. if (hresult == NOERROR )
  3040. {
  3041. goto errRtn;
  3042. }
  3043. }
  3044. }
  3045. if( !IsEqualCLSID(m_clsidServer, CLSID_NULL) )
  3046. {
  3047. *pClassID = m_clsidServer;
  3048. hresult = NOERROR;
  3049. }
  3050. else
  3051. {
  3052. hresult = GetClassBits(pClassID);
  3053. }
  3054. errRtn:
  3055. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetUserClassID "
  3056. "( %lx ) [ %p ]\n", this, hresult, pClassID));
  3057. return hresult;
  3058. }
  3059. //+-------------------------------------------------------------------------
  3060. //
  3061. // Member: CDefObject::GetUserType
  3062. //
  3063. // Synopsis: Gets a descriptive string about the object for the user
  3064. //
  3065. // Effects:
  3066. //
  3067. // Arguments: [dwFromOfType] -- whether to get a short/long/etc version
  3068. //
  3069. // Requires:
  3070. //
  3071. // Returns: HRESULT
  3072. //
  3073. // Signals:
  3074. //
  3075. // Modifies:
  3076. //
  3077. // Derivation: IOleObject
  3078. //
  3079. // Algorithm: Delegates to the server, failing that, trys the registration
  3080. // database, failing that, tries to read from the storage
  3081. //
  3082. // History: dd-mmm-yy Author Comment
  3083. // 07-Nov-93 alexgo 32bit port
  3084. //
  3085. // Notes:
  3086. //
  3087. //--------------------------------------------------------------------------
  3088. STDMETHODIMP CDefObject::GetUserType( DWORD dwFormOfType,
  3089. LPOLESTR *ppszUserType)
  3090. {
  3091. VDATEHEAP();
  3092. VDATETHREAD(this);
  3093. HRESULT hresult;
  3094. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetUserType "
  3095. "( %lu , %p )\n", this, dwFormOfType, ppszUserType));
  3096. VDATEPTROUT(ppszUserType, LPOLESTR);
  3097. CRefStabilize stabilize(this);
  3098. *ppszUserType = NULL;
  3099. if( IsRunning() && GetOleDelegate() )
  3100. {
  3101. hresult = m_pOleDelegate->GetUserType (dwFormOfType,
  3102. ppszUserType);
  3103. if (!GET_FROM_REGDB(hresult))
  3104. {
  3105. goto errRtn;
  3106. }
  3107. }
  3108. if( (hresult = OleRegGetUserType( m_clsidServer, dwFormOfType,
  3109. ppszUserType)) == NOERROR)
  3110. {
  3111. goto errRtn;
  3112. }
  3113. // Try reading from storage
  3114. // This really ugly bit of 16bit code tries to read the user type
  3115. // from the storage. If that fails, then we look in the registry
  3116. if( NULL == m_pStg ||
  3117. NOERROR != (hresult = ReadFmtUserTypeStg(m_pStg, NULL, ppszUserType)) ||
  3118. NULL == *ppszUserType )
  3119. {
  3120. OLECHAR sz[256];
  3121. long cb = sizeof(sz);// ReqQueryValue expects
  3122. // a *byte* count
  3123. *ppszUserType = UtDupString (
  3124. (ERROR_SUCCESS ==
  3125. RegQueryValue (HKEY_CLASSES_ROOT,
  3126. OLESTR("Software\\Microsoft\\OLE2\\UnknownUserType"),
  3127. sz, &cb))
  3128. ? (LPCOLESTR)sz : OLESTR("Unknown"));
  3129. if (NULL != *ppszUserType)
  3130. {
  3131. hresult = NOERROR;
  3132. }
  3133. else
  3134. {
  3135. hresult = E_OUTOFMEMORY;
  3136. }
  3137. }
  3138. errRtn:
  3139. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetUserType "
  3140. "( %lx ) [ %p ]\n", this, hresult, *ppszUserType));
  3141. return hresult;
  3142. }
  3143. /*
  3144. * IMPLEMENTATION of CROImpl methods
  3145. *
  3146. * We never delegate to the server. This is by design.
  3147. */
  3148. //+-------------------------------------------------------------------------
  3149. //
  3150. // Member: CDefObject::GetRunningClass
  3151. //
  3152. // Synopsis: Get the class id of the server
  3153. //
  3154. // Effects:
  3155. //
  3156. // Arguments: [lpClsid] -- where to put the class id
  3157. //
  3158. // Requires:
  3159. //
  3160. // Returns: HRESULT
  3161. //
  3162. // Signals:
  3163. //
  3164. // Modifies:
  3165. //
  3166. // Derivation: IRunnableObject
  3167. //
  3168. // Algorithm:
  3169. //
  3170. // History: dd-mmm-yy Author Comment
  3171. // 07-Nov-93 alexgo 32bit port
  3172. //
  3173. // Notes: We do not need to stabilize this call as no outgoing
  3174. // calls are made.
  3175. //
  3176. //--------------------------------------------------------------------------
  3177. STDMETHODIMP CDefObject::GetRunningClass(LPCLSID lpClsid)
  3178. {
  3179. VDATEHEAP();
  3180. VDATETHREAD(this);
  3181. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetRunningClass "
  3182. "( %p )\n", this, lpClsid));
  3183. VDATEPTROUT(lpClsid, CLSID);
  3184. *lpClsid = m_clsidServer;
  3185. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetRunningClass "
  3186. "( %lx ) [ %p ]\n", this, NOERROR, lpClsid));
  3187. return NOERROR;
  3188. }
  3189. //+-------------------------------------------------------------------------
  3190. //
  3191. // Member: CDefObject::Run
  3192. //
  3193. // Synopsis: Sets the object running (if it isn't already)
  3194. //
  3195. // Effects: may launch the server
  3196. //
  3197. // Arguments: [pbc] -- the bind context (unused)
  3198. //
  3199. // Requires:
  3200. //
  3201. // Returns: HRESULT
  3202. //
  3203. // Signals:
  3204. //
  3205. // Modifies:
  3206. //
  3207. // Derivation: IRunnableObject
  3208. //
  3209. // Algorithm: If already running, return. Otherwise, get the proxy
  3210. // manager to create the server. Initialize the storage
  3211. // and caches, and set the host name for the server's window.
  3212. //
  3213. // History: dd-mmm-yy Author Comment
  3214. // 07-Nov-93 alexgo 32bit port
  3215. //
  3216. // Notes:
  3217. //
  3218. //--------------------------------------------------------------------------
  3219. STDMETHODIMP CDefObject::Run(LPBINDCTX pbc)
  3220. {
  3221. VDATEHEAP();
  3222. VDATETHREAD(this);
  3223. HRESULT hresult;
  3224. IDataObject FAR* pDataDelegate = NULL;
  3225. IOleObject FAR* pOleDelegate = NULL;
  3226. IPersistStorage FAR* pPStgDelegate = NULL;
  3227. IMoniker FAR* pmk = NULL;
  3228. BOOL fLockedContainer;
  3229. DWORD dwMiscStatus;
  3230. // NOTE: ignore pbc for now
  3231. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Run ( %p )\n", this, pbc));
  3232. CRefStabilize stabilize(this);
  3233. if( IsRunning() )
  3234. {
  3235. hresult = S_OK;
  3236. // just return the error code
  3237. goto errRtn2;
  3238. }
  3239. if( (m_flags & DH_STATIC) )
  3240. {
  3241. hresult = OLE_E_STATIC;
  3242. goto errRtn2;
  3243. }
  3244. if( IsZombie() )
  3245. {
  3246. hresult = CO_E_RELEASED;
  3247. goto errRtn2;
  3248. }
  3249. if( FAILED(hresult = CreateDelegate()) )
  3250. {
  3251. // just return the error code
  3252. goto errRtn2;
  3253. }
  3254. if (m_pProxyMgr != NULL)
  3255. {
  3256. #ifdef SERVER_HANDLER
  3257. IServerHandler *pSrvHndl = NULL;
  3258. hresult = m_pProxyMgr->CreateServerWithEmbHandler(m_clsidServer,
  3259. CLSCTX_LOCAL_SERVER | CLSCTX_ESERVER_HANDLER ,
  3260. IID_IServerHandler,(void **) &pSrvHndl,NULL);
  3261. if(FAILED(hresult))
  3262. Win4Assert(NULL == pSrvHndl);
  3263. #else
  3264. hresult = m_pProxyMgr->CreateServer(m_clsidServer,
  3265. CLSCTX_LOCAL_SERVER,
  3266. NULL);
  3267. #endif // SERVER_HANDLER
  3268. if (FAILED(hresult))
  3269. {
  3270. goto errRtn;
  3271. }
  3272. // if there is a serverHandler, create a wrapper object for handling standard interfaces
  3273. #ifdef SERVER_HANDLER
  3274. if (pSrvHndl)
  3275. {
  3276. m_pEmbSrvHndlrWrapper = CreateEmbServerWrapper(m_pUnkOuter,pSrvHndl);
  3277. pSrvHndl->Release();
  3278. }
  3279. else
  3280. {
  3281. m_pEmbSrvHndlrWrapper = NULL;
  3282. }
  3283. #endif // SERVER_HANDLER
  3284. }
  3285. // NOTE: the lock state of the proxy mgr is not changed; it remembers
  3286. // the state and sets up the connection correctly.
  3287. // server is running; normally this coincides with locking the
  3288. // container, but we keep a separate flag since locking the container
  3289. // may fail.
  3290. m_flags |= DH_FORCED_RUNNING;
  3291. // Lock the container
  3292. fLockedContainer = m_flags & DH_LOCKED_CONTAINER;
  3293. DuLockContainer(m_pAppClientSite, TRUE, &fLockedContainer );
  3294. if( fLockedContainer )
  3295. {
  3296. m_flags |= DH_LOCKED_CONTAINER;
  3297. }
  3298. else
  3299. {
  3300. m_flags &= ~DH_LOCKED_CONTAINER;
  3301. }
  3302. #if DBG==1
  3303. // In debug builds, update DH_LOCKFAILED flag
  3304. if(fLockedContainer)
  3305. m_flags &= ~DH_LOCKFAILED;
  3306. else
  3307. m_flags |= DH_LOCKFAILED;
  3308. #endif
  3309. #ifdef SERVER_HANDLER
  3310. if (m_pEmbSrvHndlrWrapper)
  3311. {
  3312. MInterfacePointer *pIRDClientSite = NULL;
  3313. CStdIdentity *pStdid = NULL;
  3314. CClientSiteHandler *pClientSiteHandler = NULL;
  3315. GUID riid = IID_IOleClientSite; //Reference to the identifier of the interface
  3316. BOOL fHasIPSite = FALSE;
  3317. IUnknown *pUnk = NULL; //Pointer to the interface to be marshaled
  3318. CXmitRpcStream Stm;
  3319. if (m_pAppClientSite)
  3320. {
  3321. // Only wrap ClientSite if there is not an existing Identity.
  3322. if (NOERROR != LookupIDFromUnk(m_pAppClientSite, GetCurrentApartmentId(),0,&pStdid))
  3323. {
  3324. Assert(NULL == pClientSiteHandler);
  3325. hresult = CreateClientSiteHandler(m_pAppClientSite,&pClientSiteHandler,&fHasIPSite);
  3326. riid = IID_IClientSiteHandler;
  3327. pUnk = (IUnknown *) (IClientSiteHandler *) pClientSiteHandler;
  3328. }
  3329. else
  3330. {
  3331. riid = IID_IOleClientSite;
  3332. pUnk = (IUnknown *) (IOleClientSite*) m_pAppClientSite;
  3333. pUnk->AddRef();
  3334. }
  3335. hresult = CoMarshalInterface(&Stm,riid,
  3336. pUnk,
  3337. MSHCTX_DIFFERENTMACHINE,
  3338. NULL, MSHLFLAGS_NORMAL);
  3339. if (SUCCEEDED(hresult))
  3340. {
  3341. Stm.AssignSerializedInterface((InterfaceData **) &pIRDClientSite);
  3342. }
  3343. m_pRunClientSite = m_pAppClientSite; // Remember ClientSite on Run.
  3344. }
  3345. Assert(m_dwConnOle == 0L);
  3346. hresult = m_pEmbSrvHndlrWrapper->Run(m_flags,
  3347. riid,
  3348. pIRDClientSite,
  3349. fHasIPSite,
  3350. (LPOLESTR)m_pHostNames,
  3351. (LPOLESTR)(m_pHostNames + m_ibCntrObj),
  3352. (IStorage *) m_pStg,
  3353. (IAdviseSink *) &m_AdviseSink,
  3354. &m_dwConnOle,
  3355. &m_hresultClsidUser,
  3356. &m_clsidUser,
  3357. &m_hresultContentMiscStatus,
  3358. &m_ContentMiscStatusUser
  3359. );
  3360. if (pIRDClientSite)
  3361. CoTaskMemFree(pIRDClientSite);
  3362. if (pStdid)
  3363. pStdid->Release();
  3364. if (pUnk)
  3365. pUnk->Release();
  3366. // !!! Make sure on error don't set up Cache.
  3367. if (NOERROR != hresult)
  3368. {
  3369. goto errRtn;
  3370. }
  3371. // set up any cached interfaces
  3372. // !!!!!TODO: Not All LeSuite Linking Tests Pass when Cache DataObject through ServerHandler.
  3373. if (!m_pDataDelegate)
  3374. {
  3375. if (NOERROR == m_pEmbSrvHndlrWrapper->m_Unknown.QueryInterface(IID_IDataObject,(void **) &m_pDataDelegate))
  3376. {
  3377. m_pUnkOuter->Release();
  3378. }
  3379. }
  3380. }
  3381. else
  3382. #endif // SERVER_HANDLER
  3383. {
  3384. // Check if we have client site
  3385. if(m_pAppClientSite) {
  3386. // Clear the cached MiscStatus bits
  3387. m_ContentSRVMSBits = 0;
  3388. m_ContentSRVMSHResult = 0xFFFFFFFF;
  3389. // Get MiscStatus bits from the running server
  3390. hresult = GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
  3391. // Set the client site first if OLEMISC_SETCLIENTSITEFIRST bit is set
  3392. if(hresult == NOERROR && (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) &&
  3393. (pOleDelegate = GetOleDelegate()))
  3394. hresult = pOleDelegate->SetClientSite(m_pAppClientSite);
  3395. else if(hresult != NOERROR) {
  3396. hresult = NOERROR;
  3397. dwMiscStatus = 0;
  3398. }
  3399. }
  3400. if(hresult != NOERROR)
  3401. goto errRtn;
  3402. if( pPStgDelegate = GetPSDelegate() )
  3403. {
  3404. if( m_pStg)
  3405. {
  3406. if( (m_flags & DH_INIT_NEW) )
  3407. {
  3408. hresult = pPStgDelegate->InitNew(m_pStg);
  3409. }
  3410. else
  3411. {
  3412. hresult = pPStgDelegate->Load(m_pStg);
  3413. }
  3414. if (hresult != NOERROR)
  3415. {
  3416. // this will cause us to stop the
  3417. // the server we just launced
  3418. goto errRtn;
  3419. }
  3420. }
  3421. }
  3422. if(pOleDelegate || (pOleDelegate = GetOleDelegate()))
  3423. {
  3424. // REVIEW MM1: what are we supposed to do in case of failure
  3425. if(m_pAppClientSite && !(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
  3426. {
  3427. pOleDelegate->SetClientSite(m_pAppClientSite);
  3428. }
  3429. if (m_pHostNames)
  3430. {
  3431. if (hresult = pOleDelegate->SetHostNames((LPOLESTR)m_pHostNames,
  3432. (LPOLESTR)(m_pHostNames + m_ibCntrObj))
  3433. != NOERROR)
  3434. {
  3435. goto errRtn;
  3436. }
  3437. }
  3438. // set single ole advise (we multiplex)
  3439. Assert(m_dwConnOle == 0L);
  3440. if ((hresult = pOleDelegate->Advise((IAdviseSink *)&m_AdviseSink,
  3441. &m_dwConnOle)) != NOERROR)
  3442. {
  3443. goto errRtn;
  3444. }
  3445. if(m_pAppClientSite != NULL &&
  3446. m_pAppClientSite->GetMoniker
  3447. (OLEGETMONIKER_ONLYIFTHERE,
  3448. OLEWHICHMK_OBJREL, &pmk) == NOERROR)
  3449. {
  3450. AssertOutPtrIface(NOERROR, pmk);
  3451. pOleDelegate->SetMoniker(OLEWHICHMK_OBJREL, pmk);
  3452. pmk->Release();
  3453. }
  3454. }
  3455. }
  3456. Win4Assert(NOERROR == hresult);
  3457. if( pDataDelegate = GetDataDelegate() )
  3458. {
  3459. // inform cache that we are running
  3460. Assert(m_pCOleCache != NULL);
  3461. m_pCOleCache->OnRun(pDataDelegate);
  3462. // Enumerate all the advises we stored while we were either not
  3463. // running or running the previous time, and send them to the
  3464. // now-running object.
  3465. m_pDataAdvCache->EnumAndAdvise(pDataDelegate, TRUE);
  3466. }
  3467. errRtn:
  3468. if(hresult == NOERROR) {
  3469. // Clear the cached MiscStatus bits if not cleared before
  3470. #ifdef SERVER_HANDLER
  3471. if(m_pEmbSrvHndlrWrapper) {
  3472. m_ContentSRVMSBits = 0;
  3473. m_ContentSRVMSHResult = 0xFFFFFFFF;
  3474. }
  3475. else
  3476. #endif // SERVER_HANDLER
  3477. if(!m_pAppClientSite) {
  3478. m_ContentSRVMSBits = 0;
  3479. m_ContentSRVMSHResult = 0xFFFFFFFF;
  3480. }
  3481. }
  3482. else {
  3483. // Stop the running object
  3484. Stop();
  3485. // Assert that the container is not locked
  3486. Win4Assert(!(m_flags & DH_LOCKED_CONTAINER) && !(m_flags & DH_LOCKFAILED));
  3487. }
  3488. errRtn2:
  3489. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Run "
  3490. "( %lx )\n", this, hresult));
  3491. return hresult;
  3492. }
  3493. //+-------------------------------------------------------------------------
  3494. //
  3495. // Member: CDefObject::Stop
  3496. //
  3497. // Synopsis: Undoes some of Run() (stops the server)...internal function
  3498. //
  3499. // Effects:
  3500. //
  3501. // Arguments: void
  3502. //
  3503. // Requires:
  3504. //
  3505. // Returns: HRESULT
  3506. //
  3507. // Signals:
  3508. //
  3509. // Modifies:
  3510. //
  3511. // Derivation:
  3512. //
  3513. // Algorithm: unadvise connections (if any), stop the cache, disconnect
  3514. // from the proxy manager and unlock the container
  3515. //
  3516. // History: dd-mmm-yy Author Comment
  3517. // 07-Nov-93 alexgo 32bit port
  3518. //
  3519. // Notes:
  3520. //
  3521. // undo effects of Run(); some of this work is done also in IsRunning
  3522. // when we detect we are not running (in case the server crashed).
  3523. //--------------------------------------------------------------------------
  3524. INTERNAL CDefObject::Stop (void)
  3525. {
  3526. BOOL fLockedContainer;
  3527. VDATEHEAP();
  3528. LEDebugOut((DEB_ITRACE, "%p _IN CDefObject::CROImpl::Stop "
  3529. "( )\n", this));
  3530. CRefStabilize stabilize(this);
  3531. if( !IsRunning() )
  3532. {
  3533. // NOTE: ISRUNNING below does some of this cleanup
  3534. goto errRtn; // return NOERROR
  3535. }
  3536. // NOTE: we cleanup connections which point directly back to us;
  3537. // connections which point back to the app (e.g, the clientsite and
  3538. // data advise) are left alone; an app must know how to use
  3539. // CoDisconnectObject if deterministic shutdown is desired.
  3540. if( m_dwConnOle != 0L && GetOleDelegate() )
  3541. {
  3542. m_pOleDelegate->Unadvise(m_dwConnOle);
  3543. m_dwConnOle = 0L;
  3544. }
  3545. if( m_pDataDelegate )
  3546. {
  3547. m_pDataAdvCache->EnumAndAdvise(m_pDataDelegate, FALSE);
  3548. }
  3549. // inform cache that we are not running (Undoes advise)
  3550. Assert(m_pCOleCache != NULL);
  3551. m_pCOleCache->OnStop();
  3552. #ifdef SERVER_HANDLER
  3553. if (m_pEmbSrvHndlrWrapper)
  3554. {
  3555. CEmbServerWrapper *pSrvHndlr = m_pEmbSrvHndlrWrapper;
  3556. m_pEmbSrvHndlrWrapper = NULL;
  3557. m_pRunClientSite = NULL;
  3558. // need to release any interfaces the Handler Wraps
  3559. if(m_pDataDelegate)
  3560. {
  3561. m_pUnkOuter->AddRef();
  3562. SafeReleaseAndNULL((IUnknown **)&m_pDataDelegate);
  3563. }
  3564. // NULL out m_pSrvHndl before Release since out call could case re-entrance.
  3565. pSrvHndlr->m_Unknown.Release();
  3566. }
  3567. #endif // SERVER_HANDLER
  3568. #if DBG==1
  3569. // In debug builds, set DH_WILLUNLOCK flag
  3570. m_flags |= DH_WILLUNLOCK;
  3571. #endif
  3572. // Reset DH_FORCED_RUNNING flag and disconnect proxy manager
  3573. m_flags &= ~DH_FORCED_RUNNING;
  3574. if(m_pProxyMgr)
  3575. m_pProxyMgr->Disconnect();
  3576. // Unlock the container site
  3577. fLockedContainer = (m_flags & DH_LOCKED_CONTAINER);
  3578. if(fLockedContainer) {
  3579. m_flags &= ~DH_LOCKED_CONTAINER;
  3580. DuLockContainer(m_pAppClientSite, FALSE, &fLockedContainer);
  3581. }
  3582. Win4Assert(!fLockedContainer);
  3583. #if DBG==1
  3584. // In debug builds, reset the DH_LOCKFAILED and DH_WILLUNLOCK flags
  3585. m_flags &= ~DH_LOCKFAILED;
  3586. m_flags &= ~DH_WILLUNLOCK;
  3587. #endif
  3588. errRtn:
  3589. LEDebugOut((DEB_ITRACE, "%p OUT CDefObject::Stop "
  3590. "( %lx )\n", this, NOERROR ));
  3591. return NOERROR;
  3592. }
  3593. //+-------------------------------------------------------------------------
  3594. //
  3595. // Member: CDefObject::IsRunning
  3596. //
  3597. // Arguments: None
  3598. //
  3599. // Returns: BOOL
  3600. //
  3601. // Derivation: IRunnableObject
  3602. //
  3603. // Notes: Detects if the local server has crashed and does cleanup
  3604. // so that the user can activate the embedding in the same
  3605. // session.
  3606. //
  3607. // History: dd-mmm-yy Author Comment
  3608. // 06-Dec-96 Gopalk Rewritten
  3609. //--------------------------------------------------------------------------
  3610. STDMETHODIMP_(BOOL) CDefObject::IsRunning(void)
  3611. {
  3612. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::IsRunning()\n", this));
  3613. // Validation checks
  3614. VDATEHEAP();
  3615. VDATETHREAD(this);
  3616. // Local variable
  3617. BOOL fReturn = FALSE;
  3618. HRESULT hStatus;
  3619. CRefStabilize stabilize(this);
  3620. // Check if the inner object has been created
  3621. if(m_pUnkDelegate) {
  3622. // DEFHANDLER either has proxy manager as the inner object
  3623. // for out of proc server objects or actual server as the
  3624. // inner object for inproc server objects.
  3625. // Assert that this is TRUE
  3626. Win4Assert((m_pProxyMgr != NULL) == !!(m_flags & DH_INPROC_HANDLER));
  3627. if(m_pProxyMgr) {
  3628. // Out of proc server object.
  3629. // Check with the proxy manager whether it is connected to the
  3630. // server object. We cannot rely on the DH_FORCED_RUNNING flag
  3631. // to indicate run status because the DEFHANDLER could have been
  3632. // marshaled from the embedding conatiner and unmarshaled in the
  3633. // link container. The DEFHANDLER created by unmarshaling in the
  3634. // link container is always in the running state due to the
  3635. // requirement that IOleItemContainer::GetObject is required to
  3636. // put the embedding in running state when its bind speed
  3637. // parameter permits, else it is supposed to return
  3638. // MK_E_EXCEEDEDDEADLINE. Further, CoMarshalInterface fails
  3639. // if the the proxy manager is not connected
  3640. fReturn = m_pProxyMgr->IsConnected();
  3641. if(fReturn) {
  3642. // The proxymanager is connected to the server object
  3643. // Check the status of connection with the server object
  3644. hStatus = m_pProxyMgr->GetConnectionStatus();
  3645. if(hStatus != S_OK) {
  3646. // Either Server object called CoDisconnectObject or
  3647. // its apartment crashed or unitialized breaking the
  3648. // external connection to the objects in that apartment
  3649. // Clean up the state
  3650. Win4Assert(!"Local Server crashed or disconnected");
  3651. // Reset flags
  3652. m_flags &= ~DH_FORCED_RUNNING;
  3653. // Reset advise connection and recover the references
  3654. // placed by the server on the handler advise sink
  3655. m_dwConnOle = 0L;
  3656. CoDisconnectObject((IUnknown *) &m_AdviseSink, 0);
  3657. // Inform cache that the local server crashed
  3658. if(m_pCOleCache)
  3659. m_pCOleCache->OnCrash();
  3660. // Inform and cleanup data advice cache
  3661. m_pDataAdvCache->EnumAndAdvise(NULL, FALSE);
  3662. // Unlock the container if it is was locked
  3663. BOOL fCurLock = !!(m_flags & DH_LOCKED_CONTAINER);
  3664. if(fCurLock) {
  3665. DuLockContainer(m_pAppClientSite, FALSE, &fCurLock);
  3666. m_flags &= ~DH_LOCKED_CONTAINER;
  3667. }
  3668. Win4Assert(!fCurLock);
  3669. #if DBG==1
  3670. // In debug builds, reset DH_LOCKFAILED flag
  3671. m_flags &= ~DH_LOCKFAILED;
  3672. #endif
  3673. // Inform ProxyManager to disconnect
  3674. m_pProxyMgr->Disconnect();
  3675. // Reset fReturn
  3676. fReturn = FALSE;
  3677. }
  3678. }
  3679. }
  3680. else {
  3681. // Inproc server object.
  3682. // COM supports self embedding by allowing separate class
  3683. // objects to be registered for instatiating INPROC_SERVER
  3684. // and LOCAL_SERVER objects. Apps typically ask the Default
  3685. // handler to aggregate their INPROC_SERVER objects by
  3686. // using OleCreateEmbeddingHelper api so that embedding
  3687. // interfaces like IViewObject are supported. But this
  3688. // creates problem for self linking because link moniker
  3689. // binds to inproc servers in preference to local servers.
  3690. // As the inproc server object obtained from the INPROC_SERVER
  3691. // class factory is the default handler, it will not delegate
  3692. // method calls to the actual server object unless it thinks that
  3693. // the local object is running. Below we check if we are dealing
  3694. // with an embedded object using the assumption that embedded objects
  3695. // are initialized through IStorage. The above assumption is
  3696. // questionable but we are helpless.
  3697. if (!(m_flags & DH_EMBEDDING) || (m_flags & DH_FORCED_RUNNING))
  3698. fReturn = TRUE;
  3699. }
  3700. }
  3701. else
  3702. Win4Assert((m_flags & DH_DELAY_CREATE) && m_pCFDelegate != NULL);
  3703. // Sanity checks
  3704. if(fReturn) {
  3705. if(m_flags & DH_FORCED_RUNNING) {
  3706. Win4Assert((m_flags & DH_LOCKED_CONTAINER) || (m_flags & DH_LOCKFAILED));
  3707. Win4Assert(!(m_flags & DH_UNMARSHALED));
  3708. }
  3709. else if(m_pProxyMgr) {
  3710. Win4Assert(!m_pAppClientSite);
  3711. Win4Assert(!m_pStg);
  3712. Win4Assert(!(m_flags & DH_LOCKED_CONTAINER));
  3713. Win4Assert(!(m_flags & DH_LOCKFAILED));
  3714. Win4Assert(m_flags & DH_UNMARSHALED);
  3715. Win4Assert(!(m_flags & DH_EMBEDDING));
  3716. }
  3717. }
  3718. else {
  3719. if(!(m_flags & DH_OLE1SERVER)) {
  3720. // DDE IProxyManager::IsConnected returns FLASE until
  3721. // either IPersistStorage::Load or IPersistStorage::InitNew
  3722. // is called on it
  3723. Win4Assert(!(m_flags & DH_FORCED_RUNNING));
  3724. Win4Assert((m_flags & DH_WILLUNLOCK) || !(m_flags & DH_LOCKED_CONTAINER));
  3725. Win4Assert((m_flags & DH_WILLUNLOCK) || !(m_flags & DH_LOCKFAILED));
  3726. }
  3727. }
  3728. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::IsRunning(%lu)\n", this, fReturn));
  3729. return fReturn;
  3730. }
  3731. //+-------------------------------------------------------------------------
  3732. //
  3733. // Member: CDefObject::SetContainedObject
  3734. //
  3735. // Synopsis: sets the embedding status of an object
  3736. //
  3737. // Effects:
  3738. //
  3739. // Arguments: [fContained] -- TRUE indicates we are an embedding/
  3740. // FALSE otherwise
  3741. //
  3742. // Requires:
  3743. //
  3744. // Returns: HRESULT
  3745. //
  3746. // Signals:
  3747. //
  3748. // Modifies:
  3749. //
  3750. // Derivation: IRunnableObject
  3751. //
  3752. // Algorithm: Sets flags, if we are an improc handler, we will call
  3753. // IRunnableObject->LockRunning(FALSE) to unlock ourselves
  3754. //
  3755. // History: dd-mmm-yy Author Comment
  3756. // 08-Nov-93 alexgo 32bit port
  3757. //
  3758. // Notes:
  3759. // note that this is a contained object; this unlocks
  3760. // connection to the server
  3761. //
  3762. //--------------------------------------------------------------------------
  3763. STDMETHODIMP CDefObject::SetContainedObject(BOOL fContained)
  3764. {
  3765. VDATEHEAP();
  3766. VDATETHREAD(this);
  3767. HRESULT hresult = NOERROR;
  3768. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetContainedObject "
  3769. "( %lu )\n", this, fContained));
  3770. CRefStabilize stabilize(this);
  3771. if( !!(m_flags & DH_CONTAINED_OBJECT) != !!fContained)
  3772. {
  3773. // not contained in the same way as desired;
  3774. // for inproc handler, [un]lock connection
  3775. // for inproc server, just remember flag
  3776. if( (m_flags & DH_INPROC_HANDLER) )
  3777. {
  3778. hresult = LockRunning(!fContained, FALSE);
  3779. }
  3780. if (hresult == NOERROR)
  3781. {
  3782. // the !! ensure exactly 0 or 1 will be stored in
  3783. // m_fContainedObject
  3784. if( fContained )
  3785. {
  3786. m_flags |= DH_CONTAINED_OBJECT;
  3787. }
  3788. else
  3789. {
  3790. m_flags &= ~DH_CONTAINED_OBJECT;
  3791. }
  3792. }
  3793. }
  3794. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SetContainedObject "
  3795. "( %lx )\n", this, hresult));
  3796. return hresult;
  3797. }
  3798. //+-------------------------------------------------------------------------
  3799. //
  3800. // Member: CDefObject::LockRunning
  3801. //
  3802. // Synopsis: Locks or unlocks the object
  3803. //
  3804. // Effects:
  3805. //
  3806. // Arguments: [fLock] -- TRUE, then lock, unlock if FALSE
  3807. // [fLastUnlockCloses] -- shut down if unlocking the last
  3808. // lock
  3809. //
  3810. // Requires:
  3811. //
  3812. // Returns: HRESULT
  3813. //
  3814. // Signals:
  3815. //
  3816. // Modifies:
  3817. //
  3818. // Derivation: IRunnableObject
  3819. //
  3820. // Algorithm: If we are an improc server, call CoLockObjectExternal,
  3821. // otherwise have the proxy manager lock us down.
  3822. //
  3823. // History: dd-mmm-yy Author Comment
  3824. // 08-Nov-93 alexgo 32bit port
  3825. //
  3826. // Notes:
  3827. //
  3828. //--------------------------------------------------------------------------
  3829. STDMETHODIMP CDefObject::LockRunning(BOOL fLock, BOOL fLastUnlockCloses)
  3830. {
  3831. VDATEHEAP();
  3832. VDATETHREAD(this);
  3833. HRESULT hresult;
  3834. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::LockRunning "
  3835. "( %lu , %lu )\n", this, fLock, fLastUnlockCloses ));
  3836. CRefStabilize stabilize(this);
  3837. // else map to lock connection
  3838. if( !(m_flags & DH_INPROC_HANDLER) )
  3839. {
  3840. // inproc server: use CoLockObjExternal; will close down
  3841. // if invisible via new IExternalConnection interface.
  3842. Assert(m_pProxyMgr == NULL);
  3843. hresult = CoLockObjectExternal((IUnknown *)(IOleObject *)this, fLock,
  3844. fLastUnlockCloses); }
  3845. else if( m_pUnkDelegate == NULL )
  3846. {
  3847. // NOTE: this really shouldn't happen at present
  3848. // since we currently disallow delay create with
  3849. // inproc handler. In fact, the LockConnection below
  3850. // is one of the reasons why we must have the
  3851. // proxymgr upfront. In the future we could force
  3852. // the creation of the delegate here.
  3853. Assert( (m_flags & DH_DELAY_CREATE) && m_pCFDelegate != NULL);
  3854. hresult = NOERROR;
  3855. }
  3856. else
  3857. {
  3858. Assert(m_pProxyMgr != NULL);
  3859. hresult = m_pProxyMgr->LockConnection(fLock, fLastUnlockCloses);
  3860. }
  3861. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::LockRunning "
  3862. "( %lx )\n", this, hresult));
  3863. return hresult;
  3864. }
  3865. /*
  3866. * IMPLEMENTATION of CECImpl methods
  3867. *
  3868. */
  3869. //+-------------------------------------------------------------------------
  3870. //
  3871. // Member: CDefObject::AddConnection
  3872. //
  3873. // Synopsis: Adds an external connection
  3874. //
  3875. // Effects:
  3876. //
  3877. // Arguments: [extconn] -- the type of connection (such as
  3878. // EXTCONN_STRONG)
  3879. // [reserved] -- unused
  3880. //
  3881. // Requires:
  3882. //
  3883. // Returns: DWORD -- the number of strong connections
  3884. //
  3885. // Signals:
  3886. //
  3887. // Modifies:
  3888. //
  3889. // Derivation: IExternalConnection
  3890. //
  3891. // Algorithm: keeps track of strong connections
  3892. //
  3893. // History: dd-mmm-yy Author Comment
  3894. // 08-Nov-93 alexgo 32bit port
  3895. //
  3896. // Notes:
  3897. //
  3898. //--------------------------------------------------------------------------
  3899. STDMETHODIMP_(DWORD) CDefObject::AddConnection(DWORD extconn, DWORD reserved)
  3900. {
  3901. VDATEHEAP();
  3902. //
  3903. // VDATETHREAD contains a 'return HRESULT' but this procedure expects to
  3904. // return a DWORD. Avoid the warning.
  3905. #if ( _MSC_VER >= 800 )
  3906. #pragma warning( disable : 4245 )
  3907. #endif
  3908. VDATETHREAD(this);
  3909. #if ( _MSC_VER >= 800 )
  3910. #pragma warning( default : 4245 )
  3911. #endif
  3912. DWORD dwConn;
  3913. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::AddConnection "
  3914. "( %lu , %lu )\n", this, extconn, reserved));
  3915. Assert( !(m_flags & DH_INPROC_HANDLER) );
  3916. dwConn = extconn&EXTCONN_STRONG ? ++m_cConnections : 0;
  3917. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::AddConnection "
  3918. "( %lu )\n", this, dwConn));
  3919. return dwConn;
  3920. }
  3921. //+-------------------------------------------------------------------------
  3922. //
  3923. // Member: CDefObject::ReleaseConnection
  3924. //
  3925. // Synopsis: Releases external connection, potentially calling IOO->Close
  3926. //
  3927. // Effects:
  3928. //
  3929. // Arguments: [extconn] -- the type of connection
  3930. // [reserved] -- unused
  3931. // [fLastReleaseCloses] -- call IOO->Close if its the last
  3932. // release
  3933. //
  3934. // Requires:
  3935. //
  3936. // Returns:
  3937. //
  3938. // Signals:
  3939. //
  3940. // Modifies:
  3941. //
  3942. // Derivation:
  3943. //
  3944. // Algorithm:
  3945. //
  3946. // History: dd-mmm-yy Author Comment
  3947. // 08-Nov-93 alexgo 32bit port
  3948. //
  3949. // Notes:
  3950. //
  3951. //--------------------------------------------------------------------------
  3952. STDMETHODIMP_(DWORD) CDefObject::ReleaseConnection(DWORD extconn,
  3953. DWORD reserved, BOOL fLastReleaseCloses)
  3954. {
  3955. VDATEHEAP();
  3956. //
  3957. // VDATETHREAD contains a 'return HRESULT' but this procedure expects to
  3958. // return a DWORD. Avoid the warning.
  3959. #if ( _MSC_VER >= 800 )
  3960. #pragma warning( disable : 4245 )
  3961. #endif
  3962. VDATETHREAD(this);
  3963. #if ( _MSC_VER >= 800 )
  3964. #pragma warning( default : 4245 )
  3965. #endif
  3966. DWORD dwConn;
  3967. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::ReleaseConnection "
  3968. "( %lu , %lu , %lu )\n", this, extconn, reserved,
  3969. fLastReleaseCloses));
  3970. CRefStabilize stabilize(this);
  3971. // must be an embedding helper
  3972. Assert( !(m_flags & DH_INPROC_HANDLER) );
  3973. if( (extconn & EXTCONN_STRONG) && --m_cConnections == 0 &&
  3974. fLastReleaseCloses)
  3975. {
  3976. // REVIEW: might want this to be close save if dirty.
  3977. Close(OLECLOSE_NOSAVE);
  3978. }
  3979. dwConn = (extconn & EXTCONN_STRONG) ? m_cConnections : 0;
  3980. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::ReleaseConnection "
  3981. "( %lu )\n", this, dwConn));
  3982. return dwConn;
  3983. }
  3984. /*
  3985. *
  3986. * IMPLEMENTATION of CAdvSinkImpl methods
  3987. *
  3988. */
  3989. //
  3990. // NOTE: Advise Sink is a nested object of Default Handler that is exported
  3991. // for achieving some of its functionality. This introduces some lifetime
  3992. // complications. Can its lifetime be controlled by the server object to
  3993. // which it exported its Advise Sink? Ideally, only its client should
  3994. // control its lifetime alone, but it should also honor the ref counts
  3995. // placed on it by the server object by entering into a zombie state
  3996. // to prevent AV's on the incoming calls to the Advise Sink. All needed
  3997. // logic is coded into the new class "CRefExportCount" which manages
  3998. // the ref and export counts in a thread safe manner and invokes
  3999. // appropriate methods during the object's lifetime. Any server objects
  4000. // that export nested objects to other server objects should derive from
  4001. // "CRefExportCount" class and call its methods to manage their lifetime
  4002. // as exemplified in this Default Handler implementation.
  4003. //
  4004. // Gopalk Jan 10, 97
  4005. //
  4006. //+-------------------------------------------------------------------------
  4007. //
  4008. // Member: CDefObject::CAdvSinkImpl::QueryInterface
  4009. //
  4010. // Synopsis: Only supports IUnknown and IAdviseSink
  4011. //
  4012. // Arguments: [iid] -- Interface requested
  4013. // [ppvObj] -- pointer to hold returned interface
  4014. //
  4015. // Returns: HRESULT
  4016. //
  4017. // History: dd-mmm-yy Author Comment
  4018. // 10-Jan-96 Gopalk Rewritten
  4019. //--------------------------------------------------------------------------
  4020. STDMETHODIMP CDefObject::CAdvSinkImpl::QueryInterface(REFIID iid, void **ppv)
  4021. {
  4022. LEDebugOut((DEB_TRACE,"%p _IN CDefObject::CAdvSinkImpl::QueryInterface()\n",
  4023. this));
  4024. // Validation check
  4025. VDATEHEAP();
  4026. // Local variables
  4027. HRESULT hresult = NOERROR;
  4028. if(IsValidPtrOut(ppv, sizeof(void *))) {
  4029. if(IsEqualIID(iid, IID_IUnknown)) {
  4030. *ppv = (void *)(IUnknown *) this;
  4031. }
  4032. else if(IsEqualIID(iid, IID_IAdviseSink)) {
  4033. *ppv = (void *)(IAdviseSink *) this;
  4034. }
  4035. else {
  4036. *ppv = NULL;
  4037. hresult = E_NOINTERFACE;
  4038. }
  4039. }
  4040. else
  4041. hresult = E_INVALIDARG;
  4042. if(hresult == NOERROR)
  4043. ((IUnknown *) *ppv)->AddRef();
  4044. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::QueryInterface(%lx)\n",
  4045. this, hresult));
  4046. return hresult;
  4047. }
  4048. //+-------------------------------------------------------------------------
  4049. //
  4050. // Member: CDefObject::CAdvSinkImpl::AddRef
  4051. //
  4052. // Synopsis: Increments export count
  4053. //
  4054. // Returns: ULONG; New export count
  4055. //
  4056. // History: dd-mmm-yy Author Comment
  4057. // 10-Jan-96 Gopalk Rewritten
  4058. //--------------------------------------------------------------------------
  4059. STDMETHODIMP_(ULONG) CDefObject::CAdvSinkImpl::AddRef( void )
  4060. {
  4061. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::AddRef()\n",
  4062. this));
  4063. // Validation check
  4064. VDATEHEAP();
  4065. // Local variables
  4066. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4067. ULONG cExportCount;
  4068. // Increment export count
  4069. cExportCount = pDefObject->IncrementExportCount();
  4070. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::AddRef(%ld)\n",
  4071. this, cExportCount));
  4072. return cExportCount;
  4073. }
  4074. //+-------------------------------------------------------------------------
  4075. //
  4076. // Member: CDefObject::CAdvSinkImpl::Release
  4077. //
  4078. // Synopsis: Decerement export count and potentially destroy the object
  4079. //
  4080. // Returns: ULONG; New export count
  4081. //
  4082. // History: dd-mmm-yy Author Comment
  4083. // 10-Jan-96 Gopalk Rewritten
  4084. //--------------------------------------------------------------------------
  4085. STDMETHODIMP_(ULONG) CDefObject::CAdvSinkImpl::Release ( void )
  4086. {
  4087. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::Release()\n",
  4088. this));
  4089. // Validation check
  4090. VDATEHEAP();
  4091. // Local variables
  4092. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4093. ULONG cExportCount;
  4094. // Decrement export count.
  4095. cExportCount = pDefObject->DecrementExportCount();
  4096. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::Release(%ld)\n",
  4097. this, cExportCount));
  4098. return cExportCount;
  4099. }
  4100. //+-------------------------------------------------------------------------
  4101. //
  4102. // Member: CDefObject::CAdvSinkImpl::OnDataChange
  4103. //
  4104. // Synopsis: Function to notify on data change
  4105. //
  4106. // Effects: Never called
  4107. //
  4108. // Arguments: [pFormatetc] -- format of the data
  4109. // [pStgmed] -- data medium
  4110. //
  4111. // Requires:
  4112. //
  4113. // Returns: void
  4114. //
  4115. // Signals:
  4116. //
  4117. // Modifies:
  4118. //
  4119. // Derivation: IAdviseSink
  4120. //
  4121. // Algorithm:
  4122. //
  4123. // History: dd-mmm-yy Author Comment
  4124. // 08-Nov-93 alexgo 32bit port
  4125. //
  4126. // Notes:
  4127. //
  4128. //--------------------------------------------------------------------------
  4129. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnDataChange(
  4130. FORMATETC *pFormatetc, STGMEDIUM *pStgmed)
  4131. {
  4132. VDATEHEAP();
  4133. VOID_VDATEPTRIN( pFormatetc, FORMATETC );
  4134. VOID_VDATEPTRIN( pStgmed, STGMEDIUM );
  4135. Assert(FALSE); // never received
  4136. }
  4137. //+-------------------------------------------------------------------------
  4138. //
  4139. // Member: CDefObject::CAdvSinkImpl::OnViewChange
  4140. //
  4141. // Synopsis: notification of view changes
  4142. //
  4143. // Effects: never called
  4144. //
  4145. // Arguments: [aspects]
  4146. // [lindex]
  4147. //
  4148. // Requires:
  4149. //
  4150. // Returns: void
  4151. //
  4152. // Signals:
  4153. //
  4154. // Modifies:
  4155. //
  4156. // Derivation: IAdviseSink
  4157. //
  4158. // Algorithm:
  4159. //
  4160. // History: dd-mmm-yy Author Comment
  4161. // 08-Nov-93 alexgo 32bit port
  4162. // Notes:
  4163. //
  4164. //--------------------------------------------------------------------------
  4165. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnViewChange
  4166. (DWORD aspects, LONG lindex)
  4167. {
  4168. VDATEHEAP();
  4169. Assert(FALSE); // never received
  4170. }
  4171. //+-------------------------------------------------------------------------
  4172. //
  4173. // Member: CDefObject::CAdvSinkImpl::OnRename
  4174. //
  4175. // Synopsis: Notification of name change. Turns around and informs its
  4176. // advise sinks
  4177. //
  4178. // Arguments: [pmk] -- New name (moniker)
  4179. //
  4180. // History: dd-mmm-yy Author Comment
  4181. // 10-Jan-96 Gopalk Rewritten
  4182. //--------------------------------------------------------------------------
  4183. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnRename(IMoniker *pmk)
  4184. {
  4185. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::OnRename(%p)\n",
  4186. this, pmk));
  4187. // Validation check
  4188. VDATEHEAP();
  4189. // Local variable
  4190. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4191. if(IsValidInterface(pmk)) {
  4192. if(!pDefObject->IsZombie()) {
  4193. // Stabilize
  4194. CRefStabilize stabilize(pDefObject);
  4195. if(pDefObject->m_pOAHolder != NULL)
  4196. pDefObject->m_pOAHolder->SendOnRename(pmk);
  4197. }
  4198. else
  4199. LEDebugOut((DEB_WARN, "OnRename() method invoked on zombied "
  4200. "Default Handler"));
  4201. }
  4202. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::OnRename()\n",
  4203. this));
  4204. }
  4205. //+-------------------------------------------------------------------------
  4206. //
  4207. // Member: CDefObject::CAdvSinkImpl::OnSave
  4208. //
  4209. // Synopsis: Notification of save. Turns around and informs its
  4210. // advise sinks
  4211. //
  4212. // Arguments: None
  4213. //
  4214. // History: dd-mmm-yy Author Comment
  4215. // 10-Jan-96 Gopalk Rewritten
  4216. //--------------------------------------------------------------------------
  4217. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnSave(void)
  4218. {
  4219. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::OnSave()\n",
  4220. this));
  4221. // Validation check
  4222. VDATEHEAP();
  4223. // Local variable
  4224. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4225. if(!pDefObject->IsZombie()) {
  4226. // Stabilize
  4227. CRefStabilize stabilize(pDefObject);
  4228. if(pDefObject->m_pOAHolder != NULL)
  4229. pDefObject->m_pOAHolder->SendOnSave();
  4230. }
  4231. else
  4232. LEDebugOut((DEB_WARN,"OnSave() method invoked on zombied Default Handler"));
  4233. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::OnSave()\n",
  4234. this));
  4235. }
  4236. //+-------------------------------------------------------------------------
  4237. //
  4238. // Member: CDefObject::CAdvSinkImpl::OnClose
  4239. //
  4240. // Synopsis: notification of the object close. Turns around and informs its
  4241. // advise sinks
  4242. //
  4243. // Arguments: None
  4244. //
  4245. // History: dd-mmm-yy Author Comment
  4246. // 10-Jan-96 Gopalk Rewritten
  4247. //--------------------------------------------------------------------------
  4248. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnClose( void )
  4249. {
  4250. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::OnClose()\n",
  4251. this));
  4252. // Validation check
  4253. VDATEHEAP();
  4254. // Local variables
  4255. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4256. if(!pDefObject->IsZombie()) {
  4257. // Stabilize
  4258. CRefStabilize stabilize(pDefObject);
  4259. // Check if container has registered any of its own advise sinks
  4260. if(pDefObject->m_pOAHolder) {
  4261. // Inform the container advise sinks. Note that this can result
  4262. // in additional outgoing calls and consequently, OnClose()
  4263. // method is designed to be not asyncronous
  4264. pDefObject->m_pOAHolder->SendOnClose();
  4265. }
  4266. // Do not rely on container calling close. Stop the running server
  4267. pDefObject->Stop();
  4268. }
  4269. else
  4270. LEDebugOut((DEB_WARN,"OnClose() method invoked on zombied Default Handler"));
  4271. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::OnClose()\n",
  4272. pDefObject));
  4273. return;
  4274. }
  4275. /*
  4276. * IMPLEMENTATION of CPersistStgImpl methods
  4277. *
  4278. */
  4279. //+-------------------------------------------------------------------------
  4280. //
  4281. // Member: CDefObject::GetPSDelegate
  4282. //
  4283. // Synopsis: retrieves the IPersistStorage interface from the delegate
  4284. //
  4285. // Effects:
  4286. //
  4287. // Arguments: void
  4288. //
  4289. // Requires:
  4290. //
  4291. // Returns: IPersistStorage *
  4292. //
  4293. // Signals:
  4294. //
  4295. // Modifies:
  4296. //
  4297. // Derivation:
  4298. //
  4299. // Algorithm:
  4300. //
  4301. // History: dd-mmm-yy Author Comment
  4302. // 08-Nov-93 alexgo 32bit port
  4303. //
  4304. // Notes:
  4305. //
  4306. //--------------------------------------------------------------------------
  4307. INTERNAL_(IPersistStorage *) CDefObject::GetPSDelegate(void)
  4308. {
  4309. VDATEHEAP();
  4310. if( IsZombie() )
  4311. {
  4312. return NULL;
  4313. }
  4314. return (IPersistStorage FAR*)DuCacheDelegate(
  4315. &m_pUnkDelegate,
  4316. IID_IPersistStorage,
  4317. (LPLPVOID) &m_pPSDelegate,
  4318. m_pUnkOuter);
  4319. }
  4320. //+-------------------------------------------------------------------------
  4321. //
  4322. // Member: CDefObject::GetClassID
  4323. //
  4324. // Synopsis: Retrieves the class ID of the object
  4325. //
  4326. // Effects:
  4327. //
  4328. // Arguments: [pClassID] -- where to put the class ID
  4329. //
  4330. // Requires:
  4331. //
  4332. // Returns: HRESULT
  4333. //
  4334. // Signals:
  4335. //
  4336. // Modifies:
  4337. //
  4338. // Derivation: IPersistStorage
  4339. //
  4340. // Algorithm:
  4341. //
  4342. // History: dd-mmm-yy Author Comment
  4343. // 08-Nov-93 alexgo 32bit port
  4344. //
  4345. // Notes:
  4346. //
  4347. //--------------------------------------------------------------------------
  4348. STDMETHODIMP CDefObject::GetClassID (CLSID *pClassID)
  4349. {
  4350. VDATEHEAP();
  4351. VDATETHREAD(this);
  4352. HRESULT hresult;
  4353. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetClassID "
  4354. "( %p )\n", this, pClassID));
  4355. VDATEPTROUT(pClassID, CLSID );
  4356. hresult = GetClassBits(pClassID);
  4357. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetClassID "
  4358. "( %lx ) [ %p ]\n", this, hresult, pClassID));
  4359. return hresult;
  4360. }
  4361. //+-------------------------------------------------------------------------
  4362. //
  4363. // Member: CDefObject::IsDirty
  4364. //
  4365. // Synopsis: Returns whether or not the object needs to be saved
  4366. //
  4367. // Effects:
  4368. //
  4369. // Arguments: void
  4370. //
  4371. // Requires:
  4372. //
  4373. // Returns: HRESULT -- NOERROR means the object *is* dirty
  4374. //
  4375. // Signals:
  4376. //
  4377. // Modifies:
  4378. //
  4379. // Derivation: IPersistStorage
  4380. //
  4381. // Algorithm: if the server is running, delegate. If the server is
  4382. // clean (or not present), ask the cache
  4383. //
  4384. // History: dd-mmm-yy Author Comment
  4385. // 08-Nov-93 alexgo 32bit port
  4386. //
  4387. // Notes:
  4388. //
  4389. //--------------------------------------------------------------------------
  4390. STDMETHODIMP CDefObject::IsDirty( void )
  4391. {
  4392. VDATEHEAP();
  4393. VDATETHREAD(this);
  4394. HRESULT hresult = S_FALSE;
  4395. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::IsDirty ( )\n", this));
  4396. CRefStabilize stabilize(this);
  4397. // if server is running, it holds definitive dirty flag
  4398. if( IsRunning() && GetPSDelegate() )
  4399. {
  4400. if ( FAILED(hresult = m_pPSDelegate->IsDirty()) )
  4401. {
  4402. goto errRtn;
  4403. }
  4404. }
  4405. if (hresult == S_FALSE) {
  4406. Assert(m_pCOleCache != NULL);
  4407. hresult = m_pCOleCache->IsDirty();
  4408. }
  4409. errRtn:
  4410. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::IsDirty "
  4411. "( %lx )\n", this, hresult));
  4412. return hresult;
  4413. }
  4414. //+-------------------------------------------------------------------------
  4415. //
  4416. // Member: CDefObject::InitNew
  4417. //
  4418. // Synopsis: Create a new object with the given storage
  4419. //
  4420. // Effects:
  4421. //
  4422. // Arguments: [pstg] -- the storage for the new object
  4423. //
  4424. // Requires:
  4425. //
  4426. // Returns: HRESULT
  4427. //
  4428. // Signals:
  4429. //
  4430. // Modifies:
  4431. //
  4432. // Derivation: IPersistStorage
  4433. //
  4434. // Algorithm: Delegates to the server and to the cache. Writes
  4435. // Ole private data to the storage.
  4436. //
  4437. // History: dd-mmm-yy Author Comment
  4438. // 08-Nov-93 alexgo 32bit port
  4439. //
  4440. // Notes:
  4441. //
  4442. //--------------------------------------------------------------------------
  4443. STDMETHODIMP CDefObject::InitNew( IStorage *pstg )
  4444. {
  4445. VDATEHEAP();
  4446. VDATETHREAD(this);
  4447. VDATEIFACE( pstg );
  4448. HRESULT hresult;
  4449. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::InitNew ( %p )\n",
  4450. this, pstg));
  4451. CRefStabilize stabilize(this);
  4452. if( m_pStg )
  4453. {
  4454. hresult = CO_E_ALREADYINITIALIZED;
  4455. goto errRtn;
  4456. }
  4457. m_flags |= DH_EMBEDDING;
  4458. if( IsRunning() && GetPSDelegate()
  4459. && (hresult = m_pPSDelegate->InitNew(pstg)) != NOERROR)
  4460. {
  4461. goto errRtn;
  4462. }
  4463. m_flags |= DH_INIT_NEW;
  4464. // if we're in a zombie state, don't change the storage!
  4465. if( IsZombie() )
  4466. {
  4467. hresult = CO_E_RELEASED;
  4468. goto errRtn;
  4469. }
  4470. Assert(m_pCOleCache != NULL);
  4471. if ((hresult = m_pCOleCache->InitNew(pstg)) != NOERROR)
  4472. {
  4473. goto errRtn;
  4474. }
  4475. // remember the storage pointer
  4476. (m_pStg = pstg)->AddRef();
  4477. // go ahead and write the Ole stream now
  4478. WriteOleStg(pstg, (IOleObject *)this, NULL, NULL);
  4479. errRtn:
  4480. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::InitNew "
  4481. "( %lx )\n", this, hresult));
  4482. return hresult;
  4483. }
  4484. //+-------------------------------------------------------------------------
  4485. //
  4486. // Member: CDefObject::Load
  4487. //
  4488. // Synopsis: Loads object data from the given storage
  4489. //
  4490. // Effects:
  4491. //
  4492. // Arguments: [pstg] -- the storage for the object's data
  4493. //
  4494. // Requires:
  4495. //
  4496. // Returns: HRESULT
  4497. //
  4498. // Signals:
  4499. //
  4500. // Modifies:
  4501. //
  4502. // Derivation: IPeristStorage
  4503. //
  4504. // Algorithm: Reads ole-private data (or creates if not there), delegates
  4505. // to the server and the cache.
  4506. //
  4507. // History: dd-mmm-yy Author Comment
  4508. // 08-Nov-93 alexgo 32bit port
  4509. //
  4510. // Notes:
  4511. //
  4512. //--------------------------------------------------------------------------
  4513. STDMETHODIMP CDefObject::Load (IStorage *pstg)
  4514. {
  4515. VDATEHEAP();
  4516. VDATETHREAD(this);
  4517. HRESULT hresult;
  4518. DWORD dwOptUpdate;
  4519. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Load ( %p )\n",
  4520. this, pstg));
  4521. VDATEIFACE( pstg );
  4522. CRefStabilize stabilize(this);
  4523. if( m_pStg )
  4524. {
  4525. hresult = CO_E_ALREADYINITIALIZED;
  4526. goto errRtn;
  4527. }
  4528. m_flags |= DH_EMBEDDING;
  4529. // NOTE: we can get the moniker from container, so no need to get
  4530. // it here
  4531. hresult = ReadOleStg (pstg, &m_dwObjFlags, &dwOptUpdate, NULL, NULL, NULL);
  4532. if (hresult == NOERROR)
  4533. {
  4534. if (m_dwObjFlags & OBJFLAGS_CONVERT)
  4535. {
  4536. if( DoConversionIfSpecialClass(pstg) != NOERROR )
  4537. {
  4538. hresult = OLE_E_CANTCONVERT;
  4539. goto errRtn;
  4540. }
  4541. }
  4542. Assert (dwOptUpdate == NULL);
  4543. }
  4544. else if (hresult == STG_E_FILENOTFOUND)
  4545. {
  4546. // it is OK if the Ole stream doesn't exist.
  4547. hresult = NOERROR;
  4548. // go ahead and write the Ole stream now
  4549. WriteOleStg(pstg, (IOleObject *)this, NULL, NULL);
  4550. }
  4551. else
  4552. {
  4553. goto errRtn;
  4554. }
  4555. // if running, tell server to load from pstg
  4556. if( IsRunning() && GetPSDelegate()
  4557. && (hresult = m_pPSDelegate->Load(pstg)) != NOERROR)
  4558. {
  4559. goto errRtn;
  4560. }
  4561. // if we're in a zombie state, don't addref' the storage!
  4562. if( IsZombie() )
  4563. {
  4564. hresult = CO_E_RELEASED;
  4565. goto errRtn;
  4566. }
  4567. // now load cache from pstg
  4568. Assert(m_pCOleCache != NULL);
  4569. if(m_dwObjFlags & OBJFLAGS_CACHEEMPTY) {
  4570. hresult = m_pCOleCache->Load(pstg, TRUE);
  4571. if(hresult != NOERROR)
  4572. goto errRtn;
  4573. }
  4574. else {
  4575. hresult = m_pCOleCache->Load(pstg);
  4576. if(hresult != NOERROR)
  4577. goto errRtn;
  4578. }
  4579. m_flags &= ~DH_INIT_NEW; // clear init new flag
  4580. // remember the storage pointer
  4581. (m_pStg = pstg)->AddRef();
  4582. errRtn:
  4583. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Load "
  4584. "( %lx )\n", this, hresult));
  4585. return hresult;
  4586. }
  4587. //+-------------------------------------------------------------------------
  4588. //
  4589. // Member: CDefObject::Save
  4590. //
  4591. // Synopsis: Saves the object to the given storage
  4592. //
  4593. // Effects:
  4594. //
  4595. // Arguments: [pstgSave] -- storage in which to save
  4596. // [fSameAsLoad] -- FALSE indicates a SaveAs operation
  4597. //
  4598. // Requires:
  4599. //
  4600. // Returns: HRESULT
  4601. //
  4602. // Signals:
  4603. //
  4604. // Modifies:
  4605. //
  4606. // Derivation: IPersistStorage
  4607. //
  4608. // Algorithm: Saves ole-private data, delegates to the server and then
  4609. // to the cache
  4610. //
  4611. // History: dd-mmm-yy Author Comment
  4612. // 08-Nov-93 alexgo 32bit port
  4613. //
  4614. // Notes:
  4615. //
  4616. //--------------------------------------------------------------------------
  4617. STDMETHODIMP CDefObject::Save( IStorage *pstgSave, BOOL fSameAsLoad)
  4618. {
  4619. VDATEHEAP();
  4620. VDATETHREAD(this);
  4621. HRESULT hresult = NOERROR;
  4622. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Save "
  4623. "( %p , %lu )\n", this, pstgSave, fSameAsLoad ));
  4624. VDATEIFACE( pstgSave );
  4625. CRefStabilize stabilize(this);
  4626. Assert(m_pCOleCache != NULL);
  4627. if( IsRunning() && GetPSDelegate() )
  4628. {
  4629. DWORD grfUpdf = UPDFCACHE_IFBLANK;
  4630. DWORD ObjFlags = 0;
  4631. HRESULT error;
  4632. #ifdef NEVER
  4633. // We would have liked to have done this check as an
  4634. // optimization, but WordArt2 does not give the right answer
  4635. // (bug 3504) so we can't.
  4636. if (m_pPStgDelegate->IsDirty() == NOERROR)
  4637. #endif
  4638. grfUpdf |= UPDFCACHE_ONSAVECACHE;
  4639. // next save server data
  4640. if (hresult = m_pPSDelegate->Save(pstgSave, fSameAsLoad))
  4641. {
  4642. goto errRtn;
  4643. }
  4644. // Update any blank cached presentations
  4645. m_pCOleCache->UpdateCache(GetDataDelegate(), grfUpdf, NULL);
  4646. // Save cache
  4647. hresult = m_pCOleCache->Save(pstgSave, fSameAsLoad);
  4648. // Write the Ole stream after obtaining cache status
  4649. if(m_pCOleCache->IsEmpty())
  4650. ObjFlags |= OBJFLAGS_CACHEEMPTY;
  4651. error = WriteOleStgEx(pstgSave, (IOleObject *)this, NULL, ObjFlags, NULL);
  4652. // Remember the cache status if Ole stream was successfully written and
  4653. // fSameAsLoad is TRUE
  4654. if(error==NOERROR && fSameAsLoad)
  4655. m_dwObjFlags |= ObjFlags;
  4656. }
  4657. else
  4658. {
  4659. // Save the cache
  4660. if ((hresult = m_pCOleCache->Save(m_pStg,TRUE))
  4661. != NOERROR)
  4662. {
  4663. goto errRtn;
  4664. }
  4665. // Check to see if Ole Stream needs to be written
  4666. if((!!(m_dwObjFlags & OBJFLAGS_CACHEEMPTY)) != m_pCOleCache->IsEmpty()) {
  4667. DWORD ObjFlags = 0;
  4668. HRESULT error;
  4669. // Write the Ole stream after obtaining cache status
  4670. if(m_pCOleCache->IsEmpty())
  4671. ObjFlags |= OBJFLAGS_CACHEEMPTY;
  4672. error = WriteOleStgEx(m_pStg, (IOleObject *)this, NULL, ObjFlags, NULL);
  4673. // Remember the cache status if Ole stream was successfully written
  4674. if(error==NOERROR)
  4675. m_dwObjFlags |= ObjFlags;
  4676. }
  4677. // By now we are sure that object's current state has got
  4678. // saved into its storage.
  4679. AssertSz(m_pStg, "Object doesn't have storage");
  4680. // Is saving the existing storage when fSameAsLoad is FLASE correct?
  4681. // To me it seems wrong. Gopalk
  4682. // It is not being fixed fearing some regression in apps
  4683. if (!fSameAsLoad)
  4684. {
  4685. hresult = m_pStg->CopyTo(NULL, NULL, NULL, pstgSave);
  4686. }
  4687. }
  4688. errRtn:
  4689. if (hresult == NOERROR)
  4690. {
  4691. if( fSameAsLoad )
  4692. {
  4693. m_flags |= DH_SAME_AS_LOAD;
  4694. // gets used in SaveCompleted
  4695. m_flags &= ~DH_INIT_NEW;
  4696. }
  4697. else
  4698. {
  4699. m_flags &= ~DH_SAME_AS_LOAD;
  4700. }
  4701. }
  4702. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Save "
  4703. "( %lx )\n", this, hresult));
  4704. return hresult;
  4705. }
  4706. //+-------------------------------------------------------------------------
  4707. //
  4708. // Member: CDefObject::SaveCompleted
  4709. //
  4710. // Synopsis: called when the save is completed
  4711. //
  4712. // Effects:
  4713. //
  4714. // Arguments: [pstgNew] -- the new storage for the object
  4715. //
  4716. // Requires:
  4717. //
  4718. // Returns: HRESULT
  4719. //
  4720. // Signals:
  4721. //
  4722. // Modifies:
  4723. //
  4724. // Derivation: IPersistStorage
  4725. //
  4726. // Algorithm: delegates to the server and the cache.
  4727. //
  4728. // History: dd-mmm-yy Author Comment
  4729. // 08-Nov-93 alexgo 32bit port
  4730. //
  4731. // Notes:
  4732. //
  4733. //--------------------------------------------------------------------------
  4734. STDMETHODIMP CDefObject::SaveCompleted( IStorage *pstgNew )
  4735. {
  4736. VDATEHEAP();
  4737. VDATETHREAD(this);
  4738. HRESULT hresult = NOERROR;
  4739. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SaveCompleted "
  4740. "( %p )\n", this, pstgNew));
  4741. if( pstgNew )
  4742. {
  4743. VDATEIFACE(pstgNew);
  4744. }
  4745. CRefStabilize stabilize(this);
  4746. if( IsRunning() && GetPSDelegate() )
  4747. {
  4748. hresult = m_pPSDelegate->SaveCompleted(pstgNew);
  4749. }
  4750. // we don't save the new storage if we're in a zombie state!
  4751. if( hresult == NOERROR && pstgNew && !IsZombie() )
  4752. {
  4753. if( m_pStg )
  4754. {
  4755. m_pStg->Release();
  4756. }
  4757. m_pStg = pstgNew;
  4758. pstgNew->AddRef();
  4759. }
  4760. // let the cache know that the save is completed, so that it can
  4761. // clear its dirty flag in Save or SaveAs situation, as well as
  4762. // remember the new storage pointer if a new one is given
  4763. Assert(m_pCOleCache != NULL);
  4764. if( (m_flags & DH_SAME_AS_LOAD) || pstgNew)
  4765. {
  4766. // clear init-new and same-as-load flags
  4767. m_flags &= ~(DH_SAME_AS_LOAD | DH_INIT_NEW);
  4768. }
  4769. m_pCOleCache->SaveCompleted(pstgNew);
  4770. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SaveCompleted ( %lx )\n",
  4771. this, hresult));
  4772. return hresult;
  4773. }
  4774. //+-------------------------------------------------------------------------
  4775. //
  4776. // Member: CDefObject::HandsOffStorage
  4777. //
  4778. // Synopsis: Forces the server to release a storage (for low-mem reasons,
  4779. // etc).
  4780. //
  4781. // Effects:
  4782. //
  4783. // Arguments: void
  4784. //
  4785. // Requires:
  4786. //
  4787. // Returns: HRESULT
  4788. //
  4789. // Signals:
  4790. //
  4791. // Modifies:
  4792. //
  4793. // Derivation: IPersistStorage
  4794. //
  4795. // Algorithm: Delegates to the server and the cache
  4796. //
  4797. // History: dd-mmm-yy Author Comment
  4798. // 08-Nov-93 alexgo 32bit port
  4799. //
  4800. // Notes:
  4801. //
  4802. //--------------------------------------------------------------------------
  4803. STDMETHODIMP CDefObject::HandsOffStorage(void)
  4804. {
  4805. VDATEHEAP();
  4806. VDATETHREAD(this);
  4807. HRESULT hresult = NOERROR;
  4808. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::HandsOffStorage ( )\n",
  4809. this));
  4810. CRefStabilize stabilize(this);
  4811. if( IsRunning() && GetPSDelegate() )
  4812. {
  4813. hresult = m_pPSDelegate->HandsOffStorage();
  4814. }
  4815. if (hresult == NOERROR)
  4816. {
  4817. if( m_pStg )
  4818. {
  4819. m_pStg->Release();
  4820. m_pStg = NULL;
  4821. }
  4822. Assert(m_pCOleCache != NULL);
  4823. m_pCOleCache->HandsOffStorage();
  4824. }
  4825. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::HandsOffStorage ( %lx )\n",
  4826. this, hresult));
  4827. return hresult;
  4828. }
  4829. /*
  4830. * Default handler private functions
  4831. */
  4832. //+-------------------------------------------------------------------------
  4833. //
  4834. // Member: CDefObject::GetClassBits
  4835. //
  4836. // Synopsis: Gets a class id for the object
  4837. //
  4838. // Effects:
  4839. //
  4840. // Arguments: [pClsidBits] -- where to put the class id
  4841. //
  4842. // Requires:
  4843. //
  4844. // Returns: HRESULT
  4845. //
  4846. // Signals:
  4847. //
  4848. // Modifies:
  4849. //
  4850. // Derivation:
  4851. //
  4852. // Algorithm: Tries the server, then the storage, and finally the
  4853. // clsid we were created with
  4854. //
  4855. // History: dd-mmm-yy Author Comment
  4856. // 08-Nov-93 alexgo 32bit port
  4857. //
  4858. // Notes:
  4859. //
  4860. // always gets a clsid and returns NOERROR; the clsid may be m_clsidServer
  4861. // under certain conditions (e.g., no compobj stream).
  4862. //
  4863. //--------------------------------------------------------------------------
  4864. INTERNAL CDefObject::GetClassBits(CLSID FAR* pClsidBits)
  4865. {
  4866. VDATEHEAP();
  4867. // alway try server first; this allows the server to respond
  4868. if( IsRunning() && GetPSDelegate() )
  4869. {
  4870. if( m_pPSDelegate->GetClassID(pClsidBits) == NOERROR )
  4871. {
  4872. m_clsidBits = *pClsidBits;
  4873. return NOERROR;
  4874. }
  4875. }
  4876. // not running, no ps or error: use previously cached value
  4877. if( !IsEqualCLSID(m_clsidBits, CLSID_NULL) )
  4878. {
  4879. *pClsidBits = m_clsidBits;
  4880. return NOERROR;
  4881. }
  4882. // not running, no ps or error and no clsidBits yet: read from stg
  4883. // if not static object.
  4884. if( !(m_flags & DH_STATIC) )
  4885. {
  4886. if (m_pStg && ReadClassStg(m_pStg, pClsidBits) == NOERROR)
  4887. {
  4888. m_clsidBits = *pClsidBits;
  4889. return NOERROR;
  4890. }
  4891. }
  4892. // no contact with server and can't get from storage; don't set
  4893. // m_clsidBits so if we get a storage or the serve becomes running,
  4894. // we get the right one
  4895. *pClsidBits = m_clsidServer;
  4896. return NOERROR;
  4897. }
  4898. //+-------------------------------------------------------------------------
  4899. //
  4900. // Member: CDefObject::DoConversionIfSpecialClass
  4901. //
  4902. // Synopsis: Convert old data formats.
  4903. //
  4904. // Effects:
  4905. //
  4906. // Arguments: [pstg] -- the storage with the data
  4907. //
  4908. // Requires:
  4909. //
  4910. // Returns: HRESULT
  4911. //
  4912. // Signals:
  4913. //
  4914. // Modifies:
  4915. //
  4916. // Derivation:
  4917. //
  4918. // Algorithm: see notes...
  4919. //
  4920. // History: dd-mmm-yy Author Comment
  4921. // 08-Nov-93 alexgo 32bit port
  4922. //
  4923. // Notes: this is not yet functional for 32bit OLE
  4924. //
  4925. // If the class is CLSID_StaticDib/CLSID_StaticMetafile and the old
  4926. // format is "PBrush"/"MSDraw" the data must be in the OLE10_NATIVESTREAM.
  4927. // Move the data into the CONTENTS stream
  4928. //
  4929. // If the class is CLSID_PBrush/CLSID_MSDraw and the old format is
  4930. // metafile/DIB then data must be in the CONTENTS stream. Move the data
  4931. // from the CONTENTS stream to the OLE10_NATIVESTREAM"
  4932. //
  4933. //--------------------------------------------------------------------------
  4934. INTERNAL CDefObject::DoConversionIfSpecialClass(LPSTORAGE pstg)
  4935. {
  4936. VDATEHEAP();
  4937. LEDebugOut((DEB_ITRACE, "%p _IN CDefObject::DoConversionIfSpecialClass ("
  4938. " %p )\n", this, pstg));
  4939. HRESULT hresult;
  4940. UINT uiStatus;
  4941. /*** Handle the static object case ***/
  4942. if( (m_flags & DH_STATIC) ) {
  4943. if ((hresult = Ut10NativeStmToContentsStm(pstg, m_clsidServer,
  4944. TRUE /* fDeleteContentStm*/)) == NOERROR)
  4945. #ifdef OLD
  4946. UtRemoveExtraOlePresStreams(pstg, 0 /*iStart*/);
  4947. #endif
  4948. goto errRtn;
  4949. }
  4950. /*** Handle the PBrush & MSDraw case ***/
  4951. // Conversion is not a frequent operation. So, it is better to do the
  4952. // CLSID comparison here when it is necessary than doing comparison
  4953. // upfront and remember a flag
  4954. // if the class is not one of the following two then the object server
  4955. // will do the necessary conversion.
  4956. {
  4957. CLSID clsid = CLSID_NULL;
  4958. // Get the real CLSID from the storage. This is necessary because we
  4959. // may be a PBrush object being "treated as".
  4960. ReadClassStg(pstg, &clsid);
  4961. // if the real CLSID is not PaintBrush or the known CLSID is not MSDRAW
  4962. // head out.
  4963. if( clsid != CLSID_PBrush && m_clsidServer != CLSID_MSDraw )
  4964. {
  4965. hresult = NOERROR;
  4966. goto exitRtn;
  4967. }
  4968. // if the real CLSID is not paintbrush, then set clsid to the clsid to
  4969. // the known clsid.
  4970. if (clsid != CLSID_PBrush)
  4971. {
  4972. clsid = m_clsidServer;
  4973. }
  4974. //
  4975. hresult = UtContentsStmTo10NativeStm(pstg, clsid,
  4976. TRUE /* fDeleteContentStm*/,
  4977. &uiStatus);
  4978. }
  4979. // if OLE10_NATIVE_STREAM exists then assume success
  4980. if (!(uiStatus & CONVERT_NODESTINATION))
  4981. hresult = NOERROR;
  4982. if (hresult != NOERROR) {
  4983. // May be the static object data is in OlePres stream. If so,
  4984. // first convert that to contents stream and then try again
  4985. // In OLE2.0 first release static object were written to
  4986. // OlePres000 stream.
  4987. hresult = UtOlePresStmToContentsStm(pstg,
  4988. OLE_PRESENTATION_STREAM,
  4989. TRUE /*fDeletePresStm*/, &uiStatus);
  4990. if (hresult == NOERROR)
  4991. hresult = UtContentsStmTo10NativeStm(pstg,
  4992. m_clsidServer,
  4993. TRUE /* fDeleteContentStm*/,
  4994. &uiStatus);
  4995. }
  4996. errRtn:
  4997. if (hresult == NOERROR)
  4998. // conversion is successful, turn the bit off
  4999. SetConvertStg(pstg, FALSE);
  5000. exitRtn:
  5001. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::DoConversionIfSpecialClass "
  5002. "( %lx ) \n", this, hresult));
  5003. return hresult;
  5004. }
  5005. //+-------------------------------------------------------------------------
  5006. //
  5007. // Member: CDefObject::Dump, public (_DEBUG only)
  5008. //
  5009. // Synopsis: return a string containing the contents of the data members
  5010. //
  5011. // Effects:
  5012. //
  5013. // Arguments: [ppszDump] - an out pointer to a null terminated character array
  5014. // [ulFlag] - flag determining prefix of all newlines of the
  5015. // out character array (default is 0 - no prefix)
  5016. // [nIndentLevel] - will add a indent prefix after the other prefix
  5017. // for ALL newlines (including those with no prefix)
  5018. //
  5019. // Requires:
  5020. //
  5021. // Returns: HRESULT
  5022. //
  5023. // Signals:
  5024. //
  5025. // Modifies: [ppszDump] - argument
  5026. //
  5027. // Derivation:
  5028. //
  5029. // Algorithm: use dbgstream to create a string containing information on the
  5030. // content of data structures
  5031. //
  5032. // History: dd-mmm-yy Author Comment
  5033. // 01-Feb-95 t-ScottH author
  5034. //
  5035. // Notes:
  5036. //
  5037. //--------------------------------------------------------------------------
  5038. #ifdef _DEBUG
  5039. HRESULT CDefObject::Dump(char **ppszDump, ULONG ulFlag, int nIndentLevel)
  5040. {
  5041. int i;
  5042. char *pszPrefix;
  5043. char *pszCSafeRefCount;
  5044. char *pszCThreadCheck;
  5045. char *pszOAHolder;
  5046. char *pszCLSID;
  5047. char *pszCOleCache;
  5048. char *pszDAC;
  5049. LPOLESTR pszName;
  5050. dbgstream dstrPrefix;
  5051. dbgstream dstrDump(5000);
  5052. // determine prefix of newlines
  5053. if ( ulFlag & DEB_VERBOSE )
  5054. {
  5055. dstrPrefix << this << " _VB ";
  5056. }
  5057. // determine indentation prefix for all newlines
  5058. for (i = 0; i < nIndentLevel; i++)
  5059. {
  5060. dstrPrefix << DUMPTAB;
  5061. }
  5062. pszPrefix = dstrPrefix.str();
  5063. // put data members in stream
  5064. pszCThreadCheck = DumpCThreadCheck((CThreadCheck *)this, ulFlag, nIndentLevel + 1);
  5065. dstrDump << pszPrefix << "CThreadCheck:" << endl;
  5066. dstrDump << pszCThreadCheck;
  5067. CoTaskMemFree(pszCThreadCheck);
  5068. // only vtable pointers (plus we don't get the right address in debugger extensions)
  5069. // dstrDump << pszPrefix << "&IUnknown = " << &m_Unknown << endl;
  5070. // dstrDump << pszPrefix << "&IAdviseSink = " << &m_AdviseSink << endl;
  5071. dstrDump << pszPrefix << "pIOleObject Delegate = " << m_pOleDelegate << endl;
  5072. dstrDump << pszPrefix << "pIDataObject Delegate = " << m_pDataDelegate << endl;
  5073. dstrDump << pszPrefix << "pIPersistStorage Delegate = " << m_pPSDelegate << endl;
  5074. dstrDump << pszPrefix << "Count of Strong Connection= " << m_cConnections << endl;
  5075. dstrDump << pszPrefix << "pIUnknown pUnkOuter = ";
  5076. if (m_flags & DH_AGGREGATED)
  5077. {
  5078. dstrDump << "AGGREGATED (" << m_pUnkOuter << ")" << endl;
  5079. }
  5080. else
  5081. {
  5082. dstrDump << "NO AGGREGATION (" << m_pUnkOuter << ")" << endl;
  5083. }
  5084. pszCLSID = DumpCLSID(m_clsidServer);
  5085. dstrDump << pszPrefix << "Server CLSID = " << pszCLSID << endl;
  5086. CoTaskMemFree(pszCLSID);
  5087. pszCLSID = DumpCLSID(m_clsidBits);
  5088. dstrDump << pszPrefix << "Persistent CLSID = " << pszCLSID << endl;
  5089. CoTaskMemFree(pszCLSID);
  5090. dstrDump << pszPrefix << "Handler flags = ";
  5091. if (m_flags & DH_SAME_AS_LOAD)
  5092. {
  5093. dstrDump << "DH_SAME_AS_LOAD ";
  5094. }
  5095. if (m_flags & DH_CONTAINED_OBJECT)
  5096. {
  5097. dstrDump << "DH_CONTAINED_OBJECT ";
  5098. }
  5099. if (m_flags & DH_LOCKED_CONTAINER)
  5100. {
  5101. dstrDump << "DH_LOCKED_CONTAINER ";
  5102. }
  5103. if (m_flags & DH_FORCED_RUNNING)
  5104. {
  5105. dstrDump << "DH_FORCED_RUNNING ";
  5106. }
  5107. if (m_flags & DH_EMBEDDING)
  5108. {
  5109. dstrDump << "DH_EMBEDDING ";
  5110. }
  5111. if (m_flags & DH_INIT_NEW)
  5112. {
  5113. dstrDump << "DH_INIT_NEW ";
  5114. }
  5115. if (m_flags & DH_STATIC)
  5116. {
  5117. dstrDump << "DH_STATIC ";
  5118. }
  5119. if (m_flags & DH_INPROC_HANDLER)
  5120. {
  5121. dstrDump << "DH_INPROC_HANDLER ";
  5122. }
  5123. if (m_flags & DH_DELAY_CREATE)
  5124. {
  5125. dstrDump << "DH_DELAY_CREATE ";
  5126. }
  5127. if (m_flags & DH_AGGREGATED)
  5128. {
  5129. dstrDump << "DH_AGGREGATED ";
  5130. }
  5131. // if none of the flags are set...
  5132. if ( !( (m_flags & DH_SAME_AS_LOAD) |
  5133. (m_flags & DH_CONTAINED_OBJECT) |
  5134. (m_flags & DH_LOCKED_CONTAINER) |
  5135. (m_flags & DH_FORCED_RUNNING) |
  5136. (m_flags & DH_EMBEDDING) |
  5137. (m_flags & DH_INIT_NEW) |
  5138. (m_flags & DH_STATIC) |
  5139. (m_flags & DH_INPROC_HANDLER) |
  5140. (m_flags & DH_DELAY_CREATE) |
  5141. (m_flags & DH_AGGREGATED)))
  5142. {
  5143. dstrDump << "No FLAGS SET!";
  5144. }
  5145. dstrDump << "(" << LongToPtr(m_flags) << ")" << endl;
  5146. dstrDump << pszPrefix << "pIClassFactory Delegate = " << m_pCFDelegate << endl;
  5147. dstrDump << pszPrefix << "pIUnknown Delegate = " << m_pUnkDelegate << endl;
  5148. dstrDump << pszPrefix << "pIProxyManager = " << m_pProxyMgr << endl;
  5149. if (m_pCOleCache != NULL)
  5150. {
  5151. // pszCOleCache = DumpCOleCache(m_pCOleCache, ulFlag, nIndentLevel + 1);
  5152. dstrDump << pszPrefix << "COleCache: " << endl;
  5153. // dstrDump << pszCOleCache;
  5154. // CoTaskMemFree(pszCOleCache);
  5155. }
  5156. else
  5157. {
  5158. dstrDump << pszPrefix << "pCOleCache = " << m_pCOleCache << endl;
  5159. }
  5160. if (m_pOAHolder != NULL)
  5161. {
  5162. pszOAHolder = DumpCOAHolder(m_pOAHolder, ulFlag, nIndentLevel + 1);
  5163. dstrDump << pszPrefix << "COAHolder: " << endl;
  5164. dstrDump << pszOAHolder;
  5165. CoTaskMemFree(pszOAHolder);
  5166. }
  5167. else
  5168. {
  5169. dstrDump << pszPrefix << "pIOleAdviseHolder = " << m_pOAHolder << endl;
  5170. }
  5171. dstrDump << pszPrefix << "OLE Connection Advise ID = " << m_dwConnOle << endl;
  5172. dstrDump << pszPrefix << "pIOleClientSite = " << m_pAppClientSite << endl;
  5173. dstrDump << pszPrefix << "pIStorage = " << m_pStg << endl;
  5174. pszName = (LPOLESTR)m_pHostNames;
  5175. dstrDump << pszPrefix << "Application Name = " << pszName << endl;
  5176. pszName = (LPOLESTR)(m_pHostNames + m_ibCntrObj);
  5177. dstrDump << pszPrefix << "Document Name = " << pszName << endl;
  5178. if (m_pDataAdvCache != NULL)
  5179. {
  5180. pszDAC = DumpCDataAdviseCache(m_pDataAdvCache, ulFlag, nIndentLevel + 1);
  5181. dstrDump << pszPrefix << "CDataAdviseCache: " << endl;
  5182. dstrDump << pszDAC;
  5183. CoTaskMemFree(pszDAC);
  5184. }
  5185. else
  5186. {
  5187. dstrDump << pszPrefix << "pCDataAdviseCache = " << m_pDataAdvCache << endl;
  5188. }
  5189. // cleanup and provide pointer to character array
  5190. *ppszDump = dstrDump.str();
  5191. if (*ppszDump == NULL)
  5192. {
  5193. *ppszDump = UtDupStringA(szDumpErrorMessage);
  5194. }
  5195. CoTaskMemFree(pszPrefix);
  5196. return NOERROR;
  5197. }
  5198. #endif // _DEBUG
  5199. //+-------------------------------------------------------------------------
  5200. //
  5201. // Function: DumpCDefObject, public (_DEBUG only)
  5202. //
  5203. // Synopsis: calls the CDefObject::Dump method, takes care of errors and
  5204. // returns the zero terminated string
  5205. //
  5206. // Effects:
  5207. //
  5208. // Arguments: [pDO] - pointer to CDefObject
  5209. // [ulFlag] - flag determining prefix of all newlines of the
  5210. // out character array (default is 0 - no prefix)
  5211. // [nIndentLevel] - will add a indent prefix after the other prefix
  5212. // for ALL newlines (including those with no prefix)
  5213. //
  5214. // Requires:
  5215. //
  5216. // Returns: character array of structure dump or error (null terminated)
  5217. //
  5218. // Signals:
  5219. //
  5220. // Modifies:
  5221. //
  5222. // Algorithm:
  5223. //
  5224. // History: dd-mmm-yy Author Comment
  5225. // 01-Feb-95 t-ScottH author
  5226. //
  5227. // Notes:
  5228. //
  5229. //--------------------------------------------------------------------------
  5230. #ifdef _DEBUG
  5231. char *DumpCDefObject(CDefObject *pDO, ULONG ulFlag, int nIndentLevel)
  5232. {
  5233. HRESULT hresult;
  5234. char *pszDump;
  5235. if (pDO == NULL)
  5236. {
  5237. return UtDupStringA(szDumpBadPtr);
  5238. }
  5239. hresult = pDO->Dump(&pszDump, ulFlag, nIndentLevel);
  5240. if (hresult != NOERROR)
  5241. {
  5242. CoTaskMemFree(pszDump);
  5243. return DumpHRESULT(hresult);
  5244. }
  5245. return pszDump;
  5246. }
  5247. #endif // _DEBUG