windows-nt/Source/XPSP1/NT/shell/cpls/inetcpl/util.cpp
2020-09-26 16:20:57 +08:00

387 lines
12 KiB
C++

//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1994 **
//*********************************************************************
//
// UTIL.C - common utility functions
//
// HISTORY:
//
// 12/21/94 jeremys Created.
//
#include "inetcplp.h"
#include <advpub.h> // For REGINSTALL
#include <mluisupp.h>
#include "brutil.h"
#include <mlang.h>
// function prototypes
VOID _cdecl FormatErrorMessage(TCHAR * pszMsg,DWORD cbMsg,TCHAR * pszFmt,va_list ArgList);
extern VOID GetRNAErrorText(UINT uErr,CHAR * pszErrText,DWORD cbErrText);
extern VOID GetMAPIErrorText(UINT uErr,CHAR * pszErrText,DWORD cbErrText);
/*******************************************************************
NAME: MsgBox
SYNOPSIS: Displays a message box with the specified string ID
********************************************************************/
int MsgBox(HWND hWnd,UINT nMsgID,UINT uIcon,UINT uButtons)
{
TCHAR szMsgBuf[MAX_RES_LEN+1];
TCHAR szSmallBuf[SMALL_BUF_LEN+1];
MLLoadShellLangString(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
MLLoadShellLangString(nMsgID,szMsgBuf,sizeof(szMsgBuf));
MessageBeep(uIcon);
return (MessageBox(hWnd,szMsgBuf,szSmallBuf,uIcon | uButtons));
}
/*******************************************************************
NAME: MsgBoxSz
SYNOPSIS: Displays a message box with the specified text
********************************************************************/
int MsgBoxSz(HWND hWnd,LPTSTR szText,UINT uIcon,UINT uButtons)
{
TCHAR szSmallBuf[SMALL_BUF_LEN+1];
MLLoadShellLangString(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
MessageBeep(uIcon);
return (MessageBox(hWnd,szText,szSmallBuf,uIcon | uButtons));
}
/*******************************************************************
NAME: MsgBoxParam
SYNOPSIS: Displays a message box with the specified string ID
NOTES: extra parameters are string pointers inserted into nMsgID.
********************************************************************/
int _cdecl MsgBoxParam(HWND hWnd,UINT nMsgID,UINT uIcon,UINT uButtons,...)
{
va_list nextArg;
BUFFER Msg(3*MAX_RES_LEN+1); // nice n' big for room for inserts
BUFFER MsgFmt(MAX_RES_LEN+1);
if (!Msg || !MsgFmt) {
return MsgBox(hWnd,IDS_ERROutOfMemory,MB_ICONSTOP,MB_OK);
}
MLLoadShellLangString(nMsgID,MsgFmt.QueryPtr(),MsgFmt.QuerySize());
va_start(nextArg, uButtons);
FormatErrorMessage(Msg.QueryPtr(),Msg.QuerySize(),
MsgFmt.QueryPtr(),nextArg);
va_end(nextArg);
return MsgBoxSz(hWnd,Msg.QueryPtr(),uIcon,uButtons);
}
BOOL EnableDlgItem(HWND hDlg,UINT uID,BOOL fEnable)
{
return EnableWindow(GetDlgItem(hDlg,uID),fEnable);
}
/*******************************************************************
NAME: LoadSz
SYNOPSIS: Loads specified string resource into buffer
EXIT: returns a pointer to the passed-in buffer
NOTES: If this function fails (most likely due to low
memory), the returned buffer will have a leading NULL
so it is generally safe to use this without checking for
failure.
********************************************************************/
LPTSTR LoadSz(UINT idString,LPTSTR lpszBuf,UINT cbBuf)
{
ASSERT(lpszBuf);
// Clear the buffer and load the string
if ( lpszBuf )
{
*lpszBuf = '\0';
MLLoadString( idString, lpszBuf, cbBuf );
}
return lpszBuf;
}
/*******************************************************************
NAME: FormatErrorMessage
SYNOPSIS: Builds an error message by calling FormatMessage
NOTES: Worker function for DisplayErrorMessage
********************************************************************/
VOID _cdecl FormatErrorMessage(TCHAR * pszMsg,DWORD cbMsg,TCHAR * pszFmt,va_list ArgList)
{
ASSERT(pszMsg);
ASSERT(pszFmt);
// build the message into the pszMsg buffer
DWORD dwCount = FormatMessage(FORMAT_MESSAGE_FROM_STRING,
pszFmt,0,0,pszMsg,cbMsg,&ArgList);
ASSERT(dwCount > 0);
}
/*----------------------------------------------------------
Purpose: Calls the ADVPACK entry-point which executes an inf
file section.
*/
HRESULT CallRegInstall(LPSTR szSection)
{
HRESULT hr = E_FAIL;
STRENTRY seReg[] = {
#ifdef WINNT
{ "CHANNELBARINIT", "no" }, // channel bar off by default on NT
#else
{ "CHANNELBARINIT", "yes" } // channel bar on by default on Win95/98
#endif
};
STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
RegInstall(ghInstance, szSection, &stReg);
return hr;
}
//
// Code page to Script mapping table
// Can't load MLang during setup, so, we port this table from MLANG
//
typedef struct tagCPTOSCRIPT{
UINT uiCodePage;
SCRIPT_ID sid;
} CPTOSCRIPT;
const CPTOSCRIPT CpToScript [] =
{
{1252, sidAsciiLatin},
{1250, sidAsciiLatin},
{1254, sidAsciiLatin},
{1257, sidAsciiLatin},
{1258, sidAsciiLatin},
{1251, sidCyrillic },
{1253, sidGreek },
{1255, sidHebrew },
{1256, sidArabic },
{874, sidThai },
{932, sidKana },
{936, sidHan },
{949, sidHangul },
{950, sidBopomofo },
{50000, sidUserDefined},
};
/*******************************************************************
NAME: MigrateIEFontSetting
SYNOPSIS: Port IE4 font setting data to IE5 script settings
NOTES:
********************************************************************/
VOID MigrateIEFontSetting(void)
{
HKEY hKeyInternational;
HKEY hKeyScripts;
// Open IE international setting registry key
if (ERROR_SUCCESS ==
RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_INTERNATIONAL, NULL, KEY_READ, &hKeyInternational))
{
DWORD dwIndex = 0;
DWORD dwCreate = 0;
TCHAR szCodePage[1024] = {0};
// Open/Create scripts key
if (ERROR_SUCCESS == RegCreateKeyEx(hKeyInternational, REGSTR_VAL_FONT_SCRIPTS, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
NULL, &hKeyScripts, &dwCreate))
{
// If scripts already exists, we're upgrading from IE5, no data porting needed
if (dwCreate == REG_CREATED_NEW_KEY)
{
DWORD dwSize = ARRAYSIZE(szCodePage);
TCHAR szFont[LF_FACESIZE];
while (ERROR_SUCCESS == RegEnumKeyEx(hKeyInternational, dwIndex, szCodePage,
&dwSize, NULL, NULL, NULL, NULL))
{
UINT uiCP = StrToInt(szCodePage);
for (int i=0; i<ARRAYSIZE(CpToScript); i++)
{
if (uiCP == CpToScript[i].uiCodePage)
{
HKEY hKeyCodePage;
if ( ERROR_SUCCESS == RegOpenKeyEx(hKeyInternational, szCodePage,
NULL, KEY_READ, &hKeyCodePage))
{
HKEY hKeyScript;
CHAR szScript[1024];
wsprintfA(szScript, "%d", CpToScript[i].sid);
// Port code page font data to script font data
// If CP == 1252, we always need to use it to update Latin CP font info
if ((ERROR_SUCCESS == RegCreateKeyExA(hKeyScripts, szScript, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
NULL, &hKeyScript, &dwCreate)) &&
((dwCreate == REG_CREATED_NEW_KEY) || (uiCP == 1252)))
{
DWORD cb = sizeof(szFont);
if (ERROR_SUCCESS == RegQueryValueEx(hKeyCodePage,
REGSTR_VAL_FIXED_FONT, NULL, NULL,
(LPBYTE)szFont, &cb))
{
RegSetValueEx(hKeyScript, REGSTR_VAL_FIXED_FONT, 0,
REG_SZ, (LPBYTE)szFont, cb);
}
cb = sizeof(szFont);
if (ERROR_SUCCESS == RegQueryValueEx(hKeyCodePage,
REGSTR_VAL_PROP_FONT, NULL, NULL,
(LPBYTE)szFont, &cb))
{
RegSetValueEx(hKeyScript, REGSTR_VAL_PROP_FONT, 0,
REG_SZ, (LPBYTE)szFont, cb);
}
RegCloseKey(hKeyScript);
}
RegCloseKey(hKeyCodePage);
}
}
}
dwIndex++;
dwSize = ARRAYSIZE(szCodePage);
}
}
RegCloseKey(hKeyScripts);
}
RegCloseKey(hKeyInternational);
}
}
/*----------------------------------------------------------
Purpose: Install/uninstall user settings
*/
STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
{
#ifdef DEBUG
if (IsFlagSet(g_dwBreakFlags, BF_ONAPIENTER))
{
TraceMsg(TF_ALWAYS, "Stopping in DllInstall");
DEBUG_BREAK;
}
#endif
if (bInstall)
{
//
// We use to delete the whole key here - that doesn't work anymore
// because other people write to this key and we don't want
// to crush them. If you need to explicity delete a value
// add it to ao_2 value
// CallRegInstall("UnregDll");
CallRegInstall("RegDll");
// If we also have the integrated shell installed, throw in the options
// related to the Integrated Shell.
if (WhichPlatform() == PLATFORM_INTEGRATED)
CallRegInstall("RegDll.IntegratedShell");
// NT5's new shell has special reg key settings
if (GetUIVersion() >= 5)
CallRegInstall("RegDll.NT5");
// Run Whistler-specific settings.
if (IsOS(OS_WHISTLERORGREATER))
{
CallRegInstall("RegDll.Whistler");
}
// Port IE4 code page font setting
MigrateIEFontSetting();
}
else
{
CallRegInstall("UnregDll");
}
return S_OK;
}
#define REGSTR_CCS_CONTROL_WINDOWS REGSTR_PATH_CURRENT_CONTROL_SET TEXT("\\WINDOWS")
#define CSDVERSION TEXT("CSDVersion")
BOOL IsNTSPx(BOOL fEqualOrGreater, UINT uMajorVer, UINT uSPVer)
{
HKEY hKey;
DWORD dwSPVersion;
DWORD dwSize;
BOOL fResult = FALSE;
OSVERSIONINFO VerInfo;
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&VerInfo);
// make sure we're on NT4 or greater (or specifically NT4, if required)
if (VER_PLATFORM_WIN32_NT != VerInfo.dwPlatformId ||
(!fEqualOrGreater && VerInfo.dwMajorVersion != uMajorVer) ||
(fEqualOrGreater && VerInfo.dwMajorVersion < uMajorVer))
return FALSE;
if (fEqualOrGreater && VerInfo.dwMajorVersion > uMajorVer)
return TRUE;
// check for installed SP
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_CCS_CONTROL_WINDOWS, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
dwSize = sizeof(dwSPVersion);
if (RegQueryValueEx(hKey, CSDVERSION, NULL, NULL, (unsigned char*)&dwSPVersion, &dwSize) == ERROR_SUCCESS)
{
dwSPVersion = dwSPVersion >> 8;
}
RegCloseKey(hKey);
if (fEqualOrGreater)
fResult = (dwSPVersion >= uSPVer ? TRUE : FALSE);
else
fResult = (dwSPVersion == uSPVer ? TRUE : FALSE);
}
return fResult;
}