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.

370 lines
9.7 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1999 **
  4. //*********************************************************************
  5. //
  6. // CFACTORY.CPP - Implementation of IClassFactory
  7. //
  8. // HISTORY:
  9. //
  10. // 1/27/99 a-jaswed Created.
  11. //
  12. // Base class for reusing a single class factory for all
  13. // components in a DLL.
  14. #include <objbase.h>
  15. #include "cfactory.h"
  16. #include "registry.h"
  17. ///////////////////////////////////////////////////////////
  18. // Static variables
  19. //
  20. LONG CFactory::s_cServerLocks = 0 ; // Count of locks
  21. HMODULE CFactory::s_hModule = NULL; // DLL Module Handle.
  22. #ifdef _OUTPROC_SERVER_
  23. DWORD CFactory::s_dwThreadID = 0;
  24. #endif
  25. ///////////////////////////////////////////////////////////
  26. // CFactory implementation
  27. //
  28. CFactory::CFactory(const CFactoryData* pFactoryData)
  29. : m_cRef(1)
  30. {
  31. m_pFactoryData = pFactoryData;
  32. }
  33. ///////////////////////////////////////////////////////////
  34. // IUnknown implementation
  35. ///////////////////////////////////////////////////////////
  36. ///////////////////////////////////////////////////////////
  37. // QueryInterface
  38. //
  39. HRESULT __stdcall CFactory::QueryInterface(REFIID iid, void** ppv)
  40. {
  41. IUnknown* pI ;
  42. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  43. {
  44. pI = this;
  45. }
  46. else
  47. {
  48. *ppv = NULL;
  49. return E_NOINTERFACE;
  50. }
  51. pI->AddRef();
  52. *ppv = pI;
  53. return S_OK;
  54. }
  55. ///////////////////////////////////////////////////////////
  56. // AddRef
  57. //
  58. ULONG __stdcall CFactory::AddRef()
  59. {
  60. return ::InterlockedIncrement(&m_cRef);
  61. }
  62. ///////////////////////////////////////////////////////////
  63. // Release
  64. //
  65. ULONG __stdcall CFactory::Release()
  66. {
  67. if (::InterlockedDecrement(&m_cRef) == 0)
  68. {
  69. delete this;
  70. return 0;
  71. }
  72. return m_cRef;
  73. }
  74. ///////////////////////////////////////////////////////////
  75. // IClassFactory Implementation
  76. ///////////////////////////////////////////////////////////
  77. ///////////////////////////////////////////////////////////
  78. // CreateInstance
  79. //
  80. HRESULT __stdcall CFactory::CreateInstance( IUnknown* pOuterUnknown,
  81. const IID& iid,
  82. void** ppv)
  83. {
  84. // Aggregate only if the requested iid is IID_IUnknown
  85. if ((pOuterUnknown != NULL) && (iid != IID_IUnknown))
  86. {
  87. return CLASS_E_NOAGGREGATION;
  88. }
  89. // Create the component.
  90. CUnknown* pNewComponent ;
  91. HRESULT hr = m_pFactoryData->CreateInstance(pOuterUnknown,
  92. &pNewComponent);
  93. if (FAILED(hr))
  94. {
  95. return hr;
  96. }
  97. // Initialize the component.
  98. hr = pNewComponent->Init();
  99. if (FAILED(hr))
  100. {
  101. // Initialization failed. Release the component.
  102. pNewComponent->NondelegatingRelease();
  103. return hr ;
  104. }
  105. // Get the requested interface.
  106. hr = pNewComponent->NondelegatingQueryInterface(iid, ppv);
  107. // Release the reference held by the class factory.
  108. pNewComponent->NondelegatingRelease();
  109. return hr ;
  110. }
  111. ///////////////////////////////////////////////////////////
  112. // LockServer
  113. //
  114. HRESULT __stdcall CFactory::LockServer(BOOL bLock)
  115. {
  116. if (bLock)
  117. {
  118. ::InterlockedIncrement(&s_cServerLocks);
  119. }
  120. else
  121. {
  122. ::InterlockedDecrement(&s_cServerLocks);
  123. }
  124. // If this is an outproc server check to see if we should shut down.
  125. CloseExe() ; //@local
  126. return S_OK;
  127. }
  128. //////////////////////////////////////////////////////////
  129. // GetClassObject - Creates a class factory based on CLSID
  130. //
  131. HRESULT CFactory::GetClassObject(const CLSID& clsid,
  132. const IID& iid,
  133. void** ppv)
  134. {
  135. if ((iid != IID_IUnknown) && (iid != IID_IClassFactory))
  136. {
  137. return E_NOINTERFACE;
  138. }
  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
  146. // can 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 (*ppv == NULL)
  151. {
  152. return E_OUTOFMEMORY;
  153. }
  154. return NOERROR;
  155. }
  156. }
  157. return CLASS_E_CLASSNOTAVAILABLE;
  158. }
  159. //////////////////////////////////////////////////////////
  160. // CanUnloadNow - Determine if component can be unloaded.
  161. //
  162. HRESULT CFactory::CanUnloadNow()
  163. {
  164. if (CUnknown::ActiveComponents() || IsLocked())
  165. {
  166. return S_FALSE;
  167. }
  168. else
  169. {
  170. return S_OK;
  171. }
  172. }
  173. //////////////////////////////////////////////////////////
  174. // CFactory Member Function
  175. //////////////////////////////////////////////////////////
  176. //////////////////////////////////////////////////////////
  177. // Register all components.
  178. //
  179. HRESULT CFactory::RegisterAll()
  180. {
  181. for(int i = 0 ; i < g_cFactoryDataEntries ; i++)
  182. {
  183. RegisterServer( s_hModule,
  184. *(g_FactoryDataArray[i].m_pCLSID),
  185. g_FactoryDataArray[i].m_RegistryName,
  186. g_FactoryDataArray[i].m_szVerIndProgID,
  187. g_FactoryDataArray[i].m_szProgID );
  188. // Perform any additional registration.
  189. if (g_FactoryDataArray[i].SpecialRegistration != NULL)
  190. {
  191. g_FactoryDataArray[i].SpecialRegistration(TRUE);
  192. }
  193. }
  194. return S_OK ;
  195. }
  196. //////////////////////////////////////////////////////////
  197. // Unregister all components.
  198. //
  199. HRESULT CFactory::UnregisterAll()
  200. {
  201. for(int i = 0 ; i < g_cFactoryDataEntries ; i++)
  202. {
  203. // Undo any additional registration.
  204. if (g_FactoryDataArray[i].SpecialRegistration != NULL)
  205. {
  206. g_FactoryDataArray[i].SpecialRegistration(FALSE);
  207. }
  208. UnregisterServer(*(g_FactoryDataArray[i].m_pCLSID),
  209. g_FactoryDataArray[i].m_szVerIndProgID,
  210. g_FactoryDataArray[i].m_szProgID );
  211. }
  212. return S_OK;
  213. }
  214. #ifndef _OUTPROC_SERVER_
  215. //////////////////////////////////////////////////////////
  216. // Exported functions
  217. //////////////////////////////////////////////////////////
  218. //////////////////////////////////////////////////////////
  219. // DllCanUnloadNow
  220. //
  221. STDAPI DllCanUnloadNow()
  222. {
  223. return CFactory::CanUnloadNow();
  224. }
  225. //////////////////////////////////////////////////////////
  226. // Get class factory
  227. //
  228. STDAPI DllGetClassObject( const CLSID& clsid,
  229. const IID& iid,
  230. void** ppv)
  231. {
  232. return CFactory::GetClassObject(clsid, iid, ppv);
  233. }
  234. //////////////////////////////////////////////////////////
  235. // Server Registration
  236. //
  237. STDAPI DllRegisterServer()
  238. {
  239. return CFactory::RegisterAll();
  240. }
  241. //////////////////////////////////////////////////////////
  242. // Unregistration
  243. //
  244. STDAPI DllUnregisterServer()
  245. {
  246. return CFactory::UnregisterAll();
  247. }
  248. ///////////////////////////////////////////////////////////
  249. // DLL module information
  250. //
  251. BOOL APIENTRY DllMain(HANDLE hModule,
  252. DWORD dwReason,
  253. void* lpReserved )
  254. {
  255. if (dwReason == DLL_PROCESS_ATTACH)
  256. {
  257. CFactory::s_hModule = (HMODULE) hModule;
  258. }
  259. return TRUE;
  260. }
  261. #else
  262. //////////////////////////////////////////////////////////
  263. // Out of process Server support
  264. //////////////////////////////////////////////////////////
  265. //////////////////////////////////////////////////////////
  266. // Start factories
  267. //
  268. BOOL CFactory::StartFactories()
  269. {
  270. CFactoryData* pStart = &g_FactoryDataArray[0];
  271. const CFactoryData* pEnd = &g_FactoryDataArray[g_cFactoryDataEntries-1];
  272. for(CFactoryData* pData = pStart ; pData <= pEnd ; pData++)
  273. {
  274. // Initialize the class factory pointer and cookie.
  275. pData->m_pIClassFactory = NULL ;
  276. pData->m_dwRegister = NULL ;
  277. // Create the class factory for this component.
  278. IClassFactory* pIFactory = new CFactory(pData);
  279. // Register the class factory.
  280. DWORD dwRegister ;
  281. HRESULT hr = ::CoRegisterClassObject( *pData->m_pCLSID,
  282. (IUnknown*)pIFactory,
  283. CLSCTX_LOCAL_SERVER,
  284. REGCLS_MULTIPLEUSE,
  285. //REGCLS_MULTI_SEPARATE, //@Multi
  286. &dwRegister) ;
  287. if (FAILED(hr))
  288. {
  289. pIFactory->Release() ;
  290. return FALSE ;
  291. }
  292. // Set the data.
  293. pData->m_pIClassFactory = pIFactory ;
  294. pData->m_dwRegister = dwRegister ;
  295. }
  296. return TRUE ;
  297. }
  298. //////////////////////////////////////////////////////////
  299. // Stop factories
  300. //
  301. void CFactory::StopFactories()
  302. {
  303. CFactoryData* pStart = &g_FactoryDataArray[0];
  304. const CFactoryData* pEnd = &g_FactoryDataArray[g_cFactoryDataEntries-1];
  305. for(CFactoryData* pData = pStart ; pData <= pEnd ; pData++)
  306. {
  307. // Get the magic cookie and stop the factory from running.
  308. DWORD dwRegister = pData->m_dwRegister ;
  309. if (dwRegister != 0)
  310. {
  311. ::CoRevokeClassObject(dwRegister) ;
  312. }
  313. // Release the class factory.
  314. IClassFactory* pIFactory = pData->m_pIClassFactory;
  315. if (pIFactory != NULL)
  316. {
  317. pIFactory->Release() ;
  318. }
  319. }
  320. }
  321. #endif //_OUTPROC_SERVER_