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.

313 lines
7.8 KiB

  1. /***************************************************************************
  2. * dll.c
  3. *
  4. * Standard DLL entry-point functions
  5. *
  6. ***************************************************************************/
  7. // Note: Proxy/Stub Information from ATL
  8. //
  9. // To merge the proxy/stub code into the object DLL, add the file
  10. // dlldatax.c to the project. Make sure precompiled headers
  11. // are turned off for this file, and add _MERGE_PROXYSTUB to the
  12. // defines for the project.
  13. //
  14. // If you are not running WinNT4.0 or Win95 with DCOM, then you
  15. // need to remove the following define from dlldatax.c
  16. // #define _WIN32_WINNT 0x0400
  17. //
  18. // Further, if you are running MIDL without /Oicf switch, you also
  19. // need to remove the following define from dlldatax.c.
  20. // #define USE_STUBLESS_PROXY
  21. //
  22. // Modify the custom build rule for shappmgr.idl by adding the following
  23. // files to the Outputs.
  24. // shappmgr_p.c
  25. // dlldata.c
  26. // To build a separate proxy/stub DLL,
  27. // run nmake -f shappmgrps.mk in the project directory.
  28. #include "priv.h"
  29. #include "sccls.h"
  30. #include <ntverp.h>
  31. #include <advpub.h> // For REGINSTALL
  32. // Define GUIDs
  33. extern "C"
  34. {
  35. HINSTANCE g_hinst = NULL;
  36. int g_cxIcon;
  37. int g_cyIcon;
  38. BOOL g_bMirroredOS;
  39. LONG g_cRefThisDll = 0; // per-instance
  40. #ifdef WX86
  41. //
  42. // from uninstal.c
  43. //
  44. extern BOOL bWx86Enabled;
  45. BOOL IsWx86Enabled(VOID);
  46. #endif
  47. };
  48. CComModule _Module; // ATL module object
  49. /*----------------------------------------------------------
  50. Purpose: DllEntryPoint
  51. */
  52. BOOL
  53. APIENTRY
  54. DllMain(
  55. IN HINSTANCE hinst,
  56. IN DWORD dwReason,
  57. IN LPVOID lpReserved)
  58. {
  59. #ifdef _MERGE_PROXYSTUB
  60. if (!PrxDllMain(hInstance, dwReason, lpReserved))
  61. return FALSE;
  62. #endif
  63. switch(dwReason)
  64. {
  65. case DLL_PROCESS_ATTACH:
  66. DisableThreadLibraryCalls(hinst);
  67. SHFusionInitializeFromModule(hinst);
  68. #ifdef DEBUG
  69. CcshellGetDebugFlags();
  70. if (g_dwBreakFlags & BF_ONDLLLOAD)
  71. DebugBreak();
  72. #endif
  73. g_hinst = hinst;
  74. g_cxIcon = GetSystemMetrics(SM_CXICON);
  75. g_cyIcon = GetSystemMetrics(SM_CYICON);
  76. g_bMirroredOS = IS_MIRRORING_ENABLED();
  77. #ifdef WX86
  78. bWx86Enabled = IsWx86Enabled();
  79. #endif
  80. break;
  81. case DLL_PROCESS_DETACH:
  82. SHFusionUninitialize();
  83. break;
  84. case DLL_THREAD_ATTACH:
  85. case DLL_THREAD_DETACH:
  86. // We shouldn't get these because we called
  87. // DisableThreadLibraryCalls().
  88. ASSERT_MSG(0, "DllMain received DLL_THREAD_ATTACH/DETACH! We're not expecting this.");
  89. break;
  90. default:
  91. break;
  92. }
  93. return TRUE;
  94. }
  95. /*----------------------------------------------------------
  96. Purpose: This function provides the DLL version info. This
  97. allows the caller to distinguish running NT SUR vs.
  98. Win95 shell vs. Nashville, etc.
  99. The caller must GetProcAddress this function.
  100. Returns: NO_ERROR
  101. ERROR_INVALID_PARAMETER if pinfo is invalid
  102. */
  103. // All we have to do is declare this puppy and CCDllGetVersion does the rest
  104. DLLVER_DUALBINARY(VER_PRODUCTVERSION_DW, VER_PRODUCTBUILD_QFE);
  105. /*----------------------------------------------------------
  106. Purpose: Calls the ADVPACK entry-point which executes an inf
  107. file section.
  108. */
  109. HRESULT _CallRegInstall(LPCSTR szSection, BOOL bUninstall)
  110. {
  111. HRESULT hr = E_FAIL;
  112. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  113. if (hinstAdvPack)
  114. {
  115. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  116. if (pfnri)
  117. {
  118. STRENTRY seReg[] = {
  119. { "25", "%SystemRoot%" },
  120. { "11", "%SystemRoot%\\system32" },
  121. };
  122. STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
  123. hr = pfnri(g_hinst, szSection, &stReg);
  124. if (bUninstall)
  125. {
  126. // ADVPACK will return E_UNEXPECTED if you try to uninstall
  127. // (which does a registry restore) on an INF section that was
  128. // never installed. We uninstall sections that may never have
  129. // been installed, so ignore this error
  130. hr = ((E_UNEXPECTED == hr) ? S_OK : hr);
  131. }
  132. }
  133. FreeLibrary(hinstAdvPack);
  134. }
  135. return hr;
  136. }
  137. //
  138. // Remove any legacy registry information.
  139. //
  140. void _RemoveLegacyRegistryEntries(void)
  141. {
  142. //
  143. // Windows XP made the ADCCtl ActiveX control obsolete.
  144. // Remove the registration of this control.
  145. //
  146. SHDeleteKey(HKEY_CLASSES_ROOT, TEXT("ADCCtl.ADCCtl.1"));
  147. SHDeleteKey(HKEY_CLASSES_ROOT, TEXT("ADCCtl.ADCCtl"));
  148. SHDeleteKey(HKEY_CLASSES_ROOT, TEXT("CLSID\\{3964D9A0-AC96-11D1-9851-00C04FD91972}"));
  149. }
  150. /*----------------------------------------------------------
  151. Purpose: Install/uninstall user settings
  152. */
  153. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
  154. {
  155. HRESULT hr = S_OK;
  156. HRESULT hrExternal = S_OK;
  157. #ifdef DEBUG
  158. if (IsFlagSet(g_dwBreakFlags, BF_ONAPIENTER))
  159. {
  160. TraceMsg(TF_ALWAYS, "Stopping in DllInstall");
  161. DEBUG_BREAK;
  162. }
  163. #endif
  164. if (bInstall)
  165. {
  166. // Delete any old registration entries, then add the new ones.
  167. // Keep ADVPACK.DLL loaded across multiple calls to RegInstall.
  168. // (The inf engine doesn't guarantee DelReg/AddReg order, that's
  169. // why we explicitly unreg and reg here.)
  170. //
  171. hr = THR(_CallRegInstall("RegDll", FALSE));
  172. if (SUCCEEDED(hrExternal))
  173. hrExternal = hr;
  174. }
  175. else
  176. {
  177. hr = THR(_CallRegInstall("UnregDll", TRUE));
  178. if (SUCCEEDED(hrExternal))
  179. hrExternal = hr;
  180. }
  181. return hrExternal;
  182. }
  183. /*----------------------------------------------------------
  184. Purpose: Returns a class factory to create an object of
  185. the requested type.
  186. */
  187. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  188. {
  189. TraceMsg(TF_OBJLIFE, "DllGetClassObject called with riid=%x (%x)", riid, &riid);
  190. #ifdef _MERGE_PROXYSTUB
  191. if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
  192. return S_OK;
  193. #endif
  194. if (riid == IID_IClassFactory || riid == IID_IUnknown)
  195. {
  196. // Try our native class factory
  197. HRESULT hres = GetClassObject(rclsid, riid, ppv);
  198. if (FAILED(hres))
  199. {
  200. // Try the ATL class factory
  201. hres = _Module.GetClassObject(rclsid, riid, ppv);
  202. }
  203. return hres;
  204. }
  205. *ppv = NULL;
  206. return CLASS_E_CLASSNOTAVAILABLE;
  207. }
  208. STDAPI DllCanUnloadNow(void)
  209. {
  210. #ifdef _MERGE_PROXYSTUB
  211. if (PrxDllCanUnloadNow() != S_OK)
  212. return S_FALSE;
  213. #endif
  214. // This component uses ATL and natively-implemented COM objects
  215. if (0 != g_cRefThisDll || 0 != _Module.GetLockCount())
  216. return S_FALSE;
  217. TraceMsg(DM_TRACE, "DllCanUnloadNow returning S_OK (bye, bye...)");
  218. return S_OK;
  219. }
  220. STDAPI_(void) DllAddRef(void)
  221. {
  222. InterlockedIncrement(&g_cRefThisDll);
  223. ASSERT(g_cRefThisDll < 1000); // reasonable upper limit
  224. }
  225. STDAPI_(void) DllRelease(void)
  226. {
  227. ASSERT( 0 != g_cRefThisDll );
  228. InterlockedDecrement(&g_cRefThisDll);
  229. }
  230. STDAPI DllRegisterServer(void)
  231. {
  232. HRESULT hres = S_OK;
  233. //
  234. // We have some old registry entries that must be removed on upgrade.
  235. //
  236. _RemoveLegacyRegistryEntries();
  237. #ifdef _MERGE_PROXYSTUB
  238. hres = THR(PrxDllRegisterServer());
  239. if (FAILED(hres))
  240. return hres;
  241. #endif
  242. return hres;
  243. }
  244. STDAPI DllUnregisterServer(void)
  245. {
  246. #ifdef _MERGE_PROXYSTUB
  247. PrxDllUnregisterServer();
  248. #endif
  249. return S_OK;
  250. }