Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6200 lines
168 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. QueryClassesRootValue (OLESTR("Software\\Microsoft\\OLE2\\UnknownUserType"),
  3126. sz, &cb))
  3127. ? (LPCOLESTR)sz : OLESTR("Unknown"));
  3128. if (NULL != *ppszUserType)
  3129. {
  3130. hresult = NOERROR;
  3131. }
  3132. else
  3133. {
  3134. hresult = E_OUTOFMEMORY;
  3135. }
  3136. }
  3137. errRtn:
  3138. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetUserType "
  3139. "( %lx ) [ %p ]\n", this, hresult, *ppszUserType));
  3140. return hresult;
  3141. }
  3142. /*
  3143. * IMPLEMENTATION of CROImpl methods
  3144. *
  3145. * We never delegate to the server. This is by design.
  3146. */
  3147. //+-------------------------------------------------------------------------
  3148. //
  3149. // Member: CDefObject::GetRunningClass
  3150. //
  3151. // Synopsis: Get the class id of the server
  3152. //
  3153. // Effects:
  3154. //
  3155. // Arguments: [lpClsid] -- where to put the class id
  3156. //
  3157. // Requires:
  3158. //
  3159. // Returns: HRESULT
  3160. //
  3161. // Signals:
  3162. //
  3163. // Modifies:
  3164. //
  3165. // Derivation: IRunnableObject
  3166. //
  3167. // Algorithm:
  3168. //
  3169. // History: dd-mmm-yy Author Comment
  3170. // 07-Nov-93 alexgo 32bit port
  3171. //
  3172. // Notes: We do not need to stabilize this call as no outgoing
  3173. // calls are made.
  3174. //
  3175. //--------------------------------------------------------------------------
  3176. STDMETHODIMP CDefObject::GetRunningClass(LPCLSID lpClsid)
  3177. {
  3178. VDATEHEAP();
  3179. VDATETHREAD(this);
  3180. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetRunningClass "
  3181. "( %p )\n", this, lpClsid));
  3182. VDATEPTROUT(lpClsid, CLSID);
  3183. *lpClsid = m_clsidServer;
  3184. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetRunningClass "
  3185. "( %lx ) [ %p ]\n", this, NOERROR, lpClsid));
  3186. return NOERROR;
  3187. }
  3188. //+-------------------------------------------------------------------------
  3189. //
  3190. // Member: CDefObject::Run
  3191. //
  3192. // Synopsis: Sets the object running (if it isn't already)
  3193. //
  3194. // Effects: may launch the server
  3195. //
  3196. // Arguments: [pbc] -- the bind context (unused)
  3197. //
  3198. // Requires:
  3199. //
  3200. // Returns: HRESULT
  3201. //
  3202. // Signals:
  3203. //
  3204. // Modifies:
  3205. //
  3206. // Derivation: IRunnableObject
  3207. //
  3208. // Algorithm: If already running, return. Otherwise, get the proxy
  3209. // manager to create the server. Initialize the storage
  3210. // and caches, and set the host name for the server's window.
  3211. //
  3212. // History: dd-mmm-yy Author Comment
  3213. // 07-Nov-93 alexgo 32bit port
  3214. //
  3215. // Notes:
  3216. //
  3217. //--------------------------------------------------------------------------
  3218. STDMETHODIMP CDefObject::Run(LPBINDCTX pbc)
  3219. {
  3220. VDATEHEAP();
  3221. VDATETHREAD(this);
  3222. HRESULT hresult;
  3223. IDataObject FAR* pDataDelegate = NULL;
  3224. IOleObject FAR* pOleDelegate = NULL;
  3225. IPersistStorage FAR* pPStgDelegate = NULL;
  3226. IMoniker FAR* pmk = NULL;
  3227. BOOL fLockedContainer;
  3228. DWORD dwMiscStatus = 0;
  3229. // NOTE: ignore pbc for now
  3230. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Run ( %p )\n", this, pbc));
  3231. CRefStabilize stabilize(this);
  3232. if( IsRunning() )
  3233. {
  3234. hresult = S_OK;
  3235. // just return the error code
  3236. goto errRtn2;
  3237. }
  3238. if( (m_flags & DH_STATIC) )
  3239. {
  3240. hresult = OLE_E_STATIC;
  3241. goto errRtn2;
  3242. }
  3243. if( IsZombie() )
  3244. {
  3245. hresult = CO_E_RELEASED;
  3246. goto errRtn2;
  3247. }
  3248. if( FAILED(hresult = CreateDelegate()) )
  3249. {
  3250. // just return the error code
  3251. goto errRtn2;
  3252. }
  3253. if (m_pProxyMgr != NULL)
  3254. {
  3255. #ifdef SERVER_HANDLER
  3256. IServerHandler *pSrvHndl = NULL;
  3257. hresult = m_pProxyMgr->CreateServerWithEmbHandler(m_clsidServer,
  3258. CLSCTX_LOCAL_SERVER | CLSCTX_ESERVER_HANDLER ,
  3259. IID_IServerHandler,(void **) &pSrvHndl,NULL);
  3260. if(FAILED(hresult))
  3261. Win4Assert(NULL == pSrvHndl);
  3262. #else
  3263. hresult = m_pProxyMgr->CreateServer(m_clsidServer,
  3264. CLSCTX_LOCAL_SERVER,
  3265. NULL);
  3266. #endif // SERVER_HANDLER
  3267. if (FAILED(hresult))
  3268. {
  3269. goto errRtn;
  3270. }
  3271. // if there is a serverHandler, create a wrapper object for handling standard interfaces
  3272. #ifdef SERVER_HANDLER
  3273. if (pSrvHndl)
  3274. {
  3275. m_pEmbSrvHndlrWrapper = CreateEmbServerWrapper(m_pUnkOuter,pSrvHndl);
  3276. pSrvHndl->Release();
  3277. }
  3278. else
  3279. {
  3280. m_pEmbSrvHndlrWrapper = NULL;
  3281. }
  3282. #endif // SERVER_HANDLER
  3283. }
  3284. // NOTE: the lock state of the proxy mgr is not changed; it remembers
  3285. // the state and sets up the connection correctly.
  3286. // server is running; normally this coincides with locking the
  3287. // container, but we keep a separate flag since locking the container
  3288. // may fail.
  3289. m_flags |= DH_FORCED_RUNNING;
  3290. // Lock the container
  3291. fLockedContainer = m_flags & DH_LOCKED_CONTAINER;
  3292. DuLockContainer(m_pAppClientSite, TRUE, &fLockedContainer );
  3293. if( fLockedContainer )
  3294. {
  3295. m_flags |= DH_LOCKED_CONTAINER;
  3296. }
  3297. else
  3298. {
  3299. m_flags &= ~DH_LOCKED_CONTAINER;
  3300. }
  3301. #if DBG==1
  3302. // In debug builds, update DH_LOCKFAILED flag
  3303. if(fLockedContainer)
  3304. m_flags &= ~DH_LOCKFAILED;
  3305. else
  3306. m_flags |= DH_LOCKFAILED;
  3307. #endif
  3308. #ifdef SERVER_HANDLER
  3309. if (m_pEmbSrvHndlrWrapper)
  3310. {
  3311. MInterfacePointer *pIRDClientSite = NULL;
  3312. CStdIdentity *pStdid = NULL;
  3313. CClientSiteHandler *pClientSiteHandler = NULL;
  3314. GUID riid = IID_IOleClientSite; //Reference to the identifier of the interface
  3315. BOOL fHasIPSite = FALSE;
  3316. IUnknown *pUnk = NULL; //Pointer to the interface to be marshaled
  3317. CXmitRpcStream Stm;
  3318. if (m_pAppClientSite)
  3319. {
  3320. // Only wrap ClientSite if there is not an existing Identity.
  3321. if (NOERROR != LookupIDFromUnk(m_pAppClientSite, GetCurrentApartmentId(),0,&pStdid))
  3322. {
  3323. Assert(NULL == pClientSiteHandler);
  3324. hresult = CreateClientSiteHandler(m_pAppClientSite,&pClientSiteHandler,&fHasIPSite);
  3325. riid = IID_IClientSiteHandler;
  3326. pUnk = (IUnknown *) (IClientSiteHandler *) pClientSiteHandler;
  3327. }
  3328. else
  3329. {
  3330. riid = IID_IOleClientSite;
  3331. pUnk = (IUnknown *) (IOleClientSite*) m_pAppClientSite;
  3332. pUnk->AddRef();
  3333. }
  3334. hresult = CoMarshalInterface(&Stm,riid,
  3335. pUnk,
  3336. MSHCTX_DIFFERENTMACHINE,
  3337. NULL, MSHLFLAGS_NORMAL);
  3338. if (SUCCEEDED(hresult))
  3339. {
  3340. Stm.AssignSerializedInterface((InterfaceData **) &pIRDClientSite);
  3341. }
  3342. m_pRunClientSite = m_pAppClientSite; // Remember ClientSite on Run.
  3343. }
  3344. Assert(m_dwConnOle == 0L);
  3345. hresult = m_pEmbSrvHndlrWrapper->Run(m_flags,
  3346. riid,
  3347. pIRDClientSite,
  3348. fHasIPSite,
  3349. (LPOLESTR)m_pHostNames,
  3350. (LPOLESTR)(m_pHostNames + m_ibCntrObj),
  3351. (IStorage *) m_pStg,
  3352. (IAdviseSink *) &m_AdviseSink,
  3353. &m_dwConnOle,
  3354. &m_hresultClsidUser,
  3355. &m_clsidUser,
  3356. &m_hresultContentMiscStatus,
  3357. &m_ContentMiscStatusUser
  3358. );
  3359. if (pIRDClientSite)
  3360. CoTaskMemFree(pIRDClientSite);
  3361. if (pStdid)
  3362. pStdid->Release();
  3363. if (pUnk)
  3364. pUnk->Release();
  3365. // !!! Make sure on error don't set up Cache.
  3366. if (NOERROR != hresult)
  3367. {
  3368. goto errRtn;
  3369. }
  3370. // set up any cached interfaces
  3371. // !!!!!TODO: Not All LeSuite Linking Tests Pass when Cache DataObject through ServerHandler.
  3372. if (!m_pDataDelegate)
  3373. {
  3374. if (NOERROR == m_pEmbSrvHndlrWrapper->m_Unknown.QueryInterface(IID_IDataObject,(void **) &m_pDataDelegate))
  3375. {
  3376. m_pUnkOuter->Release();
  3377. }
  3378. }
  3379. }
  3380. else
  3381. #endif // SERVER_HANDLER
  3382. {
  3383. // Check if we have client site
  3384. if(m_pAppClientSite) {
  3385. // Clear the cached MiscStatus bits
  3386. m_ContentSRVMSBits = 0;
  3387. m_ContentSRVMSHResult = 0xFFFFFFFF;
  3388. // Get MiscStatus bits from the running server
  3389. hresult = GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
  3390. // Set the client site first if OLEMISC_SETCLIENTSITEFIRST bit is set
  3391. if(hresult == NOERROR && (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) &&
  3392. (pOleDelegate = GetOleDelegate()))
  3393. hresult = pOleDelegate->SetClientSite(m_pAppClientSite);
  3394. else if(hresult != NOERROR) {
  3395. hresult = NOERROR;
  3396. dwMiscStatus = 0;
  3397. }
  3398. }
  3399. if(hresult != NOERROR)
  3400. goto errRtn;
  3401. if( pPStgDelegate = GetPSDelegate() )
  3402. {
  3403. if( m_pStg)
  3404. {
  3405. if( (m_flags & DH_INIT_NEW) )
  3406. {
  3407. hresult = pPStgDelegate->InitNew(m_pStg);
  3408. }
  3409. else
  3410. {
  3411. hresult = pPStgDelegate->Load(m_pStg);
  3412. }
  3413. if (hresult != NOERROR)
  3414. {
  3415. // this will cause us to stop the
  3416. // the server we just launced
  3417. goto errRtn;
  3418. }
  3419. }
  3420. }
  3421. if(pOleDelegate || (pOleDelegate = GetOleDelegate()))
  3422. {
  3423. // REVIEW MM1: what are we supposed to do in case of failure
  3424. if(m_pAppClientSite && !(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
  3425. {
  3426. pOleDelegate->SetClientSite(m_pAppClientSite);
  3427. }
  3428. if (m_pHostNames)
  3429. {
  3430. if (hresult = pOleDelegate->SetHostNames((LPOLESTR)m_pHostNames,
  3431. (LPOLESTR)(m_pHostNames + m_ibCntrObj))
  3432. != NOERROR)
  3433. {
  3434. goto errRtn;
  3435. }
  3436. }
  3437. // set single ole advise (we multiplex)
  3438. Assert(m_dwConnOle == 0L);
  3439. if ((hresult = pOleDelegate->Advise((IAdviseSink *)&m_AdviseSink,
  3440. &m_dwConnOle)) != NOERROR)
  3441. {
  3442. goto errRtn;
  3443. }
  3444. if(m_pAppClientSite != NULL &&
  3445. m_pAppClientSite->GetMoniker
  3446. (OLEGETMONIKER_ONLYIFTHERE,
  3447. OLEWHICHMK_OBJREL, &pmk) == NOERROR)
  3448. {
  3449. AssertOutPtrIface(NOERROR, pmk);
  3450. pOleDelegate->SetMoniker(OLEWHICHMK_OBJREL, pmk);
  3451. pmk->Release();
  3452. }
  3453. }
  3454. }
  3455. Win4Assert(NOERROR == hresult);
  3456. if( pDataDelegate = GetDataDelegate() )
  3457. {
  3458. // inform cache that we are running
  3459. Assert(m_pCOleCache != NULL);
  3460. m_pCOleCache->OnRun(pDataDelegate);
  3461. // Enumerate all the advises we stored while we were either not
  3462. // running or running the previous time, and send them to the
  3463. // now-running object.
  3464. m_pDataAdvCache->EnumAndAdvise(pDataDelegate, TRUE);
  3465. }
  3466. errRtn:
  3467. if(hresult == NOERROR) {
  3468. // Clear the cached MiscStatus bits if not cleared before
  3469. #ifdef SERVER_HANDLER
  3470. if(m_pEmbSrvHndlrWrapper) {
  3471. m_ContentSRVMSBits = 0;
  3472. m_ContentSRVMSHResult = 0xFFFFFFFF;
  3473. }
  3474. else
  3475. #endif // SERVER_HANDLER
  3476. if(!m_pAppClientSite) {
  3477. m_ContentSRVMSBits = 0;
  3478. m_ContentSRVMSHResult = 0xFFFFFFFF;
  3479. }
  3480. }
  3481. else {
  3482. // Stop the running object
  3483. Stop();
  3484. // Assert that the container is not locked
  3485. Win4Assert(!(m_flags & DH_LOCKED_CONTAINER) && !(m_flags & DH_LOCKFAILED));
  3486. }
  3487. errRtn2:
  3488. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Run "
  3489. "( %lx )\n", this, hresult));
  3490. return hresult;
  3491. }
  3492. //+-------------------------------------------------------------------------
  3493. //
  3494. // Member: CDefObject::Stop
  3495. //
  3496. // Synopsis: Undoes some of Run() (stops the server)...internal function
  3497. //
  3498. // Effects:
  3499. //
  3500. // Arguments: void
  3501. //
  3502. // Requires:
  3503. //
  3504. // Returns: HRESULT
  3505. //
  3506. // Signals:
  3507. //
  3508. // Modifies:
  3509. //
  3510. // Derivation:
  3511. //
  3512. // Algorithm: unadvise connections (if any), stop the cache, disconnect
  3513. // from the proxy manager and unlock the container
  3514. //
  3515. // History: dd-mmm-yy Author Comment
  3516. // 07-Nov-93 alexgo 32bit port
  3517. //
  3518. // Notes:
  3519. //
  3520. // undo effects of Run(); some of this work is done also in IsRunning
  3521. // when we detect we are not running (in case the server crashed).
  3522. //--------------------------------------------------------------------------
  3523. INTERNAL CDefObject::Stop (void)
  3524. {
  3525. BOOL fLockedContainer;
  3526. VDATEHEAP();
  3527. LEDebugOut((DEB_ITRACE, "%p _IN CDefObject::CROImpl::Stop "
  3528. "( )\n", this));
  3529. CRefStabilize stabilize(this);
  3530. if( !IsRunning() )
  3531. {
  3532. // NOTE: ISRUNNING below does some of this cleanup
  3533. goto errRtn; // return NOERROR
  3534. }
  3535. // NOTE: we cleanup connections which point directly back to us;
  3536. // connections which point back to the app (e.g, the clientsite and
  3537. // data advise) are left alone; an app must know how to use
  3538. // CoDisconnectObject if deterministic shutdown is desired.
  3539. if( m_dwConnOle != 0L && GetOleDelegate() )
  3540. {
  3541. m_pOleDelegate->Unadvise(m_dwConnOle);
  3542. m_dwConnOle = 0L;
  3543. }
  3544. if( m_pDataDelegate )
  3545. {
  3546. m_pDataAdvCache->EnumAndAdvise(m_pDataDelegate, FALSE);
  3547. }
  3548. // inform cache that we are not running (Undoes advise)
  3549. Assert(m_pCOleCache != NULL);
  3550. m_pCOleCache->OnStop();
  3551. #ifdef SERVER_HANDLER
  3552. if (m_pEmbSrvHndlrWrapper)
  3553. {
  3554. CEmbServerWrapper *pSrvHndlr = m_pEmbSrvHndlrWrapper;
  3555. m_pEmbSrvHndlrWrapper = NULL;
  3556. m_pRunClientSite = NULL;
  3557. // need to release any interfaces the Handler Wraps
  3558. if(m_pDataDelegate)
  3559. {
  3560. m_pUnkOuter->AddRef();
  3561. SafeReleaseAndNULL((IUnknown **)&m_pDataDelegate);
  3562. }
  3563. // NULL out m_pSrvHndl before Release since out call could case re-entrance.
  3564. pSrvHndlr->m_Unknown.Release();
  3565. }
  3566. #endif // SERVER_HANDLER
  3567. #if DBG==1
  3568. // In debug builds, set DH_WILLUNLOCK flag
  3569. m_flags |= DH_WILLUNLOCK;
  3570. #endif
  3571. // Reset DH_FORCED_RUNNING flag and disconnect proxy manager
  3572. m_flags &= ~DH_FORCED_RUNNING;
  3573. if(m_pProxyMgr)
  3574. m_pProxyMgr->Disconnect();
  3575. // Unlock the container site
  3576. fLockedContainer = (m_flags & DH_LOCKED_CONTAINER);
  3577. if(fLockedContainer) {
  3578. m_flags &= ~DH_LOCKED_CONTAINER;
  3579. DuLockContainer(m_pAppClientSite, FALSE, &fLockedContainer);
  3580. }
  3581. Win4Assert(!fLockedContainer);
  3582. #if DBG==1
  3583. // In debug builds, reset the DH_LOCKFAILED and DH_WILLUNLOCK flags
  3584. m_flags &= ~DH_LOCKFAILED;
  3585. m_flags &= ~DH_WILLUNLOCK;
  3586. #endif
  3587. errRtn:
  3588. LEDebugOut((DEB_ITRACE, "%p OUT CDefObject::Stop "
  3589. "( %lx )\n", this, NOERROR ));
  3590. return NOERROR;
  3591. }
  3592. //+-------------------------------------------------------------------------
  3593. //
  3594. // Member: CDefObject::IsRunning
  3595. //
  3596. // Arguments: None
  3597. //
  3598. // Returns: BOOL
  3599. //
  3600. // Derivation: IRunnableObject
  3601. //
  3602. // Notes: Detects if the local server has crashed and does cleanup
  3603. // so that the user can activate the embedding in the same
  3604. // session.
  3605. //
  3606. // History: dd-mmm-yy Author Comment
  3607. // 06-Dec-96 Gopalk Rewritten
  3608. //--------------------------------------------------------------------------
  3609. STDMETHODIMP_(BOOL) CDefObject::IsRunning(void)
  3610. {
  3611. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::IsRunning()\n", this));
  3612. // Validation checks
  3613. VDATEHEAP();
  3614. VDATETHREAD(this);
  3615. // Local variable
  3616. BOOL fReturn = FALSE;
  3617. HRESULT hStatus;
  3618. CRefStabilize stabilize(this);
  3619. // Check if the inner object has been created
  3620. if(m_pUnkDelegate) {
  3621. // DEFHANDLER either has proxy manager as the inner object
  3622. // for out of proc server objects or actual server as the
  3623. // inner object for inproc server objects.
  3624. // Assert that this is TRUE
  3625. Win4Assert((m_pProxyMgr != NULL) == !!(m_flags & DH_INPROC_HANDLER));
  3626. if(m_pProxyMgr) {
  3627. // Out of proc server object.
  3628. // Check with the proxy manager whether it is connected to the
  3629. // server object. We cannot rely on the DH_FORCED_RUNNING flag
  3630. // to indicate run status because the DEFHANDLER could have been
  3631. // marshaled from the embedding conatiner and unmarshaled in the
  3632. // link container. The DEFHANDLER created by unmarshaling in the
  3633. // link container is always in the running state due to the
  3634. // requirement that IOleItemContainer::GetObject is required to
  3635. // put the embedding in running state when its bind speed
  3636. // parameter permits, else it is supposed to return
  3637. // MK_E_EXCEEDEDDEADLINE. Further, CoMarshalInterface fails
  3638. // if the the proxy manager is not connected
  3639. fReturn = m_pProxyMgr->IsConnected();
  3640. if(fReturn) {
  3641. // The proxymanager is connected to the server object
  3642. // Check the status of connection with the server object
  3643. hStatus = m_pProxyMgr->GetConnectionStatus();
  3644. if(hStatus != S_OK) {
  3645. // Either Server object called CoDisconnectObject or
  3646. // its apartment crashed or unitialized breaking the
  3647. // external connection to the objects in that apartment
  3648. // Clean up the state
  3649. Win4Assert(!"Local Server crashed or disconnected");
  3650. // Reset flags
  3651. m_flags &= ~DH_FORCED_RUNNING;
  3652. // Reset advise connection and recover the references
  3653. // placed by the server on the handler advise sink
  3654. m_dwConnOle = 0L;
  3655. CoDisconnectObject((IUnknown *) &m_AdviseSink, 0);
  3656. // Inform cache that the local server crashed
  3657. if(m_pCOleCache)
  3658. m_pCOleCache->OnCrash();
  3659. // Inform and cleanup data advice cache
  3660. m_pDataAdvCache->EnumAndAdvise(NULL, FALSE);
  3661. // Unlock the container if it is was locked
  3662. BOOL fCurLock = !!(m_flags & DH_LOCKED_CONTAINER);
  3663. if(fCurLock) {
  3664. DuLockContainer(m_pAppClientSite, FALSE, &fCurLock);
  3665. m_flags &= ~DH_LOCKED_CONTAINER;
  3666. }
  3667. Win4Assert(!fCurLock);
  3668. #if DBG==1
  3669. // In debug builds, reset DH_LOCKFAILED flag
  3670. m_flags &= ~DH_LOCKFAILED;
  3671. #endif
  3672. // Inform ProxyManager to disconnect
  3673. m_pProxyMgr->Disconnect();
  3674. // Reset fReturn
  3675. fReturn = FALSE;
  3676. }
  3677. }
  3678. }
  3679. else {
  3680. // Inproc server object.
  3681. // COM supports self embedding by allowing separate class
  3682. // objects to be registered for instatiating INPROC_SERVER
  3683. // and LOCAL_SERVER objects. Apps typically ask the Default
  3684. // handler to aggregate their INPROC_SERVER objects by
  3685. // using OleCreateEmbeddingHelper api so that embedding
  3686. // interfaces like IViewObject are supported. But this
  3687. // creates problem for self linking because link moniker
  3688. // binds to inproc servers in preference to local servers.
  3689. // As the inproc server object obtained from the INPROC_SERVER
  3690. // class factory is the default handler, it will not delegate
  3691. // method calls to the actual server object unless it thinks that
  3692. // the local object is running. Below we check if we are dealing
  3693. // with an embedded object using the assumption that embedded objects
  3694. // are initialized through IStorage. The above assumption is
  3695. // questionable but we are helpless.
  3696. if (!(m_flags & DH_EMBEDDING) || (m_flags & DH_FORCED_RUNNING))
  3697. fReturn = TRUE;
  3698. }
  3699. }
  3700. else
  3701. Win4Assert((m_flags & DH_DELAY_CREATE) && m_pCFDelegate != NULL);
  3702. // Sanity checks
  3703. if(fReturn) {
  3704. if(m_flags & DH_FORCED_RUNNING) {
  3705. Win4Assert((m_flags & DH_LOCKED_CONTAINER) || (m_flags & DH_LOCKFAILED));
  3706. Win4Assert(!(m_flags & DH_UNMARSHALED));
  3707. }
  3708. else if(m_pProxyMgr) {
  3709. Win4Assert(!m_pAppClientSite);
  3710. Win4Assert(!m_pStg);
  3711. Win4Assert(!(m_flags & DH_LOCKED_CONTAINER));
  3712. Win4Assert(!(m_flags & DH_LOCKFAILED));
  3713. Win4Assert(m_flags & DH_UNMARSHALED);
  3714. Win4Assert(!(m_flags & DH_EMBEDDING));
  3715. }
  3716. }
  3717. else {
  3718. if(!(m_flags & DH_OLE1SERVER)) {
  3719. // DDE IProxyManager::IsConnected returns FLASE until
  3720. // either IPersistStorage::Load or IPersistStorage::InitNew
  3721. // is called on it
  3722. Win4Assert(!(m_flags & DH_FORCED_RUNNING));
  3723. Win4Assert((m_flags & DH_WILLUNLOCK) || !(m_flags & DH_LOCKED_CONTAINER));
  3724. Win4Assert((m_flags & DH_WILLUNLOCK) || !(m_flags & DH_LOCKFAILED));
  3725. }
  3726. }
  3727. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::IsRunning(%lu)\n", this, fReturn));
  3728. return fReturn;
  3729. }
  3730. //+-------------------------------------------------------------------------
  3731. //
  3732. // Member: CDefObject::SetContainedObject
  3733. //
  3734. // Synopsis: sets the embedding status of an object
  3735. //
  3736. // Effects:
  3737. //
  3738. // Arguments: [fContained] -- TRUE indicates we are an embedding/
  3739. // FALSE otherwise
  3740. //
  3741. // Requires:
  3742. //
  3743. // Returns: HRESULT
  3744. //
  3745. // Signals:
  3746. //
  3747. // Modifies:
  3748. //
  3749. // Derivation: IRunnableObject
  3750. //
  3751. // Algorithm: Sets flags, if we are an improc handler, we will call
  3752. // IRunnableObject->LockRunning(FALSE) to unlock ourselves
  3753. //
  3754. // History: dd-mmm-yy Author Comment
  3755. // 08-Nov-93 alexgo 32bit port
  3756. //
  3757. // Notes:
  3758. // note that this is a contained object; this unlocks
  3759. // connection to the server
  3760. //
  3761. //--------------------------------------------------------------------------
  3762. STDMETHODIMP CDefObject::SetContainedObject(BOOL fContained)
  3763. {
  3764. VDATEHEAP();
  3765. VDATETHREAD(this);
  3766. HRESULT hresult = NOERROR;
  3767. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SetContainedObject "
  3768. "( %lu )\n", this, fContained));
  3769. CRefStabilize stabilize(this);
  3770. if( !!(m_flags & DH_CONTAINED_OBJECT) != !!fContained)
  3771. {
  3772. // not contained in the same way as desired;
  3773. // for inproc handler, [un]lock connection
  3774. // for inproc server, just remember flag
  3775. if( (m_flags & DH_INPROC_HANDLER) )
  3776. {
  3777. hresult = LockRunning(!fContained, FALSE);
  3778. }
  3779. if (hresult == NOERROR)
  3780. {
  3781. // the !! ensure exactly 0 or 1 will be stored in
  3782. // m_fContainedObject
  3783. if( fContained )
  3784. {
  3785. m_flags |= DH_CONTAINED_OBJECT;
  3786. }
  3787. else
  3788. {
  3789. m_flags &= ~DH_CONTAINED_OBJECT;
  3790. }
  3791. }
  3792. }
  3793. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SetContainedObject "
  3794. "( %lx )\n", this, hresult));
  3795. return hresult;
  3796. }
  3797. //+-------------------------------------------------------------------------
  3798. //
  3799. // Member: CDefObject::LockRunning
  3800. //
  3801. // Synopsis: Locks or unlocks the object
  3802. //
  3803. // Effects:
  3804. //
  3805. // Arguments: [fLock] -- TRUE, then lock, unlock if FALSE
  3806. // [fLastUnlockCloses] -- shut down if unlocking the last
  3807. // lock
  3808. //
  3809. // Requires:
  3810. //
  3811. // Returns: HRESULT
  3812. //
  3813. // Signals:
  3814. //
  3815. // Modifies:
  3816. //
  3817. // Derivation: IRunnableObject
  3818. //
  3819. // Algorithm: If we are an improc server, call CoLockObjectExternal,
  3820. // otherwise have the proxy manager lock us down.
  3821. //
  3822. // History: dd-mmm-yy Author Comment
  3823. // 08-Nov-93 alexgo 32bit port
  3824. //
  3825. // Notes:
  3826. //
  3827. //--------------------------------------------------------------------------
  3828. STDMETHODIMP CDefObject::LockRunning(BOOL fLock, BOOL fLastUnlockCloses)
  3829. {
  3830. VDATEHEAP();
  3831. VDATETHREAD(this);
  3832. HRESULT hresult;
  3833. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::LockRunning "
  3834. "( %lu , %lu )\n", this, fLock, fLastUnlockCloses ));
  3835. CRefStabilize stabilize(this);
  3836. // else map to lock connection
  3837. if( !(m_flags & DH_INPROC_HANDLER) )
  3838. {
  3839. // inproc server: use CoLockObjExternal; will close down
  3840. // if invisible via new IExternalConnection interface.
  3841. Assert(m_pProxyMgr == NULL);
  3842. hresult = CoLockObjectExternal((IUnknown *)(IOleObject *)this, fLock,
  3843. fLastUnlockCloses); }
  3844. else if( m_pUnkDelegate == NULL )
  3845. {
  3846. // NOTE: this really shouldn't happen at present
  3847. // since we currently disallow delay create with
  3848. // inproc handler. In fact, the LockConnection below
  3849. // is one of the reasons why we must have the
  3850. // proxymgr upfront. In the future we could force
  3851. // the creation of the delegate here.
  3852. Assert( (m_flags & DH_DELAY_CREATE) && m_pCFDelegate != NULL);
  3853. hresult = NOERROR;
  3854. }
  3855. else
  3856. {
  3857. Assert(m_pProxyMgr != NULL);
  3858. hresult = m_pProxyMgr->LockConnection(fLock, fLastUnlockCloses);
  3859. }
  3860. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::LockRunning "
  3861. "( %lx )\n", this, hresult));
  3862. return hresult;
  3863. }
  3864. /*
  3865. * IMPLEMENTATION of CECImpl methods
  3866. *
  3867. */
  3868. //+-------------------------------------------------------------------------
  3869. //
  3870. // Member: CDefObject::AddConnection
  3871. //
  3872. // Synopsis: Adds an external connection
  3873. //
  3874. // Effects:
  3875. //
  3876. // Arguments: [extconn] -- the type of connection (such as
  3877. // EXTCONN_STRONG)
  3878. // [reserved] -- unused
  3879. //
  3880. // Requires:
  3881. //
  3882. // Returns: DWORD -- the number of strong connections
  3883. //
  3884. // Signals:
  3885. //
  3886. // Modifies:
  3887. //
  3888. // Derivation: IExternalConnection
  3889. //
  3890. // Algorithm: keeps track of strong connections
  3891. //
  3892. // History: dd-mmm-yy Author Comment
  3893. // 08-Nov-93 alexgo 32bit port
  3894. //
  3895. // Notes:
  3896. //
  3897. //--------------------------------------------------------------------------
  3898. STDMETHODIMP_(DWORD) CDefObject::AddConnection(DWORD extconn, DWORD reserved)
  3899. {
  3900. VDATEHEAP();
  3901. //
  3902. // VDATETHREAD contains a 'return HRESULT' but this procedure expects to
  3903. // return a DWORD. Avoid the warning.
  3904. #if ( _MSC_VER >= 800 )
  3905. #pragma warning( disable : 4245 )
  3906. #endif
  3907. VDATETHREAD(this);
  3908. #if ( _MSC_VER >= 800 )
  3909. #pragma warning( default : 4245 )
  3910. #endif
  3911. DWORD dwConn;
  3912. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::AddConnection "
  3913. "( %lu , %lu )\n", this, extconn, reserved));
  3914. Assert( !(m_flags & DH_INPROC_HANDLER) );
  3915. dwConn = extconn&EXTCONN_STRONG ? ++m_cConnections : 0;
  3916. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::AddConnection "
  3917. "( %lu )\n", this, dwConn));
  3918. return dwConn;
  3919. }
  3920. //+-------------------------------------------------------------------------
  3921. //
  3922. // Member: CDefObject::ReleaseConnection
  3923. //
  3924. // Synopsis: Releases external connection, potentially calling IOO->Close
  3925. //
  3926. // Effects:
  3927. //
  3928. // Arguments: [extconn] -- the type of connection
  3929. // [reserved] -- unused
  3930. // [fLastReleaseCloses] -- call IOO->Close if its the last
  3931. // release
  3932. //
  3933. // Requires:
  3934. //
  3935. // Returns:
  3936. //
  3937. // Signals:
  3938. //
  3939. // Modifies:
  3940. //
  3941. // Derivation:
  3942. //
  3943. // Algorithm:
  3944. //
  3945. // History: dd-mmm-yy Author Comment
  3946. // 08-Nov-93 alexgo 32bit port
  3947. //
  3948. // Notes:
  3949. //
  3950. //--------------------------------------------------------------------------
  3951. STDMETHODIMP_(DWORD) CDefObject::ReleaseConnection(DWORD extconn,
  3952. DWORD reserved, BOOL fLastReleaseCloses)
  3953. {
  3954. VDATEHEAP();
  3955. //
  3956. // VDATETHREAD contains a 'return HRESULT' but this procedure expects to
  3957. // return a DWORD. Avoid the warning.
  3958. #if ( _MSC_VER >= 800 )
  3959. #pragma warning( disable : 4245 )
  3960. #endif
  3961. VDATETHREAD(this);
  3962. #if ( _MSC_VER >= 800 )
  3963. #pragma warning( default : 4245 )
  3964. #endif
  3965. DWORD dwConn;
  3966. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::ReleaseConnection "
  3967. "( %lu , %lu , %lu )\n", this, extconn, reserved,
  3968. fLastReleaseCloses));
  3969. CRefStabilize stabilize(this);
  3970. // must be an embedding helper
  3971. Assert( !(m_flags & DH_INPROC_HANDLER) );
  3972. if( (extconn & EXTCONN_STRONG) && --m_cConnections == 0 &&
  3973. fLastReleaseCloses)
  3974. {
  3975. // REVIEW: might want this to be close save if dirty.
  3976. Close(OLECLOSE_NOSAVE);
  3977. }
  3978. dwConn = (extconn & EXTCONN_STRONG) ? m_cConnections : 0;
  3979. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::ReleaseConnection "
  3980. "( %lu )\n", this, dwConn));
  3981. return dwConn;
  3982. }
  3983. /*
  3984. *
  3985. * IMPLEMENTATION of CAdvSinkImpl methods
  3986. *
  3987. */
  3988. //
  3989. // NOTE: Advise Sink is a nested object of Default Handler that is exported
  3990. // for achieving some of its functionality. This introduces some lifetime
  3991. // complications. Can its lifetime be controlled by the server object to
  3992. // which it exported its Advise Sink? Ideally, only its client should
  3993. // control its lifetime alone, but it should also honor the ref counts
  3994. // placed on it by the server object by entering into a zombie state
  3995. // to prevent AV's on the incoming calls to the Advise Sink. All needed
  3996. // logic is coded into the new class "CRefExportCount" which manages
  3997. // the ref and export counts in a thread safe manner and invokes
  3998. // appropriate methods during the object's lifetime. Any server objects
  3999. // that export nested objects to other server objects should derive from
  4000. // "CRefExportCount" class and call its methods to manage their lifetime
  4001. // as exemplified in this Default Handler implementation.
  4002. //
  4003. // Gopalk Jan 10, 97
  4004. //
  4005. //+-------------------------------------------------------------------------
  4006. //
  4007. // Member: CDefObject::CAdvSinkImpl::QueryInterface
  4008. //
  4009. // Synopsis: Only supports IUnknown and IAdviseSink
  4010. //
  4011. // Arguments: [iid] -- Interface requested
  4012. // [ppvObj] -- pointer to hold returned interface
  4013. //
  4014. // Returns: HRESULT
  4015. //
  4016. // History: dd-mmm-yy Author Comment
  4017. // 10-Jan-96 Gopalk Rewritten
  4018. //--------------------------------------------------------------------------
  4019. STDMETHODIMP CDefObject::CAdvSinkImpl::QueryInterface(REFIID iid, void **ppv)
  4020. {
  4021. LEDebugOut((DEB_TRACE,"%p _IN CDefObject::CAdvSinkImpl::QueryInterface()\n",
  4022. this));
  4023. // Validation check
  4024. VDATEHEAP();
  4025. // Local variables
  4026. HRESULT hresult = NOERROR;
  4027. if(IsValidPtrOut(ppv, sizeof(void *))) {
  4028. if(IsEqualIID(iid, IID_IUnknown)) {
  4029. *ppv = (void *)(IUnknown *) this;
  4030. }
  4031. else if(IsEqualIID(iid, IID_IAdviseSink)) {
  4032. *ppv = (void *)(IAdviseSink *) this;
  4033. }
  4034. else {
  4035. *ppv = NULL;
  4036. hresult = E_NOINTERFACE;
  4037. }
  4038. }
  4039. else
  4040. hresult = E_INVALIDARG;
  4041. if(hresult == NOERROR)
  4042. ((IUnknown *) *ppv)->AddRef();
  4043. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::QueryInterface(%lx)\n",
  4044. this, hresult));
  4045. return hresult;
  4046. }
  4047. //+-------------------------------------------------------------------------
  4048. //
  4049. // Member: CDefObject::CAdvSinkImpl::AddRef
  4050. //
  4051. // Synopsis: Increments export count
  4052. //
  4053. // Returns: ULONG; New export count
  4054. //
  4055. // History: dd-mmm-yy Author Comment
  4056. // 10-Jan-96 Gopalk Rewritten
  4057. //--------------------------------------------------------------------------
  4058. STDMETHODIMP_(ULONG) CDefObject::CAdvSinkImpl::AddRef( void )
  4059. {
  4060. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::AddRef()\n",
  4061. this));
  4062. // Validation check
  4063. VDATEHEAP();
  4064. // Local variables
  4065. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4066. ULONG cExportCount;
  4067. // Increment export count
  4068. cExportCount = pDefObject->IncrementExportCount();
  4069. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::AddRef(%ld)\n",
  4070. this, cExportCount));
  4071. return cExportCount;
  4072. }
  4073. //+-------------------------------------------------------------------------
  4074. //
  4075. // Member: CDefObject::CAdvSinkImpl::Release
  4076. //
  4077. // Synopsis: Decerement export count and potentially destroy the object
  4078. //
  4079. // Returns: ULONG; New export count
  4080. //
  4081. // History: dd-mmm-yy Author Comment
  4082. // 10-Jan-96 Gopalk Rewritten
  4083. //--------------------------------------------------------------------------
  4084. STDMETHODIMP_(ULONG) CDefObject::CAdvSinkImpl::Release ( void )
  4085. {
  4086. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::Release()\n",
  4087. this));
  4088. // Validation check
  4089. VDATEHEAP();
  4090. // Local variables
  4091. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4092. ULONG cExportCount;
  4093. // Decrement export count.
  4094. cExportCount = pDefObject->DecrementExportCount();
  4095. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::Release(%ld)\n",
  4096. this, cExportCount));
  4097. return cExportCount;
  4098. }
  4099. //+-------------------------------------------------------------------------
  4100. //
  4101. // Member: CDefObject::CAdvSinkImpl::OnDataChange
  4102. //
  4103. // Synopsis: Function to notify on data change
  4104. //
  4105. // Effects: Never called
  4106. //
  4107. // Arguments: [pFormatetc] -- format of the data
  4108. // [pStgmed] -- data medium
  4109. //
  4110. // Requires:
  4111. //
  4112. // Returns: void
  4113. //
  4114. // Signals:
  4115. //
  4116. // Modifies:
  4117. //
  4118. // Derivation: IAdviseSink
  4119. //
  4120. // Algorithm:
  4121. //
  4122. // History: dd-mmm-yy Author Comment
  4123. // 08-Nov-93 alexgo 32bit port
  4124. //
  4125. // Notes:
  4126. //
  4127. //--------------------------------------------------------------------------
  4128. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnDataChange(
  4129. FORMATETC *pFormatetc, STGMEDIUM *pStgmed)
  4130. {
  4131. VDATEHEAP();
  4132. VOID_VDATEPTRIN( pFormatetc, FORMATETC );
  4133. VOID_VDATEPTRIN( pStgmed, STGMEDIUM );
  4134. Assert(FALSE); // never received
  4135. }
  4136. //+-------------------------------------------------------------------------
  4137. //
  4138. // Member: CDefObject::CAdvSinkImpl::OnViewChange
  4139. //
  4140. // Synopsis: notification of view changes
  4141. //
  4142. // Effects: never called
  4143. //
  4144. // Arguments: [aspects]
  4145. // [lindex]
  4146. //
  4147. // Requires:
  4148. //
  4149. // Returns: void
  4150. //
  4151. // Signals:
  4152. //
  4153. // Modifies:
  4154. //
  4155. // Derivation: IAdviseSink
  4156. //
  4157. // Algorithm:
  4158. //
  4159. // History: dd-mmm-yy Author Comment
  4160. // 08-Nov-93 alexgo 32bit port
  4161. // Notes:
  4162. //
  4163. //--------------------------------------------------------------------------
  4164. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnViewChange
  4165. (DWORD aspects, LONG lindex)
  4166. {
  4167. VDATEHEAP();
  4168. Assert(FALSE); // never received
  4169. }
  4170. //+-------------------------------------------------------------------------
  4171. //
  4172. // Member: CDefObject::CAdvSinkImpl::OnRename
  4173. //
  4174. // Synopsis: Notification of name change. Turns around and informs its
  4175. // advise sinks
  4176. //
  4177. // Arguments: [pmk] -- New name (moniker)
  4178. //
  4179. // History: dd-mmm-yy Author Comment
  4180. // 10-Jan-96 Gopalk Rewritten
  4181. //--------------------------------------------------------------------------
  4182. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnRename(IMoniker *pmk)
  4183. {
  4184. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::OnRename(%p)\n",
  4185. this, pmk));
  4186. // Validation check
  4187. VDATEHEAP();
  4188. // Local variable
  4189. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4190. if(IsValidInterface(pmk)) {
  4191. if(!pDefObject->IsZombie()) {
  4192. // Stabilize
  4193. CRefStabilize stabilize(pDefObject);
  4194. if(pDefObject->m_pOAHolder != NULL)
  4195. pDefObject->m_pOAHolder->SendOnRename(pmk);
  4196. }
  4197. else
  4198. LEDebugOut((DEB_WARN, "OnRename() method invoked on zombied "
  4199. "Default Handler"));
  4200. }
  4201. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::OnRename()\n",
  4202. this));
  4203. }
  4204. //+-------------------------------------------------------------------------
  4205. //
  4206. // Member: CDefObject::CAdvSinkImpl::OnSave
  4207. //
  4208. // Synopsis: Notification of save. Turns around and informs its
  4209. // advise sinks
  4210. //
  4211. // Arguments: None
  4212. //
  4213. // History: dd-mmm-yy Author Comment
  4214. // 10-Jan-96 Gopalk Rewritten
  4215. //--------------------------------------------------------------------------
  4216. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnSave(void)
  4217. {
  4218. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::OnSave()\n",
  4219. this));
  4220. // Validation check
  4221. VDATEHEAP();
  4222. // Local variable
  4223. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4224. if(!pDefObject->IsZombie()) {
  4225. // Stabilize
  4226. CRefStabilize stabilize(pDefObject);
  4227. if(pDefObject->m_pOAHolder != NULL)
  4228. pDefObject->m_pOAHolder->SendOnSave();
  4229. }
  4230. else
  4231. LEDebugOut((DEB_WARN,"OnSave() method invoked on zombied Default Handler"));
  4232. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::OnSave()\n",
  4233. this));
  4234. }
  4235. //+-------------------------------------------------------------------------
  4236. //
  4237. // Member: CDefObject::CAdvSinkImpl::OnClose
  4238. //
  4239. // Synopsis: notification of the object close. Turns around and informs its
  4240. // advise sinks
  4241. //
  4242. // Arguments: None
  4243. //
  4244. // History: dd-mmm-yy Author Comment
  4245. // 10-Jan-96 Gopalk Rewritten
  4246. //--------------------------------------------------------------------------
  4247. STDMETHODIMP_(void) CDefObject::CAdvSinkImpl::OnClose( void )
  4248. {
  4249. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::CAdvSinkImpl::OnClose()\n",
  4250. this));
  4251. // Validation check
  4252. VDATEHEAP();
  4253. // Local variables
  4254. CDefObject *pDefObject = GETPPARENT(this, CDefObject, m_AdviseSink);
  4255. if(!pDefObject->IsZombie()) {
  4256. // Stabilize
  4257. CRefStabilize stabilize(pDefObject);
  4258. // Check if container has registered any of its own advise sinks
  4259. if(pDefObject->m_pOAHolder) {
  4260. // Inform the container advise sinks. Note that this can result
  4261. // in additional outgoing calls and consequently, OnClose()
  4262. // method is designed to be not asyncronous
  4263. pDefObject->m_pOAHolder->SendOnClose();
  4264. }
  4265. // Do not rely on container calling close. Stop the running server
  4266. pDefObject->Stop();
  4267. }
  4268. else
  4269. LEDebugOut((DEB_WARN,"OnClose() method invoked on zombied Default Handler"));
  4270. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::CAdvSinkImpl::OnClose()\n",
  4271. pDefObject));
  4272. return;
  4273. }
  4274. /*
  4275. * IMPLEMENTATION of CPersistStgImpl methods
  4276. *
  4277. */
  4278. //+-------------------------------------------------------------------------
  4279. //
  4280. // Member: CDefObject::GetPSDelegate
  4281. //
  4282. // Synopsis: retrieves the IPersistStorage interface from the delegate
  4283. //
  4284. // Effects:
  4285. //
  4286. // Arguments: void
  4287. //
  4288. // Requires:
  4289. //
  4290. // Returns: IPersistStorage *
  4291. //
  4292. // Signals:
  4293. //
  4294. // Modifies:
  4295. //
  4296. // Derivation:
  4297. //
  4298. // Algorithm:
  4299. //
  4300. // History: dd-mmm-yy Author Comment
  4301. // 08-Nov-93 alexgo 32bit port
  4302. //
  4303. // Notes:
  4304. //
  4305. //--------------------------------------------------------------------------
  4306. INTERNAL_(IPersistStorage *) CDefObject::GetPSDelegate(void)
  4307. {
  4308. VDATEHEAP();
  4309. if( IsZombie() )
  4310. {
  4311. return NULL;
  4312. }
  4313. return (IPersistStorage FAR*)DuCacheDelegate(
  4314. &m_pUnkDelegate,
  4315. IID_IPersistStorage,
  4316. (LPLPVOID) &m_pPSDelegate,
  4317. m_pUnkOuter);
  4318. }
  4319. //+-------------------------------------------------------------------------
  4320. //
  4321. // Member: CDefObject::GetClassID
  4322. //
  4323. // Synopsis: Retrieves the class ID of the object
  4324. //
  4325. // Effects:
  4326. //
  4327. // Arguments: [pClassID] -- where to put the class ID
  4328. //
  4329. // Requires:
  4330. //
  4331. // Returns: HRESULT
  4332. //
  4333. // Signals:
  4334. //
  4335. // Modifies:
  4336. //
  4337. // Derivation: IPersistStorage
  4338. //
  4339. // Algorithm:
  4340. //
  4341. // History: dd-mmm-yy Author Comment
  4342. // 08-Nov-93 alexgo 32bit port
  4343. //
  4344. // Notes:
  4345. //
  4346. //--------------------------------------------------------------------------
  4347. STDMETHODIMP CDefObject::GetClassID (CLSID *pClassID)
  4348. {
  4349. VDATEHEAP();
  4350. VDATETHREAD(this);
  4351. HRESULT hresult;
  4352. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::GetClassID "
  4353. "( %p )\n", this, pClassID));
  4354. VDATEPTROUT(pClassID, CLSID );
  4355. hresult = GetClassBits(pClassID);
  4356. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::GetClassID "
  4357. "( %lx ) [ %p ]\n", this, hresult, pClassID));
  4358. return hresult;
  4359. }
  4360. //+-------------------------------------------------------------------------
  4361. //
  4362. // Member: CDefObject::IsDirty
  4363. //
  4364. // Synopsis: Returns whether or not the object needs to be saved
  4365. //
  4366. // Effects:
  4367. //
  4368. // Arguments: void
  4369. //
  4370. // Requires:
  4371. //
  4372. // Returns: HRESULT -- NOERROR means the object *is* dirty
  4373. //
  4374. // Signals:
  4375. //
  4376. // Modifies:
  4377. //
  4378. // Derivation: IPersistStorage
  4379. //
  4380. // Algorithm: if the server is running, delegate. If the server is
  4381. // clean (or not present), ask the cache
  4382. //
  4383. // History: dd-mmm-yy Author Comment
  4384. // 08-Nov-93 alexgo 32bit port
  4385. //
  4386. // Notes:
  4387. //
  4388. //--------------------------------------------------------------------------
  4389. STDMETHODIMP CDefObject::IsDirty( void )
  4390. {
  4391. VDATEHEAP();
  4392. VDATETHREAD(this);
  4393. HRESULT hresult = S_FALSE;
  4394. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::IsDirty ( )\n", this));
  4395. CRefStabilize stabilize(this);
  4396. // if server is running, it holds definitive dirty flag
  4397. if( IsRunning() && GetPSDelegate() )
  4398. {
  4399. if ( FAILED(hresult = m_pPSDelegate->IsDirty()) )
  4400. {
  4401. goto errRtn;
  4402. }
  4403. }
  4404. if (hresult == S_FALSE) {
  4405. Assert(m_pCOleCache != NULL);
  4406. hresult = m_pCOleCache->IsDirty();
  4407. }
  4408. errRtn:
  4409. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::IsDirty "
  4410. "( %lx )\n", this, hresult));
  4411. return hresult;
  4412. }
  4413. //+-------------------------------------------------------------------------
  4414. //
  4415. // Member: CDefObject::InitNew
  4416. //
  4417. // Synopsis: Create a new object with the given storage
  4418. //
  4419. // Effects:
  4420. //
  4421. // Arguments: [pstg] -- the storage for the new object
  4422. //
  4423. // Requires:
  4424. //
  4425. // Returns: HRESULT
  4426. //
  4427. // Signals:
  4428. //
  4429. // Modifies:
  4430. //
  4431. // Derivation: IPersistStorage
  4432. //
  4433. // Algorithm: Delegates to the server and to the cache. Writes
  4434. // Ole private data to the storage.
  4435. //
  4436. // History: dd-mmm-yy Author Comment
  4437. // 08-Nov-93 alexgo 32bit port
  4438. //
  4439. // Notes:
  4440. //
  4441. //--------------------------------------------------------------------------
  4442. STDMETHODIMP CDefObject::InitNew( IStorage *pstg )
  4443. {
  4444. VDATEHEAP();
  4445. VDATETHREAD(this);
  4446. VDATEIFACE( pstg );
  4447. HRESULT hresult;
  4448. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::InitNew ( %p )\n",
  4449. this, pstg));
  4450. CRefStabilize stabilize(this);
  4451. if( m_pStg )
  4452. {
  4453. hresult = CO_E_ALREADYINITIALIZED;
  4454. goto errRtn;
  4455. }
  4456. m_flags |= DH_EMBEDDING;
  4457. if( IsRunning() && GetPSDelegate()
  4458. && (hresult = m_pPSDelegate->InitNew(pstg)) != NOERROR)
  4459. {
  4460. goto errRtn;
  4461. }
  4462. m_flags |= DH_INIT_NEW;
  4463. // if we're in a zombie state, don't change the storage!
  4464. if( IsZombie() )
  4465. {
  4466. hresult = CO_E_RELEASED;
  4467. goto errRtn;
  4468. }
  4469. Assert(m_pCOleCache != NULL);
  4470. if ((hresult = m_pCOleCache->InitNew(pstg)) != NOERROR)
  4471. {
  4472. goto errRtn;
  4473. }
  4474. // remember the storage pointer
  4475. (m_pStg = pstg)->AddRef();
  4476. // go ahead and write the Ole stream now
  4477. WriteOleStg(pstg, (IOleObject *)this, NULL, NULL);
  4478. errRtn:
  4479. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::InitNew "
  4480. "( %lx )\n", this, hresult));
  4481. return hresult;
  4482. }
  4483. //+-------------------------------------------------------------------------
  4484. //
  4485. // Member: CDefObject::Load
  4486. //
  4487. // Synopsis: Loads object data from the given storage
  4488. //
  4489. // Effects:
  4490. //
  4491. // Arguments: [pstg] -- the storage for the object's data
  4492. //
  4493. // Requires:
  4494. //
  4495. // Returns: HRESULT
  4496. //
  4497. // Signals:
  4498. //
  4499. // Modifies:
  4500. //
  4501. // Derivation: IPeristStorage
  4502. //
  4503. // Algorithm: Reads ole-private data (or creates if not there), delegates
  4504. // to the server and the cache.
  4505. //
  4506. // History: dd-mmm-yy Author Comment
  4507. // 08-Nov-93 alexgo 32bit port
  4508. //
  4509. // Notes:
  4510. //
  4511. //--------------------------------------------------------------------------
  4512. STDMETHODIMP CDefObject::Load (IStorage *pstg)
  4513. {
  4514. VDATEHEAP();
  4515. VDATETHREAD(this);
  4516. HRESULT hresult;
  4517. DWORD dwOptUpdate;
  4518. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Load ( %p )\n",
  4519. this, pstg));
  4520. VDATEIFACE( pstg );
  4521. CRefStabilize stabilize(this);
  4522. if( m_pStg )
  4523. {
  4524. hresult = CO_E_ALREADYINITIALIZED;
  4525. goto errRtn;
  4526. }
  4527. m_flags |= DH_EMBEDDING;
  4528. // NOTE: we can get the moniker from container, so no need to get
  4529. // it here
  4530. hresult = ReadOleStg (pstg, &m_dwObjFlags, &dwOptUpdate, NULL, NULL, NULL);
  4531. if (hresult == NOERROR)
  4532. {
  4533. if (m_dwObjFlags & OBJFLAGS_CONVERT)
  4534. {
  4535. if( DoConversionIfSpecialClass(pstg) != NOERROR )
  4536. {
  4537. hresult = OLE_E_CANTCONVERT;
  4538. goto errRtn;
  4539. }
  4540. }
  4541. Assert (dwOptUpdate == NULL);
  4542. }
  4543. else if (hresult == STG_E_FILENOTFOUND)
  4544. {
  4545. // it is OK if the Ole stream doesn't exist.
  4546. hresult = NOERROR;
  4547. // go ahead and write the Ole stream now
  4548. WriteOleStg(pstg, (IOleObject *)this, NULL, NULL);
  4549. }
  4550. else
  4551. {
  4552. goto errRtn;
  4553. }
  4554. // if running, tell server to load from pstg
  4555. if( IsRunning() && GetPSDelegate()
  4556. && (hresult = m_pPSDelegate->Load(pstg)) != NOERROR)
  4557. {
  4558. goto errRtn;
  4559. }
  4560. // if we're in a zombie state, don't addref' the storage!
  4561. if( IsZombie() )
  4562. {
  4563. hresult = CO_E_RELEASED;
  4564. goto errRtn;
  4565. }
  4566. // now load cache from pstg
  4567. Assert(m_pCOleCache != NULL);
  4568. if(m_dwObjFlags & OBJFLAGS_CACHEEMPTY) {
  4569. hresult = m_pCOleCache->Load(pstg, TRUE);
  4570. if(hresult != NOERROR)
  4571. goto errRtn;
  4572. }
  4573. else {
  4574. hresult = m_pCOleCache->Load(pstg);
  4575. if(hresult != NOERROR)
  4576. goto errRtn;
  4577. }
  4578. m_flags &= ~DH_INIT_NEW; // clear init new flag
  4579. // remember the storage pointer
  4580. (m_pStg = pstg)->AddRef();
  4581. errRtn:
  4582. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Load "
  4583. "( %lx )\n", this, hresult));
  4584. return hresult;
  4585. }
  4586. //+-------------------------------------------------------------------------
  4587. //
  4588. // Member: CDefObject::Save
  4589. //
  4590. // Synopsis: Saves the object to the given storage
  4591. //
  4592. // Effects:
  4593. //
  4594. // Arguments: [pstgSave] -- storage in which to save
  4595. // [fSameAsLoad] -- FALSE indicates a SaveAs operation
  4596. //
  4597. // Requires:
  4598. //
  4599. // Returns: HRESULT
  4600. //
  4601. // Signals:
  4602. //
  4603. // Modifies:
  4604. //
  4605. // Derivation: IPersistStorage
  4606. //
  4607. // Algorithm: Saves ole-private data, delegates to the server and then
  4608. // to the cache
  4609. //
  4610. // History: dd-mmm-yy Author Comment
  4611. // 08-Nov-93 alexgo 32bit port
  4612. //
  4613. // Notes:
  4614. //
  4615. //--------------------------------------------------------------------------
  4616. STDMETHODIMP CDefObject::Save( IStorage *pstgSave, BOOL fSameAsLoad)
  4617. {
  4618. VDATEHEAP();
  4619. VDATETHREAD(this);
  4620. HRESULT hresult = NOERROR;
  4621. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::Save "
  4622. "( %p , %lu )\n", this, pstgSave, fSameAsLoad ));
  4623. VDATEIFACE( pstgSave );
  4624. CRefStabilize stabilize(this);
  4625. Assert(m_pCOleCache != NULL);
  4626. if( IsRunning() && GetPSDelegate() )
  4627. {
  4628. DWORD grfUpdf = UPDFCACHE_IFBLANK;
  4629. DWORD ObjFlags = 0;
  4630. HRESULT error;
  4631. #ifdef NEVER
  4632. // We would have liked to have done this check as an
  4633. // optimization, but WordArt2 does not give the right answer
  4634. // (bug 3504) so we can't.
  4635. if (m_pPStgDelegate->IsDirty() == NOERROR)
  4636. #endif
  4637. grfUpdf |= UPDFCACHE_ONSAVECACHE;
  4638. // next save server data
  4639. if (hresult = m_pPSDelegate->Save(pstgSave, fSameAsLoad))
  4640. {
  4641. goto errRtn;
  4642. }
  4643. // Update any blank cached presentations
  4644. m_pCOleCache->UpdateCache(GetDataDelegate(), grfUpdf, NULL);
  4645. // Save cache
  4646. hresult = m_pCOleCache->Save(pstgSave, fSameAsLoad);
  4647. // Write the Ole stream after obtaining cache status
  4648. if(m_pCOleCache->IsEmpty())
  4649. ObjFlags |= OBJFLAGS_CACHEEMPTY;
  4650. error = WriteOleStgEx(pstgSave, (IOleObject *)this, NULL, ObjFlags, NULL);
  4651. // Remember the cache status if Ole stream was successfully written and
  4652. // fSameAsLoad is TRUE
  4653. if(error==NOERROR && fSameAsLoad)
  4654. m_dwObjFlags |= ObjFlags;
  4655. }
  4656. else
  4657. {
  4658. // Save the cache
  4659. if ((hresult = m_pCOleCache->Save(m_pStg,TRUE))
  4660. != NOERROR)
  4661. {
  4662. goto errRtn;
  4663. }
  4664. // Check to see if Ole Stream needs to be written
  4665. if((!!(m_dwObjFlags & OBJFLAGS_CACHEEMPTY)) != m_pCOleCache->IsEmpty()) {
  4666. DWORD ObjFlags = 0;
  4667. HRESULT error;
  4668. // Write the Ole stream after obtaining cache status
  4669. if(m_pCOleCache->IsEmpty())
  4670. ObjFlags |= OBJFLAGS_CACHEEMPTY;
  4671. error = WriteOleStgEx(m_pStg, (IOleObject *)this, NULL, ObjFlags, NULL);
  4672. // Remember the cache status if Ole stream was successfully written
  4673. if(error==NOERROR)
  4674. m_dwObjFlags |= ObjFlags;
  4675. }
  4676. // By now we are sure that object's current state has got
  4677. // saved into its storage.
  4678. AssertSz(m_pStg, "Object doesn't have storage");
  4679. // Is saving the existing storage when fSameAsLoad is FLASE correct?
  4680. // To me it seems wrong. Gopalk
  4681. // It is not being fixed fearing some regression in apps
  4682. if (!fSameAsLoad)
  4683. {
  4684. hresult = m_pStg->CopyTo(NULL, NULL, NULL, pstgSave);
  4685. }
  4686. }
  4687. errRtn:
  4688. if (hresult == NOERROR)
  4689. {
  4690. if( fSameAsLoad )
  4691. {
  4692. m_flags |= DH_SAME_AS_LOAD;
  4693. // gets used in SaveCompleted
  4694. m_flags &= ~DH_INIT_NEW;
  4695. }
  4696. else
  4697. {
  4698. m_flags &= ~DH_SAME_AS_LOAD;
  4699. }
  4700. }
  4701. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::Save "
  4702. "( %lx )\n", this, hresult));
  4703. return hresult;
  4704. }
  4705. //+-------------------------------------------------------------------------
  4706. //
  4707. // Member: CDefObject::SaveCompleted
  4708. //
  4709. // Synopsis: called when the save is completed
  4710. //
  4711. // Effects:
  4712. //
  4713. // Arguments: [pstgNew] -- the new storage for the object
  4714. //
  4715. // Requires:
  4716. //
  4717. // Returns: HRESULT
  4718. //
  4719. // Signals:
  4720. //
  4721. // Modifies:
  4722. //
  4723. // Derivation: IPersistStorage
  4724. //
  4725. // Algorithm: delegates to the server and the cache.
  4726. //
  4727. // History: dd-mmm-yy Author Comment
  4728. // 08-Nov-93 alexgo 32bit port
  4729. //
  4730. // Notes:
  4731. //
  4732. //--------------------------------------------------------------------------
  4733. STDMETHODIMP CDefObject::SaveCompleted( IStorage *pstgNew )
  4734. {
  4735. VDATEHEAP();
  4736. VDATETHREAD(this);
  4737. HRESULT hresult = NOERROR;
  4738. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::SaveCompleted "
  4739. "( %p )\n", this, pstgNew));
  4740. if( pstgNew )
  4741. {
  4742. VDATEIFACE(pstgNew);
  4743. }
  4744. CRefStabilize stabilize(this);
  4745. if( IsRunning() && GetPSDelegate() )
  4746. {
  4747. hresult = m_pPSDelegate->SaveCompleted(pstgNew);
  4748. }
  4749. // we don't save the new storage if we're in a zombie state!
  4750. if( hresult == NOERROR && pstgNew && !IsZombie() )
  4751. {
  4752. if( m_pStg )
  4753. {
  4754. m_pStg->Release();
  4755. }
  4756. m_pStg = pstgNew;
  4757. pstgNew->AddRef();
  4758. }
  4759. // let the cache know that the save is completed, so that it can
  4760. // clear its dirty flag in Save or SaveAs situation, as well as
  4761. // remember the new storage pointer if a new one is given
  4762. Assert(m_pCOleCache != NULL);
  4763. if( (m_flags & DH_SAME_AS_LOAD) || pstgNew)
  4764. {
  4765. // clear init-new and same-as-load flags
  4766. m_flags &= ~(DH_SAME_AS_LOAD | DH_INIT_NEW);
  4767. }
  4768. m_pCOleCache->SaveCompleted(pstgNew);
  4769. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::SaveCompleted ( %lx )\n",
  4770. this, hresult));
  4771. return hresult;
  4772. }
  4773. //+-------------------------------------------------------------------------
  4774. //
  4775. // Member: CDefObject::HandsOffStorage
  4776. //
  4777. // Synopsis: Forces the server to release a storage (for low-mem reasons,
  4778. // etc).
  4779. //
  4780. // Effects:
  4781. //
  4782. // Arguments: void
  4783. //
  4784. // Requires:
  4785. //
  4786. // Returns: HRESULT
  4787. //
  4788. // Signals:
  4789. //
  4790. // Modifies:
  4791. //
  4792. // Derivation: IPersistStorage
  4793. //
  4794. // Algorithm: Delegates to the server and the cache
  4795. //
  4796. // History: dd-mmm-yy Author Comment
  4797. // 08-Nov-93 alexgo 32bit port
  4798. //
  4799. // Notes:
  4800. //
  4801. //--------------------------------------------------------------------------
  4802. STDMETHODIMP CDefObject::HandsOffStorage(void)
  4803. {
  4804. VDATEHEAP();
  4805. VDATETHREAD(this);
  4806. HRESULT hresult = NOERROR;
  4807. LEDebugOut((DEB_TRACE, "%p _IN CDefObject::HandsOffStorage ( )\n",
  4808. this));
  4809. CRefStabilize stabilize(this);
  4810. if( IsRunning() && GetPSDelegate() )
  4811. {
  4812. hresult = m_pPSDelegate->HandsOffStorage();
  4813. }
  4814. if (hresult == NOERROR)
  4815. {
  4816. if( m_pStg )
  4817. {
  4818. m_pStg->Release();
  4819. m_pStg = NULL;
  4820. }
  4821. Assert(m_pCOleCache != NULL);
  4822. m_pCOleCache->HandsOffStorage();
  4823. }
  4824. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::HandsOffStorage ( %lx )\n",
  4825. this, hresult));
  4826. return hresult;
  4827. }
  4828. /*
  4829. * Default handler private functions
  4830. */
  4831. //+-------------------------------------------------------------------------
  4832. //
  4833. // Member: CDefObject::GetClassBits
  4834. //
  4835. // Synopsis: Gets a class id for the object
  4836. //
  4837. // Effects:
  4838. //
  4839. // Arguments: [pClsidBits] -- where to put the class id
  4840. //
  4841. // Requires:
  4842. //
  4843. // Returns: HRESULT
  4844. //
  4845. // Signals:
  4846. //
  4847. // Modifies:
  4848. //
  4849. // Derivation:
  4850. //
  4851. // Algorithm: Tries the server, then the storage, and finally the
  4852. // clsid we were created with
  4853. //
  4854. // History: dd-mmm-yy Author Comment
  4855. // 08-Nov-93 alexgo 32bit port
  4856. //
  4857. // Notes:
  4858. //
  4859. // always gets a clsid and returns NOERROR; the clsid may be m_clsidServer
  4860. // under certain conditions (e.g., no compobj stream).
  4861. //
  4862. //--------------------------------------------------------------------------
  4863. INTERNAL CDefObject::GetClassBits(CLSID FAR* pClsidBits)
  4864. {
  4865. VDATEHEAP();
  4866. // alway try server first; this allows the server to respond
  4867. if( IsRunning() && GetPSDelegate() )
  4868. {
  4869. if( m_pPSDelegate->GetClassID(pClsidBits) == NOERROR )
  4870. {
  4871. m_clsidBits = *pClsidBits;
  4872. return NOERROR;
  4873. }
  4874. }
  4875. // not running, no ps or error: use previously cached value
  4876. if( !IsEqualCLSID(m_clsidBits, CLSID_NULL) )
  4877. {
  4878. *pClsidBits = m_clsidBits;
  4879. return NOERROR;
  4880. }
  4881. // not running, no ps or error and no clsidBits yet: read from stg
  4882. // if not static object.
  4883. if( !(m_flags & DH_STATIC) )
  4884. {
  4885. if (m_pStg && ReadClassStg(m_pStg, pClsidBits) == NOERROR)
  4886. {
  4887. m_clsidBits = *pClsidBits;
  4888. return NOERROR;
  4889. }
  4890. }
  4891. // no contact with server and can't get from storage; don't set
  4892. // m_clsidBits so if we get a storage or the serve becomes running,
  4893. // we get the right one
  4894. *pClsidBits = m_clsidServer;
  4895. return NOERROR;
  4896. }
  4897. //+-------------------------------------------------------------------------
  4898. //
  4899. // Member: CDefObject::DoConversionIfSpecialClass
  4900. //
  4901. // Synopsis: Convert old data formats.
  4902. //
  4903. // Effects:
  4904. //
  4905. // Arguments: [pstg] -- the storage with the data
  4906. //
  4907. // Requires:
  4908. //
  4909. // Returns: HRESULT
  4910. //
  4911. // Signals:
  4912. //
  4913. // Modifies:
  4914. //
  4915. // Derivation:
  4916. //
  4917. // Algorithm: see notes...
  4918. //
  4919. // History: dd-mmm-yy Author Comment
  4920. // 08-Nov-93 alexgo 32bit port
  4921. //
  4922. // Notes: this is not yet functional for 32bit OLE
  4923. //
  4924. // If the class is CLSID_StaticDib/CLSID_StaticMetafile and the old
  4925. // format is "PBrush"/"MSDraw" the data must be in the OLE10_NATIVESTREAM.
  4926. // Move the data into the CONTENTS stream
  4927. //
  4928. // If the class is CLSID_PBrush/CLSID_MSDraw and the old format is
  4929. // metafile/DIB then data must be in the CONTENTS stream. Move the data
  4930. // from the CONTENTS stream to the OLE10_NATIVESTREAM"
  4931. //
  4932. //--------------------------------------------------------------------------
  4933. INTERNAL CDefObject::DoConversionIfSpecialClass(LPSTORAGE pstg)
  4934. {
  4935. VDATEHEAP();
  4936. LEDebugOut((DEB_ITRACE, "%p _IN CDefObject::DoConversionIfSpecialClass ("
  4937. " %p )\n", this, pstg));
  4938. HRESULT hresult;
  4939. UINT uiStatus;
  4940. /*** Handle the static object case ***/
  4941. if( (m_flags & DH_STATIC) ) {
  4942. if ((hresult = Ut10NativeStmToContentsStm(pstg, m_clsidServer,
  4943. TRUE /* fDeleteContentStm*/)) == NOERROR)
  4944. #ifdef OLD
  4945. UtRemoveExtraOlePresStreams(pstg, 0 /*iStart*/);
  4946. #endif
  4947. goto errRtn;
  4948. }
  4949. /*** Handle the PBrush & MSDraw case ***/
  4950. // Conversion is not a frequent operation. So, it is better to do the
  4951. // CLSID comparison here when it is necessary than doing comparison
  4952. // upfront and remember a flag
  4953. // if the class is not one of the following two then the object server
  4954. // will do the necessary conversion.
  4955. {
  4956. CLSID clsid = CLSID_NULL;
  4957. // Get the real CLSID from the storage. This is necessary because we
  4958. // may be a PBrush object being "treated as".
  4959. ReadClassStg(pstg, &clsid);
  4960. // if the real CLSID is not PaintBrush or the known CLSID is not MSDRAW
  4961. // head out.
  4962. if( clsid != CLSID_PBrush && m_clsidServer != CLSID_MSDraw )
  4963. {
  4964. hresult = NOERROR;
  4965. goto exitRtn;
  4966. }
  4967. // if the real CLSID is not paintbrush, then set clsid to the clsid to
  4968. // the known clsid.
  4969. if (clsid != CLSID_PBrush)
  4970. {
  4971. clsid = m_clsidServer;
  4972. }
  4973. //
  4974. hresult = UtContentsStmTo10NativeStm(pstg, clsid,
  4975. TRUE /* fDeleteContentStm*/,
  4976. &uiStatus);
  4977. }
  4978. // if OLE10_NATIVE_STREAM exists then assume success
  4979. if (!(uiStatus & CONVERT_NODESTINATION))
  4980. hresult = NOERROR;
  4981. if (hresult != NOERROR) {
  4982. // May be the static object data is in OlePres stream. If so,
  4983. // first convert that to contents stream and then try again
  4984. // In OLE2.0 first release static object were written to
  4985. // OlePres000 stream.
  4986. hresult = UtOlePresStmToContentsStm(pstg,
  4987. OLE_PRESENTATION_STREAM,
  4988. TRUE /*fDeletePresStm*/, &uiStatus);
  4989. if (hresult == NOERROR)
  4990. hresult = UtContentsStmTo10NativeStm(pstg,
  4991. m_clsidServer,
  4992. TRUE /* fDeleteContentStm*/,
  4993. &uiStatus);
  4994. }
  4995. errRtn:
  4996. if (hresult == NOERROR)
  4997. // conversion is successful, turn the bit off
  4998. SetConvertStg(pstg, FALSE);
  4999. exitRtn:
  5000. LEDebugOut((DEB_TRACE, "%p OUT CDefObject::DoConversionIfSpecialClass "
  5001. "( %lx ) \n", this, hresult));
  5002. return hresult;
  5003. }
  5004. //+-------------------------------------------------------------------------
  5005. //
  5006. // Member: CDefObject::Dump, public (_DEBUG only)
  5007. //
  5008. // Synopsis: return a string containing the contents of the data members
  5009. //
  5010. // Effects:
  5011. //
  5012. // Arguments: [ppszDump] - an out pointer to a null terminated character array
  5013. // [ulFlag] - flag determining prefix of all newlines of the
  5014. // out character array (default is 0 - no prefix)
  5015. // [nIndentLevel] - will add a indent prefix after the other prefix
  5016. // for ALL newlines (including those with no prefix)
  5017. //
  5018. // Requires:
  5019. //
  5020. // Returns: HRESULT
  5021. //
  5022. // Signals:
  5023. //
  5024. // Modifies: [ppszDump] - argument
  5025. //
  5026. // Derivation:
  5027. //
  5028. // Algorithm: use dbgstream to create a string containing information on the
  5029. // content of data structures
  5030. //
  5031. // History: dd-mmm-yy Author Comment
  5032. // 01-Feb-95 t-ScottH author
  5033. //
  5034. // Notes:
  5035. //
  5036. //--------------------------------------------------------------------------
  5037. #ifdef _DEBUG
  5038. HRESULT CDefObject::Dump(char **ppszDump, ULONG ulFlag, int nIndentLevel)
  5039. {
  5040. int i;
  5041. char *pszPrefix;
  5042. char *pszCSafeRefCount;
  5043. char *pszCThreadCheck;
  5044. char *pszOAHolder;
  5045. char *pszCLSID;
  5046. char *pszCOleCache;
  5047. char *pszDAC;
  5048. LPOLESTR pszName;
  5049. dbgstream dstrPrefix;
  5050. dbgstream dstrDump(5000);
  5051. // determine prefix of newlines
  5052. if ( ulFlag & DEB_VERBOSE )
  5053. {
  5054. dstrPrefix << this << " _VB ";
  5055. }
  5056. // determine indentation prefix for all newlines
  5057. for (i = 0; i < nIndentLevel; i++)
  5058. {
  5059. dstrPrefix << DUMPTAB;
  5060. }
  5061. pszPrefix = dstrPrefix.str();
  5062. // put data members in stream
  5063. pszCThreadCheck = DumpCThreadCheck((CThreadCheck *)this, ulFlag, nIndentLevel + 1);
  5064. dstrDump << pszPrefix << "CThreadCheck:" << endl;
  5065. dstrDump << pszCThreadCheck;
  5066. CoTaskMemFree(pszCThreadCheck);
  5067. // only vtable pointers (plus we don't get the right address in debugger extensions)
  5068. // dstrDump << pszPrefix << "&IUnknown = " << &m_Unknown << endl;
  5069. // dstrDump << pszPrefix << "&IAdviseSink = " << &m_AdviseSink << endl;
  5070. dstrDump << pszPrefix << "pIOleObject Delegate = " << m_pOleDelegate << endl;
  5071. dstrDump << pszPrefix << "pIDataObject Delegate = " << m_pDataDelegate << endl;
  5072. dstrDump << pszPrefix << "pIPersistStorage Delegate = " << m_pPSDelegate << endl;
  5073. dstrDump << pszPrefix << "Count of Strong Connection= " << m_cConnections << endl;
  5074. dstrDump << pszPrefix << "pIUnknown pUnkOuter = ";
  5075. if (m_flags & DH_AGGREGATED)
  5076. {
  5077. dstrDump << "AGGREGATED (" << m_pUnkOuter << ")" << endl;
  5078. }
  5079. else
  5080. {
  5081. dstrDump << "NO AGGREGATION (" << m_pUnkOuter << ")" << endl;
  5082. }
  5083. pszCLSID = DumpCLSID(m_clsidServer);
  5084. dstrDump << pszPrefix << "Server CLSID = " << pszCLSID << endl;
  5085. CoTaskMemFree(pszCLSID);
  5086. pszCLSID = DumpCLSID(m_clsidBits);
  5087. dstrDump << pszPrefix << "Persistent CLSID = " << pszCLSID << endl;
  5088. CoTaskMemFree(pszCLSID);
  5089. dstrDump << pszPrefix << "Handler flags = ";
  5090. if (m_flags & DH_SAME_AS_LOAD)
  5091. {
  5092. dstrDump << "DH_SAME_AS_LOAD ";
  5093. }
  5094. if (m_flags & DH_CONTAINED_OBJECT)
  5095. {
  5096. dstrDump << "DH_CONTAINED_OBJECT ";
  5097. }
  5098. if (m_flags & DH_LOCKED_CONTAINER)
  5099. {
  5100. dstrDump << "DH_LOCKED_CONTAINER ";
  5101. }
  5102. if (m_flags & DH_FORCED_RUNNING)
  5103. {
  5104. dstrDump << "DH_FORCED_RUNNING ";
  5105. }
  5106. if (m_flags & DH_EMBEDDING)
  5107. {
  5108. dstrDump << "DH_EMBEDDING ";
  5109. }
  5110. if (m_flags & DH_INIT_NEW)
  5111. {
  5112. dstrDump << "DH_INIT_NEW ";
  5113. }
  5114. if (m_flags & DH_STATIC)
  5115. {
  5116. dstrDump << "DH_STATIC ";
  5117. }
  5118. if (m_flags & DH_INPROC_HANDLER)
  5119. {
  5120. dstrDump << "DH_INPROC_HANDLER ";
  5121. }
  5122. if (m_flags & DH_DELAY_CREATE)
  5123. {
  5124. dstrDump << "DH_DELAY_CREATE ";
  5125. }
  5126. if (m_flags & DH_AGGREGATED)
  5127. {
  5128. dstrDump << "DH_AGGREGATED ";
  5129. }
  5130. // if none of the flags are set...
  5131. if ( !( (m_flags & DH_SAME_AS_LOAD) |
  5132. (m_flags & DH_CONTAINED_OBJECT) |
  5133. (m_flags & DH_LOCKED_CONTAINER) |
  5134. (m_flags & DH_FORCED_RUNNING) |
  5135. (m_flags & DH_EMBEDDING) |
  5136. (m_flags & DH_INIT_NEW) |
  5137. (m_flags & DH_STATIC) |
  5138. (m_flags & DH_INPROC_HANDLER) |
  5139. (m_flags & DH_DELAY_CREATE) |
  5140. (m_flags & DH_AGGREGATED)))
  5141. {
  5142. dstrDump << "No FLAGS SET!";
  5143. }
  5144. dstrDump << "(" << LongToPtr(m_flags) << ")" << endl;
  5145. dstrDump << pszPrefix << "pIClassFactory Delegate = " << m_pCFDelegate << endl;
  5146. dstrDump << pszPrefix << "pIUnknown Delegate = " << m_pUnkDelegate << endl;
  5147. dstrDump << pszPrefix << "pIProxyManager = " << m_pProxyMgr << endl;
  5148. if (m_pCOleCache != NULL)
  5149. {
  5150. // pszCOleCache = DumpCOleCache(m_pCOleCache, ulFlag, nIndentLevel + 1);
  5151. dstrDump << pszPrefix << "COleCache: " << endl;
  5152. // dstrDump << pszCOleCache;
  5153. // CoTaskMemFree(pszCOleCache);
  5154. }
  5155. else
  5156. {
  5157. dstrDump << pszPrefix << "pCOleCache = " << m_pCOleCache << endl;
  5158. }
  5159. if (m_pOAHolder != NULL)
  5160. {
  5161. pszOAHolder = DumpCOAHolder(m_pOAHolder, ulFlag, nIndentLevel + 1);
  5162. dstrDump << pszPrefix << "COAHolder: " << endl;
  5163. dstrDump << pszOAHolder;
  5164. CoTaskMemFree(pszOAHolder);
  5165. }
  5166. else
  5167. {
  5168. dstrDump << pszPrefix << "pIOleAdviseHolder = " << m_pOAHolder << endl;
  5169. }
  5170. dstrDump << pszPrefix << "OLE Connection Advise ID = " << m_dwConnOle << endl;
  5171. dstrDump << pszPrefix << "pIOleClientSite = " << m_pAppClientSite << endl;
  5172. dstrDump << pszPrefix << "pIStorage = " << m_pStg << endl;
  5173. pszName = (LPOLESTR)m_pHostNames;
  5174. dstrDump << pszPrefix << "Application Name = " << pszName << endl;
  5175. pszName = (LPOLESTR)(m_pHostNames + m_ibCntrObj);
  5176. dstrDump << pszPrefix << "Document Name = " << pszName << endl;
  5177. if (m_pDataAdvCache != NULL)
  5178. {
  5179. pszDAC = DumpCDataAdviseCache(m_pDataAdvCache, ulFlag, nIndentLevel + 1);
  5180. dstrDump << pszPrefix << "CDataAdviseCache: " << endl;
  5181. dstrDump << pszDAC;
  5182. CoTaskMemFree(pszDAC);
  5183. }
  5184. else
  5185. {
  5186. dstrDump << pszPrefix << "pCDataAdviseCache = " << m_pDataAdvCache << endl;
  5187. }
  5188. // cleanup and provide pointer to character array
  5189. *ppszDump = dstrDump.str();
  5190. if (*ppszDump == NULL)
  5191. {
  5192. *ppszDump = UtDupStringA(szDumpErrorMessage);
  5193. }
  5194. CoTaskMemFree(pszPrefix);
  5195. return NOERROR;
  5196. }
  5197. #endif // _DEBUG
  5198. //+-------------------------------------------------------------------------
  5199. //
  5200. // Function: DumpCDefObject, public (_DEBUG only)
  5201. //
  5202. // Synopsis: calls the CDefObject::Dump method, takes care of errors and
  5203. // returns the zero terminated string
  5204. //
  5205. // Effects:
  5206. //
  5207. // Arguments: [pDO] - pointer to CDefObject
  5208. // [ulFlag] - flag determining prefix of all newlines of the
  5209. // out character array (default is 0 - no prefix)
  5210. // [nIndentLevel] - will add a indent prefix after the other prefix
  5211. // for ALL newlines (including those with no prefix)
  5212. //
  5213. // Requires:
  5214. //
  5215. // Returns: character array of structure dump or error (null terminated)
  5216. //
  5217. // Signals:
  5218. //
  5219. // Modifies:
  5220. //
  5221. // Algorithm:
  5222. //
  5223. // History: dd-mmm-yy Author Comment
  5224. // 01-Feb-95 t-ScottH author
  5225. //
  5226. // Notes:
  5227. //
  5228. //--------------------------------------------------------------------------
  5229. #ifdef _DEBUG
  5230. char *DumpCDefObject(CDefObject *pDO, ULONG ulFlag, int nIndentLevel)
  5231. {
  5232. HRESULT hresult;
  5233. char *pszDump;
  5234. if (pDO == NULL)
  5235. {
  5236. return UtDupStringA(szDumpBadPtr);
  5237. }
  5238. hresult = pDO->Dump(&pszDump, ulFlag, nIndentLevel);
  5239. if (hresult != NOERROR)
  5240. {
  5241. CoTaskMemFree(pszDump);
  5242. return DumpHRESULT(hresult);
  5243. }
  5244. return pszDump;
  5245. }
  5246. #endif // _DEBUG