|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
proxysup.c
Abstract:
Contains implementation for proxy server and proxy bypass list dialog interface.
WARNING: Changes in this code need to be syncronizated with changes in proxysup.cxx in the WININET project.
Contents:
Author:
Arthur L Bierer (arthurbi) 18-Apr-1996
Revision History:
18-Apr-1996 arthurbi Created
--*/
#include "inetcplp.h"
#include <mluisupp.h>
// Disable warning for VC6 (ASSERT macro causing the problem)
#pragma warning(4:4509) // nonstandard extension used: 'ftn' uses SEH and 'object' has destructor
//
// Don't use CRTs so define our own isdigit
//
#undef isdigit
#define isdigit(ch) (ch >= '0' && ch <= '9')
//
// ARRAY_ELEMENTS - returns number of elements in array
//
#define ARRAY_ELEMENTS(array) (sizeof(array)/sizeof(array[0]))
#define GET_TERMINATOR(string) while(*string != '\0') string++
#define IS_BLANK(string) (*string == '\0')
//
// private types
//
typedef enum { STATE_START, STATE_PROTOCOL, STATE_SCHEME, STATE_SERVER, STATE_PORT, STATE_END, STATE_ERROR } PARSER_STATE;
typedef struct tagMY_URL_SCHEME { LPSTR SchemeName; DWORD SchemeLength; INTERNET_SCHEME SchemeType; DWORD dwControlId; DWORD dwPortControlId; } MY_URL_SCHEME;
const MY_URL_SCHEME UrlSchemeList[] = { NULL, 0, INTERNET_SCHEME_DEFAULT,IDC_NOTUSED, IDC_NOTUSED, "ftp", 3, INTERNET_SCHEME_FTP, IDC_PROXY_FTP_ADDRESS, IDC_PROXY_FTP_PORT, "gopher", 6, INTERNET_SCHEME_GOPHER, IDC_PROXY_GOPHER_ADDRESS, IDC_PROXY_GOPHER_PORT, "http", 4, INTERNET_SCHEME_HTTP, IDC_PROXY_HTTP_ADDRESS, IDC_PROXY_HTTP_PORT, "https", 5, INTERNET_SCHEME_HTTPS, IDC_PROXY_SECURITY_ADDRESS, IDC_PROXY_SECURITY_PORT, "socks", 5, INTERNET_SCHEME_SOCKS, IDC_PROXY_SOCKS_ADDRESS, IDC_PROXY_SOCKS_PORT, };
#define INTERNET_MAX_PORT_LENGTH sizeof("123456789")
typedef struct tagBEFOREUSESAME { // addresses
TCHAR szFTP [ INTERNET_MAX_URL_LENGTH + 1 ]; TCHAR szGOPHER [ INTERNET_MAX_URL_LENGTH + 1 ]; TCHAR szSECURE [ INTERNET_MAX_URL_LENGTH + 1 ]; TCHAR szSOCKS [ INTERNET_MAX_URL_LENGTH + 1 ];
// ports
TCHAR szFTPport [ INTERNET_MAX_PORT_LENGTH + 1 ]; TCHAR szGOPHERport [ INTERNET_MAX_PORT_LENGTH + 1 ]; TCHAR szSECUREport [ INTERNET_MAX_PORT_LENGTH + 1 ]; TCHAR szSOCKSport [ INTERNET_MAX_PORT_LENGTH + 1 ];
} BEFOREUSESAME, *LPBEFOREUSESAME;
static const int g_iProxies[] = {IDC_PROXY_HTTP_ADDRESS, IDC_PROXY_FTP_ADDRESS, IDC_PROXY_GOPHER_ADDRESS, IDC_PROXY_SECURITY_ADDRESS, IDC_PROXY_SOCKS_ADDRESS};
typedef struct tagPROXYPAGE { LPBEFOREUSESAME lpOldSettings; BOOL fNT; LPPROXYINFO lpi; HINSTANCE hinstUrlMon; // runtime load URLMON.DLL
} PROXYPAGE, *LPPROXYPAGE;
extern const TCHAR cszLocalString[] = TEXT("<local>");
#define MAX_SCHEME_NAME_LENGTH sizeof("gopher")
#define MAX_TITLE 80
#define MAX_DIALOG_MESSAGE 300
//
// private function prototypes
//
LPBEFOREUSESAME SaveCurrentSettings(HWND hDlg); void RestorePreviousSettings(HWND hDlg, LPBEFOREUSESAME lpSave);
BOOL ProxyDlgInitProxyServers( IN HWND hDlg );
BOOL ProxyDlgOK( IN HWND hDlg );
BOOL ProxyDlgInit( IN HWND hDlg, LPARAM lParam );
VOID EnableProxyControls( IN HWND hDlg );
BOOL IsProxyValid( IN HWND hDlg );
BOOL ParseEditCtlForPort( IN OUT LPSTR lpszProxyName, IN HWND hDlg, IN DWORD dwProxyNameCtlId, IN DWORD dwProxyPortCtlId );
BOOL FormatOutProxyEditCtl( IN HWND hDlg, IN DWORD dwProxyNameCtlId, IN DWORD dwProxyPortCtlId, OUT LPSTR lpszOutputStr, IN OUT LPDWORD lpdwOutputStrSize, IN DWORD dwOutputStrLength, IN BOOL fDefaultProxy );
INTERNET_SCHEME MapUrlSchemeName( IN LPSTR lpszSchemeName, IN DWORD dwSchemeNameLength );
DWORD MapUrlSchemeTypeToCtlId( IN INTERNET_SCHEME SchemeType, IN BOOL fIdForPortCtl );
BOOL MapCtlIdUrlSchemeName( IN DWORD dwEditCtlId, OUT LPSTR lpszSchemeOut );
DWORD MapAddrCtlIdToPortCtlId( IN DWORD dwEditCtlId );
BOOL RemoveLocalFromExceptionList( IN LPTSTR lpszExceptionList );
//
// functions
//
/*******************************************************************
NAME: ProxyDlgProc
SYNOPSIS: Proxy property sheet dialog proc.
********************************************************************/ INT_PTR CALLBACK ProxyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPPROXYPAGE pPxy= (LPPROXYPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
switch (uMsg) { case WM_INITDIALOG: { BOOL fInited; fInited = ProxyDlgInit(hDlg, lParam); return fInited; } case WM_NOTIFY: { NMHDR * lpnm = (NMHDR *) lParam; switch (lpnm->code) { case PSN_APPLY: { BOOL fRet = ProxyDlgOK(hDlg); SetPropSheetResult(hDlg,!fRet); return !fRet; break; } case PSN_RESET: SetPropSheetResult(hDlg,FALSE); break; } break; } case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_PROXY_ENABLE: EnableProxyControls(hDlg); break;
case IDC_PROXY_HTTP_ADDRESS: case IDC_PROXY_GOPHER_ADDRESS: case IDC_PROXY_SECURITY_ADDRESS: case IDC_PROXY_FTP_ADDRESS: case IDC_PROXY_SOCKS_ADDRESS:
if ( GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS ) { ParseEditCtlForPort(NULL, hDlg, (GET_WM_COMMAND_ID(wParam, lParam)), 0); EnableProxyControls(hDlg); } break;
case IDC_PROXY_HTTP_PORT: case IDC_PROXY_GOPHER_PORT: case IDC_PROXY_SECURITY_PORT: case IDC_PROXY_FTP_PORT: case IDC_PROXY_SOCKS_PORT:
if ( GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS ) { EnableProxyControls(hDlg); } break;
case IDC_PROXY_USE_SAME_SERVER:
if ( GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED ) { if (IsDlgButtonChecked(hDlg, IDC_PROXY_USE_SAME_SERVER)) pPxy->lpOldSettings = SaveCurrentSettings(hDlg); else if (pPxy->lpOldSettings !=NULL) { RestorePreviousSettings(hDlg, pPxy->lpOldSettings); pPxy->lpOldSettings = NULL; }
EnableProxyControls(hDlg); } break;
case IDOK:
if ( GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED ) { BOOL fLeaveDialog = TRUE;
if (!IsProxyValid(hDlg)) { // The proxy is invalid, so we need to ask the user if they want to turn it off.
TCHAR szTitle[MAX_TITLE]; TCHAR szMessage[MAX_DIALOG_MESSAGE]; int nUserResponce;
MLLoadShellLangString(IDS_INVALID_PROXY_TITLE, szTitle, ARRAYSIZE(szTitle)); MLLoadShellLangString(IDS_INVALID_PROXY, szMessage, ARRAYSIZE(szMessage));
// Ask the user if they want to turn off the proxy.
nUserResponce = MessageBox(hDlg, szMessage, szTitle, MB_YESNOCANCEL | MB_ICONERROR); if (IDYES == nUserResponce) pPxy->lpi->fEnable = FALSE; else if (IDCANCEL == nUserResponce) fLeaveDialog = FALSE; // The user hit cancel, so let's not leave the dialog.
}
if (fLeaveDialog) { //
// Read the Ctls and Save out to the proxy..
//
ProxyDlgOK(hDlg); EndDialog(hDlg, IDOK); } } break;
case IDCANCEL: if ( GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED ) { EndDialog(hDlg, IDCANCEL); } break;
} break;
case WM_DESTROY: if (pPxy->lpOldSettings) LocalFree(pPxy->lpOldSettings);
if (pPxy->hinstUrlMon) FreeLibrary(pPxy->hinstUrlMon);
LocalFree(pPxy); return TRUE;
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;
default: return FALSE; } return TRUE; }
//
// Private Functions.
//
VOID EnableProxyControls(HWND hDlg)
/*++
Routine Description:
Enables controls appropriately depending on what checkboxes are checked.
Arguments:
hDlg - Page Dialog Box.
Return Value:
VOID
--*/
{ BOOL fNT = ((LPPROXYPAGE)GetWindowLongPtr(hDlg, DWLP_USER))->fNT; BOOL fEnable = !g_restrict.fProxy; BOOL fUseOneProxy = IsDlgButtonChecked(hDlg,IDC_PROXY_USE_SAME_SERVER); EnableDlgItem(hDlg,IDC_GRP_SETTINGS2, fEnable); EnableDlgItem(hDlg,IDC_PROXY_EXCEPTIONS_GROUPBOX, fEnable);
EnableDlgItem(hDlg,IDC_TYPE_TEXT, fEnable); EnableDlgItem(hDlg,IDC_ADDR_TEXT, fEnable); EnableDlgItem(hDlg,IDC_PORT_TEXT, fEnable); EnableDlgItem(hDlg,IDC_EXCEPT_TEXT, fEnable); EnableDlgItem(hDlg,IDC_EXCEPT2_TEXT, fEnable); EnableDlgItem(hDlg,IDC_PROXY_ICON1, fEnable); EnableDlgItem(hDlg,IDC_PROXY_ICON2, fEnable); EnableDlgItem(hDlg,IDC_PROXY_HTTP_CAPTION, fEnable); EnableDlgItem(hDlg,IDC_PROXY_SECURITY_CAPTION, fEnable); EnableDlgItem(hDlg,IDC_PROXY_FTP_CAPTION, fEnable); EnableDlgItem(hDlg,IDC_PROXY_GOPHER_CAPTION, fEnable); EnableDlgItem(hDlg,IDC_PROXY_SOCKS_CAPTION, fEnable);
EnableDlgItem(hDlg, IDC_PROXY_USE_SAME_SERVER, fEnable);
EnableDlgItem(hDlg,IDC_PROXY_HTTP_ADDRESS,fEnable); EnableDlgItem(hDlg,IDC_PROXY_HTTP_PORT,fEnable); EnableDlgItem(hDlg,IDC_PROXY_OVERRIDE,fEnable);
//
// If we only want one Proxy, then make all others use the same
// proxy.
//
EnableDlgItem(hDlg,IDC_PROXY_SECURITY_ADDRESS,!fUseOneProxy && fEnable); EnableDlgItem(hDlg,IDC_PROXY_SECURITY_PORT,!fUseOneProxy && fEnable);
EnableDlgItem(hDlg,IDC_PROXY_FTP_ADDRESS,!fUseOneProxy && fEnable); EnableDlgItem(hDlg,IDC_PROXY_FTP_PORT,!fUseOneProxy && fEnable);
EnableDlgItem(hDlg,IDC_PROXY_GOPHER_ADDRESS,!fUseOneProxy && fEnable); EnableDlgItem(hDlg,IDC_PROXY_GOPHER_PORT,!fUseOneProxy && fEnable);
EnableDlgItem(hDlg,IDC_PROXY_SOCKS_ADDRESS,!fUseOneProxy && fEnable); EnableDlgItem(hDlg,IDC_PROXY_SOCKS_PORT,!fUseOneProxy && fEnable);
//
// If we only want one proxy, prepopulate the other fields
// so they use the the mirror of the first one.
//
if (fUseOneProxy) { TCHAR szProxyName[MAX_URL_STRING+1]; TCHAR szProxyPort[INTERNET_MAX_PORT_LENGTH];
GetDlgItemText(hDlg, IDC_PROXY_HTTP_ADDRESS, szProxyName, ARRAYSIZE(szProxyName));
GetDlgItemText(hDlg, IDC_PROXY_HTTP_PORT, szProxyPort, ARRAYSIZE(szProxyPort));
SetDlgItemText(hDlg,IDC_PROXY_SECURITY_ADDRESS,szProxyName); SetDlgItemText(hDlg,IDC_PROXY_SECURITY_PORT,szProxyPort);
SetDlgItemText(hDlg,IDC_PROXY_FTP_ADDRESS,szProxyName); SetDlgItemText(hDlg,IDC_PROXY_FTP_PORT,szProxyPort);
SetDlgItemText(hDlg,IDC_PROXY_GOPHER_ADDRESS,szProxyName); SetDlgItemText(hDlg,IDC_PROXY_GOPHER_PORT,szProxyPort);
SetDlgItemText(hDlg,IDC_PROXY_SOCKS_ADDRESS,TEXT("")); SetDlgItemText(hDlg,IDC_PROXY_SOCKS_PORT,TEXT("")); } }
//
// SaveCurrentSettings()
//
// Saves current settings... just in case user changes their mind.
//
// Returns a pointer to a structure filled with current settings.
//
LPBEFOREUSESAME SaveCurrentSettings(HWND hDlg) { LPBEFOREUSESAME lpSave = (LPBEFOREUSESAME)LocalAlloc(LPTR, sizeof(*lpSave));
if (!lpSave) return lpSave; // if NULL return NULL
GetDlgItemText(hDlg, IDC_PROXY_FTP_ADDRESS, lpSave->szFTP, INTERNET_MAX_URL_LENGTH); GetDlgItemText(hDlg, IDC_PROXY_GOPHER_ADDRESS, lpSave->szGOPHER, INTERNET_MAX_URL_LENGTH); GetDlgItemText(hDlg, IDC_PROXY_SECURITY_ADDRESS, lpSave->szSECURE, INTERNET_MAX_URL_LENGTH); GetDlgItemText(hDlg, IDC_PROXY_SOCKS_ADDRESS, lpSave->szSOCKS, INTERNET_MAX_URL_LENGTH);
GetDlgItemText(hDlg, IDC_PROXY_FTP_PORT, lpSave->szFTPport, INTERNET_MAX_URL_LENGTH); GetDlgItemText(hDlg, IDC_PROXY_GOPHER_PORT, lpSave->szGOPHERport, INTERNET_MAX_URL_LENGTH); GetDlgItemText(hDlg, IDC_PROXY_SECURITY_PORT, lpSave->szSECUREport, INTERNET_MAX_URL_LENGTH); GetDlgItemText(hDlg, IDC_PROXY_SOCKS_PORT, lpSave->szSOCKSport, INTERNET_MAX_URL_LENGTH);
return lpSave;
} // SaveCurrentSettings()
//
// RestorePreviousSettings()
//
// Restores settings... just in case user changes their mind.
//
void RestorePreviousSettings(HWND hDlg, LPBEFOREUSESAME lpSave) {
if (!lpSave) return; // nothing to do
SetDlgItemText(hDlg, IDC_PROXY_FTP_ADDRESS, lpSave->szFTP ); SetDlgItemText(hDlg, IDC_PROXY_GOPHER_ADDRESS, lpSave->szGOPHER ); SetDlgItemText(hDlg, IDC_PROXY_SECURITY_ADDRESS, lpSave->szSECURE ); SetDlgItemText(hDlg, IDC_PROXY_SOCKS_ADDRESS, lpSave->szSOCKS );
SetDlgItemText(hDlg, IDC_PROXY_FTP_PORT, lpSave->szFTPport ); SetDlgItemText(hDlg, IDC_PROXY_GOPHER_PORT, lpSave->szGOPHERport ); SetDlgItemText(hDlg, IDC_PROXY_SECURITY_PORT, lpSave->szSECUREport ); SetDlgItemText(hDlg, IDC_PROXY_SOCKS_PORT, lpSave->szSOCKSport );
LocalFree(lpSave); // give back the memory
} // RestorePreviousSettings()
BOOL ProxyDlgInit( IN HWND hDlg, LPARAM lParam )
/*++
Routine Description:
Initialization proc for proxy prop page
Arguments:
hDlg - Page Dialog Box.
Return Value:
BOOL Success - TRUE
Failure - FALSE
--*/
{ BOOL fSuccess; LPPROXYPAGE pPxy;
pPxy = (LPPROXYPAGE)LocalAlloc(LPTR, sizeof(*pPxy)); // NOTE: this NULLS lpOldSettings
if (!pPxy) return FALSE; // no memory?
OSVERSIONINFOA osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionExA(&osvi); pPxy->fNT = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT); ASSERT(pPxy->lpOldSettings == NULL); // tell dialog where to get info
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pPxy);
pPxy->lpi = (LPPROXYINFO)lParam; //
// Begin by reading and setting the list of proxy
// servers we have.
//
fSuccess = ProxyDlgInitProxyServers( hDlg );
if (!fSuccess) return FALSE;
//
// read settings from registry, for the list of Exclusion Hosts.
//
RegEntry re(REGSTR_PATH_INTERNETSETTINGS,HKEY_CURRENT_USER);
if (re.GetError() == ERROR_SUCCESS) { BUFFER bufProxyString(MAX_URL_STRING+1); if (!bufProxyString) { MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK); return FALSE; }
//
// get proxy override settings from registry and stuff fields
// Prevent entry of more than (MAX_URL_STRING - ("<local>" + safety))
SendMessage(GetDlgItem(hDlg, IDC_PROXY_OVERRIDE), EM_SETLIMITTEXT, (WPARAM)ARRAYSIZE(pPxy->lpi->szOverride)-20, 0); SetDlgItemText(hDlg, IDC_PROXY_OVERRIDE, pPxy->lpi->szOverride); }
//
// initialize the UI appropriately
//
EnableProxyControls(hDlg); return TRUE; }
BOOL ProxyDlgOK( IN HWND hDlg )
/*++
Routine Description:
OK button handler for proxy prop page
Arguments:
hDlg - Page Dialog Box.
Return Value:
BOOL Success - TRUE
Failure - FALSE
--*/
{ LPPROXYPAGE pPxy = (LPPROXYPAGE)GetWindowLongPtr(hDlg, DWLP_USER); TCHAR szProxyListOutputBuffer[MAX_URL_STRING]; CHAR szProxyListOutputBufferA[MAX_URL_STRING]; DWORD dwBufferOffset = 0;
//
// Get the state of our two check boxes.
//
BOOL fUseOneProxy = IsDlgButtonChecked(hDlg,IDC_PROXY_USE_SAME_SERVER); //
// Open our Registry Key.
//
RegEntry re(REGSTR_PATH_INTERNETSETTINGS,HKEY_CURRENT_USER); if (re.GetError() == ERROR_SUCCESS) { //
// Now Format, and write out the list of proxies to
// the registry. We special case the case of
// only proxy.
//
szProxyListOutputBufferA[dwBufferOffset] = '\0';
if ( fUseOneProxy ) { FormatOutProxyEditCtl( hDlg, IDC_PROXY_HTTP_ADDRESS, IDC_PROXY_HTTP_PORT, szProxyListOutputBufferA, &dwBufferOffset, ARRAY_ELEMENTS(szProxyListOutputBufferA), TRUE ); } else { for (int i = 1; i < ARRAY_ELEMENTS(UrlSchemeList); ++i) { FormatOutProxyEditCtl( hDlg, UrlSchemeList[i].dwControlId, UrlSchemeList[i].dwPortControlId, szProxyListOutputBufferA, &dwBufferOffset, ARRAY_ELEMENTS(szProxyListOutputBufferA), FALSE );
} }
szProxyListOutputBufferA[dwBufferOffset] = '\0';
#ifdef UNICODE
SHAnsiToUnicode(szProxyListOutputBufferA, szProxyListOutputBuffer, MAX_URL_STRING); #else
lstrcpy(szProxyListOutputBuffer, szProxyListOutputBufferA); #endif
StrCpyN(pPxy->lpi->szProxy, szProxyListOutputBuffer, MAX_URL_STRING);
//
// Now Write out the Proxy Exception List
// (list of addresses to use for local connections)
//
szProxyListOutputBuffer[0] = '\0'; GetDlgItemText(hDlg, IDC_PROXY_OVERRIDE, szProxyListOutputBuffer, ARRAY_ELEMENTS(szProxyListOutputBuffer)); StrCpyN(pPxy->lpi->szOverride, szProxyListOutputBuffer, MAX_URL_STRING); } else { AssertMsg(0, TEXT("Couldn't save settings to registry!")); }
// let any active (participating) wininet's get notified
//
InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
return TRUE; }
INTERNET_SCHEME MapUrlSchemeName( IN LPSTR lpszSchemeName, IN DWORD dwSchemeNameLength )
/*++
Routine Description:
Maps a scheme name/length to a scheme name type
Arguments:
lpszSchemeName - pointer to name of scheme to map
dwSchemeNameLength - length of scheme (if -1, lpszSchemeName is ASCIZ)
Return Value:
INTERNET_SCHEME
--*/
{ if (dwSchemeNameLength == (DWORD)-1) { dwSchemeNameLength = (DWORD)lstrlenA(lpszSchemeName); } for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i) { if (UrlSchemeList[i].SchemeLength == dwSchemeNameLength) { CHAR chBackup = lpszSchemeName[dwSchemeNameLength]; lpszSchemeName[dwSchemeNameLength] = '\0'; if(StrCmpIA(UrlSchemeList[i].SchemeName,lpszSchemeName) == 0) { lpszSchemeName[dwSchemeNameLength] = chBackup; return UrlSchemeList[i].SchemeType; } lpszSchemeName[dwSchemeNameLength] = chBackup; } } return INTERNET_SCHEME_UNKNOWN; }
DWORD MapUrlSchemeTypeToCtlId( IN INTERNET_SCHEME SchemeType, IN BOOL fIdForPortCtl )
/*++
Routine Description:
Maps a scheme to a dlg child control id.
Arguments:
Scheme - Scheme to Map
fIdForPortCtl - If TRUE, means we really want the ID for a the PORT control not the ADDRESS control.
Return Value:
DWORD
--*/
{ for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i) { if (SchemeType == UrlSchemeList[i].SchemeType) { return (fIdForPortCtl ? UrlSchemeList[i].dwPortControlId : UrlSchemeList[i].dwControlId ); } } return IDC_NOTUSED; }
BOOL MapCtlIdUrlSchemeName( IN DWORD dwEditCtlId, OUT LPSTR lpszSchemeOut )
/*++
Routine Description:
Maps a dlg child control id to String represnting the name of the scheme.
Arguments:
dwEditCtlId - Edit Control to Map Out.
lpszSchemeOut - Scheme to Map Out. WARNING: ASSUMED to be size of largest scheme type.
Return Value:
BOOL Success - TRUE
Failure - FALSE
--*/
{ ASSERT(lpszSchemeOut);
for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i) { if (dwEditCtlId == UrlSchemeList[i].dwControlId ) { StrCpyA(lpszSchemeOut, UrlSchemeList[i].SchemeName); return TRUE; } } return FALSE; }
DWORD MapAddrCtlIdToPortCtlId( IN DWORD dwEditCtlId )
/*++
Routine Description:
Maps a dlg child control id for addresses to a dlg control id for ports.
Arguments:
dwEditCtlId - Edit Control to Map Out.
Return Value:
DWORD Success - Correctly mapped ID.
Failure - 0.
--*/
{
for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i) { if (dwEditCtlId == UrlSchemeList[i].dwControlId ) { return UrlSchemeList[i].dwPortControlId ; } } return FALSE; }
BOOL ProxyDlgInitProxyServers( IN HWND hDlg )
/*++
Routine Description:
Parses a list of proxy servers and sets them into the newly created Proxy Dialog.
Ruthlessly stolen from RFirth's proxysup.cxx in WININET by ArthurBi.
Arguments:
hDlg - HWin to add our stuff to.
Return Value:
BOOL Success - TRUE
Failure - FALSE
Comments:
Designed to handle Proxy string entry of the Form:
pointer to list of proxies of the form:
[<protocol>=][<scheme>"://"]<server>[":"<port>][";"*]
The list can is read from the registry.
--*/
{ DWORD error = !ERROR_SUCCESS; DWORD entryLength; LPSTR protocolName; DWORD protocolLength; LPSTR schemeName; DWORD schemeLength; LPSTR serverName; DWORD serverLength; PARSER_STATE state; DWORD nSlashes; INTERNET_PORT port; BOOL done; LPSTR lpszList;
entryLength = 0; protocolLength = 0; schemeName = NULL; schemeLength = 0; serverName = NULL; serverLength = 0; state = STATE_PROTOCOL; nSlashes = 0; port = 0; done = FALSE;
//
// Open the Reg Key.
//
RegEntry re(REGSTR_PATH_INTERNETSETTINGS,HKEY_CURRENT_USER);
if (re.GetError() != ERROR_SUCCESS) return FALSE; // no REG values..
//
// Crack the Registry values, read the proxy list
//
BUFFER bufProxyString(MAX_URL_STRING+1); BOOL fProxyEnabled;
if (!bufProxyString) { MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK); return FALSE; }
//
// is proxy enabled?
// It should if we got into this dialog.
//
fProxyEnabled = (BOOL)re.GetNumber(REGSTR_VAL_PROXYENABLE,0);
//
// get proxy server and override settings from registry and stuff fields
//
re.GetString(REGSTR_VAL_PROXYSERVER,bufProxyString.QueryPtr(), bufProxyString.QuerySize());
LPPROXYPAGE pPxy = (LPPROXYPAGE)GetWindowLongPtr(hDlg, DWLP_USER);
// if there's a proxy passed in from the main page, then use it; otherwise use the registry val
#ifndef UNICODE
lpszList = pPxy->lpi->szProxy; #else
char* szList = NULL; LPTSTR lpTmp = pPxy->lpi->szProxy; DWORD cch = lstrlen(lpTmp) + 1; szList = new char[2 * cch]; if (szList) { SHUnicodeToAnsi(lpTmp, szList, 2 * cch); lpszList = szList; } else { MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK); return FALSE; } #endif
protocolName = lpszList;
//
// walk the list, pulling out the various scheme parts
//
do { char ch = *lpszList++;
if ((nSlashes == 1) && (ch != '/')) { state = STATE_ERROR; break; } switch (ch) { case '=': if ((state == STATE_PROTOCOL) && (entryLength != 0)) { protocolLength = entryLength; entryLength = 0; state = STATE_SCHEME; schemeName = lpszList; } else { //
// '=' can't legally appear anywhere else
//
state = STATE_ERROR; } break; case ':': switch (state) { case STATE_PROTOCOL: if (*lpszList == '/') { schemeName = protocolName; protocolName = NULL; schemeLength = entryLength; protocolLength = 0; state = STATE_SCHEME; } else if (*lpszList != '\0') { serverName = protocolName; serverLength = entryLength; state = STATE_PORT; } else { state = STATE_ERROR; } entryLength = 0; break; case STATE_SCHEME: if (*lpszList == '/') { schemeLength = entryLength; } else if (*lpszList != '\0') { serverName = schemeName; serverLength = entryLength; state = STATE_PORT; } else { state = STATE_ERROR; } entryLength = 0; break; case STATE_SERVER: serverLength = entryLength; state = STATE_PORT; entryLength = 0; break;
default: state = STATE_ERROR; break; } break;
case '/': if ((state == STATE_SCHEME) && (nSlashes < 2) && (entryLength == 0)) { if (++nSlashes == 2) { state = STATE_SERVER; serverName = lpszList; } } else { state = STATE_ERROR; } break;
case '\v': // vertical tab, 0x0b
case '\f': // form feed, 0x0c
if (!((state == STATE_PROTOCOL) && (entryLength == 0))) { //
// can't have embedded whitespace
//
state = STATE_ERROR; } break;
default: if (state != STATE_PORT) { ++entryLength; } else if (isdigit(ch)) { //
// we will overflow if >65535
//
Assert(port < 65535); port = port * 10 + (ch - '0'); } else { //
// STATE_PORT && non-digit character - error
//
state = STATE_ERROR; } break;
case '\0': done = TRUE;
//
// fall through
//
case ' ': case '\t': case '\n': case '\r': case ';': case ',': if (serverLength == 0) { serverLength = entryLength; } if (serverLength != 0) { if (serverName == NULL) { serverName = (schemeName != NULL) ? schemeName : protocolName; }
ASSERT(serverName != NULL);
INTERNET_SCHEME protocol;
if (protocolLength != 0) { protocol = MapUrlSchemeName(protocolName, protocolLength); } else { protocol = INTERNET_SCHEME_DEFAULT; }
INTERNET_SCHEME scheme;
if (schemeLength != 0) { scheme = MapUrlSchemeName(schemeName, schemeLength); } else { scheme = INTERNET_SCHEME_DEFAULT; }
//
// add an entry if this is a protocol we handle and we don't
// already have an entry for it
//
if ((protocol != INTERNET_SCHEME_UNKNOWN) && (scheme != INTERNET_SCHEME_UNKNOWN)) { DWORD dwCtlId = IDC_NOTUSED; DWORD dwPortCtlId = IDC_NOTUSED; CHAR chBackup;
error = ERROR_SUCCESS; //
// we can only currently handle CERN proxies (unsecure or
// secure) so kick out anything that wants to go via a different
// proxy scheme
//
if (protocol == INTERNET_SCHEME_DEFAULT) { CheckDlgButton( hDlg, IDC_PROXY_USE_SAME_SERVER, TRUE ); dwCtlId = IDC_PROXY_HTTP_ADDRESS; dwPortCtlId = IDC_PROXY_HTTP_PORT; } else { dwCtlId = MapUrlSchemeTypeToCtlId(protocol,FALSE); dwPortCtlId = MapUrlSchemeTypeToCtlId(protocol,TRUE); }
//
// Set the Field Entry.
//
LPSTR lpszProxyNameText;
if (scheme != INTERNET_SCHEME_DEFAULT) { ASSERT(schemeLength != 0); lpszProxyNameText = schemeName; } else lpszProxyNameText = serverName;
chBackup = serverName[serverLength]; serverName[serverLength] = '\0'; SetDlgItemTextA( hDlg, dwCtlId, lpszProxyNameText ); if ( port ) SetDlgItemInt( hDlg, dwPortCtlId, port, FALSE );
serverName[serverLength] = chBackup; } else { //
// bad/unrecognised protocol or scheme. Treat it as error
// for now
//
error = !ERROR_SUCCESS; } }
entryLength = 0; protocolName = lpszList; protocolLength = 0; schemeName = NULL; schemeLength = 0; serverName = NULL; serverLength = 0; nSlashes = 0; port = 0; if (error == ERROR_SUCCESS) { state = STATE_PROTOCOL; } else { state = STATE_ERROR; } break; }
if (state == STATE_ERROR) { break; } } while (!done);
#ifdef UNICODE
delete [] szList; #endif
if (state == STATE_ERROR) { error = ERROR_INVALID_PARAMETER; }
if ( error == ERROR_SUCCESS ) error = TRUE; else error = FALSE;
return error; }
BOOL IsProxyValid( IN HWND hDlg )
/*++
Routine Description:
Determines if the Proxy is valid. The proxy is invalid if all of the proxy entries are empty.
Arguments:
hDlg - HWIN of the dialog to play with.
Return Value:
BOOL Success TRUE - Valid.
FALSE - Invalid.
--*/
{ BOOL fProxyIsValid = FALSE; TCHAR szProxyUrl[MAX_URL_STRING+1]; int iCurrentProxy = 0;
ASSERT(IsWindow(hDlg));
for (int iIndex = 0; iIndex < ARRAYSIZE(g_iProxies); iIndex++) { szProxyUrl[0] = '\0'; GetDlgItemText(hDlg, g_iProxies[iIndex], szProxyUrl, sizeof(szProxyUrl)); if (szProxyUrl[0]) { fProxyIsValid = TRUE; break; } }
return fProxyIsValid; }
BOOL ParseEditCtlForPort( IN OUT LPSTR lpszProxyName, IN HWND hDlg, IN DWORD dwProxyNameCtlId, IN DWORD dwProxyPortCtlId )
/*++
Routine Description:
Parses a Port Number off then end of a Proxy Server URL that is located either in the Proxy Name Edit Box, or passed in as a string pointer.
Arguments:
lpszProxyName - (OPTIONAL) string pointer with Proxy Name to parse, and set into the Proxy Name edit ctl field.
hDlg - HWIN of the dialog to play with.
dwProxyNameCtlId - Res Ctl Id to play with.
dwProxyPortCtlId - Res Ctl Id of Port Number Edit Box.
Return Value:
BOOL Success TRUE -
Failure FALSE
--*/
{ CHAR szProxyUrl[MAX_URL_STRING+1]; LPSTR lpszPort; LPSTR lpszProxyUrl;
ASSERT(IsWindow(hDlg));
if ( dwProxyPortCtlId == 0 ) { dwProxyPortCtlId = MapAddrCtlIdToPortCtlId(dwProxyNameCtlId); ASSERT(dwProxyPortCtlId); }
//
// Get the Proxy String from the Edit Control
// (OR) from the Registry [passed in]
//
if ( lpszProxyName ) lpszProxyUrl = lpszProxyName; else { //
// Need to Grab it out of the edit control.
//
GetDlgItemTextA(hDlg, dwProxyNameCtlId, szProxyUrl, sizeof(szProxyUrl));
lpszProxyUrl = szProxyUrl; }
//
// Now find the port.
//
lpszPort = lpszProxyUrl;
GET_TERMINATOR(lpszPort);
lpszPort--;
//
// Walk backwards from the end of url looking
// for a port number sitting on the end like this
// http://proxy:1234
//
while ( (lpszPort > lpszProxyUrl) && (*lpszPort != ':') && (isdigit(*lpszPort)) ) { lpszPort--; }
//
// If we found a match for our rules
// then set the port, otherwise
// we assume the user knows what he's
// doing.
//
if ( *lpszPort == ':' && isdigit(*(lpszPort+1)) ) { *lpszPort = '\0';
SetDlgItemTextA(hDlg, dwProxyPortCtlId, (lpszPort+1)); }
SetDlgItemTextA(hDlg, dwProxyNameCtlId, lpszProxyUrl); return TRUE; }
BOOL FormatOutProxyEditCtl( IN HWND hDlg, IN DWORD dwProxyNameCtlId, IN DWORD dwProxyPortCtlId, OUT LPSTR lpszOutputStr, IN OUT LPDWORD lpdwOutputStrSize, IN DWORD dwOutputStrLength, IN BOOL fDefaultProxy )
/*++
Routine Description:
Combines Proxy URL components into a string that can be saved in the registry. Can be called multiple times to build a list of proxy servers, or once to special case a "default" proxy.
Arguments:
hDlg - HWIN of the dialog to play with.
dwProxyNameCtlId - Res Ctl Id to play with.
dwProxyPortCtlId - Res Ctl Id of Port Number Edit Box.
lpszOutputStr - The start of the output string to send the product of this function.
lpdwOutputStrSize - The amount of used space in lpszOutputStr that is already used. New output should start from (lpszOutputStr + *lpdwOutputStrSize)
fDefaultProxy - Default Proxy, don't add scheme= in front of the proxy just use plop one proxy into the registry.
Return Value:
BOOL Success TRUE
Failure FALSE
--*/
{ LPSTR lpszOutput; LPSTR lpszEndOfOutputStr;
ASSERT(IsWindow(hDlg)); ASSERT(lpdwOutputStrSize);
lpszOutput = lpszOutputStr + *lpdwOutputStrSize; lpszEndOfOutputStr = lpszOutputStr + dwOutputStrLength;
ASSERT( lpszEndOfOutputStr > lpszOutput );
if ( lpszEndOfOutputStr <= lpszOutput ) return FALSE; // bail out, ran out of space
//
// Plop ';' if we're not the first in this string buffer.
//
if (*lpdwOutputStrSize != 0 ) { *lpszOutput = ';';
lpszOutput++;
if ( lpszEndOfOutputStr <= lpszOutput ) return FALSE; // bail out, ran out of space
}
//
// Put the schemetype= into the string
// ex: http=
//
if ( ! fDefaultProxy ) { if ( lpszEndOfOutputStr <= (MAX_SCHEME_NAME_LENGTH + lpszOutput + 1) ) return FALSE; // bail out, ran out of space
if (!MapCtlIdUrlSchemeName(dwProxyNameCtlId,lpszOutput)) return FALSE; lpszOutput += lstrlenA(lpszOutput); *lpszOutput = '='; lpszOutput++; } //
// Need to Grab ProxyUrl out of the edit control.
//
GetDlgItemTextA(hDlg, dwProxyNameCtlId, lpszOutput, (int)(lpszEndOfOutputStr - lpszOutput));
if ( IS_BLANK(lpszOutput) ) return FALSE;
//
// Now seperate out the port so we can save them seperately.
// But go past the Proxy Url while we're at it.
// ex: http=http://netscape-proxy
//
if (!ParseEditCtlForPort(lpszOutput, hDlg, dwProxyNameCtlId, dwProxyPortCtlId)) return FALSE;
lpszOutput += lstrlenA(lpszOutput);
//
// Now, add in a ':" for the port number, if we don't
// have a port we'll remove it.
//
{ *lpszOutput = ':'; lpszOutput++; if ( lpszEndOfOutputStr <= lpszOutput ) return FALSE; // bail out, ran out of space
}
//
// Grab Proxy Port if its around.
// Back out the ':' if its not.
//
GetDlgItemTextA(hDlg, dwProxyPortCtlId,lpszOutput, (int)(lpszEndOfOutputStr - lpszOutput));
if ( IS_BLANK(lpszOutput) ) { lpszOutput--; ASSERT(*lpszOutput == ':');
*lpszOutput = '\0'; } lpszOutput += lstrlenA(lpszOutput); //
// Now we're done return our final sizes.
//
*lpdwOutputStrSize = (DWORD)(lpszOutput - lpszOutputStr);
return TRUE; }
BOOL RemoveLocalFromExceptionList( IN LPTSTR lpszExceptionList )
/*++
Routine Description:
Scans a delimited list of entries, and removed "<local> if found. If <local> is found we return TRUE.
Arguments:
lpszExceptionList - String List of proxy excepion entries.
Return Value:
BOOL TRUE - If found <local>
FALSE - If local was not found.
--*/
{ LPTSTR lpszLocalInstToRemove; BOOL fFoundLocal;
if ( !lpszExceptionList || ! *lpszExceptionList ) return FALSE;
fFoundLocal = FALSE; lpszLocalInstToRemove = lpszExceptionList;
//
// Loop looking "<local>" entries in the list.
//
do {
lpszLocalInstToRemove = StrStrI(lpszLocalInstToRemove,cszLocalString); if ( lpszLocalInstToRemove ) { fFoundLocal = TRUE; //
// Nuke <local> out of the string. <local>;otherstuff\0
// Dest is: '<'local>;otherstuff\0
// ??? (OR) ';'<local> if the ; is the first character.???
// Src is: >'o'therstuff\0
// size is: sizeof(';otherstuff\0')
//
MoveMemory( lpszLocalInstToRemove, (lpszLocalInstToRemove+lstrlen(cszLocalString)), lstrlen(lpszLocalInstToRemove+lstrlen(cszLocalString))*sizeof(TCHAR)+sizeof(TCHAR) ); } } while (lpszLocalInstToRemove && *lpszLocalInstToRemove);
//
// If we produced a ; on the end, nuke it.
//
lpszLocalInstToRemove = lpszExceptionList;
GET_TERMINATOR(lpszLocalInstToRemove);
if ( lpszLocalInstToRemove != lpszExceptionList && *(lpszLocalInstToRemove-1) == ';' ) { *(lpszLocalInstToRemove-1) = '\0'; } return fFoundLocal; }
|