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.

221 lines
6.8 KiB

  1. //==========================================================================;
  2. //
  3. // segimpl.h : additional infrastructure to support implementing IMSVidGraphSegment
  4. // nicely from c++
  5. // Copyright (c) Microsoft Corporation 1999.
  6. //
  7. /////////////////////////////////////////////////////////////////////////////
  8. #pragma once
  9. #ifndef SEGIMPL_H
  10. #define SEGIMPL_H
  11. #include <segment.h>
  12. #include <seg.h>
  13. #include <filterenum.h>
  14. #include "devsegimpl.h"
  15. namespace MSVideoControl {
  16. typedef CComQIPtr<IMSVidCtl> PQVidCtl;
  17. template<class T, enum MSVidSegmentType segtype, LPCGUID pCategory, class MostDerivedClass = IMSVidGraphSegment>
  18. class DECLSPEC_NOVTABLE IMSVidGraphSegmentImpl :
  19. public MostDerivedClass,
  20. public virtual CMSVidDeviceSegmentImpl {
  21. protected:
  22. HRESULT Unload() {
  23. if (!m_fInit || !m_pContainer) {
  24. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED);
  25. }
  26. try {
  27. ASSERT(m_pContainer.GetGraph() == m_pGraph);
  28. // undone: dynamic graph building may allow this
  29. if (!m_pGraph.IsStopped()) {
  30. return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidGraphSegment), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  31. }
  32. if (m_pGraph) {
  33. #ifdef CRASH
  34. std::for_each(m_Filters.begin(),
  35. m_Filters.end(),
  36. arity1_member_obj(m_pGraph,
  37. arity1_member(&DSGraph::RemoveFilter))
  38. );
  39. #else
  40. #if 0
  41. std::for_each(m_Filters.begin(),
  42. m_Filters.end(),
  43. arity1opmf<arity1pmf<DSGraph, DSFilter&, bool> >(
  44. m_pGraph,
  45. arity1_member(&DSGraph::RemoveFilter)));
  46. #endif
  47. for(DSFilterList::iterator i = m_Filters.begin(); i != m_Filters.end(); ++i){
  48. HRESULT hr = m_pGraph->RemoveFilter(*i);
  49. _ASSERT((L"Failed to remove filter from graph during Unload.", SUCCEEDED(hr)));
  50. }
  51. #endif
  52. }
  53. m_Filters.clear();
  54. m_pGraph.Release();
  55. // DON'T release the container. we're guaranteed nested lifetimes
  56. // and an addref creates circular refcounts so we never unload.
  57. // thus, we didn't addref and a release will over release and
  58. // cause destruction before other people are done with the container
  59. m_pContainer.p = NULL;
  60. } catch(ComException &e) {
  61. return e;
  62. } catch(...) {
  63. return E_UNEXPECTED;
  64. }
  65. return NOERROR;
  66. }
  67. public:
  68. // DON'T addref the container. we're guaranteed nested lifetimes
  69. // and an addref creates circular refcounts so we never unload.
  70. IMSVidGraphSegmentImpl() {}
  71. virtual ~IMSVidGraphSegmentImpl() {
  72. if (m_fInit && m_pContainer) {
  73. Unload();
  74. }
  75. }
  76. STDMETHOD(GetClassID) (LPCLSID guid) {
  77. try {
  78. memcpy(guid, &__uuidof(T), sizeof(CLSID));
  79. return NOERROR;
  80. } catch(...) {
  81. return E_POINTER;
  82. }
  83. }
  84. STDMETHOD(put_Init)(IUnknown * pInit) {
  85. if (m_fInit) {
  86. return NOERROR;
  87. }
  88. try {
  89. m_pDev = pInit;
  90. m_fInit = true;
  91. return NOERROR;
  92. } catch(...) {
  93. m_fInit = false;
  94. return E_POINTER;
  95. }
  96. }
  97. STDMETHOD(get_Init)(IUnknown ** pInit) {
  98. try{
  99. if (!pInit) {
  100. return E_POINTER;
  101. }
  102. m_pDev.CopyTo(pInit);
  103. return NOERROR;
  104. } catch(...) {
  105. m_fInit = false;
  106. return E_POINTER;
  107. }
  108. }
  109. STDMETHOD(get_Container)(IMSVidGraphSegmentContainer **ppCtl) {
  110. if (!m_fInit) {
  111. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED);
  112. }
  113. try {
  114. return m_pContainer.CopyTo(ppCtl);
  115. } catch(...) {
  116. return E_POINTER;
  117. }
  118. }
  119. STDMETHOD(put_Container)(IMSVidGraphSegmentContainer *pCtl) {
  120. try {
  121. if (!pCtl) {
  122. return Unload();
  123. }
  124. if (m_pContainer) {
  125. if (!m_pContainer.IsEqualObject(VWSegmentContainer(pCtl))) {
  126. //undone: support moving to different graph
  127. return ImplReportError(__uuidof(T), IDS_OBJ_ALREADY_INIT, __uuidof(IMSVidGraphSegment), CO_E_ALREADYINITIALIZED);
  128. } else {
  129. return NO_ERROR;
  130. }
  131. }
  132. // DON'T addref the container. we're guaranteed nested lifetimes
  133. // and an addref creates circular refcounts so we never unload.
  134. m_pContainer.p = pCtl;
  135. m_pGraph = m_pContainer.GetGraph();
  136. } catch(...) {
  137. return E_UNEXPECTED;
  138. }
  139. return NOERROR;
  140. }
  141. STDMETHOD(EnumFilters)(IEnumFilters * * pNewEnum) {
  142. if (!m_fInit) {
  143. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED);
  144. }
  145. if (pNewEnum == NULL)
  146. return E_POINTER;
  147. PQEnumFilters p;
  148. try {
  149. p = new CFilterEnumOnDSFilterList(m_Filters);
  150. } catch (...) {
  151. return E_OUTOFMEMORY;
  152. }
  153. try {
  154. *pNewEnum = p.Detach();
  155. } catch (...) {
  156. return E_POINTER;
  157. }
  158. return NOERROR;
  159. }
  160. STDMETHOD(get_Type)(MSVidSegmentType *pType) {
  161. try {
  162. *pType = segtype;
  163. return NOERROR;
  164. } catch(...) {
  165. return E_POINTER;
  166. }
  167. }
  168. STDMETHOD(get_Category)(GUID *pGuid) {
  169. if (!m_fInit) {
  170. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED);
  171. }
  172. try {
  173. memcpy(pGuid, pCategory, sizeof(*pGuid));
  174. return NOERROR;
  175. } catch(...) {
  176. return E_POINTER;
  177. }
  178. }
  179. STDMETHOD(Build)() {
  180. return E_NOTIMPL;
  181. }
  182. STDMETHOD(PreRun)() {
  183. return E_NOTIMPL;
  184. }
  185. STDMETHOD(PostRun)() {
  186. return E_NOTIMPL;
  187. }
  188. STDMETHOD(PreStop)() {
  189. return E_NOTIMPL;
  190. }
  191. STDMETHOD(PostStop)() {
  192. return E_NOTIMPL;
  193. }
  194. STDMETHOD(Select)(IUnknown *pItem) {
  195. return E_NOTIMPL;
  196. }
  197. STDMETHOD(OnEventNotify)(LONG lEvent, LONG_PTR lParm1, LONG_PTR lParm2) {
  198. return E_NOTIMPL;
  199. }
  200. STDMETHOD(OnWindowMessage)(UINT uMsg, WPARAM wParam, LPARAM lParam) {
  201. return E_NOTIMPL;
  202. }
  203. STDMETHOD(Decompose)(){
  204. return E_NOTIMPL;
  205. }
  206. };
  207. }; // namespace
  208. #endif
  209. // end of file - segimpl.h