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.

1074 lines
33 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: marshl.cxx
  7. //
  8. // Contents: Marshal/Unmarshal implementation
  9. //
  10. // History: 04-May-92 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #include <exphead.cxx>
  14. #pragma hdrstop
  15. #include <expdf.hxx>
  16. #include <expst.hxx>
  17. #include <pbstream.hxx>
  18. #include <marshl.hxx>
  19. #include <logfile.hxx>
  20. // Standard marshal data is an IID plus a DWORD
  21. #define CBSTDMARSHALSIZE (sizeof(IID)+sizeof(DWORD))
  22. SCODE VerifyIid(REFIID iid, REFIID iidObj)
  23. {
  24. if ((IsEqualIID(iid, IID_IUnknown) || (IsEqualIID(iid, iidObj))))
  25. {
  26. return S_OK;
  27. }
  28. if (IsEqualIID(iidObj, IID_ILockBytes))
  29. {
  30. if (IsEqualIID(iid, IID_IFillLockBytes))
  31. {
  32. return S_OK;
  33. }
  34. }
  35. if (IsEqualIID(iidObj, IID_IStorage))
  36. {
  37. if ( IsEqualIID(iid, IID_IPropertySetStorage)
  38. || IsEqualIID(iid, IID_IPropertyBagEx) )
  39. {
  40. return S_OK;
  41. }
  42. }
  43. return STG_E_INVALIDPARAMETER;
  44. }
  45. //+--------------------------------------------------------------
  46. //
  47. // Function: DfUnMarshalInterface, public
  48. //
  49. // Synopsis: Unmarshals marshaled data
  50. //
  51. // Arguments: [pstStm] - Stream to read data from
  52. // [iid] - Interface to unmarshal
  53. // [fFirst] - First time unmarshalling
  54. // [ppvObj] - Interface return
  55. //
  56. // Returns: Appropriate status code
  57. //
  58. // Modifies: [ppvObj]
  59. //
  60. // History: 04-May-92 DrewB Created
  61. //
  62. //---------------------------------------------------------------
  63. STDAPI DfUnMarshalInterface(IStream *pstStm,
  64. REFIID iid,
  65. BOOL fFirst,
  66. void **ppvObj)
  67. {
  68. SCODE sc;
  69. ULONG cbRead;
  70. IID iidSt;
  71. DWORD mshlflags;
  72. SafeIUnknown punk;
  73. olLog(("--------::In DfUnMarshalInterface(%p, iid, %d, %p). "
  74. "Context == %lX\n", pstStm, fFirst, ppvObj,
  75. (ULONG)GetCurrentContextId()));
  76. olDebugOut((DEB_TRACE, "In DfUnMarshalInterface("
  77. "%p, ?, %d, %p)\n", pstStm, fFirst, ppvObj));
  78. olChk(ValidateOutPtrBuffer(ppvObj));
  79. *ppvObj = NULL;
  80. olChk(ValidateInterface(pstStm, IID_IStream));
  81. olChk(ValidateIid(iid));
  82. if (!fFirst)
  83. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  84. olHChk(pstStm->Read(&iidSt, sizeof(iidSt), &cbRead));
  85. if (cbRead != sizeof(iidSt))
  86. olErr(EH_Err, STG_E_READFAULT);
  87. olHChk(pstStm->Read(&mshlflags, sizeof(mshlflags), &cbRead));
  88. if (cbRead != sizeof(mshlflags))
  89. olErr(EH_Err, STG_E_READFAULT);
  90. olChk(VerifyIid(iid, iidSt));
  91. #if !defined(MULTIHEAP)
  92. olChk(DfSyncSharedMemory());
  93. DfInitSharedMemBase();
  94. #endif
  95. if (IsEqualIID(iidSt, IID_ILockBytes))
  96. sc = CFileStream::Unmarshal(pstStm, (void **)&punk, mshlflags);
  97. else if (IsEqualIID(iidSt, IID_IStream))
  98. sc = CExposedStream::Unmarshal(pstStm, (void **)&punk, mshlflags);
  99. else if (IsEqualIID(iidSt, IID_IStorage))
  100. sc = CExposedDocFile::Unmarshal(pstStm, (void **)&punk, mshlflags);
  101. else
  102. sc = E_NOINTERFACE;
  103. if (SUCCEEDED(sc))
  104. {
  105. if (!IsEqualIID(iid, iidSt))
  106. {
  107. sc = punk->QueryInterface(iid, ppvObj);
  108. }
  109. else
  110. {
  111. TRANSFER_INTERFACE(punk, IUnknown, ppvObj);
  112. #if DBG == 1
  113. void *pvCheck;
  114. HRESULT scCheck = ((IUnknown*)*ppvObj)->QueryInterface(iidSt, &pvCheck);
  115. olAssert (scCheck == S_OK || scCheck == STG_E_REVERTED);
  116. if (SUCCEEDED(scCheck))
  117. {
  118. olAssert( pvCheck == *ppvObj );
  119. ((IUnknown*)pvCheck)->Release();
  120. }
  121. #endif
  122. }
  123. }
  124. olDebugOut((DEB_TRACE, "Out DfUnMarshalInterface => %p\n",
  125. *ppvObj));
  126. EH_Err:
  127. olLog(("--------::Out DfUnMarshalInterface(). "
  128. "*ppvObj == %p, ret == %lX\n", *ppvObj, sc));
  129. return ResultFromScode(sc);
  130. }
  131. //+---------------------------------------------------------------------------
  132. //
  133. // Function: GetCoMarshalSize, private
  134. //
  135. // Synopsis: Gets the marshal size for an interface marshalled using
  136. // CoMarshalInterface
  137. //
  138. // Arguments: [riid] - Interface id
  139. // [punk] - Interface pointer
  140. // [pv] - Context info
  141. // [dwDestContext] - Destination context
  142. // [pvDestContext] - Destination context
  143. // [mshlflags] - Marshal flags
  144. // [pcb] - Size return
  145. //
  146. // Returns: Appropriate status code
  147. //
  148. // Modifies: [pcb]
  149. //
  150. // Algorithm: CoMarshalInterface is guaranteed to add no more than
  151. // MARSHALINTERFACE_MIN bytes of overhead to a marshal
  152. // Also, the standard marshaller takes no more than that
  153. // So if the given object supports IMarshal, the return
  154. // is IMarshal::GetMarshalSizeMax+MARSHALINTERFACE_MIN,
  155. // otherwise it is just MARSHALINTERFACE_MIN
  156. //
  157. // History: 03-Aug-93 DrewB Created
  158. //
  159. // Notes: On 32-bit platforms, we can use CoGetMarshalSizeMax
  160. //
  161. //----------------------------------------------------------------------------
  162. #ifndef WIN32
  163. static SCODE GetCoMarshalSize(REFIID riid,
  164. IUnknown *punk,
  165. void *pv,
  166. DWORD dwDestContext,
  167. void *pvDestContext,
  168. DWORD mshlflags,
  169. DWORD *pcb)
  170. {
  171. IMarshal *pmsh;
  172. SCODE sc;
  173. DWORD cb;
  174. olDebugOut((DEB_ITRACE, "In GetCoMarshalSize("
  175. "riid, %p, %p, %lu, %p, %lu, %p)\n", pv, punk, dwDestContext,
  176. pvDestContext, mshlflags, pcb));
  177. sc = DfGetScode(punk->QueryInterface(IID_IMarshal, (void **)&pmsh));
  178. if (sc == E_NOINTERFACE)
  179. {
  180. *pcb = MARSHALINTERFACE_MIN;
  181. sc = S_OK;
  182. }
  183. else if (SUCCEEDED(sc))
  184. {
  185. sc = DfGetScode(pmsh->GetMarshalSizeMax(riid, pv, dwDestContext,
  186. pvDestContext, mshlflags,
  187. &cb));
  188. if (SUCCEEDED(sc))
  189. *pcb = MARSHALINTERFACE_MIN+cb;
  190. pmsh->Release();
  191. }
  192. olDebugOut((DEB_ITRACE, "Out GetCoMarshalSize => %lu, 0x%lX\n",
  193. *pcb, sc));
  194. return sc;
  195. }
  196. #else
  197. #define GetCoMarshalSize(riid, punk, pv, dwDestContext, pvDestContext,\
  198. mshlflags, pcb) \
  199. GetScode(CoGetMarshalSizeMax(pcb, riid, punk, dwDestContext, \
  200. pvDestContext, mshlflags))
  201. #endif
  202. //+--------------------------------------------------------------
  203. //
  204. // Function: GetStdMarshalSize, public
  205. //
  206. // Synopsis: Returns the size needed for a standard marshal buffer
  207. //
  208. // Arguments: [iid] - Requested marshal IID
  209. // [iidObj] - IID of object being marshalled
  210. // [dwDestContext] - Destination context
  211. // [pvDestContext] - Unreferenced
  212. // [mshlflags] - Marshal flags
  213. // [pcbSize] - Size return
  214. // [cbSize] - Object private size
  215. // [ppc] - Context to marshal or NULL
  216. // [fMarshalOriginal] - Marshal original in context
  217. //
  218. // Returns: Appropriate status code
  219. //
  220. // Modifies: [pcbSize]
  221. //
  222. // History: 04-May-92 DrewB Created
  223. //
  224. //---------------------------------------------------------------
  225. SCODE GetStdMarshalSize(REFIID iid,
  226. REFIID iidObj,
  227. DWORD dwDestContext,
  228. LPVOID pvDestContext,
  229. DWORD mshlflags,
  230. DWORD *pcbSize,
  231. DWORD cbSize,
  232. #ifdef ASYNC
  233. CAsyncConnection *pcpoint,
  234. BOOL fMarshalILBs,
  235. #endif
  236. CPerContext *ppc,
  237. BOOL const fMarshalOriginal)
  238. {
  239. DWORD cbLBSize;
  240. SCODE sc;
  241. olDebugOut((DEB_ITRACE, "In GetStdMarshalSize("
  242. "iid, iidObj, %lu, %p, %lu, %p, %lu, %p, %d)\n",
  243. dwDestContext, pvDestContext, mshlflags, pcbSize, cbSize, ppc,
  244. fMarshalOriginal));
  245. olChk(ValidateOutBuffer(pcbSize, sizeof(DWORD)));
  246. *pcbSize = 0;
  247. olChk(ValidateIid(iid));
  248. olChk(VerifyIid(iid, iidObj));
  249. if (((dwDestContext != MSHCTX_LOCAL) && (dwDestContext != MSHCTX_INPROC))
  250. || pvDestContext != NULL)
  251. olErr(EH_Err, STG_E_INVALIDFLAG);
  252. *pcbSize = CBSTDMARSHALSIZE+cbSize;
  253. #ifdef MULTIHEAP
  254. *pcbSize += sizeof(ULONG)+sizeof(ContextId)+sizeof(CPerContext*);
  255. #endif
  256. #ifdef POINTER_IDENTITY
  257. *pcbSize += sizeof(CMarshalList*);
  258. #endif
  259. #ifdef ASYNC
  260. if ((ppc) && fMarshalILBs)
  261. #else
  262. if (ppc)
  263. #endif
  264. {
  265. *pcbSize += sizeof(CGlobalContext *);
  266. olChk(GetCoMarshalSize(IID_ILockBytes,
  267. (ILockBytes *)ppc->GetBase(),
  268. NULL, dwDestContext, pvDestContext,
  269. mshlflags, &cbLBSize));
  270. *pcbSize += cbLBSize;
  271. olChk(GetCoMarshalSize(IID_ILockBytes,
  272. (ILockBytes *)ppc->GetDirty(),
  273. NULL, dwDestContext, pvDestContext,
  274. mshlflags, &cbLBSize));
  275. *pcbSize += cbLBSize;
  276. if (fMarshalOriginal)
  277. {
  278. olChk(GetCoMarshalSize(IID_ILockBytes,
  279. (ILockBytes *)ppc->GetOriginal(),
  280. NULL, dwDestContext, pvDestContext,
  281. mshlflags, &cbLBSize));
  282. *pcbSize += cbLBSize;
  283. }
  284. }
  285. #ifdef ASYNC
  286. //BOOL determines whether we have a connection to marshal or not
  287. *pcbSize += sizeof(BOOL);
  288. if ((pcpoint) && (pcpoint->GetMarshalPoint() != NULL))
  289. {
  290. ULONG cbConnectSize;
  291. //Async flags
  292. *pcbSize += sizeof(DWORD);
  293. olChk(GetCoMarshalSize(IID_IDocfileAsyncConnectionPoint,
  294. pcpoint->GetMarshalPoint(),
  295. NULL, dwDestContext, pvDestContext,
  296. mshlflags, &cbConnectSize));
  297. *pcbSize += cbConnectSize;
  298. }
  299. #endif
  300. olDebugOut((DEB_ITRACE, "Out GetStdMarshalSize\n"));
  301. EH_Err:
  302. return sc;
  303. }
  304. //+--------------------------------------------------------------
  305. //
  306. // Member: StartMarshal, public
  307. //
  308. // Synopsis: Writes standard marshal header
  309. //
  310. // Arguments: [pstStm] - Stream to write marshal data into
  311. // [iid] - Interface to marshal
  312. // [iidObj] - Object being marshalled
  313. // [mshlflags] - Marshal flags
  314. //
  315. // Returns: Appropriate status code
  316. //
  317. // History: 04-May-92 DrewB Created
  318. //
  319. //---------------------------------------------------------------
  320. SCODE StartMarshal(IStream *pstStm,
  321. REFIID iid,
  322. REFIID iidObj,
  323. DWORD mshlflags)
  324. {
  325. SCODE sc;
  326. ULONG cbWritten;
  327. olDebugOut((DEB_ITRACE, "In StartMarshal(%p, iid, iidObj, %lu)\n",
  328. pstStm, mshlflags));
  329. olChk(ValidateInterface(pstStm, IID_IStream));
  330. olChk(ValidateIid(iid));
  331. olChk(VerifyIid(iid, iidObj));
  332. olHChk(pstStm->Write((void *)&iidObj, sizeof(iidObj), &cbWritten));
  333. if (cbWritten != sizeof(iidObj))
  334. olErr(EH_Err, STG_E_WRITEFAULT);
  335. #if defined(_WIN64)
  336. mshlflags |= MSHLFLAGS_STG_WIN64;
  337. #endif
  338. olHChk(pstStm->Write((void *)&mshlflags, sizeof(mshlflags), &cbWritten));
  339. if (cbWritten != sizeof(mshlflags))
  340. olErr(EH_Err, STG_E_WRITEFAULT);
  341. olDebugOut((DEB_ITRACE, "Out StartMarshal\n"));
  342. EH_Err:
  343. return sc;
  344. }
  345. //+---------------------------------------------------------------------------
  346. //
  347. // Function: SkipStdMarshal, public
  348. //
  349. // Synopsis: Skips over the standard marshal data
  350. //
  351. // Arguments: [pstm] - Marshal stream
  352. // [piid] - IID return
  353. // [pmshlflags] - Return marshal flags
  354. //
  355. // Returns: Appropriate status code
  356. //
  357. // Modifies: [piid]
  358. // [pmshlflags]
  359. //
  360. // History: 20-Nov-92 DrewB Created
  361. //
  362. //----------------------------------------------------------------------------
  363. #ifdef WIN32
  364. SCODE SkipStdMarshal(IStream *pstm, IID *piid, DWORD *pmshlflags)
  365. {
  366. SCODE sc;
  367. ULONG cbRead;
  368. olDebugOut((DEB_ITRACE, "In SkipStdMarshal(%p, %p, %p)\n", pstm,
  369. piid, pmshlflags));
  370. olHChk(pstm->Read(piid, sizeof(IID), &cbRead));
  371. if (cbRead != sizeof(IID))
  372. olErr(EH_Err, STG_E_READFAULT);
  373. olHChk(pstm->Read(pmshlflags, sizeof(DWORD), &cbRead));
  374. if (cbRead != sizeof(DWORD))
  375. olErr(EH_Err, STG_E_READFAULT);
  376. olDebugOut((DEB_ITRACE, "Out SkipStdMarshal => %lX\n", sc));
  377. EH_Err:
  378. return sc;
  379. }
  380. #endif
  381. //+--------------------------------------------------------------
  382. //
  383. // Function: MarshalPointer, public
  384. //
  385. // Synopsis: Marshals a pointer
  386. //
  387. // Arguments: [pstm] - Marshal stream
  388. // [pv] - Pointer
  389. //
  390. // Returns: Appropriate status code
  391. //
  392. // History: 20-Aug-92 DrewB Created
  393. //
  394. //---------------------------------------------------------------
  395. SCODE MarshalPointer(IStream *pstm, void *pv)
  396. {
  397. SCODE sc;
  398. ULONG cbWritten;
  399. olDebugOut((DEB_ITRACE, "In MarshalPointer(%p, %p)\n", pstm, pv));
  400. #ifdef USEBASED
  401. ULONG ul = (ULONG)((ULONG_PTR)pv - (ULONG_PTR)DFBASEPTR);
  402. #endif
  403. sc = DfGetScode(pstm->Write(&ul, sizeof(ul), &cbWritten));
  404. if (SUCCEEDED(sc) && cbWritten != sizeof(ul))
  405. sc = STG_E_WRITEFAULT;
  406. olDebugOut((DEB_ITRACE, "Out MarshalPointer\n"));
  407. return sc;
  408. }
  409. //+--------------------------------------------------------------
  410. //
  411. // Function: MarshalContext, public
  412. //
  413. // Synopsis: Marshals a context
  414. //
  415. // Arguments: [pstm] - Marshal stream
  416. // [ppc] - Context
  417. // [dwDestContext] - Destination context
  418. // [pvDestContext] - Unreferenced
  419. // [mshlflags] - Marshal flags
  420. // [fMarshalOriginal] - Marshal original or not
  421. //
  422. // Returns: Appropriate status code
  423. //
  424. // History: 20-Aug-92 DrewB Created
  425. //
  426. //---------------------------------------------------------------
  427. SCODE MarshalContext(IStream *pstm,
  428. CPerContext *ppc,
  429. DWORD dwDestContext,
  430. LPVOID pvDestContext,
  431. DWORD mshlflags,
  432. #ifdef ASYNC
  433. BOOL const fMarshalILBs,
  434. #endif
  435. BOOL const fMarshalOriginal)
  436. {
  437. SCODE sc;
  438. olDebugOut((DEB_ITRACE, "In MarshalContext(%p, %p, %lu, %p, %lu, %d)\n",
  439. pstm, ppc, dwDestContext, pvDestContext, mshlflags,
  440. fMarshalOriginal));
  441. olChk(MarshalPointer(pstm, ppc->GetGlobal()));
  442. #ifdef ASYNC
  443. if (fMarshalILBs)
  444. #endif
  445. {
  446. olHChk(CoMarshalInterface(pstm, IID_ILockBytes, ppc->GetBase(),
  447. dwDestContext, pvDestContext, mshlflags));
  448. olHChk(CoMarshalInterface(pstm, IID_ILockBytes,
  449. (ILockBytes *)ppc->GetDirty(),
  450. dwDestContext, pvDestContext, mshlflags));
  451. if (fMarshalOriginal)
  452. olHChk(CoMarshalInterface(pstm, IID_ILockBytes, ppc->GetOriginal(),
  453. dwDestContext, pvDestContext, mshlflags));
  454. }
  455. olDebugOut((DEB_ITRACE, "Out MarshalContext\n"));
  456. EH_Err:
  457. return sc;
  458. }
  459. //+--------------------------------------------------------------
  460. //
  461. // Function: UnmarshalPointer, public
  462. //
  463. // Synopsis: Unmarshals a pointer
  464. //
  465. // Arguments: [pstm] - Marshal stream
  466. // [ppv] - Pointer return
  467. //
  468. // Returns: Appropriate status code
  469. //
  470. // Modifies: [ppv]
  471. //
  472. // History: 20-Aug-92 DrewB Created
  473. //
  474. //---------------------------------------------------------------
  475. SCODE UnmarshalPointer(IStream *pstm,
  476. void **ppv)
  477. {
  478. SCODE sc;
  479. ULONG cbRead;
  480. ULONG ul;
  481. olDebugOut((DEB_ITRACE, "In UnmarshalPointer(%p, %p)\n", pstm, ppv));
  482. sc = DfGetScode(pstm->Read(&ul, sizeof(ul), &cbRead));
  483. if (SUCCEEDED(sc) && cbRead != sizeof(ul))
  484. sc = STG_E_READFAULT;
  485. #ifdef USEBASED
  486. *ppv = (void *)(ul + (BYTE*)DFBASEPTR);
  487. #endif
  488. olDebugOut((DEB_ITRACE, "Out UnmarshalPointer => %p\n", *ppv));
  489. return sc;
  490. }
  491. //+--------------------------------------------------------------
  492. //
  493. // Function: UnmarshalContext, public
  494. //
  495. // Synopsis: Unmarshals a context
  496. //
  497. // Arguments: [pstm] - Marshal stream
  498. // [pppc] - Context return
  499. // [fUnmarshalOriginal] - Marshalled original exists or not
  500. // [fIsRoot] - Root unmarshal or not
  501. //
  502. // Returns: Appropriate status code
  503. //
  504. // Modifies: [pppc]
  505. //
  506. // History: 20-Aug-92 DrewB Created
  507. //
  508. //---------------------------------------------------------------
  509. SCODE UnmarshalContext(IStream *pstm,
  510. CGlobalContext *pgc,
  511. CPerContext **pppc,
  512. DWORD mshlflags,
  513. #ifdef ASYNC
  514. BOOL const fUnmarshalILBs,
  515. #endif
  516. BOOL const fUnmarshalOriginal,
  517. #ifdef MULTIHEAP
  518. ContextId cntxid,
  519. #endif
  520. BOOL const fIsRoot)
  521. {
  522. BOOL fNewContext;
  523. ILockBytes *plkbBase = NULL;
  524. CFileStream *pfstDirty = NULL;
  525. ILockBytes *plkbOriginal = NULL;
  526. SCODE sc, sc2;
  527. CPerContext *ppc;
  528. CPerContext *ppcNew = NULL;
  529. ULONG ulOpenLock = 0;
  530. olDebugOut((DEB_ITRACE, "In UnmarshalContext(%p, %p, %lu, %d, %d)\n",
  531. pstm, pppc, mshlflags, fUnmarshalOriginal, fIsRoot));
  532. ppc = pgc->Find(GetCurrentContextId());
  533. // ignore leaked contexts from processes that died and their ID got reused
  534. if (ppc != NULL && !ppc->IsHandleValid())
  535. ppc = NULL;
  536. fNewContext = (ppc == NULL);
  537. #ifdef MULTIHEAP
  538. // when marshaling to the same process, use the same heap
  539. // when marshaling to a different process, check the context list
  540. // if there is a matching percontext, use that heap
  541. if (GetCurrentContextId() != cntxid && ppc != NULL)
  542. {
  543. ppc->SetThreadAllocatorState(NULL); // set new base
  544. // Whenever we unmarshal into a different process, we create
  545. // a new mapping (of the same heap),
  546. // even if a mapping of the same heap may already exist in
  547. // the same process. For pointer identity, it is essential
  548. // that we find and use the existing heap.
  549. // process A ---marshal---> process B ---marshal----> process A
  550. // The "final" unmarshaled exposed object in process A should
  551. // match the original pointer used when the exposed object
  552. // was originally marshaled. To do this, we check the global
  553. // context list, and if there's a percontext match, we use
  554. // its allocator and heap mapping (and don't create a new one).
  555. // However, to actually search the global context list (it
  556. // lives in shared memory), we need a temporary mapping until
  557. // a matching percontext can be found and reused.
  558. // If not, then a new percontext is allocated and the temporary
  559. // mapping becomes "permanent" for the lifetime of the new percontext.
  560. }
  561. #endif
  562. if (fNewContext)
  563. {
  564. olMemTo(EH_Open,
  565. ppc = new (pgc->GetMalloc()) CPerContext(pgc->GetMalloc()));
  566. olChkTo(EH_ppc, ppc->InitFromGlobal(pgc));
  567. ppcNew = ppc; // used to release in error paths
  568. }
  569. #ifdef MULTIHEAP
  570. // take the ownership of the heap away from the temporary
  571. ppc->SetAllocatorState (NULL, &g_smAllocator);
  572. //ppc from above may have used incorrect base (base of temporary heap).
  573. // Since we're returning and storing an unbased pointer, we need to get
  574. // the real absolute pointer here. At this point, ppc will always be in
  575. // the context list, so we don't need to worry about a NULL return.
  576. ppc = pgc->Find(GetCurrentContextId());
  577. olAssert(ppc != NULL);
  578. #endif
  579. #ifdef ASYNC
  580. if (fUnmarshalILBs)
  581. {
  582. #endif
  583. // attempt to unmarshal all the interfaces first. this makes cleanup
  584. // easier.
  585. sc = CoUnmarshalInterface(pstm, IID_ILockBytes, (void **)&plkbBase);
  586. sc2 = CoUnmarshalInterface(pstm, IID_ILockBytes, (void **)&pfstDirty);
  587. sc = (SUCCEEDED(sc)) ? sc2 : sc; // sc = first failure code (if any)
  588. if (fUnmarshalOriginal)
  589. {
  590. sc2 = CoUnmarshalInterface(pstm, IID_ILockBytes,
  591. (void **)&plkbOriginal);
  592. sc = (SUCCEEDED(sc)) ? sc2 : sc; // sc = first failure code (if any)
  593. }
  594. // cleanup if any failure so far
  595. olChkTo(EH_plkbOriginal, sc);
  596. if (ppc->GetBase() != NULL)
  597. {
  598. // already have context, just release the things we unmarshaled.
  599. plkbBase->Release();
  600. plkbBase = NULL;
  601. }
  602. if (ppc->GetDirty() != NULL)
  603. {
  604. pfstDirty->Release();
  605. pfstDirty = NULL;
  606. }
  607. if ((plkbOriginal) && (ppc->GetOriginal() != NULL))
  608. {
  609. plkbOriginal->Release();
  610. plkbOriginal = NULL;
  611. }
  612. else if ((NULL == plkbOriginal) && plkbBase)
  613. {
  614. plkbBase->AddRef();
  615. plkbOriginal = plkbBase;
  616. }
  617. olAssert (plkbOriginal != NULL || ppc->GetOriginal() != NULL);
  618. // Make sure there is a reserved handle if this is a root
  619. // file-based lockbytes
  620. if (fIsRoot)
  621. {
  622. IFileLockBytes *pflkb;
  623. if (SUCCEEDED(DfGetScode((plkbOriginal ? plkbOriginal :
  624. ppc->GetOriginal())->
  625. QueryInterface(IID_IFileLockBytes,
  626. (void **)&pflkb))))
  627. {
  628. sc = DfGetScode(pflkb->ReserveHandle());
  629. pflkb->Release();
  630. olChkTo(EH_plkbOriginal, sc);
  631. }
  632. }
  633. #ifdef ASYNC
  634. }
  635. #endif
  636. if (fNewContext)
  637. {
  638. olAssert(plkbOriginal != NULL);
  639. // Take open locks if necessary
  640. if (fIsRoot && pgc->TakeLock())
  641. {
  642. olChkTo(EH_plkbOriginal,
  643. GetOpen(plkbOriginal, pgc->GetOpenLockFlags(),
  644. FALSE, &ulOpenLock));
  645. }
  646. ppc->SetILBInfo(plkbBase, pfstDirty, plkbOriginal, ulOpenLock);
  647. }
  648. else
  649. {
  650. if (ppc->GetBase() == NULL)
  651. {
  652. //Fill in the ILB fields
  653. ppc->SetILBInfo(plkbBase, pfstDirty, plkbOriginal, ulOpenLock);
  654. }
  655. ppc->AddRef();
  656. }
  657. *pppc = ppc;
  658. olDebugOut((DEB_ITRACE, "Out UnmarshalContext => %p\n", *pppc));
  659. return S_OK;
  660. EH_ppc:
  661. // Preserve plkbOriginal so the lock is released even after the
  662. // context releases things;
  663. plkbOriginal->AddRef();
  664. ppc->Release();
  665. ppcNew = NULL;
  666. pfstDirty = NULL;
  667. plkbBase = NULL;
  668. EH_Open:
  669. if (ulOpenLock != 0)
  670. {
  671. olAssert(plkbOriginal != NULL);
  672. ReleaseOpen(plkbOriginal, pgc->GetOpenLockFlags(), ulOpenLock);
  673. }
  674. EH_plkbOriginal:
  675. if (ppcNew != NULL)
  676. ppcNew->Release();
  677. if (plkbOriginal)
  678. plkbOriginal->Release();
  679. if (pfstDirty)
  680. pfstDirty->Release();
  681. if (plkbBase)
  682. plkbBase->Release();
  683. return sc;
  684. }
  685. //+---------------------------------------------------------------------------
  686. //
  687. // Function: ReleaseContext, public
  688. //
  689. // Synopsis: Releases references for a context's marshal data
  690. //
  691. // Arguments: [pstm] - Marshal stream
  692. // [fHasOriginal] - Original is marshalled
  693. // [mshlflags] - Marshal flags
  694. //
  695. // Returns: Appropriate status code
  696. //
  697. // History: 20-Nov-92 DrewB Created
  698. //
  699. //----------------------------------------------------------------------------
  700. #ifdef WIN32
  701. SCODE ReleaseContext(IStream *pstm,
  702. #ifdef ASYNC
  703. BOOL const fUnmarshalILBs,
  704. #endif
  705. BOOL const fHasOriginal,
  706. DWORD mshlflags)
  707. {
  708. CGlobalContext *pgc;
  709. SCODE sc;
  710. olDebugOut((DEB_ITRACE, "In ReleaseContext(%p, %d, %lu)\n", pstm,
  711. fHasOriginal, mshlflags));
  712. olChk(UnmarshalPointer(pstm, (void **)&pgc));
  713. if (fUnmarshalILBs)
  714. {
  715. olHChk(CoReleaseMarshalData(pstm));
  716. olHChk(CoReleaseMarshalData(pstm));
  717. if (fHasOriginal)
  718. olHChk(CoReleaseMarshalData(pstm));
  719. }
  720. olDebugOut((DEB_ITRACE, "Out ReleaseContext\n"));
  721. EH_Err:
  722. return sc;
  723. }
  724. #endif
  725. #ifdef MULTIHEAP
  726. //+---------------------------------------------------------------------------
  727. //
  728. // Function: MarshalSharedMemory, public
  729. //
  730. // Synopsis: marshals the shared memory context
  731. //
  732. // Arguments: [pstm] - Marshal stream
  733. // [ppc] - per context structure
  734. //
  735. // Returns: Appropriate status code
  736. //
  737. // History: 02-Dec-95 HenryLee Created
  738. //
  739. //----------------------------------------------------------------------------
  740. SCODE MarshalSharedMemory (IStream *pstStm, CPerContext *ppc)
  741. {
  742. SCODE sc = S_OK;
  743. ULONG cbWritten;
  744. ULONG ulHeapName;
  745. ContextId cntxid = GetCurrentContextId();
  746. ULONGLONG ulppc = (ULONGLONG) ppc;
  747. ulHeapName = g_smAllocator.GetHeapName();
  748. olHChk(pstStm->Write((void*) &ulHeapName, sizeof(ulHeapName), &cbWritten));
  749. if (cbWritten != sizeof(ulHeapName))
  750. olErr(EH_Err, STG_E_WRITEFAULT);
  751. olHChk(pstStm->Write((void*) &cntxid, sizeof(cntxid), &cbWritten));
  752. if (cbWritten != sizeof(cntxid))
  753. olErr(EH_Err, STG_E_WRITEFAULT);
  754. olHChk(pstStm->Write((void*) &ulppc, sizeof(ulppc), &cbWritten));
  755. if (cbWritten != sizeof(ulppc))
  756. olErr(EH_Err, STG_E_WRITEFAULT);
  757. EH_Err:
  758. return sc;
  759. }
  760. //+---------------------------------------------------------------------------
  761. //
  762. // Function: SkipSharedMemory, public
  763. //
  764. // Synopsis: Cleanup marshaling packet during CoReleaseMarshalData
  765. //
  766. // Arguments: [pstm] - Marshal stream
  767. //
  768. // Returns: Appropriate status code
  769. //
  770. // History: 02-Dec-95 HenryLee Created
  771. //
  772. //----------------------------------------------------------------------------
  773. SCODE SkipSharedMemory (IStream *pstStm, DWORD mshlflags)
  774. {
  775. SCODE sc = S_OK;
  776. ULONG cbRead;
  777. ULONG ulHeapName;
  778. ContextId cntxid;
  779. ULONGLONG ulppc;
  780. olChk(pstStm->Read(&ulHeapName, sizeof(ulHeapName), &cbRead));
  781. if (cbRead != sizeof(ulHeapName))
  782. olErr(EH_Err, STG_E_READFAULT);
  783. olChk(pstStm->Read(&cntxid, sizeof(cntxid), &cbRead));
  784. if (cbRead != sizeof(cntxid))
  785. olErr(EH_Err, STG_E_READFAULT);
  786. olChk(pstStm->Read(&ulppc, sizeof(ulppc), &cbRead));
  787. if (cbRead != sizeof(ulppc))
  788. olErr(EH_Err, STG_E_READFAULT);
  789. EH_Err:
  790. return sc;
  791. }
  792. //+---------------------------------------------------------------------------
  793. //
  794. // Function: UnMarshalSharedMemory, public
  795. //
  796. // Synopsis: Unmarshals the shared memory context
  797. //
  798. // Arguments: [pstm] - Marshal stream
  799. //
  800. // Returns: Appropriate status code
  801. //
  802. // History: 02-Dec-95 HenryLee Created
  803. //
  804. //----------------------------------------------------------------------------
  805. SCODE UnmarshalSharedMemory (IStream *pstStm, DWORD mshlflags,
  806. CPerContext *ppcOwner, ContextId *pcntxid)
  807. {
  808. SCODE sc = S_OK;
  809. ULONG cbRead;
  810. ULONG ulHeapName;
  811. ContextId cntxid;
  812. CPerContext *ppc;
  813. ULONGLONG ulppc;
  814. olHChk(pstStm->Read(&ulHeapName, sizeof(ulHeapName), &cbRead));
  815. if (cbRead != sizeof(ulHeapName))
  816. olErr(EH_Err, STG_E_READFAULT);
  817. olHChk(pstStm->Read(&cntxid, sizeof(cntxid), &cbRead));
  818. if (cbRead != sizeof(cntxid))
  819. olErr(EH_Err, STG_E_READFAULT);
  820. olHChk(pstStm->Read(&ulppc, sizeof(ulppc), &cbRead));
  821. if (cbRead != sizeof(ulppc))
  822. olErr(EH_Err, STG_E_READFAULT);
  823. ppc = (CPerContext *) ulppc;
  824. #if defined(_WIN64)
  825. if ((mshlflags & MSHLFLAGS_STG_WIN64) == 0)
  826. olErr (EH_Err, STG_E_INVALIDFUNCTION);
  827. #else
  828. if ((mshlflags & MSHLFLAGS_STG_WIN64) != 0)
  829. olErr (EH_Err, STG_E_INVALIDFUNCTION);
  830. #endif
  831. *pcntxid = cntxid;
  832. if (GetCurrentContextId() == cntxid)
  833. {
  834. // marshaling to the same process, reuse the per context and heap
  835. // in the case of marshaling to another thread
  836. // the per context takes ownership of the thread's allocator
  837. ppc->SetThreadAllocatorState(NULL);
  838. }
  839. else
  840. {
  841. // marshaling to another process on the same machine
  842. // if the name of heap is different that current one, open it
  843. if (g_smAllocator.GetHeapName() != ulHeapName)
  844. {
  845. DfInitSharedMemBase();
  846. olChk(DfSyncSharedMemory(ulHeapName));
  847. }
  848. // Because the unmarshaling code calls IStream::Read,
  849. // possibly using another shared heap, we need a temporary
  850. // owner until the real CPerContext is unmarshaled
  851. ppcOwner->GetThreadAllocatorState();
  852. ppcOwner->SetThreadAllocatorState(NULL);
  853. }
  854. EH_Err:
  855. return sc;
  856. }
  857. #endif
  858. #ifdef ASYNC
  859. SCODE MarshalConnection(IStream *pstm,
  860. CAsyncConnection *pcpoint,
  861. DWORD dwDestContext,
  862. LPVOID pvDestContext,
  863. DWORD mshlflags)
  864. {
  865. SCODE sc;
  866. ULONG cbWritten;
  867. IDocfileAsyncConnectionPoint *pdacp = pcpoint->GetMarshalPoint();
  868. BOOL fIsInitialized = (pdacp != NULL);
  869. //Write out the pointer.
  870. olHChk(pstm->Write(&fIsInitialized,
  871. sizeof(BOOL),
  872. &cbWritten));
  873. if (cbWritten != sizeof(BOOL))
  874. {
  875. olErr(EH_Err, STG_E_READFAULT);
  876. }
  877. if (fIsInitialized)
  878. {
  879. //If the pointer was NULL, we don't need to worry about actually
  880. //marshalling anything, and we can detect this in the unmarshal
  881. //path. If it wasn't NULL, we need to store some additional
  882. //information: The async flags and the actual connection point,
  883. //which will be standard marshalled.
  884. DWORD dwAsyncFlags = pcpoint->GetAsyncFlags();
  885. olChk(pstm->Write(&dwAsyncFlags, sizeof(DWORD), &cbWritten));
  886. if (cbWritten != sizeof(DWORD))
  887. {
  888. olErr(EH_Err, STG_E_WRITEFAULT);
  889. }
  890. //Finally, standard marshal the connection point itself.
  891. olHChk(CoMarshalInterface(pstm,
  892. IID_IDocfileAsyncConnectionPoint,
  893. pdacp,
  894. dwDestContext,
  895. pvDestContext,
  896. mshlflags));
  897. }
  898. EH_Err:
  899. return sc;
  900. }
  901. SCODE UnmarshalConnection(IStream *pstm,
  902. DWORD *pdwAsyncFlags,
  903. IDocfileAsyncConnectionPoint **ppdacp,
  904. DWORD mshlflags)
  905. {
  906. SCODE sc;
  907. BOOL fIsInitialized;
  908. ULONG cbRead;
  909. *ppdacp = NULL;
  910. *pdwAsyncFlags = 0;
  911. olHChk(pstm->Read(&fIsInitialized, sizeof(BOOL), &cbRead));
  912. if (cbRead != sizeof(BOOL))
  913. {
  914. olErr(EH_Err, STG_E_READFAULT);
  915. }
  916. if (fIsInitialized)
  917. {
  918. olChk(pstm->Read(pdwAsyncFlags, sizeof(DWORD), &cbRead));
  919. if (cbRead != sizeof(DWORD))
  920. {
  921. olErr(EH_Err, STG_E_READFAULT);
  922. }
  923. sc = CoUnmarshalInterface(pstm,
  924. IID_IDocfileAsyncConnectionPoint,
  925. (void **)ppdacp);
  926. }
  927. EH_Err:
  928. return sc;
  929. }
  930. SCODE ReleaseConnection(IStream *pstm, DWORD mshlflags)
  931. {
  932. SCODE sc;
  933. ULONG cbRead;
  934. BOOL fIsInitialized;
  935. DWORD dwAsyncFlags;
  936. olHChk(pstm->Read(&fIsInitialized, sizeof(BOOL), &cbRead));
  937. if (cbRead != sizeof(BOOL))
  938. {
  939. olErr(EH_Err, STG_E_READFAULT);
  940. }
  941. if (fIsInitialized)
  942. {
  943. olChk(pstm->Read(&dwAsyncFlags, sizeof(DWORD), &cbRead));
  944. if (cbRead != sizeof(DWORD))
  945. {
  946. olErr(EH_Err, STG_E_READFAULT);
  947. }
  948. olHChk(CoReleaseMarshalData(pstm));
  949. }
  950. EH_Err:
  951. return sc;
  952. }
  953. #endif