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.

168 lines
3.7 KiB

  1. // Copyright (c) 2000 Microsoft Corporation. All rights reserved.
  2. //
  3. // Implementation of CSourceText.
  4. //
  5. #include "stdinc.h"
  6. #include "dll.h"
  7. #include "sourcetext.h"
  8. const GUID CLSID_DirectMusicSourceText = { 0xc70eb77f, 0xefd4, 0x4678, { 0xa2, 0x7b, 0xbf, 0x16, 0x48, 0xf3, 0xd, 0x4 } }; // {C70EB77F-EFD4-4678-A27B-BF1648F30D04}
  9. const GUID IID_IDirectMusicSourceText = { 0xa384ffed, 0xa708, 0x48de, { 0x85, 0x5b, 0x90, 0x63, 0x8b, 0xa5, 0xc0, 0xac } }; // {A384FFED-A708-48de-855B-90638BA5C0AC}
  10. //////////////////////////////////////////////////////////////////////
  11. // Creation
  12. CSourceText::CSourceText()
  13. : m_cRef(0)
  14. {
  15. LockModule(true);
  16. }
  17. HRESULT
  18. CSourceText::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv)
  19. {
  20. *ppv = NULL;
  21. if (pUnknownOuter)
  22. return CLASS_E_NOAGGREGATION;
  23. CSourceText *pInst = new CSourceText;
  24. if (pInst == NULL)
  25. return E_OUTOFMEMORY;
  26. return pInst->QueryInterface(iid, ppv);
  27. }
  28. //////////////////////////////////////////////////////////////////////
  29. // IUnknown
  30. STDMETHODIMP
  31. CSourceText::QueryInterface(const IID &iid, void **ppv)
  32. {
  33. V_INAME(CSourceText::QueryInterface);
  34. V_PTRPTR_WRITE(ppv);
  35. V_REFGUID(iid);
  36. if (iid == IID_IUnknown || iid == IID_IDirectMusicSourceText)
  37. {
  38. *ppv = static_cast<IDirectMusicSourceText*>(this);
  39. }
  40. else if (iid == IID_IDirectMusicObject)
  41. {
  42. *ppv = static_cast<IDirectMusicObject*>(this);
  43. }
  44. else if (iid == IID_IPersistStream)
  45. {
  46. *ppv = static_cast<IPersistStream*>(this);
  47. }
  48. else if (iid == IID_IPersist)
  49. {
  50. *ppv = static_cast<IPersist*>(this);
  51. }
  52. else
  53. {
  54. *ppv = NULL;
  55. return E_NOINTERFACE;
  56. }
  57. reinterpret_cast<IUnknown*>(this)->AddRef();
  58. return S_OK;
  59. }
  60. STDMETHODIMP_(ULONG)
  61. CSourceText::AddRef()
  62. {
  63. return InterlockedIncrement(&m_cRef);
  64. }
  65. STDMETHODIMP_(ULONG)
  66. CSourceText::Release()
  67. {
  68. if (!InterlockedDecrement(&m_cRef))
  69. {
  70. delete this;
  71. LockModule(false);
  72. return 0;
  73. }
  74. return m_cRef;
  75. }
  76. //////////////////////////////////////////////////////////////////////
  77. // IPersistStream
  78. STDMETHODIMP
  79. CSourceText::Load(IStream* pStream)
  80. {
  81. V_INAME(CSourceText::Load);
  82. V_INTERFACE(pStream);
  83. // Record the stream's current position
  84. LARGE_INTEGER li;
  85. ULARGE_INTEGER ulStart;
  86. ULARGE_INTEGER ulEnd;
  87. li.HighPart = 0;
  88. li.LowPart = 0;
  89. HRESULT hr = pStream->Seek(li, STREAM_SEEK_CUR, &ulStart);
  90. if (FAILED(hr))
  91. return hr;
  92. assert(ulStart.HighPart == 0); // We don't expect streams that big.
  93. DWORD dwSavedPos = ulStart.LowPart;
  94. // Get the stream's end and record the total size
  95. hr = pStream->Seek(li, STREAM_SEEK_END, &ulEnd);
  96. if (FAILED(hr))
  97. return hr;
  98. assert(ulEnd.HighPart == 0);
  99. assert(ulEnd.LowPart > dwSavedPos);
  100. DWORD cch = ulEnd.LowPart - dwSavedPos;
  101. // Go back to the start and copy the characters
  102. li.HighPart = 0;
  103. li.LowPart = dwSavedPos;
  104. hr = pStream->Seek(li, STREAM_SEEK_SET, &ulStart);
  105. if (FAILED(hr))
  106. return hr;
  107. assert(ulStart.LowPart == dwSavedPos);
  108. CHAR *paszSource = new CHAR[cch + 1];
  109. if (!paszSource)
  110. return E_OUTOFMEMORY;
  111. DWORD cbRead;
  112. hr = pStream->Read(paszSource, cch, &cbRead);
  113. if (FAILED(hr))
  114. {
  115. assert(false);
  116. return hr;
  117. }
  118. paszSource[cch] = '\0';
  119. m_wstrText.AssignFromA(paszSource);
  120. delete[] paszSource;
  121. if (!m_wstrText)
  122. return E_OUTOFMEMORY;
  123. m_cwchText = wcslen(m_wstrText);
  124. return S_OK;
  125. }
  126. //////////////////////////////////////////////////////////////////////
  127. // IDirectMusicSourceText
  128. STDMETHODIMP_(void)
  129. CSourceText::GetTextLength(DWORD *pcwchRequiredBufferSize)
  130. {
  131. *pcwchRequiredBufferSize = m_cwchText + 1;
  132. }
  133. STDMETHODIMP_(void)
  134. CSourceText::GetText(WCHAR *pwszText)
  135. {
  136. wcscpy(pwszText, m_wstrText);
  137. }