3109 lines
105 KiB
C++
3109 lines
105 KiB
C++
/*
|
|
* Registry Management
|
|
*
|
|
* HTREGMNG.C
|
|
*
|
|
* Copyright (c) 1995 Microsoft Corporation
|
|
*
|
|
*/
|
|
|
|
#include "priv.h"
|
|
#include "htregmng.h"
|
|
#include "resource.h"
|
|
#include "regapix.h"
|
|
#include <filetype.h>
|
|
|
|
#include <advpub.h>
|
|
#include <mluisupp.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.
|
|
//
|
|
//
|
|
// NOTE: NOTE: NOTE: NOTE: NOTE: NOTE: NOTE:
|
|
//-------------------------------------------
|
|
// Any new Icon check that uses HTReg_UrlIconProc that gets added
|
|
// to any of the Assoc arrays and is REQUIRED for Default Browser check to
|
|
// succeed has to be added to the c_rlAssoc_FixIcon[] array also.
|
|
//
|
|
|
|
|
|
// Make the tables more compact
|
|
#define HKCR HKEY_CLASSES_ROOT
|
|
#define HKLM HKEY_LOCAL_MACHINE
|
|
#define HKCU HKEY_CURRENT_USER
|
|
|
|
|
|
#define IDEFICON_STD 0
|
|
#define IDEFICON_NEWS 1
|
|
#define IDEFICON_MAIL 2
|
|
|
|
#ifndef UNIX
|
|
|
|
#define IEXPLORE_APP "IExplore"
|
|
#define IEXPLORE_EXE "iexplore.exe"
|
|
#define EXPLORER_EXE "explorer.exe"
|
|
#define RUNDLL_CMD_FMT "rundll32.exe %s"
|
|
|
|
#else
|
|
|
|
#define IEXPLORE_APP "iexplorer"
|
|
#define IEXPLORE_EXE "iexplorer"
|
|
#define EXPLORER_EXE "explorer"
|
|
#define RUNDLL_CMD_FMT "rundll32 %s"
|
|
|
|
#endif
|
|
|
|
BOOL InstallRegSet(const RegSet *prs, BOOL bDontIntrude);
|
|
|
|
#ifndef UNIX
|
|
const CHAR c_szIexploreKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE";
|
|
#else
|
|
const CHAR c_szIexploreKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORER";
|
|
#endif
|
|
|
|
#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];
|
|
TCHAR szTempKey[MAXIMUM_SUB_KEY_LENGTH];
|
|
TCHAR szTempValue[MAXIMUM_VALUE_NAME_LENGTH];
|
|
|
|
ASSERT(pre);
|
|
ASSERT(pszBuf);
|
|
|
|
if (HKEY_CLASSES_ROOT == pre->hkeyRoot)
|
|
{
|
|
StrCpyN(szRoot, TEXT("HKCR"), ARRAYSIZE(szRoot));
|
|
}
|
|
else if (HKEY_CURRENT_USER == pre->hkeyRoot)
|
|
{
|
|
StrCpyN(szRoot, TEXT("HKCU"), ARRAYSIZE(szRoot));
|
|
}
|
|
else if (HKEY_LOCAL_MACHINE == pre->hkeyRoot)
|
|
{
|
|
StrCpyN(szRoot, TEXT("HKLM"), ARRAYSIZE(szRoot));
|
|
}
|
|
else
|
|
{
|
|
StrCpyN(szRoot, TEXT("????"), ARRAYSIZE(szRoot));
|
|
ASSERT(0);
|
|
}
|
|
|
|
AnsiToTChar(pre->pszKey, szTempKey, ARRAYSIZE(szTempKey));
|
|
|
|
szTempValue[0] = TEXT('\0');
|
|
if (pre->pszValName)
|
|
AnsiToTChar(pre->pszValName, szTempValue, ARRAYSIZE(szTempValue));
|
|
|
|
ASSERT(lstrlen(pszBuf) < MAX_PATH);
|
|
wnsprintf(pszBuf, MAX_PATH, TEXT("%s\\%hs\\%hs"), szRoot, szTempKey, szTempValue);
|
|
|
|
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
|
|
GetIEPath2(
|
|
OUT LPSTR pszBuf,
|
|
IN DWORD cchBuf,
|
|
IN BOOL bInsertQuotes)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
HKEY hkey;
|
|
|
|
*pszBuf = '\0';
|
|
|
|
// Get the path of Internet Explorer
|
|
if (NO_ERROR != RegOpenKeyA(HKEY_LOCAL_MACHINE, c_szIexploreKey, &hkey))
|
|
{
|
|
#ifndef UNIX
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): RegOpenKey( %s ) Failed", c_szIexploreKey) ;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
DWORD cbBrowser;
|
|
DWORD dwType;
|
|
|
|
if (bInsertQuotes)
|
|
StrCatBuffA(pszBuf, "\"", cchBuf);
|
|
|
|
cbBrowser = CbFromCchA(cchBuf - lstrlenA(" -nohome") - 4);
|
|
if (NO_ERROR != SHQueryValueExA(hkey, "", NULL, &dwType,
|
|
(LPBYTE)&pszBuf[bInsertQuotes?1:0], &cbBrowser))
|
|
{
|
|
TraceMsg(TF_ERROR, "InstallRegSet(): RegQueryValueEx() for Iexplore path failed");
|
|
}
|
|
else
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
if (bInsertQuotes)
|
|
StrCatBuffA(pszBuf, "\"", cchBuf);
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL
|
|
GetIEPath(
|
|
OUT LPSTR pszBuf,
|
|
IN DWORD cchBuf)
|
|
{
|
|
return GetIEPath2(pszBuf, cchBuf, TRUE);
|
|
}
|
|
|
|
/*----------------------------------------------------------
|
|
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, DWORD dwType)
|
|
{
|
|
BOOL bRet;
|
|
|
|
// Get the path of the Explorer
|
|
if (dwType == REG_EXPAND_SZ)
|
|
{
|
|
StrCpyNA (pszBuf, "%SystemRoot%", cchBuf);
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
bRet = (0 < GetWindowsDirectoryA(pszBuf, cchBuf));
|
|
if (bRet)
|
|
{
|
|
StrCatBuffA(pszBuf, "\\Explorer.exe", cchBuf);
|
|
}
|
|
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);
|
|
|
|
|
|
// Win9x to NT5 migration generated file.
|
|
#define MIGICONS "migicons.exe"
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
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 = (LPCSTR) pvData;
|
|
int cch;
|
|
DWORD dwType; //local type.
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
ASSERT(RSCB_QUERY == nMsg && pvData ||
|
|
RSCB_INSTALL == nMsg && !pvData);
|
|
|
|
if (!g_fRunningOnNT) {
|
|
ASSERT(REG_EXPAND_SZ == pre->dwType);
|
|
dwType = REG_SZ;
|
|
} else
|
|
dwType = (DWORD)pre->dwType;
|
|
|
|
if (dwType == REG_EXPAND_SZ)
|
|
StrCpyNA (sz, "%SystemRoot%\\system32", ARRAYSIZE(sz));
|
|
else
|
|
GetSystemDirectoryA(sz, SIZECHARS(sz));
|
|
cch = lstrlenA(sz);
|
|
|
|
// We still have to use url.dll as the source of the internet shortcut
|
|
// icons because the icons need to still be valid on uninstall.
|
|
wnsprintfA(&sz[cch], ARRAYSIZE(sz) - cch, "\\url.dll,%d", (int)pre->DUMMYUNION_MEMBER(lParam));
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
if (0 != StrCmpNIA(sz, pszPath, dwData / SIZEOF(CHAR)) &&
|
|
0 != StrCmpIA(PathFindFileNameA(sz), PathFindFileNameA(pszPath)))
|
|
{
|
|
// Failed the Url.Dll test. Check if this is NT5. In that case
|
|
// maybe the icons are in migicons.exe (Win9x to NT5 upgrade).
|
|
if (g_bRunOnNT5 && StrStrIA(pszPath,MIGICONS)!= NULL)
|
|
{ // NT5 and 'migicons.exe' => upgrade. Set global to fix this.
|
|
g_bNT5Upgrade = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s is %hs, expecting %hs", Dbg_RegStr(pre, szDbg), pszPath, sz);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RSCB_INSTALL:
|
|
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 default icon to point to a
|
|
given index in iexplore.exe
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
CALLBACK
|
|
HTReg_IEIconProc(
|
|
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 = (LPCSTR) pvData;
|
|
int cch;
|
|
DWORD dwType; //local type.
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
ASSERT(RSCB_QUERY == nMsg && pvData ||
|
|
RSCB_INSTALL == nMsg && !pvData);
|
|
|
|
if (!g_fRunningOnNT) {
|
|
// Sanity check that we don't coerce to REG_SZ wrongfully.
|
|
// If you hit this assert, it means the table entry has the
|
|
// wrong type in it.
|
|
ASSERT(REG_EXPAND_SZ == pre->dwType || REG_SZ == pre->dwType);
|
|
dwType = REG_SZ;
|
|
} else
|
|
dwType = (DWORD)pre->dwType;
|
|
|
|
if (!GetIEPath2(sz, SIZECHARS(sz), FALSE))
|
|
return FALSE;
|
|
|
|
cch = lstrlenA(sz);
|
|
wnsprintfA(&sz[cch], ARRAYSIZE(sz) - cch, ",%d", (int)pre->DUMMYUNION_MEMBER(lParam));
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
if (0 != StrCmpNIA(sz, pszPath, dwData / SIZEOF(CHAR)) &&
|
|
0 != StrCmpA(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:
|
|
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
|
|
CHAR szOther[MAX_PATH + 20]; // Need a bit extra
|
|
LPCSTR pszPath = (LPCSTR) pvData;
|
|
int cch;
|
|
DWORD dwType;
|
|
|
|
DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
|
|
|
|
ASSERT(RSCB_QUERY == nMsg && pvData ||
|
|
RSCB_INSTALL == nMsg && !pvData);
|
|
|
|
ASSERT(REG_EXPAND_SZ == pre->dwType || REG_SZ == pre->dwType);
|
|
|
|
if (!g_fRunningOnNT)
|
|
{
|
|
// Expand string is not supported on Win95
|
|
dwType = REG_SZ;
|
|
}
|
|
else
|
|
{
|
|
dwType = pre->dwType;
|
|
}
|
|
|
|
if (GetIEPath(sz, SIZECHARS(sz))) {
|
|
// sz contains the path as listed in AppPaths\IExplore.
|
|
// NOTE NOTE: GetIEPath() uses the default value which has no
|
|
// terminating ';'. Hence this check is not needed. Anyway, do it and
|
|
// then convert to other form.
|
|
cch = lstrlenA(sz) - 1;
|
|
|
|
if (*sz && sz[cch] == ';')
|
|
sz[cch] = '\0';
|
|
|
|
// Convert this to LFN or SFN as the case may be.
|
|
GetPathOtherFormA(sz, szOther, ARRAYSIZE(szOther));
|
|
|
|
if (pre->DUMMYUNION_MEMBER(lParam))
|
|
{
|
|
StrCatBuffA(sz, (LPSTR)pre->DUMMYUNION_MEMBER(lParam), ARRAYSIZE(sz));
|
|
StrCatBuffA(szOther, (LPSTR)pre->DUMMYUNION_MEMBER(lParam), ARRAYSIZE(szOther));
|
|
}
|
|
|
|
switch (nMsg)
|
|
{
|
|
case RSCB_QUERY:
|
|
if ((0 != StrCmpNIA(pszPath, sz, dwData / SIZEOF(CHAR)))
|
|
&& (0 != StrCmpNIA(pszPath, szOther, 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 (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!
|
|
StrCpyN(szT, sz, ARRAYSIZE(szT));
|
|
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->DUMMYUNION_MEMBER(lParam))
|
|
InstallRegSet((const RegSet *)pre->DUMMYUNION_MEMBER(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;
|
|
|
|
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 a microsoft browser?
|
|
wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("%hs\\shell\\open\\command"), pre->pszKey);
|
|
|
|
cbSize = sizeof(sz);
|
|
if (NO_ERROR == SHGetValue(pre->hkeyRoot, szKey, TEXT(""),
|
|
NULL, sz, &cbSize) &&
|
|
(StrStrI(sz, TEXT(IEXPLORE_EXE)) || StrStrI(sz, TEXT(EXPLORER_EXE))))
|
|
{
|
|
// Yes; proceed to prune this key of all of our values
|
|
TraceMsg(TF_REGCHECK, "Pruning HKCR\\%hs", pre->pszKey);
|
|
|
|
ASSERT(pre->DUMMYUNION_MEMBER(lParam));
|
|
|
|
InstallRegSet((const RegSet *)pre->DUMMYUNION_MEMBER(lParam), FALSE);
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// NOTE: these are ANSI strings by design.
|
|
|
|
const DWORD c_dwEditFlags2 = FTA_Show;
|
|
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[] = "shdocvw.dll,OpenURL %l";
|
|
const CHAR c_szURL[] = "url.dll";
|
|
const CHAR c_szShdocvw[] = "shdocvw.dll";
|
|
const CHAR c_szCheckAssnSwitch[] = "Software\\Microsoft\\Internet Explorer\\Main";
|
|
const CHAR c_szDDE_Default[] = "\"%1\",,-1,0,,,,";
|
|
const CHAR c_szDDE_FileDefault[] = "\"file://%1\",,-1,,,,,";
|
|
|
|
|
|
// Note (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_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_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_szFTPDdeApp[] = "ftp\\shell\\open\\ddeexec\\Application";
|
|
const CHAR c_szFTPDdeifExec[] = "ftp\\shell\\open\\ddeexec\\ifExec";
|
|
|
|
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_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_szHTMDefIcon[] = "htmlfile\\DefaultIcon";
|
|
const CHAR c_szHTMShell[] = "htmlfile\\shell";
|
|
const CHAR c_szHTMOpen[] = "htmlfile\\shell\\open";
|
|
const CHAR c_szHTMOpenCmd[] = "htmlfile\\shell\\open\\command";
|
|
const CHAR c_szHTMOpenDdeexec[] = "htmlfile\\shell\\open\\ddeexec";
|
|
const CHAR c_szHTMOpenDdeTopic[] = "htmlfile\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szHTMOpenDdeApp[] = "htmlfile\\shell\\open\\ddeexec\\Application";
|
|
|
|
const CHAR c_szMHTMDefIcon[] = "mhtmlfile\\DefaultIcon";
|
|
const CHAR c_szMHTMShell[] = "mhtmlfile\\shell";
|
|
const CHAR c_szMHTMOpen[] = "mhtmlfile\\shell\\open";
|
|
const CHAR c_szMHTMOpenCmd[] = "mhtmlfile\\shell\\open\\command";
|
|
const CHAR c_szMHTMOpenDdeexec[] = "mhtmlfile\\shell\\open\\ddeexec";
|
|
const CHAR c_szMHTMOpenDdeTopic[] = "mhtmlfile\\shell\\open\\ddeexec\\Topic";
|
|
const CHAR c_szMHTMOpenDdeApp[] = "mhtmlfile\\shell\\open\\ddeexec\\Application";
|
|
|
|
const CHAR c_szOpenNew[] = "opennew";
|
|
const CHAR c_szHTMOpenNew[] = "htmlfile\\shell\\opennew";
|
|
const CHAR c_szHTMOpenNewCmd[] = "htmlfile\\shell\\opennew\\command";
|
|
const CHAR c_szHTMOpenNewDdeexec[] = "htmlfile\\shell\\opennew\\ddeexec";
|
|
const CHAR c_szHTMOpenNewDdeIfExec[] = "htmlfile\\shell\\opennew\\ddeexec\\IfExec";
|
|
const CHAR c_szHTMOpenNewDdeTopic[] = "htmlfile\\shell\\opennew\\ddeexec\\Topic";
|
|
const CHAR c_szHTMOpenNewDdeApp[] = "htmlfile\\shell\\opennew\\ddeexec\\Application";
|
|
|
|
const CHAR c_szMHTMOpenNew[] = "mhtmlfile\\shell\\opennew";
|
|
const CHAR c_szMHTMOpenNewCmd[] = "mhtmlfile\\shell\\opennew\\command";
|
|
const CHAR c_szMHTMOpenNewDdeexec[] = "mhtmlfile\\shell\\opennew\\ddeexec";
|
|
const CHAR c_szMHTMOpenNewDdeIfExec[] = "mhtmlfile\\shell\\opennew\\ddeexec\\IfExec";
|
|
const CHAR c_szMHTMOpenNewDdeTopic[] = "mhtmlfile\\shell\\opennew\\ddeexec\\Topic";
|
|
const CHAR c_szMHTMOpenNewDdeApp[] = "mhtmlfile\\shell\\opennew\\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_szCLSIDCmdFile[] = "{57651662-CE3E-11D0-8D77-00C04FC99D61}";
|
|
const CHAR c_szCLSIDIntshcut[] = "{FBF23B40-E3F0-101B-8488-00AA003E56F8}";
|
|
const CHAR c_szCLSIDURLExecHook[] = "{AEB6717E-7E19-11d0-97EE-00C04FD91972}";
|
|
|
|
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";
|
|
|
|
//
|
|
// General associations shared across browser-only and full-shell
|
|
//
|
|
|
|
const RegEntry c_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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTP, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED
|
|
|REF_DONTINTRUDE, HKCR, c_szHTTPDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTTPS, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED|REF_DONTINTRUDE, HKCR, c_szHTTPSDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szFTP, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED|REF_DONTINTRUDE, HKCR, c_szFTPDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szGOPHER, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_NOTNEEDED|REF_DONTINTRUDE, HKCR, c_szGOPHERDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
|
|
|
|
// Telnet
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_TELNETNAME) },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szTelnetDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szRLogin, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szRLoginDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szTN3270, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szTN3270DefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szMailTo, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szMailToDefIcon, "", REG_EXPAND_SZ, IDEFICON_MAIL, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKCR, c_szNews, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKCR, c_szNewsDefIcon, "", REG_EXPAND_SZ, IDEFICON_NEWS, 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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ 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_EXPAND_SZ, IDEFICON_STD, 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, "", REG_SZ, sizeof(c_szShdocvw), c_szShdocvw },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "ThreadingModel", REG_SZ, sizeof("Apartment"), "Apartment" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "LoadWithoutCOM", REG_SZ, 1, ""},
|
|
|
|
// HTM file type
|
|
{ RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szHTMDefIcon, "", REG_SZ, (LPARAM)1, HTReg_IEIconProc },
|
|
|
|
// MHTML file type
|
|
{ RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szMHTMDefIcon, "", REG_SZ, (LPARAM)22, HTReg_IEIconProc },
|
|
};
|
|
|
|
|
|
const RegSet c_rsAssoc = {
|
|
ARRAYSIZE(c_rlAssoc),
|
|
c_rlAssoc
|
|
};
|
|
|
|
|
|
//
|
|
// .htm, .html associations for full-shell and browser-only installs
|
|
//
|
|
|
|
// This is run when the browser is opened, and considered a requirement
|
|
// to make IE be the default browser.
|
|
#ifdef UNIX
|
|
const RegEntry c_rlAssocHTM[] = {
|
|
#else
|
|
const RegList c_rlAssocHTM = {
|
|
#endif
|
|
// .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 c_rsAssocHTM = {
|
|
ARRAYSIZE(c_rlAssocHTM),
|
|
c_rlAssocHTM
|
|
};
|
|
|
|
|
|
// 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.
|
|
|
|
// This is needed just to insure webview works.
|
|
//
|
|
const RegEntry c_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 c_rsAssocHTM_WV = {
|
|
ARRAYSIZE(c_rlAssocHTM_WV),
|
|
c_rlAssocHTM_WV
|
|
};
|
|
|
|
|
|
//
|
|
// Browser-only specific association settings
|
|
//
|
|
|
|
const RegEntry c_rlAssoc_Alone[] = {
|
|
// 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_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// 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_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// FTP
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)" %1", 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_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_ADD, REF_DONTINTRUDE, 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_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// File protocol
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFile, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_FILENAME) },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFile, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFile, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFileDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFileOpenCmd, "", REG_SZ, sizeof(c_szFileHandler), c_szFileHandler },
|
|
|
|
// .htm
|
|
//
|
|
// APPCOMPAT:
|
|
// HTMOpenCmd needs to be REG_SZ because Office97 reads it out using RegQueryValue.
|
|
// WebFerret requires the string to be of type REG_SZ.
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// .mht, .mhtml
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szMHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// Internet shortcut
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
|
|
|
|
// Other stuff
|
|
{ RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURLNash), c_szOpenURLNash },
|
|
{ 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 c_rsAssoc_Alone = {
|
|
ARRAYSIZE(c_rlAssoc_Alone),
|
|
c_rlAssoc_Alone
|
|
};
|
|
|
|
|
|
// The reg entries for the browser only case for http, https, and ftp are duplicated here
|
|
const RegEntry c_rlAssoc_Quick[] = {
|
|
// 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_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// 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_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// FTP
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)" %1", 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_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeifExec, "", REG_SZ, sizeof("*"), "*" },
|
|
|
|
};
|
|
|
|
const RegSet c_rsAssoc_Quick = {
|
|
ARRAYSIZE(c_rlAssoc_Quick),
|
|
c_rlAssoc_Quick
|
|
};
|
|
|
|
|
|
|
|
|
|
//
|
|
// Full-shell specific association settings
|
|
//
|
|
|
|
const RegEntry c_rlAssoc_Full[] = {
|
|
// 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_szHTTPDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// 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_szHTTPSDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// FTP
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
{ RC_ADD, REF_DONTINTRUDE, 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_szGOPHERDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
// .htm
|
|
//
|
|
// APPCOMPAT:
|
|
// HTMOpenCmd needs to be REG_SZ because Office97 reads it out using RegQueryValue.
|
|
// WebFerret requires the string to be of type REG_SZ.
|
|
// Visual Source Safe reads the Ddeexec string, puts a file in the %1 (NOT %l!),
|
|
// and performs a dde transaction, so we are pretty much stuck with the "file:%1,,-1,,,,," string now.
|
|
//
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMShell, "", REG_SZ, sizeof(c_szOpenNew), c_szOpenNew },
|
|
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpen, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPENSAME)},
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMShell, "", REG_SZ, sizeof(c_szOpenNew), c_szOpenNew },
|
|
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNew, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPEN)},
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szHTMOpenNewCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default},
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeIfExec, "", REG_SZ, sizeof("*"), "*"},
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeTopic, "", REG_SZ, sizeof("WWW_OpenURLNewWindow"), "WWW_OpenURLNewWindow" },
|
|
|
|
// .mht, .mhtml
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpen, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPENSAME)},
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szMHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
|
|
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNew, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPEN)},
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szMHTMOpenNewCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeIfExec, "", REG_SZ, sizeof("*"), "*"},
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeTopic, "", REG_SZ, sizeof("WWW_OpenURLNewWindow"), "WWW_OpenURLNewWindow" },
|
|
|
|
// 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 },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutOpen, "LegacyDisable", REG_SZ, 1, ""},
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntshcutMayChange, "", REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, c_szIntShcutPropHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
|
|
// add ourselves to the applications key
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "Applications\\iexplore.exe\\shell\\open\\command", "", REG_SZ, (LPARAM)" ""%1""", HTReg_IEPathProc},
|
|
|
|
// Other stuff
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, c_szIEFrameAuto, "", REG_SZ, 0, HTReg_IEPathProc },
|
|
};
|
|
|
|
|
|
const RegSet c_rsAssoc_Full = {
|
|
ARRAYSIZE(c_rlAssoc_Full),
|
|
c_rlAssoc_Full
|
|
};
|
|
|
|
|
|
//
|
|
// On upgrading from Win9x to NT5, the icons are shifted to newly created
|
|
// file called "migicons.exe". This breaks our Assoc checks. Hence this is
|
|
// a list of all HTReg_UrlIconProc checks from the various Assoc arrays that
|
|
// MUST BELONG TO US FOR US TO BE DEFAULT BROWSER (REF_NOTNEEDED and
|
|
// REF_IFEMPTY ==> not used for check purposes).
|
|
// This list is used to fix the icons.
|
|
//
|
|
// NOTE: NOTE: NOTE: NOTE: NOTE: NOTE: NOTE:
|
|
// Any new Icon check that uses HTReg_UrlIconProc that gets added
|
|
// to any of the Assoc arrays and is REQUIRED for Default Browser check to
|
|
// succeed has to be added here also.
|
|
//
|
|
|
|
const RegEntry c_rlAssoc_FixIcon[] = {
|
|
// Icon checks from c_rlAssoc that are essential for us to be Default
|
|
// Browser
|
|
{ RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szIntShcutDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc }
|
|
};
|
|
|
|
const RegSet c_rsAssoc_FixIcon = {
|
|
ARRAYSIZE(c_rlAssoc_FixIcon),
|
|
c_rlAssoc_FixIcon
|
|
};
|
|
|
|
|
|
//
|
|
// General browser-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 RegEntry c_rlGeneral_Alone[] = {
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szFileTypesHook, "", REG_SZ, sizeof(c_szCLSIDMIME), c_szCLSIDMIME },
|
|
|
|
// URL Exec Hook (CLSID_URLExecHook) (this replaces the old overloaded intshcut CLSID)
|
|
{ RC_DEL, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDIntshcut, REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDURLExecHook, REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_URLEXECHOOK) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "", REG_SZ, sizeof("url.dll"), "url.dll" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "ThreadingModel", REG_SZ, sizeof("Apartment"), "Apartment" },
|
|
};
|
|
|
|
const RegSet c_rsGeneral_Alone = {
|
|
ARRAYSIZE(c_rlGeneral_Alone),
|
|
c_rlGeneral_Alone
|
|
};
|
|
|
|
|
|
//
|
|
// General full-shell only settings
|
|
//
|
|
|
|
const RegEntry c_rlGeneral_Full[] = {
|
|
{ RC_DEL, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NUKE, HKLM, c_szFileTypesHook, "", REG_SZ, sizeof(c_szCLSIDMIME), c_szCLSIDMIME },
|
|
|
|
// URL Exec Hook (this replaces the old overloaded intshcut CLSID)
|
|
{ RC_DEL, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDIntshcut, REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDURLExecHook, REG_SZ, 1, "" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_URLEXECHOOK) },
|
|
{ RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "", REG_SZ, sizeof("shell32.dll"), "shell32.dll" },
|
|
{ RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "ThreadingModel", REG_SZ, sizeof("Apartment"), "Apartment" },
|
|
};
|
|
|
|
const RegSet c_rsGeneral_Full = {
|
|
ARRAYSIZE(c_rlGeneral_Full),
|
|
c_rlGeneral_Full
|
|
};
|
|
|
|
|
|
// XP start menu
|
|
// Note: the IE start menu reg entries are created in ie.inx, this table is only needed
|
|
// to restore IE as default browser in the start menu (as a result of the user prompts)
|
|
const RegEntry c_rlStartMenu_XP[] = {
|
|
// make IE the default internet browser for this machine's Start Menu
|
|
{ RC_ADD, REF_NORMAL, HKLM, "Software\\Clients\\StartMenuInternet", "", REG_SZ, 0, "IEXPLORE.EXE" },
|
|
};
|
|
|
|
const RegSet c_rsStartMenu_XP = {
|
|
ARRAYSIZE(c_rlStartMenu_XP),
|
|
c_rlStartMenu_XP
|
|
};
|
|
|
|
const RegEntry c_rlStartMenu_XP_CU[] = {
|
|
// make IE the default internet browser for this user's Start Menu
|
|
{ RC_ADD, REF_NORMAL, HKCU, "Software\\Clients\\StartMenuInternet", "", REG_SZ, 0, "IEXPLORE.EXE" },
|
|
};
|
|
|
|
const RegSet c_rsStartMenu_XP_CU = {
|
|
ARRAYSIZE(c_rlStartMenu_XP_CU),
|
|
c_rlStartMenu_XP_CU
|
|
};
|
|
|
|
/*
|
|
* 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 RegEntry c_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_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
|
|
{ RC_ADD, REF_IFEMPTY, HKLM, SZ_EXMAILTO, "URL Protocol", REG_SZ, 1, "" },
|
|
{ RC_CALLBACK, REF_IFEMPTY, HKLM, SZ_EXMAILTO "\\DefaultIcon", "", REG_EXPAND_SZ, IDEFICON_MAIL, HTReg_UrlIconProc },
|
|
{ RC_RUNDLL, REF_IFEMPTY, HKLM, SZ_EXMAILTO "\\Shell\\Open\\Command", "", REG_SZ, sizeof(c_szMailToHandler), c_szMailToHandler },
|
|
};
|
|
|
|
const RegSet c_rsExchange = {
|
|
ARRAYSIZE(c_rlExchange),
|
|
c_rlExchange
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlAthena[] = {
|
|
#else
|
|
const RegList c_rlAthena = {
|
|
#endif
|
|
{ RC_CALLBACK, REF_NORMAL, HKLM, "", "", REG_SZ, (LPARAM)&c_rsExchange, HTReg_ExchangeProc },
|
|
};
|
|
|
|
const RegSet c_rsAthena = {
|
|
ARRAYSIZE(c_rlAthena),
|
|
c_rlAthena
|
|
};
|
|
|
|
|
|
/*
|
|
* U N I N S T A L L S E T T I N G S
|
|
*
|
|
*/
|
|
|
|
|
|
// Protocol-specific uninstall (for both full-shell and browser-only)
|
|
|
|
const RegEntry c_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 c_rsUnHTTP = {
|
|
ARRAYSIZE(c_rlUnHTTP),
|
|
c_rlUnHTTP
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnHTTPS[] = {
|
|
#else
|
|
const RegList c_rlUnHTTPS = {
|
|
#endif
|
|
{ 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 c_rsUnHTTPS = {
|
|
ARRAYSIZE(c_rlUnHTTPS),
|
|
c_rlUnHTTPS
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnFTP[] = {
|
|
#else
|
|
const RegList c_rlUnFTP = {
|
|
#endif
|
|
{ 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 c_rsUnFTP = {
|
|
ARRAYSIZE(c_rlUnFTP),
|
|
c_rlUnFTP
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnGopher[] = {
|
|
#else
|
|
const RegList c_rlUnGopher = {
|
|
#endif
|
|
{ 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 c_rsUnGopher = {
|
|
ARRAYSIZE(c_rlUnGopher),
|
|
c_rlUnGopher
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnHTM[] = {
|
|
#else
|
|
const RegList c_rlUnHTM = {
|
|
#endif
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMDefIcon, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenDdeexec, "", 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 },
|
|
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szMHTMDefIcon, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_EDITFLAGS, HKCR, "mhtmlfile", "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet c_rsUnHTM = {
|
|
ARRAYSIZE(c_rlUnHTM),
|
|
c_rlUnHTM
|
|
};
|
|
|
|
|
|
// Protocol-specific uninstall for full-shell
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnHTTP_Full[] = {
|
|
#else
|
|
const RegList c_rlUnHTTP_Full = {
|
|
#endif
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeexec, "NoActivateHandler", REG_SZ, 0, NULL }
|
|
};
|
|
|
|
const RegSet c_rsUnHTTP_Full = {
|
|
ARRAYSIZE(c_rlUnHTTP_Full),
|
|
c_rlUnHTTP_Full
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnHTTPS_Full[] = {
|
|
#else
|
|
const RegList c_rlUnHTTPS_Full = {
|
|
#endif
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeexec, "NoActivateHandler", REG_SZ, 0, NULL }
|
|
};
|
|
|
|
const RegSet c_rsUnHTTPS_Full = {
|
|
ARRAYSIZE(c_rlUnHTTPS_Full),
|
|
c_rlUnHTTPS_Full
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnFTP_Full[] = {
|
|
#else
|
|
const RegList c_rlUnFTP_Full = {
|
|
#endif
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet c_rsUnFTP_Full = {
|
|
ARRAYSIZE(c_rlUnFTP_Full),
|
|
c_rlUnFTP_Full
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnGopher_Full[] = {
|
|
#else
|
|
const RegList c_rlUnGopher_Full = {
|
|
#endif
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet c_rsUnGopher_Full = {
|
|
ARRAYSIZE(c_rlUnGopher_Full),
|
|
c_rlUnGopher_Full
|
|
};
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUnHTM_Full[] = {
|
|
#else
|
|
const RegList c_rlUnHTM_Full = {
|
|
// remove the default context menu items
|
|
#endif
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMShell, NULL, REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szMHTMShell, NULL, REG_SZ, 0, NULL },
|
|
|
|
// remove the default values
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNew, NULL, REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNew, NULL, REG_SZ, 0, NULL },
|
|
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szHTMOpenNewCmd, "", REG_SZ, 0, NULL },
|
|
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeApp, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeTopic, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "", REG_SZ, 0, NULL },
|
|
{ RC_DEL, REF_PRUNE, HKCR, c_szMHTMOpenNewCmd, "", REG_SZ, 0, NULL },
|
|
};
|
|
|
|
const RegSet c_rsUnHTM_Full = {
|
|
ARRAYSIZE(c_rlUnHTM_Full),
|
|
c_rlUnHTM_Full
|
|
};
|
|
|
|
//
|
|
// Browser-only uninstall
|
|
//
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUninstall_Alone[] = {
|
|
#else
|
|
const RegList c_rlUninstall_Alone = {
|
|
#endif
|
|
{ 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 },
|
|
|
|
// 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 },
|
|
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnHTTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnHTTPS, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnFTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnGopher, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnHTM, HTReg_UninstallProc },
|
|
};
|
|
|
|
const RegSet c_rsUninstall_Alone = {
|
|
ARRAYSIZE(c_rlUninstall_Alone),
|
|
c_rlUninstall_Alone
|
|
};
|
|
|
|
|
|
//
|
|
// Full-shell uninstall
|
|
//
|
|
|
|
#ifdef UNIX
|
|
const RegEntry c_rlUninstall_Full[] = {
|
|
#else
|
|
const RegList c_rlUninstall_Full = {
|
|
#endif
|
|
// InternetShortcut
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szIntShcutOpen, "CLSID", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
|
|
{ RC_DEL, REF_NORMAL, HKCR, c_szIntShcutOpen, "LegacyDisable", REG_SZ, 1, ""},
|
|
{ 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 },
|
|
|
|
// Protocol associations
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTP_Full, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTPS_Full, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTPS, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnFTP_Full, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnFTP, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnGopher_Full, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnGopher, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTM_Full, HTReg_UninstallProc },
|
|
{ RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTM, HTReg_UninstallProc },
|
|
};
|
|
|
|
const RegSet c_rsUninstall_Full = {
|
|
ARRAYSIZE(c_rlUninstall_Full),
|
|
c_rlUninstall_Full
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* D E F A U L T S E T O F R E G S E T S
|
|
*
|
|
*/
|
|
|
|
|
|
// Common association settings for both browser-only and full-shell
|
|
|
|
// 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 * const g_rgprsDefault[] = {
|
|
&c_rsAssoc,
|
|
&c_rsAssocHTM,
|
|
};
|
|
|
|
// Browser-only specific associations
|
|
|
|
const RegSet * const g_rgprsDefault_Alone[] = {
|
|
&c_rsAssoc_Alone,
|
|
};
|
|
|
|
// Browser-only specific associations for a quick check
|
|
const RegSet * const g_rgprsDefault_Quick[] = {
|
|
&c_rsAssoc_Quick,
|
|
};
|
|
|
|
|
|
// Full-shell specific associations
|
|
|
|
const RegSet * const g_rgprsDefault_Full[] = {
|
|
&c_rsAssoc_Full,
|
|
};
|
|
|
|
// This is the set of icon entries that need to be fixed in case of a
|
|
// Win9x to NT5 upgrade.
|
|
|
|
const RegSet * const g_rgprsDefault_FixIcon[] = {
|
|
&c_rsAssoc_FixIcon,
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// Other registry settings
|
|
//
|
|
|
|
const RegSet * const g_rgprsIE30Only[] =
|
|
{
|
|
&c_rsGeneral_Alone,
|
|
&c_rsAthena,
|
|
};
|
|
|
|
|
|
const RegSet * const g_rgprsNashOnly[] =
|
|
{
|
|
&c_rsGeneral_Full,
|
|
&c_rsAthena,
|
|
};
|
|
|
|
|
|
const RegSet * const g_rgprsUninstallIE30[] =
|
|
{
|
|
&c_rsUninstall_Alone,
|
|
};
|
|
|
|
|
|
const RegSet * const g_rgprsUninstallNash[] =
|
|
{
|
|
&c_rsUninstall_Full,
|
|
};
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Determine if a particular RegSet is installed
|
|
|
|
Returns:
|
|
Cond: --
|
|
*/
|
|
BOOL
|
|
IsRegSetInstalled(
|
|
IN const RegSet * prs)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
UINT i;
|
|
HKEY hkey = NULL;
|
|
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 == HIWORD64(pre->pvValue))
|
|
{
|
|
// Yes; load it
|
|
dwSizeExpect = LoadStringA(g_hinst, PtrToUlong(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)
|
|
{
|
|
wnsprintfA(szT, ARRAYSIZE(szT), RUNDLL_CMD_FMT, (LPSTR)pre->pvValue);
|
|
pvValue = szT;
|
|
|
|
// Add null and convert to bytes
|
|
dwSizeExpect = CbFromCchA(lstrlenA(szT) + 1);
|
|
}
|
|
else
|
|
{
|
|
pvValue = pre->pvValue;
|
|
|
|
if (0 == pre->DUMMYUNION_MEMBER(dwSize))
|
|
dwSizeExpect = (DWORD)CbFromCchA(lstrlenA((LPCSTR)pvValue) + 1);
|
|
else
|
|
dwSizeExpect = (DWORD)pre->DUMMYUNION_MEMBER(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 != StrCmpNIA((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->DUMMYUNION_MEMBER(dwSize))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s size is %d, expecting %d", Dbg_RegStr(pre, szDbg), dwSize, pre->DUMMYUNION_MEMBER(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);
|
|
|
|
StrCpyNA(szPath, pszKey, ARRAYSIZE(szPath));
|
|
|
|
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;
|
|
CHAR 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 (bDontIntrude && IsFlagSet(pre->dwFlags, REF_DONTINTRUDE))
|
|
continue;
|
|
|
|
if (IsFlagSet(pre->dwFlags, REF_IFEMPTY))
|
|
{
|
|
// 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 == HIWORD64(pre->pvValue))
|
|
{
|
|
UINT idRes = PtrToUlong(pre->pvValue);
|
|
// Yes; load it
|
|
dwSize = LoadStringA(g_hinst, idRes, 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);
|
|
|
|
wnsprintfA(szBuffer, ARRAYSIZE(szBuffer), RUNDLL_CMD_FMT, (LPSTR)pre->pvValue);
|
|
pvValue = szBuffer;
|
|
dwSize = CbFromCchA(lstrlenA(szBuffer) + 1);
|
|
}
|
|
else
|
|
{
|
|
// Normal case
|
|
pvValue = pre->pvValue;
|
|
|
|
if (0 == pre->DUMMYUNION_MEMBER(dwSize) && REG_SZ == pre->dwType)
|
|
dwSize = CbFromCchA(lstrlenA((LPCSTR)pvValue) + 1);
|
|
else
|
|
dwSize = pre->DUMMYUNION_MEMBER(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 default value, a named value, or the key?
|
|
if (pre->pszValName == NULL)
|
|
{
|
|
// Default value
|
|
DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting default value %s", Dbg_RegStr(pre, szDbg)); )
|
|
|
|
SHDeleteValueA(pre->hkeyRoot, pre->pszKey, pre->pszValName);
|
|
}
|
|
else if (*pre->pszValName)
|
|
{
|
|
// Named 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);
|
|
|
|
if (hdc)
|
|
{
|
|
wScreen = GetDeviceCaps (hdc, HORZRES);
|
|
hScreen = GetDeviceCaps (hdc, VERTRES);
|
|
ReleaseDC (hwndChild, hdc);
|
|
}
|
|
else
|
|
{
|
|
wScreen = 0;
|
|
hScreen = 0;
|
|
}
|
|
|
|
// 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
|
|
|
|
*/
|
|
BOOL_PTR
|
|
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());
|
|
|
|
if (g_bRunOnNT5)
|
|
{
|
|
// Initialize Checkbox
|
|
// uncheck by default for the first time we show this dialog,
|
|
// user's action is required. we still persist user's last choice.
|
|
if (FALSE == SHRegGetBoolUSValue(REGSTR_PATH_MAIN, TEXT("ShowedCheckBrowser"),
|
|
FALSE, FALSE))
|
|
{
|
|
Button_SetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK), FALSE);
|
|
|
|
// mark we have showed this dialog once.
|
|
LPTSTR sz = TEXT("Yes");
|
|
SHRegSetUSValue(REGSTR_PATH_MAIN, TEXT("ShowedCheckBrowser"), REG_SZ,
|
|
(LPBYTE)sz, CbFromCch(lstrlen(sz)+1), SHREGSET_HKCU | SHREGSET_FORCE_HKCU);
|
|
|
|
}
|
|
else
|
|
{
|
|
Button_SetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK), IsCheckAssociationsOn());
|
|
}
|
|
}
|
|
else
|
|
Button_SetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK), IsCheckAssociationsOn());
|
|
|
|
bMsgHandled = TRUE;
|
|
break;
|
|
|
|
//
|
|
// MSN mucks with the registry in a way that causes IE to ask if it's the
|
|
// default browser. Then after they launch IE they maximize the active
|
|
// window. Since the default browsre dialog is active, it gets maximized.
|
|
// Handeling the WM_GETMINMAXINFO prevents this dialog from maximizing.
|
|
//
|
|
case WM_GETMINMAXINFO:
|
|
{
|
|
LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam;
|
|
|
|
if (lpmmi)
|
|
{
|
|
RECT rc;
|
|
|
|
if (GetWindowRect(hdlg, &rc))
|
|
{
|
|
lpmmi->ptMaxSize.x = rc.right - rc.left;
|
|
lpmmi->ptMaxSize.y = rc.bottom - rc.top;
|
|
|
|
lpmmi->ptMaxPosition.x = rc.left;
|
|
lpmmi->ptMaxPosition.y = rc.top;
|
|
|
|
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
|
|
|
|
*/
|
|
BOOL
|
|
AskUserShouldFixReg()
|
|
{
|
|
return IDYES == SHFusionDialogBoxParam(MLGetHinst(),
|
|
MAKEINTRESOURCE(IDD_ASSOC),
|
|
NULL,
|
|
AssociationDialogProc,
|
|
NULL);
|
|
}
|
|
|
|
|
|
HRESULT InstallFTPAssociations(void)
|
|
{
|
|
IFtpInstaller * pfi;
|
|
HRESULT hr = CoCreateInstance(CLSID_FtpInstaller, NULL, CLSCTX_INPROC_SERVER, IID_IFtpInstaller, (void **) &pfi);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pfi->MakeIEDefautlFTPClient();
|
|
pfi->Release();
|
|
}
|
|
else
|
|
{
|
|
// This may fail to create if FTP wasn't installed, which is
|
|
// a valid install case.
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Install file and protocol association settings in
|
|
registry.
|
|
|
|
*/
|
|
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_BROWSERONLY:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Alone); i++)
|
|
InstallRegSet(g_rgprsDefault_Alone[i], bDontIntrude);
|
|
break;
|
|
|
|
case PLATFORM_INTEGRATED:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Full); i++)
|
|
InstallRegSet(g_rgprsDefault_Full[i], bDontIntrude);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
InstallFTPAssociations();
|
|
|
|
// Notify shell that the associations have changed.
|
|
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Settings that can only be set after user confirmation.
|
|
|
|
*/
|
|
void
|
|
InstallAfterConfirmation(
|
|
BOOL bDontIntrude) // TRUE: be non-intrusive
|
|
{
|
|
// on XP, add IE to show up in the start menu as the Internet app
|
|
if (IsOS(OS_WHISTLERORGREATER))
|
|
{
|
|
// Try to set ourselves as the system default Start Menu web browser
|
|
if (InstallRegSet(&c_rsStartMenu_XP, bDontIntrude))
|
|
{
|
|
// If that succeeds, then clear the per-user setting and let
|
|
// the user float with the system default. This is necessary
|
|
// to allow downlevel browsers like Netscape to come in and
|
|
// take over the default browser and steal the user away from us.
|
|
// (We're so nice and accomodating. I bet they won't extend
|
|
// us the same courtesy!)
|
|
SHDeleteValue(HKEY_CURRENT_USER, TEXT("Software\\Clients\\StartMenuInternet"), NULL);
|
|
}
|
|
else
|
|
{
|
|
// We don't have permission to set the global browser, so set ourselves
|
|
// as the browser for this user.
|
|
InstallRegSet(&c_rsStartMenu_XP_CU, bDontIntrude);
|
|
}
|
|
|
|
SHSendMessageBroadcast(WM_SETTINGCHANGE, 0, (LPARAM)TEXT("Software\\Clients\\StartMenuInternet"));
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Set the CheckAssocation setting in the registry
|
|
|
|
*/
|
|
void
|
|
SetCheckAssociations(
|
|
BOOL fCheck)
|
|
{
|
|
HKEY hk;
|
|
|
|
if (RegOpenKeyExA(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.
|
|
|
|
*/
|
|
BOOL IsCheckAssociationsOn()
|
|
{
|
|
BOOL rval = TRUE;
|
|
CHAR szBuf[20];
|
|
DWORD dwSize = sizeof(szBuf);
|
|
DWORD dwValType;
|
|
|
|
if (NO_ERROR == SHGetValueA(HKEY_CURRENT_USER, c_szCheckAssnSwitch,
|
|
"Check_Associations", &dwValType,
|
|
szBuf, &dwSize))
|
|
{
|
|
if ((dwValType == REG_SZ) && (dwSize < sizeof(szBuf))) {
|
|
if (StrCmpIA( szBuf, "No") == 0)
|
|
rval = FALSE;
|
|
}
|
|
}
|
|
|
|
return( rval );
|
|
}
|
|
|
|
/***********************************************************************
|
|
|
|
These routines are used to repair damage done to Internet Explorer's
|
|
settings by "Netscape Navigator" and "Netscape TuneUp For IE"
|
|
|
|
***********************************************************************/
|
|
|
|
//
|
|
// Prototype for advpack functions
|
|
//
|
|
HRESULT RunSetupCommand(HWND hWnd, LPCSTR szCmdName, LPCSTR szInfSection, LPCSTR szDir, LPCSTR lpszTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved);
|
|
|
|
//
|
|
// This flag tells us whether it's ok to used the
|
|
// cached BOOL for IsResetWebSettingsRequired.
|
|
//
|
|
BOOL g_fAlreadyCheckedForClobber = FALSE;
|
|
|
|
HRESULT RunSetupCommandW(HWND hWnd, LPCWSTR szCmdName, LPCWSTR szInfSection, LPCWSTR szDir, LPCWSTR lpszTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved)
|
|
{
|
|
|
|
CHAR szCmdNameA[MAX_PATH];
|
|
CHAR szInfSectionA[MAX_PATH];
|
|
CHAR szDirA[MAX_PATH];
|
|
|
|
SHUnicodeToAnsi(szCmdName,szCmdNameA,ARRAYSIZE(szCmdNameA));
|
|
SHUnicodeToAnsi(szInfSection,szInfSectionA,ARRAYSIZE(szInfSectionA));
|
|
SHUnicodeToAnsi(szDir,szDirA,ARRAYSIZE(szDirA));
|
|
|
|
ASSERT(NULL == pvReserved);
|
|
ASSERT(NULL == lpszTitle);
|
|
|
|
return RunSetupCommand(hWnd, szCmdNameA, szInfSectionA, szDirA, NULL, phEXE, dwFlags, NULL);
|
|
}
|
|
|
|
|
|
//
|
|
// Path to the inf file
|
|
//
|
|
#define IERESTORE_FILENAME TEXT("iereset.inf")
|
|
#define INF_PATH TEXT("inf")
|
|
|
|
//
|
|
// Names of the sections in our inf file
|
|
//
|
|
#define INFSECTION_HOMEPAGE TEXT("RestoreHomePage")
|
|
#define INFSECTION_SETTINGS TEXT("RestoreBrowserSettings")
|
|
|
|
#define IE_VERIFY_REGKEY TEXT("Software\\Microsoft\\Internet Explorer\\Main")
|
|
#define IE_VERIFY_REGVALUE TEXT("Default_Page_URL")
|
|
|
|
#define INFSECTION_VERIFY TEXT("Strings")
|
|
#define IE_VERIFY_INFKEY TEXT("START_PAGE_URL")
|
|
|
|
void GetIEResetInfFileName(LPWSTR pszBuffer)
|
|
{
|
|
TCHAR szWindowsDir[MAX_PATH];
|
|
|
|
if (NULL == pszBuffer)
|
|
return;
|
|
|
|
GetWindowsDirectory(szWindowsDir,ARRAYSIZE(szWindowsDir));
|
|
|
|
wnsprintfW(
|
|
pszBuffer,
|
|
MAX_PATH,
|
|
TEXT("%s\\%s\\%s"),
|
|
szWindowsDir,INF_PATH,IERESTORE_FILENAME);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CheckIESettings
|
|
*
|
|
* This function will try to determine whether or not IE's settings
|
|
* have been clobbered by another browser.
|
|
*
|
|
* Returns S_OK if IE settings are intact.
|
|
* Returns S_FALSE if someone has mucked with the IE settings
|
|
* Returns E_FAIL on error
|
|
*
|
|
*/
|
|
HRESULT CheckWebSettings(void)
|
|
{
|
|
|
|
TCHAR szInfPath[MAX_PATH];
|
|
TCHAR szDataFromInf[MAX_PATH];
|
|
TCHAR szDataFromReg[MAX_PATH];
|
|
LONG retval;
|
|
|
|
HKEY hkey;
|
|
DWORD dwType;
|
|
DWORD dwSize = sizeof(szDataFromReg);
|
|
//
|
|
// Get the path to the inf file
|
|
//
|
|
GetIEResetInfFileName(szInfPath);
|
|
|
|
//
|
|
// Read the string from the inf file
|
|
//
|
|
retval = SHGetIniString(
|
|
INFSECTION_VERIFY,
|
|
IE_VERIFY_INFKEY,
|
|
szDataFromInf,
|
|
ARRAYSIZE(szDataFromInf),
|
|
szInfPath);
|
|
|
|
if (retval <= 0)
|
|
return E_FAIL;
|
|
|
|
//
|
|
// Open the corresponding key in the registry
|
|
//
|
|
retval = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
IE_VERIFY_REGKEY,
|
|
NULL,
|
|
KEY_READ,
|
|
&hkey);
|
|
|
|
if (retval != ERROR_SUCCESS)
|
|
return E_FAIL;
|
|
|
|
//
|
|
// Read the data from the registry
|
|
//
|
|
retval = RegQueryValueEx(
|
|
hkey,
|
|
IE_VERIFY_REGVALUE,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szDataFromReg,
|
|
&dwSize);
|
|
|
|
if (retval != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hkey);
|
|
return E_FAIL;
|
|
}
|
|
|
|
ASSERT(dwType == REG_SZ);
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
//
|
|
// Return S_OK if they match, S_FALSE if they don't
|
|
//
|
|
return StrCmp(szDataFromReg,szDataFromInf) ? S_FALSE : S_OK;
|
|
|
|
}
|
|
|
|
extern "C" BOOL IsResetWebSettingsRequired(void)
|
|
{
|
|
static BOOL fRequired;
|
|
|
|
if (!g_fAlreadyCheckedForClobber)
|
|
{
|
|
fRequired = (S_FALSE == CheckWebSettings());
|
|
g_fAlreadyCheckedForClobber = TRUE;
|
|
}
|
|
|
|
return fRequired;
|
|
|
|
}
|
|
|
|
HRESULT ResetWebSettingsHelper(BOOL fRestoreHomePage)
|
|
{
|
|
|
|
HRESULT hr;
|
|
TCHAR szTempPath[MAX_PATH];
|
|
TCHAR szInfPath[MAX_PATH];
|
|
|
|
GetTempPath(ARRAYSIZE(szTempPath),szTempPath);
|
|
GetIEResetInfFileName(szInfPath);
|
|
|
|
g_fAlreadyCheckedForClobber = FALSE;
|
|
|
|
//
|
|
// Run the main part of the inf file
|
|
//
|
|
hr = RunSetupCommandW(
|
|
NULL,
|
|
szInfPath,
|
|
INFSECTION_SETTINGS,
|
|
szTempPath,
|
|
NULL,
|
|
NULL,
|
|
RSC_FLAG_INF|RSC_FLAG_QUIET,
|
|
NULL);
|
|
|
|
//
|
|
// Also, reset their homepage if requested to do so
|
|
//
|
|
if (SUCCEEDED(hr) && fRestoreHomePage)
|
|
hr = RunSetupCommandW(
|
|
NULL,
|
|
szInfPath,
|
|
INFSECTION_HOMEPAGE,
|
|
szTempPath,
|
|
NULL,
|
|
NULL,
|
|
RSC_FLAG_INF|RSC_FLAG_QUIET,
|
|
NULL);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Dialog Procedure for the "reset web settings" dialog
|
|
//
|
|
// Return values are:
|
|
//
|
|
// -1 Something went wrong
|
|
// 0 The user changes his/her mind
|
|
// 1 We reset everything except the homepage
|
|
// 2 We reset everything including the homepage
|
|
//
|
|
|
|
BOOL_PTR CALLBACK ResetWebSettingsDlgProc(HWND hdlg, UINT uMsg, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
|
|
CenterWindow(hdlg, GetDesktopWindow());
|
|
CheckDlgButton(hdlg,IDC_RESET_WEB_SETTINGS_HOMEPAGE,BST_CHECKED);
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch(LOWORD(wparam))
|
|
{
|
|
case IDYES:
|
|
{
|
|
HRESULT hr;
|
|
BOOL fResetHomePage = (BST_CHECKED == IsDlgButtonChecked(hdlg,IDC_RESET_WEB_SETTINGS_HOMEPAGE));
|
|
|
|
//
|
|
// Restore the settings to their IE defaults
|
|
//
|
|
hr = ResetWebSettingsHelper(fResetHomePage);
|
|
|
|
if (!IsIEDefaultBrowser())
|
|
{
|
|
InstallRegAssoc(WhichPlatform(), FALSE);
|
|
InstallAfterConfirmation(FALSE);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
EndDialog(hdlg, -1);
|
|
|
|
else if (fResetHomePage)
|
|
EndDialog(hdlg, 2);
|
|
|
|
else
|
|
EndDialog(hdlg, 1);
|
|
|
|
}
|
|
return TRUE;
|
|
|
|
case IDCANCEL:
|
|
case IDNO:
|
|
|
|
EndDialog(hdlg, 0);
|
|
return TRUE;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
HRESULT ResetWebSettings(HWND hwnd, BOOL *pfChangedHomePage)
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
if (pfChangedHomePage)
|
|
*pfChangedHomePage = FALSE;
|
|
|
|
switch (DialogBoxParam(
|
|
MLGetHinst(),
|
|
MAKEINTRESOURCE(IDD_RESET_WEB_SETTINGS),
|
|
hwnd,
|
|
ResetWebSettingsDlgProc,
|
|
NULL))
|
|
{
|
|
case -1:
|
|
hr = E_FAIL;
|
|
break;
|
|
|
|
case 0:
|
|
hr = S_FALSE;
|
|
break;
|
|
|
|
case 1:
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case 2:
|
|
if (pfChangedHomePage)
|
|
*pfChangedHomePage = TRUE;
|
|
hr = S_OK;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
MLShellMessageBox(
|
|
hwnd,
|
|
MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_FAILURE),
|
|
MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_TITLE),
|
|
MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
else if (hr == S_OK)
|
|
{
|
|
MLShellMessageBox(
|
|
hwnd,
|
|
MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_SUCCESS),
|
|
MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_TITLE),
|
|
MB_OK | MB_ICONINFORMATION);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
void EnsureWebViewRegSettings()
|
|
{
|
|
// We do the following mini-check regardless of the user's settings,
|
|
// and for every window we open
|
|
if (!IsRegSetInstalled(&c_rsAssocHTM_WV))
|
|
InstallRegSet(&c_rsAssocHTM_WV, FALSE);
|
|
}
|
|
|
|
void FixIcons()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_FixIcon); i++)
|
|
{
|
|
// 2nd param FALSE ==> always intrude.
|
|
InstallRegSet(g_rgprsDefault_FixIcon[i], FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Function that determines if we are the default browser.
|
|
If not the default browser, this function will
|
|
ask the user to if they want to become the default
|
|
browser and make those changes.
|
|
|
|
*/
|
|
void
|
|
DetectAndFixAssociations()
|
|
{
|
|
TraceMsg(TF_REGCHECK, "Performing expensive registry query for default browser!");
|
|
|
|
// We will become the Default browser if:
|
|
// 1. The User has "Check Associations" On,
|
|
// 2. We don't own the associations, and
|
|
// 3. The user said Yes when we displayed the dialog.
|
|
if (IsCheckAssociationsOn() &&
|
|
!IsIEDefaultBrowser() &&
|
|
AskUserShouldFixReg())
|
|
{
|
|
InstallRegAssoc(WhichPlatform(), FALSE);
|
|
InstallAfterConfirmation(FALSE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
A really quick - non - through check to see if IE is likely the
|
|
default browser
|
|
*/
|
|
|
|
BOOL IsIEDefaultBrowserQuick(void)
|
|
{
|
|
|
|
int i;
|
|
BOOL bAssociated = TRUE;
|
|
|
|
TraceMsg(TF_REGCHECK, "Performing expensive registry query for default browser!");
|
|
|
|
// Check the settings common to all platforms
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Quick); i++)
|
|
{
|
|
if (! IsRegSetInstalled(g_rgprsDefault_Quick[i]))
|
|
bAssociated = FALSE;
|
|
}
|
|
return bAssociated;
|
|
|
|
}
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Function that determines if we are the default browser.
|
|
|
|
*/
|
|
BOOL
|
|
IsIEDefaultBrowser(void)
|
|
{
|
|
int i;
|
|
BOOL bAssociated = TRUE;
|
|
UINT nInstall = WhichPlatform();
|
|
|
|
TraceMsg(TF_REGCHECK, "Performing expensive registry query for default browser!");
|
|
|
|
// Check the settings common to all platforms
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault); i++)
|
|
{
|
|
if (! IsRegSetInstalled(g_rgprsDefault[i]))
|
|
bAssociated = FALSE;
|
|
}
|
|
|
|
if (bAssociated)
|
|
{
|
|
// Check specific to IE or Nashville
|
|
switch (nInstall)
|
|
{
|
|
case PLATFORM_BROWSERONLY:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Alone); i++)
|
|
{
|
|
if (! IsRegSetInstalled(g_rgprsDefault_Alone[i]))
|
|
{
|
|
bAssociated = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PLATFORM_INTEGRATED:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Full); i++)
|
|
{
|
|
if (! IsRegSetInstalled(g_rgprsDefault_Full[i]))
|
|
{
|
|
bAssociated = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If IE is the default browser and this was an NT5Upgrade scenario,
|
|
// fix the Icons references.
|
|
if (g_bNT5Upgrade && bAssociated)
|
|
{
|
|
FixIcons();
|
|
}
|
|
|
|
return bAssociated;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
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
|
|
*/
|
|
BOOL
|
|
AreWeInstallingOverIE(void)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
CHAR sz[MAX_PATH + 20]; // add some padding for arguments
|
|
DWORD cbData = SIZEOF(sz);
|
|
|
|
if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, c_szHTTPOpenCmd, "",
|
|
NULL, sz, &cbData) &&
|
|
StrStrIA(sz, IEXPLORE_EXE) || StrStrIA(sz, EXPLORER_EXE))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "Installing over IEXPLORE.EXE");
|
|
bRet = TRUE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
#if 0
|
|
BOOL ShouldIEBeDefaultBrowser(void)
|
|
{
|
|
BOOL bRet = TRUE; // default to TRUE (eg take over the association)
|
|
CHAR sz[MAX_PATH] = "";
|
|
DWORD cchData = ARRAYSIZE(sz);
|
|
|
|
if (SUCCEEDED(AssocQueryStringA(0, ASSOCSTR_COMMAND, ".htm", NULL, sz, &cchData)))
|
|
{
|
|
if (sz[0] && !StrStrIA(sz, IEXPLORE_EXE))
|
|
{
|
|
TraceMsg(TF_REGCHECK, "%s is the default browser (NOT iexplore.exe)", sz);
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
// if sz[0] is NULL, (probably broken reg) - Let IE be the Default Browser.
|
|
// or IE may be the Default browser setting.
|
|
TraceMsg(TF_REGCHECK, "IEXPLORE.EXE is assumed to be the default browser");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//May be a Broken Registry - Default to IE.
|
|
TraceMsg(TF_REGCHECK, "IEXPLORE.EXE is assumed to be the default browser due to broken Association");
|
|
}
|
|
return bRet;
|
|
|
|
}
|
|
#else
|
|
BOOL ShouldIEBeDefaultBrowser(void)
|
|
{
|
|
BOOL bRet = TRUE; // default to TRUE (eg take over the association)
|
|
CHAR sz[MAX_PATH + 20]; // add some padding for arguments
|
|
DWORD cbData = ARRAYSIZE(sz);
|
|
sz[0] = '\0';
|
|
|
|
if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, ".htm", "", NULL, sz, &cbData))
|
|
{
|
|
if (!sz[0])
|
|
{
|
|
// null key so return TRUE
|
|
return bRet;
|
|
}
|
|
else if (!StrCmpIA(sz, "htmlfile"))
|
|
{
|
|
// Maybe, make sure further
|
|
sz[0] = '\0';
|
|
cbData = ARRAYSIZE(sz);
|
|
|
|
if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, c_szHTMOpenCmd, "",
|
|
NULL, sz, &cbData))
|
|
{
|
|
if (!sz[0] || // if sz[0] is NULL, we will take it over (probably broken reg)
|
|
StrStrIA(sz, IEXPLORE_EXE))
|
|
{
|
|
// Default browser was IE, so we return TRUE
|
|
TraceMsg(TF_REGCHECK, "IEXPLORE.EXE is the default browser");
|
|
}
|
|
else
|
|
{
|
|
TraceMsg(TF_REGCHECK, "%s is the default browser (NOT iexplore.exe)", sz);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// the progid does not point to "htmlfile", so IE cant be the default browser
|
|
TraceMsg(TF_REGCHECK, "%s is the .htm progid (NOT htmlfile)", sz);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
// .htm progid key does not exist, so we return TRUE
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#define SZ_REGKEY_FTPSHELLOPEN TEXT("ftp\\shell\\open")
|
|
#define SZ_REGKEY_COMMAND TEXT("command")
|
|
#define SZ_REGKEY_DDEEXEC TEXT("ddeexec\\ifExec")
|
|
|
|
#define SZ_IEXPLORE_FTP_NEW TEXT("iexplore.exe\" %1")
|
|
#define SZ_IEXPLORE_FTP_OLD TEXT("iexplore.exe\" -nohome")
|
|
|
|
HRESULT UpgradeSettings(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HKEY hKey;
|
|
|
|
LONG lRet = RegOpenKey(HKEY_CLASSES_ROOT, SZ_REGKEY_FTPSHELLOPEN, &hKey);
|
|
hr = HRESULT_FROM_WIN32(lRet);
|
|
if (hKey)
|
|
{
|
|
TCHAR szData[MAX_PATH];
|
|
LONG cbSize = sizeof(szData);
|
|
|
|
lRet = RegQueryValue(hKey, SZ_REGKEY_COMMAND, szData, &cbSize);
|
|
hr = HRESULT_FROM_WIN32(lRet);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD cchStart = (lstrlen(szData) - ARRAYSIZE(SZ_IEXPLORE_FTP_OLD) + 1);
|
|
|
|
// Do we own it?
|
|
if (0 == StrCmp(SZ_IEXPLORE_FTP_OLD, &szData[cchStart]))
|
|
{
|
|
// Yes, so we can upgrade it.
|
|
|
|
// Buffer Overflow isn't a problem because I know SZ_IEXPLORE_FTP_NEW is smaller
|
|
// than SZ_IEXPLORE_FTP_OLD.
|
|
StrCpyN(&szData[cchStart], SZ_IEXPLORE_FTP_NEW, ARRAYSIZE(szData));
|
|
|
|
// Yes, so let's upgrade.
|
|
lRet = RegSetValue(hKey, SZ_REGKEY_COMMAND, REG_SZ, szData, lstrlen(szData));
|
|
hr = HRESULT_FROM_WIN32(lRet);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
lRet = RegSetValue(hKey, SZ_REGKEY_DDEEXEC, REG_SZ, TEXT(""), ARRAYSIZE(TEXT("")));
|
|
hr = HRESULT_FROM_WIN32(lRet);
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Install registry info based upon which shell we're running
|
|
|
|
*/
|
|
HRESULT InstallIEAssociations(DWORD dwFlags) // IEA_* flags
|
|
{
|
|
int i;
|
|
UINT nInstall = WhichPlatform();
|
|
BOOL bDontIntrude = TRUE;
|
|
|
|
// If IE was the default browser before (or the registry is messed up)
|
|
// or setup is forcing us to register then we want to force IE to be
|
|
// the default browser
|
|
if (ShouldIEBeDefaultBrowser() || IsFlagSet(dwFlags, IEA_FORCEIE))
|
|
bDontIntrude = FALSE;
|
|
|
|
// Install file and protocol associations
|
|
|
|
InstallRegAssoc(nInstall, bDontIntrude);
|
|
|
|
// Install other registry settings
|
|
|
|
switch (nInstall)
|
|
{
|
|
case PLATFORM_BROWSERONLY:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsIE30Only); i++)
|
|
{
|
|
InstallRegSet(g_rgprsIE30Only[i], bDontIntrude);
|
|
}
|
|
break;
|
|
|
|
case PLATFORM_INTEGRATED:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsNashOnly); i++)
|
|
{
|
|
InstallRegSet(g_rgprsNashOnly[i], bDontIntrude);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
InstallFTPAssociations();
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
HRESULT UninstallPlatformRegItems(BOOL bIntegrated)
|
|
{
|
|
int i;
|
|
UINT uPlatform = bIntegrated ? PLATFORM_INTEGRATED : PLATFORM_BROWSERONLY;
|
|
|
|
switch (uPlatform)
|
|
{
|
|
case PLATFORM_BROWSERONLY:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsUninstallIE30); i++)
|
|
{
|
|
InstallRegSet(g_rgprsUninstallIE30[i], FALSE);
|
|
}
|
|
break;
|
|
|
|
case PLATFORM_INTEGRATED:
|
|
for (i = 0; i < ARRAYSIZE(g_rgprsUninstallNash); i++)
|
|
{
|
|
InstallRegSet(g_rgprsUninstallNash[i], FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// Don't do anything
|
|
break;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
void UninstallCurrentPlatformRegItems()
|
|
{
|
|
CHAR sz[MAX_PATH + 20]; // add some padding for arguments
|
|
DWORD cbData = SIZEOF(sz);
|
|
if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, c_szHTMOpenNewCmd, "",
|
|
NULL, sz, &cbData))
|
|
{
|
|
// Remove IE4 shell integrated settings
|
|
UninstallPlatformRegItems(TRUE);
|
|
}
|
|
else if (AreWeInstallingOverIE())
|
|
{
|
|
// Remove IE3 / browser only settings
|
|
UninstallPlatformRegItems(FALSE);
|
|
}
|
|
}
|