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

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