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.

316 lines
6.5 KiB

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