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.

210 lines
5.9 KiB

  1. // Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
  2. // Factory.cpp
  3. #include "precomp.h"
  4. #include <iostream.h>
  5. #include <objbase.h>
  6. #include "CUnknown.h"
  7. #include "factory.h"
  8. #include "Registry.h"
  9. // Set static members
  10. LONG CFactory::s_cServerLocks = 0L ; // Count of locks
  11. HMODULE CFactory::s_hModule = NULL ; // DLL module handle
  12. extern CFactoryData g_FactoryDataArray[];
  13. /*****************************************************************************/
  14. // Class factory constructor
  15. /*****************************************************************************/
  16. CFactory::CFactory(const CFactoryData* pFactoryData)
  17. : m_cRef(1)
  18. {
  19. m_pFactoryData = pFactoryData ;
  20. LockServer(TRUE);
  21. }
  22. /*****************************************************************************/
  23. // Class factory IUnknown implementation
  24. /*****************************************************************************/
  25. STDMETHODIMP CFactory::QueryInterface(const IID& iid, void** ppv)
  26. {
  27. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  28. {
  29. *ppv = static_cast<IClassFactory*>(this) ;
  30. }
  31. else
  32. {
  33. *ppv = NULL ;
  34. return E_NOINTERFACE ;
  35. }
  36. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  37. return S_OK ;
  38. }
  39. STDMETHODIMP_(ULONG) CFactory::AddRef()
  40. {
  41. return InterlockedIncrement(&m_cRef) ;
  42. }
  43. STDMETHODIMP_(ULONG) CFactory::Release()
  44. {
  45. if (InterlockedDecrement(&m_cRef) == 0)
  46. {
  47. delete this ;
  48. return 0 ;
  49. }
  50. return m_cRef ;
  51. }
  52. /*****************************************************************************/
  53. // IClassFactory implementation
  54. /*****************************************************************************/
  55. STDMETHODIMP CFactory::CreateInstance(IUnknown* pUnknownOuter,
  56. const IID& iid,
  57. void** ppv)
  58. {
  59. HRESULT hr = S_OK;
  60. // Cannot aggregate.
  61. if (pUnknownOuter != NULL)
  62. {
  63. hr = CLASS_E_NOAGGREGATION;
  64. }
  65. if(SUCCEEDED(hr))
  66. {
  67. // Create component using the specific component's version of CreateInstance.
  68. CUnknown* pNewComponent ;
  69. hr = m_pFactoryData->CreateInstance(&pNewComponent) ;
  70. if(SUCCEEDED(hr))
  71. {
  72. // Initialize the component
  73. hr = pNewComponent->Init();
  74. if(SUCCEEDED(hr))
  75. {
  76. // Get the requested interface.
  77. hr = pNewComponent->QueryInterface(iid, ppv);
  78. }
  79. // Release the IUnknown pointer (the new AND the QI incremented the refcount on SUC.
  80. // (If QueryInterface failed, component will delete itself.)
  81. pNewComponent->Release();
  82. }
  83. }
  84. return hr ;
  85. }
  86. /*****************************************************************************/
  87. // Lock server
  88. /*****************************************************************************/
  89. STDMETHODIMP CFactory::LockServer(BOOL bLock)
  90. {
  91. if (bLock)
  92. {
  93. InterlockedIncrement(&s_cServerLocks) ;
  94. }
  95. else
  96. {
  97. InterlockedDecrement(&s_cServerLocks) ;
  98. }
  99. return S_OK ;
  100. }
  101. /*****************************************************************************/
  102. // GetClassObject - Create a class factory based on a CLSID.
  103. /*****************************************************************************/
  104. HRESULT CFactory::GetClassObject(const CLSID& clsid,
  105. const IID& iid,
  106. void** ppv)
  107. {
  108. HRESULT hr = S_OK;
  109. if ((iid != IID_IUnknown) && (iid != IID_IClassFactory))
  110. {
  111. hr = E_NOINTERFACE ;
  112. }
  113. if(SUCCEEDED(hr))
  114. {
  115. // Traverse the array of data looking for this class ID.
  116. for (int i = 0; i < g_cFactoryDataEntries; i++)
  117. {
  118. if(g_FactoryDataArray[i].IsClassID(clsid))
  119. {
  120. // Found the ClassID in the array of components we can
  121. // create. So create a class factory for this component.
  122. // Pass the CFactoryData structure to the class factory
  123. // so that it knows what kind of components to create.
  124. const CFactoryData* pData = &g_FactoryDataArray[i] ;
  125. CFactory* pFactory = new CFactory(pData);
  126. if (pFactory == NULL)
  127. {
  128. hr = E_OUTOFMEMORY ;
  129. }
  130. else
  131. {
  132. // Get requested interface.
  133. HRESULT hr = pFactory->QueryInterface(iid, ppv);
  134. pFactory->Release();
  135. }
  136. break;
  137. }
  138. }
  139. if(i == g_cFactoryDataEntries)
  140. {
  141. hr = CLASS_E_CLASSNOTAVAILABLE;
  142. }
  143. }
  144. return hr;
  145. }
  146. /*****************************************************************************/
  147. // Register all components.
  148. /*****************************************************************************/
  149. HRESULT CFactory::RegisterAll()
  150. {
  151. for(int i = 0 ; i < g_cFactoryDataEntries ; i++)
  152. {
  153. RegisterServer(s_hModule,
  154. *(g_FactoryDataArray[i].m_pCLSID),
  155. g_FactoryDataArray[i].m_RegistryName,
  156. g_FactoryDataArray[i].m_szVerIndProgID,
  157. g_FactoryDataArray[i].m_szProgID) ;
  158. }
  159. return S_OK ;
  160. }
  161. /*****************************************************************************/
  162. // Un-register all components
  163. /*****************************************************************************/
  164. HRESULT CFactory::UnregisterAll()
  165. {
  166. for(int i = 0 ; i < g_cFactoryDataEntries ; i++)
  167. {
  168. UnregisterServer(*(g_FactoryDataArray[i].m_pCLSID),
  169. g_FactoryDataArray[i].m_szVerIndProgID,
  170. g_FactoryDataArray[i].m_szProgID) ;
  171. }
  172. return S_OK ;
  173. }
  174. /*****************************************************************************/
  175. // Determine if the component can be unloaded.
  176. /*****************************************************************************/
  177. HRESULT CFactory::CanUnloadNow()
  178. {
  179. if (CUnknown::ActiveComponents() || IsLocked())
  180. {
  181. return S_FALSE ;
  182. }
  183. else
  184. {
  185. return S_OK ;
  186. }
  187. }