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.
 
 
 
 
 
 

1641 lines
42 KiB

//
// Include Files.
//
#include "input.h"
#include <regstr.h>
#include "util.h"
#include "external.h"
#include "msctf.h"
#include "inputdlg.h"
#define CLSID_STRLEN 38
const TCHAR c_szSetupKey[] = TEXT("System\\Setup");
const TCHAR c_szSetupInProgress[] = TEXT("SystemSetupInProgress");
const TCHAR c_szLangBarSetting[] = TEXT("SOFTWARE\\Microsoft\\CTF\\LangBar");
const TCHAR c_szShowStatus[] = TEXT("ShowStatus");
const TCHAR c_szCtf[] = TEXT("SOFTWARE\\Microsoft\\CTF");
const TCHAR c_szCtfShared[] = TEXT("SOFTWARE\\Microsoft\\CTF\\SystemShared");
const TCHAR c_szDisableTim[] = TEXT("Disable Thread Input Manager");
const TCHAR c_szLangBarSetting_DefUser[] = TEXT(".DEFAULT\\SOFTWARE\\Microsoft\\CTF\\LangBar");
const TCHAR c_szLangGroup[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\Language Groups");
const TCHAR c_szLangJPN[] = TEXT("7");
const TCHAR c_szLanguageProfile[] = TEXT("\\LanguageProfile");
//
// Cicero Unaware Application Support const strings.
//
const TCHAR c_szIMM[] = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IMM");
const TCHAR c_szLoadIMM[] = TEXT("LoadIMM");
const TCHAR c_szIMMFile[] = TEXT("IME File");
const TCHAR c_szIMMFileName[] = TEXT("msctfime.ime");
const TCHAR c_szCUAS[] = TEXT("CUAS");
////////////////////////////////////////////////////////////////////////////
//
// CLSIDToStringA
//
// Converts a CLSID to an mbcs string.
//
////////////////////////////////////////////////////////////////////////////
static const BYTE GuidMap[] = {3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
8, 9, '-', 10, 11, 12, 13, 14, 15};
static const char szDigits[] = "0123456789ABCDEF";
BOOL CLSIDToStringA(REFGUID refGUID, char *pchA)
{
int i;
char *p = pchA;
const BYTE * pBytes = (const BYTE *) refGUID;
*p++ = '{';
for (i = 0; i < sizeof(GuidMap); i++)
{
if (GuidMap[i] == '-')
{
*p++ = '-';
}
else
{
*p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
*p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
}
}
*p++ = '}';
*p = '\0';
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
//
// TransNum
//
// Converts a number string to a dword value (in hex).
//
////////////////////////////////////////////////////////////////////////////
DWORD TransNum(
LPTSTR lpsz)
{
DWORD dw = 0L;
TCHAR c;
while (*lpsz)
{
c = *lpsz++;
if (c >= TEXT('A') && c <= TEXT('F'))
{
c -= TEXT('A') - 0xa;
}
else if (c >= TEXT('0') && c <= TEXT('9'))
{
c -= TEXT('0');
}
else if (c >= TEXT('a') && c <= TEXT('f'))
{
c -= TEXT('a') - 0xa;
}
else
{
break;
}
dw *= 0x10;
dw += c;
}
return (dw);
}
BOOL IsOSPlatform(DWORD dwOS)
{
BOOL bRet;
static OSVERSIONINFOA s_osvi;
static BOOL s_bVersionCached = FALSE;
if (!s_bVersionCached)
{
s_bVersionCached = TRUE;
s_osvi.dwOSVersionInfoSize = sizeof(s_osvi);
GetVersionExA(&s_osvi);
}
switch (dwOS)
{
case OS_WINDOWS:
bRet = (VER_PLATFORM_WIN32_WINDOWS == s_osvi.dwPlatformId);
break;
case OS_NT:
bRet = (VER_PLATFORM_WIN32_NT == s_osvi.dwPlatformId);
break;
case OS_WIN95:
bRet = (VER_PLATFORM_WIN32_WINDOWS == s_osvi.dwPlatformId &&
s_osvi.dwMajorVersion >= 4);
break;
case OS_NT4:
bRet = (VER_PLATFORM_WIN32_NT == s_osvi.dwPlatformId &&
(s_osvi.dwMajorVersion >= 4 && s_osvi.dwMajorVersion < 5));
break;
case OS_NT5:
bRet = (VER_PLATFORM_WIN32_NT == s_osvi.dwPlatformId &&
s_osvi.dwMajorVersion >= 5);
break;
case OS_NT51:
bRet = (VER_PLATFORM_WIN32_NT == s_osvi.dwPlatformId &&
s_osvi.dwMajorVersion >= 5 && s_osvi.dwMinorVersion >= 0x00000001);
break;
default:
bRet = FALSE;
break;
}
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// MirrorBitmapInDC
//
////////////////////////////////////////////////////////////////////////////
void MirrorBitmapInDC(
HDC hdc,
HBITMAP hbmOrig)
{
HDC hdcMem;
HBITMAP hbm;
BITMAP bm;
if (!GetObject(hbmOrig, sizeof(BITMAP), &bm))
{
return;
}
hdcMem = CreateCompatibleDC(hdc);
if (!hdcMem)
{
return;
}
hbm = CreateCompatibleBitmap(hdc, bm.bmWidth, bm.bmHeight);
if (!hbm)
{
DeleteDC(hdcMem);
return;
}
//
// Flip the bitmap.
//
SelectObject(hdcMem, hbm);
SetLayout(hdcMem, LAYOUT_RTL);
BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdc, 0, 0, SRCCOPY);
SetLayout(hdcMem, 0);
//
// The offset by 1 is to solve the off-by-one problem.
//
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 1, 0, SRCCOPY);
DeleteDC(hdcMem);
DeleteObject(hbm);
}
////////////////////////////////////////////////////////////////////////////
//
// IsSetupMode
//
// Look into the registry if we are currently in setup mode.
//
////////////////////////////////////////////////////////////////////////////
BOOL IsSetupMode()
{
HKEY hKey;
DWORD cb;
DWORD fSystemSetupInProgress;
//
// Open the registry key used by setup
//
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
c_szSetupKey,
0,
KEY_READ,
&hKey) != ERROR_SUCCESS)
{
return (FALSE);
}
//
// Query for the value indicating that we are in setup.
//
cb = sizeof(fSystemSetupInProgress);
if (RegQueryValueEx(hKey,
c_szSetupInProgress,
NULL,
NULL,
(LPBYTE)&fSystemSetupInProgress,
&cb) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return (FALSE);
}
//
// Clean up
//
RegCloseKey(hKey);
//
// Check the value
//
if (fSystemSetupInProgress)
{
return (TRUE);
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////
//
// IsAdminPrivilegeUser
//
////////////////////////////////////////////////////////////////////////////
BOOL IsAdminPrivilegeUser()
{
BOOL bAdmin = FALSE;
BOOL bResult = FALSE;
BOOL fSIDCreated = FALSE;
HANDLE hToken = NULL;
PSID AdminSid;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
fSIDCreated = AllocateAndInitializeSid(&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdminSid);
if (!fSIDCreated)
return FALSE;
bResult = OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY,
&hToken );
if (bResult)
{
DWORD dwSize = 0;
TOKEN_GROUPS *pTokenGrpInfo;
GetTokenInformation(hToken,
TokenGroups,
NULL,
dwSize,
&dwSize);
if (dwSize)
pTokenGrpInfo = (PTOKEN_GROUPS) LocalAlloc(LPTR, dwSize);
else
pTokenGrpInfo = NULL;
if (pTokenGrpInfo && GetTokenInformation(hToken,
TokenGroups,
pTokenGrpInfo,
dwSize,
&dwSize))
{
UINT i;
for (i = 0; i < pTokenGrpInfo->GroupCount; i++)
{
if (EqualSid(pTokenGrpInfo->Groups[i].Sid, AdminSid) &&
(pTokenGrpInfo->Groups[i].Attributes & SE_GROUP_ENABLED))
{
bAdmin = TRUE;
break;
}
}
}
if (pTokenGrpInfo)
LocalFree(pTokenGrpInfo);
}
if (hToken)
CloseHandle(hToken);
if (AdminSid)
FreeSid(AdminSid);
return bAdmin;
}
////////////////////////////////////////////////////////////////////////////
//
// IsInteractiveUserLogon
//
////////////////////////////////////////////////////////////////////////////
BOOL IsInteractiveUserLogon()
{
PSID InteractiveSid;
BOOL bCheckSucceeded;
BOOL bAmInteractive = FALSE;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(&NtAuthority,
1,
SECURITY_INTERACTIVE_RID,
0, 0, 0, 0, 0, 0, 0,
&InteractiveSid))
{
return FALSE;
}
//
// This checking is for logged on user or not. So we can blcok running
// ctfmon.exe process from non-authorized user.
//
bCheckSucceeded = CheckTokenMembership(NULL,
InteractiveSid,
&bAmInteractive);
if (InteractiveSid)
FreeSid(InteractiveSid);
return (bCheckSucceeded && bAmInteractive);
}
////////////////////////////////////////////////////////////////////////////
//
// IsValidLayout
//
////////////////////////////////////////////////////////////////////////////
BOOL IsValidLayout(
DWORD dwLayout)
{
HKEY hKey1, hKey2;
TCHAR szLayout[MAX_PATH];
//
// Get the layout id as a string.
//
StringCchPrintf(szLayout, ARRAYSIZE(szLayout), TEXT("%08x"), dwLayout);
//
// Open the Keyboard Layouts key.
//
if (RegOpenKey(HKEY_LOCAL_MACHINE, c_szLayoutPath, &hKey1) != ERROR_SUCCESS)
{
return (FALSE);
}
//
// Try to open the layout id key under the Keyboard Layouts key.
//
if (RegOpenKey(hKey1, szLayout, &hKey2) != ERROR_SUCCESS)
{
RegCloseKey(hKey1);
return (FALSE);
}
//
// Close the keys.
//
RegCloseKey(hKey1);
RegCloseKey(hKey2);
//
// Return success.
//
return (TRUE);
}
////////////////////////////////////////////////////////////////////////////
//
// SetLangBarOption
//
////////////////////////////////////////////////////////////////////////////
void SetLangBarOption(
DWORD dwShowStatus,
BOOL bDefUser)
{
DWORD cb;
HKEY hkeyLangBar;
if (bDefUser)
{
if (RegCreateKey(HKEY_USERS,
c_szLangBarSetting_DefUser,
&hkeyLangBar) != ERROR_SUCCESS)
{
hkeyLangBar = NULL;
}
}
else
{
if (RegCreateKey(HKEY_CURRENT_USER,
c_szLangBarSetting,
&hkeyLangBar) != ERROR_SUCCESS)
{
hkeyLangBar = NULL;
}
}
if (hkeyLangBar)
{
cb = sizeof(DWORD);
RegSetValueEx(hkeyLangBar,
c_szShowStatus,
0,
REG_DWORD,
(LPBYTE)&dwShowStatus,
sizeof(DWORD) );
RegCloseKey(hkeyLangBar);
}
}
////////////////////////////////////////////////////////////////////////////
//
// GetLangBarOption
//
////////////////////////////////////////////////////////////////////////////
BOOL GetLangBarOption(
DWORD *dwShowStatus,
BOOL bDefUser)
{
DWORD cb;
HKEY hkeyLangBar;
BOOL bRet = FALSE;
if (bDefUser)
{
if (RegCreateKey(HKEY_USERS,
c_szLangBarSetting_DefUser,
&hkeyLangBar) != ERROR_SUCCESS)
{
hkeyLangBar = NULL;
}
}
else
{
if (RegCreateKey(HKEY_CURRENT_USER,
c_szLangBarSetting,
&hkeyLangBar) != ERROR_SUCCESS)
{
hkeyLangBar = NULL;
}
}
if (hkeyLangBar)
{
cb = sizeof(DWORD);
if (RegQueryValueEx(hkeyLangBar,
c_szShowStatus,
NULL,
NULL,
(LPBYTE)&dwShowStatus,
&cb) == ERROR_SUCCESS)
{
bRet = TRUE;
}
RegCloseKey(hkeyLangBar);
}
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// CheckInternatModule
//
////////////////////////////////////////////////////////////////////////////
void CheckInternatModule()
{
DWORD cb;
HKEY hkeyRun;
TCHAR szInternatName[MAX_PATH];
if (RegOpenKey(HKEY_CURRENT_USER,
REGSTR_PATH_RUN,
&hkeyRun) == ERROR_SUCCESS)
{
cb = sizeof(szInternatName);
if (RegQueryValueEx(hkeyRun,
c_szInternat,
NULL,
NULL,
(LPBYTE)szInternatName,
&cb) == ERROR_SUCCESS)
{
LCID SysLocale;
BOOL bMinLangBar = TRUE;
TCHAR szCTFMonPath[MAX_PATH];
SysLocale = GetSystemDefaultLCID();
if ((SysLocale == 0x0404) || (SysLocale == 0x0411) ||
(SysLocale == 0x0412) || (SysLocale == 0x0804))
{
//
// Show language bar in case of FE system as a default
//
bMinLangBar = FALSE;
}
if (bMinLangBar)
{
if (IsOSPlatform(OS_NT51))
{
SetLangBarOption(REG_LANGBAR_DESKBAND, FALSE);
//
// Update language band menu item to Taskbar
//
SetLanguageBandMenu(TRUE);
}
else
{
SetLangBarOption(REG_LANGBAR_MINIMIZED, FALSE);
}
}
//
// Get Ctfmon full path string
//
if (GetCtfmonPath((LPTSTR) szCTFMonPath, ARRAYSIZE(szCTFMonPath)))
{
//
// Set "ctfmon.exe" instead of "internat.exe" module.
//
RegSetValueEx(hkeyRun,
c_szCTFMon,
0,
REG_SZ,
(LPBYTE)szCTFMonPath,
(lstrlen(szCTFMonPath) + 1) * sizeof(TCHAR));
}
}
RegCloseKey(hkeyRun);
}
}
#define MAX_REGKEY 10
DWORD
OpenUserKeyForWin9xUpgrade(
LPCTSTR pszUserKey,
HKEY *phKey
)
{
DWORD dwResult = ERROR_INVALID_PARAMETER;
if (NULL != pszUserKey && NULL != phKey)
{
typedef struct {
LPTSTR pszRoot;
HKEY hKeyRoot;
} REGISTRY_ROOTS, *PREGISTRY_ROOTS;
static REGISTRY_ROOTS rgRoots[] = {
{ TEXT("HKLM"), HKEY_LOCAL_MACHINE },
{ TEXT("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE },
{ TEXT("HKCC"), HKEY_CURRENT_CONFIG },
{ TEXT("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG },
{ TEXT("HKU"), HKEY_USERS },
{ TEXT("HKEY_USERS"), HKEY_USERS },
{ TEXT("HKCU"), HKEY_CURRENT_USER },
{ TEXT("HKEY_CURRENT_USER"), HKEY_CURRENT_USER },
{ TEXT("HKCR"), HKEY_CLASSES_ROOT },
{ TEXT("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT }
};
TCHAR szUserKey[MAX_PATH]; // For a local copy.
LPTSTR pszSubKey = szUserKey;
//
// Make a local copy that we can modify.
//
StringCchCopy(szUserKey, ARRAYSIZE(szUserKey), pszUserKey);
*phKey = NULL;
//
// Find the backslash.
//
while(*pszSubKey && TEXT('\\') != *pszSubKey)
pszSubKey++;
if (TEXT('\\') == *pszSubKey)
{
HKEY hkeyRoot = NULL;
int i;
//
// Replace backslash with nul to separate the root key and
// sub key strings in our local copy of the original argument
// string.
//
*pszSubKey++ = TEXT('\0');
//
// Now find the true root key in rgRoots[].
//
for (i = 0; i < MAX_REGKEY; i++)
{
if (0 == lstrcmpi(rgRoots[i].pszRoot, szUserKey))
{
hkeyRoot = rgRoots[i].hKeyRoot;
break;
}
}
if (NULL != hkeyRoot)
{
//
// Open the key.
//
dwResult = RegOpenKeyEx(hkeyRoot,
pszSubKey,
0,
KEY_ALL_ACCESS,
phKey);
}
}
}
return dwResult;
}
////////////////////////////////////////////////////////////////////////////
//
// MigrateCtfmonFromWin9x
//
////////////////////////////////////////////////////////////////////////////
DWORD MigrateCtfmonFromWin9x(LPCTSTR pszUserKey)
{
DWORD cb;
LCID SysLocale;
HKEY hkeyRun = NULL;
HKEY hkeyUser = NULL;
HKEY hkeyPreload = NULL;
BOOL bAddCtfmon = FALSE;
TCHAR szInternatName[MAX_PATH];
DWORD dwResult = ERROR_INVALID_PARAMETER;
if (lstrlen(pszUserKey) >= MAX_PATH)
return 0;
SysLocale = GetSystemDefaultLCID();
if ((SysLocale == 0x0404) || (SysLocale == 0x0411) ||
(SysLocale == 0x0412) || (SysLocale == 0x0804))
{
return 0;
}
dwResult = OpenUserKeyForWin9xUpgrade(pszUserKey, &hkeyUser);
if (ERROR_SUCCESS != dwResult || hkeyUser == NULL)
{
return dwResult;
}
//
// Now read all of preload hkl from the registry.
//
if (RegOpenKeyEx(hkeyUser,
c_szKbdPreloadKey,
0,
KEY_ALL_ACCESS,
&hkeyPreload) == ERROR_SUCCESS)
{
DWORD dwIndex;
DWORD cchValue, cbData;
TCHAR szValue[MAX_PATH]; // language id (number)
TCHAR szData[MAX_PATH]; // language name
dwIndex = 0;
cchValue = sizeof(szValue) / sizeof(TCHAR);
cbData = sizeof(szData);
dwResult = RegEnumValue(hkeyPreload,
dwIndex,
szValue,
&cchValue,
NULL,
NULL,
(LPBYTE)szData,
&cbData );
if (dwResult != ERROR_SUCCESS)
{
goto Exit;
}
do
{
dwIndex++;
if (dwIndex >= 2)
{
bAddCtfmon = TRUE;
break;
}
cchValue = sizeof(szValue) / sizeof(TCHAR);
szValue[0] = TEXT('\0');
cbData = sizeof(szData);
szData[0] = TEXT('\0');
dwResult = RegEnumValue(hkeyPreload,
dwIndex,
szValue,
&cchValue,
NULL,
NULL,
(LPBYTE)szData,
&cbData );
} while (dwResult == ERROR_SUCCESS);
}
if (!bAddCtfmon)
{
goto Exit;
}
if (RegOpenKeyEx(hkeyUser,
REGSTR_PATH_RUN,
0,
KEY_ALL_ACCESS,
&hkeyRun) == ERROR_SUCCESS)
{
HKEY hkeyLangBar;
TCHAR szCTFMonPath[MAX_PATH];
if (RegCreateKey(hkeyUser,
c_szLangBarSetting,
&hkeyLangBar) == ERROR_SUCCESS)
{
DWORD dwShowStatus = REG_LANGBAR_DESKBAND;
cb = sizeof(DWORD);
RegSetValueEx(hkeyLangBar,
c_szShowStatus,
0,
REG_DWORD,
(LPBYTE)&dwShowStatus,
sizeof(DWORD) );
RegCloseKey(hkeyLangBar);
}
//
// Get Ctfmon full path string
//
if (GetCtfmonPath((LPTSTR) szCTFMonPath, ARRAYSIZE(szCTFMonPath)))
{
//
// Set "ctfmon.exe" instead of "internat.exe" module.
//
dwResult = RegSetValueEx(hkeyRun,
c_szCTFMon,
0,
REG_SZ,
(LPBYTE)szCTFMonPath,
(lstrlen(szCTFMonPath) + 1) * sizeof(TCHAR));
}
//
// Clean up the registry for internat.
//
RegDeleteValue(hkeyRun, c_szInternat);
}
Exit:
if (hkeyPreload)
RegCloseKey(hkeyPreload);
if (hkeyRun)
RegCloseKey(hkeyRun);
if (hkeyUser)
RegCloseKey(hkeyUser);
return dwResult;
}
////////////////////////////////////////////////////////////////////////////
//
// IsDisableCtfmon
//
////////////////////////////////////////////////////////////////////////////
BOOL IsDisableCtfmon()
{
DWORD cb;
HKEY hkeyLangBar;
BOOL bRet = FALSE;
DWORD dwDisableCtfmon = 0;
if (RegOpenKey(HKEY_CURRENT_USER, c_szCtf, &hkeyLangBar) == ERROR_SUCCESS)
{
cb = sizeof(DWORD);
RegQueryValueEx(hkeyLangBar,
c_szDisableTim,
NULL,
NULL,
(LPBYTE)&dwDisableCtfmon,
&cb);
if (dwDisableCtfmon)
bRet = TRUE;
RegCloseKey(hkeyLangBar);
}
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// SetDisableCtfmon
//
////////////////////////////////////////////////////////////////////////////
void SetDisalbeCtfmon(
DWORD dwDisableCtfmon)
{
DWORD cb;
HKEY hkeyLangBar;
if (RegCreateKey(HKEY_CURRENT_USER, c_szCtf, &hkeyLangBar) == ERROR_SUCCESS)
{
cb = sizeof(DWORD);
RegSetValueEx(hkeyLangBar,
c_szDisableTim,
0,
REG_DWORD,
(LPBYTE)&dwDisableCtfmon,
cb);
RegCloseKey(hkeyLangBar);
}
}
////////////////////////////////////////////////////////////////////////////
//
// IsDisableCUAS
//
////////////////////////////////////////////////////////////////////////////
BOOL IsDisableCUAS()
{
DWORD cb;
HKEY hkeyCTF;
BOOL bRet = TRUE;
DWORD dwEnableCUAS = 0;
if (RegOpenKey(HKEY_LOCAL_MACHINE, c_szCtfShared, &hkeyCTF) == ERROR_SUCCESS)
{
cb = sizeof(DWORD);
RegQueryValueEx(hkeyCTF,
c_szCUAS,
NULL,
NULL,
(LPBYTE)&dwEnableCUAS,
&cb);
if (dwEnableCUAS)
bRet = FALSE;
RegCloseKey(hkeyCTF);
}
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// SetDisableCUAS
//
////////////////////////////////////////////////////////////////////////////
void SetDisableCUAS(
BOOL bDisableCUAS)
{
HKEY hkeyIMM;
HKEY hkeyCTF;
DWORD cb = sizeof(DWORD);
DWORD dwIMM32, dwCUAS;
if (bDisableCUAS)
dwIMM32 = dwCUAS = 0;
else
dwIMM32 = dwCUAS = 1;
if (RegCreateKey(HKEY_LOCAL_MACHINE, c_szIMM, &hkeyIMM) != ERROR_SUCCESS)
{
hkeyIMM = NULL;
}
if (RegCreateKey(HKEY_LOCAL_MACHINE, c_szCtfShared, &hkeyCTF) != ERROR_SUCCESS)
{
hkeyCTF = NULL;
}
if (!bDisableCUAS)
{
//
// Turn on LoadIMM and CUAS flags
//
if (hkeyIMM)
{
RegSetValueEx(hkeyIMM,
c_szIMMFile,
0,
REG_SZ,
(LPBYTE)c_szIMMFileName,
(lstrlen(c_szIMMFileName) + 1) * sizeof(TCHAR));
}
}
else
{
//
// Turn off LoadIMM and CUAS flags
//
BOOL bEALang = IsInstalledEALangPack();
if (bEALang)
{
dwIMM32 = 1;
}
}
if (hkeyIMM)
{
RegSetValueEx(hkeyIMM,
c_szLoadIMM,
0,
REG_DWORD,
(LPBYTE)&dwIMM32,
cb);
}
if (hkeyCTF)
{
RegSetValueEx(hkeyCTF,
c_szCUAS,
0,
REG_DWORD,
(LPBYTE)&dwCUAS,
cb);
}
if (hkeyIMM)
RegCloseKey(hkeyIMM);
if (hkeyCTF)
RegCloseKey(hkeyCTF);
}
////////////////////////////////////////////////////////////////////////////
//
// SetDisableCtfmon
//
////////////////////////////////////////////////////////////////////////////
BOOL SetLanguageBandMenu(
BOOL bLoad)
{
BOOL bRet = FALSE;
HINSTANCE hMsutb = NULL;
FARPROC pfnSetRegisterLangBand = NULL;
//
// Load MSUTB.DLL to register deskband menu item to TaskBar.
//
hMsutb = LoadSystemLibrary(TEXT("msutb.dll"));
if (hMsutb)
{
//
// Get SetRegisterLangBand()
//
pfnSetRegisterLangBand = GetProcAddress(hMsutb,
(LPVOID)8);
}
else
{
goto Exit;
}
//
// Call DllRegisterServer/DllUnregisterServer()
//
if (pfnSetRegisterLangBand)
{
pfnSetRegisterLangBand(bLoad);
bRet = TRUE;
}
if (hMsutb)
{
FreeLibrary(hMsutb);
}
Exit:
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// RunCtfmonProcess
//
////////////////////////////////////////////////////////////////////////////
BOOL RunCtfmonProcess()
{
TCHAR szCtfmonPath[MAX_PATH + 1];
if (GetCtfmonPath(szCtfmonPath, ARRAYSIZE(szCtfmonPath)))
{
PROCESS_INFORMATION pi;
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = (WORD) SW_SHOWMINNOACTIVE;
if (CreateProcess(szCtfmonPath,
c_szCTFMon,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi))
{
WaitForInputIdle(pi.hProcess, 2000) ;
return TRUE;
}
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////
//
// GetCtfmonPath
//
////////////////////////////////////////////////////////////////////////////
UINT GetCtfmonPath(
LPTSTR lpCtfmonPath,
UINT uBuffLen)
{
UINT uSize = 0;
if (!lpCtfmonPath)
return uSize;
*lpCtfmonPath = TEXT('\0');
//
// Confirmed lpCtfmonPath has MAX_PATH buffer size.
//
if (uSize = GetSystemDirectory(lpCtfmonPath, uBuffLen))
{
if (*(lpCtfmonPath + uSize - 1) != TEXT('\\'))
{
*(lpCtfmonPath + uSize) = TEXT('\\');
uSize++;
}
if (uBuffLen - uSize > (UINT) lstrlen(c_szCTFMon))
{
lstrcpyn(lpCtfmonPath + uSize, c_szCTFMon, uBuffLen - uSize);
uSize += lstrlen(c_szCTFMon);
}
else
{
*(lpCtfmonPath) = TEXT('\0');
uSize = 0;
}
}
return uSize;
}
////////////////////////////////////////////////////////////////////////////
//
// IsInstalledEALangPack
//
////////////////////////////////////////////////////////////////////////////
BOOL IsInstalledEALangPack()
{
BOOL bRet = FALSE;
HKEY hkeyLangGroup;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
c_szLangGroup,
0,
KEY_READ,
&hkeyLangGroup) == ERROR_SUCCESS)
{
DWORD cb;
TCHAR szLangInstall[10];
cb = sizeof(szLangInstall);
//
// The checking of Japan Language is enough to know EA language pack
// installation.
//
if (RegQueryValueEx(hkeyLangGroup,
c_szLangJPN,
NULL,
NULL,
(LPBYTE)szLangInstall,
&cb) == ERROR_SUCCESS)
{
if (szLangInstall[0] != 0)
return TRUE;
}
RegCloseKey(hkeyLangGroup);
}
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// IsTIPClsidEnabled
//
////////////////////////////////////////////////////////////////////////////
BOOL IsTIPClsidEnabled(
HKEY hkeyTop,
LPTSTR lpTipClsid,
BOOL *bExistEnable)
{
BOOL bRet = FALSE;
HKEY hkeyTipLang;
HKEY hkeyTipLangid;
HKEY hkeyTipGuid;
UINT uIndex;
UINT uIndex2;
DWORD cb;
DWORD cchLangid;
DWORD cchGuid;
DWORD dwEnableTIP = 0;
LPTSTR pszGuid;
LPTSTR pszLangid;
TCHAR szTIPLangid[15];
TCHAR szTIPGuid[128];
TCHAR szTIPClsidLang[MAX_PATH];
FILETIME lwt;
UINT uLangidLen;
UINT uGuidLen;
if (lstrlen(lpTipClsid) != CLSID_STRLEN)
return bRet;
StringCchCopy(szTIPClsidLang, ARRAYSIZE(szTIPClsidLang), c_szCTFTipPath);
StringCchCat(szTIPClsidLang, ARRAYSIZE(szTIPClsidLang), lpTipClsid);
StringCchCat(szTIPClsidLang, ARRAYSIZE(szTIPClsidLang), c_szLanguageProfile);
pszLangid = szTIPClsidLang + lstrlen(szTIPClsidLang);
uLangidLen = ARRAYSIZE(szTIPClsidLang) - lstrlen(szTIPClsidLang);
if (RegOpenKeyEx(hkeyTop,
szTIPClsidLang, 0,
KEY_READ, &hkeyTipLang) != ERROR_SUCCESS)
{
goto Exit;
}
for (uIndex = 0; bRet == FALSE; uIndex++)
{
cchLangid = sizeof(szTIPLangid) / sizeof(TCHAR);
if (RegEnumKeyEx(hkeyTipLang, uIndex,
szTIPLangid, &cchLangid,
NULL, NULL, NULL, &lwt) != ERROR_SUCCESS)
{
break;
}
if (cchLangid != 10)
{
// string langid subkeys should be like 0x00000409
continue;
}
if (uLangidLen > (cchLangid + 1))
{
StringCchCopy(pszLangid, uLangidLen, TEXT("\\"));
StringCchCat(pszLangid, uLangidLen, szTIPLangid);
}
if (RegOpenKeyEx(hkeyTop,
szTIPClsidLang, 0,
KEY_READ, &hkeyTipLangid) != ERROR_SUCCESS)
{
continue;
}
pszGuid = szTIPClsidLang + lstrlen(szTIPClsidLang);
uGuidLen = ARRAYSIZE(szTIPClsidLang) - lstrlen(szTIPClsidLang);
for (uIndex2 = 0; bRet == FALSE; uIndex2++)
{
cchGuid = sizeof(szTIPGuid) / sizeof(TCHAR);
if (RegEnumKeyEx(hkeyTipLangid, uIndex2,
szTIPGuid, &cchGuid,
NULL, NULL, NULL, &lwt) != ERROR_SUCCESS)
{
break;
}
if (cchGuid != CLSID_STRLEN)
{
continue;
}
if (uGuidLen > (cchGuid + 1))
{
StringCchCopy(pszGuid, uGuidLen, TEXT("\\"));
StringCchCat(szTIPClsidLang, ARRAYSIZE(szTIPClsidLang), szTIPGuid);
}
if (RegOpenKeyEx(hkeyTop,
szTIPClsidLang, 0,
KEY_READ, &hkeyTipGuid) == ERROR_SUCCESS)
{
cb = sizeof(DWORD);
if (RegQueryValueEx(hkeyTipGuid,
TEXT("Enable"),
NULL,
NULL,
(LPBYTE)&dwEnableTIP,
&cb) == ERROR_SUCCESS)
{
RegCloseKey(hkeyTipGuid);
*bExistEnable = TRUE;
if (dwEnableTIP)
{
bRet = TRUE;
}
}
else if (hkeyTop == HKEY_LOCAL_MACHINE)
{
// Default is the enabled status on HKLM
*bExistEnable = TRUE;
bRet = TRUE;
}
else
{
*bExistEnable = FALSE;
}
}
}
RegCloseKey(hkeyTipLangid);
}
RegCloseKey(hkeyTipLang);
Exit:
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// IsTipInstalled
//
////////////////////////////////////////////////////////////////////////////
BOOL IsTipInstalled()
{
const CLSID CLSID_SapiLayr = {0xdcbd6fa8, 0x032f, 0x11d3, {0xb5, 0xb1, 0x00, 0xc0, 0x4f, 0xc3, 0x24, 0xa1}};
const CLSID CLSID_SoftkbdIMX = {0xf89e9e58, 0xbd2f, 0x4008, {0x9a, 0xc2, 0x0f, 0x81, 0x6c, 0x09, 0xf4, 0xee}};
static const TCHAR c_szSpeechRecognizersKey[] = TEXT("Software\\Microsoft\\Speech\\Recognizers\\Tokens");
static const TCHAR c_szCategory[] = TEXT("\\Category\\Category");
BOOL bRet = FALSE;
BOOL bExistEnable;
HKEY hkeyTip;
HKEY hkeyTipSub;
UINT uIndex;
DWORD dwSubKeys;
DWORD cchClsid;
CLSID clsidTip;
TCHAR szTipClsid[128];
TCHAR szTipClsidPath[MAX_PATH];
FILETIME lwt;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT("Software\\Microsoft\\CTF\\TIP"),
0, KEY_READ, &hkeyTip) != ERROR_SUCCESS)
{
goto Exit;
}
// enum through all the TIP subkeys
for (uIndex = 0; TRUE; uIndex++)
{
bExistEnable = FALSE;
cchClsid = sizeof(szTipClsid) / sizeof(TCHAR);
if (RegEnumKeyEx(hkeyTip, uIndex,
szTipClsid, &cchClsid,
NULL, NULL, NULL, &lwt) != ERROR_SUCCESS)
{
break;
}
if (cchClsid != CLSID_STRLEN)
{
// string clsid subkeys should be like {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
continue;
}
StringCchCopy(szTipClsidPath, ARRAYSIZE(szTipClsidPath), szTipClsid);
// we want subkey\Language Profiles key
StringCchCat(szTipClsidPath, ARRAYSIZE(szTipClsidPath), c_szLanguageProfile);
// is this subkey a tip?
if (RegOpenKeyEx(hkeyTip,
szTipClsidPath, 0,
KEY_READ, &hkeyTipSub) == ERROR_SUCCESS)
{
RegCloseKey(hkeyTipSub);
// it's a tip, get the clsid
if (CLSIDFromString((LPOLESTR )szTipClsid, &clsidTip) != NOERROR)
continue;
// special case certain known tips
if (IsEqualGUID(&clsidTip, &CLSID_SapiLayr))
{
//
// This is SAPI TIP and need to handle it specially, since sptip has
// a default option as the enabled status.
//
if (!IsTIPClsidEnabled(HKEY_CURRENT_USER, szTipClsid, &bExistEnable))
{
//
// If SPTIP has enable registry setting on HKCU with the disabled
// speech tip, we assume user intentionally disable it.
//
if (bExistEnable)
continue;
}
// this is the sapi tip, which is always installed
// but it will not activate if sapi is not installed
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
c_szSpeechRecognizersKey, 0,
KEY_READ, &hkeyTipSub) != ERROR_SUCCESS)
{
continue; // this tip doesn't count
}
// need 1 or more subkeys for sapi to be truely installed...whistler has a Tokens with nothing underneath
if (RegQueryInfoKey(hkeyTipSub,
NULL, NULL, NULL, &dwSubKeys, NULL,
NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
dwSubKeys = 0; // assume no sub keys on failure
}
RegCloseKey(hkeyTipSub);
if (dwSubKeys != 0)
{
bRet = TRUE;
break;
}
}
else if (IsEqualGUID(&clsidTip, &CLSID_SoftkbdIMX))
{
// don't count the softkbd, it is disabled until another tip
// enables it
continue;
}
else if(IsTIPClsidEnabled(HKEY_CURRENT_USER, szTipClsid, &bExistEnable))
{
bRet = TRUE;
break;
}
else if (!bExistEnable)
{
if(IsTIPClsidEnabled(HKEY_LOCAL_MACHINE, szTipClsid, &bExistEnable))
{
bRet = TRUE;
break;
}
}
}
}
RegCloseKey(hkeyTip);
Exit:
return bRet;
}
////////////////////////////////////////////////////////////////////////////
//
// ResetImm32AndCtfImeFlag
//
////////////////////////////////////////////////////////////////////////////
void ResetImm32AndCtfIme()
{
BOOL bTipInstalled;
bTipInstalled = IsTipInstalled();
if (bTipInstalled)
{
//
// TIP is detected now, so automatically recover LoadImm
// and CUAS to "On" status
//
SetDisableCUAS(FALSE);
}
}
////////////////////////////////////////////////////////////////////////////
//
// LoadSystemLibrary
//
////////////////////////////////////////////////////////////////////////////
HMODULE LoadSystemLibrary(
LPCTSTR lpModuleName)
{
UINT uRet = 0;
HINSTANCE hModule = NULL;
TCHAR szModulePath[MAX_PATH + 1];
szModulePath[0] = TEXT('\0');
uRet = GetSystemDirectory(szModulePath, ARRAYSIZE(szModulePath));
if (uRet >= ARRAYSIZE(szModulePath))
{
// we don't have a room to copy module name.
uRet = 0;
}
else if (uRet)
{
if (szModulePath[uRet - 1] != TEXT('\\'))
{
szModulePath[uRet] = TEXT('\\');
uRet++;
}
if (ARRAYSIZE(szModulePath) - uRet > (UINT) lstrlen(lpModuleName))
{
lstrcpyn(&szModulePath[uRet],
lpModuleName,
ARRAYSIZE(szModulePath) - uRet);
}
else
{
uRet = 0;
}
}
if (uRet)
{
hModule = LoadLibrary(szModulePath);
}
return hModule;
}
////////////////////////////////////////////////////////////////////////////
//
// LoadSystemLibraryEx
//
////////////////////////////////////////////////////////////////////////////
HMODULE LoadSystemLibraryEx(
LPCTSTR lpModuleName,
HANDLE hFile,
DWORD dwFlags)
{
UINT uRet = 0;
HINSTANCE hModule = NULL;
TCHAR szModulePath[MAX_PATH + 1];
szModulePath[0] = TEXT('\0');
uRet = GetSystemDirectory(szModulePath, ARRAYSIZE(szModulePath));
if (uRet >= ARRAYSIZE(szModulePath))
{
// we don't have a room to copy module name.
uRet = 0;
}
else if (uRet)
{
if (szModulePath[uRet - 1] != TEXT('\\'))
{
szModulePath[uRet] = TEXT('\\');
uRet++;
}
if (ARRAYSIZE(szModulePath) - uRet > (UINT) lstrlen(lpModuleName))
{
lstrcpyn(&szModulePath[uRet],
lpModuleName,
ARRAYSIZE(szModulePath) - uRet);
}
else
{
uRet = 0;
}
}
if (uRet)
{
hModule = LoadLibraryEx(szModulePath, hFile,dwFlags);
}
return hModule;
}