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.

375 lines
8.0 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CFactory.cpp
  7. //
  8. // Description:
  9. // Class Factory implementation.
  10. //
  11. // Maintained By:
  12. // David Potter (DavidP) 14-JUN-2001
  13. // Geoffrey Pease (GPease) 22-NOV-1999
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16. DEFINE_THISCLASS("CFactory")
  17. //#define THISCLASS CFactory
  18. //////////////////////////////////////////////////////////////////////////////
  19. //
  20. // STDMETHODIMP
  21. // CFactory::S_HrCreateInstance(
  22. // LPCREATEINST lpfn
  23. // , CFactory** ppFactoryInstanceOut
  24. // )
  25. //
  26. //////////////////////////////////////////////////////////////////////////////
  27. HRESULT CFactory::S_HrCreateInstance(
  28. PFN_FACTORY_METHOD lpfn
  29. , CFactory ** ppFactoryInstanceOut
  30. )
  31. {
  32. TraceFunc( "" );
  33. HRESULT hr = S_OK;
  34. CFactory * pInstance = NULL;
  35. if ( ppFactoryInstanceOut == NULL )
  36. {
  37. hr = THR( E_POINTER );
  38. goto Cleanup;
  39. }
  40. *ppFactoryInstanceOut = NULL;
  41. if ( lpfn == NULL )
  42. {
  43. hr = THR( E_POINTER );
  44. goto Cleanup;
  45. }
  46. pInstance = new CFactory;
  47. if ( pInstance == NULL )
  48. {
  49. hr = THR( E_OUTOFMEMORY );
  50. goto Cleanup;
  51. }
  52. hr = THR( pInstance->HrInit( lpfn ) );
  53. if ( FAILED( hr ) )
  54. {
  55. goto Cleanup;
  56. }
  57. *ppFactoryInstanceOut = pInstance;
  58. pInstance = NULL;
  59. Cleanup:
  60. if ( pInstance != NULL )
  61. {
  62. delete pInstance;
  63. }
  64. HRETURN( hr );
  65. } //*** CFactory::S_HrCreateInstance
  66. // ************************************************************************
  67. //
  68. // Constructor / Destructor
  69. //
  70. // ************************************************************************
  71. //////////////////////////////////////////////////////////////////////////////
  72. //
  73. // Constructor
  74. //
  75. //////////////////////////////////////////////////////////////////////////////
  76. CFactory::CFactory( void )
  77. {
  78. TraceFunc( "" );
  79. InterlockedIncrement( &g_cObjects );
  80. TraceFuncExit();
  81. } //*** CFactory::CFactory
  82. //////////////////////////////////////////////////////////////////////////////
  83. //
  84. // CFactory::HrInit
  85. //
  86. //////////////////////////////////////////////////////////////////////////////
  87. STDMETHODIMP
  88. CFactory::HrInit(
  89. PFN_FACTORY_METHOD lpfnCreateIn
  90. )
  91. {
  92. TraceFunc( "" );
  93. // IUnknown stuff
  94. Assert( m_cRef == 0 );
  95. AddRef(); // Add one count
  96. // IClassFactory
  97. m_pfnCreateInstance = lpfnCreateIn;
  98. HRETURN( S_OK );
  99. } //*** CFactory::HrInit
  100. //////////////////////////////////////////////////////////////////////////////
  101. //
  102. // Destructor
  103. //
  104. //////////////////////////////////////////////////////////////////////////////
  105. CFactory::~CFactory( void )
  106. {
  107. TraceFunc( "" );
  108. InterlockedDecrement( &g_cObjects );
  109. TraceFuncExit();
  110. } //*** CFactory::~CFactory
  111. // ************************************************************************
  112. //
  113. // IUnknown
  114. //
  115. // ************************************************************************
  116. //////////////////////////////////////////////////////////////////////////////
  117. //++
  118. //
  119. // CFactory::QueryInterface
  120. //
  121. // Description:
  122. // Query this object for the passed in interface.
  123. //
  124. // Arguments:
  125. // riidIn
  126. // Id of interface requested.
  127. //
  128. // ppvOut
  129. // Pointer to the requested interface.
  130. //
  131. // Return Value:
  132. // S_OK
  133. // If the interface is available on this object.
  134. //
  135. // E_NOINTERFACE
  136. // If the interface is not available.
  137. //
  138. // E_POINTER
  139. // ppvOut was NULL.
  140. //
  141. // Remarks:
  142. // None.
  143. //
  144. //--
  145. //////////////////////////////////////////////////////////////////////////////
  146. STDMETHODIMP
  147. CFactory::QueryInterface(
  148. REFIID riidIn
  149. , LPVOID * ppvOut
  150. )
  151. {
  152. TraceQIFunc( riidIn, ppvOut );
  153. HRESULT hr = S_OK;
  154. //
  155. // Validate arguments.
  156. //
  157. Assert( ppvOut != NULL );
  158. if ( ppvOut == NULL )
  159. {
  160. hr = THR( E_POINTER );
  161. goto Cleanup;
  162. }
  163. //
  164. // Handle known interfaces.
  165. //
  166. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  167. {
  168. //
  169. // Can't track IUnknown as they must be equal the same address
  170. // for every QI.
  171. //
  172. *ppvOut = static_cast< IClassFactory * >( this );
  173. } // if: IUnknown
  174. else if ( IsEqualIID( riidIn, IID_IClassFactory ) )
  175. {
  176. *ppvOut = TraceInterface( __THISCLASS__, IClassFactory, this, 0 );
  177. } // else if: IClassFactory
  178. else
  179. {
  180. *ppvOut = NULL;
  181. hr = E_NOINTERFACE;
  182. } // else
  183. //
  184. // Add a reference to the interface if successful.
  185. //
  186. if ( SUCCEEDED( hr ) )
  187. {
  188. ((IUnknown *) *ppvOut)->AddRef();
  189. } // if: success
  190. Cleanup:
  191. QIRETURN( hr, riidIn );
  192. } //*** CFactory::QueryInterface
  193. //////////////////////////////////////////////////////////////////////////////
  194. //
  195. // STDMETHODIMP_(ULONG)
  196. // CFactory::[IUnknown] AddRef( void )
  197. //
  198. //////////////////////////////////////////////////////////////////////////////
  199. STDMETHODIMP_( ULONG )
  200. CFactory::AddRef( void )
  201. {
  202. TraceFunc( "[IUnknown]" );
  203. InterlockedIncrement( &m_cRef );
  204. RETURN( m_cRef );
  205. } //*** CFactory::AddRef
  206. //////////////////////////////////////////////////////////////////////////////
  207. //
  208. // STDMETHODIMP_(ULONG)
  209. // CFactory::[IUnknown] Release( void )
  210. //
  211. //////////////////////////////////////////////////////////////////////////////
  212. STDMETHODIMP_( ULONG )
  213. CFactory::Release( void )
  214. {
  215. TraceFunc( "[IUnknown]" );
  216. LONG cRef;
  217. cRef = InterlockedDecrement( &m_cRef );
  218. if ( cRef == 0 )
  219. {
  220. TraceDo( delete this );
  221. }
  222. RETURN( cRef );
  223. } //*** CFactory::Release
  224. // ************************************************************************
  225. //
  226. // IClassFactory
  227. //
  228. // ************************************************************************
  229. //////////////////////////////////////////////////////////////////////////////
  230. //++
  231. //
  232. // CFactory::CreateInstance
  233. //
  234. // Description:
  235. // Create the CFactory instance.
  236. //
  237. // Arguments:
  238. // pUnkOuterIn
  239. // riidIn
  240. // ppvOut
  241. //
  242. // Return Values:
  243. // S_OK
  244. // E_POINTER
  245. // E_NOINTERFACE
  246. //
  247. //--
  248. //////////////////////////////////////////////////////////////////////////////
  249. STDMETHODIMP
  250. CFactory::CreateInstance(
  251. IUnknown * pUnkOuterIn,
  252. REFIID riidIn,
  253. void ** ppvOut
  254. )
  255. {
  256. TraceFunc( "[IClassFactory]" );
  257. HRESULT hr = E_NOINTERFACE;
  258. IUnknown * pUnk = NULL;
  259. if ( ppvOut == NULL )
  260. {
  261. hr = THR( E_POINTER );
  262. goto Cleanup;
  263. }
  264. *ppvOut = NULL;
  265. if ( NULL != pUnkOuterIn )
  266. {
  267. hr = THR( CLASS_E_NOAGGREGATION );
  268. goto Cleanup;
  269. }
  270. Assert( m_pfnCreateInstance != NULL );
  271. hr = THR( m_pfnCreateInstance( &pUnk ) );
  272. if ( FAILED( hr ) )
  273. {
  274. goto Cleanup;
  275. }
  276. // Can't safe type.
  277. TraceMsgDo( hr = pUnk->QueryInterface( riidIn, ppvOut ), "0x%08x" );
  278. Cleanup:
  279. if ( pUnk != NULL )
  280. {
  281. ULONG cRef;
  282. //
  283. // Release the created instance, not the punk
  284. //
  285. TraceMsgDo( cRef = ((IUnknown*) pUnk)->Release(), "%u" );
  286. }
  287. HRETURN( hr );
  288. } //*** CFactory::CreateInstance
  289. //////////////////////////////////////////////////////////////////////////////
  290. //
  291. // STDMETHODIMP
  292. // CFactory::[IClassFactory] LockServer(
  293. // BOOL fLock
  294. // )
  295. //
  296. //////////////////////////////////////////////////////////////////////////////
  297. STDMETHODIMP
  298. CFactory::LockServer(
  299. BOOL fLock
  300. )
  301. {
  302. TraceFunc( "[IClassFactory]" );
  303. if ( fLock )
  304. {
  305. InterlockedIncrement( &g_cLock );
  306. }
  307. else
  308. {
  309. InterlockedDecrement( &g_cLock );
  310. }
  311. HRETURN( S_OK );
  312. } //*** CFactory::LockServer