2244 lines
77 KiB
Plaintext
2244 lines
77 KiB
Plaintext
/*
|
|
* Registry Management
|
|
*
|
|
* HTREGMNG.C
|
|
*
|
|
* Copyright (c) 1995 Microsoft Corporation
|
|
*
|
|
*/
|
|
|
|
#include "priv.h"
|
|
#include "htregmng.h"
|
|
|
|
// This file contains the auto-registration code, which smartly performs
|
|
// the install/uninstall of registry keys and values. While an inf file
|
|
// is sufficient most of the time, IE needs to be smart about what
|
|
// sort of values to set, based upon certain conditions. An inf file
|
|
// does not offer this depth of support. Additionally, IE requires
|
|
// code to be run when it detects that it is not the default browser,
|
|
// so it can make it the default browser. Any settings that determine
|
|
// this should be placed here, rather than the inf file.
|
|
//
|
|
// This code is table driven. The idea is simple. You have a RegSet
|
|
// which is the "Registry Set". The Registry Set indicates the
|
|
// root key and contains a list of RegEntries. Each RegEntry
|
|
// specifies a command, flags, key and value names, and optional data
|
|
// that provides the essential info to set/change/delete a registry
|
|
// value or key.
|
|
//
|
|
//
|
|
|
|
// Make the tables more compact
|
|
#define HKCR HKEY_CLASSES_ROOT
|
|
#define HKLM HKEY_LOCAL_MACHINE
|
|
#define HKCU HKEY_CURRENT_USER
|
|
|
|
BOOL InstallRegSet(const RegSet *prs, BOOL bDontIntrude);
|
|
|
|
const CHAR c_szIexploreKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE";
|
|
|
|
#ifdef DEBUG
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Return a string path composed of hkey\pszKey\pszValueName.
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
LPTSTR
|
|
Dbg_RegStr(
|
|
IN const RegEntry * pre,
|
|
IN LPTSTR pszBuf)
|
|
{
|
|
TCHAR szRoot[5];
|
|
|
|
ASSERT(pre);
|
|
ASSERT(pszBuf);
|
|
|
|
if (HKEY_CLASSES_ROOT == pre->hkeyRoot)
|
|
{
|
|
lstrcpy(szRoot, TEXT("HKCR"));
|
|
}
|
|
else if (HKEY_CURRENT_USER == pre->hkeyRoot)
|
|
{
|
|
lstrcpy(szRoot, TEXT("HKCU"));
|
|
}
|
|
else if (HKEY_LOCAL_MACHINE == pre->hkeyRoot)
|
|
{
|
|
lstrcpy(szRoot, TEXT("HKLM"));
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(szRoot, TEXT("????"));
|
|
ASSERT(0);
|
|
}
|
|
|
|
wsprintf(pszBuf, TEXT("%s\\%hs\\%hs"), szRoot, pre->pszKey, pre->pszValName);
|
|
|
|
return pszBuf;
|
|
}
|
|
|
|
#else
|
|
|
|
#define Dbg_RegStr(x, y) 0
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Queries the registry for the location of the path
|
|
of Internet Explorer and returns it in pszBuf.
|
|
|
|
Returns: TRUE on success
|
|
FALSE if path cannot be determined
|
|
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
GetIEPath(
|
|
OUT LPSTR pszBuf,
|
|
IN DWORD cchBuf)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
HKEY hkey;
|
|
|
|
*pszBuf = '\0';
|
|
|
|
// Get the path of Internet Explorer
|
|
if (NO_ERROR != RegOpenKey(HKEY_LOCAL_MACHINE, c_szIexploreKey, &hkey))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): RegOpenKey( %s ) Failed", c_szIexploreKey) ;
|
|
}
|
|
else
|
|
{
|
|
DWORD cbBrowser;
|
|
DWORD dwType;
|
|
|
|
lstrcatA(pszBuf, "\"");
|
|
|
|
cbBrowser = CbFromCchA(cchBuf - lstrlen(" -nohome") - 4);
|
|
if (NO_ERROR != RegQueryValueExA(hkey, "", NULL, &dwType,
|
|
(LPBYTE)&pszBuf[1], &cbBrowser))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): RegQueryValueEx() for Iexplore path failed");
|
|
}
|
|
else
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
lstrcatA(pszBuf, "\"");
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Queries the registry for the location of the path
|
|
of the shell's Explorer and returns it in pszBuf.
|
|
|
|
Returns: TRUE on success
|
|
FALSE if path cannot be determined
|
|
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
GetExplorerPath(
|
|
OUT LPSTR pszBuf,
|
|
IN DWORD cchBuf)
|
|
{
|
|
BOOL bRet;
|
|
|
|
// Get the path of the Explorer
|
|
if (g_fRunningOnNT)
|
|
{
|
|
lstrcpyA (pszBuf, "%SystemRoot%");
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
bRet = (0 < GetWindowsDirectoryA(pszBuf, cchBuf));
|
|
if (bRet)
|
|
{
|
|
lstrcatA(pszBuf, "\\Explorer.exe");
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
// Callback messages
|
|
|
|
#define RSCB_QUERY 1
|
|
#define RSCB_INSTALL 2
|
|
|
|
typedef BOOL (CALLBACK* RSPECPROC)(UINT nMsg, const RegEntry * pre, LPVOID pvData, DWORD dwData);
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: This callback sets the default icon to point to a
|
|
given index in url.dll.
|
|
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
CALLBACK
|
|
HTReg_UrlIconProc(
|
|
IN UINT nMsg,
|
|
IN const RegEntry * pre,
|
|
IN LPVOID pvData, OPTIONAL
|
|
IN DWORD dwData)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
CHAR sz[MAX_PATH + 20]; // Need a bit extra
|
|
LPCSTR pszPath = pvData;
|
|
int cch;
|
|
DWORD dwType; //local type.
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
ASSERT(RSCB_QUERY == nMsg && pvData ||
|
|
RSCB_INSTALL == nMsg && !pvData);
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
if (g_fRunningOnNT)
|
|
lstrcpyA (sz, "%SystemRoot%\\system32");
|
|
else
|
|
GetSystemDirectoryA(sz, SIZECHARS(sz));
|
|
cch = lstrlenA(sz);
|
|
wsprintfA(&sz[cch], "\\URL.DLL,%u", (UINT)pre->lParam);
|
|
|
|
if (0 != lstrnicmpA(sz, pszPath, dwData / SIZEOF(CHAR)) &&
|
|
0 != lstrcmpiA(PathFindFileNameA(sz), PathFindFileNameA(pszPath)))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s is %hs, expecting %hs", Dbg_RegStr(pre, szDbg), pszPath, sz);
|
|
bRet = FALSE;
|
|
}
|
|
break;
|
|
|
|
case RSCB_INSTALL:
|
|
ASSERT(REG_SZ == pre->dwType);
|
|
|
|
if (g_fRunningOnNT)
|
|
lstrcpyA (sz, "%SystemRoot%\\system32");
|
|
else
|
|
GetSystemDirectoryA(sz, SIZECHARS(sz));
|
|
cch = lstrlenA(sz);
|
|
wsprintfA(&sz[cch], "\\URL.DLL,%u", (UINT)pre->lParam);
|
|
|
|
dwType = g_fRunningOnNT ? REG_EXPAND_SZ : (DWORD)pre->dwType;
|
|
if (NO_ERROR != SHSetValueA(pre->hkeyRoot, pre->pszKey,
|
|
pre->pszValName, dwType,
|
|
sz, CbFromCchA(lstrlenA(sz) + 1)))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): SHSetValue(%s) Failed", Dbg_RegStr(pre, szDbg));
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
|
|
}
|
|
break;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: This callback sets the IExplore path.
|
|
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
CALLBACK
|
|
HTReg_IEPathProc(
|
|
IN UINT nMsg,
|
|
IN const RegEntry * pre,
|
|
IN LPVOID pvData, OPTIONAL
|
|
IN DWORD dwData)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
CHAR sz[MAX_PATH + 20]; // Need a bit extra
|
|
LPCSTR pszPath = pvData;
|
|
int cch;
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
ASSERT(RSCB_QUERY == nMsg && pvData ||
|
|
RSCB_INSTALL == nMsg && !pvData);
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
if (GetIEPath(sz, SIZECHARS(sz)))
|
|
{
|
|
cch = lstrlenA(sz) - 1;
|
|
|
|
if (*sz && sz[cch] == ';')
|
|
sz[cch] = '\0';
|
|
|
|
if (pre->lParam)
|
|
lstrcatA(sz, (LPSTR)pre->lParam);
|
|
|
|
if (0 != lstrnicmpA(pszPath, sz, dwData / SIZEOF(CHAR)))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s string is \"%hs\", expecting \"%hs\"", Dbg_RegStr(pre, szDbg), pszPath, sz);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RSCB_INSTALL:
|
|
if (GetIEPath(sz, SIZECHARS(sz)))
|
|
{
|
|
DWORD dwType;
|
|
cch = lstrlenA(sz) - 1;
|
|
|
|
if (*sz && sz[cch] == ';')
|
|
sz[cch] = '\0';
|
|
|
|
if (pre->lParam)
|
|
lstrcatA(sz, (LPTSTR)pre->lParam);
|
|
|
|
ASSERT(REG_SZ == pre->dwType);
|
|
|
|
dwType = g_fRunningOnNT ? REG_EXPAND_SZ : (DWORD)pre->dwType;
|
|
if (NO_ERROR != SHSetValueA(pre->hkeyRoot, pre->pszKey,
|
|
pre->pszValName, dwType,
|
|
sz, CbFromCchA(lstrlenA(sz) + 1)))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): SHSetValue(%hs) Failed", pre->pszValName);
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: This callback sets the Explorer path.
|
|
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
CALLBACK
|
|
HTReg_ShellPathProc(
|
|
IN UINT nMsg,
|
|
IN const RegEntry * pre,
|
|
IN LPVOID pvData, OPTIONAL
|
|
IN DWORD dwData)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
CHAR sz[MAX_PATH + 20]; // Need a bit extra
|
|
LPCSTR pszPath = pvData;
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
ASSERT(RSCB_QUERY == nMsg && pvData ||
|
|
RSCB_INSTALL == nMsg && !pvData);
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
if (GetExplorerPath(sz, SIZECHARS(sz)))
|
|
{
|
|
if (pre->lParam)
|
|
lstrcatA(sz, (LPSTR)pre->lParam);
|
|
|
|
if (0 != lstrnicmpA(pszPath, sz, dwData / SIZEOF(CHAR)))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s string is \"%hs\", expecting \"%hs\"", Dbg_RegStr(pre, szDbg), pszPath, sz);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RSCB_INSTALL:
|
|
if (GetExplorerPath(sz, SIZECHARS(sz)))
|
|
{
|
|
DWORD dwType;
|
|
if (pre->lParam)
|
|
lstrcatA(sz, (LPTSTR)pre->lParam);
|
|
|
|
ASSERT(REG_SZ == pre->dwType);
|
|
|
|
dwType = g_fRunningOnNT ? REG_EXPAND_SZ : (DWORD)pre->dwType;
|
|
if (NO_ERROR != SHSetValueA(pre->hkeyRoot, pre->pszKey,
|
|
pre->pszValName, dwType,
|
|
sz, CbFromCchA(lstrlenA(sz) + 1)))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): SHSetValue(%hs) Failed", pre->pszValName);
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: This callback checks for the existence of the string
|
|
value "Exchange" at HKLM\Software\Microsoft. If it
|
|
exists, the value is copied into the default value
|
|
of HKLM\Software\Clients\Mail\Exchange\shell\open\command.
|
|
|
|
This is for Athena. It only happens when setup is run,
|
|
not when the browser checks to see if it is the default.
|
|
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
CALLBACK
|
|
HTReg_ExchangeProc(
|
|
IN UINT nMsg,
|
|
IN const RegEntry * pre,
|
|
IN LPVOID pvData,
|
|
IN DWORD dwData)
|
|
{
|
|
TCHAR sz[MAX_PATH+2]; // +2 because we may need to wrap the path in quotes.
|
|
DWORD cbSize;
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
// We shouldn't be called for this one
|
|
ASSERT(0);
|
|
break;
|
|
|
|
case RSCB_INSTALL:
|
|
// Does the Exchange value exist at "HKLM\Software\Microsoft"?
|
|
cbSize = sizeof(sz);
|
|
if (NO_ERROR == SHGetValue(HKEY_LOCAL_MACHINE,
|
|
TEXT("Software\\Microsoft"), TEXT("Exchange"), NULL, sz, &cbSize))
|
|
{
|
|
// Yes; copy it to HKLM\Software\Clients\Mail\Exchange\shell\open\command
|
|
TCHAR szT[MAX_PATH+2];
|
|
|
|
// Wrap the path in quotes. Don't wrap any args though!
|
|
lstrcpy(szT, sz);
|
|
PathProcessCommand(szT, sz, ARRAYSIZE(szT), PPCF_ADDQUOTES|PPCF_ADDARGUMENTS);
|
|
|
|
// Set the size again
|
|
cbSize = CbFromCch(lstrlen(sz)+1);
|
|
|
|
SHSetValue(HKEY_LOCAL_MACHINE,
|
|
TEXT("Software\\Clients\\Mail\\Exchange\\shell\\open\\command"),
|
|
TEXT(""), REG_SZ, sz, cbSize);
|
|
|
|
TraceMsg(TF_REGCHECK, "Copying \"%s\" to HKLM\\Software\\Clients\\Mail\\Exchange", sz);
|
|
|
|
// Set any other settings in this condition too?
|
|
if (pre->lParam)
|
|
InstallRegSet((const RegSet *)pre->lParam, TRUE);
|
|
|
|
// In OSR2 installs, the mailto handler will get out of
|
|
// sync with the actual default mail client. (Athena installs
|
|
// itself as the default mail client, but exchange remains
|
|
// the mailto: handler.) In this case, if exchange is the
|
|
// mailto: handler, change the default mail client to be
|
|
// exchange.
|
|
|
|
// Is Exchange the mailto handler?
|
|
cbSize = SIZEOF(sz);
|
|
if (NO_ERROR == SHGetValue(HKEY_CLASSES_ROOT, TEXT("mailto\\shell\\open\\command"),
|
|
TEXT(""), NULL, sz, &cbSize) &&
|
|
StrStrI(sz, TEXT("url.dll,MailToProtocolHandler")))
|
|
{
|
|
// Yes; make it be the default mail client too
|
|
SHSetValue(HKEY_LOCAL_MACHINE, TEXT("Software\\Clients\\Mail"),
|
|
TEXT(""), REG_SZ, TEXT("Exchange"), sizeof(TEXT("Exchange")));
|
|
|
|
TraceMsg(TF_REGCHECK, "Setting Exchange to be the default mail client.");
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Uninstall certain keys, as specified by pre->pszKey.
|
|
|
|
We do not uninstall a key if the class\shell\open\command
|
|
does not have iexplore.exe.
|
|
|
|
If someone else registered themselves to add more
|
|
verbs under class\shell (other than open) or class\shellex,
|
|
then we remove everything but their keys.
|
|
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
CALLBACK
|
|
HTReg_UninstallProc(
|
|
IN UINT nMsg,
|
|
IN const RegEntry * pre,
|
|
IN LPVOID pvData,
|
|
IN DWORD dwData)
|
|
{
|
|
TCHAR szKey[MAX_PATH];
|
|
TCHAR sz[MAX_PATH + 20]; // add some padding for arguments
|
|
DWORD cbSize;
|
|
LPCTSTR pszExe;
|
|
|
|
// HACKHACK: we overload dwType to indicate the platform that
|
|
// we are uninstalling.
|
|
if (PLATFORM_NASH == pre->dwType)
|
|
pszExe = TEXT("explorer.exe");
|
|
else
|
|
pszExe = TEXT("iexplore.exe");
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
// We shouldn't be called for this one
|
|
ASSERT(0);
|
|
break;
|
|
|
|
case RSCB_INSTALL:
|
|
ASSERT(pre->pszKey);
|
|
|
|
// Does the shell\open\command value have "iexplore.exe"?
|
|
wsprintf(szKey, TEXT("%hs\\shell\\open\\command"), pre->pszKey);
|
|
|
|
cbSize = sizeof(sz);
|
|
if (NO_ERROR == SHGetValue(pre->hkeyRoot, szKey, TEXT(""),
|
|
NULL, sz, &cbSize) &&
|
|
StrStrI(sz, pszExe))
|
|
{
|
|
// Yes; proceed to prune this key of all of our values
|
|
TraceMsg(TF_REGCHECK, "Pruning HKCR\\%hs", pre->pszKey);
|
|
|
|
ASSERT(pre->lParam);
|
|
|
|
InstallRegSet((const RegSet *)pre->lParam, FALSE);
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// NOTE: these are ANSI strings by design.
|
|
|
|
const INT vEditFlags2 = 0x02;
|
|
const INT vEditFlagsSafe = 0x010002;
|
|
const DWORD c_dwFaveAttr = 0xe0000000;
|
|
const CHAR c_szTelnetHandler[] = "url.dll,TelnetProtocolHandler %l";
|
|
const CHAR c_szMailToHandler[] = "url.dll,MailToProtocolHandler %l";
|
|
const CHAR c_szNewsHandler[] = "url.dll,NewsProtocolHandler %l";
|
|
const CHAR c_szFileHandler[] = "url.dll,FileProtocolHandler %l";
|
|
const CHAR c_szOpenURL[] = "url.dll,OpenURL %l";
|
|
const CHAR c_szOpenURLNash[] = "shell32.dll,OpenURL %l";
|
|
const CHAR c_szURL[] = "url.dll";
|
|
const CHAR c_szShell32[] = "shell32.dll";
|
|
const CHAR c_szAlphaNashOnDesktop[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\{3DC7A020-0ACD-11CF-A9BB-00AA004AE837}";
|
|
const CHAR c_szCheckAssnSwitch[] = "Software\\Microsoft\\Internet Explorer\\Main";
|
|
const CHAR c_szDDE_Default[] = "\"%1\",,-1,,,,,";
|
|
const CHAR c_szDDE_FileDefault[] = "\"file:%1\",,-1,,,,,";
|
|
const CHAR c_szViewFolderTemp[] = "[ViewFolder(\"%l\",\"%l\",%S)]";
|
|
const CHAR c_szExploreFolderTemp[] = "[ExploreFolder(\"%l\",\"%l\",%S)]";
|
|
const CHAR c_szViewAppendage[] = " /idlist,%l,%L";
|
|
const CHAR c_szExploreAppendage[] = " /e,/idlist,%l,%L";
|
|
|
|
|
|
// BUGBUG (scotth): a lot of the strings below have substrings that
|
|
// are repeated over and over and over again. Should add some
|
|
// smarter RC_ values that will concatenate the common strings
|
|
// together to save data space.
|
|
|
|
const CHAR c_szHTTP[] = "http";
|
|
const CHAR c_szHTTPDefIcon[] = "http\\DefaultIcon";
|
|
const CHAR c_szHTTPOpenCmd[] = "http\\shell\\open\\command";
|
|
const CHAR c_szHTTPDdeexec[] = "http\\shell\\open\\ddeexec";
|
|
const CHAR c_szHTTPDdeTopic[] = "http\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szHTTPDdeIfExec[] = "http\\shell\\open\\ddeexec\\IfExec";
|
|
const CHAR c_szHTTPDdeApp[] = "http\\shell\\open\\ddeexec\\Application";
|
|
|
|
const CHAR c_szHTTPS[] = "https";
|
|
const CHAR c_szHTTPSDefIcon[] = "https\\DefaultIcon";
|
|
const CHAR c_szHTTPSOpenCmd[] = "https\\shell\\open\\command";
|
|
const CHAR c_szHTTPSDdeexec[] = "https\\shell\\open\\ddeexec";
|
|
const CHAR c_szHTTPSDdeTopic[] = "https\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szHTTPSDdeIfExec[] = "https\\shell\\open\\ddeexec\\IfExec";
|
|
const CHAR c_szHTTPSDdeApp[] = "https\\shell\\open\\ddeexec\\Application";
|
|
|
|
const CHAR c_szFTP[] = "ftp";
|
|
const CHAR c_szFTPDefIcon[] = "ftp\\DefaultIcon";
|
|
const CHAR c_szFTPOpenCmd[] = "ftp\\shell\\open\\command";
|
|
const CHAR c_szFTPDdeexec[] = "ftp\\shell\\open\\ddeexec";
|
|
const CHAR c_szFTPDdeTopic[] = "ftp\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szFTPDdeIfExec[] = "ftp\\shell\\open\\ddeexec\\IfExec";
|
|
const CHAR c_szFTPDdeApp[] = "ftp\\shell\\open\\ddeexec\\Application";
|
|
|
|
const CHAR c_szGOPHER[] = "gopher";
|
|
const CHAR c_szGOPHERDefIcon[] = "gopher\\DefaultIcon";
|
|
const CHAR c_szGOPHEROpenCmd[] = "gopher\\shell\\open\\command";
|
|
const CHAR c_szGOPHERDdeexec[] = "gopher\\shell\\open\\ddeexec";
|
|
const CHAR c_szGOPHERDdeTopic[] = "gopher\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szGOPHERDdeIfExec[] = "gopher\\shell\\open\\ddeexec\\IfExec";
|
|
const CHAR c_szGOPHERDdeApp[] = "gopher\\shell\\open\\ddeexec\\Application";
|
|
|
|
const CHAR c_szMailTo[] = "mailto";
|
|
const CHAR c_szMailToDefIcon[] = "mailto\\DefaultIcon";
|
|
const CHAR c_szMailToOpenCmd[] = "mailto\\shell\\open\\command";
|
|
|
|
const CHAR c_szTelnet[] = "telnet";
|
|
const CHAR c_szTelnetDefIcon[] = "telnet\\DefaultIcon";
|
|
const CHAR c_szTelnetOpenCmd[] = "telnet\\shell\\open\\command";
|
|
|
|
const CHAR c_szRLogin[] = "rlogin";
|
|
const CHAR c_szRLoginDefIcon[] = "rlogin\\DefaultIcon";
|
|
const CHAR c_szRLoginOpenCmd[] = "rlogin\\shell\\open\\command";
|
|
|
|
const CHAR c_szTN3270[] = "tn3270";
|
|
const CHAR c_szTN3270DefIcon[] = "tn3270\\DefaultIcon";
|
|
const CHAR c_szTN3270OpenCmd[] = "tn3270\\shell\\open\\command";
|
|
|
|
const CHAR c_szNews[] = "news";
|
|
const CHAR c_szNewsDefIcon[] = "news\\DefaultIcon";
|
|
const CHAR c_szNewsOpenCmd[] = "news\\shell\\open\\command";
|
|
|
|
const CHAR c_szFile[] = "file";
|
|
const CHAR c_szFileDefIcon[] = "file\\DefaultIcon";
|
|
const CHAR c_szFileOpenCmd[] = "file\\shell\\open\\command";
|
|
const CHAR c_szFileDdeexec[] = "file\\shell\\open\\ddeexec";
|
|
const CHAR c_szFileDdeTopic[] = "file\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szFileDdeIfExec[] = "file\\shell\\open\\ddeexec\\IfExec";
|
|
const CHAR c_szFileDdeApp[] = "file\\shell\\open\\ddeexec\\Application";
|
|
|
|
const CHAR c_szHTMOpenCmd[] = "htmlfile\\shell\\open\\command";
|
|
const CHAR c_szHTMDdeexec[] = "htmlfile\\shell\\open\\ddeexec";
|
|
const CHAR c_szHTMDdeTopic[] = "htmlfile\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szHTMDdeIfExec[] = "htmlfile\\shell\\open\\ddeexec\\IfExec";
|
|
const CHAR c_szHTMDdeApp[] = "htmlfile\\shell\\open\\ddeexec\\Application";
|
|
const CHAR c_szHTMExploreCmd[] = "htmlfile\\shell\\explore\\command";
|
|
const CHAR c_szHTMExploreDdeexec[] = "htmlfile\\shell\\explore\\ddeexec";
|
|
const CHAR c_szHTMExploreDdeTopic[] = "htmlfile\\shell\\explore\\ddeexec\\Topic";
|
|
const CHAR c_szHTMExploreDdeIfExec[] = "htmlfile\\shell\\explore\\ddeexec\\IfExec";
|
|
const CHAR c_szHTMExploreDdeApp[] = "htmlfile\\shell\\explore\\ddeexec\\Application";
|
|
|
|
const CHAR c_szIntShcut[] = "InternetShortcut";
|
|
const CHAR c_szIntShcutDefIcon[] = "InternetShortcut\\DefaultIcon";
|
|
const CHAR c_szIntShcutCLSID[] = "InternetShortcut\\CLSID";
|
|
const CHAR c_szIntShcutOpen[] = "InternetShortcut\\shell\\open";
|
|
const CHAR c_szIntShcutOpenCmd[] = "InternetShortcut\\shell\\open\\command";
|
|
const CHAR c_szIntShcutIconHandler[] = "InternetShortcut\\shellex\\IconHandler";
|
|
const CHAR c_szIntShcutPrshtHandler[]= "InternetShortcut\\shellex\\PropertySheetHandlers\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}";
|
|
const CHAR c_szIntShcutPropHandler[] = "InternetShortcut\\shellex\\PropertyHandler";
|
|
const CHAR c_szIntShcutCMHandler[] = "InternetShortcut\\shellex\\ContextMenuHandlers\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}";
|
|
|
|
const CHAR c_szCLSIDIntshcut[] = "{FBF23B40-E3F0-101B-8488-00AA003E56F8}";
|
|
|
|
const CHAR c_szIntshcutInproc[] = "CLSID\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}\\InProcServer32";
|
|
const CHAR c_szIEFrameAuto[] = "CLSID\\{0002DF01-0000-0000-C000-000000000046}\\LocalServer32";
|
|
const CHAR c_szIENameSpaceOpen[] = "CLSID\\{FBF23B42-E3F0-101B-8488-00AA003E56F8}\\shell\\open\\command";
|
|
const CHAR c_szCLSIDURLRoot[] = "CLSID\\{3DC7A020-0ACD-11CF-A9BB-00AA004AE837}";
|
|
const CHAR c_szIntshcutMayChange[] = "CLSID\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}\\shellex\\MayChangeDefaultMenu";
|
|
const CHAR c_szFaveShellFolder[] = "CLSID\\{1A9BA3A0-143A-11CF-8350-444553540000}\\ShellFolder";
|
|
|
|
|
|
//
|
|
// General associations shared across IE 3.0 and 4.0
|
|
//
|
|
|
|
const RegList g_rlAssoc = {
|
|
// HTTP
|
|
{ RC_ADD, REF_NOTNEEDED, HKCR, c_szHTTP, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_HTTPNAME) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTP, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPVOID) &vEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTP, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szHTTPDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
|
|
// HTTPS
|
|
{ RC_ADD, REF_NOTNEEDED, HKCR, c_szHTTPS, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_HTTPSNAME) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPS, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPS, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szHTTPSDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
|
|
// FTP
|
|
{ RC_ADD, REF_NOTNEEDED, HKCR, c_szFTP, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_FTPNAME) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFTP, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFTP, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szFTPDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
|
|
// Gopher
|
|
{ RC_ADD, REF_NOTNEEDED, HKCR, c_szGOPHER, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_GOPHERNAME) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szGOPHER, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szGOPHER, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szGOPHERDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
|
|
// File protocol
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFile, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_FILENAME) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFile, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFile, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szFileDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
|
|
{ RC_RUNDLL, REF_NORMAL, HKCR, c_szFileOpenCmd, "", REG_SZ, sizeof(c_szFileHandler), c_szFileHandler },
|
|
|
|
// Telnet
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_TELNETNAME) },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szTelnetDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
{ RC_RUNDLL, REF_IFEMPTY, HKCR, c_szTelnetOpenCmd, "", REG_SZ, sizeof(c_szTelnetHandler), c_szTelnetHandler },
|
|
|
|
// RLogin
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szRLogin, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_RLOGINNAME) },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szRLogin, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szRLogin, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szRLoginDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
{ RC_RUNDLL, REF_IFEMPTY, HKCR, c_szRLoginOpenCmd, "", REG_SZ, sizeof(c_szTelnetHandler), c_szTelnetHandler },
|
|
|
|
// TN3270
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTN3270, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_TN3270NAME) },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTN3270, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTN3270, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szTN3270DefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
{ RC_RUNDLL, REF_IFEMPTY, HKCR, c_szTN3270OpenCmd, "", REG_SZ, sizeof(c_szTelnetHandler), c_szTelnetHandler },
|
|
|
|
// Mailto protocol
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szMailTo, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_MAILTONAME) },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szMailTo, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szMailTo, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szMailToDefIcon, "", REG_SZ, 2, HTReg_UrlIconProc },
|
|
{ RC_RUNDLL, REF_IFEMPTY, HKCR, c_szMailToOpenCmd, "", REG_SZ, sizeof(c_szMailToHandler), c_szMailToHandler },
|
|
|
|
// News protocol
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szNews, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_NEWSNAME) },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szNews, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szNews, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szNewsDefIcon, "", REG_SZ, 1, HTReg_UrlIconProc },
|
|
{ RC_RUNDLL, REF_IFEMPTY, HKCR, c_szNewsOpenCmd, "", REG_SZ, sizeof(c_szNewsHandler), c_szNewsHandler },
|
|
|
|
// Internet shortcut
|
|
{ RC_ADD, REF_NORMAL, HKCR, ".url", "", REG_SZ, sizeof(c_szIntShcut), c_szIntShcut },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcut, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_INTSHNAME) },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szIntShcut, "EditFlags", REG_BINARY, sizeof(vEditFlagsSafe), (LPSTR) &vEditFlagsSafe },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcut, "IsShortcut", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcut, "NeverShowExt", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutCLSID, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szIntShcutDefIcon, "", REG_SZ, 0, HTReg_UrlIconProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutIconHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutPrshtHandler, "", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, "CLSID\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_INTSHNAME) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "ThreadingModel", REG_SZ, sizeof("Apartment"), "Apartment" },
|
|
|
|
};
|
|
|
|
|
|
const RegSet g_rsAssoc = {
|
|
ARRAYSIZE(g_rlAssoc),
|
|
g_rlAssoc
|
|
};
|
|
|
|
|
|
//
|
|
// .htm, .html assocations for IE 3.0 and IE 4.0
|
|
//
|
|
|
|
// This is run when the browser is opened, and considered a requirement
|
|
// to make IE be the default browser.
|
|
const RegList g_rlAssocHTM = {
|
|
// .html
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, ".htm", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, ".htm", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
|
|
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, ".html", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, ".html", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
|
|
};
|
|
|
|
const RegSet g_rsAssocHTM = {
|
|
ARRAYSIZE(g_rlAssocHTM),
|
|
g_rlAssocHTM
|
|
};
|
|
|
|
|
|
// This is needed just to insure webview works.
|
|
//
|
|
const RegList g_rlAssocHTM_WV = {
|
|
// .html
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, ".htm", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, ".htm", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
|
|
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, ".html", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, ".html", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
|
|
};
|
|
|
|
|
|
const RegSet g_rsAssocHTM_WV = {
|
|
ARRAYSIZE(g_rlAssocHTM_WV),
|
|
g_rlAssocHTM_WV
|
|
};
|
|
|
|
|
|
//
|
|
// IE 3.0 specific association settings
|
|
//
|
|
|
|
const RegList g_rlAssoc_IE = {
|
|
// HTTP
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szHTTPDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
|
|
// HTTPS
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPSOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szHTTPSDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
|
|
// FTP
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szFTPDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
|
|
// Gopher
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szGOPHEROpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szGOPHERDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
|
|
// .html
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szHTMDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
|
|
// Other stuff
|
|
{ RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURL), c_szOpenURL },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "", REG_SZ, sizeof(c_szURL), c_szURL },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szIEFrameAuto, "", REG_SZ, 0, HTReg_IEPathProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szIENameSpaceOpen, "", REG_SZ, 0, HTReg_IEPathProc },
|
|
};
|
|
|
|
|
|
const RegSet g_rsAssoc_IE = {
|
|
ARRAYSIZE(g_rlAssoc_IE),
|
|
g_rlAssoc_IE
|
|
};
|
|
|
|
//
|
|
// defaults in case INF defaults not present
|
|
//
|
|
|
|
const CHAR c_szDefaultHome[] = "Software\\Microsoft\\Internet Explorer\\Main";
|
|
|
|
const RegList g_rlPages_IE = {
|
|
{ RC_ADD, REF_IFEMPTY, HKCU, c_szDefaultHome, "Start Page", REG_SZ, 0, MAKEINTRESOURCE(IDS_DEF_HOME)},
|
|
{ RC_ADD, REF_IFEMPTY, HKCU, c_szDefaultHome, "Search Page", REG_SZ, 0, MAKEINTRESOURCE(IDS_DEF_SEARCH)},
|
|
};
|
|
|
|
const RegSet g_rsPages_IE = {
|
|
ARRAYSIZE (g_rlPages_IE),
|
|
g_rlPages_IE
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// Nashville specific association settings
|
|
//
|
|
|
|
// BUGBUG (scotth): we are explicitly removing this because our beta1
|
|
// rollout to mscorp added it. Having ifexec breaks
|
|
// Netscape. We don't need to explicitly remove these
|
|
// values by RTM.
|
|
|
|
const RegList g_rlAssoc_Nash = {
|
|
// HTTP
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szHTTPOpenCmd, "", REG_SZ, (LPARAM)c_szViewAppendage, HTReg_ShellPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szHTTPDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// HTTPS
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szHTTPSOpenCmd, "", REG_SZ, (LPARAM)c_szViewAppendage, HTReg_ShellPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPSDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPSDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPSDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szHTTPSDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// FTP
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)c_szViewAppendage, HTReg_ShellPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFTPDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFTPDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szFTPDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// Gopher
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szGOPHEROpenCmd, "", REG_SZ, (LPARAM)c_szViewAppendage, HTReg_ShellPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szGOPHERDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szGOPHERDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szGOPHERDdeApp, "", REG_SZ, sizeof("IExplore"), "IExplore" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szGOPHERDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// File protocol
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFileDdeexec, "", REG_SZ, sizeof(c_szViewFolderTemp), c_szViewFolderTemp },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFileDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFileDdeApp, "", REG_SZ, sizeof("Folders"), "Folders" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFileDdeTopic, "", REG_SZ, sizeof("AppProperties"), "AppProperties" },
|
|
|
|
// .htm
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szHTMOpenCmd, "", REG_SZ, (LPARAM)c_szViewAppendage, HTReg_ShellPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMDdeexec, "", REG_SZ, sizeof(c_szViewFolderTemp), c_szViewFolderTemp },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMDdeApp, "", REG_SZ, sizeof("Folders"), "Folders" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szHTMDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMDdeTopic, "", REG_SZ, sizeof("AppProperties"), "AppProperties" },
|
|
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szHTMExploreCmd, "", REG_SZ, (LPARAM)c_szExploreAppendage, HTReg_ShellPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMExploreDdeexec, "", REG_SZ, sizeof(c_szExploreFolderTemp), c_szExploreFolderTemp },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMExploreDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMExploreDdeApp, "", REG_SZ, sizeof("Folders"), "Folders" },
|
|
{ RC_DEL, REF_NUKE, HKCR, c_szHTMExploreDdeIfExec, "", REG_SZ, sizeof("[]"), "[]" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMExploreDdeTopic, "", REG_SZ, sizeof("AppProperties"), "AppProperties" },
|
|
|
|
// Internet shortcut
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szCLSIDURLRoot, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
|
|
{ RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURLNash), c_szOpenURLNash },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutOpen, "CLSID", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
// BUGBUG (scotth): remove this at RTM. Alpha 1 set this.
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szIntShcutOpen, "DontAddToMenu", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "", REG_SZ, sizeof(c_szShell32), c_szShell32 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutMayChange, "", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutPropHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
|
|
// Other stuff
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szIEFrameAuto, "", REG_SZ, 0, HTReg_ShellPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFaveShellFolder, "Attributes", REG_BINARY, SIZEOF(c_dwFaveAttr), (LPVOID) &c_dwFaveAttr },
|
|
};
|
|
|
|
|
|
const RegSet g_rsAssoc_Nash = {
|
|
ARRAYSIZE(g_rlAssoc_Nash),
|
|
g_rlAssoc_Nash
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// General IE 3.0 only settings
|
|
//
|
|
|
|
const CHAR c_szCLSIDMIME[] = "{FBF23B41-E3F0-101B-8488-00AA003E56F8}";
|
|
const CHAR c_szIEOnDesktop[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\{FBF23B42-E3F0-101B-8488-00AA003E56F8}";
|
|
const CHAR c_szShellExecHook[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellExecuteHooks";
|
|
const CHAR c_szFileTypesHook[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileTypesPropertySheetHook";
|
|
|
|
const RegList g_rlGeneral_IE = {
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDIntshcut, REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szFileTypesHook, "", REG_SZ, sizeof(c_szCLSIDMIME), c_szCLSIDMIME },
|
|
};
|
|
|
|
const RegSet g_rsGeneral_IE = {
|
|
ARRAYSIZE(g_rlGeneral_IE),
|
|
g_rlGeneral_IE
|
|
};
|
|
|
|
|
|
//
|
|
// General Nashville-only settings
|
|
//
|
|
|
|
const RegList g_rlGeneral_Nash = {
|
|
{ RC_DEL, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, NULL },
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDIntshcut, REG_SZ, 1, "" },
|
|
{ RC_DEL, REF_NUKE, HKLM, c_szFileTypesHook, "", REG_SZ, sizeof(c_szCLSIDMIME), c_szCLSIDMIME },
|
|
{ RC_DEL, REF_NUKE, HKLM, c_szAlphaNashOnDesktop, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
|
|
};
|
|
|
|
const RegSet g_rsGeneral_Nash = {
|
|
ARRAYSIZE(g_rlGeneral_Nash),
|
|
g_rlGeneral_Nash
|
|
};
|
|
|
|
|
|
/*
|
|
* S P E C I A L D Y N A M I C S E T T I N G S
|
|
*
|
|
*/
|
|
|
|
#define SZ_EXMAILTO "Software\\Clients\\Mail\\Exchange\\Protocols\\Mailto"
|
|
|
|
const RegList g_rlExchange = {
|
|
{ RC_ADD, REF_NORMAL, HKLM, "Software\\Clients\\Mail\\Exchange", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_EXCHANGE) },
|
|
|
|
{ RC_ADD, REF_IFEMPTY, HKLM, SZ_EXMAILTO, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_MAILTONAME) },
|
|
{ RC_ADD, REF_IFEMPTY, HKLM, SZ_EXMAILTO, "EditFlags", REG_BINARY, sizeof(vEditFlags2), (LPSTR) &vEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKLM, SZ_EXMAILTO, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKLM, SZ_EXMAILTO "\\DefaultIcon", "", REG_SZ, 2, HTReg_UrlIconProc },
|
|
{ RC_RUNDLL, REF_IFEMPTY, HKLM, SZ_EXMAILTO "\\Shell\\Open\\Command", "", REG_SZ, sizeof(c_szMailToHandler), c_szMailToHandler },
|
|
};
|
|
|
|
const RegSet g_rsExchange = {
|
|
ARRAYSIZE(g_rlExchange),
|
|
g_rlExchange
|
|
};
|
|
|
|
const RegList g_rlAthena = {
|
|
{ RC_CALLBACK, REF_NORMAL, HKLM, "", "", REG_SZ, (LPARAM)&g_rsExchange, HTReg_ExchangeProc },
|
|
};
|
|
|
|
const RegSet g_rsAthena = {
|
|
ARRAYSIZE(g_rlAthena),
|
|
g_rlAthena
|
|
};
|
|
|
|
|
|
/*
|
|
* U N I N S T A L L S E T T I N G S
|
|
*
|
|
*/
|
|
|
|
|
|
// Protocol-specific uninstall (for both IE 3.0 and 4.0)
|
|
|
|
const RegList g_rlUnHTTP = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTP, "URL Protocol", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPDefIcon, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szHTTPOpenCmd, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_EDITFLAGS, HKCR, c_szHTTP, "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnHTTP = {
|
|
ARRAYSIZE(g_rlUnHTTP),
|
|
g_rlUnHTTP
|
|
};
|
|
|
|
const RegList g_rlUnHTTPS = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPS, "URL Protocol", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDefIcon, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szHTTPSOpenCmd, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_EDITFLAGS, HKCR, c_szHTTPS, "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnHTTPS = {
|
|
ARRAYSIZE(g_rlUnHTTPS),
|
|
g_rlUnHTTPS
|
|
};
|
|
|
|
const RegList g_rlUnFTP = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFTP, "URL Protocol", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFTPDefIcon, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szFTPOpenCmd, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_EDITFLAGS, HKCR, c_szFTP, "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnFTP = {
|
|
ARRAYSIZE(g_rlUnFTP),
|
|
g_rlUnFTP
|
|
};
|
|
|
|
const RegList g_rlUnGopher = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szGOPHER, "URL Protocol", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDefIcon, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szGOPHEROpenCmd, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_EDITFLAGS, HKCR, c_szGOPHER, "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnGopher = {
|
|
ARRAYSIZE(g_rlUnGopher),
|
|
g_rlUnGopher
|
|
};
|
|
|
|
const RegList g_rlUnHTM = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, "htmlfile\\DefaultIcon", "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szHTMOpenCmd, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_EDITFLAGS, HKCR, "htmlfile", "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnHTM = {
|
|
ARRAYSIZE(g_rlUnHTM),
|
|
g_rlUnHTM
|
|
};
|
|
|
|
|
|
// Protocol-specific uninstall for Nashville
|
|
|
|
|
|
const RegList g_rlUnHTTP_Nash = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnHTTP_Nash = {
|
|
ARRAYSIZE(g_rlUnHTTP_Nash),
|
|
g_rlUnHTTP_Nash
|
|
};
|
|
|
|
const RegList g_rlUnHTTPS_Nash = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnHTTPS_Nash = {
|
|
ARRAYSIZE(g_rlUnHTTPS_Nash),
|
|
g_rlUnHTTPS_Nash
|
|
};
|
|
|
|
const RegList g_rlUnFTP_Nash = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnFTP_Nash = {
|
|
ARRAYSIZE(g_rlUnFTP_Nash),
|
|
g_rlUnFTP_Nash
|
|
};
|
|
|
|
const RegList g_rlUnGopher_Nash = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnGopher_Nash = {
|
|
ARRAYSIZE(g_rlUnGopher_Nash),
|
|
g_rlUnGopher_Nash
|
|
};
|
|
|
|
const RegList g_rlUnHTM_Nash = {
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMExploreDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMExploreDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMExploreDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMExploreDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szHTMExploreCmd, "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet g_rsUnHTM_Nash = {
|
|
ARRAYSIZE(g_rlUnHTM_Nash),
|
|
g_rlUnHTM_Nash
|
|
};
|
|
|
|
|
|
//
|
|
// IE 3.0 uninstall
|
|
//
|
|
|
|
const RegList g_rlUninstall_IE = {
|
|
{ RC_DEL, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szIENameSpaceOpen, "", REG_SZ, 0, NULL },
|
|
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_IE3, (LPARAM)&g_rsUnHTTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_IE3, (LPARAM)&g_rsUnHTTPS, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_IE3, (LPARAM)&g_rsUnFTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_IE3, (LPARAM)&g_rsUnGopher, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_IE3, (LPARAM)&g_rsUnHTM, HTReg_UninstallProc },
|
|
};
|
|
|
|
const RegSet g_rsUninstall_IE = {
|
|
ARRAYSIZE(g_rlUninstall_IE),
|
|
g_rlUninstall_IE
|
|
};
|
|
|
|
|
|
//
|
|
// Nashville uninstall
|
|
//
|
|
|
|
const RegList g_rlUninstall_Nash = {
|
|
// InternetShortcut
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szIntShcutOpen, "CLSID", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szIntshcutMayChange, "", REG_SZ, 1, "" },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szIntShcutPropHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
|
|
// Change the inprocserver after removing "MayChangeDefaultMenu" above.
|
|
// Do this so url.dll doesn't repatch the registry.
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "", REG_SZ, sizeof(c_szURL), c_szURL },
|
|
{ RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURL), c_szOpenURL },
|
|
|
|
// File protocol
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFileDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFileDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFileDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szFileDdeexec, "", REG_SZ, 0, NULL },
|
|
|
|
// Favorite folder
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szFaveShellFolder, "Attributes", REG_BINARY, SIZEOF(c_dwFaveAttr), (LPVOID) &c_dwFaveAttr },
|
|
|
|
// Protocol associations
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_NASH, (LPARAM)&g_rsUnHTTP_Nash, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_NASH, (LPARAM)&g_rsUnHTTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_NASH, (LPARAM)&g_rsUnHTTPS_Nash, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_NASH, (LPARAM)&g_rsUnHTTPS, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_NASH, (LPARAM)&g_rsUnFTP_Nash, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_NASH, (LPARAM)&g_rsUnFTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_NASH, (LPARAM)&g_rsUnGopher_Nash, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_NASH, (LPARAM)&g_rsUnGopher, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_NASH, (LPARAM)&g_rsUnHTM_Nash, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_NASH, (LPARAM)&g_rsUnHTM, HTReg_UninstallProc },
|
|
};
|
|
|
|
const RegSet g_rsUninstall_Nash = {
|
|
ARRAYSIZE(g_rlUninstall_Nash),
|
|
g_rlUninstall_Nash
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* D E F A U L T S E T O F R E G S E T S
|
|
*
|
|
*/
|
|
|
|
|
|
// Common association settings for both IE and Nashville
|
|
|
|
// This is the minimum set that is queried every time a shell window opens.
|
|
// WARNING: this should be small to reduce the time it takes to open a folder.
|
|
|
|
const RegSet * g_rgprsWebview[] = {
|
|
&g_rsAssocHTM_WV,
|
|
};
|
|
|
|
// This is the minimum set that is queried every time a browser window
|
|
// opens (but not an explorer window).
|
|
|
|
const RegSet * g_rgprsMin_IE[] = {
|
|
&g_rsPages_IE,
|
|
};
|
|
|
|
|
|
// This is the required set of entries to make IE be the default
|
|
// browser. Only used if the user hasn't turned this off.
|
|
|
|
const RegSet * g_rgprsDefault[] = {
|
|
&g_rsAssoc,
|
|
&g_rsAssocHTM,
|
|
};
|
|
|
|
// IE 3.0 specific associations
|
|
|
|
const RegSet * g_rgprsDefault_IE[] = {
|
|
&g_rsAssoc_IE,
|
|
};
|
|
|
|
// Nashville specific associations
|
|
|
|
const RegSet * g_rgprsDefault_Nash[] = {
|
|
&g_rsAssoc_Nash,
|
|
};
|
|
|
|
|
|
//
|
|
// Other registry settings
|
|
//
|
|
|
|
const RegSet * g_rgprsIE30Only[] =
|
|
{
|
|
&g_rsGeneral_IE,
|
|
&g_rsAthena,
|
|
};
|
|
|
|
|
|
const RegSet *g_rgprsNashOnly[] =
|
|
{
|
|
&g_rsGeneral_Nash,
|
|
&g_rsAthena,
|
|
};
|
|
|
|
|
|
const RegSet *g_rgprsUninstallIE30[] =
|
|
{
|
|
&g_rsUninstall_IE,
|
|
};
|
|
|
|
|
|
const RegSet *g_rgprsUninstallNash[] =
|
|
{
|
|
&g_rsUninstall_Nash,
|
|
};
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Determine if a particular RegSet is installed
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
IsRegSetInstalled(
|
|
IN const RegSet * prs)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
UINT i;
|
|
HKEY hkey;
|
|
const RegEntry * pre;
|
|
CHAR szBuffer[1024]; // Registry Data Holder
|
|
CHAR szT[MAX_PATH + 20]; // Need a bit extra for pszIExpAppendage
|
|
DWORD dwType;
|
|
DWORD dwSize;
|
|
DWORD dwSizeExpect;
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
// Check each registry entry. Stop when we encounter the first
|
|
// entry which doesn't match (no need to waste time looking at
|
|
// other entries).
|
|
//
|
|
// In the debug build, we enumerate the whole list, so we can
|
|
// see all the differences at once.
|
|
//
|
|
|
|
#ifdef DEBUG
|
|
#define BAIL_OUT bRet = TRUE; continue
|
|
#else
|
|
#define BAIL_OUT goto Bail
|
|
#endif
|
|
|
|
|
|
for (i = 0; i < prs->cre; i++)
|
|
{
|
|
pre = &(prs->pre[i]);
|
|
|
|
// Is this regentry not needed, or can it be set by some third
|
|
// party?
|
|
if (IsFlagSet(pre->dwFlags, REF_NOTNEEDED))
|
|
{
|
|
// Yes; skip to next
|
|
continue;
|
|
}
|
|
|
|
// Does the key exist?
|
|
if (NO_ERROR != RegOpenKeyA(pre->hkeyRoot, pre->pszKey, &hkey))
|
|
{
|
|
// No; should it?
|
|
if (RC_DEL == pre->regcmd)
|
|
{
|
|
// No; skip to next
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
// Yes
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s doesn't exist and should", Dbg_RegStr(pre, szDbg)); )
|
|
BAIL_OUT;
|
|
}
|
|
}
|
|
// Yes; should it?
|
|
else if (RC_DEL == pre->regcmd && !*pre->pszValName)
|
|
{
|
|
// No
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s exists and shouldn't", Dbg_RegStr(pre, szDbg)); )
|
|
RegCloseKey(hkey);
|
|
BAIL_OUT;
|
|
}
|
|
|
|
// Does the value exist?
|
|
dwSize = SIZEOF(szBuffer);
|
|
if (NO_ERROR != RegQueryValueExA(hkey, pre->pszValName, NULL,
|
|
&dwType, (BYTE *)szBuffer, &dwSize))
|
|
{
|
|
// No; should it?
|
|
if (RC_DEL != pre->regcmd)
|
|
{
|
|
// Yes
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: RegQueryValueEx( %hs, %hs ) Failed", pre->pszKey, pre->pszValName);
|
|
RegCloseKey(hkey);
|
|
BAIL_OUT;
|
|
}
|
|
}
|
|
// Yes; should it?
|
|
else if (RC_DEL == pre->regcmd)
|
|
{
|
|
// No
|
|
ASSERT(pre->pszValName && *pre->pszValName);
|
|
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s exists and shouldn't",
|
|
Dbg_RegStr(pre, szDbg)); )
|
|
RegCloseKey(hkey);
|
|
BAIL_OUT;
|
|
}
|
|
RegCloseKey(hkey);
|
|
|
|
// Is this a value that cannot be stomped (ie, a 3rd party might have
|
|
// set its value, and that's okay with us)?
|
|
if (IsFlagSet(pre->dwFlags, REF_IFEMPTY))
|
|
{
|
|
// Yes; the existence of the value is good enough for us,
|
|
// skip to next
|
|
continue;
|
|
}
|
|
|
|
switch (pre->regcmd)
|
|
{
|
|
case RC_ADD:
|
|
case RC_RUNDLL:
|
|
if (dwType == REG_SZ)
|
|
{
|
|
LPCVOID pvValue;
|
|
|
|
// Is this a resource string?
|
|
if (0 == HIWORD(pre->pvValue))
|
|
{
|
|
// Yes; load it
|
|
dwSizeExpect = LoadStringA(g_hinst, (UINT)pre->pvValue, szT, SIZECHARS(szT));
|
|
|
|
// Add null and convert to bytes
|
|
dwSizeExpect = CbFromCchA(dwSizeExpect + 1);
|
|
pvValue = szT;
|
|
}
|
|
else
|
|
{
|
|
// No
|
|
ASSERT(pre->pvValue);
|
|
|
|
if (RC_RUNDLL == pre->regcmd)
|
|
{
|
|
wsprintfA(szT, "rundll32.exe %s", (LPSTR)pre->pvValue);
|
|
pvValue = szT;
|
|
|
|
// Add null and convert to bytes
|
|
dwSizeExpect = CbFromCchA(lstrlenA(szT) + 1);
|
|
}
|
|
else
|
|
{
|
|
pvValue = pre->pvValue;
|
|
|
|
if (0 == pre->dwSize)
|
|
dwSizeExpect = CbFromCchA(lstrlenA(pvValue) + 1);
|
|
else
|
|
dwSizeExpect = pre->dwSize;
|
|
}
|
|
}
|
|
|
|
if (dwSize != dwSizeExpect)
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s string size is %d, expecting %d", Dbg_RegStr(pre, szDbg), dwSize, dwSizeExpect);
|
|
BAIL_OUT;
|
|
}
|
|
|
|
// Compare case-insensitive (otherwise we'd just use
|
|
// memcmp below)
|
|
if (0 != lstrnicmpA((LPSTR)pvValue, szBuffer, dwSize / SIZEOF(CHAR)))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s string is \"%hs\", expecting \"%hs\"", Dbg_RegStr(pre, szDbg), szBuffer, pvValue);
|
|
BAIL_OUT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Non-string case
|
|
if (dwSize != pre->dwSize)
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s size is %d, expecting %d", Dbg_RegStr(pre, szDbg), dwSize, pre->dwSize);
|
|
BAIL_OUT;
|
|
}
|
|
|
|
if (0 != memcmp(pre->pvValue, (BYTE *)szBuffer, dwSize))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s value is different, expecting %#08x", Dbg_RegStr(pre, szDbg), *(LPDWORD)pre->pvValue);
|
|
BAIL_OUT;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RC_CALLBACK:
|
|
{
|
|
RSPECPROC pfn = (RSPECPROC)pre->pvValue;
|
|
|
|
ASSERT(IS_VALID_CODE_PTR(pfn, RSPECPROC));
|
|
|
|
// If the callback returns false, it means we're not the
|
|
// default browser.
|
|
if ( !pfn(RSCB_QUERY, pre, szBuffer, dwSize) )
|
|
BAIL_OUT;
|
|
break;
|
|
}
|
|
|
|
case RC_DEL:
|
|
// Work is done before the switch statement. Do nothing here.
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
TraceMsg(TF_ERROR, "IsRegSetInstalled: Unhandled Special Type");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
// In the debug build, leaving the above loop with bRet == TRUE means
|
|
// something doesn't match, so we need to flip the boolean value.
|
|
bRet ^= TRUE;
|
|
#else
|
|
bRet = TRUE;
|
|
|
|
Bail:
|
|
#endif
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Returns TRUE if the key is empty of all subkeys and
|
|
all (non-default) values.
|
|
|
|
If dwFlags has REF_EDITFLAGS set, then this function
|
|
ignores the EditFlags value.
|
|
|
|
Returns: see above
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
IsKeyPsuedoEmpty(
|
|
IN HKEY hkey,
|
|
IN LPCSTR pszSubKey,
|
|
IN DWORD dwFlags) // REF_ flags
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwRet;
|
|
HKEY hkeyNew;
|
|
|
|
dwRet = RegOpenKeyExA(hkey, pszSubKey, 0, KEY_READ, &hkeyNew);
|
|
if (NO_ERROR == dwRet)
|
|
{
|
|
DWORD ckeys;
|
|
DWORD cvalues;
|
|
|
|
// Are the any subkeys?
|
|
if (NO_ERROR == RegQueryInfoKey(hkeyNew, NULL, NULL, NULL, &ckeys,
|
|
NULL, NULL, &cvalues, NULL, NULL,
|
|
NULL, NULL) &&
|
|
0 == ckeys)
|
|
{
|
|
// No; how about non-default values?
|
|
DWORD dwRetDef = SHGetValueA(hkey, pszSubKey, "", NULL, NULL, NULL);
|
|
|
|
bRet = (0 == cvalues || (1 == cvalues && NO_ERROR == dwRetDef));
|
|
|
|
// Should we ignore edit flags?
|
|
if (!bRet && IsFlagSet(dwFlags, REF_EDITFLAGS))
|
|
{
|
|
// Yes
|
|
DWORD dwRetEdit = SHGetValueA(hkey, pszSubKey, "EditFlags", NULL, NULL, NULL);
|
|
|
|
bRet = ((1 == cvalues && NO_ERROR == dwRetEdit) ||
|
|
(2 == cvalues && NO_ERROR == dwRetEdit &&
|
|
NO_ERROR == dwRetDef));
|
|
}
|
|
}
|
|
RegCloseKey(hkeyNew);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Prune the key of our keys and values. Walk back up
|
|
the tree and delete empty keys below us.
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
void
|
|
PruneKey(
|
|
IN HKEY hkeyRoot,
|
|
IN LPCSTR pszKey)
|
|
{
|
|
CHAR szPath[MAX_PATH];
|
|
|
|
ASSERT(hkeyRoot);
|
|
ASSERT(pszKey);
|
|
|
|
lstrcpyA(szPath, pszKey);
|
|
|
|
while (PathRemoveFileSpecA(szPath) && *szPath)
|
|
{
|
|
SHDeleteOrphanKeyA(hkeyRoot, szPath);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Install a regset (set of registry entries).
|
|
|
|
If bDontIntrude is TRUE , then behave such that any
|
|
REF_DONTINTRUDE entry is not forcefully installed (i.e., it
|
|
will only get installed if the key doesn't already
|
|
have a value in it).
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
InstallRegSet(
|
|
IN const RegSet *prs,
|
|
IN BOOL bDontIntrude)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
UINT i;
|
|
HKEY hkey;
|
|
const RegEntry * pre;
|
|
TCHAR szBuffer[MAX_PATH + 20]; // Need additional space for pszIExpAppendage
|
|
DWORD dwSize;
|
|
LPCVOID pvValue;
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
/*
|
|
* Install each registry entry
|
|
*/
|
|
for (i = 0; i < prs->cre; i++)
|
|
{
|
|
pre = &(prs->pre[i]);
|
|
|
|
// Stomp on this value?
|
|
if (IsFlagSet(pre->dwFlags, REF_IFEMPTY) ||
|
|
bDontIntrude && IsFlagSet(pre->dwFlags, REF_DONTINTRUDE))
|
|
{
|
|
// No
|
|
if (NO_ERROR == RegOpenKeyA(pre->hkeyRoot, pre->pszKey, &hkey))
|
|
{
|
|
BOOL bSkip;
|
|
|
|
// Are we checking the default value?
|
|
if (0 == *pre->pszValName)
|
|
{
|
|
// Yes; check the size, because default values
|
|
// always exist with at least a null terminator.
|
|
dwSize = 0;
|
|
RegQueryValueExA(hkey, pre->pszValName, NULL, NULL, NULL, &dwSize);
|
|
bSkip = (1 < dwSize);
|
|
}
|
|
else
|
|
{
|
|
// No
|
|
bSkip = (NO_ERROR == RegQueryValueExA(hkey, pre->pszValName,
|
|
NULL, NULL, NULL, NULL));
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
// Does it exist?
|
|
if (bSkip)
|
|
{
|
|
// Yes; skip it
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s already exists, skipping",
|
|
Dbg_RegStr(pre, szDbg)); )
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (pre->regcmd)
|
|
{
|
|
case RC_ADD:
|
|
case RC_RUNDLL:
|
|
if (NO_ERROR != RegCreateKeyA(pre->hkeyRoot, pre->pszKey, &hkey))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): RegCreateKey(%hs) Failed", pre->pszKey);
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
// Is the value a resource string?
|
|
if (REG_SZ == pre->dwType && 0 == HIWORD(pre->pvValue))
|
|
{
|
|
// Yes; load it
|
|
dwSize = LoadStringA(g_hinst, (UINT)pre->pvValue, szBuffer,
|
|
SIZECHARS(szBuffer));
|
|
|
|
// Add null and convert to bytes
|
|
dwSize = CbFromCchA(dwSize + 1);
|
|
pvValue = szBuffer;
|
|
}
|
|
else
|
|
{
|
|
// No
|
|
if (RC_RUNDLL == pre->regcmd)
|
|
{
|
|
ASSERT(pre->pvValue);
|
|
ASSERT(REG_SZ == pre->dwType);
|
|
|
|
wsprintfA(szBuffer, "rundll32.exe %s", (LPSTR)pre->pvValue);
|
|
pvValue = szBuffer;
|
|
dwSize = CbFromCchA(lstrlenA(szBuffer) + 1);
|
|
}
|
|
else
|
|
{
|
|
// Normal case
|
|
pvValue = pre->pvValue;
|
|
|
|
if (0 == pre->dwSize && REG_SZ == pre->dwType)
|
|
dwSize = CbFromCchA(lstrlenA(pvValue) + 1);
|
|
else
|
|
dwSize = pre->dwSize;
|
|
}
|
|
}
|
|
|
|
ASSERT(0 < dwSize);
|
|
|
|
if (NO_ERROR != RegSetValueExA(hkey, pre->pszValName, 0,
|
|
pre->dwType, (BYTE*)pvValue,
|
|
dwSize))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): RegSetValueEx(%hs) Failed", pre->pszValName );
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
break;
|
|
|
|
case RC_CALLBACK:
|
|
{
|
|
RSPECPROC pfn = (RSPECPROC)pre->pvValue;
|
|
|
|
ASSERT(IS_VALID_CODE_PTR(pfn, RSPECPROC));
|
|
|
|
pfn(RSCB_INSTALL, pre, NULL, 0);
|
|
break;
|
|
}
|
|
|
|
case RC_DEL:
|
|
// Delete the value or the key?
|
|
if (*pre->pszValName)
|
|
{
|
|
// Value
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting value %s", Dbg_RegStr(pre, szDbg)); )
|
|
|
|
SHDeleteValueA(pre->hkeyRoot, pre->pszKey, pre->pszValName);
|
|
}
|
|
else
|
|
{
|
|
// Key
|
|
if (IsFlagSet(pre->dwFlags, REF_NUKE))
|
|
{
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting key %s", Dbg_RegStr(pre, szDbg)); )
|
|
|
|
SHDeleteKeyA(pre->hkeyRoot, pre->pszKey);
|
|
}
|
|
// If there are keys or values (other than the
|
|
// default value) that are set, then we don't want
|
|
// to delete either the default value or the
|
|
// key.
|
|
else if (IsKeyPsuedoEmpty(pre->hkeyRoot, pre->pszKey, pre->dwFlags))
|
|
{
|
|
// Delete the default value so SHDeleteOrphanKey
|
|
// will work
|
|
SHDeleteValueA(pre->hkeyRoot, pre->pszKey, "");
|
|
|
|
// Delete the EditFlags value? (Without the EditFlags,
|
|
// the user will not be able to specify associations
|
|
// for this class in the FileTypes dialog, b/c that
|
|
// dialog requires this value. So the rule is, this
|
|
// function will delete the EditFlags if there is
|
|
// nothing else in the key.)
|
|
if (IsFlagSet(pre->dwFlags, REF_EDITFLAGS))
|
|
{
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting %s\\EditFlags", Dbg_RegStr(pre, szDbg)); )
|
|
|
|
SHDeleteValueA(pre->hkeyRoot, pre->pszKey, "EditFlags");
|
|
}
|
|
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting empty key %s", Dbg_RegStr(pre, szDbg)); )
|
|
|
|
SHDeleteOrphanKeyA(pre->hkeyRoot, pre->pszKey);
|
|
|
|
// Should we prune? (This mean we'll walk back up
|
|
// the tree and try deleting empty keys that lead
|
|
// to this key.)
|
|
if (IsFlagSet(pre->dwFlags, REF_PRUNE))
|
|
PruneKey(pre->hkeyRoot, pre->pszKey);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): Unhandled Special Case");
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CenterWindow (HWND, HWND)
|
|
|
|
PURPOSE: Center one window over another
|
|
|
|
COMMENTS:
|
|
|
|
Dialog boxes take on the screen position that they were designed at,
|
|
which is not always appropriate. Centering the dialog over a particular
|
|
window usually results in a better position.
|
|
|
|
****************************************************************************/
|
|
BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
|
|
{
|
|
RECT rChild, rParent;
|
|
int wChild, hChild, wParent, hParent;
|
|
int wScreen, hScreen, xNew, yNew;
|
|
HDC hdc;
|
|
|
|
// Get the Height and Width of the child window
|
|
GetWindowRect (hwndChild, &rChild);
|
|
wChild = rChild.right - rChild.left;
|
|
hChild = rChild.bottom - rChild.top;
|
|
|
|
// Get the Height and Width of the parent window
|
|
GetWindowRect (hwndParent, &rParent);
|
|
wParent = rParent.right - rParent.left;
|
|
hParent = rParent.bottom - rParent.top;
|
|
|
|
// Get the display limits
|
|
hdc = GetDC (hwndChild);
|
|
wScreen = GetDeviceCaps (hdc, HORZRES);
|
|
hScreen = GetDeviceCaps (hdc, VERTRES);
|
|
ReleaseDC (hwndChild, hdc);
|
|
|
|
// Calculate new X position, then adjust for screen
|
|
xNew = rParent.left + ((wParent - wChild) /2);
|
|
if (xNew < 0) {
|
|
xNew = 0;
|
|
} else if ((xNew+wChild) > wScreen) {
|
|
xNew = wScreen - wChild;
|
|
}
|
|
|
|
// Calculate new Y position, then adjust for screen
|
|
yNew = rParent.top + ((hParent - hChild) /2);
|
|
if (yNew < 0) {
|
|
yNew = 0;
|
|
} else if ((yNew+hChild) > hScreen) {
|
|
yNew = hScreen - hChild;
|
|
}
|
|
|
|
// Set it, and return
|
|
return SetWindowPos (hwndChild, NULL,
|
|
xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Dialog proc
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
CALLBACK
|
|
AssociationDialogProc(HWND hdlg, UINT uMsg, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
BOOL bMsgHandled = FALSE;
|
|
|
|
/* uMsg may be any value. */
|
|
/* wparam may be any value. */
|
|
/* lparam may be any value. */
|
|
|
|
switch (uMsg){
|
|
case WM_INITDIALOG:
|
|
CenterWindow( hdlg, GetDesktopWindow());
|
|
|
|
// Initialize Checkbox
|
|
Button_SetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK), IsCheckAssociationsOn());
|
|
|
|
// Show the right text
|
|
if (PLATFORM_NASH == WhichPlatform())
|
|
{
|
|
ShowWindow(GetDlgItem(hdlg, IDC_ASSOC_IE30), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hdlg, IDC_ASSOC_IE40), SW_SHOWNA);
|
|
}
|
|
bMsgHandled = TRUE;
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam)) {
|
|
case IDYES:
|
|
case IDNO:
|
|
SetCheckAssociations( Button_GetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK)) );
|
|
EndDialog( hdlg, LOWORD(wparam));
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return(bMsgHandled);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Asks the user whether to make IE be the default browser
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
AskUserShouldFixReg()
|
|
{
|
|
return IDYES == DialogBox( HINST_THISDLL, MAKEINTRESOURCE(IDD_ASSOC), NULL, (DLGPROC)AssociationDialogProc);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Install file and protocol association settings in
|
|
registry.
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
HRESULT
|
|
InstallRegAssoc(
|
|
UINT nInstall, // One of PLATFORM_*
|
|
BOOL bDontIntrude) // TRUE: be non-intrusive
|
|
{
|
|
int i;
|
|
|
|
// Install associations common across both IE and Nashville
|
|
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault); i++)
|
|
InstallRegSet(g_rgprsDefault[i], bDontIntrude);
|
|
|
|
if (PLATFORM_UNKNOWN == nInstall)
|
|
{
|
|
nInstall = WhichPlatform();
|
|
}
|
|
|
|
switch (nInstall)
|
|
{
|
|
case PLATFORM_IE3:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_IE); i++)
|
|
InstallRegSet(g_rgprsDefault_IE[i], bDontIntrude);
|
|
break;
|
|
|
|
case PLATFORM_NASH:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Nash); i++)
|
|
InstallRegSet(g_rgprsDefault_Nash[i], bDontIntrude);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Set the CheckAssocation setting in the registry
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
void
|
|
SetCheckAssociations(
|
|
BOOL fCheck)
|
|
{
|
|
HKEY hk;
|
|
|
|
if (RegOpenKeyEx( HKEY_CURRENT_USER, c_szCheckAssnSwitch, 0, KEY_WRITE, &hk ) == ERROR_SUCCESS) {
|
|
LPTSTR szStr;
|
|
DWORD dwSize;
|
|
|
|
if (fCheck)
|
|
szStr = TEXT("Yes");
|
|
else
|
|
szStr = TEXT("No");
|
|
dwSize = CbFromCch( lstrlen( szStr ) + 1 );
|
|
RegSetValueEx( hk, TEXT("Check_Associations"), 0, REG_SZ, (LPBYTE) szStr, dwSize );
|
|
RegCloseKey( hk );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Determines if the user has turned off the "check for
|
|
default browser" in the registry.
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
BOOL IsCheckAssociationsOn()
|
|
{
|
|
BOOL rval = TRUE;
|
|
TCHAR szBuf[20];
|
|
DWORD dwSize = sizeof(szBuf);
|
|
DWORD dwValType;
|
|
|
|
if (NO_ERROR == SHGetValue(HKEY_CURRENT_USER, c_szCheckAssnSwitch,
|
|
TEXT("Check_Associations"), &dwValType,
|
|
szBuf, &dwSize))
|
|
{
|
|
if ((dwValType == REG_SZ) && (dwSize < sizeof(szBuf))) {
|
|
if (lstrcmpi( szBuf, TEXT("No")) == 0)
|
|
rval = FALSE;
|
|
}
|
|
}
|
|
|
|
return( rval );
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Queries a registry set. If the registry doesn't have
|
|
the right values, this function applies the registry
|
|
set changes to the registry.
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void
|
|
QueryAndApplyRegSet(
|
|
IN RegSet ** rgprs,
|
|
IN UINT cprs)
|
|
{
|
|
UINT i;
|
|
|
|
for (i = 0; i < cprs; i++)
|
|
{
|
|
// Does the registry have the right settings?
|
|
if (!IsRegSetInstalled(rgprs[i]))
|
|
{
|
|
// No; apply the settings
|
|
for (i = 0; i < ARRAYSIZE(rgprs); i++)
|
|
InstallRegSet(rgprs[i], FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnsureWebViewRegSettings()
|
|
{
|
|
// We do the following mini-check regardless of the user's settings,
|
|
// and for every window we open
|
|
QueryAndApplyRegSet(g_rgprsWebview, ARRAYSIZE(g_rgprsWebview));
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Function that determines if we are the default browser.
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
void
|
|
DetectAndFixAssociations()
|
|
{
|
|
TraceMsg(TF_WARNING, "Performing expensive registry query for default browser!");
|
|
|
|
// This ensures we have a valid Start and Search Page in the registry
|
|
// for this user, regardless of Profile.
|
|
QueryAndApplyRegSet(g_rgprsMin_IE, ARRAYSIZE(g_rgprsMin_IE));
|
|
|
|
// If we already checked once, or the user doesn't
|
|
// want us to check the associations then don't do the check
|
|
if ( IsCheckAssociationsOn() )
|
|
{
|
|
int i;
|
|
BOOL bNeedFix = FALSE;
|
|
UINT nInstall = WhichPlatform();
|
|
|
|
// Check the settings common to all platforms
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault); i++)
|
|
{
|
|
if (! IsRegSetInstalled(g_rgprsDefault[i]))
|
|
{
|
|
bNeedFix = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bNeedFix)
|
|
{
|
|
// Check specific to IE or Nashville
|
|
switch (nInstall)
|
|
{
|
|
case PLATFORM_IE3:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_IE); i++)
|
|
{
|
|
if (! IsRegSetInstalled(g_rgprsDefault_IE[i]))
|
|
{
|
|
bNeedFix = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PLATFORM_NASH:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Nash); i++)
|
|
{
|
|
if (! IsRegSetInstalled(g_rgprsDefault_Nash[i]))
|
|
{
|
|
bNeedFix = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bNeedFix && AskUserShouldFixReg())
|
|
InstallRegAssoc(nInstall, FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Checks if we're installing over IE. This function
|
|
looks at the associated shell\open\command handler
|
|
for the http protocol.
|
|
|
|
Returns: TRUE if we're installing over IE
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
AreWeInstallingOverIE(void)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
TCHAR sz[MAX_PATH + 20]; // add some padding for arguments
|
|
DWORD cbData = SIZEOF(sz);
|
|
|
|
if (NO_ERROR == SHGetValue(HKEY_CLASSES_ROOT, c_szHTTPOpenCmd, TEXT(""),
|
|
NULL, sz, &cbData) &&
|
|
StrStrI(sz, TEXT("iexplore.exe")))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "Installing over IEXPLORE.EXE");
|
|
bRet = TRUE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Install registry info based upon which shell we're running
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
HRESULT
|
|
InstallPlatformRegItems(void)
|
|
{
|
|
int i;
|
|
UINT nInstall = WhichPlatform();
|
|
BOOL bDontIntrude;
|
|
|
|
// If we aren't installing over a previous IE build, don't intrude
|
|
// until IE is invoked.
|
|
bDontIntrude = !AreWeInstallingOverIE();
|
|
|
|
// Install file and protocol associations
|
|
|
|
InstallRegAssoc(nInstall, bDontIntrude);
|
|
|
|
// Install other registry settings
|
|
|
|
switch (nInstall)
|
|
{
|
|
case PLATFORM_IE3:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsIE30Only); i++)
|
|
{
|
|
InstallRegSet(g_rgprsIE30Only[i], bDontIntrude);
|
|
}
|
|
break;
|
|
|
|
case PLATFORM_NASH:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsNashOnly); i++)
|
|
{
|
|
InstallRegSet(g_rgprsNashOnly[i], bDontIntrude);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Uninstall registry info based on given platform
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
HRESULT
|
|
UninstallPlatformRegItems(
|
|
IN UINT uPlatform)
|
|
{
|
|
int i;
|
|
|
|
switch (uPlatform)
|
|
{
|
|
case PLATFORM_IE3:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsUninstallIE30); i++)
|
|
{
|
|
InstallRegSet(g_rgprsUninstallIE30[i], FALSE);
|
|
}
|
|
break;
|
|
|
|
case PLATFORM_NASH:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsUninstallNash); i++)
|
|
{
|
|
InstallRegSet(g_rgprsUninstallNash[i], FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// Don't do anything
|
|
break;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|