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.

329 lines
9.2 KiB

  1. ///////////////////////////////////////////////////////////
  2. //
  3. // CFactory
  4. // - Base class for reusing a single class factory for
  5. // all components in a DLL
  6. //
  7. #include <objbase.h>
  8. #include <fusenetincludes.h>
  9. #include "CFactory.h"
  10. LONG CFactory::s_cServerLocks = 0 ; // Count of locks
  11. HMODULE CFactory::s_hModule = NULL ; // DLL module handle
  12. #ifdef _OUTPROC_SERVER_
  13. DWORD CFactory::s_dwThreadID = 0 ;
  14. #endif
  15. // ---------------------------------------------------------------------------
  16. // ctor
  17. // ---------------------------------------------------------------------------
  18. CFactory::CFactory(const CFactoryData* pFactoryData)
  19. : m_cRef(1)
  20. {
  21. m_pFactoryData = pFactoryData ;
  22. }
  23. // ---------------------------------------------------------------------------
  24. // dtor
  25. // ---------------------------------------------------------------------------
  26. CFactory::~CFactory()
  27. {}
  28. // IUnknown implementation
  29. // ---------------------------------------------------------------------------
  30. // QueryInterface
  31. // ---------------------------------------------------------------------------
  32. STDMETHODIMP CFactory::QueryInterface(REFIID iid, void** ppv)
  33. {
  34. IUnknown* pI ;
  35. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  36. {
  37. pI = this ;
  38. }
  39. else
  40. {
  41. *ppv = NULL;
  42. return E_NOINTERFACE;
  43. }
  44. pI->AddRef() ;
  45. *ppv = pI ;
  46. return S_OK;
  47. }
  48. // ---------------------------------------------------------------------------
  49. // AddRef
  50. // ---------------------------------------------------------------------------
  51. STDMETHODIMP_(ULONG) CFactory::AddRef()
  52. {
  53. return ::InterlockedIncrement((LONG*) &m_cRef) ;
  54. }
  55. // ---------------------------------------------------------------------------
  56. // Release
  57. // ---------------------------------------------------------------------------
  58. STDMETHODIMP_(ULONG) CFactory::Release()
  59. {
  60. if (::InterlockedDecrement((LONG*) &m_cRef) == 0)
  61. {
  62. delete this;
  63. return 0 ;
  64. }
  65. return m_cRef;
  66. }
  67. // ---------------------------------------------------------------------------
  68. // IClassFactory implementation
  69. // ---------------------------------------------------------------------------
  70. STDMETHODIMP CFactory::CreateInstance(IUnknown* pUnknownOuter,
  71. const IID& iid, void** ppv)
  72. {
  73. HRESULT hr = S_OK;
  74. MAKE_ERROR_MACROS_STATIC(hr);
  75. CUnknown* pNewComponent = NULL;
  76. // Aggregate only if the requested IID is IID_IUnknown.
  77. if ((pUnknownOuter != NULL) && (iid != IID_IUnknown))
  78. {
  79. hr = CLASS_E_NOAGGREGATION ;
  80. goto exit;
  81. }
  82. // Create the component.
  83. IF_FAILED_EXIT(m_pFactoryData->CreateInstance(pUnknownOuter, &pNewComponent));
  84. // Initialize the component.
  85. IF_FAILED_EXIT(pNewComponent->Init());
  86. // Get the requested interface.
  87. IF_FAILED_EXIT(pNewComponent->QueryInterface(iid, ppv));
  88. exit:
  89. // Release the reference held by the class factory.
  90. SAFERELEASE(pNewComponent);
  91. return hr ;
  92. }
  93. // ---------------------------------------------------------------------------
  94. // LockServer
  95. // ---------------------------------------------------------------------------
  96. STDMETHODIMP CFactory::LockServer(BOOL bLock)
  97. {
  98. if (bLock)
  99. {
  100. ::InterlockedIncrement(&s_cServerLocks) ;
  101. }
  102. else
  103. {
  104. ::InterlockedDecrement(&s_cServerLocks) ;
  105. }
  106. // If this is an out-of-proc server, check to see
  107. // whether we should shut down.
  108. CloseExe() ; //@local
  109. return S_OK ;
  110. }
  111. // -------------------Support Common to Inproc/OutProc--------------------------
  112. // ---------------------------------------------------------------------------
  113. // Determine if the component can be unloaded.
  114. // ---------------------------------------------------------------------------
  115. HRESULT CFactory::CanUnloadNow()
  116. {
  117. if (CUnknown::ActiveComponents() || IsLocked())
  118. {
  119. return S_FALSE ;
  120. }
  121. else
  122. {
  123. return S_OK ;
  124. }
  125. }
  126. // --------------------------InProc Server support-------------------------------
  127. #ifndef _OUTPROC_SERVER_
  128. // ---------------------------------------------------------------------------
  129. // GetClassObject
  130. // ---------------------------------------------------------------------------
  131. HRESULT CFactory::GetClassObject(const CLSID& clsid,
  132. const IID& iid,
  133. void** ppv)
  134. {
  135. HRESULT hr = S_OK;
  136. MAKE_ERROR_MACROS_STATIC(hr);
  137. BOOL fFound = FALSE;
  138. IF_FALSE_EXIT(((iid == IID_IUnknown) || (iid == IID_IClassFactory)), E_NOINTERFACE);
  139. // Traverse the array of data looking for this class ID.
  140. for (int i = 0; i < g_cFactoryDataEntries; i++)
  141. {
  142. const CFactoryData* pData = &g_FactoryDataArray[i] ;
  143. if (pData->IsClassID(clsid))
  144. {
  145. // Found the ClassID in the array of components we can
  146. // create. So create a class factory for this component.
  147. // Pass the CFactoryData structure to the class factory
  148. // so that it knows what kind of components to create.
  149. *ppv = (IUnknown*) new CFactory(pData) ;
  150. IF_ALLOC_FAILED_EXIT(*ppv);
  151. fFound = TRUE;
  152. }
  153. }
  154. hr = fFound ? NOERROR : CLASS_E_CLASSNOTAVAILABLE;
  155. exit:
  156. return hr;
  157. }
  158. // ---------------------------------------------------------------------------
  159. // DllCanUnloadNow
  160. // ---------------------------------------------------------------------------
  161. STDAPI DllCanUnloadNow()
  162. {
  163. return CFactory::CanUnloadNow() ;
  164. }
  165. // ---------------------------------------------------------------------------
  166. // DllGetClassObject
  167. // ---------------------------------------------------------------------------
  168. STDAPI DllGetClassObject(const CLSID& clsid,
  169. const IID& iid,
  170. void** ppv)
  171. {
  172. return CFactory::GetClassObject(clsid, iid, ppv) ;
  173. }
  174. // ---------------------------------------------------------------------------
  175. // DllRegisterServer
  176. // ---------------------------------------------------------------------------
  177. STDAPI DllRegisterServer()
  178. {
  179. return CFactory::RegisterAll() ;
  180. }
  181. // ---------------------------------------------------------------------------
  182. // DllUnregisterServer
  183. // ---------------------------------------------------------------------------
  184. STDAPI DllUnregisterServer()
  185. {
  186. return CFactory::UnregisterAll() ;
  187. }
  188. // ---------------------------------------------------------------------------
  189. // DllMain
  190. // ---------------------------------------------------------------------------
  191. BOOL APIENTRY DllMain(HANDLE hModule,
  192. DWORD dwReason, void* lpReserved )
  193. {
  194. if (dwReason == DLL_PROCESS_ATTACH)
  195. {
  196. CFactory::s_hModule = (HMODULE) hModule ;
  197. }
  198. return TRUE ;
  199. }
  200. // -------------------------OutProc server support-----------------------------
  201. #else
  202. // ---------------------------------------------------------------------------
  203. // Start factories
  204. // ---------------------------------------------------------------------------
  205. HRESULT CFactory::StartFactories()
  206. {
  207. HRESULT hr = S_OK;
  208. MAKE_ERROR_MACROS_STATIC(hr);
  209. CFactoryData* pStart = &g_FactoryDataArray[0] ;
  210. const CFactoryData* pEnd =
  211. &g_FactoryDataArray[g_cFactoryDataEntries - 1] ;
  212. IClassFactory* pIFactory = NULL;
  213. for(CFactoryData* pData = pStart ; pData <= pEnd ; pData++)
  214. {
  215. // Initialize the class factory pointer and cookie.
  216. pData->m_pIClassFactory = NULL ;
  217. pData->m_dwRegister = NULL ;
  218. // Create the class factory for this component.
  219. pIFactory = new CFactory(pData) ;
  220. IF_ALLOC_FAILED_EXIT(pIFactory);
  221. // Register the class factory.
  222. DWORD dwRegister ;
  223. hr = ::CoRegisterClassObject(
  224. *pData->m_pCLSID,
  225. static_cast<IUnknown*>(pIFactory),
  226. CLSCTX_LOCAL_SERVER,
  227. REGCLS_MULTIPLEUSE,
  228. // REGCLS_MULTI_SEPARATE, //@Multi
  229. &dwRegister) ;
  230. IF_FAILED_EXIT(hr);
  231. // Set the data.
  232. pData->m_pIClassFactory = pIFactory ;
  233. pData->m_dwRegister = dwRegister ;
  234. }
  235. exit:
  236. if (FAILED(hr))
  237. SAFERELEASE(pIFactory);
  238. return hr;
  239. }
  240. // ---------------------------------------------------------------------------
  241. // Stop factories
  242. // ---------------------------------------------------------------------------
  243. void CFactory::StopFactories()
  244. {
  245. CFactoryData* pStart = &g_FactoryDataArray[0] ;
  246. const CFactoryData* pEnd =
  247. &g_FactoryDataArray[g_cFactoryDataEntries - 1] ;
  248. for (CFactoryData* pData = pStart ; pData <= pEnd ; pData++)
  249. {
  250. // Get the magic cookie and stop the factory from running.
  251. DWORD dwRegister = pData->m_dwRegister ;
  252. if (dwRegister != 0)
  253. {
  254. ::CoRevokeClassObject(dwRegister) ;
  255. }
  256. // Release the class factory.
  257. IClassFactory* pIFactory = pData->m_pIClassFactory ;
  258. SAFERELEASE(pIFactory);
  259. }
  260. }
  261. #endif //_OUTPROC_SERVER_