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.

229 lines
5.7 KiB

  1. #include <windows.h>
  2. #include <olectl.h>
  3. #include <advpub.h> // REGINSTALL
  4. #include "volclean.h"
  5. /*
  6. **------------------------------------------------------------------------------
  7. ** Global variables
  8. **------------------------------------------------------------------------------
  9. */
  10. extern "C" {
  11. LONG g_cRefCount = 0;
  12. }
  13. typedef HRESULT (WINAPI *PFNCREATEINSTANCE)(REFIID, void **);
  14. /*
  15. **------------------------------------------------------------------------------
  16. ** DllCanUnloadNow
  17. **
  18. ** Purpose: Answers if the DLL can be free, that is, if there are no
  19. ** references to anything this DLL provides.
  20. ** Return: TRUE, if OK to unload (i.e. nobody is using us or has us locked)
  21. ** FALSE, otherwise
  22. ** Notes;
  23. **------------------------------------------------------------------------------
  24. */
  25. STDAPI DllCanUnloadNow(void)
  26. {
  27. //
  28. // Are there any outstanding references?
  29. //
  30. return (g_cRefCount == 0 ? S_OK : S_FALSE);
  31. }
  32. STDAPI_(void) DllAddRef(void)
  33. {
  34. InterlockedIncrement(&g_cRefCount);
  35. }
  36. STDAPI_(void) DllRelease(void)
  37. {
  38. InterlockedDecrement(&g_cRefCount);
  39. }
  40. class CWebDavCleanerClassFactory : IClassFactory
  41. {
  42. LONG m_cRef;
  43. PFNCREATEINSTANCE m_pfnCreateInstance;
  44. public:
  45. CWebDavCleanerClassFactory(PFNCREATEINSTANCE pfnCreate)
  46. : m_cRef(1),
  47. m_pfnCreateInstance(pfnCreate)
  48. {
  49. Trace(L"CWebDavCleanerClassFactory::CWebDavCleanerClassFactory");
  50. DllAddRef();
  51. }
  52. ~CWebDavCleanerClassFactory()
  53. {
  54. Trace(L"CWebDavCleanerClassFactory::~CWebDavCleanerClassFactory");
  55. DllRelease();
  56. }
  57. // IUnknown methods
  58. STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
  59. STDMETHODIMP_(ULONG) AddRef();
  60. STDMETHODIMP_(ULONG) Release();
  61. // IClassFactory methods
  62. STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *);
  63. STDMETHODIMP LockServer(BOOL);
  64. };
  65. /*
  66. **------------------------------------------------------------------------------
  67. ** DllGetClassObject
  68. **
  69. ** Purpose: Provides an IClassFactory for a given CLSID that this DLL is
  70. ** registered to support. This DLL is placed under the CLSID
  71. ** in the registration database as the InProcServer.
  72. ** Parameters:
  73. ** clsID - REFCLSID that identifies the class factory desired.
  74. ** Since this parameter is passed this DLL can handle
  75. ** any number of objects simply by returning different
  76. ** different class factories here for different CLSIDs.
  77. ** riid - REFIID specifying the interface the caller wants
  78. ** on the class object, usually IID_ClassFactory.
  79. ** ppvOut - pointer in which to return the interface pointer.
  80. ** Return: NOERROR on success, otherwise an error code
  81. ** Notes;
  82. **------------------------------------------------------------------------------
  83. */
  84. STDAPI DllGetClassObject(
  85. IN REFCLSID rclsid,
  86. IN REFIID riid,
  87. OUT void **ppv
  88. )
  89. {
  90. HRESULT hr = E_FAIL;
  91. PFNCREATEINSTANCE pfnCreateInstance = NULL;
  92. Trace(L"DllGetClassObject");
  93. *ppv = NULL;
  94. //
  95. // Is the request for our cleaner object?
  96. //
  97. if (IsEqualCLSID(rclsid, CLSID_WebDavVolumeCleaner)) {
  98. pfnCreateInstance = CWebDavCleaner::CreateInstance;
  99. }
  100. else {
  101. //
  102. // Error - we don't know about this object
  103. //
  104. return CLASS_E_CLASSNOTAVAILABLE;
  105. }
  106. //
  107. // Get our IClassFactory for making CWebDavCleaner objects
  108. //
  109. CWebDavCleanerClassFactory *pClassFactory = new CWebDavCleanerClassFactory(pfnCreateInstance);
  110. if (pClassFactory) {
  111. //
  112. // Make sure the new class factory likes the requested interface
  113. //
  114. hr = pClassFactory->QueryInterface(riid, ppv);
  115. if (FAILED(hr)) {
  116. //
  117. // Error - interface rejected
  118. //
  119. delete pClassFactory;
  120. }
  121. else {
  122. //
  123. // Release initial ref
  124. //
  125. pClassFactory->Release();
  126. }
  127. }
  128. else {
  129. //
  130. // Error - couldn't make factory object
  131. //
  132. hr = E_OUTOFMEMORY;
  133. }
  134. return hr;
  135. }
  136. STDMETHODIMP
  137. CWebDavCleanerClassFactory::QueryInterface(REFIID riid, void **ppv)
  138. {
  139. Trace(L"CWebDavCleanerClassFactory::QueryInterface");
  140. if (!ppv) {
  141. return E_POINTER;
  142. }
  143. if (riid == IID_IClassFactory) {
  144. *ppv = static_cast<IClassFactory*>(this);
  145. }
  146. else {
  147. *ppv = NULL;
  148. return E_NOINTERFACE;
  149. }
  150. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  151. return S_OK;
  152. }
  153. STDMETHODIMP_(ULONG)
  154. CWebDavCleanerClassFactory::AddRef()
  155. {
  156. Trace(L"CWebDavCleanerClassFactory::AddRef");
  157. return InterlockedIncrement(&m_cRef);
  158. }
  159. STDMETHODIMP_(ULONG)
  160. CWebDavCleanerClassFactory::Release()
  161. {
  162. Trace(L"CWebDavCleanerClassFactory::Release");
  163. if (InterlockedDecrement(&m_cRef))
  164. return m_cRef;
  165. delete this;
  166. return 0;
  167. }
  168. STDMETHODIMP
  169. CWebDavCleanerClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
  170. {
  171. HRESULT hr = E_UNEXPECTED;
  172. Trace(L"CWebDavCleanerClassFactory::CreateInstance");
  173. *ppv = NULL;
  174. if (pUnkOuter)
  175. return CLASS_E_NOAGGREGATION;
  176. if (m_pfnCreateInstance)
  177. hr = m_pfnCreateInstance(riid, ppv);
  178. return hr;
  179. }
  180. STDMETHODIMP
  181. CWebDavCleanerClassFactory::LockServer(BOOL fLock)
  182. {
  183. Trace(L"CWebDavCleanerClassFactory::LockServer");
  184. if (fLock)
  185. DllAddRef();
  186. else
  187. DllRelease();
  188. return S_OK;
  189. }