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.

243 lines
5.8 KiB

  1. //+---------------------------------------------------------------------
  2. //
  3. // File: stdfact.cxx
  4. //
  5. // Contents: Standard IClassFactory implementation
  6. //
  7. // Classes: StdClassFactory
  8. // CDynamicCF
  9. //
  10. // History: 6-21-94 adams added CDynamicCF
  11. // 19-Jul-94 doncl init StdClassFactory::_ulRefs to 1
  12. //
  13. //----------------------------------------------------------------------
  14. #include "procs.hxx"
  15. //+------------------------------------------------------------------------
  16. //
  17. // StdClassFactory Implementation
  18. //
  19. //-------------------------------------------------------------------------
  20. //+---------------------------------------------------------------
  21. //
  22. // Member: StdClassFactory::QueryInterface, public
  23. //
  24. // Synopsis: Method of IUnknown interface
  25. //
  26. //----------------------------------------------------------------
  27. STDMETHODIMP
  28. StdClassFactory::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  29. {
  30. if (!ppv)
  31. RRETURN(E_INVALIDARG);
  32. if (IsEqualIID(riid, IID_IUnknown) ||
  33. IsEqualIID(riid, IID_IClassFactory))
  34. {
  35. *ppv = (IClassFactory *) this;
  36. }
  37. else
  38. {
  39. *ppv = NULL;
  40. return E_NOINTERFACE;
  41. }
  42. ((IUnknown *)*ppv)->AddRef();
  43. return S_OK;
  44. }
  45. //+---------------------------------------------------------------
  46. //
  47. // Member: StdClassFactory::AddRef, public
  48. //
  49. // Synopsis: Method of IUnknown interface
  50. //
  51. //----------------------------------------------------------------
  52. STDMETHODIMP_(ULONG)
  53. StdClassFactory::AddRef(void)
  54. {
  55. ADsAssert(_ulRefs);
  56. if (_ulRefs == 1)
  57. INC_OBJECT_COUNT();
  58. return ++_ulRefs;
  59. }
  60. //+---------------------------------------------------------------
  61. //
  62. // Member: StdClassFactory::Release, public
  63. //
  64. // Synopsis: Method of IUnknown interface
  65. //
  66. //----------------------------------------------------------------
  67. STDMETHODIMP_(ULONG)
  68. StdClassFactory::Release(void)
  69. {
  70. ADsAssert(_ulRefs > 1);
  71. if (--_ulRefs == 1)
  72. DEC_OBJECT_COUNT();
  73. return _ulRefs;
  74. }
  75. //+---------------------------------------------------------------
  76. //
  77. // Member: StdClassFactory::LockServer, public
  78. //
  79. // Synopsis: Method of IClassFactory interface
  80. //
  81. // Notes: Since class factories based on this class are global static
  82. // objects, this method doesn't serve much purpose.
  83. //
  84. //----------------------------------------------------------------
  85. STDMETHODIMP
  86. StdClassFactory::LockServer (BOOL fLock)
  87. {
  88. if (fLock)
  89. INC_OBJECT_COUNT();
  90. else
  91. DEC_OBJECT_COUNT();
  92. return NOERROR;
  93. }
  94. #ifdef DOCGEN
  95. //+---------------------------------------------------------------
  96. //
  97. // Member: StdClassFactory::CreateInstance, public
  98. //
  99. // Synopsis: Manufactures an instance of the class
  100. //
  101. // Notes: This pure virtual function must be overridden by the
  102. // inheriting class because the base class does not know what
  103. // class to instantiate.
  104. //
  105. //----------------------------------------------------------------
  106. STDMETHODIMP
  107. StdClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
  108. REFIID iid,
  109. LPVOID FAR* ppv) {};
  110. //REVIEW: how to enforce ref counting of Class factory in object
  111. // constructor/destructor? Can we do this in a conjunction of StdUnknown
  112. // with StdClassFactory.
  113. #endif // DOCGEN
  114. //+------------------------------------------------------------------------
  115. //
  116. // CDynamicCF Implementation
  117. //
  118. //-------------------------------------------------------------------------
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Member: CDynamicCF::CDynamicCF
  122. //
  123. // Synopsis: Constructor.
  124. //
  125. // History: 7-20-94 adams Created
  126. //
  127. //----------------------------------------------------------------------------
  128. CDynamicCF::CDynamicCF(void)
  129. {
  130. _ulRefs = 1;
  131. INC_OBJECT_COUNT();
  132. }
  133. //+---------------------------------------------------------------------------
  134. //
  135. // Member: CDynamicCF::~CDynamicCF
  136. //
  137. // Synopsis: Destructor.
  138. //
  139. // History: 7-20-94 adams Created
  140. //
  141. //----------------------------------------------------------------------------
  142. CDynamicCF::~CDynamicCF(void)
  143. {
  144. DEC_OBJECT_COUNT();
  145. }
  146. //+---------------------------------------------------------------
  147. //
  148. // Member: CDynamicCF::QueryInterface, public
  149. //
  150. // Synopsis: Method of IUnknown interface
  151. //
  152. //----------------------------------------------------------------
  153. STDMETHODIMP
  154. CDynamicCF::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  155. {
  156. if (!ppv)
  157. RRETURN(E_INVALIDARG);
  158. if (IsEqualIID(riid, IID_IUnknown) ||
  159. IsEqualIID(riid, IID_IClassFactory))
  160. {
  161. *ppv = (IClassFactory *) this;
  162. }
  163. else
  164. {
  165. *ppv = NULL;
  166. return E_NOINTERFACE;
  167. }
  168. ((IUnknown *)*ppv)->AddRef();
  169. return S_OK;
  170. }
  171. //+---------------------------------------------------------------
  172. //
  173. // Member: CDynamicCF::LockServer, public
  174. //
  175. // Synopsis: Since these class factories are on the heap, we have
  176. // to implement this properly. In our case, LockServer is
  177. // equivalent to AddRef/Release because we don't have a single
  178. // 'application' object that we can put an external lock on.
  179. // Each time CreateInstance is called, we return a newly created
  180. // object. If, instead, we returned a pointer to an existing
  181. // object, we would need to call CoLockObjectExternal on that
  182. // global object in the implementation of LockServer to keep it
  183. // alive.
  184. //
  185. //----------------------------------------------------------------
  186. STDMETHODIMP
  187. CDynamicCF::LockServer (BOOL fLock)
  188. {
  189. if (fLock)
  190. {
  191. _ulRefs++;
  192. }
  193. else
  194. {
  195. _ulRefs--;
  196. Assert(_ulRefs != 0 && "Improper use of IClassFactory::LockServer!");
  197. }
  198. return S_OK;
  199. }