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.

284 lines
7.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: stdclass.cxx
  7. //
  8. // Contents: Implementation for standard base class for factory objects
  9. //
  10. // Classes: CStdClassFactory
  11. //
  12. // Functions: DllGetClassObject
  13. // DllCanUnloadNow
  14. //
  15. // History: 28-May-93 MikeSe Created
  16. // 2-Jul-93 ShannonC Split into CStdFactory and CStdClassFactory
  17. //
  18. //--------------------------------------------------------------------------
  19. #include <stdclass.hxx>
  20. //+-------------------------------------------------------------------------
  21. //
  22. // Global data
  23. //
  24. //--------------------------------------------------------------------------
  25. CStdClassFactory * CStdClassFactory::_gpcfFirst = NULL;
  26. ULONG CStdClassFactory::_gcDllRefs = 0;
  27. //+-------------------------------------------------------------------------
  28. //
  29. // Function: DllGetClassObject
  30. //
  31. // Synopsis: Standard implementation of entrypoint required by binder.
  32. //
  33. // Arguments: [rclsid] -- class id to find
  34. // [riid] -- interface to return
  35. // [ppv] -- output pointer
  36. //
  37. // Returns: E_UNEXPECTED if class not found
  38. // Otherwise, whatever is returned by the class's QI
  39. //
  40. // Algorithm: Searches the linked list for the required class.
  41. //
  42. // Notes:
  43. //
  44. //--------------------------------------------------------------------------
  45. STDAPI DllGetClassObject (
  46. REFCLSID rclsid,
  47. REFIID riid,
  48. LPVOID FAR* ppv )
  49. {
  50. HRESULT hr;
  51. // Note: this doesn't need to be reentrancy protected either
  52. // as the linked list is fixed post-init.
  53. CStdClassFactory * pcfTry = CStdClassFactory::_gpcfFirst;
  54. while ( pcfTry != NULL &&
  55. !IsEqualCLSID ( rclsid, pcfTry->_rcls ) )
  56. {
  57. pcfTry = pcfTry->_pcfNext;
  58. }
  59. if ( pcfTry != NULL )
  60. {
  61. // Note: QueryInterface is supposed (required) to do an AddRef
  62. // so we don't need to directly.
  63. hr = pcfTry->QueryInterface ( riid, ppv );
  64. }
  65. else
  66. {
  67. hr = E_UNEXPECTED;
  68. *ppv = NULL;
  69. }
  70. return hr;
  71. }
  72. //+-------------------------------------------------------------------------
  73. //
  74. // Function: DllCanUnloadNow
  75. //
  76. // Synopsis: Standard entrypoint required by binder
  77. //
  78. // Returns: S_OK if DLL reference count is zero
  79. // S_FALSE otherwise
  80. //
  81. // Notes:
  82. //
  83. //--------------------------------------------------------------------------
  84. STDAPI DllCanUnloadNow ()
  85. {
  86. return (CStdClassFactory::_gcDllRefs==0)? S_OK: S_FALSE;
  87. }
  88. //+-------------------------------------------------------------------------
  89. //
  90. // Function: DllAddRef
  91. //
  92. // Synopsis: Allows incrementing the DLL reference count without
  93. // AddRef'ing a specific class object.
  94. //
  95. // Notes:
  96. //
  97. //--------------------------------------------------------------------------
  98. STDAPI_(void) DllAddRef ()
  99. {
  100. InterlockedIncrement ( (LONG*)&CStdClassFactory::_gcDllRefs );
  101. }
  102. //+-------------------------------------------------------------------------
  103. //
  104. // Function: DllRelease
  105. //
  106. // Synopsis: Allows decrementing the DLL reference count without
  107. // Release'ing a specific class object.
  108. //
  109. // Notes:
  110. //
  111. //--------------------------------------------------------------------------
  112. STDAPI_(void) DllRelease ()
  113. {
  114. InterlockedDecrement ( (LONG*)&CStdClassFactory::_gcDllRefs );
  115. }
  116. //+-------------------------------------------------------------------------
  117. //
  118. // Member: CStdClassFactory::CStdClassFactory
  119. //
  120. // Synopsis: Constructor
  121. //
  122. // Effects: Initialises member variables
  123. // Adds object to global linked list.
  124. //
  125. // Arguments: [rcls] -- class id of derived class
  126. // [punk] -- controlling IUnknown of derived class
  127. //
  128. // Notes: Do not make this function inline, even though it appears
  129. // trivial, since it is necessary to force the static library
  130. // to be pulled in.
  131. //
  132. //--------------------------------------------------------------------------
  133. CStdClassFactory::CStdClassFactory (
  134. REFCLSID rcls )
  135. :_rcls(rcls),
  136. _cRefs(1) // DaveStr - 11/3/94 - Ole32 requires (_cRefs >= 1)
  137. {
  138. // Note: the following is not protected against reentrancy, since it
  139. // is assumed to take place prior to LibMain/main/WinMain.
  140. _pcfNext = _gpcfFirst;
  141. _gpcfFirst = this;
  142. }
  143. //+-------------------------------------------------------------------------
  144. //
  145. // Method: CStdClassFactory::LockServer
  146. //
  147. // Synopsis: ???
  148. //
  149. // Derivation: IClassFactory
  150. //
  151. //--------------------------------------------------------------------------
  152. STDMETHODIMP CStdClassFactory::LockServer (
  153. BOOL fLock )
  154. {
  155. return S_OK;
  156. }
  157. //+-------------------------------------------------------------------------
  158. //
  159. // Method: CStdClassFactory::CreateInstance, public
  160. //
  161. // Synopsis: Creates a new instance and returns the requested interface.
  162. // The returned object has a reference count of 1.
  163. //
  164. // Derivation: IClassFactory
  165. //
  166. // Note: Calls the pure virtual method _CreateInstance, which must
  167. // be implemented by subclasses.
  168. //
  169. //--------------------------------------------------------------------------
  170. STDMETHODIMP CStdClassFactory::CreateInstance (
  171. IUnknown* punkOuter,
  172. REFIID iidInterface,
  173. void** ppv )
  174. {
  175. return _CreateInstance ( punkOuter, iidInterface, ppv );
  176. }
  177. //+-------------------------------------------------------------------------
  178. //
  179. // Method: CStdClassFactory::QueryInterface, public
  180. //
  181. // Synopsis: Query for an interface on the class factory.
  182. //
  183. // Derivation: IUnknown
  184. //
  185. //--------------------------------------------------------------------------
  186. STDMETHODIMP CStdClassFactory::QueryInterface (
  187. REFIID iid,
  188. void * * ppv )
  189. {
  190. HRESULT hr;
  191. if ((IsEqualIID(iid, IID_IUnknown)) ||
  192. (IsEqualIID(iid, IID_IClassFactory)))
  193. {
  194. *ppv = (IClassFactory*)this;
  195. AddRef();
  196. hr = S_OK;
  197. }
  198. else
  199. {
  200. // Make sure we null the return value in case of error
  201. *ppv = NULL;
  202. hr = _QueryInterface ( iid, ppv );
  203. }
  204. return hr;
  205. }
  206. //+-------------------------------------------------------------------------
  207. //
  208. // Method: CStdClassFactory::_QueryInterface, protected
  209. //
  210. // Synopsis: Default private QI, normally overridden in subclass
  211. //
  212. // Derivation: IUnknown
  213. //
  214. //--------------------------------------------------------------------------
  215. STDMETHODIMP CStdClassFactory::_QueryInterface (
  216. REFIID iid,
  217. void * * ppv )
  218. {
  219. return E_NOINTERFACE;
  220. }
  221. //+-------------------------------------------------------------------------
  222. //
  223. // Method: CStdClassFactory::AddRef, public
  224. //
  225. // Synopsis: Increment DLL and object reference counts
  226. //
  227. // Derivation: IUnknown
  228. //
  229. //--------------------------------------------------------------------------
  230. STDMETHODIMP_(ULONG) CStdClassFactory::AddRef ()
  231. {
  232. InterlockedIncrement ( (LONG*)&_gcDllRefs );
  233. return (ULONG)InterlockedIncrement ( (LONG*)&_cRefs );
  234. }
  235. //+-------------------------------------------------------------------------
  236. //
  237. // Method: CStdClassFactory::Release, public
  238. //
  239. // Synopsis: Decrement DLL and object reference counts
  240. //
  241. // Derivation: IUnknown
  242. //
  243. //--------------------------------------------------------------------------
  244. STDMETHODIMP_(ULONG) CStdClassFactory::Release ()
  245. {
  246. InterlockedDecrement ( (LONG*)&_gcDllRefs );
  247. return (ULONG)InterlockedDecrement ( (LONG*)&_cRefs );
  248. }