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.

918 lines
34 KiB

  1. /*****************************************************************************\
  2. FILE: dllreg.cpp
  3. DESCRIPTION:
  4. Register selfreg.inf, which exists in our resource.
  5. BryanSt 4/4/2000 (Bryan Starbuck)
  6. Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
  7. \*****************************************************************************/
  8. #include "priv.h"
  9. #include <advpub.h>
  10. #include <comcat.h>
  11. #include <theme.h> // For LIBID_Theme
  12. #include <userenv.h> // PT_ROAMING from userenv.dll
  13. #define SZ_MUILANG_CMDLINEARG L"/RES="
  14. #define SZ_MUILANG_CMDLINEARG_DEFAULT L"/RES=%04x"
  15. extern CComModule _Module;
  16. BOOL g_fInSetup = FALSE;
  17. BOOL g_fDoNotInstallThemeWallpaper = FALSE; // This is used to not install wallpaper.
  18. HRESULT InstallVS(LPCWSTR pszCmdLine);
  19. // helper macros
  20. // ADVPACK will return E_UNEXPECTED if you try to uninstall (which does a registry restore)
  21. // on an INF section that was never installed. We uninstall sections that may never have
  22. // been installed, so this MACRO will quiet these errors.
  23. #define QuietInstallNoOp(hr) ((E_UNEXPECTED == hr) ? S_OK : hr)
  24. BOOL UnregisterTypeLibrary(const CLSID* piidLibrary)
  25. {
  26. TCHAR szScratch[GUIDSTR_MAX];
  27. HKEY hk;
  28. BOOL fResult = FALSE;
  29. // convert the libid into a string.
  30. SHStringFromGUID(*piidLibrary, szScratch, ARRAYSIZE(szScratch));
  31. if (RegOpenKey(HKEY_CLASSES_ROOT, TEXT("TypeLib"), &hk) == ERROR_SUCCESS)
  32. {
  33. fResult = RegDeleteKey(hk, szScratch);
  34. RegCloseKey(hk);
  35. }
  36. return fResult;
  37. }
  38. HRESULT MyRegTypeLib(void)
  39. {
  40. ITypeLib * pTypeLib;
  41. WCHAR szTmp[MAX_PATH];
  42. GetModuleFileName(HINST_THISDLL, szTmp, ARRAYSIZE(szTmp));
  43. // Load and register our type library.
  44. HRESULT hr = LoadTypeLib(szTmp, &pTypeLib);
  45. if (SUCCEEDED(hr))
  46. {
  47. // call the unregister type library as we had some old junk that
  48. // was registered by a previous version of OleAut32, which is now causing
  49. // the current version to not work on NT...
  50. UnregisterTypeLibrary(&LIBID_Theme);
  51. hr = RegisterTypeLib(pTypeLib, szTmp, NULL);
  52. if (FAILED(hr))
  53. {
  54. TraceMsg(TF_WARNING, "RegisterTypeLib failed (%x)", hr);
  55. }
  56. pTypeLib->Release();
  57. }
  58. else
  59. {
  60. TraceMsg(TF_WARNING, "LoadTypeLib failed (%x)", hr);
  61. }
  62. return hr;
  63. }
  64. /*----------------------------------------------------------
  65. Purpose: Calls the ADVPACK entry-point which executes an inf
  66. file section.
  67. Returns:
  68. Cond: --
  69. */
  70. HRESULT CallRegInstall(LPSTR szSection)
  71. {
  72. HRESULT hr = E_FAIL;
  73. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  74. if (hinstAdvPack)
  75. {
  76. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  77. if (pfnri)
  78. {
  79. char szIEPath[MAX_PATH];
  80. STRENTRY seReg[] = {
  81. { "NO_LONGER_USED", szIEPath },
  82. // These two NT-specific entries must be at the end
  83. { "25", "%SystemRoot%" },
  84. { "11", "%SystemRoot%\\system32" },
  85. };
  86. STRTABLE stReg = { ARRAYSIZE(seReg) - 2, seReg };
  87. szIEPath[0] = 0;
  88. hr = pfnri(HINST_THISDLL, szSection, &stReg);
  89. }
  90. FreeLibrary(hinstAdvPack);
  91. }
  92. return hr;
  93. }
  94. enum eThemeToSetup
  95. {
  96. eThemeNoChange = 0,
  97. eThemeWindowsClassic,
  98. eThemeProfessional,
  99. eThemeConsumer,
  100. };
  101. eThemeToSetup GetVisualStyleToSetup(BOOL fPerUser)
  102. {
  103. eThemeToSetup eVisualStyle = eThemeNoChange;
  104. #ifndef _WIN64
  105. if (IsOS(OS_PERSONAL))
  106. {
  107. #ifdef FEATURE_PERSONAL_SKIN_ENABLED
  108. eVisualStyle = eThemeConsumer;
  109. #else // FEATURE_PERSONAL_SKIN_ENABLED
  110. eVisualStyle = eThemeProfessional; // We don't support Consumer yet.
  111. #endif // FEATURE_PERSONAL_SKIN_ENABLED
  112. }
  113. else if (IsOS(OS_PROFESSIONAL))
  114. {
  115. eVisualStyle = eThemeProfessional;
  116. }
  117. #endif
  118. return eVisualStyle;
  119. }
  120. eThemeToSetup GetThemeToSetup(BOOL fPerUser)
  121. {
  122. eThemeToSetup eTheme = eThemeNoChange;
  123. // We want Pro, if:
  124. // 1. Not IA64
  125. // 2. Not Server or Personal
  126. // 3. Not Roaming
  127. #ifndef _WIN64
  128. if (IsOS(OS_PERSONAL))
  129. {
  130. #ifdef FEATURE_PERSONAL_SKIN_ENABLED
  131. eTheme = eThemeConsumer;
  132. #else // FEATURE_PERSONAL_SKIN_ENABLED
  133. eTheme = eThemeProfessional; // We don't support Consumer yet.
  134. #endif // FEATURE_PERSONAL_SKIN_ENABLED
  135. }
  136. else if (IsOS(OS_PROFESSIONAL))
  137. {
  138. eTheme = eThemeProfessional;
  139. }
  140. #endif
  141. return eTheme;
  142. }
  143. BOOL IsNewUser(void)
  144. {
  145. // We know this user is newly created because it has a key that as copied from
  146. // the ".default" hive. If it was a upgrade user from pre-whistler, then it
  147. // would not have this key.
  148. BOOL fNewUser = FALSE;
  149. TCHAR szVersion[MAX_PATH];
  150. if (SUCCEEDED(HrRegGetValueString(HKEY_CURRENT_USER, THEMEMGR_REGKEY, THEMEPROP_WHISTLERBUILD, szVersion, ARRAYSIZE(szVersion))) &&
  151. szVersion[0])
  152. {
  153. fNewUser = TRUE;
  154. }
  155. return fNewUser;
  156. }
  157. BOOL IsUserRoaming(void)
  158. {
  159. BOOL fRoaming = FALSE;
  160. DWORD dwProfile;
  161. if (GetProfileType(&dwProfile))
  162. {
  163. fRoaming = ((dwProfile & (PT_ROAMING | PT_MANDATORY)) ? TRUE : FALSE);
  164. }
  165. return fRoaming;
  166. }
  167. BOOL IsUserHighContrastUser(void)
  168. {
  169. BOOL fHighContrast = FALSE;
  170. HIGHCONTRAST hc;
  171. hc.cbSize = sizeof(hc);
  172. if (ClassicSystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, 0) &&
  173. (hc.dwFlags & HCF_HIGHCONTRASTON))
  174. {
  175. fHighContrast = TRUE;
  176. }
  177. return fHighContrast;
  178. }
  179. SIZE_T GetMachinePhysicalRAMSize(void)
  180. {
  181. MEMORYSTATUS ms = {0};
  182. GlobalMemoryStatus(&ms);
  183. SIZE_T nMegabytes = (ms.dwTotalPhys / (1024 * 1024));
  184. return nMegabytes;
  185. }
  186. HRESULT InstallTheme(IThemeManager * pThemeManager, LPCTSTR pszThemePath)
  187. {
  188. HRESULT hr = E_OUTOFMEMORY;
  189. CComVariant varTheme(pszThemePath);
  190. if (varTheme.bstrVal)
  191. {
  192. ITheme * pTheme;
  193. hr = pThemeManager->get_item(varTheme, &pTheme);
  194. if (SUCCEEDED(hr))
  195. {
  196. hr = pThemeManager->put_SelectedTheme(pTheme);
  197. pTheme->Release();
  198. }
  199. }
  200. return hr;
  201. }
  202. HRESULT InstallThemeAndDoNotStompBackground(int nLastVersion, LPCTSTR pszThemePath, LPCTSTR pszVisualStylePath, LPCTSTR pszVisualStyleColor, LPCTSTR pszVisualStyleSize)
  203. {
  204. TCHAR szPath[MAX_PATH];
  205. WALLPAPEROPT wpo = {0};
  206. HRESULT hr = S_OK;
  207. wpo.dwSize = sizeof(wpo);
  208. wpo.dwStyle = WPSTYLE_STRETCH; // We use stretch in case it fails.
  209. szPath[0] = 0;
  210. // This implements Whistler #185935. We want to set the wallpaper to
  211. // "%windir%\web\wallpaper\Professional.bmp" if it's a clean install,
  212. // the wallpaper is blank, or it's set to something we don't like.
  213. {
  214. IActiveDesktop * pActiveDesktop = NULL;
  215. hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IActiveDesktop, &pActiveDesktop));
  216. if (SUCCEEDED(hr))
  217. {
  218. // Let's see if this is an upgrade case and they already specified wallpaper.
  219. hr = pActiveDesktop->GetWallpaper(szPath, ARRAYSIZE(szPath), 0);
  220. if (SUCCEEDED(hr) && szPath[0])
  221. {
  222. TCHAR szNone[MAX_PATH];
  223. LogStatus("InstallThemeAndDoNotStompBackground() Existing Background=%ls\r\n", szPath);
  224. if (LoadString(HINST_THISDLL, IDS_NONE, szNone, ARRAYSIZE(szNone)) &&
  225. !StrCmpI(szNone, szPath)) // Make sure the wallpaper isn't "(None)".
  226. {
  227. szPath[0] = 0;
  228. }
  229. else
  230. {
  231. LPTSTR pszFilename = PathFindFileName(szPath);
  232. if (LoadString(HINST_THISDLL, IDS_SETUP_BETA2_UPGRADEWALLPAPER, szNone, ARRAYSIZE(szNone)) &&
  233. (3 == nLastVersion) &&
  234. !StrCmpI(szNone, pszFilename))
  235. {
  236. // This is a "Beta2"->RTM upgrade. We need to move from "Red Moon Desert.bmp" to "Bliss.bmp".
  237. szPath[0] = 0;
  238. }
  239. else
  240. {
  241. if ((14 == lstrlen(pszFilename)) &&
  242. !StrCmpNI(pszFilename, TEXT("Wallpaper"), 9))
  243. {
  244. // This is the "WallpaperX.bmp" template wallpaper we use. So find the original.
  245. TCHAR szOriginal[MAX_PATH];
  246. if (SUCCEEDED(HrRegGetPath(HKEY_CURRENT_USER, SZ_REGKEY_CPDESKTOP, SZ_REGVALUE_CONVERTED_WALLPAPER, szOriginal, ARRAYSIZE(szOriginal))))
  247. {
  248. StrCpyN(szPath, szOriginal, ARRAYSIZE(szPath));
  249. }
  250. }
  251. hr = pActiveDesktop->GetWallpaperOptions(&wpo, 0);
  252. }
  253. }
  254. WCHAR szTemp[MAX_PATH];
  255. // The string may come back with environment variables.
  256. if (0 == SHExpandEnvironmentStrings(szPath, szTemp, ARRAYSIZE(szTemp)))
  257. {
  258. StrCpyN(szTemp, szPath, ARRAYSIZE(szTemp)); // We failed so use the original.
  259. }
  260. StrCpyN(szPath, szTemp, ARRAYSIZE(szPath)); // We failed so use the original.
  261. LogStatus("InstallThemeAndDoNotStompBackground() Background=%ls\r\n", szPath);
  262. if (szPath[0])
  263. {
  264. g_fDoNotInstallThemeWallpaper = TRUE;
  265. }
  266. }
  267. ATOMICRELEASE(pActiveDesktop);
  268. }
  269. // If the machine has 64MB or less, don't have setup add a wallpaper. Wallpapers
  270. // use about 1.5MB of working set and cause super physical memory contention.
  271. if (!g_fDoNotInstallThemeWallpaper && (70 >= GetMachinePhysicalRAMSize()))
  272. {
  273. g_fDoNotInstallThemeWallpaper = TRUE;
  274. }
  275. }
  276. IThemeManager * pThemeManager;
  277. hr = CThemeManager_CreateInstance(NULL, IID_PPV_ARG(IThemeManager, &pThemeManager));
  278. if (SUCCEEDED(hr))
  279. {
  280. if (pszThemePath && pszThemePath[0])
  281. {
  282. LogStatus("InstallThemeAndDoNotStompBackground() Installing Theme=%ls\r\n", pszThemePath);
  283. hr = InstallTheme(pThemeManager, pszThemePath);
  284. }
  285. if (pszVisualStylePath && pszVisualStylePath[0])
  286. {
  287. // Otherwise, we install the visual style.
  288. LogStatus("InstallThemeAndDoNotStompBackground() VS=%ls, Color=%ls, Size=%ls.\r\n", pszVisualStylePath, pszVisualStyleColor, pszVisualStyleSize);
  289. hr = InstallVisualStyle(pThemeManager, pszVisualStylePath, pszVisualStyleColor, pszVisualStyleSize);
  290. }
  291. // This ApplyNow() call will take a little while in normal situation (~10-20 seconds) in order
  292. // to broadcast the message to all open apps. If a top level window is hung, it may take the
  293. // full 30 seconds to timeout.
  294. hr = pThemeManager->ApplyNow();
  295. IUnknown_SetSite(pThemeManager, NULL); // Tell him to break the ref-count cycle with his children.
  296. ATOMICRELEASE(pThemeManager);
  297. // Now we put the wallpaper back
  298. if (szPath[0])
  299. {
  300. IActiveDesktop * pActiveDesktop2 = NULL;
  301. // I purposely do not use the same IActiveDesktop object as above. I do not want them to think
  302. // this is a no-op because they have stale info.
  303. hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IActiveDesktop, &pActiveDesktop2));
  304. if (SUCCEEDED(hr))
  305. {
  306. // Oh no, we replaced their wallpaper. Let's set it back to what they like.
  307. hr = pActiveDesktop2->SetWallpaper(szPath, 0);
  308. if (SUCCEEDED(hr))
  309. {
  310. LogStatus("InstallThemeAndDoNotStompBackground() Reapplying Wallpaper=%ls.\r\n", szPath);
  311. hr = pActiveDesktop2->SetWallpaperOptions(&wpo, 0);
  312. }
  313. pActiveDesktop2->ApplyChanges(AD_APPLY_ALL);
  314. pActiveDesktop2->Release();
  315. }
  316. }
  317. }
  318. LogStatus("InstallThemeAndDoNotStompBackground() returned hr=%#08lx.\r\n", hr);
  319. return hr;
  320. }
  321. /*****************************************************************************\
  322. DESCRIPTION:
  323. This function will put the defaults for "Visual Styles Off" and "Visual
  324. Styles on" so the Perf CPL can toggle back and forth.
  325. \*****************************************************************************/
  326. HRESULT SetupPerfDefaultsForUser(void)
  327. {
  328. HRESULT hr = S_OK;
  329. TCHAR szThemePath[MAX_PATH];
  330. TCHAR szVisualStylePath[MAX_PATH];
  331. TCHAR szVisualStyleColor[MAX_PATH];
  332. TCHAR szVisualStyleSize[MAX_PATH];
  333. hr = HrRegGetPath(HKEY_LOCAL_MACHINE, SZ_THEMES, SZ_REGVALUE_INSTALLCUSTOM_THEME, szThemePath, ARRAYSIZE(szThemePath));
  334. if (FAILED(hr))
  335. {
  336. hr = HrRegGetPath(HKEY_LOCAL_MACHINE, SZ_THEMES, SZ_REGVALUE_INSTALL_THEME, szThemePath, ARRAYSIZE(szThemePath));
  337. }
  338. if (FAILED(hr) || !szThemePath[0])
  339. {
  340. StrCpyN(szThemePath, L"%ResourceDir%\\themes\\Windows Classic.theme", ARRAYSIZE(szThemePath));
  341. }
  342. switch (GetVisualStyleToSetup(FALSE))
  343. {
  344. case eThemeNoChange:
  345. case eThemeWindowsClassic:
  346. StrCpyN(szVisualStylePath, L"", ARRAYSIZE(szVisualStylePath));
  347. LoadString(HINST_THISDLL, IDS_DEFAULT_APPEARANCES_SCHEME, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  348. LoadString(HINST_THISDLL, IDS_SCHEME_SIZE_NORMAL_CANONICAL, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  349. break;
  350. case eThemeProfessional:
  351. StrCpyN(szVisualStylePath, L"%ResourceDir%\\themes\\Luna\\Luna.msstyles", ARRAYSIZE(szVisualStylePath));
  352. LoadString(HINST_THISDLL, IDS_PROMSTHEME_DEFAULTCOLOR, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  353. LoadString(HINST_THISDLL, IDS_PROMSTHEME_DEFAULTSIZE, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  354. break;
  355. case eThemeConsumer:
  356. StrCpyN(szVisualStylePath, L"%ResourceDir%\\themes\\Consumer\\Consumer.msstyles", ARRAYSIZE(szVisualStylePath));
  357. LoadString(HINST_THISDLL, IDS_CONMSTHEME_DEFAULTCOLOR, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  358. LoadString(HINST_THISDLL, IDS_CONMSTHEME_DEFAULTSIZE, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  359. break;
  360. }
  361. // Set the defaults
  362. hr = HrRegSetPath(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_THEME, TRUE, szThemePath);
  363. hr = HrRegSetPath(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_VISUALSTYLE, TRUE, szVisualStylePath);
  364. hr = HrRegSetValueString(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_VSCOLOR, szVisualStyleColor);
  365. hr = HrRegSetValueString(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_VSSIZE, szVisualStyleSize);
  366. // Set the defaults for the perf CPL to use if forced to "Visual Styles On"
  367. #ifdef FEATURE_PERSONAL_SKIN_ENABLED
  368. if (IsOS(OS_PERSONAL))
  369. {
  370. StrCpyN(szThemePath, L"%ResourceDir%\\themes\\Personal.theme", ARRAYSIZE(szThemePath));
  371. StrCpyN(szVisualStylePath, L"%ResourceDir%\\themes\\Consumer\\Consumer.msstyles", ARRAYSIZE(szVisualStylePath));
  372. LoadString(HINST_THISDLL, IDS_CONMSTHEME_DEFAULTCOLOR, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  373. LoadString(HINST_THISDLL, IDS_CONMSTHEME_DEFAULTSIZE, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  374. }
  375. else
  376. #endif // FEATURE_PERSONAL_SKIN_ENABLED
  377. {
  378. StrCpyN(szThemePath, L"%ResourceDir%\\themes\\Luna.theme", ARRAYSIZE(szThemePath));
  379. StrCpyN(szVisualStylePath, L"%ResourceDir%\\themes\\Luna\\Luna.msstyles", ARRAYSIZE(szVisualStylePath));
  380. LoadString(HINST_THISDLL, IDS_PROMSTHEME_DEFAULTCOLOR, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  381. LoadString(HINST_THISDLL, IDS_PROMSTHEME_DEFAULTSIZE, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  382. }
  383. hr = HrRegSetPath(HKEY_CURRENT_USER, SZ_REGKEY_THEME_DEFVSON, SZ_REGVALUE_INSTALL_VISUALSTYLE, TRUE, szVisualStylePath);
  384. hr = HrRegSetValueString(HKEY_CURRENT_USER, SZ_REGKEY_THEME_DEFVSON, SZ_REGVALUE_INSTALL_VSCOLOR, szVisualStyleColor);
  385. hr = HrRegSetValueString(HKEY_CURRENT_USER, SZ_REGKEY_THEME_DEFVSON, SZ_REGVALUE_INSTALL_VSSIZE, szVisualStyleSize);
  386. // Set the defaults for the perf CPL to use if forced to "Visual Styles Off"
  387. StrCpyN(szVisualStylePath, L"", ARRAYSIZE(szVisualStylePath));
  388. LoadString(HINST_THISDLL, IDS_DEFAULT_APPEARANCES_SCHEME, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  389. LoadString(HINST_THISDLL, IDS_SCHEME_SIZE_NORMAL_CANONICAL, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  390. hr = HrRegSetPath(HKEY_CURRENT_USER, SZ_REGKEY_THEME_DEFVSOFF, SZ_REGVALUE_INSTALL_VISUALSTYLE, TRUE, szVisualStylePath);
  391. hr = HrRegSetValueString(HKEY_CURRENT_USER, SZ_REGKEY_THEME_DEFVSOFF, SZ_REGVALUE_INSTALL_VSCOLOR, szVisualStyleColor);
  392. hr = HrRegSetValueString(HKEY_CURRENT_USER, SZ_REGKEY_THEME_DEFVSOFF, SZ_REGVALUE_INSTALL_VSSIZE, szVisualStyleSize);
  393. LogStatus("SetupPerfDefaultsForUser() sets:\r\n Theme=%ls,\r\n VisualStyle=%ls,\r\n Color=%ls,\r\n Size=%ls. returned hr=%#08lx.\r\n", szThemePath, szVisualStylePath, szVisualStyleColor, szVisualStyleSize, hr);
  394. return hr;
  395. }
  396. #define SZ_THEMESETUP_VERISON L"1"
  397. /*****************************************************************************\
  398. DESCRIPTION:
  399. This function will be called for each user when "theme setup" has not
  400. yet run for that user. The machine setup will determine it's prefered
  401. Theme and VisualStyle. This code needs to take additional information about
  402. the user (Accessibilities on?, Policy on?, etc.) into account before finally
  403. installing the Theme and/or VisualStyle.
  404. \*****************************************************************************/
  405. HRESULT SetupThemeForUser(void)
  406. {
  407. HRESULT hr = S_OK;
  408. TCHAR szVersion[MAX_PATH];
  409. int nVersion;
  410. int nCurrentVersion = 0;
  411. if (SUCCEEDED(HrRegGetValueString(HKEY_CURRENT_USER, SZ_THEMES, REGVALUE_THEMESSETUPVER, szVersion, ARRAYSIZE(szVersion))))
  412. {
  413. StrToIntEx(szVersion, STIF_DEFAULT, &nCurrentVersion);
  414. }
  415. // If we succeeded, mark the registry that we don't need the user setup again.
  416. if (SUCCEEDED(HrRegGetValueString(HKEY_LOCAL_MACHINE, SZ_THEMES, REGVALUE_THEMESSETUPVER, szVersion, ARRAYSIZE(szVersion))) &&
  417. StrToIntEx(szVersion, STIF_DEFAULT, &nVersion))
  418. {
  419. if (nVersion > nCurrentVersion)
  420. {
  421. // We will skip this setup step for Clean boot. We will get called back during
  422. // the next logon to do the work then.
  423. if (!ClassicGetSystemMetrics(SM_CLEANBOOT))
  424. {
  425. TCHAR szThemePath[MAX_PATH];
  426. TCHAR szVisualStylePath[MAX_PATH];
  427. TCHAR szVisualStyleColor[MAX_PATH];
  428. TCHAR szVisualStyleSize[MAX_PATH];
  429. DWORD dwType;
  430. DWORD cbSize = sizeof(szThemePath);
  431. szVisualStylePath[0] = szVisualStyleColor[0] = szVisualStyleSize[0] = szThemePath[0] = 0;
  432. SetupPerfDefaultsForUser();
  433. SHRegGetUSValue(SZ_REGKEY_POLICIES_SYSTEM, SZ_REGVALUE_POLICY_INSTALLTHEME, &dwType, (void *) szThemePath, &cbSize, FALSE, NULL, 0);
  434. // First check the policy that admins use to force users to always use a certain visual style.
  435. // Specifying an empty value will cause no visual style to be setup.
  436. cbSize = sizeof(szVisualStylePath);
  437. if (ERROR_SUCCESS != SHRegGetUSValue(SZ_REGKEY_POLICIES_SYSTEM, SZ_REGVALUE_POLICY_SETVISUALSTYLE, &dwType, (void *) szVisualStylePath, &cbSize, FALSE, NULL, 0))
  438. {
  439. cbSize = sizeof(szVisualStylePath);
  440. // That was not set, so check for the policy admins want to set the visual style for the first time.
  441. if ((ERROR_SUCCESS != SHRegGetUSValue(SZ_REGKEY_POLICIES_SYSTEM, SZ_REGVALUE_POLICY_INSTALLVISUALSTYLE, &dwType, (void *) szVisualStylePath, &cbSize, FALSE, NULL, 0)))
  442. {
  443. if (!SHRegGetBoolUSValue(SZ_THEMES, SZ_REGVALUE_NO_THEMEINSTALL, FALSE, FALSE))
  444. {
  445. // If the user is Roaming, we don't setup themes or visual styles in order that their
  446. // settings will successfully roam downlevel.
  447. // We also do not modify user settings if their high contrast bit is set. We do this so
  448. // their system does not become unreadable.
  449. if (!IsUserRoaming() && !IsUserHighContrastUser())
  450. {
  451. LogStatus("SetupThemeForUser() Not Roaming and Not HighContrast.\r\n");
  452. hr = HrRegGetPath(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_THEME, szThemePath, ARRAYSIZE(szThemePath));
  453. if (FAILED(hr))
  454. {
  455. // That was not set, so see what the OS wants as a default.
  456. hr = HrRegGetPath(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_VISUALSTYLE, szVisualStylePath, ARRAYSIZE(szVisualStylePath));
  457. hr = HrRegGetPath(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_VSCOLOR, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  458. hr = HrRegGetPath(HKEY_CURRENT_USER, SZ_THEMES, SZ_REGVALUE_INSTALL_VSSIZE, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  459. }
  460. }
  461. else
  462. {
  463. LogStatus("SetupThemeForUser() Roaming or HighContrast is on.\r\n");
  464. }
  465. }
  466. }
  467. else
  468. {
  469. // It's okay if these fail, we will use defaults
  470. HrRegGetPath(HKEY_CURRENT_USER, SZ_REGKEY_POLICIES_SYSTEM, SZ_REGVALUE_INSTALL_VSCOLOR, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  471. HrRegGetPath(HKEY_CURRENT_USER, SZ_REGKEY_POLICIES_SYSTEM, SZ_REGVALUE_INSTALL_VSSIZE, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  472. LogStatus("SetupThemeForUser() SZ_REGVALUE_POLICY_INSTALLVISUALSTYLE policy set.\r\n");
  473. }
  474. }
  475. else
  476. {
  477. // Someone set the SetVisualStyle policy. This means that we won't install anything.
  478. szThemePath[0] = 0;
  479. LogStatus("SetupThemeForUser() SZ_REGVALUE_POLICY_SETVISUALSTYLE policy set.\r\n");
  480. if (szVisualStylePath[0] == L'\0') // If the policy is empty
  481. {
  482. // Install the default theme with no style
  483. LogStatus("SetupThemeForUser() Installed Windows Standard as per the SETVISUALSTYLE policy.\r\n");
  484. TCHAR szVisualStylePath[MAX_PATH];
  485. TCHAR szVisualStyleColor[MAX_PATH];
  486. TCHAR szVisualStyleSize[MAX_PATH];
  487. StrCpyN(szVisualStylePath, L"", ARRAYSIZE(szVisualStylePath));
  488. LoadString(HINST_THISDLL, IDS_DEFAULT_APPEARANCES_SCHEME, szVisualStyleColor, ARRAYSIZE(szVisualStyleColor));
  489. LoadString(HINST_THISDLL, IDS_SCHEME_SIZE_NORMAL_CANONICAL, szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  490. WCHAR szCmdLine[MAX_PATH * 3];
  491. StrCpyN(szCmdLine, SZ_INSTALL_VS, ARRAYSIZE(szCmdLine));
  492. StrCatBuff(szCmdLine, szVisualStylePath, ARRAYSIZE(szCmdLine));
  493. StrCatBuff(szCmdLine, L"','", ARRAYSIZE(szCmdLine));
  494. StrCatBuff(szCmdLine, szVisualStyleColor, ARRAYSIZE(szCmdLine));
  495. StrCatBuff(szCmdLine, L"','", ARRAYSIZE(szCmdLine));
  496. StrCatBuff(szCmdLine, szVisualStyleSize, ARRAYSIZE(szCmdLine));
  497. StrCatBuff(szCmdLine, L"'", ARRAYSIZE(szCmdLine));
  498. InstallVS(szCmdLine);
  499. }
  500. }
  501. ExpandResourceDir(szThemePath, ARRAYSIZE(szThemePath));
  502. ExpandResourceDir(szVisualStylePath, ARRAYSIZE(szVisualStylePath));
  503. // Specifying a Theme is specified, we install that. In that case, the visual style comes from there.
  504. if (szThemePath[0] || szVisualStylePath[0])
  505. {
  506. hr = InstallThemeAndDoNotStompBackground(nCurrentVersion, szThemePath, szVisualStylePath, szVisualStyleColor, szVisualStyleSize);
  507. }
  508. if (SUCCEEDED(hr))
  509. {
  510. // If we succeeded, mark the registry that we don't need the user setup again.
  511. hr = HrRegSetValueString(HKEY_CURRENT_USER, SZ_THEMES, REGVALUE_THEMESSETUPVER, szVersion);
  512. }
  513. LogStatus("SetupThemeForUser() sets:\r\n Theme=%ls,\r\n VisualStyle=%ls,\r\n Color=%ls,\r\n Size=%ls. returned hr=%#08lx.\r\n", szThemePath, szVisualStylePath, szVisualStyleColor, szVisualStyleSize, hr);
  514. }
  515. }
  516. }
  517. return hr;
  518. }
  519. HRESULT SetupThemeForMachine(void)
  520. {
  521. HRESULT hr = S_OK;
  522. eThemeToSetup eTheme = GetThemeToSetup(FALSE);
  523. eThemeToSetup eVisualStyle = GetVisualStyleToSetup(FALSE);
  524. WCHAR szVisualStyleName[MAX_PATH];
  525. WCHAR szThemeName[MAX_PATH];
  526. WCHAR szTemp[MAX_PATH];
  527. switch (eTheme)
  528. {
  529. case eThemeNoChange:
  530. szThemeName[0] = 0;
  531. break;
  532. case eThemeWindowsClassic:
  533. StrCpyN(szThemeName, L"%ResourceDir%\\themes\\Windows Classic.theme", ARRAYSIZE(szThemeName));
  534. break;
  535. case eThemeProfessional:
  536. StrCpyN(szThemeName, L"%ResourceDir%\\themes\\Luna.theme", ARRAYSIZE(szThemeName));
  537. break;
  538. case eThemeConsumer:
  539. StrCpyN(szThemeName, L"%ResourceDir%\\themes\\Personal.theme", ARRAYSIZE(szThemeName));
  540. break;
  541. }
  542. if (SUCCEEDED(HrRegGetValueString(HKEY_LOCAL_MACHINE, SZ_THEMES, SZ_REGVALUE_INSTALLCUSTOM_THEME, szTemp, ARRAYSIZE(szTemp))) &&
  543. (!szTemp[0] || PathFileExists(szTemp)))
  544. {
  545. // The admin or OEM wanted this custom theme installed instead.
  546. StrCpyN(szThemeName, szTemp, ARRAYSIZE(szThemeName));
  547. }
  548. if (szThemeName[0])
  549. {
  550. DWORD cbSize = (sizeof(szThemeName[0]) * (lstrlen(szThemeName) + 1));
  551. SHSetValue(HKEY_LOCAL_MACHINE, SZ_THEMES, SZ_REGVALUE_INSTALL_THEME, REG_SZ, (LPCVOID) szThemeName, cbSize);
  552. }
  553. switch (eVisualStyle)
  554. {
  555. case eThemeNoChange:
  556. szVisualStyleName[0] = 0;
  557. break;
  558. case eThemeWindowsClassic:
  559. szVisualStyleName[0] = 0;
  560. break;
  561. case eThemeProfessional:
  562. StrCpyN(szVisualStyleName, L"%SystemRoot%\\Resources\\themes\\Luna\\Luna.msstyles", ARRAYSIZE(szVisualStyleName));
  563. break;
  564. case eThemeConsumer:
  565. StrCpyN(szVisualStyleName, L"%SystemRoot%\\Resources\\themes\\Personal\\Personal.msstyles", ARRAYSIZE(szVisualStyleName));
  566. break;
  567. }
  568. if (szVisualStyleName[0])
  569. {
  570. DWORD cbSize = (sizeof(szVisualStyleName[0]) * (lstrlen(szVisualStyleName) + 1));
  571. SHSetValue(HKEY_LOCAL_MACHINE, SZ_THEMES, SZ_REGVALUE_INSTALL_VISUALSTYLE, REG_SZ, (LPCVOID) szVisualStyleName, cbSize);
  572. ExpandResourceDir(szVisualStyleName, ARRAYSIZE(szVisualStyleName));
  573. hr = ExpandThemeTokens(NULL, szVisualStyleName, ARRAYSIZE(szVisualStyleName)); // Expand %ThemeDir% or %WinDir%
  574. hr = RegisterDefaultTheme(szVisualStyleName, TRUE);
  575. }
  576. LogStatus("SetupThemeForMachine() T=%ls, VS=%ls. returned hr=%#08lx.\r\n", szThemeName, szVisualStyleName, hr);
  577. return hr;
  578. }
  579. STDAPI DllRegisterServer(void)
  580. {
  581. HRESULT hr;
  582. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  583. hr = CallRegInstall("DLL_RegInstall");
  584. //---- do this even if error occured ----
  585. MyRegTypeLib();
  586. if (hinstAdvPack)
  587. FreeLibrary(hinstAdvPack);
  588. return hr;
  589. }
  590. STDAPI DllUnregisterServer(void)
  591. {
  592. HRESULT hr;
  593. // UnInstall the registry values
  594. hr = CallRegInstall("DLL_RegUnInstall");
  595. UnregisterTypeLibrary(&LIBID_Theme);
  596. return hr;
  597. }
  598. HRESULT GetLanguageIDFromCmdLine(LPCWSTR pszCmdLine, LPWSTR pszLangID, DWORD cchSize)
  599. {
  600. HRESULT hr = E_FAIL;
  601. if (pszCmdLine && pszCmdLine[0])
  602. {
  603. LPWSTR pszStart = StrStrIW(pszCmdLine, SZ_MUILANG_CMDLINEARG);
  604. if (pszStart)
  605. {
  606. pszStart += ARRAYSIZE(SZ_MUILANG_CMDLINEARG)-1;
  607. StrCpyN(pszLangID, pszStart, cchSize);
  608. LPWSTR pszEnd = StrStrIW(pszLangID, L" ");
  609. if (pszEnd)
  610. {
  611. pszEnd[0] = 0x00;
  612. }
  613. hr = S_OK;
  614. }
  615. }
  616. if (FAILED(hr))
  617. {
  618. LANGID nLangID = GetUserDefaultLangID();
  619. if (!nLangID)
  620. {
  621. nLangID = GetSystemDefaultLangID();
  622. }
  623. wnsprintf(pszLangID, cchSize, L"%04x", nLangID);
  624. }
  625. return S_OK;
  626. }
  627. HRESULT VSParseCmdLine(LPCWSTR pszCmdLine, LPWSTR pszPath, int cchPath, LPWSTR pszColor, int cchColor, LPWSTR pszSize, int cchSize)
  628. {
  629. HRESULT hr = E_FAIL;
  630. pszPath[0] = pszColor[0] = pszSize[0] = 0;
  631. pszCmdLine = StrStrW(pszCmdLine, SZ_INSTALL_VS);
  632. pszCmdLine += (ARRAYSIZE(SZ_INSTALL_VS) - 1);
  633. LPWSTR pszEndOfVS = StrStrW(pszCmdLine, L"','");
  634. if (pszEndOfVS)
  635. {
  636. LPWSTR pszStartOfColor = (pszEndOfVS + 3);
  637. LPWSTR pszEndOfColor = StrStrW(pszStartOfColor, L"','");
  638. if (pszEndOfColor)
  639. {
  640. LPWSTR pszStartOfSize = (pszEndOfColor + 3);
  641. LPWSTR pszEndOfSize = StrStrW(pszStartOfSize, L"'");
  642. if (pszEndOfSize)
  643. {
  644. StrCpyN(pszPath, pszCmdLine, (int)min(cchPath, (pszEndOfVS - pszCmdLine + 1)));
  645. StrCpyN(pszColor, pszStartOfColor, (int)min(cchColor, (pszEndOfColor - pszStartOfColor + 1)));
  646. StrCpyN(pszSize, pszStartOfSize, (int)min(cchSize, (pszEndOfSize - pszStartOfSize + 1)));
  647. hr = S_OK;
  648. }
  649. }
  650. }
  651. return hr;
  652. }
  653. HRESULT InstallVS(LPCWSTR pszCmdLine)
  654. {
  655. TCHAR szVisualStylePath[MAX_PATH];
  656. TCHAR szVisualStyleColor[MAX_PATH];
  657. TCHAR szVisualStyleSize[MAX_PATH];
  658. HRESULT hr = VSParseCmdLine(pszCmdLine, szVisualStylePath, ARRAYSIZE(szVisualStylePath), szVisualStyleColor, ARRAYSIZE(szVisualStyleColor), szVisualStyleSize, ARRAYSIZE(szVisualStyleSize));
  659. if (SUCCEEDED(hr))
  660. {
  661. IThemeManager * pThemeManager;
  662. hr = CThemeManager_CreateInstance(NULL, IID_PPV_ARG(IThemeManager, &pThemeManager));
  663. if (SUCCEEDED(hr))
  664. {
  665. // Otherwise, we install the visual style.
  666. LogStatus("InstallVS() VS=%ls, Color=%ls, Size=%ls.\r\n", szVisualStylePath, szVisualStyleColor, szVisualStyleSize);
  667. hr = InstallVisualStyle(pThemeManager, szVisualStylePath, szVisualStyleColor, szVisualStyleSize);
  668. if (SUCCEEDED(hr))
  669. {
  670. // This ApplyNow() call will take a little while in normal situation (~10-20 seconds) in order
  671. // to broadcast the message to all open apps. If a top level window is hung, it may take the
  672. // full 30 seconds to timeout.
  673. hr = pThemeManager->ApplyNow();
  674. }
  675. IUnknown_SetSite(pThemeManager, NULL); // Tell him to break the ref-count cycle with his children.
  676. pThemeManager->Release();
  677. }
  678. }
  679. return hr;
  680. }
  681. void HandleBeta2Upgrade(void)
  682. {
  683. TCHAR szPath[MAX_PATH];
  684. TCHAR szTemp[MAX_PATH];
  685. SHExpandEnvironmentStringsW(L"%SystemRoot%\\web\\wallpaper\\", szPath, ARRAYSIZE(szPath));
  686. LoadString(HINST_THISDLL, IDS_SETUP_BETA2_UPGRADEWALLPAPER, szTemp, ARRAYSIZE(szTemp));
  687. PathAppend(szPath, szTemp);
  688. if (PathFileExists(szPath))
  689. {
  690. // We no longer use "Red Moon Desert.bmp", now the default is "Bliss.bmp".
  691. DeleteFile(szPath);
  692. }
  693. }
  694. /*****************************************************************************\
  695. DESCRIPTION:
  696. This function will be called in the following situations:
  697. 1. GUI Mode Setup: In this case the cmdline is "regsvr32.exe /i themeui.dll".
  698. In that case, we install the machine settings.
  699. 2. Per User Login: ActiveSetup will call us with "regsvr32.exe /n /i:/UserInstall themeui.dll"
  700. per user and only once.
  701. 3. External Callers to Set Visual Style: External Callers will call us with:
  702. "regsvr32.exe /n /i:"/InstallVS:'<VisualStyle>','<ColorScheme>','<Size>'" themeui.dll"
  703. This will install that visual style. <VisualStyle> can be an empty string
  704. to install "Windows Classic".
  705. BryanSt 4/4/2000 (Bryan Starbuck)
  706. Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
  707. \*****************************************************************************/
  708. STDAPI DllInstall(BOOL fInstall, LPCWSTR pszCmdLine)
  709. {
  710. HRESULT hr = S_OK;
  711. BOOL fUserSetup = (pszCmdLine && StrStrW(pszCmdLine, SZ_USER_INSTALL) ? TRUE : FALSE);
  712. BOOL fInstallVS = (pszCmdLine && StrStrW(pszCmdLine, SZ_INSTALL_VS) ? TRUE : FALSE);
  713. g_fInSetup = TRUE;
  714. if (fUserSetup)
  715. {
  716. if (fInstall)
  717. {
  718. hr = CoInitialize(0);
  719. if (SUCCEEDED(hr))
  720. {
  721. hr = SetupThemeForUser();
  722. CoUninitialize();
  723. }
  724. }
  725. }
  726. else if (fInstallVS)
  727. {
  728. if (fInstall)
  729. {
  730. hr = CoInitialize(0);
  731. if (SUCCEEDED(hr))
  732. {
  733. hr = InstallVS(pszCmdLine);
  734. CoUninitialize();
  735. }
  736. }
  737. }
  738. else
  739. {
  740. if (fInstall)
  741. {
  742. // Ignore errors from theme manager here
  743. SetupThemeForMachine();
  744. HandleBeta2Upgrade();
  745. }
  746. }
  747. g_fInSetup = FALSE;
  748. LogStatus("DllInstall(%hs, \"%ls\") returned hr=%#08lx.\r\n", (fInstall ? "TRUE" : "FALSE"), (pszCmdLine ? pszCmdLine : L""), hr);
  749. return hr;
  750. }