Source code of Windows XP (NT5)
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.

379 lines
11 KiB

  1. //==========================================================================;
  2. //
  3. // Devices.h : Declaration of the CDevices
  4. // Copyright (c) Microsoft Corporation 1999.
  5. //
  6. /////////////////////////////////////////////////////////////////////////////
  7. #pragma once
  8. #ifndef DEVICES_H_
  9. #define DEVICES_H_
  10. #include <vector>
  11. #include <objectwithsiteimplsec.h>
  12. #include "devseq.h"
  13. #if 0
  14. #define DEBUGREGISTRY
  15. #endif
  16. #ifdef DEBUGREGISTRY
  17. #include <statreg.h>
  18. #endif
  19. void CtorStaticVWDevicesFwdSeqPMFs(void);
  20. void DtorStaticVWDevicesFwdSeqPMFs(void);
  21. template<class DEVICETYPECOLLECTIONINTERFACE,
  22. class DEVICETYPEINTERFACE,
  23. const CLSID* DEVICETYPE_CLSID,
  24. int IDSPROGID,
  25. int IDSDESC> class CTypedDevices;
  26. template<class DEVICETYPECOLLECTIONINTERFACE, class DEVICETYPEINTERFACE, const CLSID* DEVICETYPE_CLSID, int IDSPROGID, int IDSDESC> class ATL_NO_VTABLE CTypedDevicesBase :
  27. public CComObjectRootEx<CComSingleThreadModel>,
  28. public CComCoClass<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC>, DEVICETYPE_CLSID>,
  29. public ISupportErrorInfo,
  30. public IObjectWithSiteImplSec<CTypedDevicesBase>,
  31. public IDispatchImpl<DEVICETYPECOLLECTIONINTERFACE, &__uuidof(DEVICETYPECOLLECTIONINTERFACE), &LIBID_MSVidCtlLib>
  32. {
  33. public:
  34. DECLARE_PROTECT_FINAL_CONSTRUCT()
  35. BEGIN_COM_MAP(CTypedDevicesBase)
  36. COM_INTERFACE_ENTRY(DEVICETYPECOLLECTIONINTERFACE)
  37. COM_INTERFACE_ENTRY(IDispatch)
  38. COM_INTERFACE_ENTRY(IObjectWithSite)
  39. COM_INTERFACE_ENTRY(ISupportErrorInfo)
  40. END_COM_MAP()
  41. BEGIN_CATEGORY_MAP(CTypedDevicesBase)
  42. IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
  43. IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
  44. IMPLEMENTED_CATEGORY(CATID_PersistsToPropertyBag)
  45. END_CATEGORY_MAP()
  46. // ISupportsErrorInfo
  47. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
  48. {
  49. static const IID* arr[] =
  50. {
  51. &__uuidof(DEVICETYPECOLLECTIONINTERFACE)
  52. };
  53. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  54. {
  55. if (InlineIsEqualGUID(*arr[i],riid))
  56. return S_OK;
  57. }
  58. return S_FALSE;
  59. }
  60. virtual ~CTypedDevicesBase() {}
  61. };
  62. class CDevEnum;
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CTypedDevices
  65. template<class DEVICETYPECOLLECTIONINTERFACE,
  66. class DEVICETYPEINTERFACE,
  67. const CLSID* DEVICETYPE_CLSID,
  68. int IDSPROGID,
  69. int IDSDESC> class CTypedDevices :
  70. public CComObject<CTypedDevicesBase<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC> >
  71. {
  72. typedef CComQIPtr<DEVICETYPECOLLECTIONINTERFACE> PQDEVICETYPECOLLECTIONINTERFACE;
  73. typedef CComQIPtr<DEVICETYPEINTERFACE> PQDEVICETYPEINTERFACE;
  74. PQDEVICETYPECOLLECTIONINTERFACE m_Collection;
  75. bool m_fRO;
  76. bool m_fValid;
  77. public:
  78. CTypedDevices(const DeviceCollection &Devices = DeviceCollection(), bool fRO = false, bool fValid = false) :
  79. m_fRO(fRO), m_fValid(fValid) {
  80. m_Devices.clear();
  81. m_Devices.insert(m_Devices.end(), Devices.begin(), Devices.end());
  82. }
  83. CTypedDevices(bool fRO, bool fValid = false) :
  84. m_Devices(DeviceCollection()), m_fRO(fRO), m_fValid(fValid) {}
  85. CTypedDevices(const CTypedDevices &src) :
  86. m_fRO(src.m_fRO), m_fValid(src.m_fValid) {
  87. m_Devices.clear();
  88. m_Devices.insert(m_Devices.end(), src.m_Devices.begin(), src.m_Devices.end());
  89. }
  90. CTypedDevices(const PQDEVICETYPECOLLECTIONINTERFACE& src) :
  91. m_fRO(static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
  92. DEVICETYPEINTERFACE,
  93. DEVICETYPE_CLSID,
  94. IDSPROGID,
  95. IDSDESC> *>(src.p)->m_fRO),
  96. m_fValid(static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
  97. DEVICETYPEINTERFACE,
  98. DEVICETYPE_CLSID,
  99. IDSPROGID,
  100. IDSDESC> *>(src.p)->m_fValid) {
  101. m_Devices.clear();
  102. m_Devices.insert(m_Devices.end(),
  103. static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
  104. DEVICETYPEINTERFACE,
  105. DEVICETYPE_CLSID,
  106. IDSPROGID,
  107. IDSDESC> *>(src.p)->m_Devices.begin(),
  108. static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
  109. DEVICETYPEINTERFACE,
  110. DEVICETYPE_CLSID,
  111. IDSPROGID,
  112. IDSDESC> *>(src.p)->m_Devices.end()
  113. );
  114. }
  115. CTypedDevices<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC> &operator=(const CTypedDevices<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC> &rhs) {
  116. if (this != &rhs) {
  117. m_Devices.clear();
  118. m_Devices.insert(m_Devices.end(), rhs.m_Devices.begin(), rhs.m_Devices.end());
  119. m_fRO = rhs.m_fRO;
  120. m_fValid = rhs.m_fValid;
  121. }
  122. }
  123. virtual ~CTypedDevices() {
  124. }
  125. static HRESULT WINAPI UpdateRegistry(BOOL bRegister) {
  126. CRegObject ro;
  127. return CObjRegHelp::RegisterAutomationClass(bRegister ? true : false,
  128. ro,
  129. IDS_PROJNAME,
  130. IDSPROGID,
  131. IDSDESC,
  132. *DEVICETYPE_CLSID,
  133. LIBID_MSVidCtlLib);
  134. }
  135. // IMSVidDevices
  136. public:
  137. inline bool IsRO() { return m_fRO; }
  138. inline bool GetValid() { return m_fValid; }
  139. inline void SetValid(bool fValid) { m_fValid = fValid; }
  140. __declspec(property(get=GetValid, put=SetValid)) bool Valid;
  141. DeviceCollection m_Devices;
  142. // IMSVidDevices
  143. STDMETHOD(get_Count)(LONG * lCount)
  144. {
  145. if (lCount == NULL)
  146. return E_POINTER;
  147. try {
  148. *lCount = m_Devices.size();
  149. } catch(...) {
  150. return E_POINTER;
  151. }
  152. return NOERROR;
  153. }
  154. STDMETHODIMP get__NewEnum(IEnumVARIANT * * pD)
  155. {
  156. if (pD == NULL)
  157. return E_POINTER;
  158. PQEnumVARIANT temp;
  159. try {
  160. temp = new CDevEnum(PQDispatch(this), m_Devices);
  161. } catch(...) {
  162. return E_OUTOFMEMORY;
  163. }
  164. try {
  165. *pD = temp.Detach();
  166. } catch(...) {
  167. return E_POINTER;
  168. }
  169. return NOERROR;
  170. }
  171. STDMETHOD(get_Item)(VARIANT v, DEVICETYPEINTERFACE * * pDB)
  172. {
  173. if (pDB == NULL)
  174. return E_POINTER;
  175. int idx;
  176. CComVariant vidx;
  177. try {
  178. if (SUCCEEDED(vidx.ChangeType(VT_I4, &v))) {
  179. idx = vidx.lVal;
  180. } else {
  181. return DISP_E_TYPEMISMATCH;
  182. }
  183. if (idx >= m_Devices.size()) {
  184. return DISP_E_BADINDEX;
  185. }
  186. } catch(...) {
  187. return E_UNEXPECTED;
  188. }
  189. try {
  190. PQDevice pd(m_Devices[idx]);
  191. if (!pd) {
  192. return E_UNEXPECTED;
  193. }
  194. *pDB = PQDEVICETYPEINTERFACE(pd);
  195. if (!*pDB) {
  196. return E_UNEXPECTED;
  197. }
  198. (*pDB)->AddRef();
  199. } catch(...) {
  200. return E_POINTER;
  201. }
  202. return NOERROR;
  203. }
  204. STDMETHOD(Add)(DEVICETYPEINTERFACE * pDB)
  205. {
  206. if (m_fRO) {
  207. return Error(IDS_E_ROCOLLECTION, __uuidof(DEVICETYPECOLLECTIONINTERFACE), E_ACCESSDENIED);
  208. }
  209. try {
  210. PQDevice p(pDB);
  211. try {
  212. m_Devices.push_back(p);
  213. } catch(...) {
  214. return E_OUTOFMEMORY;
  215. }
  216. } catch(...) {
  217. E_POINTER;
  218. }
  219. return NOERROR;
  220. }
  221. STDMETHOD(Remove)(VARIANT v)
  222. {
  223. if (m_fRO) {
  224. return E_ACCESSDENIED;
  225. }
  226. int idx;
  227. CComVariant vidx;
  228. try {
  229. if (SUCCEEDED(vidx.ChangeType(VT_I4, &v))) {
  230. idx = vidx.lVal;
  231. } else {
  232. return DISP_E_TYPEMISMATCH;
  233. }
  234. if (idx >= m_Devices.size()) {
  235. return DISP_E_BADINDEX;
  236. }
  237. m_Devices.erase(m_Devices.begin() + idx);
  238. } catch(...) {
  239. return E_UNEXPECTED;
  240. }
  241. return NOERROR;
  242. }
  243. };
  244. typedef CTypedDevices<IMSVidInputDevices, IMSVidInputDevice, &CLSID_MSVidInputDevices, IDS_INPUTDEVICES_PROGID, IDS_INPUTDEVICES_DESCRIPTION> CInputDevices;
  245. typedef CTypedDevices<IMSVidOutputDevices, IMSVidOutputDevice, &CLSID_MSVidOutputDevices, IDS_OUTPUTDEVICES_PROGID, IDS_OUTPUTDEVICES_DESCRIPTION> COutputDevices;
  246. typedef CTypedDevices<IMSVidVideoRendererDevices, IMSVidVideoRenderer, &CLSID_MSVidVideoRendererDevices, IDS_VIDEORENDERERS_PROGID, IDS_VIDEORENDERERS_DESCRIPTION> CVideoRendererDevices;
  247. typedef CTypedDevices<IMSVidAudioRendererDevices, IMSVidAudioRenderer, &CLSID_MSVidAudioRendererDevices, IDS_AUDIORENDERERS_PROGID, IDS_AUDIORENDERERS_DESCRIPTION> CAudioRendererDevices;
  248. typedef CTypedDevices<IMSVidFeatures, IMSVidFeature, &CLSID_MSVidFeatures, IDS_FEATURES_PROGID, IDS_FEATURES_DESCRIPTION> CFeatures;
  249. /////////////////////////////////////////////////////////////////////////////
  250. // CDevEnum
  251. class ATL_NO_VTABLE CDevEnumBase :
  252. public CComObjectRootEx<CComSingleThreadModel>,
  253. public IObjectWithSiteImplSec<CDevEnumBase>,
  254. public IEnumVARIANT
  255. {
  256. BEGIN_COM_MAP(CDevEnumBase)
  257. COM_INTERFACE_ENTRY(IEnumVARIANT)
  258. COM_INTERFACE_ENTRY(IObjectWithSite)
  259. END_COM_MAP()
  260. DECLARE_PROTECT_FINAL_CONSTRUCT()
  261. virtual ~CDevEnumBase() {}
  262. };
  263. /////////////////////////////////////////////////////////////////////////////
  264. class CDevEnum : public CComObject<CDevEnumBase>
  265. {
  266. public:
  267. CDevEnum(const PQDispatch& pDevices, DeviceCollection& dci) :
  268. m_pDevices(pDevices), m_DC(dci), i(dci.begin()) {}
  269. CDevEnum(const CDevEnum &orig) :
  270. m_pDevices(orig.m_pDevices), m_DC(orig.m_DC), i(orig.i) {}
  271. virtual ~CDevEnum() {}
  272. // IDevEnum
  273. public:
  274. PQDispatch m_pDevices;
  275. DeviceCollection& m_DC;
  276. DeviceCollection::iterator i;
  277. // IEnumVARIANT
  278. STDMETHOD(Next)(ULONG celt, VARIANT * rgvar, ULONG * pceltFetched)
  279. {
  280. // pceltFetched can legally == 0
  281. //
  282. if (pceltFetched != NULL) {
  283. try {
  284. *pceltFetched = 0;
  285. } catch(...) {
  286. return E_POINTER;
  287. }
  288. }
  289. for (ULONG l=0; l < celt; l++) {
  290. try {
  291. VariantInit( &rgvar[l] ) ;
  292. } catch(...) {
  293. return E_POINTER;
  294. }
  295. }
  296. // Retrieve the next celt elements.
  297. HRESULT hr = NOERROR ;
  298. for (l = 0;i != m_DC.end() && celt != 0 ; ++i, ++l, --celt) {
  299. rgvar[l].vt = VT_DISPATCH ;
  300. rgvar[l].pdispVal = PQDevice(*i).Detach();
  301. if (pceltFetched != NULL) {
  302. (*pceltFetched)++ ;
  303. }
  304. }
  305. if (celt != 0) {
  306. hr = ResultFromScode( S_FALSE ) ;
  307. }
  308. return hr ;
  309. }
  310. STDMETHOD(Skip)(ULONG celt)
  311. {
  312. for (;i != m_DC.end() && celt--; ++i);
  313. return (celt == 0 ? NOERROR : ResultFromScode( S_FALSE )) ;
  314. }
  315. STDMETHOD(Reset)()
  316. {
  317. i = m_DC.begin();
  318. return NOERROR;
  319. }
  320. STDMETHOD(Clone)(IEnumVARIANT * * ppenum)
  321. {
  322. if (ppenum == NULL)
  323. return E_POINTER;
  324. PQEnumVARIANT temp;
  325. try {
  326. temp = new CDevEnum(*this);
  327. } catch(...) {
  328. return E_OUTOFMEMORY;
  329. }
  330. try {
  331. *ppenum = temp.Detach();
  332. } catch(...) {
  333. return E_POINTER;
  334. }
  335. return NOERROR;
  336. }
  337. };
  338. #endif
  339. //end of file devices.h