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.

273 lines
7.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: dll.cpp
  8. //
  9. // Authors;
  10. // Jeff Saathoff (jeffreys)
  11. //
  12. // Notes;
  13. // Core entry points for the DLL
  14. //--------------------------------------------------------------------------
  15. #include "pch.h"
  16. #include <advpub.h> // REGINSTALL
  17. #include <shfusion.h>
  18. #include "msgbox.h"
  19. STDAPI COfflineFilesFolder_CreateInstance(REFIID riid, void **ppv);
  20. STDAPI COfflineFilesOptions_CreateInstance(REFIID riid, void **ppv);
  21. ///////////////////////////////////////////////////////////////////////////////
  22. // //
  23. // Global variables //
  24. // //
  25. ///////////////////////////////////////////////////////////////////////////////
  26. LONG g_cRefCount = 0;
  27. HINSTANCE g_hInstance = NULL;
  28. CLIPFORMAT g_cfShellIDList = 0;
  29. HANDLE g_heventTerminate = NULL;
  30. HANDLE g_hmutexAdminPin = NULL;
  31. typedef HRESULT (WINAPI *PFNCREATEINSTANCE)(REFIID, void **);
  32. class CClassFactory : IClassFactory
  33. {
  34. LONG m_cRef;
  35. PFNCREATEINSTANCE m_pfnCreateInstance;
  36. public:
  37. CClassFactory(PFNCREATEINSTANCE pfnCreate) : m_cRef(1), m_pfnCreateInstance(pfnCreate)
  38. {
  39. DllAddRef();
  40. }
  41. ~CClassFactory()
  42. {
  43. DllRelease();
  44. }
  45. // IUnknown methods
  46. STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
  47. STDMETHODIMP_(ULONG) AddRef();
  48. STDMETHODIMP_(ULONG) Release();
  49. // IClassFactory methods
  50. STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *);
  51. STDMETHODIMP LockServer(BOOL);
  52. };
  53. STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
  54. {
  55. switch (dwReason)
  56. {
  57. case DLL_PROCESS_ATTACH:
  58. #ifndef DEBUG
  59. DisableThreadLibraryCalls(hInstance);
  60. #endif
  61. g_hInstance = hInstance; // instance handle...
  62. SHFusionInitializeFromModuleID(hInstance, 124);
  63. g_cfShellIDList = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_SHELLIDLIST);
  64. DebugProcessAttach();
  65. TraceSetMaskFromCLSID(CLSID_CscShellExt);
  66. break;
  67. case DLL_PROCESS_DETACH:
  68. DebugProcessDetach();
  69. if (NULL != g_heventTerminate)
  70. CloseHandle(g_heventTerminate);
  71. if (NULL != g_hmutexAdminPin)
  72. CloseHandle(g_hmutexAdminPin);
  73. SHFusionUninitialize();
  74. break;
  75. case DLL_THREAD_DETACH:
  76. DebugThreadDetach();
  77. break;
  78. }
  79. return TRUE;
  80. }
  81. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  82. {
  83. HRESULT hr;
  84. PFNCREATEINSTANCE pfnCreateInstance = NULL;
  85. *ppv = NULL;
  86. if (IsOS(OS_PERSONAL))
  87. {
  88. //
  89. // Offline Files is not available on 'Personal' SKU
  90. //
  91. return CLASS_E_CLASSNOTAVAILABLE;
  92. }
  93. if (IsEqualCLSID(rclsid, CLSID_OfflineFilesOptions))
  94. {
  95. //
  96. // Post Win2000:
  97. // The Offline Files options page is always available
  98. // even if TS is in a mode incompatible with CSC. In such
  99. // cases we'll display the Options page but replace the controls
  100. // with static text telling the user to place TS in a CSC-
  101. // compatible mode. Once they do this, the text will be replaced
  102. // with the normal controls to manage CSC.
  103. //
  104. pfnCreateInstance = COfflineFilesOptions_CreateInstance;
  105. }
  106. else
  107. {
  108. //
  109. // The objects at the top here can be created even
  110. // when CSC is disabled.
  111. //
  112. if (IsEqualCLSID(rclsid, CLSID_OfflineFilesFolder))
  113. {
  114. if (CConfig::GetSingleton().NoCacheViewer())
  115. {
  116. //
  117. // Policy can specify that the user not have access to the
  118. // Offline Files folder (aka viewer). If this policy is set,
  119. // the user should have no way to get to this point through
  120. // the UI. This check is a small dose of paranoia.
  121. //
  122. return CLASS_E_CLASSNOTAVAILABLE;
  123. }
  124. pfnCreateInstance = COfflineFilesFolder_CreateInstance;
  125. }
  126. else
  127. {
  128. //
  129. // The objects below here require CSC. That is, it
  130. // makes no sense for them to be created when CSC
  131. // is disabled.
  132. //
  133. if (!IsCSCEnabled())
  134. return E_FAIL;
  135. if (IsEqualCLSID(rclsid, CLSID_CscShellExt))
  136. pfnCreateInstance = CCscShellExt::CreateInstance;
  137. else if (IsEqualCLSID(rclsid, CLSID_CscUpdateHandler))
  138. pfnCreateInstance = CCscUpdate::CreateInstance;
  139. else if (IsEqualCLSID(rclsid, CLSID_CscVolumeCleaner))
  140. pfnCreateInstance = CCscVolumeCleaner::CreateInstance;
  141. else if (IsEqualCLSID(rclsid, CLSID_CscVolumeCleaner2))
  142. pfnCreateInstance = CCscVolumeCleaner::CreateInstance2;
  143. else
  144. return CLASS_E_CLASSNOTAVAILABLE;
  145. }
  146. }
  147. CClassFactory *pClassFactory = new CClassFactory(pfnCreateInstance);
  148. if (pClassFactory)
  149. {
  150. hr = pClassFactory->QueryInterface(riid, ppv);
  151. pClassFactory->Release(); // release initial ref
  152. }
  153. else
  154. hr = E_OUTOFMEMORY;
  155. return hr;
  156. }
  157. STDAPI DllCanUnloadNow(void)
  158. {
  159. return (g_cRefCount == 0 ? S_OK : S_FALSE);
  160. }
  161. STDAPI_(void) DllAddRef(void)
  162. {
  163. InterlockedIncrement(&g_cRefCount);
  164. }
  165. STDAPI_(void) DllRelease(void)
  166. {
  167. InterlockedDecrement(&g_cRefCount);
  168. }
  169. HRESULT CallRegInstall(HMODULE hModule, LPCSTR pszSection)
  170. {
  171. HRESULT hr = E_FAIL;
  172. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  173. if (hinstAdvPack)
  174. {
  175. REGINSTALL pfnRegInstall = (REGINSTALL)GetProcAddress(hinstAdvPack, achREGINSTALL);
  176. if (pfnRegInstall)
  177. hr = pfnRegInstall(hModule, pszSection, NULL);
  178. FreeLibrary(hinstAdvPack);
  179. }
  180. return hr;
  181. }
  182. STDAPI DllRegisterServer(void)
  183. {
  184. return CallRegInstall(g_hInstance, "DefaultInstall");
  185. }
  186. STDAPI DllUnregisterServer(void)
  187. {
  188. return CallRegInstall(g_hInstance, "DefaultUninstall");
  189. }
  190. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppv)
  191. {
  192. static const QITAB qit[] =
  193. {
  194. QITABENT(CClassFactory, IClassFactory),
  195. { 0 },
  196. };
  197. return QISearch(this, qit, riid, ppv);
  198. }
  199. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  200. {
  201. return InterlockedIncrement(&m_cRef);
  202. }
  203. STDMETHODIMP_(ULONG) CClassFactory::Release()
  204. {
  205. ASSERT( 0 != m_cRef );
  206. ULONG cRef = InterlockedDecrement(&m_cRef);
  207. if ( 0 == cRef )
  208. {
  209. delete this;
  210. }
  211. return cRef;
  212. }
  213. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
  214. {
  215. HRESULT hr = E_UNEXPECTED;
  216. *ppv = NULL;
  217. if (pUnkOuter)
  218. return CLASS_E_NOAGGREGATION;
  219. if (m_pfnCreateInstance)
  220. hr = m_pfnCreateInstance(riid, ppv);
  221. return hr;
  222. }
  223. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  224. {
  225. if (fLock)
  226. DllAddRef();
  227. else
  228. DllRelease();
  229. return S_OK;
  230. }