Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

782 lines
18 KiB

/****************************** Module Header ******************************\
* Module Name: accrare.c
*
* Copyright (c) 1985-95, Microsoft Corporation
*
* History:
* 12-18-95 a-jimhar Created based on rare.c
\***************************************************************************/
#include "Access.h"
#define REGSTR_PATH_APPEARANCE __TEXT("Control Panel\\Appearance")
#define REGSTR_PATH_LOOKSCHEMES __TEXT("Control Panel\\Appearance\\Schemes")
#define REGSTR_VAL_CUSTOMCOLORS __TEXT("CustomColors")
#define APPEARANCESCHEME REGSTR_PATH_LOOKSCHEMES
#define DEFSCHEMEKEY REGSTR_PATH_APPEARANCE
#define DEFSCHEMENAME __TEXT("Current")
#define HIGHCONTRASTSCHEME __TEXT("High Contrast Scheme")
#define CURHCSCHEME __TEXT("Volital HC Scheme")
#define PRE_HC_SCHEME __TEXT("Pre-High Contrast Scheme")
#define REGSTR_PATH_SERIALKEYS __TEXT("Control Panel\\Accessibility\\SerialKeys")
#define REGSTR_VAL_ACTIVEPORT __TEXT("ActivePort")
#define REGSTR_VAL_BAUDRATE __TEXT("BaudRate")
#define REGSTR_VAL_FLAGS __TEXT("Flags")
#define REGSTR_VAL_PORTSTATE __TEXT("PortState")
#define MAXSCHEMENAME 100
#ifndef COLOR_MAX
#define COLOR_MAX 25
#endif
// structure used to store a scheme in the registry
#ifdef UNICODE
# define SCHEME_VERSION 2 // Ver 2 == Unicode
#else
# define SCHEME_VERSION 1 // Ver 1 == Win95 ANSI
#endif
typedef struct {
int version;
NONCLIENTMETRICS ncm;
LOGFONT lfIconTitle;
COLORREF rgb[COLOR_MAX];
} SCHEMEDATA;
#define PMAP_STICKYKEYS __TEXT("Control Panel\\Accessibility\\StickyKeys")
#define PMAP_KEYBOARDRESPONSE __TEXT("Control Panel\\Accessibility\\Keyboard Response")
#define PMAP_MOUSEKEYS __TEXT("Control Panel\\Accessibility\\MouseKeys")
#define PMAP_TOGGLEKEYS __TEXT("Control Panel\\Accessibility\\ToggleKeys")
#define PMAP_TIMEOUT __TEXT("Control Panel\\Accessibility\\TimeOut")
#define PMAP_SOUNDSENTRY __TEXT("Control Panel\\Accessibility\\SoundSentry")
#define PMAP_SHOWSOUNDS __TEXT("Control Panel\\Accessibility\\ShowSounds")
#define ISACCESSFLAGSET(s, flag) ((s).dwFlags & flag)
#define SK_SPI_INITUSER -1
typedef int (*PSKEY_SPI)(
UINT uAction,
UINT uParam,
LPSERIALKEYS lpvParam,
BOOL fuWinIni);
/***************************************************************************
* GetRegValue
*
* Passed the key, and the identifier, return the string data from the
* registry.
***************************************************************************/
long GetRegValue(LPTSTR RegKey, LPTSTR RegEntry, LPTSTR RegVal, long Size)
{
HKEY hReg; // Registry handle for schemes
DWORD Type; // Type of value
long retval;
retval = RegCreateKey(HKEY_CURRENT_USER, RegKey, &hReg);
if (retval != ERROR_SUCCESS)
return retval;
retval = RegQueryValueEx(hReg,
RegEntry,
NULL,
(LPDWORD)&Type,
(LPBYTE)RegVal,
&Size);
RegCloseKey(hReg);
return retval;
}
/***************************************************************************
* SetRegValue
*
* Passed the key, and the identifier, set the string data from the
* registry.
***************************************************************************/
long SetRegValue(LPTSTR RegKey, LPTSTR RegEntry, LPVOID RegVal, long Size, DWORD Type)
{
HKEY hReg; // Registry handle for schemes
DWORD Reserved = 0;
long retval;
if (RegCreateKey(HKEY_CURRENT_USER,RegKey, &hReg) != ERROR_SUCCESS)
return 0;
// A common error is to omit the `+1', so we just smash the correct
// value into place regardless.
if (Type == REG_SZ)
Size = (lstrlen(RegVal) + 1) * sizeof(TCHAR);
retval = RegSetValueEx(hReg,
RegEntry,
0,
Type,
RegVal,
Size);
RegCloseKey(hReg);
return retval;
}
/***************************************************************************
* DelRegValue
*
* Passed the key and the subkey, delete the subkey.
*
***************************************************************************/
long DelRegValue(LPTSTR RegKey, LPTSTR RegEntry)
{
HKEY hReg; // Registry handle for schemes
DWORD Reserved = 0;
long retval;
retval = RegCreateKey(HKEY_CURRENT_USER,RegKey, &hReg);
if (retval != ERROR_SUCCESS)
return retval;
retval = RegDeleteValue(hReg,
RegEntry);
RegCloseKey(hReg);
return retval;
}
/***************************************************************************
*
* GetCurrentSchemeName
*
* Input: szBuf -> Buffer to receive name of scheme (MAXSCHEMENAME)
* Output: None
*
* Returns the name of the current scheme. If the current scheme does not
* have a name, create one (ID_PRE_HC_SCHEME).
*
* If anything goes wrong, tough. What can you do?
*
***************************************************************************/
void NEAR PASCAL GetCurrentSchemeName(LPTSTR szBuf)
{
if (GetRegValue(DEFSCHEMEKEY, DEFSCHEMENAME, szBuf, MAXSCHEMENAME*sizeof(TCHAR)) !=
ERROR_SUCCESS) {
SCHEMEDATA scm;
int i;
/* Load the current scheme into scm */
scm.version = 1;
scm.ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS),
&scm.ncm,
0);
SystemParametersInfo(SPI_GETICONTITLELOGFONT,
sizeof(LOGFONT),
&scm.lfIconTitle,
0);
for (i = 0; i < COLOR_MAX; i++) {
scm.rgb[i] = GetSysColor(i);
}
/* Now give it a name */
SetRegValue(APPEARANCESCHEME, PRE_HC_SCHEME, &scm, sizeof(scm), REG_BINARY);
}
}
/***************************************************************************
*
*
* SetCurrentSchemeName
*
* Input: szName -> name of scheme to become current
* Output: Boolean success/failure
*
***************************************************************************/
typedef LONG (CALLBACK *APPLETPROC)(HWND, UINT, LPARAM, LPARAM);
typedef BOOL (CALLBACK *SETSCHEME)(LPCTSTR);
typedef BOOL (CALLBACK *SETSCHEMEA)(LPCSTR);
BOOL NEAR PASCAL SetCurrentSchemeName(LPCTSTR szName)
{
BOOL fRc = FALSE;
HINSTANCE hinst = LoadLibrary(__TEXT("DESK.CPL"));
if (NULL != hinst)
{
APPLETPROC ap = (APPLETPROC)GetProcAddress((HMODULE)hinst, "CPlApplet");
if (ap)
{
if (ap(0, CPL_INIT, 0, 0))
{
#ifdef UNICODE
SETSCHEME ss =
(SETSCHEME)GetProcAddress(hinst, "DeskSetCurrentSchemeW");
if (ss)
{
fRc = ss(szName);
}
else
{
SETSCHEMEA ssa =
(SETSCHEMEA)GetProcAddress(hinst, "DeskSetCurrentScheme");
if (ssa)
{
int cch = 0;
LPSTR pszName = NULL;
WideCharToMultiByte( CP_ACP, 0, szName, -1, pszName, cch, NULL, NULL);
if (0 != cch)
{
pszName = LocalAlloc(LMEM_FIXED, cch);
if (NULL != pszName)
{
WideCharToMultiByte(CP_ACP, 0, szName, -1, pszName, cch, NULL, NULL);
fRc = ssa(pszName);
LocalFree(pszName);
}
}
}
}
#else
SETSCHEME ss =
(SETSCHEME)GetProcAddress(hinst, "DeskSetCurrentScheme");
if (ss) {
fRc = ss(szName);
}
#endif
ap(0, CPL_EXIT, 0, 0);
}
}
FreeLibrary(hinst);
}
return fRc;
}
/***************************************************************************
*
*
* SetHighContrast
*
* Input: None
* Output: None
*
* Outline:
*
***************************************************************************/
short FAR PASCAL SetHighContrast(LPTSTR lpszScheme, BOOL fEnabledOld)
{
BOOL fOk = 0;
TCHAR szBuf[MAXSCHEMENAME];
szBuf[0] = '\0';
if (!fEnabledOld)
{
GetCurrentSchemeName(szBuf); /* Creates a name if necessary */
SetRegValue(HC_KEY, PRE_HC_SCHEME, szBuf, 0, REG_SZ); /* Save it */
}
if (NULL != lpszScheme && '\0' != *lpszScheme)
{
lstrcpy(szBuf, lpszScheme);
}
else
{
/*
* Get the name of the HC scheme. By stupid design, we have to look
* in about fifty places... We get the default one first, then try
* to get better and better ones. That way, when we're done, we have
* the best one that succeeded.
*/
lstrcpy(szBuf, WHITEBLACK_HC);
GetRegValue(HC_KEY, HIGHCONTRASTSCHEME, szBuf, sizeof(szBuf));
GetRegValue(DEFSCHEMEKEY, CURHCSCHEME, szBuf, sizeof(szBuf));
}
fOk = SetCurrentSchemeName(szBuf);
return (short)fOk;
}
/***************************************************************************
*
*
* ClearHighContrast
*
* Input: None
* Output: None
*
* Outline:
*
* If high contrast is currently on:
*
* Get the PRE_HC_SCHEME.
*
* If able to get it:
*
* Make it the current scheme.
*
* If the name is IDS_PRE_HC_SCHEME, then delete the scheme
* data and set the current scheme name to null. (Clean up.)
*
* End if
*
* Set the key that says that high contrast is now off.
*
* End if
*
***************************************************************************/
BOOL FAR PASCAL ClearHighContrast(BOOL fEnabledOld)
{
BOOL fOk = FALSE;
TCHAR szBuf[MAXSCHEMENAME];
TCHAR szPreHc[MAXSCHEMENAME];
szBuf[0] = '\0';
if (fEnabledOld) { /* Currently on */
if (ERROR_SUCCESS ==
GetRegValue(HC_KEY, PRE_HC_SCHEME, szBuf, sizeof(szBuf)) ) {
fOk = SetCurrentSchemeName(szBuf);
if (lstrcmpi(szBuf, PRE_HC_SCHEME) == 0) {
DelRegValue(APPEARANCESCHEME, szPreHc);
DelRegValue(DEFSCHEMEKEY, DEFSCHEMENAME);
}
}
}
return fOk;
}
BOOL FAR PASCAL DoHighContrast(LPHIGHCONTRAST phc)
{
BOOL fRc = 0;
DWORD dwType;
long lRet;
HKEY hkey;
DWORD dwDisposition;
DWORD dwFlagsOld = 0;
DWORD cbData;
TCHAR szOldScheme[MAXSCHEMENAME];
lRet = RegCreateKeyEx(
HKEY_CURRENT_USER, // handle of an open key
HC_KEY, // address of subkey name
0, // reserved
NULL, // address of class string
0, // special options flag
KEY_READ | KEY_WRITE, // desired security access
NULL, // address of key security structure
&hkey, // address of buffer for opened handle
&dwDisposition); // address of disposition value buffer
if (ERROR_SUCCESS == lRet) {
cbData = sizeof(szOldScheme);
RegQueryValueEx(
hkey,
HIGHCONTRAST_SCHEME,
NULL,
&dwType,
(PBYTE)szOldScheme,
&cbData);
dwFlagsOld = RegQueryStrDW(
0,
HKEY_CURRENT_USER,
HC_KEY,
REGSTR_VAL_FLAGS);
if (phc->dwFlags & HCF_HIGHCONTRASTON) {
fRc = SetHighContrast(
phc->lpszDefaultScheme,
(dwFlagsOld & HCF_HIGHCONTRASTON));
}
else
{
fRc = ClearHighContrast(dwFlagsOld & HCF_HIGHCONTRASTON);
}
if (fRc) {
RegSetStrDW(
HKEY_CURRENT_USER,
HC_KEY,
REGSTR_VAL_FLAGS,
phc->dwFlags);
}
RegCloseKey(hkey);
}
return fRc;
}
/****************************************************************************/
BOOL AccessSKeySystemParametersInfo(
UINT uAction,
UINT uParam,
LPSERIALKEYS psk,
BOOL fu)
{
BOOL fRet = FALSE;
static PSKEY_SPI s_pSKEY_SystemParametersInfo =NULL;
static BOOL s_fSKeySPIAttemptedLoad = FALSE;
#ifdef UNICODE
static BOOL s_fMustConvert = FALSE;
CHAR szActivePort[MAX_PATH];
CHAR szPort[MAX_PATH];
PWSTR pszActivePort;
PWSTR pszPort;
#endif
if (NULL == s_pSKEY_SystemParametersInfo && !s_fSKeySPIAttemptedLoad)
{
BOOL fRc = FALSE;
HINSTANCE hinst = LoadLibrary(__TEXT("SKDLL.DLL"));
if (NULL != hinst)
{
#ifdef UNICODE
s_pSKEY_SystemParametersInfo = (PSKEY_SPI)GetProcAddress(
(HMODULE)hinst, "SKEY_SystemParametersInfoW");
if (NULL == s_pSKEY_SystemParametersInfo)
{
s_pSKEY_SystemParametersInfo = (PSKEY_SPI)GetProcAddress(
(HMODULE)hinst, "SKEY_SystemParametersInfo");
s_fMustConvert = TRUE;
}
#else
s_pSKEY_SystemParametersInfo = (PSKEY_SPI)GetProcAddress(
(HMODULE)hinst, "SKEY_SystemParametersInfo");
#endif // UNICODE
// We don't bother calling FreeLibrary(hinst), the library will be freed
// when the app terminates
}
s_fSKeySPIAttemptedLoad = TRUE;
}
if (NULL != s_pSKEY_SystemParametersInfo)
{
#ifdef UNICODE
if (s_fMustConvert)
{
memset(szActivePort, 0, sizeof(szActivePort));
memset(szPort, 0, sizeof(szPort));
pszActivePort = psk->lpszActivePort;
pszPort = psk->lpszPort;
if (NULL != psk->lpszActivePort)
{
psk->lpszActivePort = (PTSTR)szActivePort;
}
if (NULL != psk->lpszPort)
{
psk->lpszPort = (PTSTR)szPort;
}
if (SPI_SETSERIALKEYS == uAction)
{
if (NULL != psk->lpszActivePort)
{
WideCharToMultiByte(
CP_ACP, 0, pszActivePort, -1,
(PCHAR)psk->lpszActivePort, MAX_PATH, NULL, NULL);
}
if (NULL != psk->lpszPort)
{
WideCharToMultiByte(
CP_ACP, 0, pszPort, -1,
(PCHAR)psk->lpszPort, MAX_PATH, NULL, NULL);
}
}
}
#endif // UNICODE
fRet = (BOOL)(*s_pSKEY_SystemParametersInfo)(
uAction,
uParam,
psk,
fu);
#ifdef UNICODE
if (s_fMustConvert && SPI_GETSERIALKEYS == uAction)
{
if (NULL != psk->lpszActivePort)
{
MultiByteToWideChar(
CP_ACP, 0, (PCHAR)psk->lpszActivePort, -1,
pszActivePort, MAX_PATH);
}
if (NULL != psk->lpszPort)
{
MultiByteToWideChar(
CP_ACP, 0, (PCHAR)psk->lpszPort, -1,
pszPort, MAX_PATH);
}
}
if (NULL != psk->lpszActivePort)
{
psk->lpszActivePort = pszActivePort;
}
if (NULL != psk->lpszPort)
{
psk->lpszPort = pszPort;
}
#endif // UNICODE
}
return(fRet);
}
/***************************************************************************\
* FixupAndRetrySystemParametersInfo
*
* Used by access but not implemented by NT's SPI:
*
* SPI_GETKEYBOARDPREF
* SPI_SETKEYBOARDPREF
*
* SPI_GETHIGHCONTRAST
* SPI_SETHIGHCONTRAST
*
* SPI_GETSERIALKEYS
* SPI_SETSERIALKEYS
*
*
* History:
* 12-18-95 a-jimhar Created, derived from xxxSystemParametersInfo
* 01-22-95 a-jimhar Removed old code that worked around NT bugs
*
* On NT this function fixes the parameters and calls SystemParametersInfo
*
\***************************************************************************/
static BOOL FixupAndRetrySystemParametersInfo(
UINT wFlag,
DWORD wParam,
PVOID lParam,
UINT flags) // we ignoring this flag
// could add support for SPIF_UPDATEINIFILE and SPIF_SENDCHANGE
{
BOOL fRet = FALSE;
BOOL fCallSpi = FALSE;
BOOL fChanged = FALSE;
if (NULL != (PVOID)lParam)
{
switch (wFlag) {
// Fake support
case SPI_GETKEYBOARDPREF:
{
*(PBOOL) lParam = FALSE;
fRet = TRUE;
fCallSpi = FALSE;
}
break;
#ifdef ENABLEHIGHCONTRAST //// bugbug a-jimhar remove this ifdef when ready to enable highcontrast ////
case SPI_GETHIGHCONTRAST:
{
LPHIGHCONTRAST phc = (LPHIGHCONTRAST)lParam;
static TCHAR szCurScheme[MAXSCHEMENAME]; // current scheme name
if (NULL != phc &&
(sizeof(*phc) == phc->cbSize || 0 == phc->cbSize))
{
DWORD dwType;
long lRet;
HKEY hkey;
DWORD dwDisposition;
lRet = RegCreateKeyEx(
HKEY_CURRENT_USER, // handle of an open key
HC_KEY, // address of subkey name
0, // reserved
NULL, // address of class string
0, // special options flag
KEY_READ, // desired security access
NULL, // address of key security structure
&hkey, // address of buffer for opened handle
&dwDisposition); // address of disposition value buffer
if (ERROR_SUCCESS == lRet) {
DWORD cbData;
cbData = sizeof(szCurScheme);
RegQueryValueEx(
hkey,
HIGHCONTRAST_SCHEME,
NULL,
&dwType,
(PBYTE)szCurScheme,
&cbData);
phc->lpszDefaultScheme = szCurScheme;
cbData = sizeof(phc->dwFlags);
phc->dwFlags = RegQueryStrDW(
0,
HKEY_CURRENT_USER,
HC_KEY,
REGSTR_VAL_FLAGS);
phc->dwFlags |= HCF_AVAILABLE;
RegCloseKey(hkey);
}
}
fCallSpi = FALSE;
}
break;
case SPI_SETHIGHCONTRAST:
{
LPHIGHCONTRAST phc = (LPHIGHCONTRAST)lParam;
if (NULL != phc &&
(sizeof(*phc) == phc->cbSize || 0 == phc->cbSize))
{
DoHighContrast(phc);
fChanged = TRUE;
}
fCallSpi = FALSE;
}
break;
#endif ////////////////////////////////////////////////////////////////////////
case SPI_GETSERIALKEYS:
{
LPSERIALKEYS psk = (LPSERIALKEYS)lParam;
if (NULL != psk &&
(sizeof(*psk) == psk->cbSize || 0 == psk->cbSize))
{
fRet = AccessSKeySystemParametersInfo(
wFlag,
0,
psk,
TRUE);
}
fCallSpi = FALSE;
}
break;
case SPI_SETSERIALKEYS:
{
LPSERIALKEYS psk = (LPSERIALKEYS)lParam;
if (NULL != psk &&
(sizeof(*psk) == psk->cbSize || 0 == psk->cbSize))
{
fRet = AccessSKeySystemParametersInfo(
wFlag,
0,
psk,
TRUE);
fChanged = TRUE;
}
fCallSpi = FALSE;
}
break;
default:
// This function is only for fix-up and second chance calls.
// We didn't fix anything, don't call SPI.
fCallSpi = FALSE;
fRet = FALSE;
break;
}
}
if (fCallSpi)
{
fRet = SystemParametersInfo(wFlag, wParam, lParam, flags);
}
else if (fChanged && (flags & SPIF_SENDCHANGE))
{
DWORD dwResult;
SendMessageTimeout(
HWND_BROADCAST,
WM_WININICHANGE,
wFlag,
(LONG)NULL,
SMTO_NORMAL,
100,
&dwResult);
}
return(fRet);
}
/***************************************************************************\
* AccessSystemParametersInfo
*
* History:
* 12-18-95 a-jimhar Created.
\***************************************************************************/
BOOL AccessSystemParametersInfo(
UINT wFlag,
DWORD wParam,
PVOID lParam,
UINT flags)
{
BOOL fRet;
// first give the system SPI a chance
fRet = SystemParametersInfo(wFlag, wParam, lParam, flags);
if (!fRet && g_fWinNT)
{
// the system SPI failed, fixup the params and try again
fRet = FixupAndRetrySystemParametersInfo(wFlag, wParam, lParam, flags);
}
return(fRet);
}