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.

1756 lines
44 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. proxysup.c
  5. Abstract:
  6. Contains implementation for proxy server and proxy bypass list
  7. dialog interface.
  8. WARNING: Changes in this code need to be syncronizated
  9. with changes in proxysup.cxx in the WININET project.
  10. Contents:
  11. Author:
  12. Arthur L Bierer (arthurbi) 18-Apr-1996
  13. Revision History:
  14. 18-Apr-1996 arthurbi
  15. Created
  16. --*/
  17. #include "inetcplp.h"
  18. #include <mluisupp.h>
  19. // Disable warning for VC6 (ASSERT macro causing the problem)
  20. #pragma warning(4:4509) // nonstandard extension used: 'ftn' uses SEH and 'object' has destructor
  21. //
  22. // Don't use CRTs so define our own isdigit
  23. //
  24. #undef isdigit
  25. #define isdigit(ch) (ch >= '0' && ch <= '9')
  26. //
  27. // ARRAY_ELEMENTS - returns number of elements in array
  28. //
  29. #define ARRAY_ELEMENTS(array) (sizeof(array)/sizeof(array[0]))
  30. #define GET_TERMINATOR(string) while(*string != '\0') string++
  31. #define IS_BLANK(string) (*string == '\0')
  32. //
  33. // private types
  34. //
  35. typedef enum {
  36. STATE_START,
  37. STATE_PROTOCOL,
  38. STATE_SCHEME,
  39. STATE_SERVER,
  40. STATE_PORT,
  41. STATE_END,
  42. STATE_ERROR
  43. } PARSER_STATE;
  44. typedef struct tagMY_URL_SCHEME
  45. {
  46. LPSTR SchemeName;
  47. DWORD SchemeLength;
  48. INTERNET_SCHEME SchemeType;
  49. DWORD dwControlId;
  50. DWORD dwPortControlId;
  51. } MY_URL_SCHEME;
  52. const MY_URL_SCHEME UrlSchemeList[] =
  53. {
  54. NULL, 0, INTERNET_SCHEME_DEFAULT,IDC_NOTUSED, IDC_NOTUSED,
  55. "ftp", 3, INTERNET_SCHEME_FTP, IDC_PROXY_FTP_ADDRESS, IDC_PROXY_FTP_PORT,
  56. "gopher", 6, INTERNET_SCHEME_GOPHER, IDC_PROXY_GOPHER_ADDRESS, IDC_PROXY_GOPHER_PORT,
  57. "http", 4, INTERNET_SCHEME_HTTP, IDC_PROXY_HTTP_ADDRESS, IDC_PROXY_HTTP_PORT,
  58. "https", 5, INTERNET_SCHEME_HTTPS, IDC_PROXY_SECURITY_ADDRESS, IDC_PROXY_SECURITY_PORT,
  59. "socks", 5, INTERNET_SCHEME_SOCKS, IDC_PROXY_SOCKS_ADDRESS, IDC_PROXY_SOCKS_PORT,
  60. };
  61. #define INTERNET_MAX_PORT_LENGTH sizeof("123456789")
  62. typedef struct tagBEFOREUSESAME
  63. {
  64. // addresses
  65. TCHAR szFTP [ INTERNET_MAX_URL_LENGTH + 1 ];
  66. TCHAR szGOPHER [ INTERNET_MAX_URL_LENGTH + 1 ];
  67. TCHAR szSECURE [ INTERNET_MAX_URL_LENGTH + 1 ];
  68. TCHAR szSOCKS [ INTERNET_MAX_URL_LENGTH + 1 ];
  69. // ports
  70. TCHAR szFTPport [ INTERNET_MAX_PORT_LENGTH + 1 ];
  71. TCHAR szGOPHERport [ INTERNET_MAX_PORT_LENGTH + 1 ];
  72. TCHAR szSECUREport [ INTERNET_MAX_PORT_LENGTH + 1 ];
  73. TCHAR szSOCKSport [ INTERNET_MAX_PORT_LENGTH + 1 ];
  74. } BEFOREUSESAME, *LPBEFOREUSESAME;
  75. 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};
  76. typedef struct tagPROXYPAGE
  77. {
  78. LPBEFOREUSESAME lpOldSettings;
  79. BOOL fNT;
  80. LPPROXYINFO lpi;
  81. HINSTANCE hinstUrlMon; // runtime load URLMON.DLL
  82. } PROXYPAGE, *LPPROXYPAGE;
  83. extern const TCHAR cszLocalString[] = TEXT("<local>");
  84. #define MAX_SCHEME_NAME_LENGTH sizeof("gopher")
  85. #define MAX_TITLE 80
  86. #define MAX_DIALOG_MESSAGE 300
  87. //
  88. // private function prototypes
  89. //
  90. LPBEFOREUSESAME SaveCurrentSettings(HWND hDlg);
  91. void RestorePreviousSettings(HWND hDlg, LPBEFOREUSESAME lpSave);
  92. BOOL
  93. ProxyDlgInitProxyServers(
  94. IN HWND hDlg
  95. );
  96. BOOL
  97. ProxyDlgOK(
  98. IN HWND hDlg
  99. );
  100. BOOL
  101. ProxyDlgInit(
  102. IN HWND hDlg, LPARAM lParam
  103. );
  104. VOID
  105. EnableProxyControls(
  106. IN HWND hDlg
  107. );
  108. BOOL
  109. IsProxyValid(
  110. IN HWND hDlg
  111. );
  112. BOOL
  113. ParseEditCtlForPort(
  114. IN OUT LPSTR lpszProxyName,
  115. IN HWND hDlg,
  116. IN DWORD dwProxyNameCtlId,
  117. IN DWORD dwProxyPortCtlId
  118. );
  119. BOOL
  120. FormatOutProxyEditCtl(
  121. IN HWND hDlg,
  122. IN DWORD dwProxyNameCtlId,
  123. IN DWORD dwProxyPortCtlId,
  124. OUT LPSTR lpszOutputStr,
  125. IN OUT LPDWORD lpdwOutputStrSize,
  126. IN DWORD dwOutputStrLength,
  127. IN BOOL fDefaultProxy
  128. );
  129. INTERNET_SCHEME
  130. MapUrlSchemeName(
  131. IN LPSTR lpszSchemeName,
  132. IN DWORD dwSchemeNameLength
  133. );
  134. DWORD
  135. MapUrlSchemeTypeToCtlId(
  136. IN INTERNET_SCHEME SchemeType,
  137. IN BOOL fIdForPortCtl
  138. );
  139. BOOL
  140. MapCtlIdUrlSchemeName(
  141. IN DWORD dwEditCtlId,
  142. OUT LPSTR lpszSchemeOut
  143. );
  144. DWORD
  145. MapAddrCtlIdToPortCtlId(
  146. IN DWORD dwEditCtlId
  147. );
  148. BOOL
  149. RemoveLocalFromExceptionList(
  150. IN LPTSTR lpszExceptionList
  151. );
  152. //
  153. // functions
  154. //
  155. /*******************************************************************
  156. NAME: ProxyDlgProc
  157. SYNOPSIS: Proxy property sheet dialog proc.
  158. ********************************************************************/
  159. INT_PTR CALLBACK ProxyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  160. LPARAM lParam)
  161. {
  162. LPPROXYPAGE pPxy= (LPPROXYPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
  163. switch (uMsg)
  164. {
  165. case WM_INITDIALOG:
  166. {
  167. BOOL fInited;
  168. fInited = ProxyDlgInit(hDlg, lParam);
  169. return fInited;
  170. }
  171. case WM_NOTIFY:
  172. {
  173. NMHDR * lpnm = (NMHDR *) lParam;
  174. switch (lpnm->code)
  175. {
  176. case PSN_APPLY:
  177. {
  178. BOOL fRet = ProxyDlgOK(hDlg);
  179. SetPropSheetResult(hDlg,!fRet);
  180. return !fRet;
  181. break;
  182. }
  183. case PSN_RESET:
  184. SetPropSheetResult(hDlg,FALSE);
  185. break;
  186. }
  187. break;
  188. }
  189. case WM_COMMAND:
  190. switch (GET_WM_COMMAND_ID(wParam, lParam))
  191. {
  192. case IDC_PROXY_ENABLE:
  193. EnableProxyControls(hDlg);
  194. break;
  195. case IDC_PROXY_HTTP_ADDRESS:
  196. case IDC_PROXY_GOPHER_ADDRESS:
  197. case IDC_PROXY_SECURITY_ADDRESS:
  198. case IDC_PROXY_FTP_ADDRESS:
  199. case IDC_PROXY_SOCKS_ADDRESS:
  200. if ( GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS )
  201. {
  202. ParseEditCtlForPort(NULL, hDlg, (GET_WM_COMMAND_ID(wParam, lParam)), 0);
  203. EnableProxyControls(hDlg);
  204. }
  205. break;
  206. case IDC_PROXY_HTTP_PORT:
  207. case IDC_PROXY_GOPHER_PORT:
  208. case IDC_PROXY_SECURITY_PORT:
  209. case IDC_PROXY_FTP_PORT:
  210. case IDC_PROXY_SOCKS_PORT:
  211. if ( GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS )
  212. {
  213. EnableProxyControls(hDlg);
  214. }
  215. break;
  216. case IDC_PROXY_USE_SAME_SERVER:
  217. if ( GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED )
  218. {
  219. if (IsDlgButtonChecked(hDlg, IDC_PROXY_USE_SAME_SERVER))
  220. pPxy->lpOldSettings = SaveCurrentSettings(hDlg);
  221. else if (pPxy->lpOldSettings !=NULL)
  222. {
  223. RestorePreviousSettings(hDlg, pPxy->lpOldSettings);
  224. pPxy->lpOldSettings = NULL;
  225. }
  226. EnableProxyControls(hDlg);
  227. }
  228. break;
  229. case IDOK:
  230. if ( GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED )
  231. {
  232. BOOL fLeaveDialog = TRUE;
  233. if (!IsProxyValid(hDlg))
  234. {
  235. // The proxy is invalid, so we need to ask the user if they want to turn it off.
  236. TCHAR szTitle[MAX_TITLE];
  237. TCHAR szMessage[MAX_DIALOG_MESSAGE];
  238. int nUserResponce;
  239. MLLoadShellLangString(IDS_INVALID_PROXY_TITLE, szTitle, ARRAYSIZE(szTitle));
  240. MLLoadShellLangString(IDS_INVALID_PROXY, szMessage, ARRAYSIZE(szMessage));
  241. // Ask the user if they want to turn off the proxy.
  242. nUserResponce = MessageBox(hDlg, szMessage, szTitle, MB_YESNOCANCEL | MB_ICONERROR);
  243. if (IDYES == nUserResponce)
  244. pPxy->lpi->fEnable = FALSE;
  245. else if (IDCANCEL == nUserResponce)
  246. fLeaveDialog = FALSE; // The user hit cancel, so let's not leave the dialog.
  247. }
  248. if (fLeaveDialog)
  249. {
  250. //
  251. // Read the Ctls and Save out to the proxy..
  252. //
  253. ProxyDlgOK(hDlg);
  254. EndDialog(hDlg, IDOK);
  255. }
  256. }
  257. break;
  258. case IDCANCEL:
  259. if ( GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED )
  260. {
  261. EndDialog(hDlg, IDCANCEL);
  262. }
  263. break;
  264. }
  265. break;
  266. case WM_DESTROY:
  267. if (pPxy->lpOldSettings)
  268. LocalFree(pPxy->lpOldSettings);
  269. if (pPxy->hinstUrlMon)
  270. FreeLibrary(pPxy->hinstUrlMon);
  271. LocalFree(pPxy);
  272. return TRUE;
  273. case WM_HELP: // F1
  274. ResWinHelp((HWND) ((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  275. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  276. break;
  277. case WM_CONTEXTMENU: // right mouse click
  278. ResWinHelp((HWND)wParam, IDS_HELPFILE,
  279. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  280. break;
  281. default:
  282. return FALSE;
  283. }
  284. return TRUE;
  285. }
  286. //
  287. // Private Functions.
  288. //
  289. VOID
  290. EnableProxyControls(HWND hDlg)
  291. /*++
  292. Routine Description:
  293. Enables controls appropriately depending on what
  294. checkboxes are checked.
  295. Arguments:
  296. hDlg - Page Dialog Box.
  297. Return Value:
  298. VOID
  299. --*/
  300. {
  301. BOOL fNT = ((LPPROXYPAGE)GetWindowLongPtr(hDlg, DWLP_USER))->fNT;
  302. BOOL fEnable = !g_restrict.fProxy;
  303. BOOL fUseOneProxy = IsDlgButtonChecked(hDlg,IDC_PROXY_USE_SAME_SERVER);
  304. EnableDlgItem(hDlg,IDC_GRP_SETTINGS2, fEnable);
  305. EnableDlgItem(hDlg,IDC_PROXY_EXCEPTIONS_GROUPBOX, fEnable);
  306. EnableDlgItem(hDlg,IDC_TYPE_TEXT, fEnable);
  307. EnableDlgItem(hDlg,IDC_ADDR_TEXT, fEnable);
  308. EnableDlgItem(hDlg,IDC_PORT_TEXT, fEnable);
  309. EnableDlgItem(hDlg,IDC_EXCEPT_TEXT, fEnable);
  310. EnableDlgItem(hDlg,IDC_EXCEPT2_TEXT, fEnable);
  311. EnableDlgItem(hDlg,IDC_PROXY_ICON1, fEnable);
  312. EnableDlgItem(hDlg,IDC_PROXY_ICON2, fEnable);
  313. EnableDlgItem(hDlg,IDC_PROXY_HTTP_CAPTION, fEnable);
  314. EnableDlgItem(hDlg,IDC_PROXY_SECURITY_CAPTION, fEnable);
  315. EnableDlgItem(hDlg,IDC_PROXY_FTP_CAPTION, fEnable);
  316. EnableDlgItem(hDlg,IDC_PROXY_GOPHER_CAPTION, fEnable);
  317. EnableDlgItem(hDlg,IDC_PROXY_SOCKS_CAPTION, fEnable);
  318. EnableDlgItem(hDlg, IDC_PROXY_USE_SAME_SERVER, fEnable);
  319. EnableDlgItem(hDlg,IDC_PROXY_HTTP_ADDRESS,fEnable);
  320. EnableDlgItem(hDlg,IDC_PROXY_HTTP_PORT,fEnable);
  321. EnableDlgItem(hDlg,IDC_PROXY_OVERRIDE,fEnable);
  322. //
  323. // If we only want one Proxy, then make all others use the same
  324. // proxy.
  325. //
  326. EnableDlgItem(hDlg,IDC_PROXY_SECURITY_ADDRESS,!fUseOneProxy && fEnable);
  327. EnableDlgItem(hDlg,IDC_PROXY_SECURITY_PORT,!fUseOneProxy && fEnable);
  328. EnableDlgItem(hDlg,IDC_PROXY_FTP_ADDRESS,!fUseOneProxy && fEnable);
  329. EnableDlgItem(hDlg,IDC_PROXY_FTP_PORT,!fUseOneProxy && fEnable);
  330. EnableDlgItem(hDlg,IDC_PROXY_GOPHER_ADDRESS,!fUseOneProxy && fEnable);
  331. EnableDlgItem(hDlg,IDC_PROXY_GOPHER_PORT,!fUseOneProxy && fEnable);
  332. EnableDlgItem(hDlg,IDC_PROXY_SOCKS_ADDRESS,!fUseOneProxy && fEnable);
  333. EnableDlgItem(hDlg,IDC_PROXY_SOCKS_PORT,!fUseOneProxy && fEnable);
  334. //
  335. // If we only want one proxy, prepopulate the other fields
  336. // so they use the the mirror of the first one.
  337. //
  338. if (fUseOneProxy)
  339. {
  340. TCHAR szProxyName[MAX_URL_STRING+1];
  341. TCHAR szProxyPort[INTERNET_MAX_PORT_LENGTH];
  342. GetDlgItemText(hDlg,
  343. IDC_PROXY_HTTP_ADDRESS,
  344. szProxyName,
  345. ARRAYSIZE(szProxyName));
  346. GetDlgItemText(hDlg,
  347. IDC_PROXY_HTTP_PORT,
  348. szProxyPort,
  349. ARRAYSIZE(szProxyPort));
  350. SetDlgItemText(hDlg,IDC_PROXY_SECURITY_ADDRESS,szProxyName);
  351. SetDlgItemText(hDlg,IDC_PROXY_SECURITY_PORT,szProxyPort);
  352. SetDlgItemText(hDlg,IDC_PROXY_FTP_ADDRESS,szProxyName);
  353. SetDlgItemText(hDlg,IDC_PROXY_FTP_PORT,szProxyPort);
  354. SetDlgItemText(hDlg,IDC_PROXY_GOPHER_ADDRESS,szProxyName);
  355. SetDlgItemText(hDlg,IDC_PROXY_GOPHER_PORT,szProxyPort);
  356. SetDlgItemText(hDlg,IDC_PROXY_SOCKS_ADDRESS,TEXT(""));
  357. SetDlgItemText(hDlg,IDC_PROXY_SOCKS_PORT,TEXT(""));
  358. }
  359. }
  360. //
  361. // SaveCurrentSettings()
  362. //
  363. // Saves current settings... just in case user changes their mind.
  364. //
  365. // Returns a pointer to a structure filled with current settings.
  366. //
  367. LPBEFOREUSESAME SaveCurrentSettings(HWND hDlg)
  368. {
  369. LPBEFOREUSESAME lpSave = (LPBEFOREUSESAME)LocalAlloc(LPTR, sizeof(*lpSave));
  370. if (!lpSave)
  371. return lpSave; // if NULL return NULL
  372. GetDlgItemText(hDlg, IDC_PROXY_FTP_ADDRESS, lpSave->szFTP, INTERNET_MAX_URL_LENGTH);
  373. GetDlgItemText(hDlg, IDC_PROXY_GOPHER_ADDRESS, lpSave->szGOPHER, INTERNET_MAX_URL_LENGTH);
  374. GetDlgItemText(hDlg, IDC_PROXY_SECURITY_ADDRESS, lpSave->szSECURE, INTERNET_MAX_URL_LENGTH);
  375. GetDlgItemText(hDlg, IDC_PROXY_SOCKS_ADDRESS, lpSave->szSOCKS, INTERNET_MAX_URL_LENGTH);
  376. GetDlgItemText(hDlg, IDC_PROXY_FTP_PORT, lpSave->szFTPport, INTERNET_MAX_URL_LENGTH);
  377. GetDlgItemText(hDlg, IDC_PROXY_GOPHER_PORT, lpSave->szGOPHERport, INTERNET_MAX_URL_LENGTH);
  378. GetDlgItemText(hDlg, IDC_PROXY_SECURITY_PORT, lpSave->szSECUREport, INTERNET_MAX_URL_LENGTH);
  379. GetDlgItemText(hDlg, IDC_PROXY_SOCKS_PORT, lpSave->szSOCKSport, INTERNET_MAX_URL_LENGTH);
  380. return lpSave;
  381. } // SaveCurrentSettings()
  382. //
  383. // RestorePreviousSettings()
  384. //
  385. // Restores settings... just in case user changes their mind.
  386. //
  387. void RestorePreviousSettings(HWND hDlg, LPBEFOREUSESAME lpSave)
  388. {
  389. if (!lpSave)
  390. return; // nothing to do
  391. SetDlgItemText(hDlg, IDC_PROXY_FTP_ADDRESS, lpSave->szFTP );
  392. SetDlgItemText(hDlg, IDC_PROXY_GOPHER_ADDRESS, lpSave->szGOPHER );
  393. SetDlgItemText(hDlg, IDC_PROXY_SECURITY_ADDRESS, lpSave->szSECURE );
  394. SetDlgItemText(hDlg, IDC_PROXY_SOCKS_ADDRESS, lpSave->szSOCKS );
  395. SetDlgItemText(hDlg, IDC_PROXY_FTP_PORT, lpSave->szFTPport );
  396. SetDlgItemText(hDlg, IDC_PROXY_GOPHER_PORT, lpSave->szGOPHERport );
  397. SetDlgItemText(hDlg, IDC_PROXY_SECURITY_PORT, lpSave->szSECUREport );
  398. SetDlgItemText(hDlg, IDC_PROXY_SOCKS_PORT, lpSave->szSOCKSport );
  399. LocalFree(lpSave); // give back the memory
  400. } // RestorePreviousSettings()
  401. BOOL
  402. ProxyDlgInit(
  403. IN HWND hDlg, LPARAM lParam
  404. )
  405. /*++
  406. Routine Description:
  407. Initialization proc for proxy prop page
  408. Arguments:
  409. hDlg - Page Dialog Box.
  410. Return Value:
  411. BOOL
  412. Success - TRUE
  413. Failure - FALSE
  414. --*/
  415. {
  416. BOOL fSuccess;
  417. LPPROXYPAGE pPxy;
  418. pPxy = (LPPROXYPAGE)LocalAlloc(LPTR, sizeof(*pPxy));
  419. // NOTE: this NULLS lpOldSettings
  420. if (!pPxy)
  421. return FALSE; // no memory?
  422. OSVERSIONINFOA osvi;
  423. osvi.dwOSVersionInfoSize = sizeof(osvi);
  424. GetVersionExA(&osvi);
  425. pPxy->fNT = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT);
  426. ASSERT(pPxy->lpOldSettings == NULL);
  427. // tell dialog where to get info
  428. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pPxy);
  429. pPxy->lpi = (LPPROXYINFO)lParam;
  430. //
  431. // Begin by reading and setting the list of proxy
  432. // servers we have.
  433. //
  434. fSuccess = ProxyDlgInitProxyServers( hDlg );
  435. if (!fSuccess)
  436. return FALSE;
  437. //
  438. // read settings from registry, for the list of Exclusion Hosts.
  439. //
  440. RegEntry re(REGSTR_PATH_INTERNETSETTINGS,HKEY_CURRENT_USER);
  441. if (re.GetError() == ERROR_SUCCESS)
  442. {
  443. BUFFER bufProxyString(MAX_URL_STRING+1);
  444. if (!bufProxyString)
  445. {
  446. MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK);
  447. return FALSE;
  448. }
  449. //
  450. // get proxy override settings from registry and stuff fields
  451. // Prevent entry of more than (MAX_URL_STRING - ("<local>" + safety))
  452. SendMessage(GetDlgItem(hDlg, IDC_PROXY_OVERRIDE), EM_SETLIMITTEXT, (WPARAM)ARRAYSIZE(pPxy->lpi->szOverride)-20, 0);
  453. SetDlgItemText(hDlg, IDC_PROXY_OVERRIDE, pPxy->lpi->szOverride);
  454. }
  455. //
  456. // initialize the UI appropriately
  457. //
  458. EnableProxyControls(hDlg);
  459. return TRUE;
  460. }
  461. BOOL
  462. ProxyDlgOK(
  463. IN HWND hDlg
  464. )
  465. /*++
  466. Routine Description:
  467. OK button handler for proxy prop page
  468. Arguments:
  469. hDlg - Page Dialog Box.
  470. Return Value:
  471. BOOL
  472. Success - TRUE
  473. Failure - FALSE
  474. --*/
  475. {
  476. LPPROXYPAGE pPxy = (LPPROXYPAGE)GetWindowLongPtr(hDlg, DWLP_USER);
  477. TCHAR szProxyListOutputBuffer[MAX_URL_STRING];
  478. CHAR szProxyListOutputBufferA[MAX_URL_STRING];
  479. DWORD dwBufferOffset = 0;
  480. //
  481. // Get the state of our two check boxes.
  482. //
  483. BOOL fUseOneProxy =
  484. IsDlgButtonChecked(hDlg,IDC_PROXY_USE_SAME_SERVER);
  485. //
  486. // Open our Registry Key.
  487. //
  488. RegEntry re(REGSTR_PATH_INTERNETSETTINGS,HKEY_CURRENT_USER);
  489. if (re.GetError() == ERROR_SUCCESS)
  490. {
  491. //
  492. // Now Format, and write out the list of proxies to
  493. // the registry. We special case the case of
  494. // only proxy.
  495. //
  496. szProxyListOutputBufferA[dwBufferOffset] = '\0';
  497. if ( fUseOneProxy )
  498. {
  499. FormatOutProxyEditCtl(
  500. hDlg,
  501. IDC_PROXY_HTTP_ADDRESS,
  502. IDC_PROXY_HTTP_PORT,
  503. szProxyListOutputBufferA,
  504. &dwBufferOffset,
  505. ARRAY_ELEMENTS(szProxyListOutputBufferA),
  506. TRUE
  507. );
  508. }
  509. else
  510. {
  511. for (int i = 1; i < ARRAY_ELEMENTS(UrlSchemeList); ++i)
  512. {
  513. FormatOutProxyEditCtl(
  514. hDlg,
  515. UrlSchemeList[i].dwControlId,
  516. UrlSchemeList[i].dwPortControlId,
  517. szProxyListOutputBufferA,
  518. &dwBufferOffset,
  519. ARRAY_ELEMENTS(szProxyListOutputBufferA),
  520. FALSE
  521. );
  522. }
  523. }
  524. szProxyListOutputBufferA[dwBufferOffset] = '\0';
  525. #ifdef UNICODE
  526. SHAnsiToUnicode(szProxyListOutputBufferA, szProxyListOutputBuffer, MAX_URL_STRING);
  527. #else
  528. lstrcpy(szProxyListOutputBuffer, szProxyListOutputBufferA);
  529. #endif
  530. StrCpyN(pPxy->lpi->szProxy, szProxyListOutputBuffer, MAX_URL_STRING);
  531. //
  532. // Now Write out the Proxy Exception List
  533. // (list of addresses to use for local connections)
  534. //
  535. szProxyListOutputBuffer[0] = '\0';
  536. GetDlgItemText(hDlg,
  537. IDC_PROXY_OVERRIDE,
  538. szProxyListOutputBuffer,
  539. ARRAY_ELEMENTS(szProxyListOutputBuffer));
  540. StrCpyN(pPxy->lpi->szOverride, szProxyListOutputBuffer, MAX_URL_STRING);
  541. }
  542. else
  543. {
  544. AssertMsg(0, TEXT("Couldn't save settings to registry!"));
  545. }
  546. // let any active (participating) wininet's get notified
  547. //
  548. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
  549. return TRUE;
  550. }
  551. INTERNET_SCHEME
  552. MapUrlSchemeName(
  553. IN LPSTR lpszSchemeName,
  554. IN DWORD dwSchemeNameLength
  555. )
  556. /*++
  557. Routine Description:
  558. Maps a scheme name/length to a scheme name type
  559. Arguments:
  560. lpszSchemeName - pointer to name of scheme to map
  561. dwSchemeNameLength - length of scheme (if -1, lpszSchemeName is ASCIZ)
  562. Return Value:
  563. INTERNET_SCHEME
  564. --*/
  565. {
  566. if (dwSchemeNameLength == (DWORD)-1)
  567. {
  568. dwSchemeNameLength = (DWORD)lstrlenA(lpszSchemeName);
  569. }
  570. for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i)
  571. {
  572. if (UrlSchemeList[i].SchemeLength == dwSchemeNameLength)
  573. {
  574. CHAR chBackup = lpszSchemeName[dwSchemeNameLength];
  575. lpszSchemeName[dwSchemeNameLength] = '\0';
  576. if(StrCmpIA(UrlSchemeList[i].SchemeName,lpszSchemeName) == 0)
  577. {
  578. lpszSchemeName[dwSchemeNameLength] = chBackup;
  579. return UrlSchemeList[i].SchemeType;
  580. }
  581. lpszSchemeName[dwSchemeNameLength] = chBackup;
  582. }
  583. }
  584. return INTERNET_SCHEME_UNKNOWN;
  585. }
  586. DWORD
  587. MapUrlSchemeTypeToCtlId(
  588. IN INTERNET_SCHEME SchemeType,
  589. IN BOOL fIdForPortCtl
  590. )
  591. /*++
  592. Routine Description:
  593. Maps a scheme to a dlg child control id.
  594. Arguments:
  595. Scheme - Scheme to Map
  596. fIdForPortCtl - If TRUE, means we really want the ID for a the PORT control
  597. not the ADDRESS control.
  598. Return Value:
  599. DWORD
  600. --*/
  601. {
  602. for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i)
  603. {
  604. if (SchemeType == UrlSchemeList[i].SchemeType)
  605. {
  606. return (fIdForPortCtl ? UrlSchemeList[i].dwPortControlId :
  607. UrlSchemeList[i].dwControlId );
  608. }
  609. }
  610. return IDC_NOTUSED;
  611. }
  612. BOOL
  613. MapCtlIdUrlSchemeName(
  614. IN DWORD dwEditCtlId,
  615. OUT LPSTR lpszSchemeOut
  616. )
  617. /*++
  618. Routine Description:
  619. Maps a dlg child control id to String represnting
  620. the name of the scheme.
  621. Arguments:
  622. dwEditCtlId - Edit Control to Map Out.
  623. lpszSchemeOut - Scheme to Map Out.
  624. WARNING: ASSUMED to be size of largest scheme type.
  625. Return Value:
  626. BOOL
  627. Success - TRUE
  628. Failure - FALSE
  629. --*/
  630. {
  631. ASSERT(lpszSchemeOut);
  632. for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i)
  633. {
  634. if (dwEditCtlId == UrlSchemeList[i].dwControlId )
  635. {
  636. StrCpyA(lpszSchemeOut, UrlSchemeList[i].SchemeName);
  637. return TRUE;
  638. }
  639. }
  640. return FALSE;
  641. }
  642. DWORD
  643. MapAddrCtlIdToPortCtlId(
  644. IN DWORD dwEditCtlId
  645. )
  646. /*++
  647. Routine Description:
  648. Maps a dlg child control id for addresses to
  649. a dlg control id for ports.
  650. Arguments:
  651. dwEditCtlId - Edit Control to Map Out.
  652. Return Value:
  653. DWORD
  654. Success - Correctly mapped ID.
  655. Failure - 0.
  656. --*/
  657. {
  658. for (int i = 0; i < ARRAY_ELEMENTS(UrlSchemeList); ++i)
  659. {
  660. if (dwEditCtlId == UrlSchemeList[i].dwControlId )
  661. {
  662. return UrlSchemeList[i].dwPortControlId ;
  663. }
  664. }
  665. return FALSE;
  666. }
  667. BOOL
  668. ProxyDlgInitProxyServers(
  669. IN HWND hDlg
  670. )
  671. /*++
  672. Routine Description:
  673. Parses a list of proxy servers and sets them into the newly created
  674. Proxy Dialog.
  675. Ruthlessly stolen from RFirth's proxysup.cxx in WININET by
  676. ArthurBi.
  677. Arguments:
  678. hDlg - HWin to add our stuff to.
  679. Return Value:
  680. BOOL
  681. Success - TRUE
  682. Failure - FALSE
  683. Comments:
  684. Designed to handle Proxy string entry of the Form:
  685. pointer to list of proxies of the form:
  686. [<protocol>=][<scheme>"://"]<server>[":"<port>][";"*]
  687. The list can is read from the registry.
  688. --*/
  689. {
  690. DWORD error = !ERROR_SUCCESS;
  691. DWORD entryLength;
  692. LPSTR protocolName;
  693. DWORD protocolLength;
  694. LPSTR schemeName;
  695. DWORD schemeLength;
  696. LPSTR serverName;
  697. DWORD serverLength;
  698. PARSER_STATE state;
  699. DWORD nSlashes;
  700. INTERNET_PORT port;
  701. BOOL done;
  702. LPSTR lpszList;
  703. entryLength = 0;
  704. protocolLength = 0;
  705. schemeName = NULL;
  706. schemeLength = 0;
  707. serverName = NULL;
  708. serverLength = 0;
  709. state = STATE_PROTOCOL;
  710. nSlashes = 0;
  711. port = 0;
  712. done = FALSE;
  713. //
  714. // Open the Reg Key.
  715. //
  716. RegEntry re(REGSTR_PATH_INTERNETSETTINGS,HKEY_CURRENT_USER);
  717. if (re.GetError() != ERROR_SUCCESS)
  718. return FALSE; // no REG values..
  719. //
  720. // Crack the Registry values, read the proxy list
  721. //
  722. BUFFER bufProxyString(MAX_URL_STRING+1);
  723. BOOL fProxyEnabled;
  724. if (!bufProxyString)
  725. {
  726. MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK);
  727. return FALSE;
  728. }
  729. //
  730. // is proxy enabled?
  731. // It should if we got into this dialog.
  732. //
  733. fProxyEnabled = (BOOL)re.GetNumber(REGSTR_VAL_PROXYENABLE,0);
  734. //
  735. // get proxy server and override settings from registry and stuff fields
  736. //
  737. re.GetString(REGSTR_VAL_PROXYSERVER,bufProxyString.QueryPtr(),
  738. bufProxyString.QuerySize());
  739. LPPROXYPAGE pPxy = (LPPROXYPAGE)GetWindowLongPtr(hDlg, DWLP_USER);
  740. // if there's a proxy passed in from the main page, then use it; otherwise use the registry val
  741. #ifndef UNICODE
  742. lpszList = pPxy->lpi->szProxy;
  743. #else
  744. char* szList = NULL;
  745. LPTSTR lpTmp = pPxy->lpi->szProxy;
  746. DWORD cch = lstrlen(lpTmp) + 1;
  747. szList = new char[2 * cch];
  748. if (szList)
  749. {
  750. SHUnicodeToAnsi(lpTmp, szList, 2 * cch);
  751. lpszList = szList;
  752. }
  753. else
  754. {
  755. MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK);
  756. return FALSE;
  757. }
  758. #endif
  759. protocolName = lpszList;
  760. //
  761. // walk the list, pulling out the various scheme parts
  762. //
  763. do
  764. {
  765. char ch = *lpszList++;
  766. if ((nSlashes == 1) && (ch != '/'))
  767. {
  768. state = STATE_ERROR;
  769. break;
  770. }
  771. switch (ch)
  772. {
  773. case '=':
  774. if ((state == STATE_PROTOCOL) && (entryLength != 0))
  775. {
  776. protocolLength = entryLength;
  777. entryLength = 0;
  778. state = STATE_SCHEME;
  779. schemeName = lpszList;
  780. }
  781. else
  782. {
  783. //
  784. // '=' can't legally appear anywhere else
  785. //
  786. state = STATE_ERROR;
  787. }
  788. break;
  789. case ':':
  790. switch (state)
  791. {
  792. case STATE_PROTOCOL:
  793. if (*lpszList == '/')
  794. {
  795. schemeName = protocolName;
  796. protocolName = NULL;
  797. schemeLength = entryLength;
  798. protocolLength = 0;
  799. state = STATE_SCHEME;
  800. }
  801. else if (*lpszList != '\0')
  802. {
  803. serverName = protocolName;
  804. serverLength = entryLength;
  805. state = STATE_PORT;
  806. }
  807. else
  808. {
  809. state = STATE_ERROR;
  810. }
  811. entryLength = 0;
  812. break;
  813. case STATE_SCHEME:
  814. if (*lpszList == '/')
  815. {
  816. schemeLength = entryLength;
  817. }
  818. else if (*lpszList != '\0')
  819. {
  820. serverName = schemeName;
  821. serverLength = entryLength;
  822. state = STATE_PORT;
  823. }
  824. else
  825. {
  826. state = STATE_ERROR;
  827. }
  828. entryLength = 0;
  829. break;
  830. case STATE_SERVER:
  831. serverLength = entryLength;
  832. state = STATE_PORT;
  833. entryLength = 0;
  834. break;
  835. default:
  836. state = STATE_ERROR;
  837. break;
  838. }
  839. break;
  840. case '/':
  841. if ((state == STATE_SCHEME) && (nSlashes < 2) && (entryLength == 0))
  842. {
  843. if (++nSlashes == 2)
  844. {
  845. state = STATE_SERVER;
  846. serverName = lpszList;
  847. }
  848. }
  849. else
  850. {
  851. state = STATE_ERROR;
  852. }
  853. break;
  854. case '\v': // vertical tab, 0x0b
  855. case '\f': // form feed, 0x0c
  856. if (!((state == STATE_PROTOCOL) && (entryLength == 0)))
  857. {
  858. //
  859. // can't have embedded whitespace
  860. //
  861. state = STATE_ERROR;
  862. }
  863. break;
  864. default:
  865. if (state != STATE_PORT)
  866. {
  867. ++entryLength;
  868. }
  869. else if (isdigit(ch))
  870. {
  871. //
  872. // we will overflow if >65535
  873. //
  874. Assert(port < 65535);
  875. port = port * 10 + (ch - '0');
  876. }
  877. else
  878. {
  879. //
  880. // STATE_PORT && non-digit character - error
  881. //
  882. state = STATE_ERROR;
  883. }
  884. break;
  885. case '\0':
  886. done = TRUE;
  887. //
  888. // fall through
  889. //
  890. case ' ':
  891. case '\t':
  892. case '\n':
  893. case '\r':
  894. case ';':
  895. case ',':
  896. if (serverLength == 0)
  897. {
  898. serverLength = entryLength;
  899. }
  900. if (serverLength != 0)
  901. {
  902. if (serverName == NULL)
  903. {
  904. serverName = (schemeName != NULL)
  905. ? schemeName : protocolName;
  906. }
  907. ASSERT(serverName != NULL);
  908. INTERNET_SCHEME protocol;
  909. if (protocolLength != 0)
  910. {
  911. protocol = MapUrlSchemeName(protocolName, protocolLength);
  912. }
  913. else
  914. {
  915. protocol = INTERNET_SCHEME_DEFAULT;
  916. }
  917. INTERNET_SCHEME scheme;
  918. if (schemeLength != 0)
  919. {
  920. scheme = MapUrlSchemeName(schemeName, schemeLength);
  921. }
  922. else
  923. {
  924. scheme = INTERNET_SCHEME_DEFAULT;
  925. }
  926. //
  927. // add an entry if this is a protocol we handle and we don't
  928. // already have an entry for it
  929. //
  930. if ((protocol != INTERNET_SCHEME_UNKNOWN)
  931. && (scheme != INTERNET_SCHEME_UNKNOWN))
  932. {
  933. DWORD dwCtlId = IDC_NOTUSED;
  934. DWORD dwPortCtlId = IDC_NOTUSED;
  935. CHAR chBackup;
  936. error = ERROR_SUCCESS;
  937. //
  938. // we can only currently handle CERN proxies (unsecure or
  939. // secure) so kick out anything that wants to go via a different
  940. // proxy scheme
  941. //
  942. if (protocol == INTERNET_SCHEME_DEFAULT)
  943. {
  944. CheckDlgButton( hDlg, IDC_PROXY_USE_SAME_SERVER, TRUE );
  945. dwCtlId = IDC_PROXY_HTTP_ADDRESS;
  946. dwPortCtlId = IDC_PROXY_HTTP_PORT;
  947. }
  948. else
  949. {
  950. dwCtlId = MapUrlSchemeTypeToCtlId(protocol,FALSE);
  951. dwPortCtlId = MapUrlSchemeTypeToCtlId(protocol,TRUE);
  952. }
  953. //
  954. // Set the Field Entry.
  955. //
  956. LPSTR lpszProxyNameText;
  957. if (scheme != INTERNET_SCHEME_DEFAULT)
  958. {
  959. ASSERT(schemeLength != 0);
  960. lpszProxyNameText = schemeName;
  961. }
  962. else
  963. lpszProxyNameText = serverName;
  964. chBackup = serverName[serverLength];
  965. serverName[serverLength] = '\0';
  966. SetDlgItemTextA( hDlg, dwCtlId, lpszProxyNameText );
  967. if ( port )
  968. SetDlgItemInt( hDlg, dwPortCtlId, port, FALSE );
  969. serverName[serverLength] = chBackup;
  970. }
  971. else
  972. {
  973. //
  974. // bad/unrecognised protocol or scheme. Treat it as error
  975. // for now
  976. //
  977. error = !ERROR_SUCCESS;
  978. }
  979. }
  980. entryLength = 0;
  981. protocolName = lpszList;
  982. protocolLength = 0;
  983. schemeName = NULL;
  984. schemeLength = 0;
  985. serverName = NULL;
  986. serverLength = 0;
  987. nSlashes = 0;
  988. port = 0;
  989. if (error == ERROR_SUCCESS)
  990. {
  991. state = STATE_PROTOCOL;
  992. }
  993. else
  994. {
  995. state = STATE_ERROR;
  996. }
  997. break;
  998. }
  999. if (state == STATE_ERROR)
  1000. {
  1001. break;
  1002. }
  1003. } while (!done);
  1004. #ifdef UNICODE
  1005. delete [] szList;
  1006. #endif
  1007. if (state == STATE_ERROR)
  1008. {
  1009. error = ERROR_INVALID_PARAMETER;
  1010. }
  1011. if ( error == ERROR_SUCCESS )
  1012. error = TRUE;
  1013. else
  1014. error = FALSE;
  1015. return error;
  1016. }
  1017. BOOL
  1018. IsProxyValid(
  1019. IN HWND hDlg
  1020. )
  1021. /*++
  1022. Routine Description:
  1023. Determines if the Proxy is valid. The proxy is invalid if
  1024. all of the proxy entries are empty.
  1025. Arguments:
  1026. hDlg - HWIN of the dialog to play with.
  1027. Return Value:
  1028. BOOL
  1029. Success TRUE - Valid.
  1030. FALSE - Invalid.
  1031. --*/
  1032. {
  1033. BOOL fProxyIsValid = FALSE;
  1034. TCHAR szProxyUrl[MAX_URL_STRING+1];
  1035. int iCurrentProxy = 0;
  1036. ASSERT(IsWindow(hDlg));
  1037. for (int iIndex = 0; iIndex < ARRAYSIZE(g_iProxies); iIndex++)
  1038. {
  1039. szProxyUrl[0] = '\0';
  1040. GetDlgItemText(hDlg,
  1041. g_iProxies[iIndex],
  1042. szProxyUrl,
  1043. sizeof(szProxyUrl));
  1044. if (szProxyUrl[0])
  1045. {
  1046. fProxyIsValid = TRUE;
  1047. break;
  1048. }
  1049. }
  1050. return fProxyIsValid;
  1051. }
  1052. BOOL
  1053. ParseEditCtlForPort(
  1054. IN OUT LPSTR lpszProxyName,
  1055. IN HWND hDlg,
  1056. IN DWORD dwProxyNameCtlId,
  1057. IN DWORD dwProxyPortCtlId
  1058. )
  1059. /*++
  1060. Routine Description:
  1061. Parses a Port Number off then end of a Proxy Server URL that is
  1062. located either in the Proxy Name Edit Box, or passed in as
  1063. a string pointer.
  1064. Arguments:
  1065. lpszProxyName - (OPTIONAL) string pointer with Proxy Name to parse, and
  1066. set into the Proxy Name edit ctl field.
  1067. hDlg - HWIN of the dialog to play with.
  1068. dwProxyNameCtlId - Res Ctl Id to play with.
  1069. dwProxyPortCtlId - Res Ctl Id of Port Number Edit Box.
  1070. Return Value:
  1071. BOOL
  1072. Success TRUE -
  1073. Failure FALSE
  1074. --*/
  1075. {
  1076. CHAR szProxyUrl[MAX_URL_STRING+1];
  1077. LPSTR lpszPort;
  1078. LPSTR lpszProxyUrl;
  1079. ASSERT(IsWindow(hDlg));
  1080. if ( dwProxyPortCtlId == 0 )
  1081. {
  1082. dwProxyPortCtlId = MapAddrCtlIdToPortCtlId(dwProxyNameCtlId);
  1083. ASSERT(dwProxyPortCtlId);
  1084. }
  1085. //
  1086. // Get the Proxy String from the Edit Control
  1087. // (OR) from the Registry [passed in]
  1088. //
  1089. if ( lpszProxyName )
  1090. lpszProxyUrl = lpszProxyName;
  1091. else
  1092. {
  1093. //
  1094. // Need to Grab it out of the edit control.
  1095. //
  1096. GetDlgItemTextA(hDlg,
  1097. dwProxyNameCtlId,
  1098. szProxyUrl,
  1099. sizeof(szProxyUrl));
  1100. lpszProxyUrl = szProxyUrl;
  1101. }
  1102. //
  1103. // Now find the port.
  1104. //
  1105. lpszPort = lpszProxyUrl;
  1106. GET_TERMINATOR(lpszPort);
  1107. lpszPort--;
  1108. //
  1109. // Walk backwards from the end of url looking
  1110. // for a port number sitting on the end like this
  1111. // http://proxy:1234
  1112. //
  1113. while ( (lpszPort > lpszProxyUrl) &&
  1114. (*lpszPort != ':') &&
  1115. (isdigit(*lpszPort)) )
  1116. {
  1117. lpszPort--;
  1118. }
  1119. //
  1120. // If we found a match for our rules
  1121. // then set the port, otherwise
  1122. // we assume the user knows what he's
  1123. // doing.
  1124. //
  1125. if ( *lpszPort == ':' && isdigit(*(lpszPort+1)) )
  1126. {
  1127. *lpszPort = '\0';
  1128. SetDlgItemTextA(hDlg, dwProxyPortCtlId, (lpszPort+1));
  1129. }
  1130. SetDlgItemTextA(hDlg, dwProxyNameCtlId, lpszProxyUrl);
  1131. return TRUE;
  1132. }
  1133. BOOL
  1134. FormatOutProxyEditCtl(
  1135. IN HWND hDlg,
  1136. IN DWORD dwProxyNameCtlId,
  1137. IN DWORD dwProxyPortCtlId,
  1138. OUT LPSTR lpszOutputStr,
  1139. IN OUT LPDWORD lpdwOutputStrSize,
  1140. IN DWORD dwOutputStrLength,
  1141. IN BOOL fDefaultProxy
  1142. )
  1143. /*++
  1144. Routine Description:
  1145. Combines Proxy URL components into a string that can be saved
  1146. in the registry. Can be called multiple times to build
  1147. a list of proxy servers, or once to special case a "default"
  1148. proxy.
  1149. Arguments:
  1150. hDlg - HWIN of the dialog to play with.
  1151. dwProxyNameCtlId - Res Ctl Id to play with.
  1152. dwProxyPortCtlId - Res Ctl Id of Port Number Edit Box.
  1153. lpszOutputStr - The start of the output string to send
  1154. the product of this function.
  1155. lpdwOutputStrSize - The amount of used space in lpszOutputStr
  1156. that is already used. New output should
  1157. start from (lpszOutputStr + *lpdwOutputStrSize)
  1158. fDefaultProxy - Default Proxy, don't add scheme= in front of the proxy
  1159. just use plop one proxy into the registry.
  1160. Return Value:
  1161. BOOL
  1162. Success TRUE
  1163. Failure FALSE
  1164. --*/
  1165. {
  1166. LPSTR lpszOutput;
  1167. LPSTR lpszEndOfOutputStr;
  1168. ASSERT(IsWindow(hDlg));
  1169. ASSERT(lpdwOutputStrSize);
  1170. lpszOutput = lpszOutputStr + *lpdwOutputStrSize;
  1171. lpszEndOfOutputStr = lpszOutputStr + dwOutputStrLength;
  1172. ASSERT( lpszEndOfOutputStr > lpszOutput );
  1173. if ( lpszEndOfOutputStr <= lpszOutput )
  1174. return FALSE; // bail out, ran out of space
  1175. //
  1176. // Plop ';' if we're not the first in this string buffer.
  1177. //
  1178. if (*lpdwOutputStrSize != 0 )
  1179. {
  1180. *lpszOutput = ';';
  1181. lpszOutput++;
  1182. if ( lpszEndOfOutputStr <= lpszOutput )
  1183. return FALSE; // bail out, ran out of space
  1184. }
  1185. //
  1186. // Put the schemetype= into the string
  1187. // ex: http=
  1188. //
  1189. if ( ! fDefaultProxy )
  1190. {
  1191. if ( lpszEndOfOutputStr <= (MAX_SCHEME_NAME_LENGTH + lpszOutput + 1) )
  1192. return FALSE; // bail out, ran out of space
  1193. if (!MapCtlIdUrlSchemeName(dwProxyNameCtlId,lpszOutput))
  1194. return FALSE;
  1195. lpszOutput += lstrlenA(lpszOutput);
  1196. *lpszOutput = '=';
  1197. lpszOutput++;
  1198. }
  1199. //
  1200. // Need to Grab ProxyUrl out of the edit control.
  1201. //
  1202. GetDlgItemTextA(hDlg, dwProxyNameCtlId, lpszOutput, (int)(lpszEndOfOutputStr - lpszOutput));
  1203. if ( IS_BLANK(lpszOutput) )
  1204. return FALSE;
  1205. //
  1206. // Now seperate out the port so we can save them seperately.
  1207. // But go past the Proxy Url while we're at it.
  1208. // ex: http=http://netscape-proxy
  1209. //
  1210. if (!ParseEditCtlForPort(lpszOutput, hDlg, dwProxyNameCtlId, dwProxyPortCtlId))
  1211. return FALSE;
  1212. lpszOutput += lstrlenA(lpszOutput);
  1213. //
  1214. // Now, add in a ':" for the port number, if we don't
  1215. // have a port we'll remove it.
  1216. //
  1217. {
  1218. *lpszOutput = ':';
  1219. lpszOutput++;
  1220. if ( lpszEndOfOutputStr <= lpszOutput )
  1221. return FALSE; // bail out, ran out of space
  1222. }
  1223. //
  1224. // Grab Proxy Port if its around.
  1225. // Back out the ':' if its not.
  1226. //
  1227. GetDlgItemTextA(hDlg, dwProxyPortCtlId,lpszOutput, (int)(lpszEndOfOutputStr - lpszOutput));
  1228. if ( IS_BLANK(lpszOutput) )
  1229. {
  1230. lpszOutput--;
  1231. ASSERT(*lpszOutput == ':');
  1232. *lpszOutput = '\0';
  1233. }
  1234. lpszOutput += lstrlenA(lpszOutput);
  1235. //
  1236. // Now we're done return our final sizes.
  1237. //
  1238. *lpdwOutputStrSize = (DWORD)(lpszOutput - lpszOutputStr);
  1239. return TRUE;
  1240. }
  1241. BOOL
  1242. RemoveLocalFromExceptionList(
  1243. IN LPTSTR lpszExceptionList
  1244. )
  1245. /*++
  1246. Routine Description:
  1247. Scans a delimited list of entries, and removed "<local>
  1248. if found. If <local> is found we return TRUE.
  1249. Arguments:
  1250. lpszExceptionList - String List of proxy excepion entries.
  1251. Return Value:
  1252. BOOL
  1253. TRUE - If found <local>
  1254. FALSE - If local was not found.
  1255. --*/
  1256. {
  1257. LPTSTR lpszLocalInstToRemove;
  1258. BOOL fFoundLocal;
  1259. if ( !lpszExceptionList || ! *lpszExceptionList )
  1260. return FALSE;
  1261. fFoundLocal = FALSE;
  1262. lpszLocalInstToRemove = lpszExceptionList;
  1263. //
  1264. // Loop looking "<local>" entries in the list.
  1265. //
  1266. do {
  1267. lpszLocalInstToRemove =
  1268. StrStrI(lpszLocalInstToRemove,cszLocalString);
  1269. if ( lpszLocalInstToRemove )
  1270. {
  1271. fFoundLocal = TRUE;
  1272. //
  1273. // Nuke <local> out of the string. <local>;otherstuff\0
  1274. // Dest is: '<'local>;otherstuff\0
  1275. // ??? (OR) ';'<local> if the ; is the first character.???
  1276. // Src is: >'o'therstuff\0
  1277. // size is: sizeof(';otherstuff\0')
  1278. //
  1279. MoveMemory(
  1280. lpszLocalInstToRemove,
  1281. (lpszLocalInstToRemove+lstrlen(cszLocalString)),
  1282. lstrlen(lpszLocalInstToRemove+lstrlen(cszLocalString))*sizeof(TCHAR)+sizeof(TCHAR)
  1283. );
  1284. }
  1285. } while (lpszLocalInstToRemove && *lpszLocalInstToRemove);
  1286. //
  1287. // If we produced a ; on the end, nuke it.
  1288. //
  1289. lpszLocalInstToRemove = lpszExceptionList;
  1290. GET_TERMINATOR(lpszLocalInstToRemove);
  1291. if ( lpszLocalInstToRemove != lpszExceptionList &&
  1292. *(lpszLocalInstToRemove-1) == ';' )
  1293. {
  1294. *(lpszLocalInstToRemove-1) = '\0';
  1295. }
  1296. return fFoundLocal;
  1297. }