Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1406 lines
44 KiB

//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1995 **
//*********************************************************************
//
// PROGRAMS.C - "Programs" property sheet UI handlers doe InetCpl
//
//
//
// History:
//
// 6/20/96 t-gpease created
//
#include "inetcplp.h"
#include <mluisupp.h>
#include <advpub.h>
//
// Private Functions and Structures
//
BOOL ProgramsDlgInit( HWND hDlg);
void UpdateMailIconLabel();
typedef struct {
HWND hDlg; // dialog windows handle
HWND hwndMail; // Mail dropdown
HWND hwndNews; // News dropdown
HWND hwndCalendar; // Calendar dropdown
HWND hwndContact; // Contact dropdown
HWND hwndCall; // Internet call dropdown
HWND hwndHtmlEdit; // HTML Editors dropdown
BOOL bAssociationCheck; // Is IE the default browser?
#ifndef UNIX
BOOL bIEIsFTPClient; // Is IE the default FTP Client?
IFtpInstaller * pfi; // FTP Installer
#endif // UNIX
int iHtmlEditor;
int iMail;
int iNews;
int iCalendar;
int iContact;
int iCall;
BOOL fChanged;
#ifdef UNIX
HWND hwndVSource; // View Source
HWND hwndMailEdit;
HWND hwndMailFind;
HWND hwndNewsFind;
HWND hwndNewsEdit;
DWORD dwUseOEMail;
DWORD dwUseOENews;
HWND hwndEnableUseOEMail;
HWND hwndEnableUseOENews;
int iVSource;
#endif
} PROGRAMSPAGE, *LPPROGRAMSPAGE;
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#ifdef WALLET
typedef int (*PFN_DISPLAYWALLETPAYDIALOG_PROC)(HWND, HINSTANCE, LPTSTR, int);
typedef int (*PFN_DISPLAYWALLETADDRDIALOG_PROC)(HWND, HINSTANCE, LPTSTR, int);
// NOTE: This is dumb. Wallet uses different GUIDs for Alpha and x86 versions
//
#ifdef _ALPHA_
static const TCHAR g_szWalletPaymentDirKey[] = TEXT("CLSID\\{B7FB4D5C-9FBE-11D0-8965-0000F822DEA9}\\InprocServer32");
static const TCHAR g_szWalletAddressDirKey[] = TEXT("CLSID\\{B7FB4D5C-9FBE-11D0-8965-0000F822DEA9}\\InprocServer32");
#else
static const TCHAR g_szWalletPaymentDirKey[] = TEXT("CLSID\\{87D3CB66-BA2E-11CF-B9D6-00A0C9083362}\\InprocServer32");
static const TCHAR g_szWalletAddressDirKey[] = TEXT("CLSID\\{87D3CB63-BA2E-11CF-B9D6-00A0C9083362}\\InprocServer32");
#endif
static const char g_szWalletPaymentFN[] = "DisplayWalletPaymentDialog";
static const char g_szWalletAddressFN[] = "DisplayWalletAddressDialog";
HINSTANCE GetWalletPaymentDProc(PFN_DISPLAYWALLETPAYDIALOG_PROC * ppfnDialogProc)
{
TCHAR szDLLFile[MAX_PATH];
DWORD dwType;
DWORD dwSize = SIZEOF(szDLLFile);
HINSTANCE hInst = NULL;
*ppfnDialogProc = NULL;
if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, g_szWalletPaymentDirKey, NULL, &dwType, (LPVOID)szDLLFile, &dwSize))
{
hInst = LoadLibrary(szDLLFile);
// Will Fail if OCX is not installed.
if (hInst)
{
*ppfnDialogProc = (PFN_DISPLAYWALLETPAYDIALOG_PROC) GetProcAddress(hInst, g_szWalletPaymentFN);
}
}
if (!*ppfnDialogProc && hInst)
{
FreeLibrary(hInst);
hInst = NULL;
}
return hInst;
}
BOOL IsWalletPaymentAvailable(VOID)
{
HINSTANCE hInst;
PFN_DISPLAYWALLETPAYDIALOG_PROC pfnDialogProc;
BOOL fIsAvailable = FALSE;
hInst = GetWalletPaymentDProc(&pfnDialogProc);
if (hInst)
{
fIsAvailable = TRUE;
FreeLibrary(hInst);
}
return fIsAvailable;
}
VOID DisplayWalletPaymentDialog(HWND hWnd)
{
HINSTANCE hInst;
PFN_DISPLAYWALLETPAYDIALOG_PROC pfnDialogProc;
hInst = GetWalletPaymentDProc(&pfnDialogProc);
if (hInst)
{
(*pfnDialogProc)(hWnd, NULL, NULL, 0);
FreeLibrary(hInst);
}
}
HINSTANCE GetWalletAddressDProc(PFN_DISPLAYWALLETADDRDIALOG_PROC * ppfnDialogProc)
{
TCHAR szDLLFile[MAX_PATH];
DWORD dwType;
DWORD dwSize = SIZEOF(szDLLFile);
HINSTANCE hInst = NULL;
*ppfnDialogProc = NULL;
if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, g_szWalletAddressDirKey, NULL, &dwType, (LPVOID)szDLLFile, &dwSize))
{
hInst = LoadLibrary(szDLLFile);
// Will Fail if OCX is not installed.
if (hInst)
{
*ppfnDialogProc = (PFN_DISPLAYWALLETADDRDIALOG_PROC) GetProcAddress(hInst, g_szWalletAddressFN);
}
}
if (!*ppfnDialogProc && hInst)
{
FreeLibrary(hInst);
hInst = NULL;
}
return hInst;
}
BOOL IsWallet3Installed()
{
HINSTANCE hInst;
PFN_DISPLAYWALLETADDRDIALOG_PROC pfnDialogProc;
BOOL fWallet3 = FALSE;
hInst = GetWalletAddressDProc(&pfnDialogProc);
if (hInst)
{
CHAR chPath[MAX_PATH];
if (GetModuleFileNameA(hInst, chPath, ARRAYSIZE(chPath)))
{
DWORD dwMSVer, dwLSVer;
if (SUCCEEDED(GetVersionFromFile(chPath, &dwMSVer, &dwLSVer, TRUE)))
{
if (dwMSVer >= 3)
{
fWallet3 = TRUE;
}
}
}
FreeLibrary(hInst);
}
return fWallet3;
}
BOOL IsWalletAddressAvailable(VOID)
{
HINSTANCE hInst;
PFN_DISPLAYWALLETADDRDIALOG_PROC pfnDialogProc;
BOOL fIsAvailable = FALSE;
hInst = GetWalletAddressDProc(&pfnDialogProc);
if (hInst)
{
fIsAvailable = TRUE;
FreeLibrary(hInst);
}
return fIsAvailable;
}
VOID DisplayWalletAddressDialog(HWND hWnd)
{
HINSTANCE hInst;
PFN_DISPLAYWALLETADDRDIALOG_PROC pfnDialogProc;
hInst = GetWalletAddressDProc(&pfnDialogProc);
if (hInst)
{
(*pfnDialogProc)(hWnd, NULL, NULL, 0);
FreeLibrary(hInst);
}
}
#endif // WALLET
//
//
//
// "Programs" Tab
//
//
//
//
// RegPopulateComboBox()
//
// Takes an open HKEY (hkeyProtocol) and populates hwndCB with the friendly
// names of clients. The currently selected client is the "(default)" key of
// hkeyProtocol. The clients are sub-keys under the open key. The friendly
// names of the clients are in the "(default)" value of these sub-keys. This
// function also makes the currently selected client the selected item in
// hwndCB and returns the index number to the item.
//
// History:
//
// 7/ 8/96 t-gpease created
//
UINT RegPopulateComboBox(HWND hwndCB, HKEY hkeyProtocol)
{
TCHAR szFriendlyName [MAX_PATH];
TCHAR szKeyName [MAX_PATH];
TCHAR szCurrent [MAX_PATH];
TCHAR szFriendlyCurrent [MAX_PATH];
FILETIME ftLastWriteTime;
DWORD i; // Index counter
HKEY hkeyClient;
DWORD cb;
// find the currently selected client
cb = sizeof(szCurrent);
if (RegQueryValueEx(hkeyProtocol, NULL, NULL, NULL, (LPBYTE)szCurrent, &cb)
!= ERROR_SUCCESS)
{
// if not found then blank the friendly name and keyname.
szCurrent[0]=0;
szFriendlyCurrent[0]=0;
}
// populate the dropdown
for(i=0; // always start with 0
cb=ARRAYSIZE(szKeyName), // string size
ERROR_SUCCESS==RegEnumKeyEx(hkeyProtocol, i, szKeyName, &cb, NULL, NULL, NULL, &ftLastWriteTime);
i++) // get next entry
{
// get the friendly name of the client
if (RegOpenKeyEx(hkeyProtocol, szKeyName, 0, KEY_READ, &hkeyClient)==ERROR_SUCCESS)
{
cb = sizeof(szFriendlyName);
if (RegQueryValueEx(hkeyClient, NULL, NULL, NULL, (LPBYTE)szFriendlyName, &cb)
== ERROR_SUCCESS)
{
// add name to dropdown
SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)szFriendlyName);
// check to see if it's the current default
if (!StrCmp(szKeyName, szCurrent))
{
// save its the friendly name which we'll use later to
// select the current client and what index it is.
StrCpyN(szFriendlyCurrent, szFriendlyName, ARRAYSIZE(szFriendlyCurrent));
}
}
// close key
RegCloseKey(hkeyClient);
}
} // for
// select current client and get index number... just in case listboxes are sorted we
// are doing this last.
return (unsigned int) SendMessage(hwndCB, CB_SELECTSTRING, (WPARAM) 0, (LPARAM) szFriendlyCurrent);
} // RegPopulateComboBox()
//
// Adds the item and its associated HKEY in the combobox. Stores the hkey
// as data associated with the item. Frees hkey if the item is already present
// or if an error occurs.
//
BOOL AddItemToEditorsCombobox
(
HWND hwndCB,
LPTSTR pszFriendlyName, // friendly name of the app
HKEY hkey // location of assoc shell\edit verb
)
{
ASSERT(pszFriendlyName);
ASSERT(hkey);
BOOL fRet = FALSE;
// Only add if not already in combo
if (SendMessage(hwndCB, CB_FINDSTRINGEXACT, -1, (LPARAM)pszFriendlyName) == CB_ERR)
{
// Add name to dropdown
INT_PTR i = SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)pszFriendlyName);
if (i >= 0)
{
fRet = (SendMessage(hwndCB, CB_SETITEMDATA, i, (LPARAM)hkey) != CB_ERR);
}
}
if (!fRet)
{
RegCloseKey(hkey);
}
return fRet;
}
//
// Adds the edit verb to the OpenWithList associated with .htm files.
//
void AddToOpenWithList(LPCTSTR pszFriendly, HKEY hkeyFrom, HKEY hkeyOpenWithList)
{
ASSERT(pszFriendly);
ASSERT(hkeyFrom);
if (NULL == hkeyOpenWithList)
{
return;
}
TCHAR szBuf[MAX_PATH];
StrCpyN(szBuf, pszFriendly, ARRAYSIZE(szBuf));
StrCatBuff(szBuf, TEXT("\\shell\\edit"), ARRAYSIZE(szBuf));
DWORD dwDisposition;
HKEY hkeyDest;
if (hkeyOpenWithList &&
ERROR_SUCCESS == RegCreateKeyEx(hkeyOpenWithList, szBuf, 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL, &hkeyDest, &dwDisposition))
{
// Copy everything under shell if this item did not exist
if (dwDisposition == REG_CREATED_NEW_KEY)
{
SHCopyKey(hkeyFrom, L"shell\\edit", hkeyDest, 0);
}
RegCloseKey(hkeyDest);
}
}
//
// Returns TRUE if the verb
//
BOOL IsHtmlStub
(
HKEY hkeyVerb, // reg location of the shell\verb\command
LPCWSTR pszVerb // verb to check for ("edit" or "open")
)
{
BOOL fRet = FALSE;
// We don't display programs that are simple redirectors (such as Office's msohtmed.exe)
TCHAR sz[MAX_PATH];
if (SUCCEEDED(AssocQueryStringByKey(ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE, hkeyVerb, pszVerb, sz, (LPDWORD)MAKEINTRESOURCE(SIZECHARS(sz)))))
{
// Get the MULTISZ list of known redirectors
TCHAR szRedir[MAX_PATH];
ZeroMemory(szRedir, sizeof(szRedir)); // Protect against non-multisz strings in the reg
DWORD dwType;
DWORD cb = sizeof(szRedir) - 4;
if (ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_DEFAULT_HTML_EDITOR, L"Stubs", &dwType, szRedir, &cb))
{
// Nothing in registry, so default to ignore the Office redirector
StrCpyN(szRedir, L"msohtmed.exe\0", ARRAYSIZE(szRedir));
}
// Compare exe name with list of redirectors
LPCTSTR pszFile = PathFindFileName(sz);
for (LPTSTR p = szRedir; *p != NULL; p += lstrlen(p) + 1)
{
if (StrCmpI(p, pszFile) == 0)
{
fRet = TRUE;
break;
}
}
}
return fRet;
}
BOOL GetAppKey(LPCWSTR pszApp, HKEY *phkApp)
{
ASSERT(pszApp && *pszApp);
WCHAR szKey[MAX_PATH];
StrCpy(szKey, L"Applications\\");
StrCatBuff(szKey, pszApp, SIZECHARS(szKey));
return (NOERROR == RegOpenKeyEx(
HKEY_CLASSES_ROOT,
szKey,
0L,
MAXIMUM_ALLOWED,
phkApp));
}
//
// Adds the html editors to the combobox. Looks for edit verbs associated
// with the .htm extension, the .htm OpenWithList, and the current default
// editor.
//
void PopulateEditorsCombobox(HWND hwndCB)
{
//
// Add items from the OpenWithList for .htm
//
DWORD dw;
HKEY hkeyOpenWithList = NULL;
TCHAR szOpenWith[MAX_PATH];
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CLASSES_ROOT, L".htm\\OpenWithList", 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL, &hkeyOpenWithList, &dw))
{
//
// First enumerate the entries in the OpenWithList
//
HKEY hkeyOpenWith = NULL;
DWORD dwIndex = 0;
DWORD dwSize = ARRAYSIZE(szOpenWith);
while (ERROR_SUCCESS == RegEnumKeyEx(hkeyOpenWithList, dwIndex, szOpenWith, &dwSize, NULL, NULL, NULL, NULL))
{
if (GetAppKey(szOpenWith, &hkeyOpenWith))
{
// We only accept items that have an edit verb
TCHAR sz[MAX_PATH];
if (SUCCEEDED(AssocQueryStringByKey(ASSOCF_VERIFY, ASSOCSTR_FRIENDLYAPPNAME, hkeyOpenWith, L"edit", sz, (LPDWORD)MAKEINTRESOURCE(SIZECHARS(sz)))))
{
// Note that we store hkeyOpenWith in the combo so don't close it
AddItemToEditorsCombobox(hwndCB, sz, hkeyOpenWith);
}
else
{
RegCloseKey(hkeyOpenWith);
}
}
++dwIndex;
dwSize = ARRAYSIZE(szOpenWith);
}
// hkeyOpenWithList is closed below
}
//
// Add the editor associated with .htm
//
HKEY hkeyHtm;
// FEATURE - should use AssocCreate(IQueryAssociations) here instead
if (SUCCEEDED(AssocQueryKey(0, ASSOCKEY_SHELLEXECCLASS, L".htm", NULL, &hkeyHtm)))
{
TCHAR sz[MAX_PATH];
if (!IsHtmlStub(hkeyHtm, L"edit") &&
SUCCEEDED(AssocQueryStringByKey(ASSOCF_VERIFY, ASSOCSTR_FRIENDLYAPPNAME, hkeyHtm, L"edit", sz, (LPDWORD)MAKEINTRESOURCE(SIZECHARS(sz)))))
{
AddItemToEditorsCombobox(hwndCB, sz, hkeyHtm);
AddToOpenWithList(sz, hkeyHtm, hkeyOpenWithList);
// Don't free the key we cached away
hkeyHtm = NULL;
}
if (hkeyHtm)
{
RegCloseKey(hkeyHtm);
}
}
//
// Get the default editor. We check both hkcu & hklm.
//
HKEY hkeyDefault;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_DEFAULT_HTML_EDITOR, 0, KEY_READ, &hkeyDefault) ||
ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_DEFAULT_HTML_EDITOR, 0, KEY_READ, &hkeyDefault))
{
TCHAR sz[MAX_PATH];
if (SUCCEEDED(AssocQueryStringByKey(ASSOCF_VERIFY, ASSOCSTR_FRIENDLYAPPNAME, hkeyDefault, L"edit", sz, (LPDWORD)MAKEINTRESOURCE(SIZECHARS(sz)))))
{
// Add name to dropdown and save hkeyDefault in the combobox (so don't close it)
AddItemToEditorsCombobox(hwndCB, sz, hkeyDefault);
// Select this item
SendMessage(hwndCB, CB_SELECTSTRING, -1, (LPARAM)sz);
//
// Make sure the default editor is in the htm OpenWithList so it doesn't dissapear
// if we change it
//
AddToOpenWithList(sz, hkeyDefault, hkeyOpenWithList);
}
else
{
RegCloseKey(hkeyDefault);
}
}
if (hkeyOpenWithList)
{
RegCloseKey(hkeyOpenWithList);
}
}
//
// ProgramsDlgInit()
//
// Does initalization for Programs Dlg.
//
// History:
//
// 6/17/96 t-gpease created
// 7/ 8/96 t-gpease added Mail and News initialization
//
BOOL ProgramsDlgInit( HWND hDlg)
{
LPPROGRAMSPAGE pPrg;
DWORD dw;
HKEY hkey;
pPrg = (LPPROGRAMSPAGE)LocalAlloc(LPTR, sizeof(*pPrg));
if (!pPrg)
{
EndDialog(hDlg, 0);
return FALSE; // no memory?
}
// tell dialog where to get info
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pPrg);
// save the handle to the page
pPrg->hDlg = hDlg;
//
// Set default values.
//
pPrg->bAssociationCheck = TRUE; // we want everybody to use IE!
SUCCEEDED(CoCreateInstance(CLSID_FtpInstaller, NULL, CLSCTX_INPROC_SERVER, IID_IFtpInstaller, (void **) &pPrg->pfi));
if (pPrg->pfi)
pPrg->bIEIsFTPClient = ((S_OK == pPrg->pfi->IsIEDefautlFTPClient()) ? TRUE : FALSE);
pPrg->iMail = -1; // nothing selected
pPrg->iNews = -1; // nothing selected
pPrg->bAssociationCheck = SHRegGetBoolUSValue(REGSTR_PATH_MAIN,REGSTR_VAL_CHECKASSOC,FALSE,TRUE);
//
// Get the html editors
//
pPrg->hwndHtmlEdit = GetDlgItem(pPrg->hDlg, IDC_PROGRAMS_HTMLEDITOR_COMBO);
PopulateEditorsCombobox(pPrg->hwndHtmlEdit);
// Sundown: coercion to int because 32b is sufficient for cursor selection
pPrg->iHtmlEditor = (int) SendMessage(pPrg->hwndHtmlEdit, CB_GETCURSEL, 0, 0);
//
// Get the Mail Clients
//
pPrg->hwndMail = GetDlgItem(pPrg->hDlg, IDC_PROGRAMS_MAIL_COMBO);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_MAILCLIENTS,
0, NULL, 0, KEY_READ, NULL, &hkey, &dw) == ERROR_SUCCESS)
{
// populate the combobox
pPrg->iMail = RegPopulateComboBox(pPrg->hwndMail, hkey);
// close the keys
RegCloseKey(hkey);
}
//
// Get the News Clients
//
pPrg->hwndNews = GetDlgItem(pPrg->hDlg, IDC_PROGRAMS_NEWS_COMBO);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_NEWSCLIENTS,
0, NULL, 0, KEY_READ, NULL, &hkey, &dw) == ERROR_SUCCESS)
{
// populate the combobox
pPrg->iNews = RegPopulateComboBox(pPrg->hwndNews, hkey);
// close the keys
RegCloseKey(hkey);
}
//
// get the calendar clients
//
pPrg->hwndCalendar = GetDlgItem(pPrg->hDlg, IDC_PROGRAMS_CALENDAR_COMBO);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CALENDARCLIENTS,
0, NULL, 0, KEY_READ, NULL, &hkey, &dw) == ERROR_SUCCESS)
{
// populate the combobox
pPrg->iCalendar = RegPopulateComboBox(pPrg->hwndCalendar, hkey);
// close the keys
RegCloseKey(hkey);
}
//
// get the contacts clients
//
pPrg->hwndContact = GetDlgItem(pPrg->hDlg, IDC_PROGRAMS_CONTACT_COMBO);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTACTCLIENTS,
0, NULL, 0, KEY_READ, NULL, &hkey, &dw) == ERROR_SUCCESS)
{
// populate the combobox
pPrg->iContact = RegPopulateComboBox(pPrg->hwndContact, hkey);
// close the keys
RegCloseKey(hkey);
}
//
// get the internet call clients
//
pPrg->hwndCall = GetDlgItem(pPrg->hDlg, IDC_PROGRAMS_CALL_COMBO);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CALLCLIENTS,
0, NULL, 0, KEY_READ, NULL, &hkey, &dw) == ERROR_SUCCESS)
{
// populate the combobox
pPrg->iCall = RegPopulateComboBox(pPrg->hwndCall, hkey);
// close the keys
RegCloseKey(hkey);
}
// Set dialog items
CheckDlgButton(hDlg, IDC_CHECK_ASSOCIATIONS_CHECKBOX, pPrg->bAssociationCheck);
HRESULT hrIEDefaultFTPClient = E_FAIL;
if (pPrg->pfi)
{
hrIEDefaultFTPClient = pPrg->pfi->IsIEDefautlFTPClient();
// Is this option not applicable because only the IE FTP client is installed?
if (SUCCEEDED(hrIEDefaultFTPClient))
CheckDlgButton(hDlg, IDC_PROGRAMS_IE_IS_FTPCLIENT, pPrg->bIEIsFTPClient);
}
if (FAILED(hrIEDefaultFTPClient))
{
// Yes, so remove the option.
ShowWindow(GetDlgItem(hDlg, IDC_PROGRAMS_IE_IS_FTPCLIENT), SW_HIDE);
}
if( g_restrict.fMailNews )
{
EnableWindow( GetDlgItem(hDlg, IDC_PROGRAMS_MAIL_COMBO), FALSE);
EnableWindow( GetDlgItem(hDlg, IDC_PROGRAMS_NEWS_COMBO), FALSE);
EnableWindow( GetDlgItem(hDlg, IDC_PROGRAMS_CALL_COMBO), FALSE);
}
if ( g_restrict.fCalContact )
{
EnableWindow( GetDlgItem(hDlg, IDC_PROGRAMS_CALENDAR_COMBO), FALSE);
EnableWindow( GetDlgItem(hDlg, IDC_PROGRAMS_CONTACT_COMBO), FALSE);
}
EnableWindow( GetDlgItem(hDlg, IDC_RESETWEBSETTINGS), !g_restrict.fResetWebSettings );
EnableWindow( GetDlgItem(hDlg, IDC_CHECK_ASSOCIATIONS_CHECKBOX), !g_restrict.fDefault );
return TRUE; // success
} // ProgramsDlgInit()
//
// RegCopyKey()
//
// Copies all the keys from hkeySrc down into hkeyRoot:pszDest.
//
// History:
//
// 7/ 8/96 t-gpease created
//
void RegCopyKey(HKEY hkeyRoot, const TCHAR *pszDest, HKEY hkeySrc)
{
HKEY hkeyDest;
HKEY hkey;
DWORD dw;
DWORD i;
DWORD cb;
DWORD cbData;
DWORD Type;
TCHAR szName[MAX_PATH];
TCHAR szData[MAX_URL_STRING+1];
// open/create the destination key
if (RegCreateKeyEx(hkeyRoot, pszDest,
NULL, 0, NULL, KEY_READ|KEY_WRITE, NULL, &hkeyDest, &dw) == ERROR_SUCCESS)
{
i=0;
// copy values of the key
while(1)
{
// find next value
cb=ARRAYSIZE(szName);
cbData=sizeof(szData);
if (RegEnumValue(hkeySrc, i, szName, &cb, NULL, &Type, (LPBYTE)&szData, &cbData)!=ERROR_SUCCESS)
break; // not found... exit loop
// make a copy of the value in new location
RegSetValueEx(hkeyDest, szName, NULL, Type, (CONST BYTE *)szData, cbData);
// increase index count
i++;
} // while
// look for more sub-keys in the source
for(i=0;
cb=ARRAYSIZE(szName),
RegEnumKey(hkeySrc, i, szName, cb)==ERROR_SUCCESS;
i++)
{
// open the sub-key
if (RegCreateKeyEx(hkeySrc, szName,
NULL, 0, NULL, KEY_READ, NULL, &hkey, &dw) == ERROR_SUCCESS)
{
// copy the sub-key
RegCopyKey(hkeyDest, szName, hkey);
// close the key
RegCloseKey(hkey);
} // if RegCreateKey()
} // for
// close the key
RegCloseKey(hkeyDest);
} // if RegCreateKey()
} // RegCopyKey()
//
// CopyInfoTo()
//
// Copies the information needed to run a mailto: or news: protocol
//
// History:
//
// 7/ 8/96 t-gpease created
//
void CopyInfoTo(const TCHAR *pszKeyName, HKEY hkeyClient)
{
HKEY hkey;
TCHAR szName[MAX_PATH];
// create the protocol sub-key path
StrCpyN(szName, TSZPROTOCOLSPATH, ARRAYSIZE(szName));
int len = lstrlen(szName);
StrCpyN(szName + len, pszKeyName, ARRAYSIZE(szName) - len);
// make sure it has the protocol we are looking for
if (RegOpenKeyEx(hkeyClient, szName, NULL, KEY_READ|KEY_WRITE, &hkey)
==ERROR_SUCCESS)
{
// Netscape Messenger registry patch: they are missing "URL Protocol" in the HKLM mailto branch
// and we should set this value, otherwise we get the 68992 bug. The source is changed rather
// than the destination to protect against other programs copying the tree without the value.
// Might as well check this for all clients rather than look for Netscape, since we don't
// change any data if it exists.
if (lstrcmpi(pszKeyName, TSZMAILTOPROTOCOL) == 0 &&
RegQueryValueEx(hkey, TEXT("URL Protocol"), NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
RegSetValueEx(hkey, TEXT("URL Protocol"), 0, REG_SZ, (BYTE *) TEXT(""), sizeof(TCHAR));
}
// start by deleting all the old info
if ( lstrcmpi(pszKeyName, TSZLDAPPROTOCOL) )
SHDeleteKey(HKEY_CLASSES_ROOT, pszKeyName);
// recreate key and copy the protocol info
RegCopyKey(HKEY_CLASSES_ROOT, pszKeyName, hkey);
// close the key
RegCloseKey(hkey);
} // if RegOpenKey()
} // CopyInfoTo()
//
// FindClient()
//
// Finds the currently selected item in hwndComboBox and locates it
// in the szPath's subkeys. If found it will then make a call to copy
// the information to szProtocol key under HKCR.
//
// History:
//
// 7/ 8/96 t-gpease created
//
void FindClient(LPCTSTR szProtocol, HWND hwndComboBox, int iSelected, LPCTSTR szPath)
{
TCHAR szFriendlyName[MAX_PATH];
TCHAR szKeyName[MAX_PATH];
TCHAR szCurrent[MAX_PATH];
FILETIME ftLastWriteTime;
DWORD i; // Index counter
HKEY hkeyClient;
HKEY hkey;
DWORD dw;
// get the name of the new client
if (CB_ERR!=SendMessage(hwndComboBox, CB_GETLBTEXT, (WPARAM)iSelected, (LPARAM)szCurrent))
{
// got the friendly name... now lets find the internal name
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szPath,
0, NULL, 0, KEY_READ|KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS)
{
DWORD cb;
// we must search all the sub-keys for the correct friendly name
for(i=0; // always start with 0
cb=ARRAYSIZE(szKeyName), // string size
ERROR_SUCCESS==RegEnumKeyEx(hkey, i, szKeyName, &cb, NULL, NULL, NULL, &ftLastWriteTime);
i++) // get next entry
{
// get more info on the entry
if (RegOpenKeyEx(hkey, szKeyName, 0, KEY_READ, &hkeyClient)==ERROR_SUCCESS)
{
// get the friendly name of the client
cb = sizeof(szFriendlyName);
if (RegQueryValueEx(hkeyClient, NULL, NULL, NULL, (LPBYTE)szFriendlyName, &cb)
== ERROR_SUCCESS)
{
// is it the one we are looking for?
if (!StrCmp(szFriendlyName, szCurrent))
{
// yep... copy its info
CopyInfoTo(szProtocol, hkeyClient);
// make it the default handler
cb = (lstrlen(szKeyName) + 1)*sizeof(TCHAR);
RegSetValueEx(hkey, NULL, NULL, REG_SZ, (LPBYTE)szKeyName, cb);
}
}
// close key
RegCloseKey(hkeyClient);
} // if RegOpenKey()
} // for
// close the keys
RegCloseKey(hkey);
} // if RegCreateKeyEx()
}
} // FindClient()
//
// ProgramsDlgApplyNow()
//
// Enters "Programs" changes into registry.
//
// History:
//
// 6/20/96 t-gpease created
// 7/ 8/96 t-gpease added Mail and News
//
void ProgramsDlgApplyNow(LPPROGRAMSPAGE pPrg)
{
int tmp;
if (pPrg->fChanged)
{
// Did the user have a chance to change this option?
if (pPrg->pfi)
{
HRESULT hrIEDefaultFTPClient = pPrg->pfi->IsIEDefautlFTPClient();
if (IsWindowVisible(GetDlgItem(pPrg->hDlg, IDC_PROGRAMS_IE_IS_FTPCLIENT)))
{
// Yes, so see if they changed it.
pPrg->bIEIsFTPClient = IsDlgButtonChecked(pPrg->hDlg, IDC_PROGRAMS_IE_IS_FTPCLIENT);
// Did they user want IE as default and currently someone else is?
if (pPrg->bIEIsFTPClient && (S_FALSE == hrIEDefaultFTPClient))
pPrg->pfi->MakeIEDefautlFTPClient();
// Did they user NOT want IE as default and it currently is?
if (!pPrg->bIEIsFTPClient && (S_OK == hrIEDefaultFTPClient))
pPrg->pfi->RestoreFTPClient();
}
}
pPrg->bAssociationCheck = IsDlgButtonChecked(pPrg->hDlg, IDC_CHECK_ASSOCIATIONS_CHECKBOX);
TCHAR szYesNo[5];
StrCpyN(szYesNo, (pPrg->bAssociationCheck ? TEXT("yes") : TEXT("no")), ARRAYSIZE(szYesNo));
SHRegSetUSValue(REGSTR_PATH_MAIN,
REGSTR_VAL_CHECKASSOC,
REG_SZ,
(LPVOID)szYesNo,
(lstrlen(szYesNo)+1)*sizeof(TCHAR),
SHREGSET_DEFAULT);
//
// Save the new default editor
//
// See if the selection was changed
tmp = (int) SendMessage(pPrg->hwndHtmlEdit, CB_GETCURSEL, 0, 0);
if (tmp != pPrg->iHtmlEditor)
{
pPrg->iHtmlEditor = tmp;
// Get the text and hkey for the selected item
WCHAR szDefault[MAX_PATH];
SendMessage(pPrg->hwndHtmlEdit, CB_GETLBTEXT, tmp, (LPARAM)szDefault);
HKEY hkeyFrom = (HKEY)SendMessage(pPrg->hwndHtmlEdit, CB_GETITEMDATA, tmp, 0);
if (hkeyFrom && (INT_PTR)hkeyFrom != CB_ERR)
{
//
// Save the selected item as the default editor
//
DWORD dw;
HKEY hkeyDest;
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_DEFAULT_HTML_EDITOR, 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL, &hkeyDest, &dw))
{
// Update the name of the default editor
SHSetValue(hkeyDest, NULL, L"Description", REG_SZ, szDefault, CbFromCch(lstrlen(szDefault)+1));
// Delete the old shell command (and all subkeys). This purges keys such as DDEEXEC.
SHDeleteKey(hkeyDest, L"shell");
// Update the verb of the default editor
HKEY hkeyEdit;
if (ERROR_SUCCESS == RegCreateKeyEx(hkeyDest, L"shell\\edit", 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL, &hkeyEdit, &dw))
{
SHCopyKey(hkeyFrom, L"shell\\edit", hkeyEdit, 0);
RegCloseKey(hkeyEdit);
}
RegCloseKey(hkeyDest);
}
//
// Also update Office's default editor
//
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Shared\\HTML\\Default Editor", 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL, &hkeyDest, &dw))
{
// Delete the old shell command (and all subkeys). This purges keys such as DDEEXEC.
SHDeleteKey(hkeyDest, L"shell\\edit");
// Update the verb of the default editor
HKEY hkeyEdit;
if (ERROR_SUCCESS == RegCreateKeyEx(hkeyDest, L"shell\\edit", 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL, &hkeyEdit, &dw))
{
SHCopyKey(hkeyFrom, L"shell\\edit", hkeyEdit, 0);
RegCloseKey(hkeyEdit);
}
RegCloseKey(hkeyDest);
}
//
// Finally, update the edit verb for .htm files so that the shell honors the change.
// But if .htm uses a stub like moshtmed, we leave it alone and assume that it
// uses one of the above keys as the default editor.
//
HKEY hkeyHtm;
if (SUCCEEDED(AssocQueryKey(0, ASSOCKEY_SHELLEXECCLASS, L".htm", NULL, &hkeyHtm)))
{
if (!IsHtmlStub(hkeyHtm, L"edit"))
{
// Delete the old shell command (and all subkeys). This purges keys such as DDEEXEC.
SHDeleteKey(hkeyHtm, L"shell\\edit");
// Copy the edit verb to the .htm
HKEY hkeyEdit;
if (ERROR_SUCCESS == RegCreateKeyEx(hkeyHtm, L"shell\\edit", 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL, &hkeyEdit, &dw))
{
SHCopyKey(hkeyFrom, L"shell\\edit", hkeyEdit, 0);
RegCloseKey(hkeyEdit);
}
}
RegCloseKey(hkeyHtm);
}
}
}
//
// Save Mail Client Info
//
// is there a new client?
tmp = (int) SendMessage(pPrg->hwndMail, CB_GETCURSEL, 0, 0);
if (tmp!=pPrg->iMail)
{
pPrg->iMail = tmp;
// find it and copy its info
FindClient(TSZMAILTOPROTOCOL, pPrg->hwndMail, tmp, REGSTR_PATH_MAILCLIENTS);
//Update the mail icon label
UpdateMailIconLabel();
// tell the world that something has changed
SendBroadcastMessage(WM_WININICHANGE, 0, (LPARAM)REGSTR_PATH_MAILCLIENTS);
}
//
// Save News Client Info
//
// is there a new client?
tmp = (int) SendMessage(pPrg->hwndNews, CB_GETCURSEL, 0, 0);
if (tmp!=pPrg->iNews)
{
pPrg->iNews = tmp;
// find it and copy its info
FindClient(TSZNEWSPROTOCOL, pPrg->hwndNews, tmp, REGSTR_PATH_NEWSCLIENTS);
FindClient(TEXT("snews"), pPrg->hwndNews, tmp, REGSTR_PATH_NEWSCLIENTS);
FindClient(TEXT("nntp"), pPrg->hwndNews, tmp, REGSTR_PATH_NEWSCLIENTS);
// tell the world that something has changed
SendBroadcastMessage(WM_WININICHANGE, 0, (LPARAM)REGSTR_PATH_NEWSCLIENTS);
}
//
// Save Internet Call Client info
//
// is there a new client?
tmp = (int) SendMessage(pPrg->hwndCall, CB_GETCURSEL, 0, 0);
if (tmp!=pPrg->iCall)
{
pPrg->iCall = tmp;
// find it and copy its info
FindClient(TSZCALLTOPROTOCOL, pPrg->hwndCall, tmp, REGSTR_PATH_CALLCLIENTS);
// tell the world that something has changed
SendBroadcastMessage(WM_WININICHANGE, 0, (LPARAM)REGSTR_PATH_CALLCLIENTS);
}
//
// Save Contacts Client Info
//
// is there a new client?
tmp = (int) SendMessage(pPrg->hwndContact, CB_GETCURSEL, 0, 0);
if (tmp!=pPrg->iContact)
{
pPrg->iContact = tmp;
// find it and copy its info
FindClient(TSZLDAPPROTOCOL, pPrg->hwndContact, tmp, REGSTR_PATH_CONTACTCLIENTS);
// tell the world that something has changed
SendBroadcastMessage(WM_WININICHANGE, 0, (LPARAM)REGSTR_PATH_CONTACTCLIENTS);
}
//
// Save Calendar Client Info
//
// is there a new client?
tmp = (int) SendMessage(pPrg->hwndCalendar, CB_GETCURSEL, 0, 0);
if (tmp!=pPrg->iCalendar)
{
pPrg->iCalendar = tmp;
// find it and copy its info
FindClient(TSZCALENDARPROTOCOL, pPrg->hwndCalendar, tmp, REGSTR_PATH_CALENDARCLIENTS);
// tell the world that something has changed
SendBroadcastMessage(WM_WININICHANGE, 0, (LPARAM)REGSTR_PATH_CALENDARCLIENTS);
}
UpdateAllWindows();
pPrg->fChanged = FALSE;
}
} // ProgramsDlgApplyNow()
extern HRESULT ResetWebSettings(HWND hwnd, BOOL *pfChangedHomePage);
//
// ProgramsOnCommand()
//
// Handles "Programs" property page's window commands
//
// History:
//
// 6/20/96 t-gpease created
//
void ProgramsOnCommand(LPPROGRAMSPAGE pPrg, UINT id, UINT nCmd)
{
switch (id) {
case IDC_PROGRAMS_HTMLEDITOR_COMBO:
{
INT_PTR tmp;
// Is there a new editor?
tmp = SendMessage(pPrg->hwndHtmlEdit, CB_GETCURSEL, 0, 0);
if (tmp != pPrg->iHtmlEditor)
{
ENABLEAPPLY(pPrg->hDlg);
pPrg->fChanged = TRUE;
}
}
break;
case IDC_PROGRAMS_NEWS_COMBO:
{
INT_PTR tmp;
// is there a new client?
tmp = SendMessage(pPrg->hwndNews, CB_GETCURSEL, 0, 0);
if (tmp != pPrg->iNews)
{
ENABLEAPPLY(pPrg->hDlg);
pPrg->fChanged = TRUE;
}
}
break;
case IDC_PROGRAMS_MAIL_COMBO:
{
INT_PTR tmp;
// is there a new client?
tmp = SendMessage(pPrg->hwndMail, CB_GETCURSEL, 0, 0);
if (tmp != pPrg->iMail)
{
ENABLEAPPLY(pPrg->hDlg);
pPrg->fChanged = TRUE;
}
}
break;
case IDC_PROGRAMS_CALENDAR_COMBO:
{
INT_PTR tmp;
// is there a new client?
tmp = SendMessage(pPrg->hwndCalendar, CB_GETCURSEL, 0, 0);
if (tmp != pPrg->iCalendar)
{
ENABLEAPPLY(pPrg->hDlg);
pPrg->fChanged = TRUE;
}
}
break;
case IDC_PROGRAMS_CONTACT_COMBO:
{
INT_PTR tmp;
// is there a new client?
tmp = SendMessage(pPrg->hwndContact, CB_GETCURSEL, 0, 0);
if (tmp != pPrg->iContact)
{
ENABLEAPPLY(pPrg->hDlg);
pPrg->fChanged = TRUE;
}
}
break;
case IDC_PROGRAMS_CALL_COMBO:
{
INT_PTR tmp;
// is there a new client?
tmp = SendMessage(pPrg->hwndCall, CB_GETCURSEL, 0, 0);
if (tmp != pPrg->iCall)
{
ENABLEAPPLY(pPrg->hDlg);
pPrg->fChanged = TRUE;
}
}
break;
case IDC_RESETWEBSETTINGS:
{
BOOL fReloadHomePage;
ResetWebSettings(pPrg->hDlg,&fReloadHomePage);
if (fReloadHomePage)
g_fReloadHomePage = TRUE;
}
break;
case IDC_PROGRAMS_IE_IS_FTPCLIENT:
case IDC_CHECK_ASSOCIATIONS_CHECKBOX:
ENABLEAPPLY(pPrg->hDlg);
pPrg->fChanged = TRUE;
break;
} // switch
} // ProgramsOnCommand()
//
// ProgramsDlgProc()
//
// Handles window messages sent to the Programs Property Sheet.
//
// History:
//
// 6/20/96 t-gpease created
//
INT_PTR CALLBACK ProgramsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
LPPROGRAMSPAGE pPrg;
if (uMsg == WM_INITDIALOG)
return ProgramsDlgInit( hDlg );
else
pPrg= (LPPROGRAMSPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
if (!pPrg)
return FALSE;
switch (uMsg) {
case WM_COMMAND:
ProgramsOnCommand(pPrg, LOWORD(wParam), HIWORD(wParam));
return TRUE;
case WM_NOTIFY:
{
NMHDR *lpnm = (NMHDR *) lParam;
ASSERT(lpnm);
switch (lpnm->code)
{
case PSN_KILLACTIVE:
case PSN_QUERYCANCEL:
case PSN_RESET:
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
return TRUE;
case PSN_APPLY:
//
// Save Programs Dlg Stuff.
//
ProgramsDlgApplyNow(pPrg);
break;
}
}
break;
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_DESTROY:
{
// Free the data stored the HTML editor combo
int iMax = (int) SendMessage(pPrg->hwndHtmlEdit, CB_GETCOUNT, 0, 0);
HKEY hkey;
for (int i = 0; i < iMax; ++i)
{
hkey = (HKEY) SendMessage(pPrg->hwndHtmlEdit, CB_GETITEMDATA, i, 0);
if (hkey && (INT_PTR)hkey != CB_ERR)
{
RegCloseKey(hkey);
}
}
if (pPrg)
{
if (pPrg->pfi)
pPrg->pfi->Release();
LocalFree(pPrg);
}
SetWindowLongPtr(hDlg, DWLP_USER, (LONG)NULL);
break;
}
}
return FALSE;
}
static const TCHAR c_szMailIcon[] = TEXT("Software\\Microsoft\\MailIcon");
static const TCHAR c_szMailIconGuid[] = TEXT("CLSID\\{dacf95b0-0a3f-11d1-9389-006097d503d9}");
static const TCHAR c_szKeyMail[] = TEXT("Software\\Clients\\Mail");
static const TCHAR c_szRegFmt2[] = TEXT("%s\\%s");
static const TCHAR c_szFormatClient[] = TEXT("FormatClient");
static const TCHAR c_szFormatNoClient[] = TEXT("FormatNoClient");
static WCHAR c_wszMailIconGuid[] = L"::{dacf95b0-0a3f-11d1-9389-006097d503d9}";
void UpdateMailIconLabel()
{
TCHAR szOldLabel[MAX_PATH];
TCHAR szNewLabel[MAX_PATH];
TCHAR szDefClient[MAX_PATH];
TCHAR szTemp[MAX_PATH];
DWORD cbSize;
HKEY hKey;
*szNewLabel = 0;
*szOldLabel = 0;
// check if the mail icon is even installed
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szMailIcon, 0, KEY_READ, &hKey))
{
cbSize = sizeof(szOldLabel);
// get the current mail icon label
if (ERROR_SUCCESS == RegQueryValue(HKEY_CLASSES_ROOT, c_szMailIconGuid, szOldLabel, (PLONG)&cbSize))
{
cbSize = sizeof(szDefClient);
// get the default client's reg key
if (ERROR_SUCCESS == RegQueryValue(HKEY_LOCAL_MACHINE, c_szKeyMail, szDefClient, (PLONG)&cbSize) && cbSize)
{
wnsprintf(szTemp, ARRAYSIZE(szTemp), c_szRegFmt2, c_szKeyMail, szDefClient);
cbSize = sizeof(szDefClient);
// get the default client's display name
if (ERROR_SUCCESS == RegQueryValue(HKEY_LOCAL_MACHINE, szTemp, szDefClient, (PLONG)&cbSize) && cbSize)
{
cbSize = sizeof(szTemp);
// get the mail icon label format string
if (ERROR_SUCCESS == RegQueryValueEx(hKey, c_szFormatClient, 0, NULL, (LPBYTE)szTemp, &cbSize))
{
wnsprintf(szNewLabel, ARRAYSIZE(szNewLabel), szTemp, szDefClient);
}
}
}
else
{
cbSize = sizeof(szNewLabel);
// get the mail icon label format string
RegQueryValueEx(hKey, c_szFormatNoClient, 0, NULL, (LPBYTE)szNewLabel, &cbSize);
}
}
// if the above succeeded, and the label is different
if (*szNewLabel && StrCmp(szNewLabel, szOldLabel))
{
IShellFolder *psf;
// set the new label
RegSetValue(HKEY_CLASSES_ROOT, c_szMailIconGuid, REG_SZ, szNewLabel, (lstrlen(szNewLabel)+1)*sizeof(TCHAR));
// let the shell know that it changed
if (SUCCEEDED(SHGetDesktopFolder(&psf)))
{
LPITEMIDLIST pidl;
ULONG chEaten;
if (SUCCEEDED(psf->ParseDisplayName(NULL, NULL, c_wszMailIconGuid, &chEaten, &pidl, NULL)))
{
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_IDLIST, pidl, NULL);
SHFree(pidl);
}
psf->Release();
}
}
RegCloseKey(hKey);
}
}