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.

276 lines
7.7 KiB

  1. /****************************************************************************
  2. *
  3. * FACTORY.cpp
  4. *
  5. * Microsoft Confidential
  6. * Copyright (c) Microsoft Corporation 1992-1997
  7. * All rights reserved
  8. *
  9. * This module provides the implementation of the methods for
  10. * the CFactory class, which is used by COM's CoCreateInstance
  11. *
  12. * The code comes almost verbatim from Chapter 7 of Dale Rogerson's
  13. * "Inside COM", and thus is minimally commented.
  14. *
  15. * 05/14/98 donaldm migrated from INETCFG
  16. *
  17. ***************************************************************************/
  18. #include "pre.h"
  19. #include "icwconn.h"
  20. // #include "icwextsn.h"
  21. #include "icwaprtc.h"
  22. // Friendly name of component
  23. const TCHAR g_szFriendlyName[] = TEXT("CLSID_ApprenticeICWCONN") ;
  24. // Version-independent ProgID
  25. const TCHAR g_szVerIndProgID[] = TEXT("ICWCONN.Apprentice") ;
  26. // ProgID
  27. const TCHAR g_szProgID[] = TEXT("ICWCONN.Apprentice.1") ;
  28. static long g_cComponents = 0 ; // Count of active components
  29. static long g_cServerLocks = 0 ; // Count of locks
  30. ///////////////////////////////////////////////////////////
  31. //
  32. // Class factory
  33. //
  34. class CFactory : public IClassFactory
  35. {
  36. public:
  37. // IUnknown
  38. virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;
  39. virtual ULONG __stdcall AddRef() ;
  40. virtual ULONG __stdcall Release() ;
  41. // Interface IClassFactory
  42. virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,
  43. const IID& iid,
  44. void** ppv) ;
  45. virtual HRESULT __stdcall LockServer(BOOL bLock) ;
  46. // Constructor
  47. CFactory() : m_cRef(1) {}
  48. // Destructor
  49. ~CFactory() { TraceMsg(TF_CLASSFACTORY, "Class factory:\t\tDestroy self.") ;}
  50. private:
  51. long m_cRef ;
  52. } ;
  53. //
  54. // Class factory IUnknown implementation
  55. //
  56. HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)
  57. {
  58. TraceMsg(TF_CLASSFACTORY, "CFactory::QueryInterface");
  59. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  60. {
  61. *ppv = static_cast<IClassFactory*>(this) ;
  62. }
  63. else
  64. {
  65. *ppv = NULL ;
  66. return E_NOINTERFACE ;
  67. }
  68. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  69. return S_OK ;
  70. }
  71. ULONG __stdcall CFactory::AddRef()
  72. {
  73. TraceMsg(TF_CLASSFACTORY, "CFactory::AddRef %d", m_cRef + 1);
  74. return InterlockedIncrement(&m_cRef) ;
  75. }
  76. ULONG __stdcall CFactory::Release()
  77. {
  78. if (InterlockedDecrement(&m_cRef) == 0)
  79. {
  80. delete this ;
  81. return 0 ;
  82. }
  83. TraceMsg(TF_CLASSFACTORY, "CFactory::Release %d", m_cRef);
  84. return m_cRef ;
  85. }
  86. //
  87. // IClassFactory implementation
  88. //
  89. HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
  90. const IID& iid,
  91. void** ppv)
  92. {
  93. TraceMsg(TF_CLASSFACTORY, "CFactory::CreateInstance:\t\tCreate component.") ;
  94. // Cannot aggregate.
  95. if (pUnknownOuter != NULL)
  96. {
  97. return CLASS_E_NOAGGREGATION ;
  98. }
  99. // Create component. Since there's no direct IUnknown implementation,
  100. // use CICWApprentice.
  101. CICWApprentice *pApprentice = new CICWApprentice;
  102. TraceMsg(TF_CLASSFACTORY, "CFactory::CreateInstance CICWApprentice->AddRef");
  103. pApprentice->AddRef();
  104. if( NULL == pApprentice )
  105. {
  106. return E_OUTOFMEMORY;
  107. }
  108. // Get the requested interface.
  109. TraceMsg(TF_CLASSFACTORY, "CFactory::CreateInstance About to QI on CICWApprentice");
  110. HRESULT hr = pApprentice->QueryInterface(iid, ppv) ;
  111. // Release the IUnknown pointer.
  112. // (If QueryInterface failed, component will delete itself.)
  113. TraceMsg(TF_CLASSFACTORY, "CFactory::CreateInstance done with CICWApprentice, releasing (aprtc should have ct of 1)");
  114. pApprentice->Release() ;
  115. return hr ;
  116. }
  117. // LockServer
  118. HRESULT __stdcall CFactory::LockServer(BOOL bLock)
  119. {
  120. if (bLock)
  121. {
  122. InterlockedIncrement(&g_cServerLocks) ;
  123. }
  124. else
  125. {
  126. InterlockedDecrement(&g_cServerLocks) ;
  127. }
  128. return S_OK ;
  129. }
  130. ///////////////////////////////////////////////////////////
  131. //
  132. // Exported functions
  133. //
  134. // These are the functions that COM expects to find
  135. //
  136. //
  137. // Can DLL unload now?
  138. //
  139. STDAPI DllCanUnloadNow()
  140. {
  141. if ((g_cComponents == 0) && (g_cServerLocks == 0))
  142. {
  143. return S_OK ;
  144. }
  145. else
  146. {
  147. return S_FALSE ;
  148. }
  149. }
  150. //
  151. // Get class factory
  152. //
  153. STDAPI DllGetClassObject(const CLSID& clsid,
  154. const IID& iid,
  155. void** ppv)
  156. {
  157. TraceMsg(TF_CLASSFACTORY, "DllGetClassObject:\tCreate class factory.") ;
  158. // Can we create this component?
  159. if (clsid != CLSID_ApprenticeICWCONN)
  160. {
  161. return CLASS_E_CLASSNOTAVAILABLE ;
  162. }
  163. // Create class factory.
  164. CFactory* pFactory = new CFactory ; // No AddRef in constructor
  165. if (pFactory == NULL)
  166. {
  167. return E_OUTOFMEMORY ;
  168. }
  169. // Get requested interface.
  170. TraceMsg(TF_CLASSFACTORY, "DllGetClassObject about to QI on CFactory");
  171. HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
  172. TraceMsg(TF_CLASSFACTORY, "DllGetClassObject done with CFactory, releasing");
  173. pFactory->Release() ;
  174. return hr ;
  175. }
  176. // The following two exported functions are what regsvr32 uses to
  177. // self-register and unregister the dll. See REGISTRY.CPP for
  178. // actual implementation
  179. //
  180. // Server registration
  181. //
  182. typedef BOOL (WINAPI * REGISTERSERVER)(HMODULE hModule,
  183. const CLSID& clsid,
  184. const LPTSTR szFriendlyName,
  185. const LPTSTR szVerIndProgID,
  186. const LPTSTR szProgID);
  187. typedef BOOL (WINAPI * UNREGISTERSERVER)(const CLSID& clsid,
  188. const LPTSTR szVerIndProgID,
  189. const LPTSTR szProgID);
  190. STDAPI DllRegisterServer()
  191. {
  192. // Use the register server function that is in ICWUTIL.DLL
  193. HINSTANCE hInstUtilDLL = LoadLibrary(ICW_UTIL);
  194. REGISTERSERVER lpfnRegisterServer = NULL;
  195. HRESULT hr = E_FAIL;
  196. if (hInstUtilDLL)
  197. {
  198. lpfnRegisterServer = (REGISTERSERVER)GetProcAddress(hInstUtilDLL, "RegisterServer");
  199. if (NULL != lpfnRegisterServer)
  200. {
  201. if (lpfnRegisterServer(ghInstance,
  202. CLSID_ApprenticeICWCONN,
  203. (LPTSTR)g_szFriendlyName,
  204. (LPTSTR)g_szVerIndProgID,
  205. (LPTSTR)g_szProgID))
  206. hr = S_OK;
  207. }
  208. FreeLibrary(hInstUtilDLL);
  209. }
  210. return (hr);
  211. }
  212. //
  213. // Server unregistration
  214. //
  215. STDAPI DllUnregisterServer()
  216. {
  217. // Use the un-register server function that is in ICWUTIL.DLL
  218. HINSTANCE hInstUtilDLL = LoadLibrary(ICW_UTIL);
  219. UNREGISTERSERVER lpfnUnregisterServer = NULL;
  220. HRESULT hr = E_FAIL;
  221. if (hInstUtilDLL)
  222. {
  223. lpfnUnregisterServer = (UNREGISTERSERVER)GetProcAddress(hInstUtilDLL, "UnregisterServer");
  224. if (NULL != lpfnUnregisterServer)
  225. {
  226. if (lpfnUnregisterServer(CLSID_ApprenticeICWCONN,
  227. (LPTSTR)g_szVerIndProgID,
  228. (LPTSTR)g_szProgID))
  229. hr = S_OK;
  230. }
  231. FreeLibrary(hInstUtilDLL);
  232. }
  233. return (hr);
  234. }