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.

236 lines
5.5 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. * 4/24/97 jmazner Created
  16. *
  17. ***************************************************************************/
  18. #include "wizard.h"
  19. #include "icwextsn.h"
  20. #include "icwaprtc.h"
  21. #include "imnext.h"
  22. #include "registry.h"
  23. // Friendly name of component
  24. const TCHAR g_szFriendlyName[] = TEXT("CLSID_ApprenticeICW") ;
  25. // Version-independent ProgID
  26. const TCHAR g_szVerIndProgID[] = TEXT("INETCFG.Apprentice") ;
  27. // ProgID
  28. const TCHAR g_szProgID[] = TEXT("INETCFG.Apprentice.1") ;
  29. static long g_cComponents = 0 ; // Count of active components
  30. static long g_cServerLocks = 0 ; // Count of locks
  31. ///////////////////////////////////////////////////////////
  32. //
  33. // Class factory
  34. //
  35. class CFactory : public IClassFactory
  36. {
  37. public:
  38. // IUnknown
  39. virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;
  40. virtual ULONG __stdcall AddRef() ;
  41. virtual ULONG __stdcall Release() ;
  42. // Interface IClassFactory
  43. virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,
  44. const IID& iid,
  45. void** ppv) ;
  46. virtual HRESULT __stdcall LockServer(BOOL bLock) ;
  47. // Constructor
  48. CFactory() : m_cRef(1) {}
  49. // Destructor
  50. ~CFactory() { DEBUGMSG("Class factory:\t\tDestroy self.") ;}
  51. private:
  52. long m_cRef ;
  53. } ;
  54. //
  55. // Class factory IUnknown implementation
  56. //
  57. HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)
  58. {
  59. DEBUGMSG("CFactory::QueryInterface");
  60. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  61. {
  62. *ppv = static_cast<IClassFactory*>(this) ;
  63. }
  64. else
  65. {
  66. *ppv = NULL ;
  67. return E_NOINTERFACE ;
  68. }
  69. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  70. return S_OK ;
  71. }
  72. ULONG __stdcall CFactory::AddRef()
  73. {
  74. DEBUGMSG("CFactory::AddRef %d", m_cRef + 1);
  75. return InterlockedIncrement(&m_cRef) ;
  76. }
  77. ULONG __stdcall CFactory::Release()
  78. {
  79. if (InterlockedDecrement(&m_cRef) == 0)
  80. {
  81. delete this ;
  82. return 0 ;
  83. }
  84. DEBUGMSG("CFactory::Release %d", m_cRef);
  85. return m_cRef ;
  86. }
  87. //
  88. // IClassFactory implementation
  89. //
  90. HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
  91. const IID& iid,
  92. void** ppv)
  93. {
  94. DEBUGMSG("CFactory::CreateInstance:\t\tCreate component.") ;
  95. // Cannot aggregate.
  96. if (pUnknownOuter != NULL)
  97. {
  98. return CLASS_E_NOAGGREGATION ;
  99. }
  100. // Create component. Since there's no direct IUnknown implementation,
  101. // use CICWApprentice.
  102. CICWApprentice *pApprentice = new CICWApprentice;
  103. DEBUGMSG("CFactory::CreateInstance CICWApprentice->AddRef");
  104. pApprentice->AddRef();
  105. if( NULL == pApprentice )
  106. {
  107. return E_OUTOFMEMORY;
  108. }
  109. // Get the requested interface.
  110. DEBUGMSG("CFactory::CreateInstance About to QI on CICWApprentice");
  111. HRESULT hr = pApprentice->QueryInterface(iid, ppv) ;
  112. // Release the IUnknown pointer.
  113. // (If QueryInterface failed, component will delete itself.)
  114. DEBUGMSG("CFactory::CreateInstance done with CICWApprentice, releasing (aprtc should have ct of 1)");
  115. pApprentice->Release() ;
  116. return hr ;
  117. }
  118. // LockServer
  119. HRESULT __stdcall CFactory::LockServer(BOOL bLock)
  120. {
  121. if (bLock)
  122. {
  123. InterlockedIncrement(&g_cServerLocks) ;
  124. }
  125. else
  126. {
  127. InterlockedDecrement(&g_cServerLocks) ;
  128. }
  129. return S_OK ;
  130. }
  131. ///////////////////////////////////////////////////////////
  132. //
  133. // Exported functions
  134. //
  135. // These are the functions that COM expects to find
  136. //
  137. //
  138. // Can DLL unload now?
  139. //
  140. STDAPI DllCanUnloadNow()
  141. {
  142. if ((g_cComponents == 0) && (g_cServerLocks == 0))
  143. {
  144. return S_OK ;
  145. }
  146. else
  147. {
  148. return S_FALSE ;
  149. }
  150. }
  151. //
  152. // Get class factory
  153. //
  154. STDAPI DllGetClassObject(const CLSID& clsid,
  155. const IID& iid,
  156. void** ppv)
  157. {
  158. DEBUGMSG("DllGetClassObject:\tCreate class factory.") ;
  159. // Can we create this component?
  160. if (clsid != CLSID_ApprenticeICW)
  161. {
  162. return CLASS_E_CLASSNOTAVAILABLE ;
  163. }
  164. // Create class factory.
  165. CFactory* pFactory = new CFactory ; // No AddRef in constructor
  166. if (pFactory == NULL)
  167. {
  168. return E_OUTOFMEMORY ;
  169. }
  170. // Get requested interface.
  171. DEBUGMSG("DllGetClassObject about to QI on CFactory");
  172. HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
  173. DEBUGMSG("DllGetClassObject done with CFactory, releasing");
  174. pFactory->Release() ;
  175. return hr ;
  176. }
  177. // The following two exported functions are what regsvr32 uses to
  178. // self-register and unregister the dll. See REGISTRY.CPP for
  179. // actual implementation
  180. //
  181. // Server registration
  182. //
  183. STDAPI DllRegisterServer()
  184. {
  185. return RegisterServer(ghInstance,
  186. CLSID_ApprenticeICW,
  187. g_szFriendlyName,
  188. g_szVerIndProgID,
  189. g_szProgID) ;
  190. }
  191. //
  192. // Server unregistration
  193. //
  194. STDAPI DllUnregisterServer()
  195. {
  196. return UnregisterServer(CLSID_ApprenticeICW,
  197. g_szVerIndProgID,
  198. g_szProgID) ;
  199. }