Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3126 lines
98 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: actprops.cxx
  7. //
  8. // Contents: Activation Functions used by object servers.
  9. //
  10. // Functions: Implements classes in Actprops.hxx
  11. //
  12. // History: 24-Jan-98 Vinaykr Created
  13. // 24-Jul-98 CBiks Fixed RAID# 199660.
  14. // 14-Sep-98 CBiks Fixed RAID# 214719.
  15. // 29-Sep-98 vinaykr Fixed RAID# 169084,
  16. // inproc unmarshaller for perf
  17. // 14-Sep-98 CBiks Fixed RAID# 151056.
  18. // 22-Oct-98 TarunA Fixed RAID# 234750
  19. //
  20. //--------------------------------------------------------------------------
  21. #include <ole2int.h>
  22. #include <actprops.hxx>
  23. #include <stdidx.h>
  24. //---------------------------------------------------------------------------
  25. // GUIDs need to be declared here since they have to
  26. // live in both the SCM and OLE32.
  27. //---------------------------------------------------------------------------
  28. // catalog query helper defined in ..\com\objact.cxx
  29. HRESULT GetClassInfoFromClsid(REFCLSID rclsid, IComClassInfo **ppClassInfo);
  30. CLSID CLSID_Grammatik = {0xc9da6c40,0x83b1,0x11ce,
  31. {0x81, 0xac, 0x00, 0x60, 0x8c, 0xb9, 0xf8, 0x3b}};
  32. CLSID CLSID_WonderWare = {0x28dd9320, 0x6f69, 0x11ce,
  33. {0x8b, 0x69, 0x00, 0x60, 0x8c, 0xc9, 0x7d, 0x5b}};
  34. CLSID CLSID_WPNatLangTools = {0xe6246810, 0x030f, 0x11cf,
  35. {0x88, 0x75, 0x00, 0x60, 0x8c, 0xf5, 0xab, 0x6f}};
  36. CLSID CLSID_Grammatik8 = {0xc0e10005, 0x0201, 0x0180,
  37. {0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1}};
  38. InprocActpropsUnmarshaller InprocActpropsUnmarshaller::_InprocActUnmarshaller;
  39. CLSID *arBrokenRefCount[] =
  40. {
  41. &CLSID_Grammatik,
  42. &CLSID_WonderWare,
  43. &CLSID_WPNatLangTools,
  44. &CLSID_Grammatik8
  45. };
  46. //
  47. // Marshalling functions. They are here because we cannot link to ole32.dll
  48. // if we are in the SCM.
  49. //
  50. PFN_CORELEASEMARSHALDATA pfnCoReleaseMarshalData = NULL;
  51. PFN_COUNMARSHALINTERFACE pfnCoUnmarshalInterface = NULL;
  52. PFN_COGETMARSHALSIZEMAX pfnCoGetMarshalSizeMax = NULL;
  53. PFN_COMARSHALINTERFACE pfnCoMarshalInterface = NULL;
  54. // Resolve the function pointers for marshalling. Call this before you
  55. // use any of the above functions, or you WILL crash, ole32 or not.
  56. void InitMarshalling(void)
  57. {
  58. static int init = 0;
  59. // Only attempt to initialize once.
  60. if (init)
  61. return;
  62. // Do not load ole32.dll, but if it is loaded then we are linked into it,
  63. // and this will work.
  64. HMODULE hOle32 = GetModuleHandle(L"ole32.dll");
  65. if (hOle32)
  66. {
  67. // Get the functions we need.
  68. pfnCoGetMarshalSizeMax = (PFN_COGETMARSHALSIZEMAX)GetProcAddress(hOle32, "CoGetMarshalSizeMax");
  69. Win4Assert(pfnCoGetMarshalSizeMax && "Could not get CoGetMarshalSizeMax!");
  70. pfnCoMarshalInterface = (PFN_COMARSHALINTERFACE)GetProcAddress(hOle32, "CoMarshalInterface");
  71. Win4Assert(pfnCoMarshalInterface && "Could not get CoMarshalInterface!");
  72. pfnCoUnmarshalInterface = (PFN_COUNMARSHALINTERFACE)GetProcAddress(hOle32, "CoUnmarshalInterface");
  73. Win4Assert(pfnCoUnmarshalInterface && "Could not get CoUnmarshalInterface!");
  74. pfnCoReleaseMarshalData = (PFN_CORELEASEMARSHALDATA)GetProcAddress(hOle32, "CoReleaseMarshalData");
  75. Win4Assert(pfnCoReleaseMarshalData && "Could not get CoReleaseMarshalData!");
  76. }
  77. else
  78. {
  79. // ole32.dll is not loaded. The functions stay null. If anybody
  80. // tries to call them, you will crash. You should not be calling
  81. // such functions from the SCM.
  82. //
  83. // REVIEW: We might want to assert here. Revisit when Jon Schwartz
  84. // makes ole32.dll delay load.
  85. }
  86. init = 1;
  87. }
  88. //+----------------------------------------------------------------------------
  89. //
  90. // Function: IsBrokenRefCount
  91. //
  92. // Synopsis: Check to see if this clsid is known to have broken reference
  93. // counting.
  94. //
  95. // History: 21-Apr-98 MattSmit Created
  96. //
  97. //-----------------------------------------------------------------------------
  98. BOOL IsBrokenRefCount(CLSID *pClsId)
  99. {
  100. ULONG i;
  101. ULONG len = sizeof(arBrokenRefCount)/sizeof(CLSID*);
  102. for (i = 0; i < len; i++)
  103. {
  104. if (IsEqualIID(*pClsId, *(arBrokenRefCount[i])))
  105. {
  106. return TRUE;
  107. }
  108. }
  109. return FALSE;
  110. }
  111. //---------------------------------------------------------------------------
  112. // Internal Class Factories for Activation Properties
  113. //---------------------------------------------------------------------------
  114. HRESULT CActivationPropertiesInCF_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv)
  115. {
  116. ActivationPropertiesIn * actin =
  117. new ActivationPropertiesIn();
  118. if (actin==NULL)
  119. return E_OUTOFMEMORY;
  120. HRESULT hr = actin->QueryInterface(riid, ppv);
  121. actin->Release();
  122. return hr;
  123. }
  124. HRESULT CActivationPropertiesOutCF_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv)
  125. {
  126. ActivationPropertiesOut * actout =
  127. new ActivationPropertiesOut(FALSE /* fBrokenRefCount */ );
  128. if (actout==NULL)
  129. return E_OUTOFMEMORY;
  130. HRESULT hr = actout->QueryInterface(riid, ppv);
  131. actout->Release();
  132. return hr;
  133. }
  134. HRESULT CInprocActpropsUnmarshallerCF_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv)
  135. {
  136. InprocActpropsUnmarshaller *pInst;
  137. pInst = InprocActpropsUnmarshaller::GetInstance();
  138. Win4Assert(pInst);
  139. return pInst->QueryInterface(riid, ppv);
  140. }
  141. //---------------------------------------------------------------------------
  142. // ActivationProperties is a helper class for marshalling
  143. // different property objects. It implements ISerializableParent
  144. // and manages a set of serializable interfaces.
  145. // Assumptions are:
  146. // a. QI'ing an interface can bring an
  147. // instance into existence.
  148. // b. It is possible for some interfaces
  149. // to never be instantiatable on
  150. // an unserialized Actprops object.
  151. // This is achieved through GetClass()
  152. // c. It is possible for some interfaces
  153. // to never be instantiated again
  154. // after they are unserialized(at
  155. // least once). Achieved by returning
  156. // a size of 0 in GetMarshalSizeMax
  157. // Used to turn off propagation at a
  158. // particular stage.
  159. //---------------------------------------------------------------------------
  160. //---------------------------------------------------------------------------
  161. // Methods for ActivationProperties
  162. //---------------------------------------------------------------------------
  163. ActivationProperties::ActivationProperties()
  164. {
  165. memset(&_serHeader, 0, sizeof(CustomHeader));
  166. memset(&_unSerHeader, 0, sizeof(CustomHeader));
  167. _ifsIndex = 0;
  168. _unSerialized = FALSE;
  169. _unSerializedInproc = FALSE;
  170. _pUnSer = 0;
  171. _serHeader.destCtx = MSHCTX_CROSSCTX;
  172. _marshalFlags = MSHLFLAGS_NORMAL;
  173. _toDelete = TRUE;
  174. _fDestruct = FALSE;
  175. _marshalState = NOT_MARSHALLED;
  176. _fInprocSerializationRequired = FALSE;
  177. }
  178. ActivationProperties::~ActivationProperties()
  179. {
  180. #if 0 // Allocate them as member vars now
  181. //-------------------------------------------------------------------
  182. // Release all references to property objects held
  183. //-------------------------------------------------------------------
  184. for (DWORD i=0; i<_ifsIndex; i++)
  185. {
  186. if (serializableIfsCollection[i])
  187. serializableIfsCollection[i]->Release();
  188. }
  189. #endif
  190. //-------------------------------------------------------------------
  191. // Release reference to unserialized stream
  192. //-------------------------------------------------------------------
  193. if (_pUnSer)
  194. _pUnSer->Release();
  195. //-------------------------------------------------------------------
  196. // Release unserialized data
  197. //-------------------------------------------------------------------
  198. if (_unSerialized)
  199. {
  200. ActMemFree(_unSerHeader.pclsid);
  201. ActMemFree(_unSerHeader.pSizes);
  202. }
  203. if (_serHeader.cOpaqueData)
  204. {
  205. for (DWORD i=0; i<_serHeader.cOpaqueData;i++)
  206. ActMemFree(_serHeader.opaqueData[i].data);
  207. ActMemFree(_serHeader.opaqueData);
  208. }
  209. }
  210. //---------------------------------------------------------------------------
  211. // Methods for IUnknown
  212. //---------------------------------------------------------------------------
  213. //-----------------------------------------------------------------------
  214. // Assumption is that the Top-level ActivationProperties object
  215. // supports interfaces of the objects contained within it.
  216. // QI'ing an interface of a property object can bring it into
  217. // existence. GetClass is used for this.
  218. // When this is unmarshalled, the contained objects are not
  219. // unserialized. They are unserialized when QI's for using
  220. // UnSerializeCallback().
  221. //-----------------------------------------------------------------------
  222. STDMETHODIMP ActivationProperties::QueryInterface( REFIID riid, LPVOID* ppv)
  223. {
  224. HRESULT hr;
  225. //-------------------------------------------------------------------
  226. // Check for Top level interfaces
  227. //-------------------------------------------------------------------
  228. if (IsEqualIID(riid, IID_IUnknown))
  229. *ppv = (IActivationProperties*)this;
  230. else
  231. if (IsEqualIID(riid, IID_IActivationProperties))
  232. *ppv = (IActivationProperties*)this;
  233. else
  234. if (IsEqualIID(riid, IID_ISerializableParent))
  235. *ppv = (ISerializableParent*)this;
  236. else
  237. if (IsEqualIID(riid, IID_IMarshal))
  238. *ppv = (IMarshal*)this;
  239. else
  240. if (IsEqualIID(riid, IID_IMarshal2))
  241. *ppv = (IMarshal2*)this;
  242. else
  243. if (IsEqualIID(riid, IID_IGetCatalogObject))
  244. *ppv = (IGetCatalogObject*)this;
  245. else
  246. if (IsEqualIID(riid, CLSID_ActivationProperties))
  247. {
  248. // Don't addref for this one
  249. *ppv = (ActivationProperties*)this;
  250. return S_OK;
  251. }
  252. else
  253. *ppv = NULL;
  254. if (*ppv != NULL)
  255. {
  256. AddRef();
  257. return S_OK;
  258. }
  259. //-------------------------------------------------------------------
  260. // Check Contained objects
  261. //-------------------------------------------------------------------
  262. for (DWORD i=0; i<_ifsIndex; i++)
  263. if (serializableIfsCollection[i])
  264. if (serializableIfsCollection[i]->SerializableQueryInterface(riid, ppv) == S_OK)
  265. return S_OK;
  266. //-------------------------------------------------------------------
  267. // Check for unserialized objects */
  268. //-------------------------------------------------------------------
  269. SerializableProperty *pSer;
  270. if (_unSerialized)
  271. {
  272. if ((hr = UnSerializeCallBack(riid, &pSer)) == S_OK)
  273. {
  274. if (pSer->SerializableQueryInterface(riid, ppv) == S_OK)
  275. return S_OK;
  276. }
  277. else
  278. if (hr != E_FAIL)
  279. {
  280. *ppv = NULL;
  281. return hr;
  282. }
  283. }
  284. //-------------------------------------------------------------------
  285. // Check if interface supported here */
  286. //-------------------------------------------------------------------
  287. if (GetClass(riid, &pSer, TRUE) == S_OK)
  288. {
  289. AddSerializableIfs(pSer);
  290. HRESULT hr = pSer->SerializableQueryInterface(riid, ppv);
  291. Win4Assert(hr==S_OK);
  292. return S_OK;
  293. }
  294. *ppv = NULL;
  295. return E_NOINTERFACE;
  296. }
  297. ULONG ActivationProperties::AddRef(void)
  298. {
  299. return InterlockedIncrement(&_refCount);
  300. }
  301. ULONG ActivationProperties::Release(void)
  302. {
  303. ULONG count;
  304. if ((count = InterlockedDecrement(&_refCount)) == 0)
  305. {
  306. //-------------------------------------------------------------------
  307. // Relinquish parent-child relationship and send child off into
  308. // the big bad world.
  309. //-------------------------------------------------------------------
  310. for (DWORD i=0; i<_ifsIndex; i++)
  311. if (serializableIfsCollection[i])
  312. {
  313. serializableIfsCollection[i]->SetParent(NULL);
  314. }
  315. return 0;
  316. }
  317. return count;
  318. }
  319. //---------------------------------------------------------------------------
  320. // Custom marshalling Methods(IMarshal) */
  321. // Ignore Table marshalling
  322. //---------------------------------------------------------------------------
  323. STDMETHODIMP ActivationProperties::MarshalInterface(
  324. IStream *pStm,
  325. REFIID riid,
  326. void *pv,
  327. DWORD dwDestContext,
  328. void *pvDestContext,
  329. DWORD mshlflags)
  330. {
  331. HRESULT hr;
  332. BOOL fReleaseThis;
  333. //-------------------------------------------------------------------
  334. // Check to see that requested interface is supported
  335. //-------------------------------------------------------------------
  336. void *ppv;
  337. if (!SUCCEEDED(hr=QueryInterface(riid, &ppv)))
  338. {
  339. return hr;
  340. }
  341. else
  342. fReleaseThis = TRUE;
  343. RpcTryExcept
  344. {
  345. //-------------------------------------------------------------------
  346. // Internal marshalling distance flag already set up by
  347. // GetMarshalSizeMax
  348. //-------------------------------------------------------------------
  349. void *pv;
  350. if (MARSHALCTX_WITHIN_PROCESS(dwDestContext))
  351. {
  352. pv = (void*)((ActivationProperties*) this);
  353. fReleaseThis = FALSE;
  354. }
  355. else
  356. pv = NULL;
  357. //-------------------------------------------------------------------
  358. // Create Serializer for serialization
  359. //-------------------------------------------------------------------
  360. Serializer ser(_serHeader.destCtx, dwDestContext, _marshalFlags);
  361. hr = ser.InitStream(pStm, _serHeader.totalSize,
  362. Serializer::DIRECTION_WRITE, pv);
  363. if (FAILED(hr))
  364. {
  365. if(fReleaseThis)
  366. Release();
  367. return hr;
  368. }
  369. if ((!pv) || _fInprocSerializationRequired)
  370. hr = Serialize(ser);
  371. else
  372. hr = S_OK;
  373. _marshalState = MARSHALLED;
  374. }
  375. RpcExcept(TRUE)
  376. {
  377. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  378. }
  379. RpcEndExcept
  380. if (fReleaseThis)
  381. Release();
  382. return hr;
  383. }
  384. inline HRESULT ActivationProperties::Serialize(Serializer &ser)
  385. {
  386. HRESULT hr;
  387. //-------------------------------------------------------------------
  388. // First encode Generic header
  389. //-------------------------------------------------------------------
  390. handle_t handle;
  391. hr = ser.GetSerializationHandle((void*) &handle);
  392. if (FAILED(hr))
  393. return hr;
  394. CustomHeader_Encode(handle, &_serHeader);
  395. hr = ser.IncrementPosition(_headerSize);
  396. if (FAILED(hr))
  397. return hr;
  398. DWORD unSerializedPosition=_unSerHeader.headerSize;
  399. DWORD totalinc = 0;
  400. //-------------------------------------------------------------------
  401. // Now serialize all contained objects
  402. //-------------------------------------------------------------------
  403. for (DWORD i=0; i<_ifsIndex;i++)
  404. {
  405. if (!_sizeArray[i])
  406. continue;
  407. if ((_unSerialized) && (!serializableIfsCollection[i]))
  408. {
  409. hr = _pUnSer->CopyTo(&ser, unSerializedPosition, _sizeArray[i]);
  410. if (FAILED(hr))
  411. return hr;
  412. }
  413. else
  414. {
  415. hr = serializableIfsCollection[i]->Serialize(&ser);
  416. if (hr != S_OK)
  417. return hr;
  418. hr = ser.IncrementPosition(_sizeArray[i]);
  419. if (FAILED(hr))
  420. return hr;
  421. }
  422. if (_unSerialized && (i<_unSerHeader.cIfs))
  423. unSerializedPosition += _unSerHeader.pSizes[i];
  424. }
  425. //-------------------------------------------------------------------
  426. // Commit to stream
  427. //-------------------------------------------------------------------
  428. return ser.Commit();
  429. }
  430. inline HRESULT ActivationProperties::SetupForUnserializing(Serializer *pSer)
  431. {
  432. //---------------------------------------------------------------
  433. // Read Custom header
  434. // Make a copy to hold still unserialized objects for future
  435. // Set up state for next serialization
  436. //---------------------------------------------------------------
  437. handle_t handle;
  438. pSer->GetSerializationHandle((void*) &handle);
  439. _unSerHeader.pclsid = 0;
  440. _unSerHeader.pSizes = 0;
  441. _unSerHeader.opaqueData = 0;
  442. CustomHeader_Decode(handle, &_unSerHeader);
  443. pSer->IncrementPosition(_unSerHeader.headerSize);
  444. HRESULT hr = pSer->GetCopy(&_pUnSer);
  445. if (FAILED(hr))
  446. return hr;
  447. pSer->Commit();
  448. _unSerialized = TRUE;
  449. _ifsIndex = _unSerHeader.cIfs;
  450. _serHeader.destCtx = _unSerHeader.destCtx;
  451. _serHeader.cOpaqueData = _unSerHeader.cOpaqueData;
  452. _serHeader.opaqueData = _unSerHeader.opaqueData;
  453. return S_OK;
  454. }
  455. STDMETHODIMP InprocActpropsUnmarshaller::UnmarshalInterface(IStream *pStm,
  456. REFIID riid,
  457. void **ppv)
  458. {
  459. ActivationProperties *pAct = NULL;
  460. RpcTryExcept
  461. {
  462. HRESULT hr;
  463. DWORD dwSize;
  464. void *pv = NULL;
  465. //---------------------------------------------------------------
  466. // Init Serializer for reading from stream
  467. //---------------------------------------------------------------
  468. Serializer ser;
  469. hr = ser.InitStream(pStm, dwSize,
  470. Serializer::DIRECTION_READ, pv);
  471. if (!SUCCEEDED(hr))
  472. return hr;
  473. pAct = (ActivationProperties*) pv;
  474. Win4Assert(pAct);
  475. if (!pAct)
  476. return(E_UNEXPECTED);
  477. //---------------------------------------------------------------
  478. // If we received a pointer, check if any further unserialization
  479. // required. If so set up stream inside object pointed to
  480. //---------------------------------------------------------------
  481. Win4Assert(pAct->_marshalState !=
  482. ActivationProperties::UNMARSHALLED);
  483. if (dwSize != 0)
  484. hr = pAct->SetupForUnserializing(&ser);
  485. if (SUCCEEDED(hr))
  486. {
  487. if (ppv != NULL)
  488. hr = pAct->QueryInterface(riid, ppv);
  489. else
  490. hr = E_UNEXPECTED;
  491. }
  492. pAct->_marshalState = ActivationProperties::UNMARSHALLED;
  493. pAct->Release();
  494. return hr;
  495. }
  496. RpcExcept(TRUE)
  497. {
  498. //---------------------------------------------------------------
  499. // If we get here and have a pAct then we must release it
  500. //---------------------------------------------------------------
  501. if (pAct)
  502. {
  503. pAct->Release();
  504. }
  505. return HRESULT_FROM_WIN32(RpcExceptionCode());
  506. }
  507. RpcEndExcept
  508. // Should never get here !
  509. Win4Assert(0 && "Should never reach here");
  510. return E_UNEXPECTED;
  511. }
  512. STDMETHODIMP ActivationProperties::UnmarshalInterface(IStream *pStm,
  513. REFIID riid,
  514. void **ppv)
  515. {
  516. RpcTryExcept
  517. {
  518. Win4Assert(_marshalState != UNMARSHALLED);
  519. HRESULT hr;
  520. DWORD dwSize;
  521. void *pv = NULL;
  522. //---------------------------------------------------------------
  523. // Init Serializer for reading from stream
  524. //---------------------------------------------------------------
  525. Serializer ser;
  526. hr = ser.InitStream(pStm, dwSize,
  527. Serializer::DIRECTION_READ, pv);
  528. if (!SUCCEEDED(hr))
  529. return hr;
  530. hr = SetupForUnserializing(&ser);
  531. if (FAILED(hr))
  532. return hr;
  533. for (DWORD i=0; i<_ifsIndex;i++)
  534. serializableIfsCollection[i] = 0;
  535. _marshalState = UNMARSHALLED;
  536. }
  537. RpcExcept(TRUE)
  538. {
  539. return HRESULT_FROM_WIN32(RpcExceptionCode());
  540. }
  541. RpcEndExcept
  542. //-------------------------------------------------------------------
  543. // Query for requested interface to return
  544. //-------------------------------------------------------------------
  545. if (ppv != NULL)
  546. return QueryInterface(riid, ppv);
  547. else
  548. return S_OK;
  549. }
  550. STDMETHODIMP ActivationProperties::GetMarshalSizeMax(
  551. REFIID riid,
  552. void *pv,
  553. DWORD dwDestContext,
  554. void *pvDestContext,
  555. DWORD mshlflags,
  556. DWORD *pSize)
  557. {
  558. HRESULT hr;
  559. //-------------------------------------------------------------------
  560. // If already know size, return it
  561. //-------------------------------------------------------------------
  562. if (_marshalState == SIZED)
  563. {
  564. *pSize = _size;
  565. return S_OK;
  566. }
  567. else
  568. {
  569. //---------------------------------------------------------------
  570. // First set internal marshalling distance flag
  571. //---------------------------------------------------------------
  572. SetDestCtx(dwDestContext);
  573. if (MARSHALCTX_WITHIN_PROCESS(dwDestContext) &&
  574. (!_fInprocSerializationRequired))
  575. {
  576. _size = 0;
  577. hr = S_OK;
  578. }
  579. else
  580. {
  581. RpcTryExcept
  582. {
  583. //---------------------------------------------------------------
  584. // Create Serializer for serialization
  585. //---------------------------------------------------------------
  586. Serializer ser(_serHeader.destCtx, dwDestContext, _marshalFlags);
  587. hr = GetSize(ser, pSize);
  588. _size = *pSize;
  589. if (!_size)
  590. _fInprocSerializationRequired = FALSE;
  591. }
  592. RpcExcept(TRUE)
  593. {
  594. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  595. }
  596. RpcEndExcept
  597. }
  598. }
  599. if (SUCCEEDED(hr))
  600. {
  601. // Add fixed serializer header size to serialization size
  602. _size += Serializer::GetSize();
  603. *pSize = _size;
  604. _marshalState = SIZED;
  605. }
  606. return hr;
  607. }
  608. inline HRESULT ActivationProperties::GetSize(Serializer &ser, DWORD *pSize)
  609. {
  610. HRESULT hr;
  611. DWORD size = 0;
  612. //-------------------------------------------------------------------
  613. // Get sizes of contained objects
  614. //-------------------------------------------------------------------
  615. for (DWORD i=0; i<_ifsIndex;i++)
  616. {
  617. //---------------------------------------------------------------
  618. // If object was never unserialized then simply use old size
  619. //---------------------------------------------------------------
  620. if ((_unSerialized) && (!serializableIfsCollection[i]))
  621. {
  622. _clsidArray[i] = _unSerHeader.pclsid[i];
  623. _sizeArray[i] = _unSerHeader.pSizes[i];
  624. }
  625. else
  626. {
  627. hr = serializableIfsCollection[i]->GetCLSID(&_clsidArray[i]);
  628. Win4Assert(hr==S_OK);
  629. hr = serializableIfsCollection[i]->GetSize(&ser, &_sizeArray[i]);
  630. if (FAILED(hr))
  631. return hr;
  632. _sizeArray[i] = (_sizeArray[i]+7) & ~7;
  633. }
  634. size += _sizeArray[i];
  635. }
  636. //-------------------------------------------------------------------
  637. // Set up header for serialization and get its size if we need
  638. // to marshal any information(i.e size>0)
  639. //-------------------------------------------------------------------
  640. if (size)
  641. {
  642. _serHeader.cIfs = _ifsIndex;
  643. _serHeader.pSizes = _sizeArray;
  644. _serHeader.pclsid = _clsidArray;
  645. handle_t handle;
  646. hr = ser.GetSizingHandle((void*) &handle);
  647. if (FAILED(hr))
  648. return hr;
  649. _headerSize = CustomHeader_AlignSize(handle, &_serHeader);
  650. MesHandleFree(handle);
  651. _serHeader.headerSize = _headerSize;
  652. size += _headerSize;
  653. }
  654. // return serialization size
  655. _serHeader.totalSize = size;
  656. *pSize = size;
  657. return S_OK;
  658. }
  659. STDMETHODIMP ActivationProperties::GetUnmarshalClass(
  660. REFIID riid,
  661. void *pv,
  662. DWORD dwDestContext,
  663. void *pvDestContext,
  664. DWORD mshlflags,
  665. CLSID *pCid)
  666. {
  667. if (MARSHALCTX_WITHIN_PROCESS(dwDestContext))
  668. *pCid = CLSID_InprocActpropsUnmarshaller;
  669. else
  670. *pCid = _actCLSID;
  671. return S_OK;
  672. }
  673. STDMETHODIMP ActivationProperties::ReleaseMarshalData(IStream *pStm)
  674. {
  675. return E_NOTIMPL;
  676. }
  677. STDMETHODIMP ActivationProperties::DisconnectObject(DWORD dwReserved)
  678. {
  679. return E_NOTIMPL;
  680. }
  681. //---------------------------------------------------------------------------
  682. // Methods from ISerializableParent
  683. //---------------------------------------------------------------------------
  684. //-----------------------------------------------------------------------
  685. // Returns serializer pointing to unserialized data for referenced
  686. // CLSID
  687. //-----------------------------------------------------------------------
  688. STDMETHODIMP ActivationProperties::GetUnserialized(REFCLSID clsid,
  689. void **ppISer,
  690. DWORD *pSize, DWORD *pPos)
  691. {
  692. if (!_unSerialized)
  693. return E_FAIL;
  694. DWORD pos = _unSerHeader.headerSize;
  695. HRESULT hr;
  696. for (DWORD i=0; i<_ifsIndex; i++)
  697. {
  698. if (IsEqualIID(clsid,_unSerHeader.pclsid[i]))
  699. {
  700. hr = _pUnSer->SetPosition(pos);
  701. if (FAILED (hr))
  702. {
  703. return hr;
  704. }
  705. *pSize = _unSerHeader.pSizes[i];
  706. *ppISer = _pUnSer;
  707. *pPos = pos;
  708. return S_OK;
  709. }
  710. pos +=_unSerHeader.pSizes[i];
  711. }
  712. return E_FAIL;
  713. }
  714. //-----------------------------------------------------------------------
  715. // Used to do late unserialization via a QueryInterface
  716. // returns -
  717. // E_NOINTERFACE: implies that this interface can
  718. // never be supported here(even if GetClass
  719. // returns a valid instance).
  720. // Implication is that once a class is
  721. // signalled in the activation stream to
  722. // not be marshalled by setting its size
  723. // to zero, it can never be QI'd again.
  724. // E_FAIL: implies that this interface was not
  725. // part of the serialized packet(but could
  726. // be supported if GetClass succeeds).
  727. //-----------------------------------------------------------------------
  728. inline HRESULT ActivationProperties::UnSerializeCallBack(REFCLSID clsid,
  729. SerializableProperty **ppSer)
  730. {
  731. HRESULT hr;
  732. SerializableProperty *pClass = NULL;
  733. BOOL pClassUsed = FALSE;
  734. Win4Assert(_unSerialized!=0);
  735. //-------------------------------------------------------------------
  736. // Position past header
  737. //-------------------------------------------------------------------
  738. DWORD pos = _unSerHeader.headerSize;
  739. CLSID realclsid;
  740. //-------------------------------------------------------------------
  741. // Check to see if class supported at all
  742. //-------------------------------------------------------------------
  743. BOOL bZeroSizeOk;
  744. if ((hr = GetClass(clsid, &pClass, FALSE, &bZeroSizeOk))==S_OK)
  745. pClass->GetCLSID(&realclsid);
  746. else
  747. return hr;
  748. hr = E_FAIL;
  749. for (DWORD i=0; i<_unSerHeader.cIfs; i++)
  750. {
  751. //---------------------------------------------------------------
  752. // Check if contained objects match requested class ID
  753. // If so then it may or may not be unserialized.
  754. //---------------------------------------------------------------
  755. if (IsEqualIID(realclsid,_unSerHeader.pclsid[i]))
  756. {
  757. RpcTryExcept
  758. {
  759. //-------------------------------------------------------
  760. // If size is zero for a matched object then it is an
  761. // interface that is no longer supported unless we
  762. // are told otherwise
  763. //-------------------------------------------------------
  764. if ((!_unSerHeader.pSizes[i]) && (!bZeroSizeOk))
  765. {
  766. hr = E_NOINTERFACE;
  767. break;
  768. }
  769. //-------------------------------------------------------
  770. // Set position for serializer for unserializing
  771. //-------------------------------------------------------
  772. hr = S_OK;
  773. hr = _pUnSer->SetPosition(pos);
  774. if (FAILED(hr))
  775. {
  776. break;
  777. }
  778. //-------------------------------------------------------
  779. // If unserializing add it to our collection and make it
  780. // a child and return found object.
  781. //-------------------------------------------------------
  782. if (serializableIfsCollection[i] == NULL)
  783. {
  784. SetSerializableIfs(i, pClass);
  785. pClassUsed = TRUE;
  786. if (FAILED(hr = pClass->UnSerialize(_pUnSer)))
  787. {
  788. serializableIfsCollection[i] = NULL;
  789. pClass->SetParent(NULL);
  790. pClassUsed = FALSE;
  791. }
  792. }
  793. else
  794. {
  795. hr = serializableIfsCollection[i]->UnSerialize(_pUnSer);
  796. }
  797. if (ppSer)
  798. *ppSer = serializableIfsCollection[i];
  799. }
  800. RpcExcept(TRUE)
  801. {
  802. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  803. }
  804. RpcEndExcept
  805. //
  806. // E_FAIL is not considered catastrophic by caller
  807. // But this is a catastrophic condition since we could
  808. // not unserialize.
  809. //
  810. if (hr == E_FAIL)
  811. hr = E_UNEXPECTED;
  812. break;
  813. }
  814. //---------------------------------------------------------------
  815. // Increment position for next one
  816. //---------------------------------------------------------------
  817. pos +=_unSerHeader.pSizes[i];
  818. }
  819. if (pClass != NULL && !pClassUsed)
  820. {
  821. ReturnClass (clsid, pClass);
  822. }
  823. return hr;
  824. }
  825. //-----------------------------------------------------------------------
  826. // Do things required to make a child
  827. //-----------------------------------------------------------------------
  828. inline void ActivationProperties::SetSerializableIfs(DWORD index,
  829. SerializableProperty *pSer)
  830. {
  831. serializableIfsCollection[index]= pSer;
  832. pSer->SetParent((ISerializableParent*) this);
  833. pSer->Added();
  834. }
  835. //-----------------------------------------------------------------------
  836. // Add a serializiable object to the collection
  837. //-----------------------------------------------------------------------
  838. inline void ActivationProperties::AddSerializableIfs(SerializableProperty *pSer)
  839. {
  840. if (pSer->IsAdded())
  841. return;
  842. Win4Assert(_ifsIndex < MAX_ACTARRAY_SIZE);
  843. SetSerializableIfs(_ifsIndex, pSer);
  844. _ifsIndex++;
  845. }
  846. //---------------------------------------------------------------------------
  847. // Methods for ActivationPropertiesIn
  848. //---------------------------------------------------------------------------
  849. ActivationPropertiesIn::ActivationPropertiesIn()
  850. {
  851. _customIndex = 0;
  852. _cCustomAct = 0;
  853. _actCLSID=CLSID_ActivationPropertiesIn;
  854. _refCount = 1;
  855. _pinst = NULL;
  856. _pPersist = NULL;
  857. _pContextInfo = NULL;
  858. _pServerLocationInfo = NULL;
  859. _pSecurityInfo = NULL;
  860. _pSpecialProperties = NULL;
  861. _pClassInfo = NULL;
  862. _customActList = NULL;
  863. _delegated = FALSE;
  864. _actOut.SetNotDelete();
  865. _pDip = NULL;
  866. _clientToken = NULL;
  867. _fComplusOnly = FALSE;
  868. _fUseSystemIdentity = FALSE;
  869. _dwInitialContext = 0;
  870. }
  871. ActivationPropertiesIn::~ActivationPropertiesIn()
  872. {
  873. if (_pClassInfo)
  874. {
  875. _pClassInfo->Unlock();
  876. _pClassInfo->Release();
  877. }
  878. }
  879. //-----------------------------------------------------------------------
  880. // Methods from IUnknown
  881. //-----------------------------------------------------------------------
  882. STDMETHODIMP ActivationPropertiesIn::QueryInterface( REFIID riid, LPVOID* ppv)
  883. {
  884. // USE CLSID_ActivationPropertiesIn to get at the real object
  885. // Note that this is a hidden contract to be used by COM only and
  886. // the object is not AddRef'd as an optimization
  887. if (IsEqualIID(riid, CLSID_ActivationPropertiesIn))
  888. {
  889. *ppv = (ActivationPropertiesIn*)this;
  890. return S_OK;
  891. }
  892. else
  893. if (IsEqualIID(riid, IID_IUnknown) ||
  894. IsEqualIID(riid, IID_IActivationPropertiesIn))
  895. *ppv = (IActivationPropertiesIn*)this;
  896. else
  897. if (IsEqualIID(riid, IID_IPrivActivationPropertiesIn))
  898. *ppv = (IPrivActivationPropertiesIn*)this;
  899. else
  900. if (IsEqualIID(riid, IID_IInitActivationPropertiesIn))
  901. *ppv = (IInitActivationPropertiesIn*)this;
  902. else
  903. if (IsEqualIID(riid, IID_IActivationStageInfo))
  904. *ppv = (IActivationStageInfo*)this;
  905. else
  906. *ppv = NULL;
  907. if (*ppv != NULL)
  908. {
  909. AddRef();
  910. return S_OK;
  911. }
  912. return ActivationProperties::QueryInterface(riid, ppv);
  913. }
  914. ULONG ActivationPropertiesIn::AddRef(void)
  915. {
  916. return ActivationProperties::AddRef();
  917. }
  918. ULONG ActivationPropertiesIn::Release(void)
  919. {
  920. ULONG ret=ActivationProperties::Release();
  921. if (ret==0)
  922. {
  923. if (_toDelete)
  924. delete this;
  925. else
  926. if (_fDestruct)
  927. this->ActivationPropertiesIn::~ActivationPropertiesIn();
  928. }
  929. return ret;
  930. }
  931. //---------------------------------------------------------------------------
  932. // Methods from IInitActivationPropertiesIn
  933. //---------------------------------------------------------------------------
  934. STDMETHODIMP ActivationPropertiesIn::SetClsctx (DWORD dwClsCtx)
  935. {
  936. if (dwClsCtx && _pClassInfo)
  937. {
  938. DWORD dwAcceptableClsCtx;
  939. //Note: hack for VB since it cannot specify CLSCTX_REMOTE_SERVER
  940. if (dwClsCtx & CLSCTX_LOCAL_SERVER)
  941. dwClsCtx |= CLSCTX_REMOTE_SERVER;
  942. // Before we filter the specified class context by the class
  943. // info, we remember the original class context.
  944. if (_dwInitialContext == 0)
  945. _dwInitialContext = dwClsCtx;
  946. // Here we figure out the desired ClsCtx
  947. // by anding the one in the catalog with the
  948. // one requested by the user.
  949. // If the GetClassContext()
  950. // returns an error, we just go ahead and
  951. // use the one the user passed.
  952. HRESULT hr = _pClassInfo->GetClassContext( (CLSCTX) dwClsCtx,
  953. (CLSCTX*) &dwAcceptableClsCtx);
  954. // REVIEW: Continue if Get fails?
  955. if (SUCCEEDED(hr))
  956. {
  957. dwClsCtx &= (dwAcceptableClsCtx |
  958. (CLSCTX_PS_DLL | CLSCTX_LOCAL_SERVER));
  959. #ifdef WX86OLE
  960. // The code above filters the acceptable context bits found
  961. // with those supplied by the caller. The x86 context bits
  962. // might have been found and should be allowed. For example
  963. // INPROC_SERVER might have been set and an x86 server found,
  964. // which is valid.
  965. if ( dwAcceptableClsCtx & CLSCTX_INPROC_SERVERX86 )
  966. {
  967. dwClsCtx |= CLSCTX_INPROC_SERVERX86;
  968. }
  969. if ( dwAcceptableClsCtx & CLSCTX_INPROC_HANDLERX86 )
  970. {
  971. dwClsCtx |= CLSCTX_INPROC_HANDLERX86;
  972. }
  973. #endif
  974. }
  975. }
  976. return GetInstantiationInfo()->SetClsctx(dwClsCtx);
  977. }
  978. STDMETHODIMP ActivationPropertiesIn::SetActivationFlags (IN DWORD actvflags)
  979. {
  980. return GetInstantiationInfo()->SetActivationFlags(actvflags);
  981. // The following code was the original implementation by CBiks.
  982. // This code is no longer executes because we delegate above.
  983. //
  984. /*
  985. HRESULT hr;
  986. hr = GetPropertyInfo(IID_IInstantiationInfo, (void**) &_pinst);
  987. if (SUCCEEDED(hr))
  988. {
  989. Win4Assert(_pinst != NULL);
  990. hr = _pinst->SetActivationFlags(actvflags);
  991. }
  992. return hr;
  993. */
  994. }
  995. STDMETHODIMP ActivationPropertiesIn::SetClassInfo (IUnknown* pUnkClassInfo)
  996. {
  997. if (_pClassInfo)
  998. {
  999. _pClassInfo->Unlock();
  1000. _pClassInfo->Release();
  1001. _pClassInfo = NULL;
  1002. }
  1003. // useful and tests minimal usefulness of the object given
  1004. HRESULT hr = pUnkClassInfo->QueryInterface(IID_IComClassInfo,(LPVOID*)&_pClassInfo);
  1005. CLSID *pclsid;
  1006. if (FAILED(hr))
  1007. return hr;
  1008. _pClassInfo->Lock();
  1009. hr = _pClassInfo->GetConfiguredClsid(&pclsid);
  1010. GetInstantiationInfo()->SetClsid(*pclsid);
  1011. if (SUCCEEDED(hr) && _dwInitialContext)
  1012. {
  1013. // Somebody has specifically set the class
  1014. // context on this actprops, but has now changed
  1015. // the IComClassInfo. We need to change our
  1016. // filtered CLSCTX to match the new ClassInfo.
  1017. hr = SetClsctx(_dwInitialContext);
  1018. }
  1019. return hr;
  1020. }
  1021. STDMETHODIMP ActivationPropertiesIn::SetContextInfo (
  1022. IContext* pClientContext,
  1023. IContext* pPrototypeContext)
  1024. {
  1025. HRESULT hr;
  1026. ContextInfo *pactctx= GetContextInfo();
  1027. Win4Assert(pactctx != NULL);
  1028. hr = pactctx->SetClientContext(pClientContext);
  1029. if (hr != S_OK)
  1030. return hr;
  1031. hr = pactctx->SetPrototypeContext(pPrototypeContext);
  1032. return hr;
  1033. }
  1034. STDMETHODIMP ActivationPropertiesIn::SetConstructFromStorage (IStorage* pStorage)
  1035. {
  1036. HRESULT hr;
  1037. GetPersistInfo();
  1038. Win4Assert(_pPersist != NULL);
  1039. // This is an optimization for inproc marshalling. We know
  1040. // that the storage pointer is the only one that requires
  1041. // inproc serialization in the ActivationPropertiesIn object.
  1042. _fInprocSerializationRequired = TRUE;
  1043. return _pPersist->SetStorage(pStorage);
  1044. }
  1045. STDMETHODIMP ActivationPropertiesIn::SetConstructFromFile (WCHAR* wszFileName, DWORD dwMode)
  1046. {
  1047. HRESULT hr;
  1048. GetPersistInfo();
  1049. Win4Assert(_pPersist != NULL);
  1050. return _pPersist->SetFile(wszFileName, dwMode);
  1051. }
  1052. //---------------------------------------------------------------------------
  1053. // Methods for IActivationPropertiesIn
  1054. //---------------------------------------------------------------------------
  1055. STDMETHODIMP ActivationPropertiesIn::GetClsctx(OUT DWORD *pdwClsctx)
  1056. {
  1057. return GetInstantiationInfo()->GetClsctx(pdwClsctx);
  1058. }
  1059. STDMETHODIMP ActivationPropertiesIn::AddRequestedIIDs(IN DWORD cIfs,
  1060. IN IID *pIID)
  1061. {
  1062. return GetInstantiationInfo()->AddRequestedIIDs(cIfs, pIID);
  1063. }
  1064. STDMETHODIMP ActivationPropertiesIn::GetRequestedIIDs(OUT DWORD *pcIfs,
  1065. OUT IID **ppIID)
  1066. {
  1067. return GetInstantiationInfo()->GetRequestedIIDs(pcIfs, ppIID);
  1068. }
  1069. STDMETHODIMP ActivationPropertiesIn::GetActivationID(OUT GUID *pActivationID)
  1070. {
  1071. *pActivationID = GUID_NULL; // currently unused and not supported
  1072. return E_NOTIMPL;
  1073. }
  1074. STDMETHODIMP ActivationPropertiesIn::GetActivationFlags(OUT DWORD *pactvflags)
  1075. {
  1076. return GetInstantiationInfo()->GetActivationFlags(pactvflags);
  1077. // The following code was the original implementation by CBiks.
  1078. // This code is no longer executes because we delegate above.
  1079. //
  1080. /*
  1081. HRESULT hr;
  1082. hr = GetPropertyInfo(IID_IInstantiationInfo, (void**) &_pinst);
  1083. if (SUCCEEDED(hr))
  1084. {
  1085. Win4Assert(_pinst != NULL);
  1086. return _pinst->GetActivationFlags(pactvflags);
  1087. }
  1088. return hr;
  1089. */
  1090. }
  1091. //-----------------------------------------------------------------------
  1092. // The Following 3 routines should be called at the tail end of the
  1093. // activation path to get activation properties for return
  1094. // Only the first one is meant to be pubicly used
  1095. //-----------------------------------------------------------------------
  1096. STDMETHODIMP ActivationPropertiesIn::GetReturnActivationProperties(
  1097. IN IUnknown *pobj,
  1098. OUT IActivationPropertiesOut **ppActOut)
  1099. {
  1100. HRESULT hr;
  1101. *ppActOut = NULL;
  1102. //-------------------------------------------------------------------
  1103. // If no punk then don't return an out object
  1104. //-------------------------------------------------------------------
  1105. if (!pobj)
  1106. {
  1107. return E_FAIL;
  1108. }
  1109. if (_unSerialized)
  1110. hr = GetPropertyInfo(IID_IInstantiationInfo, (void**) &_pinst);
  1111. Win4Assert(_pinst != NULL);
  1112. CLSID clsid;
  1113. hr = _pinst->GetClsid(&clsid);
  1114. Win4Assert(hr == S_OK);
  1115. //-------------------------------------------------------------------
  1116. // Create Return Object
  1117. //-------------------------------------------------------------------
  1118. ActivationPropertiesOut *pout;
  1119. if (!_unSerialized && !_toDelete && !IsBrokenRefCount(&clsid))
  1120. {
  1121. _actOut.Initialize();
  1122. pout = &_actOut;
  1123. }
  1124. else
  1125. {
  1126. pout = new ActivationPropertiesOut(IsBrokenRefCount(&clsid));
  1127. if (pout==NULL)
  1128. return E_OUTOFMEMORY;
  1129. }
  1130. //-------------------------------------------------------------------
  1131. // Set the marshal and dest context flags for marshalling returns
  1132. //-------------------------------------------------------------------
  1133. pout->SetMarshalFlags(_marshalFlags);
  1134. pout->SetDestCtx(_serHeader.destCtx);
  1135. //-------------------------------------------------------------------
  1136. // Check to see if we are handling a persistent instance
  1137. // NOTE: cannot call GetPeristInfo because we need to QI to
  1138. // so that this will only cause this interface to exist
  1139. // if it was ever added to the properties object
  1140. //-------------------------------------------------------------------
  1141. if (_unSerialized)
  1142. hr = GetPropertyInfo(IID_IInstanceInfo, (void**) &_pPersist);
  1143. if (_pPersist)
  1144. {
  1145. hr = LoadPersistentObject(pobj, _pPersist);
  1146. if (FAILED(hr))
  1147. {
  1148. pout->Release();
  1149. return hr;
  1150. }
  1151. }
  1152. //-------------------------------------------------------------------
  1153. // Set COMVERSION of client for marshalling
  1154. //-------------------------------------------------------------------
  1155. Win4Assert(_pinst != NULL);
  1156. COMVERSION *pVersion;
  1157. GetInstantiationInfo()->GetClientCOMVersion(&pVersion);
  1158. pout->SetClientCOMVersion(*pVersion);
  1159. //-------------------------------------------------------------------
  1160. // Get IIDs requested and set them for return
  1161. //-------------------------------------------------------------------
  1162. DWORD cifs;
  1163. IID *pIID;
  1164. hr = _pinst->GetRequestedIIDs(&cifs, &pIID);
  1165. Win4Assert(hr==S_OK);
  1166. hr = pout->SetObjectInterfaces(cifs, pIID, pobj);
  1167. *ppActOut = pout;
  1168. CleanupLocalState();
  1169. return hr;
  1170. }
  1171. STDMETHODIMP ActivationPropertiesIn::PrivGetReturnActivationProperties(
  1172. OUT IPrivActivationPropertiesOut **ppActOut)
  1173. {
  1174. //-------------------------------------------------------------------
  1175. // Create Return Object
  1176. //-------------------------------------------------------------------
  1177. ActivationPropertiesOut *pout = new ActivationPropertiesOut(FALSE /* fBrokenRefCount */ );
  1178. if (pout==NULL)
  1179. return E_OUTOFMEMORY;
  1180. //-------------------------------------------------------------------
  1181. // Set the marshal and dest context flags for marshalling returns
  1182. //-------------------------------------------------------------------
  1183. pout->SetMarshalFlags(_marshalFlags);
  1184. pout->SetDestCtx(_serHeader.destCtx);
  1185. *ppActOut = (IPrivActivationPropertiesOut*) pout;
  1186. CleanupLocalState();
  1187. return S_OK;
  1188. }
  1189. STDMETHODIMP ActivationPropertiesIn::GetReturnActivationProperties(
  1190. ActivationPropertiesOut **ppActOut)
  1191. {
  1192. //-------------------------------------------------------------------
  1193. // Create Return Object
  1194. //-------------------------------------------------------------------
  1195. *ppActOut = new ActivationPropertiesOut(FALSE /* fBrokenRefCount */ );
  1196. if (*ppActOut==NULL)
  1197. return E_OUTOFMEMORY;
  1198. //-------------------------------------------------------------------
  1199. // Set the marshal and dest context flags for marshalling returns
  1200. //-------------------------------------------------------------------
  1201. (*ppActOut)->SetMarshalFlags(_marshalFlags);
  1202. (*ppActOut)->SetDestCtx(_serHeader.destCtx);
  1203. CleanupLocalState();
  1204. return S_OK;
  1205. }
  1206. //-----------------------------------------------------------------------
  1207. // Following two routines are used delegate through a chain of custom
  1208. // activators. When the chain is exhausted, the COM activator for the
  1209. // current stage is invoked.
  1210. //-----------------------------------------------------------------------
  1211. STDMETHODIMP ActivationPropertiesIn::DelegateGetClassObject(
  1212. OUT IActivationPropertiesOut **pActPropsOut)
  1213. {
  1214. Win4Assert(_customIndex <= _cCustomAct && (LONG) _customIndex >= 0);
  1215. _delegated=TRUE;
  1216. if ((_cCustomAct == 0) || (_customIndex == _cCustomAct))
  1217. {
  1218. ISystemActivator *pComAct = GetComActivatorForStage(_stage);
  1219. return pComAct->GetClassObject(this, pActPropsOut);
  1220. }
  1221. _customIndex++;
  1222. // Sajia - Support for partitions.
  1223. // a) See if the activator supports IReplaceClassInfo
  1224. // b) If yes, this is the partition activator.Delegate to it.
  1225. // If the partition activator switches the classinfo,
  1226. // it returns ERROR_RETRY. It will not delegate in this case.
  1227. // Otherwise, it simply delegates down the chain.
  1228. // c) If it returns ERROR_RETRY, call IReplaceClassInfo->GetClassInfo().
  1229. // Switch our class info and return ERROR_RETRY so our caller
  1230. // knows to restart the activation chain.
  1231. //
  1232. IReplaceClassInfo *pReplaceClassInfo = NULL;
  1233. HRESULT hr = _customActList[_customIndex-1]->QueryInterface(IID_IReplaceClassInfo, (void**)&pReplaceClassInfo);
  1234. if (SUCCEEDED(hr))
  1235. {
  1236. Win4Assert(pReplaceClassInfo && "QI Error");
  1237. // Assert that the partition activator is supported only
  1238. // in the SCM and Server Process stage and must be the
  1239. // first activator in the stage.
  1240. Win4Assert((_customIndex == 1) && (_stage == SERVER_MACHINE_STAGE || _stage == SERVER_PROCESS_STAGE || _stage == CLIENT_CONTEXT_STAGE));
  1241. hr = _customActList[_customIndex-1]->GetClassObject(this, pActPropsOut);
  1242. if (ERROR_RETRY == hr)
  1243. {
  1244. CLSID clsid;
  1245. IUnknown *pClassInfo;
  1246. hr = GetClsid(&clsid);
  1247. Win4Assert(SUCCEEDED(hr));
  1248. if (SUCCEEDED(hr))
  1249. {
  1250. hr = pReplaceClassInfo->GetClassInfo(clsid, IID_IUnknown, (void**)&pClassInfo);
  1251. Win4Assert(SUCCEEDED(hr));
  1252. if (SUCCEEDED(hr))
  1253. {
  1254. hr = SetClassInfo(pClassInfo);
  1255. Win4Assert(SUCCEEDED(hr));
  1256. pClassInfo->Release();
  1257. if (SUCCEEDED(hr))
  1258. {
  1259. hr = ERROR_RETRY;
  1260. }
  1261. }
  1262. }
  1263. }
  1264. pReplaceClassInfo->Release();
  1265. return hr;
  1266. }
  1267. else
  1268. return _customActList[_customIndex-1]->GetClassObject(this, pActPropsOut);
  1269. }
  1270. STDMETHODIMP ActivationPropertiesIn::DelegateCreateInstance(
  1271. IN IUnknown *pUnkOuter,
  1272. OUT IActivationPropertiesOut **ppActPropsOut)
  1273. {
  1274. Win4Assert(_customIndex <= _cCustomAct && (LONG) _customIndex >= 0);
  1275. _delegated=TRUE;
  1276. if ((_cCustomAct == 0) || (_customIndex == _cCustomAct))
  1277. {
  1278. ISystemActivator *pComAct = GetComActivatorForStage(_stage);
  1279. return pComAct->CreateInstance(pUnkOuter, this, ppActPropsOut);
  1280. }
  1281. _customIndex++;
  1282. // Sajia - Support for partitions.
  1283. // a) See if the activator supports IReplaceClassInfo
  1284. // b) If yes, this is the partition activator.Delegate to it.
  1285. // If the partition activator switches the classinfo,
  1286. // it returns ERROR_RETRY. It will not delegate in this case.
  1287. // Otherwise, it simply delegates down the chain.
  1288. // c) If it returns ERROR_RETRY, call IReplaceClassInfo->GetClassInfo().
  1289. // Switch our class info and return ERROR_RETRY so our caller
  1290. // knows to restart the activation chain.
  1291. //
  1292. IReplaceClassInfo *pReplaceClassInfo = NULL;
  1293. HRESULT hr = _customActList[_customIndex-1]->QueryInterface(IID_IReplaceClassInfo, (void**)&pReplaceClassInfo);
  1294. if (SUCCEEDED(hr))
  1295. {
  1296. Win4Assert(pReplaceClassInfo && "QI Error");
  1297. // Assert that the partition activator is supported only
  1298. // in the SCM and Server Process stage and must be the
  1299. // first activator in the stage.
  1300. Win4Assert((_customIndex == 1) && (_stage == SERVER_MACHINE_STAGE || _stage == SERVER_PROCESS_STAGE || _stage == CLIENT_CONTEXT_STAGE));
  1301. hr = _customActList[_customIndex-1]->CreateInstance(pUnkOuter, this, ppActPropsOut);
  1302. if (ERROR_RETRY == hr)
  1303. {
  1304. CLSID clsid;
  1305. IUnknown *pClassInfo;
  1306. hr = GetClsid(&clsid);
  1307. Win4Assert(SUCCEEDED(hr));
  1308. if (SUCCEEDED(hr))
  1309. {
  1310. hr = pReplaceClassInfo->GetClassInfo(clsid, IID_IUnknown, (void**)&pClassInfo);
  1311. Win4Assert(SUCCEEDED(hr));
  1312. if (SUCCEEDED(hr))
  1313. {
  1314. hr = SetClassInfo(pClassInfo);
  1315. Win4Assert(SUCCEEDED(hr));
  1316. pClassInfo->Release();
  1317. if (SUCCEEDED(hr))
  1318. {
  1319. hr = ERROR_RETRY;
  1320. }
  1321. }
  1322. }
  1323. }
  1324. pReplaceClassInfo->Release();
  1325. return hr;
  1326. }
  1327. else
  1328. return _customActList[_customIndex-1]->CreateInstance(pUnkOuter, this, ppActPropsOut);
  1329. }
  1330. //-----------------------------------------------------------------------
  1331. // Note that this function could return a NULL Class Factory if an
  1332. // intercepting custom activator returns an object.
  1333. //-----------------------------------------------------------------------
  1334. STDMETHODIMP ActivationPropertiesIn::DelegateCIAndGetCF(
  1335. IN IUnknown *pUnkOuter,
  1336. OUT IActivationPropertiesOut **ppActPropsOut,
  1337. OUT IClassFactory **ppCF)
  1338. {
  1339. if (_stage != SERVER_CONTEXT_STAGE)
  1340. return E_UNEXPECTED;
  1341. HRESULT hr = DelegateCreateInstance(pUnkOuter, ppActPropsOut);
  1342. if (FAILED(hr))
  1343. return hr;
  1344. ActivationPropertiesOut *pActOut;
  1345. hr = (*ppActPropsOut)->QueryInterface(CLSID_ActivationPropertiesOut,
  1346. (void**) &pActOut);
  1347. Win4Assert(SUCCEEDED(hr));
  1348. *ppCF = pActOut->GetCF();
  1349. return S_OK;
  1350. }
  1351. //-----------------------------------------------------------------------
  1352. // Instantiate classes supported by this interfaces given an IID
  1353. //-----------------------------------------------------------------------
  1354. HRESULT ActivationPropertiesIn::GetClass(REFIID iid,
  1355. SerializableProperty **ppSer,
  1356. BOOL forQI,
  1357. BOOL *pbZeroSizeOk)
  1358. {
  1359. if (pbZeroSizeOk)
  1360. *pbZeroSizeOk = FALSE;
  1361. if ((iid == IID_IActivationSecurityInfo) || (iid == IID_ILegacyInfo))
  1362. *ppSer = &_securityInfo;
  1363. else
  1364. if (iid == IID_IServerLocationInfo)
  1365. *ppSer = &_serverLocationInfo;
  1366. else
  1367. if (iid == IID_IInstantiationInfo)
  1368. *ppSer = &_instantiationInfo;
  1369. else
  1370. if (iid == IID_IActivationContextInfo || iid == IID_IPrivActivationContextInfo)
  1371. *ppSer = &_contextInfo;
  1372. else
  1373. if ((!(_delegated && forQI)) && (iid == IID_IInstanceInfo))
  1374. *ppSer = &_instanceInfo;
  1375. else
  1376. if (iid == IID_IScmRequestInfo)
  1377. *ppSer = &_scmRequestInfo;
  1378. else
  1379. if (iid == IID_ISpecialSystemProperties)
  1380. {
  1381. *ppSer = &_specialProperties;
  1382. }
  1383. else
  1384. if (iid == IID_IOpaqueDataInfo)
  1385. {
  1386. *ppSer = new OpaqueDataInfo();
  1387. if (pbZeroSizeOk)
  1388. *pbZeroSizeOk = TRUE;
  1389. }
  1390. else
  1391. return E_NOINTERFACE;
  1392. return S_OK;
  1393. }
  1394. HRESULT ActivationProperties::ReturnClass(REFIID iid, SerializableProperty *pSer)
  1395. {
  1396. if (iid == IID_IOpaqueDataInfo)
  1397. {
  1398. delete (OpaqueDataInfo*) pSer;
  1399. return S_OK;
  1400. }
  1401. return S_FALSE;
  1402. }
  1403. //---------------------------------------------------------------------------
  1404. // Methods from IActivationStageInfo
  1405. //---------------------------------------------------------------------------
  1406. STDMETHODIMP ActivationPropertiesIn::SetStageAndIndex(ACTIVATION_STAGE stage,
  1407. int index)
  1408. {
  1409. _stage = stage;
  1410. _customIndex = index;
  1411. _cCustomAct = 0;
  1412. _customActList = NULL;
  1413. HRESULT hr = E_UNEXPECTED;
  1414. // JSimmons -- 6/30/99 added this assert:
  1415. Win4Assert(_pClassInfo && "SetStageAndIndex called and _pClassInfo is not set");
  1416. if (_pClassInfo)
  1417. {
  1418. hr = _pClassInfo->GetCustomActivatorCount(stage,&_cCustomAct);
  1419. if (SUCCEEDED (hr) && _cCustomAct)
  1420. {
  1421. hr = _pClassInfo->GetCustomActivators(stage,&_customActList);
  1422. if (FAILED (hr))
  1423. {
  1424. _cCustomAct = 0;
  1425. _customActList = NULL;
  1426. }
  1427. }
  1428. }
  1429. return hr;
  1430. }
  1431. STDMETHODIMP ActivationPropertiesIn::UnmarshalInterface(IStream *pStm,REFIID riid,void **ppv)
  1432. {
  1433. HRESULT hr = ActivationProperties::UnmarshalInterface(pStm, riid,ppv);
  1434. if (hr != S_OK)
  1435. return hr;
  1436. CLSID clsid;
  1437. GetInstantiationInfo()->GetClsid(&clsid);
  1438. hr = GetClassInfoFromClsid(clsid, &_pClassInfo);
  1439. if ((hr == S_OK) && _pClassInfo)
  1440. {
  1441. _pClassInfo->Lock();
  1442. }
  1443. _delegated=TRUE; //assume unmarshalling imples that delegation happened
  1444. return hr;
  1445. }
  1446. //---------------------------------------------------------------------------
  1447. // Methods for ActivationPropertiesOut
  1448. //---------------------------------------------------------------------------
  1449. ActivationPropertiesOut::ActivationPropertiesOut(BOOL fBrokenRefCount)
  1450. : _outSer(fBrokenRefCount)
  1451. {
  1452. _pOutSer=0;
  1453. _refCount = 1;
  1454. _actCLSID=CLSID_ActivationPropertiesOut;
  1455. _fBrokenRefCount = fBrokenRefCount;
  1456. _fInprocSerializationRequired = TRUE;
  1457. }
  1458. ActivationPropertiesOut::~ActivationPropertiesOut()
  1459. {
  1460. }
  1461. //---------------------------------------------------------------------------
  1462. // Methods for IUnknown
  1463. //---------------------------------------------------------------------------
  1464. STDMETHODIMP ActivationPropertiesOut::QueryInterface( REFIID riid, LPVOID* ppv)
  1465. {
  1466. // USE CLSID_ActivationPropertiesOut to get at the real object
  1467. // Note that this is a hidden contract to be used by COM only and
  1468. // the object is not AddRef'd as an optimization
  1469. if (IsEqualIID(riid, CLSID_ActivationPropertiesOut))
  1470. {
  1471. *ppv = (ActivationPropertiesOut*)this;
  1472. return S_OK;
  1473. }
  1474. else
  1475. if (IsEqualIID(riid, IID_IUnknown))
  1476. *ppv = (IActivationPropertiesOut*)this;
  1477. else
  1478. if (IsEqualIID(riid, IID_IPrivActivationPropertiesOut))
  1479. *ppv = (IPrivActivationPropertiesOut*)this;
  1480. else
  1481. if (IsEqualIID(riid, IID_IActivationPropertiesOut))
  1482. *ppv = (IActivationPropertiesOut*)this;
  1483. else
  1484. *ppv = NULL;
  1485. if (*ppv != NULL)
  1486. {
  1487. AddRef();
  1488. return S_OK;
  1489. }
  1490. return ActivationProperties::QueryInterface(riid, ppv);
  1491. }
  1492. ULONG ActivationPropertiesOut::AddRef(void)
  1493. {
  1494. return ActivationProperties::AddRef();
  1495. }
  1496. ULONG ActivationPropertiesOut::Release(void)
  1497. {
  1498. ULONG ret=ActivationProperties::Release();
  1499. if (ret==0)
  1500. {
  1501. if (_toDelete)
  1502. delete this;
  1503. else
  1504. if (_fDestruct)
  1505. this->ActivationPropertiesOut::~ActivationPropertiesOut();
  1506. }
  1507. return ret;
  1508. }
  1509. STDMETHODIMP ActivationPropertiesOut::GetActivationID(OUT GUID *pActivationID)
  1510. {
  1511. *pActivationID = GUID_NULL; // currently unused and not supported
  1512. return E_NOTIMPL;
  1513. }
  1514. //-----------------------------------------------------------------------
  1515. // Set Marshalled interface data that are results of activation
  1516. //-----------------------------------------------------------------------
  1517. STDMETHODIMP ActivationPropertiesOut::SetMarshalledResults(
  1518. IN DWORD cIfs,
  1519. IN IID *pIID,
  1520. IN HRESULT *pHr,
  1521. IN MInterfacePointer **ppIntfData)
  1522. {
  1523. if (!_pOutSer)
  1524. {
  1525. _pOutSer = &_outSer;
  1526. AddSerializableIfs((SerializableProperty*) _pOutSer);
  1527. }
  1528. _pOutSer->_info.cIfs = cIfs;
  1529. //
  1530. // Allocate new storage and copy parameters
  1531. //
  1532. _pOutSer->_info.piid = (IID*) ActMemAlloc(sizeof(IID)*cIfs);
  1533. if (_pOutSer->_info.piid == NULL)
  1534. {
  1535. _pOutSer->_info.cIfs=0;
  1536. return E_OUTOFMEMORY;
  1537. }
  1538. _pOutSer->_info.ppIntfData = (MInterfacePointer**)
  1539. ActMemAlloc(sizeof(MInterfacePointer*)*cIfs);
  1540. if (_pOutSer->_info.ppIntfData == NULL)
  1541. {
  1542. _pOutSer->_info.cIfs=0;
  1543. ActMemFree(_pOutSer->_info.piid);
  1544. _pOutSer->_info.piid = NULL;
  1545. return E_OUTOFMEMORY;
  1546. }
  1547. _pOutSer->_info.phresults = (HRESULT*) ActMemAlloc(sizeof(HRESULT)*cIfs);
  1548. if (_pOutSer->_info.phresults == NULL)
  1549. {
  1550. _pOutSer->_info.cIfs=0;
  1551. ActMemFree(_pOutSer->_info.piid);
  1552. _pOutSer->_info.piid = NULL;
  1553. ActMemFree(_pOutSer->_info.ppIntfData);
  1554. _pOutSer->_info.ppIntfData = NULL;
  1555. return E_OUTOFMEMORY;
  1556. }
  1557. for (DWORD i=0; i< cIfs; i++)
  1558. {
  1559. _pOutSer->_info.piid[i] = pIID[i];
  1560. if (ppIntfData[i])
  1561. {
  1562. //
  1563. // Use stream cloning to copy marshalled stuff
  1564. //
  1565. ActivationStream strm((InterfaceData*) ppIntfData[i]);
  1566. ActivationStream *newStrm;
  1567. newStrm = strm.Clone();
  1568. if (newStrm == NULL)
  1569. {
  1570. _pOutSer->_info.cIfs=0;
  1571. ActMemFree(_pOutSer->_info.piid);
  1572. _pOutSer->_info.piid = NULL;
  1573. ActMemFree(_pOutSer->_info.ppIntfData);
  1574. _pOutSer->_info.ppIntfData = NULL;
  1575. ActMemFree(_pOutSer->_info.phresults);
  1576. _pOutSer->_info.phresults = NULL;
  1577. return E_OUTOFMEMORY;
  1578. }
  1579. newStrm->AssignSerializedInterface(
  1580. (InterfaceData**)&_pOutSer->_info.ppIntfData[i]);
  1581. newStrm->Release();
  1582. }
  1583. else
  1584. _pOutSer->_info.ppIntfData[i] = NULL;
  1585. _pOutSer->_info.phresults[i] = pHr[i];
  1586. }
  1587. return S_OK;
  1588. }
  1589. //-----------------------------------------------------------------------
  1590. // Get results of activation in marshalled form
  1591. //-----------------------------------------------------------------------
  1592. STDMETHODIMP ActivationPropertiesOut::GetMarshalledResults(OUT DWORD *pcIfs,
  1593. OUT IID **ppIID,
  1594. OUT HRESULT **ppHr,
  1595. OUT MInterfacePointer ***pppIntfData)
  1596. {
  1597. HRESULT hr;
  1598. //-------------------------------------------------------------------
  1599. // If not unserialized we have to unserialize appropriately
  1600. //-------------------------------------------------------------------
  1601. if ((!_pOutSer) && (_unSerialized))
  1602. {
  1603. if (!SUCCEEDED(hr = UnSerializeCallBack(CLSID_ActivationPropertiesOut,
  1604. (SerializableProperty**)&_pOutSer)))
  1605. return hr;
  1606. }
  1607. Win4Assert(_pOutSer != NULL);
  1608. //-------------------------------------------------------------------
  1609. // If user passed holders, copy into them otherwise allocate
  1610. //-------------------------------------------------------------------
  1611. //-------------------------------------------------------------------
  1612. // First do IIDs
  1613. //-------------------------------------------------------------------
  1614. *pcIfs = _pOutSer->_info.cIfs;
  1615. DWORD i;
  1616. if (*ppIID == NULL)
  1617. *ppIID = _pOutSer->_info.piid;
  1618. else
  1619. {
  1620. IID *pIID = *ppIID;
  1621. for (i=0;i<_pOutSer->_info.cIfs;i++)
  1622. pIID[i] = _pOutSer->_info.piid[i];
  1623. }
  1624. //-------------------------------------------------------------------
  1625. // Do Marshalled results
  1626. //-------------------------------------------------------------------
  1627. if (*pppIntfData == NULL)
  1628. *pppIntfData = _pOutSer->_info.ppIntfData;
  1629. else
  1630. {
  1631. MInterfacePointer **ppIntfData = *pppIntfData;
  1632. for (i=0;i<_pOutSer->_info.cIfs;i++)
  1633. {
  1634. ActivationStream strm((InterfaceData*)_pOutSer->_info.ppIntfData[i]);
  1635. ActivationStream *newStrm;
  1636. newStrm = strm.Clone();
  1637. if (newStrm==NULL)
  1638. return E_OUTOFMEMORY;
  1639. newStrm->AssignSerializedInterface((InterfaceData**)&ppIntfData[i]);
  1640. newStrm->Release();
  1641. }
  1642. }
  1643. //-------------------------------------------------------------------
  1644. // Set error codes and return appropriate one as result
  1645. // Call suceeds if at least one interface exists
  1646. //-------------------------------------------------------------------
  1647. HRESULT rethr = E_NOINTERFACE;
  1648. if (*ppHr == NULL)
  1649. {
  1650. *ppHr = _pOutSer->_info.phresults;
  1651. for (i=0;i<_pOutSer->_info.cIfs;i++)
  1652. if (_pOutSer->_info.phresults[i] == S_OK)
  1653. {
  1654. rethr = S_OK;
  1655. break;
  1656. }
  1657. }
  1658. else
  1659. {
  1660. HRESULT *phr = *ppHr;
  1661. for (i=0;i<_pOutSer->_info.cIfs;i++)
  1662. {
  1663. phr[i] = _pOutSer->_info.phresults[i];
  1664. if (phr[i] == S_OK)
  1665. rethr = S_OK;
  1666. }
  1667. }
  1668. return rethr;
  1669. }
  1670. //-----------------------------------------------------------------------
  1671. // Set results of activation
  1672. //-----------------------------------------------------------------------
  1673. STDMETHODIMP ActivationPropertiesOut::SetObjectInterfaces(
  1674. IN DWORD cIfs,
  1675. IN IID *pIID,
  1676. IN IUnknown *pUnk)
  1677. {
  1678. if (!cIfs)
  1679. return E_FAIL;
  1680. if (!_pOutSer)
  1681. {
  1682. _pOutSer = &_outSer;
  1683. _pOutSer->_pClientCOMVersion = &_clientCOMVersion;
  1684. AddSerializableIfs((SerializableProperty*) _pOutSer);
  1685. }
  1686. _pOutSer->_info.cIfs = cIfs;
  1687. if (cIfs > MAX_ACTARRAY_SIZE)
  1688. {
  1689. _pOutSer->_info.piid = (IID*) ActMemAlloc(sizeof(IID)*cIfs);
  1690. if (_pOutSer->_info.piid == NULL)
  1691. return E_OUTOFMEMORY;
  1692. }
  1693. else
  1694. _pOutSer->_info.piid = _pOutSer->_pIIDs;
  1695. for (DWORD i=0; i< cIfs; i++)
  1696. _pOutSer->_info.piid[i] = pIID[i];
  1697. _pOutSer->_pUnk = pUnk;
  1698. if (!_fBrokenRefCount)
  1699. {
  1700. pUnk->AddRef();
  1701. }
  1702. _pOutSer->_info.phresults = NULL;
  1703. return S_OK;
  1704. }
  1705. //-----------------------------------------------------------------------
  1706. // Get results of activation
  1707. //-----------------------------------------------------------------------
  1708. STDMETHODIMP ActivationPropertiesOut::GetObjectInterface(
  1709. IN REFIID riid,
  1710. IN DWORD actvflags,
  1711. OUT void **ppv)
  1712. {
  1713. //-------------------------------------------------------------------
  1714. // If not unserialized we have to unserialize appropriately
  1715. //-------------------------------------------------------------------
  1716. if (!_pOutSer)
  1717. {
  1718. if (_unSerialized)
  1719. {
  1720. HRESULT rethr;
  1721. rethr = UnSerializeCallBack(CLSID_ActivationPropertiesOut,
  1722. (SerializableProperty**)&_pOutSer);
  1723. if (FAILED(rethr))
  1724. return rethr;
  1725. }
  1726. else
  1727. return E_UNEXPECTED; // We must have a _pOutSer
  1728. }
  1729. Win4Assert(_pOutSer);
  1730. IUnknown *punk = NULL;
  1731. *ppv = NULL;
  1732. BOOL fCountedPunk = FALSE; // Indicates whether we hold a reference
  1733. // to punk and must release it.
  1734. if (!_pOutSer->_ppvObj)
  1735. {
  1736. Win4Assert(_pOutSer->_pUnk!=NULL);
  1737. punk = _pOutSer->_pUnk;
  1738. }
  1739. else
  1740. for (DWORD i=0; i<_pOutSer->_info.cIfs; i++)
  1741. {
  1742. if (IsEqualIID(riid, _pOutSer->_info.piid[i]))
  1743. {
  1744. _pOutSer->UnmarshalAtIndex(i);
  1745. if (_pOutSer->_info.phresults[i] == S_OK)
  1746. {
  1747. _fInprocSerializationRequired = TRUE;
  1748. punk = (IUnknown*) _pOutSer->_ppvObj[i];
  1749. *ppv = punk;
  1750. punk->AddRef();
  1751. return S_OK;
  1752. }
  1753. }
  1754. }
  1755. if (!punk)
  1756. {
  1757. if (!IsEqualIID(IID_IUnknown, riid))
  1758. {
  1759. // If we get a punk back here, it will be counted, so we
  1760. // must release it.
  1761. HRESULT hr = GetObjectInterface(IID_IUnknown,
  1762. NULL,
  1763. (void**) &punk);
  1764. if (FAILED(hr))
  1765. punk = NULL;
  1766. else
  1767. fCountedPunk = TRUE;
  1768. }
  1769. else
  1770. for (DWORD i=0; i<_pOutSer->_info.cIfs; i++)
  1771. {
  1772. _pOutSer->UnmarshalAtIndex(i);
  1773. if (_pOutSer->_info.phresults[i] == S_OK)
  1774. {
  1775. _fInprocSerializationRequired = TRUE;
  1776. punk = (IUnknown*) _pOutSer->_ppvObj[i];
  1777. }
  1778. }
  1779. }
  1780. if (punk)
  1781. {
  1782. // If we're being called by x86 code and the IP is x86 then set the
  1783. // OleStubInvoked flag to allow MapIFacePtr() to thunk unknown IP
  1784. // return values as -1 because we're just returning this to x86
  1785. // code anyway.
  1786. #ifdef WX86OLE
  1787. if ( (actvflags & ACTVFLAGS_WX86_CALLER) && gcwx86.IsN2XProxy(punk) )
  1788. {
  1789. gcwx86.SetStubInvokeFlag((UCHAR)-1);
  1790. }
  1791. #endif
  1792. HRESULT hr = punk->QueryInterface(riid, ppv);
  1793. // If we hold a reference on the punk, release it.
  1794. if (fCountedPunk)
  1795. punk->Release();
  1796. return hr;
  1797. }
  1798. else
  1799. return E_NOINTERFACE;
  1800. }
  1801. //-----------------------------------------------------------------------
  1802. // Get results of activation
  1803. //-----------------------------------------------------------------------
  1804. STDMETHODIMP ActivationPropertiesOut::GetObjectInterfaces(
  1805. IN DWORD cIfs,
  1806. IN DWORD actvflags,
  1807. IN MULTI_QI *pMultiQi)
  1808. {
  1809. HRESULT rethr;
  1810. //-------------------------------------------------------------------
  1811. // If not unserialized we have to unserialize appropriately
  1812. //-------------------------------------------------------------------
  1813. if (!_pOutSer)
  1814. {
  1815. if (_unSerialized)
  1816. {
  1817. rethr = UnSerializeCallBack(CLSID_ActivationPropertiesOut,
  1818. (SerializableProperty**)&_pOutSer);
  1819. if (FAILED(rethr))
  1820. return rethr;
  1821. }
  1822. else
  1823. return E_UNEXPECTED; // We must have a _pOutSer
  1824. }
  1825. Win4Assert(_pOutSer);
  1826. rethr = E_NOINTERFACE;
  1827. //-------------------------------------------------------------------
  1828. // Either Interfaces already unmarshalled or marshalling never
  1829. // took place.
  1830. // Set error codes and return appropriate one as result
  1831. //-------------------------------------------------------------------
  1832. for (DWORD i=0; i<cIfs; i++)
  1833. {
  1834. //---------------------------------------------------------------
  1835. // If no umarshalled result then we have to have a pUnk
  1836. //---------------------------------------------------------------
  1837. if (!_pOutSer->_ppvObj)
  1838. {
  1839. Win4Assert(_pOutSer->_pUnk!=NULL);
  1840. if (_fBrokenRefCount && (i == 0))
  1841. {
  1842. pMultiQi[i].pItf = _pOutSer->_pUnk;
  1843. pMultiQi[i].hr = S_OK;
  1844. }
  1845. else
  1846. {
  1847. #ifdef WX86OLE
  1848. // If we're being called by x86 code and the IP is x86 thenset the
  1849. // OleStubInvoked flag to allow MapIFacePtr() to thunk unknown IP
  1850. // return values as -1 because we're just returning this tox86
  1851. // code anyway.
  1852. if ( (actvflags & ACTVFLAGS_WX86_CALLER) && gcwx86.IsN2XProxy(_pOutSer->_pUnk) )
  1853. {
  1854. gcwx86.SetStubInvokeFlag((UCHAR)-1);
  1855. }
  1856. #endif
  1857. pMultiQi[i].hr =
  1858. _pOutSer->_pUnk->QueryInterface(*pMultiQi[i].pIID,
  1859. (void**) &pMultiQi[i].pItf);
  1860. }
  1861. }
  1862. else
  1863. //---------------------------------------------------------------
  1864. // If IIDs don't match then we're inefficient(order n-square)
  1865. // anyway so call to get a single interface.
  1866. //---------------------------------------------------------------
  1867. if ((_pOutSer->_info.piid[i] != *pMultiQi[i].pIID)||
  1868. (_pOutSer->_info.ppIntfData[i] == NULL))
  1869. {
  1870. pMultiQi[i].hr = GetObjectInterface(*pMultiQi[i].pIID,
  1871. actvflags,
  1872. (void**)&pMultiQi[i].pItf);
  1873. }
  1874. else
  1875. //---------------------------------------------------------------
  1876. // Common case where we are returning originally requested
  1877. // IIDs after unmarshalling.
  1878. //---------------------------------------------------------------
  1879. {
  1880. Win4Assert(!_fBrokenRefCount);
  1881. Win4Assert(_outSer._info.ppIntfData != NULL);
  1882. _pOutSer->UnmarshalAtIndex(i);
  1883. _fInprocSerializationRequired = TRUE;
  1884. pMultiQi[i].pItf = (IUnknown*) _pOutSer->_ppvObj[i];
  1885. pMultiQi[i].hr = _pOutSer->_info.phresults[i];
  1886. if (pMultiQi[i].hr == S_OK)
  1887. ((IUnknown*)_pOutSer->_ppvObj[i])->AddRef();
  1888. }
  1889. //---------------------------------------------------------------
  1890. // Call suceeds if at least one interface exists
  1891. //---------------------------------------------------------------
  1892. if (rethr != S_OK)
  1893. rethr = pMultiQi[i].hr;
  1894. }
  1895. return rethr;
  1896. }
  1897. //-----------------------------------------------------------------------
  1898. // Removes requested IIDs: to be used by custom activators
  1899. // REVIEW: Longer term, having a refcount on the IIDs may make code
  1900. // more readable and could be more efficient all round.
  1901. // However, since this method can add on to existing scheme
  1902. // without change we will punt refcounting IIDs for now.
  1903. // However, also issue of Marshalling n-times at source vs
  1904. // marshalling once at source and n-1 times in b/w should be
  1905. // considered as a tradeoff.
  1906. // Also if something is unmarshallable in an intermediate
  1907. // stage but activation does'nt fail, all is not lost.
  1908. //-----------------------------------------------------------------------
  1909. STDMETHODIMP ActivationPropertiesOut::RemoveRequestedIIDs(
  1910. IN DWORD cIfs,
  1911. IN IID *pIID)
  1912. {
  1913. //-------------------------------------------------------------------
  1914. // If not unserialized we have to unserialize appropriately
  1915. //-------------------------------------------------------------------
  1916. if (!_pOutSer)
  1917. {
  1918. if (!_unSerialized)
  1919. return E_INVALIDARG;
  1920. if (UnSerializeCallBack(CLSID_ActivationPropertiesOut,
  1921. (SerializableProperty**)&_pOutSer)!= S_OK)
  1922. return E_FAIL;
  1923. Win4Assert(_pOutSer != NULL);
  1924. }
  1925. //
  1926. //Assume that we never remove originally requested ones
  1927. //
  1928. if ((cIfs > _pOutSer->_info.cIfs) || (cIfs == 0))
  1929. return E_INVALIDARG;
  1930. LONG i,j;
  1931. DWORD dec = 0;
  1932. //
  1933. //First try to do it efficiently assuming
  1934. //that we always added to end
  1935. //
  1936. for (i=_pOutSer->_info.cIfs-1; i>=0 && cIfs; i--)
  1937. {
  1938. if (_pOutSer->_info.piid[i]==pIID[cIfs-1])
  1939. {
  1940. //
  1941. //If we still have interface data then make sure
  1942. //that we give to duplicate entry if it exists and does'nt
  1943. //have one. Otherwise free it
  1944. //
  1945. if (_pOutSer->_info.ppIntfData)
  1946. {
  1947. if (_pOutSer->_info.ppIntfData[i])
  1948. {
  1949. for (j=0;j<i;j++)
  1950. {
  1951. if ((_pOutSer->_info.piid[i]==_pOutSer->_info.piid[j]) &&
  1952. (_pOutSer->_info.ppIntfData[j] == NULL))
  1953. {
  1954. _pOutSer->_info.ppIntfData[j] =
  1955. _pOutSer->_info.ppIntfData[i];
  1956. _pOutSer->_info.ppIntfData[i] = NULL;
  1957. _pOutSer->_info.phresults[j] =
  1958. _pOutSer->_info.phresults[i];
  1959. Win4Assert(_pOutSer->_info.phresults[j]==S_OK);
  1960. if (_pOutSer->_ppvObj && _pOutSer->_ppvObj[j])
  1961. {
  1962. ((IUnknown*)_pOutSer->_ppvObj[j])->Release();
  1963. _pOutSer->_ppvObj[j] = NULL;
  1964. }
  1965. }
  1966. }
  1967. // If we did'nt give it away release it
  1968. if (_pOutSer->_info.ppIntfData[i])
  1969. {
  1970. ReleaseIFD(_pOutSer->_info.ppIntfData[i]);
  1971. ActMemFree(_pOutSer->_info.ppIntfData[i]);
  1972. _pOutSer->_info.ppIntfData[i] = NULL;
  1973. }
  1974. }
  1975. else
  1976. // Release Unmarshalled object
  1977. if (_pOutSer->_ppvObj && _pOutSer->_ppvObj[i])
  1978. {
  1979. ((IUnknown*)_pOutSer->_ppvObj[i])->Release();
  1980. _pOutSer->_ppvObj[i] = NULL;
  1981. }
  1982. }
  1983. _pOutSer->_info.cIfs--;
  1984. cIfs--;
  1985. dec++;
  1986. }
  1987. else
  1988. break;
  1989. }
  1990. //
  1991. //Do inefficiently if we still have leftover IIDs
  1992. //
  1993. if (cIfs)
  1994. {
  1995. IID *newIIDs=NULL;
  1996. MInterfacePointer **newIFD=NULL;
  1997. void **newppv = NULL;
  1998. HRESULT *newhr=NULL;
  1999. BOOL *pFound = (BOOL*) ActMemAlloc(sizeof(BOOL) * cIfs);
  2000. if (pFound == NULL)
  2001. return E_OUTOFMEMORY;
  2002. DWORD newLen = _pOutSer->_info.cIfs-cIfs;
  2003. //
  2004. // Allocate storage for new stuff
  2005. //
  2006. if (newLen)
  2007. {
  2008. newIIDs = (IID*) ActMemAlloc(sizeof(IID)*newLen);
  2009. if (_marshalState == UNMARSHALLED)
  2010. {
  2011. newIFD = (MInterfacePointer**)
  2012. ActMemAlloc(sizeof(MInterfacePointer*)*
  2013. newLen);
  2014. newppv = (void**) ActMemAlloc(sizeof(IUnknown*)*newLen);
  2015. newhr = (HRESULT*) ActMemAlloc(sizeof(HRESULT)*newLen);
  2016. if ((newIIDs==NULL) || (newppv==NULL) ||
  2017. (newIFD==NULL) || (newhr == NULL))
  2018. {
  2019. ActMemFree(newppv);
  2020. ActMemFree(newIIDs);
  2021. ActMemFree(newIFD);
  2022. ActMemFree(newhr);
  2023. ActMemFree(pFound);
  2024. return E_OUTOFMEMORY;
  2025. }
  2026. }
  2027. }
  2028. for (i=0;i<(LONG)cIfs;i++)
  2029. pFound[i] = FALSE;
  2030. DWORD newIndex=0;
  2031. //
  2032. // Loop trying to establish new arrays
  2033. //
  2034. for (i=0;i<(LONG)_pOutSer->_info.cIfs;i++)
  2035. {
  2036. BOOL found=FALSE;
  2037. for (j=0;j<(LONG)cIfs;j++)
  2038. if (!pFound[j])
  2039. {
  2040. if (_pOutSer->_info.piid[i] == pIID[j])
  2041. {
  2042. found = TRUE;
  2043. pFound[j] = TRUE;
  2044. if ((_marshalState == UNMARSHALLED) &&
  2045. (SUCCEEDED(_pOutSer->_info.phresults[i])))
  2046. {
  2047. if (_pOutSer->_info.ppIntfData[i])
  2048. {
  2049. ReleaseIFD(_pOutSer->_info.ppIntfData[i]);
  2050. ActMemFree(_pOutSer->_info.ppIntfData[i]);
  2051. _pOutSer->_info.ppIntfData[i] = NULL;
  2052. }
  2053. else
  2054. if (_pOutSer->_ppvObj && _pOutSer->_ppvObj[i])
  2055. {
  2056. ((IUnknown*)_pOutSer->_ppvObj[i])->Release();
  2057. _pOutSer->_ppvObj[i] = NULL;
  2058. }
  2059. }
  2060. break;
  2061. }
  2062. }
  2063. // If this was'nt part of passed in array we need to
  2064. // keep it
  2065. if ((!found) && newLen)
  2066. {
  2067. newIIDs[newIndex] = _pOutSer->_info.piid[i];
  2068. if (_marshalState == UNMARSHALLED)
  2069. {
  2070. newIFD[newIndex] = _pOutSer->_info.ppIntfData[i];
  2071. newppv[newIndex] = _pOutSer->_ppvObj[i];
  2072. newhr[newIndex] = _pOutSer->_info.phresults[i];
  2073. }
  2074. newIndex++;
  2075. }
  2076. }
  2077. #if 0 //Assume good behaviour since implementing
  2078. //This failure case would require more changes
  2079. //than necessary for a failure that should'nt happen
  2080. for (i=0;i<cIfs;i++)
  2081. if (!pFound[i])
  2082. {
  2083. ActMemFree(pFound);
  2084. ActMemFree(newIIDs);
  2085. ActMemFree(newIFD);
  2086. ActMemFree(newppv);
  2087. ActMemFree(newhr);
  2088. _pOutSer->_info.cIfs += dec; // this will not work
  2089. // unless we preserve
  2090. // _ppvObj[k] till here
  2091. return E_INVALIDARG;
  2092. }
  2093. #endif
  2094. Win4Assert(newIndex == newLen);
  2095. ActMemFree(pFound);
  2096. //
  2097. //Free old ones and set new ones
  2098. //
  2099. _pOutSer->_info.cIfs = newLen;
  2100. if (_pOutSer->_info.piid != _pOutSer->_pIIDs)
  2101. ActMemFree(_pOutSer->_info.piid);
  2102. _pOutSer->_info.piid = newIIDs;
  2103. if (_marshalState == UNMARSHALLED)
  2104. {
  2105. ActMemFree(_pOutSer->_info.ppIntfData);
  2106. _pOutSer->_info.ppIntfData = newIFD;
  2107. ActMemFree(_pOutSer->_ppvObj);
  2108. _pOutSer->_ppvObj = newppv;
  2109. ActMemFree(_pOutSer->_info.phresults);
  2110. _pOutSer->_info.phresults = newhr;
  2111. }
  2112. }
  2113. return S_OK;
  2114. }
  2115. //-----------------------------------------------------------------------
  2116. // Get classes supported by this interfaces given an IID
  2117. //-----------------------------------------------------------------------
  2118. HRESULT ActivationPropertiesOut::GetClass(REFIID iid,
  2119. SerializableProperty **ppSer,
  2120. BOOL forQI,
  2121. BOOL *pbZeroSizeOk)
  2122. {
  2123. if (pbZeroSizeOk)
  2124. *pbZeroSizeOk = FALSE;
  2125. if (iid == CLSID_ActivationPropertiesOut)
  2126. *ppSer = &_outSer;
  2127. else
  2128. if (iid == IID_IScmReplyInfo)
  2129. *ppSer = &_scmReplyInfo;
  2130. else
  2131. if (iid == IID_IOpaqueDataInfo)
  2132. {
  2133. *ppSer = new OpaqueDataInfo();
  2134. if (pbZeroSizeOk)
  2135. *pbZeroSizeOk = TRUE;
  2136. }
  2137. else
  2138. return E_NOINTERFACE;
  2139. return S_OK;
  2140. }
  2141. //---------------------------------------------------------------------------
  2142. // Methods for ActivationPropertiesOut::OutSerializer
  2143. //---------------------------------------------------------------------------
  2144. ActivationPropertiesOut::OutSerializer::OutSerializer(BOOL fBrokenRefCount)
  2145. {
  2146. memset(&_info, 0, sizeof(PropsOutInfo));
  2147. _ppvObj = NULL;
  2148. _unSerialized=FALSE;
  2149. _pUnk = NULL;
  2150. _parent = NULL;
  2151. _fBrokenRefCount = fBrokenRefCount;
  2152. _fToReleaseIFD = FALSE;
  2153. }
  2154. ActivationPropertiesOut::OutSerializer::~OutSerializer()
  2155. {
  2156. //-------------------------------------------------------------------
  2157. // Free marshalled data
  2158. //-------------------------------------------------------------------
  2159. if (_info.ppIntfData)
  2160. {
  2161. for (DWORD i=0;i<_info.cIfs;i++)
  2162. {
  2163. if ((_info.ppIntfData[i]) && (_fToReleaseIFD))
  2164. ReleaseIFD(_info.ppIntfData[i]);
  2165. ActMemFree(_info.ppIntfData[i]);
  2166. if (_ppvObj && _ppvObj[i])
  2167. ((IUnknown*)_ppvObj[i])->Release();
  2168. }
  2169. ActMemFree(_info.ppIntfData);
  2170. ActMemFree(_ppvObj);
  2171. }
  2172. ActMemFree(_info.phresults);
  2173. if (_info.piid != _pIIDs)
  2174. ActMemFree(_info.piid);
  2175. if (_pUnk && !_fBrokenRefCount)
  2176. {
  2177. _pUnk->Release();
  2178. }
  2179. }
  2180. inline void ActivationPropertiesOut::OutSerializer::UnmarshalAtIndex(DWORD index)
  2181. {
  2182. InitMarshalling();
  2183. Win4Assert(_info.ppIntfData != NULL);
  2184. if (_info.ppIntfData[index] && (_info.phresults[index] == S_OK))
  2185. {
  2186. ActivationStream strm((InterfaceData*)_info.ppIntfData[index]);
  2187. if (IsInterfaceImplementedByProxy(_info.piid[index]))
  2188. {
  2189. IUnknown* pUnk = NULL;
  2190. HRESULT hr;
  2191. if (pfnCoUnmarshalInterface)
  2192. {
  2193. hr = pfnCoUnmarshalInterface(&strm, IID_IUnknown, (void**) &pUnk);
  2194. }
  2195. else
  2196. {
  2197. hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
  2198. }
  2199. if (SUCCEEDED(hr))
  2200. {
  2201. _info.phresults[index] = pUnk->QueryInterface (_info.piid[index], &_ppvObj[index]);
  2202. pUnk->Release();
  2203. }
  2204. else
  2205. {
  2206. _info.phresults[index] = hr;
  2207. _ppvObj[index] = (void*) pUnk;
  2208. }
  2209. }
  2210. else
  2211. {
  2212. if (pfnCoUnmarshalInterface)
  2213. {
  2214. _info.phresults[index] = pfnCoUnmarshalInterface(&strm, _info.piid[index], &_ppvObj[index]);
  2215. }
  2216. else
  2217. {
  2218. _info.phresults[index] = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
  2219. }
  2220. }
  2221. if (_info.phresults[index] != S_OK)
  2222. _ppvObj[index] = NULL;
  2223. ActMemFree(_info.ppIntfData[index]);
  2224. _info.ppIntfData[index] = NULL;
  2225. }
  2226. }
  2227. //---------------------------------------------------------------------------
  2228. // Methods from IUnknown
  2229. //---------------------------------------------------------------------------
  2230. STDMETHODIMP ActivationPropertiesOut::OutSerializer::QueryInterface( REFIID riid, LPVOID* ppvObj)
  2231. {
  2232. if (_parent)
  2233. return _parent->QueryInterface(riid, ppvObj);
  2234. else
  2235. return SerializableQueryInterface(riid, ppvObj);
  2236. }
  2237. STDMETHODIMP ActivationPropertiesOut::OutSerializer::SerializableQueryInterface( REFIID riid, LPVOID* ppvObj)
  2238. {
  2239. *ppvObj = NULL;
  2240. return E_NOINTERFACE;
  2241. }
  2242. ULONG ActivationPropertiesOut::OutSerializer::AddRef(void)
  2243. {
  2244. if (_parent)
  2245. return _parent->AddRef();
  2246. return 1;
  2247. }
  2248. ULONG ActivationPropertiesOut::OutSerializer::Release(void)
  2249. {
  2250. if (_parent)
  2251. return _parent->Release();
  2252. return 0;
  2253. }
  2254. //---------------------------------------------------------------------------
  2255. // Methods from ISerializable
  2256. //---------------------------------------------------------------------------
  2257. STDMETHODIMP ActivationPropertiesOut::OutSerializer::Serialize(void *pv)
  2258. {
  2259. HRESULT hr;
  2260. Serializer *pSer = (Serializer*) pv;
  2261. //-------------------------------------------------------------------
  2262. // Encode this object
  2263. //-------------------------------------------------------------------
  2264. handle_t handle;
  2265. hr = pSer->GetSerializationHandle((void*) &handle);
  2266. PropsOutInfo_Encode(handle, &_info);
  2267. return S_OK;
  2268. }
  2269. STDMETHODIMP ActivationPropertiesOut::OutSerializer::UnSerialize(void *pv)
  2270. {
  2271. Serializer *pSer = (Serializer*) pv;
  2272. //-------------------------------------------------------------------
  2273. // If not unserialized then read header
  2274. //-------------------------------------------------------------------
  2275. if (!_unSerialized)
  2276. {
  2277. handle_t handle;
  2278. pSer->GetSerializationHandle((void*) &handle);
  2279. if (_info.piid)
  2280. ActMemFree(_info.piid);
  2281. _info.piid = 0;
  2282. if (_info.phresults)
  2283. ActMemFree(_info.phresults);
  2284. _info.phresults = 0;
  2285. PropsOutInfo_Decode(handle, &_info);
  2286. if (_info.ppIntfData)
  2287. {
  2288. Win4Assert(_info.cIfs != 0);
  2289. _ppvObj = (void**) ActMemAlloc(sizeof(IUnknown*)*_info.cIfs);
  2290. if (_ppvObj == NULL)
  2291. return E_OUTOFMEMORY;
  2292. for (DWORD i=0; i<_info.cIfs; i++)
  2293. _ppvObj[i] = NULL;
  2294. }
  2295. else
  2296. _ppvObj = NULL;
  2297. }
  2298. return S_OK;
  2299. }
  2300. STDMETHODIMP ActivationPropertiesOut::OutSerializer::GetSize(IN void *pv, OUT DWORD *pdwSize)
  2301. {
  2302. Serializer *pSer = (Serializer*) pv;
  2303. //-------------------------------------------------------------------
  2304. // Need to marshal interfaces to calculate size
  2305. //-------------------------------------------------------------------
  2306. DWORD dwMaxDestCtx;
  2307. BOOL firstMarshal;
  2308. DWORD i;
  2309. HRESULT hr;
  2310. InitMarshalling();
  2311. pSer->GetMaxDestCtx(&dwMaxDestCtx);
  2312. if (!_info.cIfs)
  2313. goto EncodeOut;
  2314. if (_info.ppIntfData == NULL)
  2315. {
  2316. _info.ppIntfData = (MInterfacePointer**)
  2317. ActMemAlloc(sizeof(MInterfacePointer*)
  2318. * _info.cIfs);
  2319. if (_info.ppIntfData == NULL)
  2320. return E_OUTOFMEMORY;
  2321. for (DWORD i=0; i< _info.cIfs; i++)
  2322. _info.ppIntfData[i] = NULL;
  2323. Win4Assert(_info.phresults == NULL);
  2324. _info.phresults = (HRESULT *)
  2325. ActMemAlloc(sizeof(HRESULT)*_info.cIfs);
  2326. if (_info.phresults == NULL)
  2327. {
  2328. ActMemFree(_info.ppIntfData);
  2329. _info.ppIntfData=NULL;
  2330. return E_OUTOFMEMORY;
  2331. }
  2332. firstMarshal = TRUE;
  2333. }
  2334. else
  2335. firstMarshal = FALSE;
  2336. for (i=0; i< _info.cIfs; i++)
  2337. {
  2338. if ((!firstMarshal) &&
  2339. ((_info.ppIntfData[i]) ||
  2340. (FAILED(_info.phresults[i]))))
  2341. continue;
  2342. // Stream to put marshaled interface in
  2343. ActivationStream xrpc;
  2344. DWORD dwMarshalFlags;
  2345. pSer->GetMarshalFlags(&dwMarshalFlags);
  2346. IUnknown *punk;
  2347. if (firstMarshal)
  2348. punk = _pUnk;
  2349. else
  2350. punk = (IUnknown*) _ppvObj[i];
  2351. Win4Assert(punk != NULL);
  2352. void *pvDestCtx = NULL;
  2353. if (dwMaxDestCtx == MSHCTX_DIFFERENTMACHINE)
  2354. {
  2355. pvDestCtx = GetDestCtxPtr(_pClientCOMVersion);
  2356. if (pvDestCtx == NULL)
  2357. {
  2358. ActMemFree(_info.ppIntfData);
  2359. _info.ppIntfData=NULL;
  2360. ActMemFree(_info.phresults);
  2361. _info.phresults = NULL;
  2362. return E_OUTOFMEMORY;
  2363. }
  2364. }
  2365. if (pfnCoMarshalInterface)
  2366. {
  2367. if (IsInterfaceImplementedByProxy(_info.piid[i]))
  2368. {
  2369. hr = pfnCoMarshalInterface(&xrpc,
  2370. IID_IUnknown,
  2371. punk,
  2372. dwMaxDestCtx,
  2373. pvDestCtx,
  2374. dwMarshalFlags);
  2375. }
  2376. else
  2377. {
  2378. hr = pfnCoMarshalInterface(&xrpc,
  2379. _info.piid[i],
  2380. punk,
  2381. dwMaxDestCtx,
  2382. pvDestCtx,
  2383. dwMarshalFlags);
  2384. }
  2385. }
  2386. else
  2387. {
  2388. hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
  2389. }
  2390. if (pvDestCtx != NULL)
  2391. {
  2392. delete pvDestCtx;
  2393. pvDestCtx = NULL;
  2394. }
  2395. _info.phresults[i] = hr;
  2396. if (SUCCEEDED(hr))
  2397. {
  2398. xrpc.AssignSerializedInterface(
  2399. (InterfaceData**)&_info.ppIntfData[i]);
  2400. }
  2401. else
  2402. {
  2403. _info.ppIntfData[i] = NULL;
  2404. // If MSHLFLAGS_NOTIFYACTIVATION is set then
  2405. // it is an error path in the LocalServer case
  2406. // (CobjServer) and it is possible for the server
  2407. // to linger around forever unless the LockServer
  2408. // api is toggled on the class factory
  2409. if (dwMarshalFlags & MSHLFLAGS_NOTIFYACTIVATION)
  2410. {
  2411. Win4Assert(_info.cIfs == 1);
  2412. IClassFactory *pcf;
  2413. BOOL fToRelease;
  2414. if (_info.piid[0] != IID_IClassFactory)
  2415. {
  2416. HRESULT hr2;
  2417. hr2 = punk->QueryInterface(IID_IClassFactory,
  2418. (void**) &pcf);
  2419. if (FAILED(hr2))
  2420. pcf = NULL;
  2421. fToRelease = TRUE;
  2422. }
  2423. else
  2424. {
  2425. pcf = (IClassFactory*)punk;
  2426. fToRelease = FALSE;
  2427. }
  2428. if (pcf)
  2429. {
  2430. pcf->LockServer(TRUE);
  2431. pcf->LockServer(FALSE);
  2432. if (fToRelease)
  2433. pcf->Release();
  2434. }
  2435. }
  2436. }
  2437. }
  2438. EncodeOut:
  2439. DWORD dwCurrDestCtx;
  2440. pSer->GetCurrDestCtx(&dwCurrDestCtx);
  2441. // If marshalling within process, set up as though unmarshalled
  2442. if (MARSHALCTX_WITHIN_PROCESS(dwCurrDestCtx))
  2443. {
  2444. if (_info.ppIntfData)
  2445. {
  2446. Win4Assert(_info.cIfs != 0);
  2447. if (!_ppvObj)
  2448. _ppvObj = (void**) ActMemAlloc(sizeof(IUnknown*)*_info.cIfs);
  2449. if (_ppvObj == NULL)
  2450. {
  2451. ActMemFree(_info.ppIntfData);
  2452. _info.ppIntfData=NULL;
  2453. ActMemFree(_info.phresults);
  2454. _info.phresults = NULL;
  2455. return E_OUTOFMEMORY;
  2456. }
  2457. for (DWORD i=0; i<_info.cIfs; i++)
  2458. _ppvObj[i] = NULL;
  2459. // Release punk since destructor won't get called
  2460. if (_pUnk)
  2461. {
  2462. if (!_fBrokenRefCount)
  2463. _pUnk->Release();
  2464. _pUnk = NULL;
  2465. }
  2466. }
  2467. else
  2468. _ppvObj = NULL;
  2469. _size = 0;
  2470. }
  2471. else
  2472. {
  2473. _fToReleaseIFD = FALSE;
  2474. //-------------------------------------------------------------------
  2475. // Get Header size
  2476. //-------------------------------------------------------------------
  2477. handle_t handle;
  2478. hr = pSer->GetSizingHandle((void*) &handle);
  2479. if (FAILED(hr))
  2480. return hr;
  2481. _size = PropsOutInfo_AlignSize(handle, &_info);
  2482. MesHandleFree(handle);
  2483. }
  2484. *pdwSize = _size;
  2485. return S_OK;
  2486. }
  2487. STDMETHODIMP ActivationPropertiesOut::OutSerializer::GetCLSID(OUT CLSID *pclsid)
  2488. {
  2489. *pclsid = CLSID_ActivationPropertiesOut;
  2490. return S_OK;
  2491. }
  2492. //---------------------------------------------------------------------------
  2493. //
  2494. // Function: ActPropsMarshalHelper
  2495. //
  2496. // Synopsis: Makes an "on the wire" representation of an ActProps
  2497. //
  2498. // Arguments: [pact] - interface to marshal
  2499. // [riid] - iid to marshal
  2500. // [ppIRD] - where to put pointer to marshaled data
  2501. //
  2502. // Returns: S_OK - object successfully marshaled.
  2503. //
  2504. // Algorithm: Marshal the object and then get the pointer to
  2505. // the marshaled data so we can give it to RPC
  2506. //
  2507. //---------------------------------------------------------------------------
  2508. HRESULT ActPropsMarshalHelper(
  2509. IActivationProperties *pact,
  2510. REFIID riid,
  2511. DWORD destCtx,
  2512. DWORD mshlflags,
  2513. MInterfacePointer **ppIRD)
  2514. {
  2515. TRACECALL(TRACE_ACTIVATION, "ActPropsMarshalHelper");
  2516. HRESULT hr;
  2517. // This should'nt really get used by functions
  2518. // called. If that changes we should really QI
  2519. IUnknown *punk = (IUnknown *)pact;
  2520. // Do Marshalling ourselves since this is also
  2521. // used in the SCM. Code collapsed and copied from
  2522. // dcomrem for Custom marshalling
  2523. ULONG dwSize, objrefSize;
  2524. hr = pact->GetMarshalSizeMax(riid,
  2525. (void*) punk,
  2526. destCtx,
  2527. NULL,
  2528. mshlflags,
  2529. &dwSize);
  2530. if (FAILED(hr))
  2531. return hr;
  2532. objrefSize = dwSize + sizeof(OBJREF);
  2533. // Stream to put marshaled interface in
  2534. ActivationStream xrpc(objrefSize);
  2535. // get the clsid for unmarshaling
  2536. CLSID UnmarshalCLSID;
  2537. hr = pact->GetUnmarshalClass(riid, punk, destCtx, NULL,
  2538. mshlflags, &UnmarshalCLSID);
  2539. if (FAILED(hr))
  2540. return hr;
  2541. OBJREF objref;
  2542. objref.signature = OBJREF_SIGNATURE;
  2543. objref.flags = OBJREF_CUSTOM;
  2544. objref.iid = riid;
  2545. objref.u_objref.u_custom.clsid = UnmarshalCLSID;
  2546. objref.u_objref.u_custom.size = dwSize;
  2547. // currently we dont write any extensions into the custom
  2548. // objref. The provision is there so we can do it in the
  2549. // future, for example, if the unmarshaler does not have the
  2550. // unmarshal class code available we could to provide a callback
  2551. // mechanism by putting the OXID, and saResAddr in there.
  2552. objref.u_objref.u_custom.cbExtension = 0;
  2553. // write the objref header info into the stream
  2554. ULONG cbToWrite = PtrToUlong( (LPVOID)( (BYTE *)(&objref.u_objref.u_custom.pData)
  2555. - (BYTE *)&objref ) );
  2556. hr = xrpc.Write(&objref, cbToWrite, NULL);
  2557. if (FAILED(hr))
  2558. return hr;
  2559. hr = pact->MarshalInterface(&xrpc, riid, punk,
  2560. destCtx, NULL,
  2561. mshlflags);
  2562. if (SUCCEEDED(hr))
  2563. xrpc.AssignSerializedInterface((InterfaceData**)ppIRD);
  2564. return hr;
  2565. }
  2566. //---------------------------------------------------------------------------
  2567. //
  2568. // Function: ActPropsUnMarshalHelper
  2569. //
  2570. // Synopsis: Unmarshals an Activation Properties given an IFD
  2571. //
  2572. // Arguments: [pact] - Object to unmarshal into
  2573. // [riid] - iid to unmarshal
  2574. // [pIFP] - pointer to marshaled data
  2575. //
  2576. // Returns: S_OK - object successfully unmarshaled.
  2577. //
  2578. //---------------------------------------------------------------------------
  2579. HRESULT ActPropsUnMarshalHelper(
  2580. IActivationProperties *pAct,
  2581. MInterfacePointer *pIFP,
  2582. REFIID riid,
  2583. void **ppv
  2584. )
  2585. {
  2586. HRESULT hr = E_INVALIDARG;
  2587. if (pIFP && ppv)
  2588. {
  2589. ActivationStream Stm((InterfaceData *) pIFP);
  2590. *ppv = NULL;
  2591. hr = pAct->UnmarshalInterface(&Stm, riid, ppv);
  2592. }
  2593. return hr;
  2594. }
  2595. //---------------------------------------------------------------------------
  2596. //
  2597. // Function: GetIFDFromInterface
  2598. //
  2599. // Synopsis: Makes an "on the wire" representation of an interface
  2600. //
  2601. // Arguments: [punk] - interface to marshal
  2602. // [riid] - iid to marshal
  2603. // [ppIRD] - where to put pointer to marshaled data
  2604. //
  2605. // Returns: S_OK - object successfully marshaled.
  2606. //
  2607. // Algorithm: Marshal the object and then get the pointer to
  2608. // the marshaled data
  2609. //
  2610. //---------------------------------------------------------------------------
  2611. HRESULT GetIFDFromInterface(
  2612. IUnknown *pUnk,
  2613. REFIID riid,
  2614. DWORD destCtx,
  2615. DWORD mshlflags,
  2616. MInterfacePointer **ppIRD)
  2617. {
  2618. DWORD sz;
  2619. InitMarshalling();
  2620. HRESULT rethr;
  2621. if (pfnCoGetMarshalSizeMax)
  2622. {
  2623. rethr = pfnCoGetMarshalSizeMax(&sz, riid , pUnk,
  2624. destCtx,
  2625. NULL, mshlflags);
  2626. }
  2627. else
  2628. {
  2629. rethr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
  2630. }
  2631. if (rethr == S_OK)
  2632. {
  2633. ActivationStream stream(sz);
  2634. if (pfnCoMarshalInterface)
  2635. {
  2636. rethr = pfnCoMarshalInterface(&stream, riid , pUnk,
  2637. destCtx, NULL, mshlflags);
  2638. }
  2639. else
  2640. {
  2641. rethr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
  2642. }
  2643. if (rethr == S_OK)
  2644. stream.AssignSerializedInterface((InterfaceData**)ppIRD);
  2645. else
  2646. *ppIRD = NULL;
  2647. }
  2648. return rethr;
  2649. }
  2650. //---------------------------------------------------------------------------
  2651. //
  2652. // Function: ReleaseIFD
  2653. //
  2654. // Synopsis: Releases Marshalled Data
  2655. //
  2656. // Arguments: [pIRD] - Marshalled Data
  2657. //
  2658. // Returns: S_OK - object successfully marshaled.
  2659. //
  2660. // Algorithm: Marshal the object and then get the pointer to
  2661. // the marshaled data
  2662. //
  2663. //---------------------------------------------------------------------------
  2664. HRESULT ReleaseIFD(
  2665. MInterfacePointer *pIRD)
  2666. {
  2667. InitMarshalling();
  2668. if (pIRD == NULL)
  2669. return S_OK;
  2670. if (pfnCoReleaseMarshalData == NULL)
  2671. return HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
  2672. ActivationStream Strm((InterfaceData *) pIRD);
  2673. return pfnCoReleaseMarshalData(&Strm);
  2674. }