windows-nt/Source/XPSP1/NT/base/ntsetup/oobe/msobmain/language.cpp
2020-09-26 16:20:57 +08:00

630 lines
16 KiB
C++

//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1999 **
//*********************************************************************
//
// LANGUAGE.CPP - Header for the implementation of CLanguage
//
// HISTORY:
//
// 1/27/99 a-jaswed Created.
//
#include "precomp.h"
#include "msobmain.h"
#include "language.h"
#include "appdefs.h"
#include "dispids.h"
#define DEFAULT_BUFFER_SIZE BYTES_REQUIRED_BY_CCH(2048)
DISPATCHLIST LanguageExternalInterface[] =
{
{L"get_NumOfRegions", DISPID_GETNUMOFREGIONS },
{L"get_RegionName", DISPID_GETREGIONNAME },
{L"get_RegionIndex", DISPID_GETREGIONINDEX },
{L"set_RegionIndex", DISPID_SETREGIONINDEX },
{L"get_NumOfLangs", DISPID_GETNUMOFLANGS },
{L"get_LangName", DISPID_GETLANGNAME },
{L"get_LangIndex", DISPID_GETLANGINDEX },
{L"set_LangIndex", DISPID_SETLANGINDEX },
{L"get_NumOfKeyboardLayouts", DISPID_GETNUMOFKEYLAYOUTS },
{L"get_KeyboardLayoutName", DISPID_GETKEYNAME },
{L"get_KeyboardLayoutIndex", DISPID_GETKEYLAYOUTINDEX },
{L"set_KeyboardLayoutIndex", DISPID_SETKEYLAYOUTINDEX },
{L"get_RebootState", DISPID_LANGUAGE_GETREBOOTSTATE },
{L"SaveSettings", DISPID_LANGUAGE_SAVESETTINGS },
{L"get_PhoneCountries", DISPID_GETPHONECOUNTRIES }
};
//+---------------------------------------------------------------------------
//
// Function: CompareNameLookUpElements()
//
// Synopsis: Function to compare names used by sort
//
//+---------------------------------------------------------------------------
int __cdecl CompareNameLookUpElements(const void *e1, const void *e2)
{
LPNAMELOOKUPELEMENT pCUE1 = (LPNAMELOOKUPELEMENT)e1;
LPNAMELOOKUPELEMENT pCUE2 = (LPNAMELOOKUPELEMENT)e2;
return CompareString(LOCALE_USER_DEFAULT, 0,
pCUE1->pszName,
-1,
pCUE2->pszName,
-1) - 2;
}
/////////////////////////////////////////////////////////////
// CLanguage::CLanguage
CLanguage::CLanguage()
{
WCHAR szINIPath[MAX_PATH] = L"";
WCHAR Answer[MAX_PATH];
// Init member vars
m_cRef = 0;
m_lRebootState = LANGUAGE_REBOOT_NEVER;
m_poliRegions = NULL;
m_lRegionTotal = 0;
m_lRegionDefault = -1;
m_poliLangs = NULL;
m_lLangTotal = 0;
m_lLangDefault = -1;
m_poliKeyboards = NULL;
m_lKeyboardLayoutTotal = 0;
m_lKeyboardLayoutDefault = -1;
GetCanonicalizedPath(szINIPath, INI_SETTINGS_FILENAME);
m_DefaultRegion = GetPrivateProfileInt(
OPTIONS_SECTION,
DEFAULT_REGION,
0,
szINIPath
);
GetPrivateProfileString(
OPTIONS_SECTION,
DEFAULT_LANGUAGE,
L"",
Answer,
MAX_PATH,
szINIPath
);
m_DefaultLanguage = wcstoul(Answer, NULL, 16);
GetPrivateProfileString(
OPTIONS_SECTION,
DEFAULT_KEYBOARD,
L"",
Answer,
MAX_PATH,
szINIPath
);
m_DefaultKeyboard = wcstoul(Answer, NULL, 16);
SetupGetGeoOptions(
m_DefaultRegion,
&m_poliRegions,
(LPDWORD) &m_lRegionTotal,
(LPDWORD) &m_lRegionDefault
);
MYASSERT( m_poliRegions );
SetupGetLocaleOptions(
m_DefaultLanguage,
&m_poliLangs,
(LPDWORD) &m_lLangTotal,
(LPDWORD) &m_lLangDefault
);
MYASSERT( m_poliLangs );
SetupGetKeyboardOptions(
m_DefaultKeyboard,
&m_poliKeyboards,
(LPDWORD) &m_lKeyboardLayoutTotal,
(LPDWORD) &m_lKeyboardLayoutDefault);
MYASSERT( m_poliKeyboards );
// The current index should be the defaults.
//
m_lRegionIndex = m_lRegionDefault;
m_lLangIndex = m_lLangDefault;
m_lKeyboardLayoutIndex = m_lKeyboardLayoutDefault;
}
/////////////////////////////////////////////////////////////
// CLanguage::~CLanguage
CLanguage::~CLanguage()
{
if ( m_poliRegions )
SetupDestroyLanguageList( m_poliRegions, m_lRegionTotal );
if ( m_poliLangs )
SetupDestroyLanguageList( m_poliLangs, m_lLangTotal );
if ( m_poliKeyboards )
SetupDestroyLanguageList( m_poliKeyboards, m_lKeyboardLayoutTotal );
MYASSERT(m_cRef == 0);
}
HRESULT CLanguage::get_NumOfRegions(long* plVal)
{
*plVal = m_lRegionTotal;
return S_OK;
}
HRESULT CLanguage::get_NumOfKeyboardLayouts(long* plVal)
{
*plVal = m_lKeyboardLayoutTotal;
return S_OK;
}
HRESULT CLanguage::get_RegionName(long lIndex, BSTR* pbstrVal)
{
if ( lIndex >= m_lRegionTotal )
return E_FAIL;
// *pbstrVal = SysAllocString(m_pRegionNameLookUp[lIndex].pszName);
*pbstrVal = SysAllocString( m_poliRegions[lIndex].Name );
return S_OK;
}
HRESULT CLanguage::get_KeyboardLayoutName(long lIndex, BSTR* pbstrVal)
{
if ( lIndex >= m_lKeyboardLayoutTotal )
return E_FAIL;
// *pbstrVal = SysAllocString(m_pKeyboardNameLookUp[lIndex].pszName);
*pbstrVal = SysAllocString( m_poliKeyboards[lIndex].Name );
return S_OK;
}
HRESULT CLanguage::get_RebootState(long* plVal)
{
*plVal = m_lRebootState;
return S_OK;
}
HRESULT CLanguage::SaveSettings()
{
// Only save the settings if they changed.
//
if ( ( m_lRegionIndex >= 0 ) &&
( m_lLangIndex >= 0 ) &&
( m_lKeyboardLayoutIndex >= 0 ) &&
m_poliRegions &&
m_poliLangs &&
m_poliKeyboards
)
//( m_lRegionDefault != m_lRegionIndex ) ||
//( m_lKeyboardLayoutDefault != m_lKeyboardLayoutIndex ) )
{
if (SetupSetIntlOptions(
m_poliRegions[m_lRegionIndex].Id,
m_poliLangs[m_lLangIndex].Id,
m_poliKeyboards[m_lKeyboardLayoutIndex].Id
))
{
// BUGBUG: The return value from SetIntlOptions on Win9x is
// interpreted as a reboot state. How do we determine reboot state
// on Whistler?
// Now the defaults are what is currently saved.
//
m_lRegionDefault = m_lRegionIndex;
m_lLangDefault = m_lLangIndex;
m_lKeyboardLayoutDefault = m_lKeyboardLayoutIndex;
}
}
return S_OK;
}
////////////////////////////////////////////////
////////////////////////////////////////////////
//// GET / SET :: RegionIndex
////
HRESULT CLanguage::get_RegionIndex(long* plVal)
{
*plVal = m_lRegionIndex;
return S_OK;
}
HRESULT CLanguage::set_RegionIndex(long lVal)
{
m_lRegionIndex = lVal;
// m_lRegionIndex = m_pRegionNameLookUp[lVal].nIndex;
return S_OK;
}
////////////////////////////////////////////////
////////////////////////////////////////////////
//// GET / SET :: KeyboardLayoutIndex
////
HRESULT CLanguage::get_KeyboardLayoutIndex(long* plVal)
{
*plVal = m_lKeyboardLayoutIndex;
return S_OK;
}
HRESULT CLanguage::set_KeyboardLayoutIndex(long lVal)
{
m_lKeyboardLayoutIndex = lVal;
// m_lKeyboardLayoutIndex = m_pKeyboardNameLookUp[lVal].nIndex;;
return S_OK;
}
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////// IUnknown implementation
///////
///////
/////////////////////////////////////////////////////////////
// CLanguage::QueryInterface
STDMETHODIMP CLanguage::QueryInterface(REFIID riid, LPVOID* ppvObj)
{
// must set out pointer parameters to NULL
*ppvObj = NULL;
if ( riid == IID_IUnknown)
{
AddRef();
*ppvObj = (IUnknown*)this;
return ResultFromScode(S_OK);
}
if (riid == IID_IDispatch)
{
AddRef();
*ppvObj = (IDispatch*)this;
return ResultFromScode(S_OK);
}
// Not a supported interface
return ResultFromScode(E_NOINTERFACE);
}
/////////////////////////////////////////////////////////////
// CLanguage::AddRef
STDMETHODIMP_(ULONG) CLanguage::AddRef()
{
return ++m_cRef;
}
/////////////////////////////////////////////////////////////
// CLanguage::Release
STDMETHODIMP_(ULONG) CLanguage::Release()
{
return --m_cRef;
}
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////// IDispatch implementation
///////
///////
/////////////////////////////////////////////////////////////
// CLanguage::GetTypeInfo
STDMETHODIMP CLanguage::GetTypeInfo(UINT, LCID, ITypeInfo**)
{
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////
// CLanguage::GetTypeInfoCount
STDMETHODIMP CLanguage::GetTypeInfoCount(UINT* pcInfo)
{
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////
// CLanguage::GetIDsOfNames
STDMETHODIMP CLanguage::GetIDsOfNames(REFIID riid,
OLECHAR** rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgDispId)
{
HRESULT hr = DISP_E_UNKNOWNNAME;
rgDispId[0] = DISPID_UNKNOWN;
for (int iX = 0; iX < sizeof(LanguageExternalInterface)/sizeof(DISPATCHLIST); iX ++)
{
if(lstrcmp(LanguageExternalInterface[iX].szName, rgszNames[0]) == 0)
{
rgDispId[0] = LanguageExternalInterface[iX].dwDispID;
hr = NOERROR;
break;
}
}
// Set the disid's for the parameters
if (cNames > 1)
{
// Set a DISPID for function parameters
for (UINT i = 1; i < cNames ; i++)
rgDispId[i] = DISPID_UNKNOWN;
}
return hr;
}
/////////////////////////////////////////////////////////////
// CLanguage::Invoke
HRESULT CLanguage::Invoke
(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr
)
{
HRESULT hr = S_OK;
switch(dispidMember)
{
case DISPID_GETNUMOFREGIONS:
{
TRACE(L"DISPID_GETNUMOFREGIONS\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_I4;
get_NumOfRegions(&(pvarResult->lVal));
}
break;
}
case DISPID_GETREGIONINDEX:
{
TRACE(L"DISPID_GETREGIONINDEX\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_I4;
get_RegionIndex(&(pvarResult->lVal));
}
break;
}
case DISPID_SETREGIONINDEX:
{
TRACE(L"DISPID_SETREGIONINDEX\n");
if(pdispparams && &pdispparams[0].rgvarg[0])
set_RegionIndex(pdispparams[0].rgvarg[0].lVal);
break;
}
case DISPID_GETREGIONNAME:
{
TRACE(L"DISPID_GETREGIONNAME\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_BSTR;
if(pdispparams && &pdispparams[0].rgvarg[0])
get_RegionName(pdispparams[0].rgvarg[0].lVal, &(pvarResult->bstrVal));
}
break;
}
// BUGBUG: Need to Lang processing to syssetup.dll
case DISPID_GETNUMOFLANGS:
{
TRACE(L"DISPID_GETNUMOFFLANGS\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_I4;
pvarResult->lVal = m_lLangTotal;
}
break;
}
case DISPID_GETLANGINDEX:
{
TRACE(L"DISPID_GETLANGINDEX\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_I4;
pvarResult->lVal = m_lLangIndex;
}
break;
}
case DISPID_SETLANGINDEX:
{
TRACE(L"DISPID_SETLANGINDEX\n");
if(pdispparams && &pdispparams[0].rgvarg[0]) {
m_lLangIndex = pdispparams[0].rgvarg[0].lVal;
}
break;
}
case DISPID_GETLANGNAME:
{
TRACE(L"DISPID_GETLANGNAME\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_BSTR;
if(pdispparams && &pdispparams[0].rgvarg[0]) {
long lIndex = pdispparams[0].rgvarg[0].lVal;
// BUGBUG: What if lIndex < 0??
if ( lIndex >= m_lLangTotal )
return E_FAIL;
pvarResult->bstrVal = SysAllocString( m_poliLangs[lIndex].Name );
}
}
break;
}
case DISPID_GETNUMOFKEYLAYOUTS:
{
TRACE(L"DISPID_GETNUMOFKEYLAYOUTS\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_I4;
get_NumOfKeyboardLayouts(&(pvarResult->lVal));
}
break;
}
case DISPID_GETKEYLAYOUTINDEX:
{
TRACE(L"DISPID_GETKEYLAYOUTINDEX\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_I4;
get_KeyboardLayoutIndex(&(pvarResult->lVal));
}
break;
}
case DISPID_SETKEYLAYOUTINDEX:
{
TRACE(L"DISPID_SETKEYLAYOUTINDEX\n");
if(pdispparams && &pdispparams[0].rgvarg[0])
set_KeyboardLayoutIndex(pdispparams[0].rgvarg[0].lVal);
break;
}
case DISPID_GETKEYNAME:
{
TRACE(L"DISPID_GETKEYNAME\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_BSTR;
if(pdispparams && &pdispparams[0].rgvarg[0])
get_KeyboardLayoutName(pdispparams[0].rgvarg[0].lVal, &(pvarResult->bstrVal));
}
break;
}
case DISPID_LANGUAGE_GETREBOOTSTATE:
{
TRACE(L"DISPID_LANGUAGE_GETREBOOTSTATE\n");
if(pvarResult)
{
VariantInit(pvarResult);
V_VT(pvarResult) = VT_I4;
get_RebootState(&(pvarResult->lVal));
}
break;
}
case DISPID_LANGUAGE_SAVESETTINGS:
{
TRACE(L"DISPID_LANGUAGE_SAVESETTINGS\n");
SaveSettings();
break;
}
case DISPID_GETPHONECOUNTRIES:
{
TRACE(L"DISPID_GETPHONECOUNTRIES");
if(pvarResult)
{
WCHAR PhoneInfName[MAX_PATH];
GetOOBEMUIPath( PhoneInfName );
lstrcat( PhoneInfName, L"\\phone.inf" );
VariantInit(pvarResult);
V_VT(pvarResult) = VT_BSTR;
pvarResult->bstrVal = SysAllocString(
SetupReadPhoneList( PhoneInfName ) );
}
break;
}
default:
{
hr = DISP_E_MEMBERNOTFOUND;
break;
}
}
return hr;
}