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.
 
 
 
 
 
 

408 lines
12 KiB

//
// regwatch.cpp
//
#include "private.h"
#include "regwatch.h"
#include "indicml.h"
#include "tfpriv.h"
#include "ctffunc.h"
#include "tlapi.h"
#include "immxutil.h"
extern "C" HRESULT WINAPI TF_InvalidAssemblyListCache();
extern "C" HRESULT WINAPI TF_PostAllThreadMsg(WPARAM wParam, DWORD dwFlags);
static const char c_szKbdLayout[] = "keyboard layout";
static const char c_szKbdToggleKey[] = "Keyboard Layout\\Toggle";
static const char c_szKbdPreload[] = "keyboard layout\\Preload";
static const char c_szRun[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
static const char c_szSpeechKey[] = "Software\\Microsoft\\Speech";
static const char c_szCPLAppearance[] = "Control Panel\\Appearance";
static const char c_szCPLColors[] = "Control Panel\\Colors";
static const char c_szCPLMetrics[] = "Control Panel\\Desktop\\WindowMetrics";
static const TCHAR c_szCTFTIPKey[] = TEXT("SOFTWARE\\Microsoft\\CTF\\TIP\\");
static const TCHAR c_szCTFAssemblies[] = TEXT("SOFTWARE\\Microsoft\\CTF\\Assemblies\\");
REGWATCH CRegWatcher::_rgRegWatch[NUM_REG_WATCH] =
{
{ HKEY_CURRENT_USER, c_szKbdToggleKey, 0 },
{ HKEY_LOCAL_MACHINE, c_szCTFTIPKey, 0 },
{ HKEY_CURRENT_USER, c_szKbdPreload, 0 },
{ HKEY_CURRENT_USER, c_szRun, 0 },
{ HKEY_CURRENT_USER, c_szCTFTIPKey, 0 },
{ HKEY_CURRENT_USER, c_szSpeechKey, 0 },
{ HKEY_CURRENT_USER, c_szCPLAppearance, 0 },
{ HKEY_CURRENT_USER, c_szCPLColors, 0 },
{ HKEY_CURRENT_USER, c_szCPLMetrics, 0 },
{ HKEY_LOCAL_MACHINE, c_szSpeechKey, 0 },
{ HKEY_CURRENT_USER, c_szKbdLayout, 0 },
{ HKEY_CURRENT_USER, c_szCTFAssemblies, 0 },
};
HANDLE CRegWatcher::_rgEvent[NUM_REG_WATCH] = { 0 };
typedef LONG (STDAPICALLTYPE* PFNREGNOTIFYCHANGEKEYVALUE) ( HKEY,
BOOL,
DWORD,
HANDLE,
BOOL);
typedef HRESULT (STDAPICALLTYPE* PFNCREATELANGPROFILEUTIL) (ITfFnLangProfileUtil **);
PFNREGNOTIFYCHANGEKEYVALUE g_pfnRegNotifyChangeKeyValue = NULL;
//////////////////////////////////////////////////////////////////////////////
//
// CRegWatcher
//
//////////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------
//
// Init
//
//--------------------------------------------------------------------------
BOOL CRegWatcher::Init()
{
int i;
BOOL bRet = FALSE;
if (!IsOnNT())
{
_rgRegWatch[REG_WATCH_RUN].hKeyRoot = HKEY_LOCAL_MACHINE;
}
HMODULE hMod = LoadSystemLibrary("advapi32.dll"); // Issue: why no release?
g_pfnRegNotifyChangeKeyValue = (PFNREGNOTIFYCHANGEKEYVALUE)GetProcAddress(hMod, "RegNotifyChangeKeyValue");
if (!g_pfnRegNotifyChangeKeyValue)
{
Assert(0);
goto Exit;
}
for (i = 0; i < NUM_REG_WATCH; i++)
{
if ((_rgEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL)) != 0)
{
InitEvent(i);
}
}
KillInternat();
UpdateSpTip();
bRet = TRUE;
Exit:
return bRet;
}
//--------------------------------------------------------------------------
//
// Uninit
//
//--------------------------------------------------------------------------
void CRegWatcher::Uninit()
{
int i;
for (i = 0; i < NUM_REG_WATCH; i++)
{
RegCloseKey(_rgRegWatch[i].hKey);
if (_rgEvent[i])
{
CloseHandle(_rgEvent[i]);
}
}
}
//--------------------------------------------------------------------------
//
// RegImxTimerProc
//
//--------------------------------------------------------------------------
UINT_PTR CRegWatcher::nRegImxTimerId = 0;
void CRegWatcher::RegImxTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
KillTimer(NULL, nRegImxTimerId);
nRegImxTimerId = 0;
TF_InvalidAssemblyListCache();
TF_PostAllThreadMsg(TFPRIV_UPDATE_REG_IMX, TLF_LBIMGR);
}
//--------------------------------------------------------------------------
//
// SysColorTimerProc
//
//--------------------------------------------------------------------------
UINT_PTR CRegWatcher::nSysColorTimerId = 0;
void CRegWatcher::SysColorTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
KillTimer(NULL, nSysColorTimerId);
nSysColorTimerId = 0;
TF_PostAllThreadMsg(TFPRIV_SYSCOLORCHANGED, TLF_LBIMGR);
}
//--------------------------------------------------------------------------
//
// KbdToggleTimerProc
//
//--------------------------------------------------------------------------
UINT_PTR CRegWatcher::nKbdToggleTimerId = 0;
void CRegWatcher::KbdToggleTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
KillTimer(NULL, nKbdToggleTimerId);
nKbdToggleTimerId = 0;
TF_PostAllThreadMsg(TFPRIV_UPDATE_REG_KBDTOGGLE, TLF_LBIMGR);
}
//--------------------------------------------------------------------------
//
// OnEvent
//
//--------------------------------------------------------------------------
void CRegWatcher::OnEvent(DWORD dwEventId)
{
Assert(dwEventId < NUM_REG_WATCH); // bogus event?
InitEvent(dwEventId, TRUE);
switch (dwEventId)
{
case REG_WATCH_KBDTOGGLE:
if (nKbdToggleTimerId)
{
KillTimer(NULL, nKbdToggleTimerId);
nKbdToggleTimerId = 0;
}
nKbdToggleTimerId = SetTimer(NULL, 0, 500, KbdToggleTimerProc);
break;
case REG_WATCH_KBDLAYOUT:
case REG_WATCH_KBDPRELOAD:
case REG_WATCH_HKLM_IMX:
case REG_WATCH_HKCU_IMX:
case REG_WATCH_HKCU_ASSEMBLIES:
if (nRegImxTimerId)
{
KillTimer(NULL, nRegImxTimerId);
nRegImxTimerId = 0;
}
nRegImxTimerId = SetTimer(NULL, 0, 200, RegImxTimerProc);
break;
case REG_WATCH_RUN:
KillInternat();
break;
case REG_WATCH_HKCU_SPEECH:
case REG_WATCH_HKLM_SPEECH:
UpdateSpTip();
// Forcelly update assembly list
// fix bug 4871
if (nRegImxTimerId)
{
KillTimer(NULL, nRegImxTimerId);
nRegImxTimerId = 0;
}
nRegImxTimerId = SetTimer(NULL, 0, 200, RegImxTimerProc);
break;
case REG_WATCH_HKCU_CPL_APPEARANCE:
case REG_WATCH_HKCU_CPL_COLORS:
case REG_WATCH_HKCU_CPL_METRICS:
StartSysColorChangeTimer();
break;
}
}
//--------------------------------------------------------------------------
//
// StartSysColorChangeTimer
//
//--------------------------------------------------------------------------
void CRegWatcher::StartSysColorChangeTimer()
{
if (nSysColorTimerId)
{
KillTimer(NULL, nSysColorTimerId);
nSysColorTimerId = 0;
}
nSysColorTimerId = SetTimer(NULL, 0, 500, SysColorTimerProc);
}
//--------------------------------------------------------------------------
//
// InitEvent
//
//--------------------------------------------------------------------------
BOOL CRegWatcher::InitEvent(int nId, BOOL fReset)
{
LONG lErrorCode;
if (fReset)
::ResetEvent(_rgEvent[nId]);
RegCloseKey(_rgRegWatch[nId].hKey);
if (RegOpenKeyEx(_rgRegWatch[nId].hKeyRoot, _rgRegWatch[nId].pszKey, 0, KEY_READ, &_rgRegWatch[nId].hKey) == S_OK ||
RegCreateKeyEx(_rgRegWatch[nId].hKeyRoot, _rgRegWatch[nId].pszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &_rgRegWatch[nId].hKey, NULL) == S_OK)
{
Assert(g_pfnRegNotifyChangeKeyValue);
lErrorCode = g_pfnRegNotifyChangeKeyValue(_rgRegWatch[nId].hKey,
TRUE,
REG_NOTIFY_CHANGE_NAME |
REG_NOTIFY_CHANGE_LAST_SET,
_rgEvent[nId],
TRUE);
if (lErrorCode != ERROR_SUCCESS)
{
Assert(0);
return FALSE;
}
return TRUE;
}
return FALSE;
}
//--------------------------------------------------------------------------
//
// KillInternat
//
//--------------------------------------------------------------------------
void CRegWatcher::KillInternat()
{
HKEY hKey;
if (RegOpenKeyEx(_rgRegWatch[REG_WATCH_RUN].hKeyRoot, _rgRegWatch[REG_WATCH_RUN].pszKey, 0, KEY_ALL_ACCESS, &hKey) == S_OK)
{
RegDeleteValue(hKey, "internat.exe");
RegCloseKey(hKey);
}
HWND hwndIndic = FindWindow(INDICATOR_CLASS, NULL);
if (hwndIndic)
{
PostMessage(hwndIndic, WM_CLOSE, 0, 0);
}
}
//--------------------------------------------------------------------------
//
// UpdateSpTip
//
//--------------------------------------------------------------------------
#define WM_PRIV_SPEECHOPTION WM_APP+2
const char c_szWorkerWndClass[] = "SapiTipWorkerClass";
const TCHAR c_szSapilayrKey[] = TEXT("SOFTWARE\\Microsoft\\CTF\\Sapilayr\\");
const TCHAR c_szProfileInit[] = TEXT("ProfileInitialized");
const TCHAR c_szSpTipFile[] = TEXT("\\IME\\sptip.dll");
const TCHAR c_szTFCreateLangPropUtil[] = TEXT("TF_CreateLangProfileUtil");
extern "C" HRESULT WINAPI TF_InvalidAssemblyListCacheIfExist();
void CRegWatcher::UpdateSpTip()
{
EnumWindows( EnumWndProc, NULL);
// clear the key that states "we've init'ed profiles"
//
// 03/27/01 - for bug#4818, we re-enabled this piece of code for HKCU value
// instead of HKLM
//
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, c_szSapilayrKey, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
{
DWORD dw = 0;
RegSetValueEx(hKey, c_szProfileInit, NULL, REG_DWORD, (const BYTE *)&dw, sizeof(dw));
RegCloseKey(hKey);
}
//
// ..then call into sptip's ITfFnLangProfileUtil to update sptip's profile
// we probably don't need to do this at the moment app starts
// if we don't need to register profiles at app boot, we also don't need
// the code above to reset 'ProfileInit' - actually we need to remove this
// code to fix bug 2801 or 3479 (not to access HKLM)
//
PFNCREATELANGPROFILEUTIL pfnCreateLangProfUtil = NULL;
ITfFnLangProfileUtil *pFnLangUtil = NULL;
TCHAR szPathSpTip[MAX_PATH];
HMODULE hSpTip = NULL;
UINT uLength = GetSystemWindowsDirectory(szPathSpTip, ARRAYSIZE(szPathSpTip));
if (uLength &&
(ARRAYSIZE(szPathSpTip) > (uLength + ARRAYSIZE(c_szSpTipFile))))
{
_tcscat(szPathSpTip, c_szSpTipFile);
hSpTip = LoadLibrary(szPathSpTip); // Issue: why no release?
}
if (hSpTip != NULL)
{
pfnCreateLangProfUtil = (PFNCREATELANGPROFILEUTIL)GetProcAddress(hSpTip, c_szTFCreateLangPropUtil);
}
HRESULT hr = E_FAIL;
if (pfnCreateLangProfUtil != NULL)
{
hr = pfnCreateLangProfUtil(&pFnLangUtil);
}
if (S_OK == hr)
{
if (S_OK == pFnLangUtil->RegisterActiveProfiles())
TF_InvalidAssemblyListCacheIfExist();
}
if (pFnLangUtil)
pFnLangUtil->Release();
if (hSpTip != NULL)
{
FreeLibrary(hSpTip);
}
}
BOOL CALLBACK CRegWatcher::EnumWndProc(HWND hwnd, LPARAM lparam)
{
char szCls[MAX_PATH];
if (GetClassNameA(hwnd, szCls, ARRAYSIZE(szCls)) > 0)
{
if ( 0 == lstrcmpiA(szCls, c_szWorkerWndClass) )
{
PostMessage(hwnd, WM_PRIV_SPEECHOPTION, 0, 0);
}
}
return TRUE;
}