windows-nt/Source/XPSP1/NT/base/ntsetup/opktools/factory/setshell.c
2020-09-26 16:20:57 +08:00

548 lines
19 KiB
C

/****************************************************************************\
SHELL.C / Factory Mode (FACTORY.EXE)
Microsoft Confidential
Copyright (c) Microsoft Corporation 2001
All rights reserved
Source file for Factory that contains the shell settings state functions.
06/2001 - Jason Cohen (JCOHEN)
Added this new source file for factory for setting shell settings in
the Winbom.
\****************************************************************************/
//
// Include File(s):
//
#include "factoryp.h"
#include <shlobj.h>
#include <shlobjp.h>
#include <uxthemep.h>
//
// Internal Define(s):
//
#define REG_KEY_THEMEMGR _T("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager")
#define REG_VAL_THEMEPROP_DLLNAME _T("DllName")
//#define REG_VAL_THEMEPROP_THEMEACTIVE _T("ThemeActive")
#define REG_KEY_LASTTHEME _T("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\LastTheme")
#define REG_VAL_THEMEFILE _T("ThemeFile")
#define INI_SEC_STYLES _T("VisualStyles")
#define INI_KEY_STYLES_PATH _T("Path")
#define INI_KEY_STYLES_COLOR _T("ColorStyle")
#define INI_KEY_STYLES_SIZE _T("Size")
#define REG_KEY_DOCLEANUP _T("Software\\Microsoft\\Windows\\CurrentVersion\\OemStartMenuData")
#define REG_VAL_DOCLEANUP _T("DoDesktopCleanup")
#define REG_KEY_STARTMESSENGER _T("Software\\Policies\\Microsoft\\Messenger\\Client")
#define REG_VAL_STARTMESSENGERAUTO _T("PreventAutoRun")
#define REG_KEY_USEMSNEXPLORER _T("Software\\Microsoft\\MSN6\\Setup\\MSN\\Codes")
#define REG_VAL_USEMSNEXPLORER _T("IAOnly")
//
// External Function(s):
//
BOOL ShellSettings(LPSTATEDATA lpStateData)
{
LPTSTR lpszIniVal = NULL;
BOOL bIniVal = FALSE,
bError = FALSE,
bReturn = TRUE;
// Determine if the DoDesktopCleanup value is in the winbom, if nothing is there don't make any changes.
//
if ( lpszIniVal = IniGetString(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_DOCLEANUP, NULL) )
{
if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_YES) == 0 )
{
// Do desktop cleanup.
//
bIniVal = TRUE;
}
else if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_NO) == 0 )
{
// Delay desktop cleanup.
//
bIniVal = FALSE;
}
else
{
// Error processing value, user did not choose valid value (Yes/No)
//
bError = TRUE;
bReturn = FALSE;
FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_DOCLEANUP, lpszIniVal);
}
// If there was not an error, set the proper value in the registry
//
if ( !bError )
{
RegSetDword(HKLM, REG_KEY_DOCLEANUP, REG_VAL_DOCLEANUP, bIniVal ? 1 : 0);
}
// Free up the used memory
//
FREE(lpszIniVal);
}
// Reset the error value
//
bError = FALSE;
// Determine if the StartMessenger value is in the winbom, if nothing is there, don't make any changes
//
if ( lpszIniVal = IniGetString(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTMESSENGER, NULL) )
{
if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_YES) == 0 )
{
// User not starting messenger
bIniVal = TRUE;
}
else if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_NO) == 0 )
{
// User starting messenger
//
bIniVal = FALSE;
}
else
{
// Error processing value, user did not choose valid value (Yes/No)
//
bError = TRUE;
bReturn = FALSE;
FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTMESSENGER, lpszIniVal);
}
// If there was not an error, set the proper values in the registry
//
if ( !bError )
{
RegSetDword(HKLM, REG_KEY_STARTMESSENGER, REG_VAL_STARTMESSENGERAUTO, bIniVal ? 0 : 1);
}
// Free up the used memory
//
FREE(lpszIniVal);
}
// Reset the error value
//
bError = FALSE;
// Determine if the UseMSNSignup value is in the winbom, if nothing is there, don't make any changes
//
if ( lpszIniVal = IniGetString(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_USEMSNEXPLORER, NULL) )
{
if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_YES) == 0 )
{
// User is using MSNExplorer
//
bIniVal = TRUE;
}
else if ( LSTRCMPI(lpszIniVal, INI_VAL_WBOM_NO) == 0 )
{
// User is not using MSNExplorer
//
bIniVal = FALSE;
}
else
{
// Error processing value, user did not choose valid value (Yes/No)
//
bError = TRUE;
bReturn = FALSE;
FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_USEMSNEXPLORER, lpszIniVal);
}
// If there was not an error, set the proper values in the registry
//
if ( !bError )
{
TCHAR szFilePath1[MAX_PATH] = NULLSTR,
szFilePath2[MAX_PATH] = NULLSTR;
LPTSTR lpMSNExplorer = NULL,
lpMSNOnline = NULL;
// Set the proper string in the registry
//
RegSetString(HKLM, REG_KEY_USEMSNEXPLORER, REG_VAL_USEMSNEXPLORER, bIniVal ? _T("NO") : _T("YES"));
// Attempt to rename the file in the program menu
//
if ( SHGetSpecialFolderPath( NULL, szFilePath1, CSIDL_COMMON_PROGRAMS, FALSE ) &&
lstrcpyn( szFilePath2, szFilePath1, AS ( szFilePath2 ) ) &&
(lpMSNExplorer = AllocateString(NULL, IDS_MSN_EXPLORER)) &&
(lpMSNOnline = AllocateString(NULL, IDS_GET_ONLINE_MSN)) &&
AddPathN(szFilePath1, bIniVal ? lpMSNOnline : lpMSNExplorer, AS(szFilePath1)) &&
AddPathN(szFilePath2, bIniVal ? lpMSNExplorer: lpMSNOnline, AS(szFilePath2))
)
{
if ( !MoveFile(szFilePath1, szFilePath2) )
{
FacLogFileStr(3 | LOG_ERR, _T("DEBUG: MoveFile('%s','%s') - Failed (Error: %d)\n"), szFilePath1, szFilePath2, GetLastError());
bReturn = FALSE;
}
else
{
FacLogFileStr(3, _T("DEBUG: MoveFile('%s','%s') - Succeeded\n"), szFilePath1, szFilePath2);
}
}
// Free up the used memory
//
FREE(lpMSNExplorer);
FREE(lpMSNOnline);
}
// Free up the used memory
//
FREE(lpszIniVal);
}
// This only sets these settings for new users created. ShellSettings2() will
// fix it up so the current factory user will also get the right settings.
//
return ( SetupShellSettings(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL) && bReturn );
}
BOOL ShellSettings2(LPSTATEDATA lpStateData)
{
BOOL bRet = TRUE,
bNewTheme = FALSE,
bWantThemeOn,
bIsThemeOn,
bStartPanel,
bIniSetting;
LPTSTR lpszTheme = NULL,
lpszThemeColor = NULL,
lpszThemeSize = NULL,
lpszIniSetting;
// Now see if they want to turn the theme on or off.
//
bIniSetting = FALSE;
if ( lpszIniSetting = IniGetExpand(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_THEMEOFF, NULL) )
{
// See if it is a value we recognize.
//
if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_YES) == 0 )
{
bWantThemeOn = FALSE;
bIniSetting = TRUE;
}
else if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_NO) == 0 )
{
bWantThemeOn = TRUE;
bIniSetting = TRUE;
}
else
{
FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_THEMEOFF, lpszIniSetting);
bRet = FALSE;
}
FREE(lpszIniSetting);
}
// See if they have a custom theme they want to use.
//
if ( lpszIniSetting = IniGetExpand(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_THEMEFILE, NULL) )
{
// The file has to exist so we can look for the visual style
// of the theme.
//
if ( FileExists(lpszIniSetting) )
{
BOOL bVisualStyle;
// Check for the visual style in the theme file. If missing, we just use the
// classic one.
//
lpszTheme = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_PATH, NULL);
bVisualStyle = ( NULL != lpszTheme );
if ( bVisualStyle )
{
// If they want styles on, get what the settings are for the color and size.
//
lpszThemeColor = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_COLOR, NULL);
lpszThemeSize = IniGetExpand(lpszIniSetting, INI_SEC_STYLES, INI_KEY_STYLES_SIZE, NULL);
}
// We override what they may have specified above for "want themes on" based
// on if there is a visual style in this them or not. May also need to warn
// them if there default themes off key conflicts with the theme specified.
//
if ( ( bIniSetting ) &&
( bVisualStyle != bWantThemeOn ) )
{
// May not want to actually return failure here, but really one of the settings they
// put in the winbom is not going to be used because the other one is overriding
// it.
//
FacLogFile(0, bVisualStyle ? IDS_ERR_THEME_CONFLICT_ON : IDS_ERR_THEME_CONFLICT_OFF, lpszIniSetting);
}
bWantThemeOn = bVisualStyle;
// If the file exists, means we want to change the visual style even
// if the theme doesn't contain one. Also set the ini setting flag so
// we know we have a vallid setting to change.
//
bNewTheme = TRUE;
bIniSetting = TRUE;
}
else
{
// File is not there, so log error and ignore this key.
//
FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_MISSING, lpszIniSetting);
bRet = FALSE;
}
FREE(lpszIniSetting);
}
// Only need to do anything if there is a new theme to use
// or they wanted to change the default theme to on/off.
//
if ( bIniSetting )
{
HRESULT hr;
// We need COM to do the theme stuff.
//
hr = CoInitialize(NULL);
if ( SUCCEEDED(hr) )
{
TCHAR szPath[MAX_PATH] = NULLSTR;
// Check to see if the themes are turned on or not.
//
hr = GetCurrentThemeName(szPath, AS(szPath), NULL, 0, NULL, 0);
bIsThemeOn = ( SUCCEEDED(hr) && szPath[0] );
// Now find out if we really need to do anything. Only if they have
// an new theme to use or they want to switch themes on/off.
//
if ( ( bNewTheme && bWantThemeOn ) ||
( bWantThemeOn != bIsThemeOn ) )
{
// See if we need to turn the themes on, or set a new
// theme.
//
if ( bWantThemeOn )
{
HTHEMEFILE hThemeFile;
// If they didn't specify a new theme, we need to get the default
// visual style from the registry.
//
if ( NULL == lpszTheme )
{
lpszTheme = RegGetExpand(HKLM, REG_KEY_THEMEMGR, REG_VAL_THEMEPROP_DLLNAME);
}
// We should have some theme to apply at this point.
//
if ( lpszTheme && *lpszTheme )
{
// Try to open the theme file (using the non-expanded path).
//
hr = OpenThemeFile(lpszTheme, lpszThemeColor, lpszThemeSize, &hThemeFile, TRUE);
if ( SUCCEEDED(hr) )
{
// Now try to apply the theme.
//
hr = ApplyTheme(hThemeFile, AT_LOAD_SYSMETRICS, NULL);
if ( SUCCEEDED(hr) )
{
// Woo hoo, successfully applied the theme.
//
FacLogFile(1, IDS_LOG_THEME_CHANGED, lpszTheme);
bIsThemeOn = TRUE;
// This is a cheap hack so that if you go into
// control panel it shows "Modified Theme" instead of
// whatever one you last had selected. We do this
// rather than set the name because we are only appling
// the visual effects, not other stuff in the theme
// like wallpaper.
//
RegDelete(HKCU, REG_KEY_LASTTHEME, REG_VAL_THEMEFILE);
}
else
{
// Do'h, apply failed for some reason.
//
FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_APPLY, lpszTheme, hr);
bRet = FALSE;
}
// Can close the theme file now.
//
CloseThemeFile(hThemeFile);
}
else
{
// Must be an invalid style file.
//
FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_OPEN, lpszTheme, hr);
bRet = FALSE;
}
}
else
{
// Strange, no default theme file to use to enable
// the new themes.
//
FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_NODEFAULT);
bRet = FALSE;
}
}
else
{
// Disable the new theme styles and use the clasic windows
// styles since they have one current selected.
//
hr = ApplyTheme(NULL, 0, NULL);
if ( SUCCEEDED(hr) )
{
// Woo hoo, we disabled the new themes.
//
FacLogFile(1, IDS_LOG_THEME_DISABLED);
bIsThemeOn = FALSE;
// This is a cheap hack so that if you go into
// control panel it shows "Modified Theme" instead of
// whatever one you last had selected. We do this
// rather than set the name because we are only appling
// the visual effects, not other stuff in the theme
// like wallpaper.
//
RegDelete(HKCU, REG_KEY_LASTTHEME, REG_VAL_THEMEFILE);
}
else
{
// Do'h, couldn't remove the current theme for some reason.
//
FacLogFile(0 | LOG_ERR, IDS_ERR_THEME_DISABLE, hr);
bRet = FALSE;
}
}
}
else
{
// Theme already disabled or enabled, just log a high level warning
// since the key they are setting is really doing nothing.
//
FacLogFile(2, bIsThemeOn ? IDS_LOG_THEME_ALREADYENABLED : IDS_LOG_THEME_ALREADYDISABLED);
}
// Free up COM since we don't need it any more.
//
CoUninitialize();
}
else
{
// COM error, this is bad.
//
FacLogFile(0 | LOG_ERR, IDS_ERR_COMINIT, hr);
bRet = FALSE;
}
// Free these guys (macro checks for NULL).
//
FREE(lpszTheme);
FREE(lpszThemeColor);
FREE(lpszThemeSize);
}
// Get the new start panel setting from the winbom.
//
bIniSetting = FALSE;
if ( lpszIniSetting = IniGetExpand(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTPANELOFF, NULL) )
{
// See if it is a value we recognize.
//
if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_YES) == 0 )
{
bStartPanel = FALSE;
bIniSetting = TRUE;
}
else if ( LSTRCMPI(lpszIniSetting, INI_VAL_WBOM_NO) == 0 )
{
bStartPanel = TRUE;
bIniSetting = TRUE;
}
else
{
FacLogFile(0 | LOG_ERR, IDS_ERR_WINBOMVALUE, lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, INI_KEY_WBOM_SHELL_STARTPANELOFF, lpszIniSetting);
bRet = FALSE;
}
FREE(lpszIniSetting);
}
// See if they had a recognized value for the start panel key.
//
if ( bIniSetting )
{
SHELLSTATE ss = {0};
// Get the current start panel setting.
//
SHGetSetSettings(&ss, SSF_STARTPANELON, FALSE);
// I think that fStartPanelOn is set to -1, not TRUE
// if enabled, so we have to do this rather than a !=.
// It would be nice to have an exclusive or here.
//
if ( ( bStartPanel && !ss.fStartPanelOn ) ||
( !bStartPanel && ss.fStartPanelOn ) )
{
// This will disable or enable the new start panel depending
// on what was in the winbom.
//
FacLogFile(1, bStartPanel ? IDS_LOG_STARTPANEL_ENABLE : IDS_LOG_STARTPANEL_DISABLE);
ss.fStartPanelOn = bStartPanel;
SHGetSetSettings(&ss, SSF_STARTPANELON, TRUE);
}
else
{
// Start panel already disabled or enabled, just log a high level warning
// since the key they are setting is really doing nothing.
//
FacLogFile(2, bStartPanel ? IDS_LOG_STARTPANEL_ALREADYENABLED : IDS_LOG_STARTPANEL_ALREADYDISABLED);
}
}
return bRet;
}
BOOL DisplayShellSettings(LPSTATEDATA lpStateData)
{
return IniSettingExists(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_SHELL, NULL, NULL);
}