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.

527 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 lpszVisualStyle = NULL,
  196. lpszVisualStyleColor = NULL,
  197. lpszVisualStyleSize = 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. lpszVisualStyle = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_PATH, NULL);
  237. bVisualStyle = ( NULL != lpszVisualStyle );
  238. if ( bVisualStyle )
  239. {
  240. // If they want styles on, get what the settings are for the color and size.
  241. //
  242. lpszVisualStyleColor = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_COLOR, NULL);
  243. lpszVisualStyleSize = 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. // If they didn't specify a new theme, we need to get the default
  303. // visual style from the registry.
  304. //
  305. if ( NULL == lpszVisualStyle )
  306. {
  307. lpszVisualStyle = RegGetExpand(HKLM, REG_KEY_THEMEMGR, REG_VAL_THEMEPROP_DLLNAME);
  308. }
  309. // We should have some theme to apply at this point.
  310. //
  311. if ( lpszVisualStyle && *lpszVisualStyle )
  312. {
  313. // apply the theme.
  314. hr = SetSystemVisualStyle(lpszVisualStyle, lpszVisualStyleColor, lpszVisualStyleSize, AT_LOAD_SYSMETRICS);
  315. if ( SUCCEEDED(hr) )
  316. {
  317. // Woo hoo, successfully applied the theme.
  318. //
  319. FacLogFile(1, IDS_LOG_THEME_CHANGED, lpszVisualStyle);
  320. bIsThemeOn = TRUE;
  321. // This is a cheap hack so that if you go into
  322. // control panel it shows "Modified Theme" instead of
  323. // whatever one you last had selected. We do this
  324. // rather than set the name because we are only appling
  325. // the visual effects, not other stuff in the theme
  326. // like wallpaper.
  327. //
  328. RegDelete(HKCU, REG_KEY_LASTTHEME, REG_VAL_THEMEFILE);
  329. }
  330. else
  331. {
  332. // Do'h, apply failed for some reason.
  333. //
  334. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_APPLY, lpszVisualStyle, hr);
  335. bRet = FALSE;
  336. }
  337. }
  338. else
  339. {
  340. // Strange, no default theme file to use to enable
  341. // the new themes.
  342. //
  343. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_NODEFAULT);
  344. bRet = FALSE;
  345. }
  346. }
  347. else
  348. {
  349. // Disable the new theme styles and use the clasic windows
  350. // styles since they have one current selected.
  351. //
  352. hr = ApplyTheme(NULL, 0, NULL);
  353. if ( SUCCEEDED(hr) )
  354. {
  355. // Woo hoo, we disabled the new themes.
  356. //
  357. FacLogFile(1, IDS_LOG_THEME_DISABLED);
  358. bIsThemeOn = FALSE;
  359. // This is a cheap hack so that if you go into
  360. // control panel it shows "Modified Theme" instead of
  361. // whatever one you last had selected. We do this
  362. // rather than set the name because we are only appling
  363. // the visual effects, not other stuff in the theme
  364. // like wallpaper.
  365. //
  366. RegDelete(HKCU, REG_KEY_LASTTHEME, REG_VAL_THEMEFILE);
  367. }
  368. else
  369. {
  370. // Do'h, couldn't remove the current theme for some reason.
  371. //
  372. FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_DISABLE, hr);
  373. bRet = FALSE;
  374. }
  375. }
  376. }
  377. else
  378. {
  379. // Theme already disabled or enabled, just log a high level warning
  380. // since the key they are setting is really doing nothing.
  381. //
  382. FacLogFile(2, bIsThemeOn ? IDS_LOG_THEME_ALREADYENABLED : IDS_LOG_THEME_ALREADYDISABLED);
  383. }
  384. // Free up COM since we don't need it any more.
  385. //
  386. CoUninitialize();
  387. }
  388. else
  389. {
  390. // COM error, this is bad.
  391. //
  392. FacLogFile(0 | LOG_ERR, IDS_ERR_COMINIT, hr);
  393. bRet = FALSE;
  394. }
  395. // Free these guys (macro checks for NULL).
  396. //
  397. FREE(lpszVisualStyle);
  398. FREE(lpszVisualStyleColor);
  399. FREE(lpszVisualStyleSize);
  400. }
  401. // Get the new start panel setting from the winbom.
  402. //
  403. bIniSetting = FALSE;
  404. if ( lpszIniSetting = IniGetExpand(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTPANELOFF, NULL) )
  405. {
  406. // See if it is a value we recognize.
  407. //
  408. if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_YES) == 0 )
  409. {
  410. bStartPanel = FALSE;
  411. bIniSetting = TRUE;
  412. }
  413. else if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_NO) == 0 )
  414. {
  415. bStartPanel = TRUE;
  416. bIniSetting = TRUE;
  417. }
  418. else
  419. {
  420. FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTPANELOFF, lpszIniSetting);
  421. bRet = FALSE;
  422. }
  423. FREE(lpszIniSetting);
  424. }
  425. // See if they had a recognized value for the start panel key.
  426. //
  427. if ( bIniSetting )
  428. {
  429. SHELLSTATE ss = {0};
  430. // Get the current start panel setting.
  431. //
  432. SHGetSetSettings(&ss, SSF_STARTPANELON, FALSE);
  433. // I think that fStartPanelOn is set to -1, not TRUE
  434. // if enabled, so we have to do this rather than a !=.
  435. // It would be nice to have an exclusive or here.
  436. //
  437. if ( ( bStartPanel && !ss.fStartPanelOn ) ||
  438. ( !bStartPanel && ss.fStartPanelOn ) )
  439. {
  440. // This will disable or enable the new start panel depending
  441. // on what was in the winbom.
  442. //
  443. FacLogFile(1, bStartPanel ? IDS_LOG_STARTPANEL_ENABLE : IDS_LOG_STARTPANEL_DISABLE);
  444. ss.fStartPanelOn = bStartPanel;
  445. SHGetSetSettings(&ss, SSF_STARTPANELON, TRUE);
  446. }
  447. else
  448. {
  449. // Start panel already disabled or enabled, just log a high level warning
  450. // since the key they are setting is really doing nothing.
  451. //
  452. FacLogFile(2, bStartPanel ? IDS_LOG_STARTPANEL_ALREADYENABLED : IDS_LOG_STARTPANEL_ALREADYDISABLED);
  453. }
  454. }
  455. return bRet;
  456. }
  457. BOOL DisplayShellSettings(LPSTATEDATA lpStateData)
  458. {
  459. return IniSettingExists(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, NULL, NULL);
  460. }