TCMarshalByValue.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /////////////////////////////////////////////////////////////////////////////
  2. // TCMarshalByValue.cpp | Implementation of the CTCMarshalByValue class,
  3. // which implements the CLSID_TCMarshalByValue component object.<nl><nl>
  4. // This object can be used as a COM aggregate that implements IMarshal in
  5. // terms of the outer object's IPersistStream or IPersistStreamInit
  6. // implementation.
  7. //
  8. #include "pch.h"
  9. #include "TCMarshalByValue.h"
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CTCMarshalByValue
  12. TC_OBJECT_EXTERN_IMPL(CTCMarshalByValue)
  13. /////////////////////////////////////////////////////////////////////////////
  14. // Construction / Destruction
  15. CTCMarshalByValue::CTCMarshalByValue()
  16. : m_dwEndian(0),
  17. m_dwEndianOriginal(0xFF669900),
  18. m_dwEndianInverted(0x009966FF)
  19. {
  20. }
  21. #if defined(_DEBUG) && defined(CTCMarshalByValue_DEBUG)
  22. HRESULT CTCMarshalByValue::FinalConstruct()
  23. {
  24. _TRACE0("CTCMarshalByValue::FinalConstruct()\n");
  25. return S_OK;
  26. }
  27. void CTCMarshalByValue::FinalRelease()
  28. {
  29. _TRACE0("CTCMarshalByValue::FinalRelease()\n");
  30. }
  31. #endif // _DEBUG
  32. /////////////////////////////////////////////////////////////////////////////
  33. // IMarshal Interface Methods
  34. STDMETHODIMP CTCMarshalByValue::GetUnmarshalClass(REFIID riid, void* pv,
  35. DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid)
  36. {
  37. UNUSED(riid);
  38. UNUSED(pv);
  39. UNUSED(dwDestContext);
  40. UNUSED(pvDestContext);
  41. UNUSED(mshlflags);
  42. // Delegate to the IPersistStream::GetClassID of the controlling unknown
  43. IPersistStreamPtr spps;
  44. HRESULT hr = GetOuterPersistStream(&spps);
  45. if (SUCCEEDED(hr))
  46. hr = spps->GetClassID(pCid);
  47. // Return the last HRESULT
  48. return hr;
  49. }
  50. STDMETHODIMP CTCMarshalByValue::GetMarshalSizeMax(REFIID riid, void* pv,
  51. DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize)
  52. {
  53. UNUSED(riid);
  54. UNUSED(pv);
  55. UNUSED(dwDestContext);
  56. UNUSED(pvDestContext);
  57. UNUSED(mshlflags);
  58. // Initialize the [out] parameter
  59. *pSize = 0;
  60. // Delegate to the IPersistStream::GetSizeMax of the controlling unknown
  61. IPersistStreamPtr pps;
  62. HRESULT hr = GetOuterPersistStream(&pps);
  63. if (SUCCEEDED(hr))
  64. {
  65. // Include the size of an endian indicator DWORD value
  66. ULARGE_INTEGER uli;
  67. if (SUCCEEDED(hr = pps->GetSizeMax(&uli)) || (E_NOTIMPL == hr
  68. && SUCCEEDED(hr = TCGetPersistStreamSize(pps, &uli))))
  69. *pSize = uli.LowPart + sizeof(m_dwEndian);
  70. }
  71. // Display a trace message
  72. #if defined(_DEBUG) && defined(CTCMarshalByValue_DEBUG)
  73. _TRACE1("CTCMarshalByValue::GetMarshalSizeMax(): returning 0x%08X\n", *pSize);
  74. #endif
  75. // Return the last HRESULT
  76. return hr;
  77. }
  78. STDMETHODIMP CTCMarshalByValue::MarshalInterface(IStream* pStm, REFIID riid,
  79. void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags)
  80. {
  81. UNUSED(riid);
  82. UNUSED(pv);
  83. UNUSED(dwDestContext);
  84. UNUSED(pvDestContext);
  85. UNUSED(mshlflags);
  86. // Write an endian indicator DWORD value to the stream
  87. DWORD dwEndian = m_dwEndianOriginal;
  88. HRESULT hr = pStm->Write(&dwEndian, sizeof(dwEndian), NULL);
  89. if (SUCCEEDED(hr))
  90. {
  91. // Delegate to the IPersistStream::Save of the controlling unknown
  92. IPersistStreamPtr pps;
  93. if (SUCCEEDED(hr = GetOuterPersistStream(&pps)))
  94. hr = pps->Save(pStm, FALSE);
  95. }
  96. // Return the last HRESULT
  97. return hr;
  98. }
  99. STDMETHODIMP CTCMarshalByValue::UnmarshalInterface(IStream* pStm,
  100. REFIID riid, void** ppv)
  101. {
  102. // Read the endian indicator DWORD value from the stream
  103. CLock lock(this);
  104. HRESULT hr = pStm->Read(&m_dwEndian, sizeof(m_dwEndian), NULL);
  105. if (SUCCEEDED(hr))
  106. {
  107. // Unlock the object
  108. lock.Unlock();
  109. // Delegate to the IPersistStream::Load of the controlling unknown
  110. IPersistStreamPtr pps;
  111. if (SUCCEEDED(hr = GetOuterPersistStream(&pps)))
  112. if (SUCCEEDED(hr = pps->Load(pStm)))
  113. hr = pps->QueryInterface(riid, ppv);
  114. }
  115. // Return the last HRESULT
  116. return hr;
  117. }
  118. STDMETHODIMP CTCMarshalByValue::ReleaseMarshalData(IStream* pStm)
  119. {
  120. // Marshaling by value does not cause us to acquire any resources
  121. return S_OK;
  122. }
  123. STDMETHODIMP CTCMarshalByValue::DisconnectObject(DWORD dwReserved)
  124. {
  125. // Marshaling by value has no notion of connected-ness
  126. return S_OK;
  127. }