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.

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