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.

438 lines
11 KiB

  1. //
  2. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. // ***************************************************************************
  5. //
  6. // Original Author: Rajesh Rao
  7. //
  8. // $Author: rajeshr $
  9. // $Date: 6/11/98 4:43p $
  10. // $Workfile:classfac.cpp $
  11. //
  12. // $Modtime: 6/11/98 11:21a $
  13. // $Revision: 1 $
  14. // $Nokeywords: $
  15. //
  16. //
  17. // Description: Contains the implementation of the DS Class Provider factory.
  18. // Currently it always creates the LDAP CLass Provider. It remains to be decided as to how this can
  19. // be changed
  20. //
  21. //***************************************************************************
  22. #include "precomp.h"
  23. // Initializer objects required by the classes used by the DLL
  24. CDSClassProviderInitializer *CDSClassProviderClassFactory::s_pDSClassProviderInitializer = NULL;
  25. CLDAPClassProviderInitializer *CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer = NULL;
  26. //***************************************************************************
  27. //
  28. // CDSClassProviderClassFactory::CDSClassProviderClassFactory
  29. // CDSClassProviderClassFactory::~CDSClassProviderClassFactory
  30. //
  31. // Constructor Parameters:
  32. // None
  33. //***************************************************************************
  34. CDSClassProviderClassFactory :: CDSClassProviderClassFactory ()
  35. {
  36. m_ReferenceCount = 0 ;
  37. InterlockedIncrement(&g_lComponents);
  38. }
  39. CDSClassProviderClassFactory::~CDSClassProviderClassFactory ()
  40. {
  41. InterlockedDecrement(&g_lComponents);
  42. }
  43. //***************************************************************************
  44. //
  45. // CDSClassProviderClassFactory::QueryInterface
  46. // CDSClassProviderClassFactory::AddRef
  47. // CDSClassProviderClassFactory::Release
  48. //
  49. // Purpose: Standard COM routines needed for all interfaces
  50. //
  51. //***************************************************************************
  52. STDMETHODIMP CDSClassProviderClassFactory::QueryInterface (
  53. REFIID iid ,
  54. LPVOID FAR *iplpv
  55. )
  56. {
  57. *iplpv = NULL ;
  58. if ( iid == IID_IUnknown )
  59. {
  60. *iplpv = ( LPVOID ) this ;
  61. }
  62. else if ( iid == IID_IClassFactory )
  63. {
  64. *iplpv = ( LPVOID ) this ;
  65. }
  66. else
  67. {
  68. return E_NOINTERFACE;
  69. }
  70. ( ( LPUNKNOWN ) *iplpv )->AddRef () ;
  71. return S_OK;
  72. }
  73. STDMETHODIMP_( ULONG ) CDSClassProviderClassFactory :: AddRef ()
  74. {
  75. return InterlockedIncrement ( & m_ReferenceCount ) ;
  76. }
  77. STDMETHODIMP_(ULONG) CDSClassProviderClassFactory :: Release ()
  78. {
  79. LONG ref ;
  80. if ( ( ref = InterlockedDecrement ( & m_ReferenceCount ) ) == 0 )
  81. {
  82. delete this ;
  83. return 0 ;
  84. }
  85. else
  86. {
  87. return ref ;
  88. }
  89. }
  90. //***************************************************************************
  91. //
  92. // CDSClassProviderClassFactory::CreateInstance
  93. //
  94. // Purpose: Instantiates a Provider object returning an interface pointer.
  95. //
  96. // Parameters:
  97. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  98. // being used in an aggregation.
  99. // riid REFIID identifying the interface the caller
  100. // desires to have for the new object.
  101. // ppvObj PPVOID in which to store the desired
  102. // interface pointer for the new object.
  103. //
  104. // Return Value:
  105. // HRESULT NOERROR if successful, otherwise E_NOINTERFACE
  106. // if we cannot support the requested interface.
  107. //***************************************************************************
  108. STDMETHODIMP CDSClassProviderClassFactory :: CreateInstance (
  109. LPUNKNOWN pUnkOuter ,
  110. REFIID riid ,
  111. LPVOID FAR * ppvObject
  112. )
  113. {
  114. HRESULT status = S_OK ;
  115. // We do not support aggregation
  116. if ( pUnkOuter )
  117. {
  118. status = CLASS_E_NOAGGREGATION ;
  119. }
  120. else
  121. {
  122. // Check to see if the static members have been initialized
  123. // Create any initializer objects required for the classes
  124. EnterCriticalSection(&g_StaticsCreationDeletion);
  125. if(!s_pDSClassProviderInitializer)
  126. {
  127. BOOL bLogObjectAllocated = FALSE;
  128. try
  129. {
  130. // Th Log Object might have been created by the CreateInstance() function for the other
  131. // providers (Instance/ Class Association)
  132. if( !g_pLogObject )
  133. {
  134. g_pLogObject = new ProvDebugLog(DSPROVIDER);
  135. bLogObjectAllocated = TRUE;
  136. }
  137. g_pLogObject->WriteW(L"CDSClassProviderClassFactory::CreateInstance() called\r\n");
  138. s_pDSClassProviderInitializer = new CDSClassProviderInitializer();
  139. s_pLDAPClassProviderInitializer = new CLDAPClassProviderInitializer();
  140. }
  141. catch(Heap_Exception e_HE)
  142. {
  143. if ( bLogObjectAllocated && g_pLogObject )
  144. {
  145. delete g_pLogObject;
  146. g_pLogObject = NULL;
  147. }
  148. if ( s_pDSClassProviderInitializer )
  149. {
  150. delete s_pDSClassProviderInitializer;
  151. s_pDSClassProviderInitializer = NULL;
  152. }
  153. if ( s_pLDAPClassProviderInitializer )
  154. {
  155. delete s_pLDAPClassProviderInitializer;
  156. s_pLDAPClassProviderInitializer = NULL;
  157. }
  158. status = E_OUTOFMEMORY ;
  159. }
  160. }
  161. LeaveCriticalSection(&g_StaticsCreationDeletion);
  162. if(SUCCEEDED(status))
  163. {
  164. CLDAPClassProvider *lpunk = NULL;
  165. try
  166. {
  167. lpunk = new CLDAPClassProvider();
  168. status = lpunk->QueryInterface ( riid , ppvObject ) ;
  169. if ( FAILED ( status ) )
  170. {
  171. delete lpunk ;
  172. }
  173. }
  174. catch(Heap_Exception e_HE)
  175. {
  176. if ( lpunk )
  177. {
  178. delete lpunk ;
  179. lpunk = NULL;
  180. }
  181. status = E_OUTOFMEMORY ;
  182. }
  183. }
  184. }
  185. return status ;
  186. }
  187. //***************************************************************************
  188. //
  189. // CDSClassProviderClassFactory::LockServer
  190. //
  191. // Purpose:
  192. // Increments or decrements the lock count of the DLL. If the
  193. // lock count goes to zero and there are no objects, the DLL
  194. // is allowed to unload. See DllCanUnloadNow.
  195. //
  196. // Parameters:
  197. // fLock BOOL specifying whether to increment or
  198. // decrement the lock count.
  199. //
  200. // Return Value:
  201. // HRESULT NOERROR always.
  202. //***************************************************************************
  203. STDMETHODIMP CDSClassProviderClassFactory :: LockServer ( BOOL fLock )
  204. {
  205. if ( fLock )
  206. {
  207. InterlockedIncrement ( & g_lServerLocks ) ;
  208. }
  209. else
  210. {
  211. InterlockedDecrement ( & g_lServerLocks ) ;
  212. }
  213. return S_OK ;
  214. }
  215. //***************************************************************************
  216. //
  217. // CDSClassAssociationsProviderClassFactory::CDSClassAssociationsProviderClassFactory
  218. // CDSClassAssociationsProviderClassFactory::~CDSClassAssociationsProviderClassFactory
  219. //
  220. // Constructor Parameters:
  221. // None
  222. //***************************************************************************
  223. CDSClassAssociationsProviderClassFactory :: CDSClassAssociationsProviderClassFactory ()
  224. {
  225. m_ReferenceCount = 0 ;
  226. InterlockedIncrement(&g_lComponents);
  227. }
  228. CDSClassAssociationsProviderClassFactory::~CDSClassAssociationsProviderClassFactory ()
  229. {
  230. InterlockedDecrement(&g_lComponents);
  231. }
  232. //***************************************************************************
  233. //
  234. // CDSClassAssociationsProviderClassFactory::QueryInterface
  235. // CDSClassAssociationsProviderClassFactory::AddRef
  236. // CDSClassAssociationsProviderClassFactory::Release
  237. //
  238. // Purpose: Standard COM routines needed for all interfaces
  239. //
  240. //***************************************************************************
  241. STDMETHODIMP CDSClassAssociationsProviderClassFactory::QueryInterface (
  242. REFIID iid ,
  243. LPVOID FAR *iplpv
  244. )
  245. {
  246. *iplpv = NULL ;
  247. if ( iid == IID_IUnknown )
  248. {
  249. *iplpv = ( LPVOID ) this ;
  250. }
  251. else if ( iid == IID_IClassFactory )
  252. {
  253. *iplpv = ( LPVOID ) this ;
  254. }
  255. else
  256. {
  257. return E_NOINTERFACE;
  258. }
  259. ( ( LPUNKNOWN ) *iplpv )->AddRef () ;
  260. return S_OK;
  261. }
  262. STDMETHODIMP_( ULONG ) CDSClassAssociationsProviderClassFactory :: AddRef ()
  263. {
  264. return InterlockedIncrement ( & m_ReferenceCount ) ;
  265. }
  266. STDMETHODIMP_(ULONG) CDSClassAssociationsProviderClassFactory :: Release ()
  267. {
  268. LONG ref ;
  269. if ( ( ref = InterlockedDecrement ( & m_ReferenceCount ) ) == 0 )
  270. {
  271. delete this ;
  272. return 0 ;
  273. }
  274. else
  275. {
  276. return ref ;
  277. }
  278. }
  279. //***************************************************************************
  280. //
  281. // CDSClassAssociationsProviderClassFactory::CreateInstance
  282. //
  283. // Purpose: Instantiates a Provider object returning an interface pointer.
  284. //
  285. // Parameters:
  286. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  287. // being used in an aggregation.
  288. // riid REFIID identifying the interface the caller
  289. // desires to have for the new object.
  290. // ppvObj PPVOID in which to store the desired
  291. // interface pointer for the new object.
  292. //
  293. // Return Value:
  294. // HRESULT NOERROR if successful, otherwise E_NOINTERFACE
  295. // if we cannot support the requested interface.
  296. //***************************************************************************
  297. STDMETHODIMP CDSClassAssociationsProviderClassFactory :: CreateInstance (
  298. LPUNKNOWN pUnkOuter ,
  299. REFIID riid ,
  300. LPVOID FAR * ppvObject
  301. )
  302. {
  303. HRESULT status = S_OK ;
  304. // We do not support aggregation
  305. if ( pUnkOuter )
  306. {
  307. status = CLASS_E_NOAGGREGATION ;
  308. }
  309. else
  310. {
  311. CLDAPClassAsssociationsProvider *lpunk = NULL;
  312. // Check to see if the static members have been initialized
  313. // Create any initializer objects required for the classes
  314. EnterCriticalSection(&g_StaticsCreationDeletion);
  315. BOOL bLogObjectAllocated = FALSE;
  316. try
  317. {
  318. // This might have been created by the CreateInstance() function of the
  319. // other DS Providers (Class, ClassAssociation)
  320. if( !g_pLogObject )
  321. {
  322. g_pLogObject = new ProvDebugLog(DSPROVIDER);
  323. bLogObjectAllocated = TRUE;
  324. }
  325. g_pLogObject->WriteW(L"CDSClassAssociationsProviderClassFactory::CreateInstance() called\r\n");
  326. lpunk = new CLDAPClassAsssociationsProvider();
  327. status = lpunk->QueryInterface ( riid , ppvObject ) ;
  328. if ( FAILED ( status ) )
  329. {
  330. delete lpunk ;
  331. }
  332. }
  333. catch(Heap_Exception e_HE)
  334. {
  335. if ( bLogObjectAllocated && g_pLogObject )
  336. {
  337. delete g_pLogObject;
  338. g_pLogObject = NULL;
  339. }
  340. if ( lpunk )
  341. {
  342. delete lpunk;
  343. lpunk = NULL;
  344. }
  345. status = E_OUTOFMEMORY ;
  346. }
  347. LeaveCriticalSection(&g_StaticsCreationDeletion);
  348. }
  349. return status ;
  350. }
  351. //***************************************************************************
  352. //
  353. // CDSClassAssociationsProviderClassFactory::LockServer
  354. //
  355. // Purpose:
  356. // Increments or decrements the lock count of the DLL. If the
  357. // lock count goes to zero and there are no objects, the DLL
  358. // is allowed to unload. See DllCanUnloadNow.
  359. //
  360. // Parameters:
  361. // fLock BOOL specifying whether to increment or
  362. // decrement the lock count.
  363. //
  364. // Return Value:
  365. // HRESULT NOERROR always.
  366. //***************************************************************************
  367. STDMETHODIMP CDSClassAssociationsProviderClassFactory :: LockServer ( BOOL fLock )
  368. {
  369. if ( fLock )
  370. {
  371. InterlockedIncrement ( & g_lServerLocks ) ;
  372. }
  373. else
  374. {
  375. InterlockedDecrement ( & g_lServerLocks ) ;
  376. }
  377. return S_OK ;
  378. }