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.

341 lines
12 KiB

  1. //==========================================================================;
  2. //
  3. // ksextend.h : additional infrastructure to extend the ks stuff so that it
  4. // works nicely from c++
  5. // Copyright (c) Microsoft Corporation 1995-1997.
  6. //
  7. /////////////////////////////////////////////////////////////////////////////
  8. #pragma once
  9. #ifndef KSEXTEND_H
  10. #define KSEXTEND_H
  11. #include <strmif.h>
  12. #include <uuids.h>
  13. #include <ks.h>
  14. #include <ksmedia.h>
  15. //NOTE: ksproxy won't define IKsPin without __STREAMS__ and then it requires CMediaType from
  16. // mtype.h
  17. #define __STREAMS__
  18. // for some reason in the area of media types the am guys have severely blurred the distinction
  19. // between their public client interface for apps and their internal class hierarchy for building
  20. // filters. mtype.h and mtype.cpp should be combined and placed into \sdk\include instead of
  21. // classes\base\include. they should also put an ifdef MMSYSTEM_H around their definitions
  22. // that use WAVEFORMATEX, so its not necessary to put all that stuff into your app if you're not
  23. // using it. to work around this i'm using the following hack:
  24. #include <mtype.h>
  25. #include <ksproxy.h>
  26. #include <stextend.h>
  27. #include <w32extend.h>
  28. const int KSMEDIUM_INPUTFLAG = 0x1;
  29. typedef unsigned char UBYTE;
  30. typedef CComQIPtr<IKsPropertySet, &IID_IKsPropertySet> PQKSPropertySet;
  31. typedef CComQIPtr<IKsPin, &__uuidof(IKsPin)> PQKSPin;
  32. class KSPinMedium : public KSIDENTIFIER {
  33. public:
  34. KSPinMedium() { memset(this, 0, sizeof(*this)); }
  35. KSPinMedium(REFGUID SetInit, ULONG IdInit, ULONG FlagsInit) {
  36. Set = SetInit;
  37. Id = IdInit;
  38. Flags = FlagsInit;
  39. }
  40. KSPinMedium(const KSPinMedium &rhs) {
  41. Set = rhs.Set;
  42. Id = rhs.Id;
  43. Flags = rhs.Flags;
  44. }
  45. KSPinMedium(const KSIDENTIFIER &rhs) {
  46. Set = rhs.Set;
  47. Id = rhs.Id;
  48. Flags = rhs.Flags;
  49. }
  50. KSPinMedium& operator=(const KSPinMedium &rhs) {
  51. if (&rhs != this) {
  52. Set = rhs.Set;
  53. Id = rhs.Id;
  54. Flags = rhs.Flags;
  55. }
  56. return *this;
  57. }
  58. #if 0
  59. // hopefully we can get the ks guys to fix their anonymous union problem
  60. // so that we don't need this hack
  61. operator KSIDENTIFIER() { return *(reinterpret_cast<KSIDENTIFIER*>(this)); }
  62. #endif
  63. KSPinMedium& operator=(const KSIDENTIFIER &rhs) {
  64. if (&rhs != reinterpret_cast<KSIDENTIFIER*>(this)) {
  65. Set = rhs.Set;
  66. Id = rhs.Id;
  67. Flags = rhs.Flags;
  68. }
  69. return *this;
  70. }
  71. bool operator==(const KSPinMedium &rhs) const {
  72. // NOTE: at some point there will be a flag in Flags to
  73. // indicate whether or not Id is significant for this object
  74. // at that point this method will need to change
  75. return (Id == rhs.Id && Set == rhs.Set);
  76. }
  77. bool operator!=(const KSPinMedium &rhs) const {
  78. // NOTE: at some point there will be a flag in Flags to
  79. // indicate whether or not Id is significant for this object
  80. // at that point this method will need to change
  81. return !(*this == rhs);
  82. }
  83. };
  84. #ifdef _DEBUG
  85. inline tostream &operator<<(tostream &dc, const KSPinMedium &g) {
  86. GUID2 g2(g.Set);
  87. dc << _T("KsPinMedium( ");
  88. g2.Dump(dc);
  89. dc << _T(", ") << hexdump(g.Id) << _T(", ") << hexdump(g.Flags) << _T(")");
  90. return dc;
  91. }
  92. #if 0
  93. inline CDumpContext &operator<<(CDumpContext &dc, const KSPinMedium &g) {
  94. GUID2 g2(g.Set);
  95. dc << "KsPinMedium( ";
  96. g2.Dump(dc);
  97. dc << ", " << hexdump(g.Id) << ", " << hexdump(g.Flags) << ")";
  98. return dc;
  99. }
  100. template<> struct equal_to<KSPinMedium> {
  101. bool operator()(const KSPinMedium& _X, const KSPinMedium& _Y) const {
  102. TraceDump << "equal_to<KSPinMedium> x = " << _X << " y = " << _Y;
  103. return (_X == _Y);
  104. }
  105. };
  106. #endif
  107. #endif
  108. const KSPinMedium NULL_MEDIUM(GUID_NULL, 0, 0);
  109. const KSPinMedium HOST_MEMORY_MEDIUM(KSMEDIUMSETID_Standard, 0, 0);
  110. // this is basically a CComQIPtr with appropriate CoMem* allocate/copy semantics
  111. // instead of refcount semantics and without the QI stuff.
  112. class PQKsMultipleItem {
  113. public:
  114. KSMULTIPLE_ITEM *p;
  115. PQKsMultipleItem() : p(NULL) {}
  116. virtual ~PQKsMultipleItem() {
  117. if (p) {
  118. CoTaskMemFree(p);
  119. p = NULL;
  120. }
  121. }
  122. operator KSMULTIPLE_ITEM*() const {return p;}
  123. KSMULTIPLE_ITEM& operator*() const {_ASSERTE(p!=NULL); return *p; }
  124. KSMULTIPLE_ITEM ** operator&() {ASSERT(p == NULL); return &p; }
  125. KSMULTIPLE_ITEM * operator->() const {_ASSERTE(p!=NULL); return p; }
  126. PQKsMultipleItem * address(void) { return this; }
  127. const PQKsMultipleItem * const_address(void) const { return this; }
  128. // this is expensive. don't do it unless you have to.
  129. PQKsMultipleItem& operator=(const KSMULTIPLE_ITEM &d) {
  130. if (&d != p) {
  131. if (p) {
  132. CoTaskMemFree(p);
  133. }
  134. p = reinterpret_cast<KSMULTIPLE_ITEM *>(CoTaskMemAlloc(d.Size));
  135. memcpy(p, &d, d.Size);
  136. }
  137. return *this;
  138. }
  139. PQKsMultipleItem& operator=(const KSMULTIPLE_ITEM *pd) {
  140. if (pd != p) {
  141. if (p) {
  142. CoTaskMemFree(p);
  143. }
  144. p = reinterpret_cast<KSMULTIPLE_ITEM *>(CoTaskMemAlloc(pd->Size));
  145. memcpy(p, pd, pd->Size);
  146. }
  147. return *this;
  148. }
  149. PQKsMultipleItem& operator=(const PQKsMultipleItem &d) {
  150. if (d.const_address() != this) {
  151. if (p) {
  152. CoTaskMemFree(p);
  153. }
  154. p = reinterpret_cast<KSMULTIPLE_ITEM *>(CoTaskMemAlloc(d.p->Size));
  155. memcpy(p, d.p, d.p->Size);
  156. }
  157. return *this;
  158. }
  159. PQKsMultipleItem& operator=(int d) {
  160. if (p) {
  161. CoTaskMemFree(p);
  162. p = NULL;
  163. }
  164. return *this;
  165. }
  166. #if 0
  167. bool operator==(const PQKsMultipleItem &d) const {
  168. return p->majortype == d.p->majortype &&
  169. (p->subtype == GUID_NULL || d.p->subtype == GUID_NULL || p->subtype == d.p->subtype);
  170. }
  171. bool operator!=(const PQKsMultipleItem &d) const {
  172. return !(*this == d);
  173. }
  174. #endif
  175. private:
  176. // i don't want spend the time to do a layered refcounted implementation here
  177. // but since these are CoTaskMem alloc'd we can't have multiple ref's without
  178. // a high risk of leaks. so we're just going to disallow the copy constructor
  179. // since copying is expensive anyway. we will allow explicit assignment which will
  180. // do a copy
  181. PQKsMultipleItem(const PQKsMultipleItem &d);
  182. };
  183. // this is a stl based template for containing KSMULTIPLEITEM lists
  184. // i've only implemented the stuff i need for certain of the stl predicates so this
  185. // isn't a complete collection with a true random access or bidirectional iterator
  186. // furthermore this won't work correctly with hterogeneous KSMULTIPLEITEM lists it
  187. // also won't work right for KSMI lists that have sizes and count headers in the sub items.
  188. // it could be easily extended to do all of these things but i don't have time and all
  189. // i need it for is mediums
  190. // Base is smart pointer wrapper class being contained in this container
  191. // Base_Inner is actual wrapped class that the smart pointer class contains
  192. template<class Value_Type, class Allocator = std::allocator<Value_Type> > class KsMultipleItem_Sequence : public PQKsMultipleItem {
  193. public:
  194. typedef typename Allocator::value_type value_type;
  195. typedef typename Allocator::size_type size_type;
  196. typedef typename Allocator::difference_type difference_type;
  197. typedef Allocator allocator_type;
  198. typedef typename Allocator::pointer value_ptr;
  199. typedef typename Allocator::const_pointer value_cptr;
  200. typedef typename Allocator::reference reference;
  201. typedef typename Allocator::const_reference const_reference;
  202. // CLASS iterator
  203. class iterator;
  204. friend class iterator;
  205. class iterator : public std::_Bidit<Value_Type, difference_type> {
  206. public:
  207. iterator(KsMultipleItem_Sequence<Value_Type, Allocator> *outerinit = NULL, value_type *currentinit = NULL) :
  208. outer(outerinit), current(currentinit) {}
  209. iterator(iterator &e) : current(e.current), outer(e.outer) {}
  210. reference operator*() const {return *current;}
  211. value_ptr operator->() const {return current; }
  212. iterator& operator++() {
  213. if (current) {
  214. current++;
  215. if (current >= reinterpret_cast<value_type *>(reinterpret_cast<UBYTE *>(outer->p) + outer->p->Size)) {
  216. current = NULL;
  217. }
  218. } else {
  219. current = reinterpret_cast<value_type *>(const_cast<UBYTE *>(reinterpret_cast<const UBYTE *>(outer->p)) + sizeof(KSMULTIPLE_ITEM));
  220. }
  221. return *this;
  222. }
  223. iterator& operator++(int) {
  224. iterator Tmp = *this;
  225. ++*this;
  226. return Tmp;
  227. }
  228. iterator& operator--() {
  229. if (current) {
  230. current--;
  231. if (current < reinterpret_cast<value_type *>(const_cast<UBYTE *>(reinterpret_cast<const UBYTE *>(outer->p)) + sizeof(KSMULTIPLE_ITEM))) {
  232. current = NULL;
  233. }
  234. } else {
  235. current = reinterpret_cast<value_type *>(reinterpret_cast<UBYTE *>(outer->p) + (outer->p->Size - sizeof(value_type)));
  236. }
  237. return (*this);
  238. }
  239. iterator operator--(int) {
  240. iterator _Tmp = *this;
  241. --*this;
  242. return (_Tmp);
  243. }
  244. bool operator==(const iterator& rhs) const
  245. {return (current == rhs.current); }
  246. bool operator!=(const iterator& rhs) const
  247. {return (!(*this == rhs)); }
  248. protected:
  249. value_type *current;
  250. const KsMultipleItem_Sequence<Value_Type, Allocator> *outer;
  251. };
  252. // CLASS const_iterator
  253. class const_iterator;
  254. friend class const_iterator;
  255. class const_iterator : public iterator {
  256. public:
  257. const_iterator(const KsMultipleItem_Sequence<Value_Type, Allocator> *outerinit = NULL, value_type *currentinit = NULL) {
  258. outer = outerinit;
  259. current = currentinit;
  260. }
  261. const_iterator(const_iterator &e) {
  262. current = e.current;
  263. outer = e.outer;
  264. }
  265. const_reference operator*() const {return iterator::operator*(); }
  266. value_cptr operator->() const {return iterator::operator->(); }
  267. const_iterator& operator++() { iterator::operator++(); return *this;}
  268. const_iterator operator++(int) {
  269. const_iterator Tmp = *this;
  270. ++*this;
  271. return (Tmp);
  272. }
  273. const_iterator& operator--() {iterator::operator--(); return (*this); }
  274. const_iterator operator--(int) {
  275. const_iterator Tmp = *this;
  276. --*this;
  277. return (Tmp);
  278. }
  279. bool operator==(const const_iterator& rhs) const
  280. {return iterator::operator==(rhs); }
  281. bool operator!=(const const_iterator& rhs) const
  282. {return (!(*this == rhs)); }
  283. };
  284. KsMultipleItem_Sequence() {}
  285. virtual ~KsMultipleItem_Sequence() {}
  286. iterator begin() {
  287. return iterator(this, ((p->Count) ? reinterpret_cast<value_ptr>(reinterpret_cast<UBYTE *>(p) + sizeof(KSMULTIPLE_ITEM)) : NULL));
  288. }
  289. const_iterator begin() const {
  290. return const_iterator(this, ((p->Count) ? reinterpret_cast<value_ptr>(reinterpret_cast<UBYTE *>(p) + sizeof(KSMULTIPLE_ITEM)) : NULL));
  291. }
  292. iterator end() { return iterator(); }
  293. const_iterator end() const { return const_iterator(); }
  294. size_type size() const {
  295. return p->Count;
  296. }
  297. private:
  298. // no copy constructor, its too expensive. see PQKsMultiple item for further details
  299. KsMultipleItem_Sequence(KsMultipleItem_Sequence &a);
  300. KsMultipleItem_Sequence(PQKsMultipleItem &a);
  301. };
  302. typedef KsMultipleItem_Sequence<KSPinMedium> KSMediumList;
  303. #endif
  304. // end of file - ksextend.h