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.

314 lines
6.4 KiB

  1. /***************************************************************************
  2. *
  3. * Copyright (C) 1998-2001 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dp8simclassfac.cpp
  6. *
  7. * Content: a generic class factory.
  8. *
  9. *
  10. * This is a generic C++ class factory. All you need to do is implement
  11. * a function called DoCreateInstance that will create an instance of
  12. * your object.
  13. *
  14. * GP_ stands for "General Purpose"
  15. *
  16. *
  17. * History:
  18. * Date By Reason
  19. * ======== ======== =========
  20. * 04/23/01 VanceO Copied from DPNHUPNP.
  21. *
  22. ***************************************************************************/
  23. #include "dp8simi.h"
  24. #ifdef __MWERKS__
  25. #define EXP __declspec(dllexport)
  26. #else
  27. #define EXP
  28. #endif
  29. //**********************************************************************
  30. // Constant definitions
  31. //**********************************************************************
  32. //**********************************************************************
  33. // Macro definitions
  34. //**********************************************************************
  35. //**********************************************************************
  36. // Structure definitions
  37. //**********************************************************************
  38. //
  39. // class factory class definition
  40. //
  41. typedef class GPClassFactory:public IClassFactory
  42. {
  43. public:
  44. GPClassFactory(const CLSID * pclsid) { m_dwRefCnt = 0; memcpy(&m_clsid, pclsid, sizeof(CLSID)); };
  45. ~GPClassFactory(void) {};
  46. STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  47. STDMETHODIMP_(ULONG) AddRef(void);
  48. STDMETHODIMP_(ULONG) Release(void);
  49. STDMETHODIMP CreateInstance(IUnknown * pUnkOuter, REFIID riid, void ** ppvObject);
  50. STDMETHODIMP LockServer(BOOL fLock);
  51. private:
  52. DWORD m_dwRefCnt;
  53. CLSID m_clsid;
  54. } GPCLASSFACTORY, *LPGPCLASSFACTORY;
  55. //
  56. // function prototype for CoLockObjectExternal()
  57. //
  58. typedef HRESULT (WINAPI * PCOLOCKOBJECTEXTERNAL)(LPUNKNOWN, BOOL, BOOL );
  59. //**********************************************************************
  60. // Variable definitions
  61. //**********************************************************************
  62. //
  63. // count of outstanding COM interfaces, defined in dpnathlpdllmain.cpp
  64. //
  65. extern volatile LONG g_lOutstandingInterfaceCount;
  66. //**********************************************************************
  67. // Function prototypes
  68. //**********************************************************************
  69. //**********************************************************************
  70. // Function definitions
  71. //**********************************************************************
  72. /*
  73. * GPClassFactory::QueryInterface
  74. */
  75. STDMETHODIMP GPClassFactory::QueryInterface(
  76. REFIID riid,
  77. LPVOID *ppvObj )
  78. {
  79. HRESULT hr;
  80. *ppvObj = NULL;
  81. if( IsEqualIID(riid, IID_IClassFactory) ||
  82. IsEqualIID(riid, IID_IUnknown))
  83. {
  84. this->m_dwRefCnt++;
  85. *ppvObj = this;
  86. hr = S_OK;
  87. }
  88. else
  89. {
  90. hr = E_NOINTERFACE;
  91. }
  92. return hr;
  93. } /* GPClassFactory::QueryInterface */
  94. /*
  95. * GPClassFactory::AddRef
  96. */
  97. STDMETHODIMP_(ULONG) GPClassFactory::AddRef( void )
  98. {
  99. this->m_dwRefCnt++;
  100. return this->m_dwRefCnt;
  101. } /* GPClassFactory::AddRef */
  102. /*
  103. * GPClassFactory::Release
  104. */
  105. STDMETHODIMP_(ULONG) GPClassFactory::Release( void )
  106. {
  107. this->m_dwRefCnt--;
  108. if( this->m_dwRefCnt != 0 )
  109. {
  110. return this->m_dwRefCnt;
  111. }
  112. delete this;
  113. return 0;
  114. } /* GPClassFactory::Release */
  115. /*
  116. * GPClassFactory::CreateInstance
  117. *
  118. * Creates an instance of the object
  119. */
  120. STDMETHODIMP GPClassFactory::CreateInstance(
  121. LPUNKNOWN pUnkOuter,
  122. REFIID riid,
  123. LPVOID *ppvObj
  124. )
  125. {
  126. HRESULT hr = S_OK;
  127. if( pUnkOuter != NULL )
  128. {
  129. return CLASS_E_NOAGGREGATION;
  130. }
  131. *ppvObj = NULL;
  132. /*
  133. * create the object by calling DoCreateInstance. This function
  134. * must be implemented specifically for your COM object
  135. */
  136. hr = DoCreateInstance(this, pUnkOuter, this->m_clsid, riid, ppvObj);
  137. if (FAILED(hr))
  138. {
  139. *ppvObj = NULL;
  140. return hr;
  141. }
  142. return S_OK;
  143. } /* GPClassFactory::CreateInstance */
  144. /*
  145. * GPClassFactory::LockServer
  146. *
  147. * Called to force our DLL to stayed loaded
  148. */
  149. STDMETHODIMP GPClassFactory::LockServer(
  150. BOOL fLock
  151. )
  152. {
  153. HRESULT hr;
  154. HINSTANCE hdll;
  155. /*
  156. * call CoLockObjectExternal
  157. */
  158. hr = E_UNEXPECTED;
  159. hdll = LoadLibraryA( "OLE32.DLL" );
  160. if( hdll != NULL )
  161. {
  162. PCOLOCKOBJECTEXTERNAL lpCoLockObjectExternal;
  163. lpCoLockObjectExternal = reinterpret_cast<PCOLOCKOBJECTEXTERNAL>( GetProcAddress( hdll, "CoLockObjectExternal" ) );
  164. if( lpCoLockObjectExternal != NULL )
  165. {
  166. hr = lpCoLockObjectExternal( (LPUNKNOWN) this, fLock, TRUE );
  167. }
  168. else
  169. {
  170. }
  171. }
  172. else
  173. {
  174. }
  175. return hr;
  176. } /* GPClassFactory::LockServer */
  177. /*
  178. * DllGetClassObject
  179. *
  180. * Entry point called by COM to get a ClassFactory pointer
  181. */
  182. EXP STDAPI DllGetClassObject(
  183. REFCLSID rclsid,
  184. REFIID riid,
  185. LPVOID *ppvObj )
  186. {
  187. LPGPCLASSFACTORY pcf;
  188. HRESULT hr;
  189. *ppvObj = NULL;
  190. /*
  191. * is this our class id?
  192. */
  193. // you must implement GetClassID() for your specific COM object
  194. if (!IsClassImplemented(rclsid))
  195. {
  196. return CLASS_E_CLASSNOTAVAILABLE;
  197. }
  198. /*
  199. * only allow IUnknown and IClassFactory
  200. */
  201. if( !IsEqualIID( riid, IID_IUnknown ) &&
  202. !IsEqualIID( riid, IID_IClassFactory ) )
  203. {
  204. return E_NOINTERFACE;
  205. }
  206. /*
  207. * create a class factory object
  208. */
  209. pcf = new GPClassFactory(&rclsid);
  210. if( NULL == pcf)
  211. {
  212. return E_OUTOFMEMORY;
  213. }
  214. hr = pcf->QueryInterface( riid, ppvObj );
  215. if( FAILED( hr ) )
  216. {
  217. delete pcf;
  218. *ppvObj = NULL;
  219. }
  220. else
  221. {
  222. }
  223. return hr;
  224. } /* DllGetClassObject */
  225. /*
  226. * DllCanUnloadNow
  227. *
  228. * Entry point called by COM to see if it is OK to free our DLL
  229. */
  230. EXP STDAPI DllCanUnloadNow( void )
  231. {
  232. HRESULT hr = S_FALSE;
  233. if ( g_lOutstandingInterfaceCount == 0 )
  234. {
  235. hr = S_OK;
  236. }
  237. return hr;
  238. } /* DllCanUnloadNow */