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.

547 lines
19 KiB

  1. /****************************************************************************\
  2. SHELL.C / Factory Mode (FACTORY.EXE)
  3. Microsoft Confidential
  4. Copyright (c) Microsoft Corporation 2001
  5. All rights reserved
  6. Source file for Factory that contains the shell settings state functions.
  7. 06/2001 - Jason Cohen (JCOHEN)
  8. Added this new source file for factory for setting shell settings in
  9. the Winbom.
  10. \****************************************************************************/
  11. //
  12. // Include File(s):
  13. //
  14. #include "factoryp.h"
  15. #include <shlobj.h>
  16. #include <shlobjp.h>
  17. #include <uxthemep.h>
  18. //
  19. // Internal Define(s):
  20. //
  21. #define REG_KEY_THEMEMGR _T("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager")
  22. #define REG_VAL_THEMEPROP_DLLNAME _T("DllName")
  23. //#define REG_VAL_THEMEPROP_THEMEACTIVE _T("ThemeActive")
  24. #define REG_KEY_LASTTHEME _T("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\LastTheme")
  25. #define REG_VAL_THEMEFILE _T("ThemeFile")
  26. #define INI_SEC_STYLES _T("VisualStyles")
  27. #define INI_KEY_STYLES_PATH _T("Path")
  28. #define INI_KEY_STYLES_COLOR _T("ColorStyle")
  29. #define INI_KEY_STYLES_SIZE _T("Size")
  30. #define REG_KEY_DOCLEANUP _T("Software\\Microsoft\\Windows\\CurrentVersion\\OemStartMenuData")
  31. #define REG_VAL_DOCLEANUP _T("DoDesktopCleanup")
  32. #define REG_KEY_STARTMESSENGER _T("Software\\Policies\\Microsoft\\Messenger\\Client")
  33. #define REG_VAL_STARTMESSENGERAUTO _T("PreventAutoRun")
  34. #define REG_KEY_USEMSNEXPLORER _T("Software\\Microsoft\\MSN6\\Setup\\MSN\\Codes")
  35. #define REG_VAL_USEMSNEXPLORER _T("IAOnly")
  36. //
  37. // External Function(s):
  38. //
  39. BOOL ShellSettings(LPSTATEDATA lpStateData)
  40. {
  41. LPTSTR lpszIniVal = NULL;
  42. BOOL bIniVal = FALSE,
  43. bError = FALSE,
  44. bReturn = TRUE;
  45. // Determine if the DoDesktopCleanup value is in the winbom, if nothing is there don't make any changes.
  46. //
  47. if ( lpszIniVal = IniGetString(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_DOCLEANUP, NULL) )
  48. {
  49. if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_YES) == 0 )
  50. {
  51. // Do desktop cleanup.
  52. //
  53. bIniVal = TRUE;
  54. }
  55. else if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_NO) == 0 )
  56. {
  57. // Delay desktop cleanup.
  58. //
  59. bIniVal = FALSE;
  60. }
  61. else
  62. {
  63. // Error processing value, user did not choose valid value (Yes/No)
  64. //
  65. bError = TRUE;
  66. bReturn = FALSE;
  67. FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_DOCLEANUP, lpszIniVal);
  68. }
  69. // If there was not an error, set the proper value in the registry
  70. //
  71. if ( !bError )
  72. {
  73. RegSetDword(HKLM, REG_KEY_DOCLEANUP, REG_VAL_DOCLEANUP, bIniVal ? 1 : 0);
  74. }
  75. // Free up the used memory
  76. //
  77. FREE(lpszIniVal);
  78. }
  79. // Reset the error value
  80. //
  81. bError = FALSE;
  82. // Determine if the StartMessenger value is in the winbom, if nothing is there, don't make any changes
  83. //
  84. if ( lpszIniVal = IniGetString(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTMESSENGER, NULL) )
  85. {
  86. if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_YES) == 0 )
  87. {
  88. // User not starting messenger
  89. bIniVal = TRUE;
  90. }
  91. else if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_NO) == 0 )
  92. {
  93. // User starting messenger
  94. //
  95. bIniVal = FALSE;
  96. }
  97. else
  98. {
  99. // Error processing value, user did not choose valid value (Yes/No)
  100. //
  101. bError = TRUE;
  102. bReturn = FALSE;
  103. FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTMESSENGER, lpszIniVal);
  104. }
  105. // If there was not an error, set the proper values in the registry
  106. //
  107. if ( !bError )
  108. {
  109. RegSetDword(HKLM, REG_KEY_STARTMESSENGER, REG_VAL_STARTMESSENGERAUTO, bIniVal ? 0 : 1);
  110. }
  111. // Free up the used memory
  112. //
  113. FREE(lpszIniVal);
  114. }
  115. // Reset the error value
  116. //
  117. bError = FALSE;
  118. // Determine if the UseMSNSignup value is in the winbom, if nothing is there, don't make any changes
  119. //
  120. if ( lpszIniVal = IniGetString(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_USEMSNEXPLORER, NULL) )
  121. {
  122. if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_YES) == 0 )
  123. {
  124. // User is using MSNExplorer
  125. //
  126. bIniVal = TRUE;
  127. }
  128. else if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_NO) == 0 )
  129. {
  130. // User is not using MSNExplorer
  131. //
  132. bIniVal = FALSE;
  133. }
  134. else
  135. {
  136. // Error processing value, user did not choose valid value (Yes/No)
  137. //
  138. bError = TRUE;
  139. bReturn = FALSE;
  140. FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_USEMSNEXPLORER, lpszIniVal);
  141. }
  142. // If there was not an error, set the proper values in the registry
  143. //
  144. if ( !bError )
  145. {
  146. TCHAR szFilePath1[MAX_PATH] = NULLSTR,
  147. szFilePath2[MAX_PATH] = NULLSTR;
  148. LPTSTR lpMSNExplorer = NULL,
  149. lpMSNOnline = NULL;
  150. // Set the proper string in the registry
  151. //
  152. RegSetString(HKLM, REG_KEY_USEMSNEXPLORER, REG_VAL_USEMSNEXPLORER, bIniVal ? _T("NO") : _T("YES"));
  153. // Attempt to rename the file in the program menu
  154. //
  155. if ( SHGetSpecialFolderPath( NULL, szFilePath1, CSIDL_COMMON_PROGRAMS, FALSE ) &&
  156. lstrcpyn( szFilePath2, szFilePath1, AS ( szFilePath2 ) ) &&
  157. (lpMSNExplorer = AllocateString(NULL, IDS_MSN_EXPLORER)) &&
  158. (lpMSNOnline = AllocateString(NULL, IDS_GET_ONLINE_MSN)) &&
  159. AddPathN(szFilePath1, bIniVal ? lpMSNOnline : lpMSNExplorer, AS(szFilePath1)) &&
  160. AddPathN(szFilePath2, bIniVal ? lpMSNExplorer: lpMSNOnline, AS(szFilePath2))
  161. )
  162. {
  163. if ( !MoveFile(szFilePath1, szFilePath2) )
  164. {
  165. FacLogFileStr(3 | LOG_ERR, _T("DEBUG: MoveFile('%s','%s') - Failed (Error: %d)\n"), szFilePath1, szFilePath2, GetLastError());
  166. bReturn = FALSE;
  167. }
  168. else
  169. {
  170. FacLogFileStr(3, _T("DEBUG: MoveFile('%s','%s') - Succeeded\n"), szFilePath1, szFilePath2);
  171. }
  172. }
  173. // Free up the used memory
  174. //
  175. FREE(lpMSNExplorer);
  176. FREE(lpMSNOnline);
  177. }
  178. // Free up the used memory
  179. //
  180. FREE(lpszIniVal);
  181. }
  182. // This only sets these settings for new users created. ShellSettings2() will
  183. // fix it up so the current factory user will also get the right settings.
  184. //
  185. return ( SetupShellSettings(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL) && bReturn );
  186. }
  187. BOOL ShellSettings2(LPSTATEDATA lpStateData)
  188. {
  189. BOOL bRet = TRUE,
  190. bNewTheme = FALSE,
  191. bWantThemeOn,
  192. bIsThemeOn,
  193. bStartPanel,
  194. bIniSetting;
  195. LPTSTR lpszTheme = NULL,
  196. lpszThemeColor = NULL,
  197. lpszThemeSize = NULL,
  198. lpszIniSetting;
  199. // Now see if they want to turn the theme on or off.
  200. //
  201. bIniSetting = FALSE;
  202. if ( lpszIniSetting = IniGetExpand(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_THEMEOFF, NULL) )
  203. {
  204. // See if it is a value we recognize.
  205. //
  206. if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_YES) == 0 )
  207. {
  208. bWantThemeOn = FALSE;
  209. bIniSetting = TRUE;
  210. }
  211. else if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_NO) == 0 )
  212. {
  213. bWantThemeOn = TRUE;
  214. bIniSetting = TRUE;
  215. }
  216. else
  217. {
  218. FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_THEMEOFF, lpszIniSetting);
  219. bRet = FALSE;
  220. }
  221. FREE(lpszIniSetting);
  222. }
  223. // See if they have a custom theme they want to use.
  224. //
  225. if ( lpszIniSetting = IniGetExpand(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_THEMEFILE, NULL) )
  226. {
  227. // The file has to exist so we can look for the visual style
  228. // of the theme.
  229. //
  230. if ( FileExists(lpszIniSetting) )
  231. {
  232. BOOL bVisualStyle;
  233. // Check for the visual style in the theme file. If missing, we just use the
  234. // classic one.
  235. //
  236. lpszTheme = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_PATH, NULL);
  237. bVisualStyle = ( NULL != lpszTheme );
  238. if ( bVisualStyle )
  239. {
  240. // If they want styles on, get what the settings are for the color and size.
  241. //
  242. lpszThemeColor = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_COLOR, NULL);
  243. lpszThemeSize = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_SIZE, NULL);
  244. }
  245. // We override what they may have specified above for "want themes on" based
  246. // on if there is a visual style in this them or not. May also need to warn
  247. // them if there default themes off key conflicts with the theme specified.
  248. //
  249. if ( ( bIniSetting ) &&
  250. ( bVisualStyle != bWantThemeOn ) )
  251. {
  252. // May not want to actually return failure here, but really one of the settings they
  253. // put in the winbom is not going to be used because the other one is overriding
  254. // it.
  255. //
  256. FacLogFile(0, bVisualStyle ? IDS_ERR_THEME_CONFLICT_ON : IDS_ERR_THEME_CONFLICT_OFF, lpszIniSetting);
  257. }
  258. bWantThemeOn = bVisualStyle;
  259. // If the file exists, means we want to change the visual style even
  260. // if the theme doesn't contain one. Also set the ini setting flag so
  261. // we know we have a vallid setting to change.
  262. //
  263. bNewTheme = TRUE;
  264. bIniSetting = TRUE;
  265. }
  266. else
  267. {
  268. // File is not there, so log error and ignore this key.
  269. //
  270. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_MISSING, lpszIniSetting);
  271. bRet = FALSE;
  272. }
  273. FREE(lpszIniSetting);
  274. }
  275. // Only need to do anything if there is a new theme to use
  276. // or they wanted to change the default theme to on/off.
  277. //
  278. if ( bIniSetting )
  279. {
  280. HRESULT hr;
  281. // We need COM to do the theme stuff.
  282. //
  283. hr = CoInitialize(NULL);
  284. if ( SUCCEEDED(hr) )
  285. {
  286. TCHAR szPath[MAX_PATH] = NULLSTR;
  287. // Check to see if the themes are turned on or not.
  288. //
  289. hr = GetCurrentThemeName(szPath, AS(szPath), NULL, 0, NULL, 0);
  290. bIsThemeOn = ( SUCCEEDED(hr) && szPath[0] );
  291. // Now find out if we really need to do anything. Only if they have
  292. // an new theme to use or they want to switch themes on/off.
  293. //
  294. if ( ( bNewTheme && bWantThemeOn ) ||
  295. ( bWantThemeOn != bIsThemeOn ) )
  296. {
  297. // See if we need to turn the themes on, or set a new
  298. // theme.
  299. //
  300. if ( bWantThemeOn )
  301. {
  302. HTHEMEFILE hThemeFile;
  303. // If they didn't specify a new theme, we need to get the default
  304. // visual style from the registry.
  305. //
  306. if ( NULL == lpszTheme )
  307. {
  308. lpszTheme = RegGetExpand(HKLM, REG_KEY_THEMEMGR, REG_VAL_THEMEPROP_DLLNAME);
  309. }
  310. // We should have some theme to apply at this point.
  311. //
  312. if ( lpszTheme && *lpszTheme )
  313. {
  314. // Try to open the theme file (using the non-expanded path).
  315. //
  316. hr = OpenThemeFile(lpszTheme, lpszThemeColor, lpszThemeSize, &hThemeFile, TRUE);
  317. if ( SUCCEEDED(hr) )
  318. {
  319. // Now try to apply the theme.
  320. //
  321. hr = ApplyTheme(hThemeFile, AT_LOAD_SYSMETRICS, NULL);
  322. if ( SUCCEEDED(hr) )
  323. {
  324. // Woo hoo, successfully applied the theme.
  325. //
  326. FacLogFile(1, IDS_LOG_THEME_CHANGED, lpszTheme);
  327. bIsThemeOn = TRUE;
  328. // This is a cheap hack so that if you go into
  329. // control panel it shows "Modified Theme" instead of
  330. // whatever one you last had selected. We do this
  331. // rather than set the name because we are only appling
  332. // the visual effects, not other stuff in the theme
  333. // like wallpaper.
  334. //
  335. RegDelete(HKCU, REG_KEY_LASTTHEME, REG_VAL_THEMEFILE);
  336. }
  337. else
  338. {
  339. // Do'h, apply failed for some reason.
  340. //
  341. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_APPLY, lpszTheme, hr);
  342. bRet = FALSE;
  343. }
  344. // Can close the theme file now.
  345. //
  346. CloseThemeFile(hThemeFile);
  347. }
  348. else
  349. {
  350. // Must be an invalid style file.
  351. //
  352. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_OPEN, lpszTheme, hr);
  353. bRet = FALSE;
  354. }
  355. }
  356. else
  357. {
  358. // Strange, no default theme file to use to enable
  359. // the new themes.
  360. //
  361. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_NODEFAULT);
  362. bRet = FALSE;
  363. }
  364. }
  365. else
  366. {
  367. // Disable the new theme styles and use the clasic windows
  368. // styles since they have one current selected.
  369. //
  370. hr = ApplyTheme(NULL, 0, NULL);
  371. if ( SUCCEEDED(hr) )
  372. {
  373. // Woo hoo, we disabled the new themes.
  374. //
  375. FacLogFile(1, IDS_LOG_THEME_DISABLED);
  376. bIsThemeOn = FALSE;
  377. // This is a cheap hack so that if you go into
  378. // control panel it shows "Modified Theme" instead of
  379. // whatever one you last had selected. We do this
  380. // rather than set the name because we are only appling
  381. // the visual effects, not other stuff in the theme
  382. // like wallpaper.
  383. //
  384. RegDelete(HKCU, REG_KEY_LASTTHEME, REG_VAL_THEMEFILE);
  385. }
  386. else
  387. {
  388. // Do'h, couldn't remove the current theme for some reason.
  389. //
  390. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_DISABLE, hr);
  391. bRet = FALSE;
  392. }
  393. }
  394. }
  395. else
  396. {
  397. // Theme already disabled or enabled, just log a high level warning
  398. // since the key they are setting is really doing nothing.
  399. //
  400. FacLogFile(2, bIsThemeOn ? IDS_LOG_THEME_ALREADYENABLED : IDS_LOG_THEME_ALREADYDISABLED);
  401. }
  402. // Free up COM since we don't need it any more.
  403. //
  404. CoUninitialize();
  405. }
  406. else
  407. {
  408. // COM error, this is bad.
  409. //
  410. FacLogFile(0 | LOG_ERR, IDS_ERR_COMINIT, hr);
  411. bRet = FALSE;
  412. }
  413. // Free these guys (macro checks for NULL).
  414. //
  415. FREE(lpszTheme);
  416. FREE(lpszThemeColor);
  417. FREE(lpszThemeSize);
  418. }
  419. // Get the new start panel setting from the winbom.
  420. //
  421. bIniSetting = FALSE;
  422. if ( lpszIniSetting = IniGetExpand(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTPANELOFF, NULL) )
  423. {
  424. // See if it is a value we recognize.
  425. //
  426. if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_YES) == 0 )
  427. {
  428. bStartPanel = FALSE;
  429. bIniSetting = TRUE;
  430. }
  431. else if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_NO) == 0 )
  432. {
  433. bStartPanel = TRUE;
  434. bIniSetting = TRUE;
  435. }
  436. else
  437. {
  438. FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTPANELOFF, lpszIniSetting);
  439. bRet = FALSE;
  440. }
  441. FREE(lpszIniSetting);
  442. }
  443. // See if they had a recognized value for the start panel key.
  444. //
  445. if ( bIniSetting )
  446. {
  447. SHELLSTATE ss = {0};
  448. // Get the current start panel setting.
  449. //
  450. SHGetSetSettings(&ss, SSF_STARTPANELON, FALSE);
  451. // I think that fStartPanelOn is set to -1, not TRUE
  452. // if enabled, so we have to do this rather than a !=.
  453. // It would be nice to have an exclusive or here.
  454. //
  455. if ( ( bStartPanel && !ss.fStartPanelOn ) ||
  456. ( !bStartPanel && ss.fStartPanelOn ) )
  457. {
  458. // This will disable or enable the new start panel depending
  459. // on what was in the winbom.
  460. //
  461. FacLogFile(1, bStartPanel ? IDS_LOG_STARTPANEL_ENABLE : IDS_LOG_STARTPANEL_DISABLE);
  462. ss.fStartPanelOn = bStartPanel;
  463. SHGetSetSettings(&ss, SSF_STARTPANELON, TRUE);
  464. }
  465. else
  466. {
  467. // Start panel already disabled or enabled, just log a high level warning
  468. // since the key they are setting is really doing nothing.
  469. //
  470. FacLogFile(2, bStartPanel ? IDS_LOG_STARTPANEL_ALREADYENABLED : IDS_LOG_STARTPANEL_ALREADYDISABLED);
  471. }
  472. }
  473. return bRet;
  474. }
  475. BOOL DisplayShellSettings(LPSTATEDATA lpStateData)
  476. {
  477. return IniSettingExists(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, NULL, NULL);
  478. }