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.

4754 lines
172 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1993-1996 Microsoft Corporation. All Rights Reserved.
  3. //
  4. // MODULE: Server.cpp
  5. //
  6. // PURPOSE: Contains the dialog callback and supporting functions for
  7. // the Add/Remove news server dialog.
  8. //
  9. #include "pch.hxx"
  10. #include <mimeole.h>
  11. #include <commctrl.h>
  12. #include <wininet.h>
  13. #include <shlwapi.h>
  14. #include <shlwapip.h>
  15. #include <ras.h>
  16. #include "imnact.h"
  17. #include "acctman.h"
  18. #include "connect.h"
  19. #include "acctui.h"
  20. #include "server.h"
  21. #include "strconst.h"
  22. #include "dllmain.h"
  23. #include <icwcfg.h>
  24. #include "resource.h"
  25. #include "accthelp.h"
  26. #include <icwacct.h>
  27. #include <acctimp.h>
  28. #include "icwwiz.h"
  29. #include <wincrypt.h>
  30. #include <wintrust.h>
  31. #include <cryptdlg.h>
  32. #include "htmlhelp.h"
  33. #include "shared.h"
  34. #include "oeconprp.h"
  35. #include "demand.h"
  36. #ifdef _UNICODE
  37. #define _T(x) L ## x
  38. #else
  39. #define _T(x) x
  40. #endif
  41. ASSERTDATA
  42. typedef struct tagFilterInfo
  43. {
  44. TCHAR *szEmail;
  45. BOOL fEncryption;
  46. DWORD dwFlags;
  47. } ACCTFILTERINFO;
  48. typedef struct tagSVRDLGINFO
  49. {
  50. SERVER_TYPE sfType;
  51. DWORD dwDirty;
  52. BOOL dwInit;
  53. BOOL fNoValidate;
  54. } SVRDLGINFO;
  55. typedef struct tagSECPAGEINFO
  56. {
  57. PCCERT_CONTEXT pCert;
  58. HCERTSTORE hCertStore;
  59. PCCERT_CONTEXT pEncryptCert;
  60. } SECPAGEINFO;
  61. typedef struct tagSMTPAUTHINFO
  62. {
  63. BOOL fDirty;
  64. SMTPAUTHTYPE authtype;
  65. CHAR szUserName[CCHMAX_USERNAME];
  66. CHAR szPassword[CCHMAX_PASSWORD];
  67. BOOL fPromptPassword;
  68. } SMTPAUTHINFO, *LPSMTPAUTHINFO;
  69. INT_PTR CALLBACK ServerProp_GeneralDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  70. INT_PTR CALLBACK ServerProp_ServerDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  71. INT_PTR CALLBACK ServerProp_AdvancedDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  72. INT_PTR CALLBACK SmtpLogonSettingsDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  73. INT_PTR CALLBACK MailServer_GeneralDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  74. INT_PTR CALLBACK MailServer_ServersDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  75. INT_PTR CALLBACK MailServer_SecurityDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  76. INT_PTR CALLBACK MailServer_AdvancedDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  77. INT_PTR CALLBACK MailServer_IMAPDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  78. INT_PTR CALLBACK DirServer_GeneralDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  79. INT_PTR CALLBACK DirServer_AdvancedDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  80. void ImapRemoveTrailingHC(LPSTR pszPath, UINT uiLen);
  81. BOOL ValidateAccountName(HWND hwnd, HWND hwndEdit, IImnAccount *pAcct, int *pidsError);
  82. void GetAccountName(HWND hwndEdit, IImnAccount *pAcct);
  83. void InitUserInformation(HWND hwnd, IImnAccount *pAcct, BOOL fNews);
  84. BOOL ValidateUserInformation(HWND hwnd, IImnAccount *pAcct, BOOL fNews, HWND *phwndErr, int *puIdsErr, BOOL fApply);
  85. void GetUserInformation(HWND hwnd, IImnAccount *pAcct, BOOL fNews);
  86. BOOL ValidateServerName(HWND hwnd, HWND hwndEdit, IImnAccount *pAcct, DWORD dwPropSvr, int *pidsError, BOOL fApply);
  87. void GetServerName(HWND hwndEdit, IImnAccount *pAcct, DWORD dwPropSvr);
  88. BOOL ValidateLogonSettings(HWND hwnd, DWORD dwDlgFlags, HWND *phwndError, int *pidsError);
  89. void GetLogonSettings(HWND hwnd, IImnAccount *pAcct, BOOL fLogon, DWORD srv);
  90. BOOL fWarnDomainName(HWND hwnd, DWORD dwDlgFlags, LPTSTR pszPreviousLoginName);
  91. int CALLBACK PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam);
  92. BOOL ValidateCertificate(HWND hwnd, IImnAccount *pAcct, SVRDLGINFO *psdi, HWND *phwndErr, int *puIdsErr);
  93. BOOL DoCertDialog(HWND hwndOwner, HWND hwndEmail, PCCERT_CONTEXT *ppCert, HCERTSTORE hCertStore, int *pidsError, DWORD dwFlags, BOOL fEncription);
  94. BOOL CertFilterFunction(PCCERT_CONTEXT pCertContext, LPARAM dwEmailAddr, DWORD dwFlags, DWORD);
  95. void GetCertificate(HWND hwnd, IImnAccount *pAcct, SVRDLGINFO *psdi);
  96. DWORD InitCertificateData(TCHAR * szEmail, SVRDLGINFO *psdi, IImnAccount *pAcct);
  97. DWORD InitEncryptData(TCHAR * szEmail, SECPAGEINFO *psdi, IImnAccount *pAcct);
  98. int CheckKeyUsage(PCCERT_CONTEXT pCert, DWORD dwFlag);
  99. HRESULT HrGetHighestSymcaps(LPBYTE * ppbSymcap, ULONG *pcbSymcap);
  100. BOOL AdvSec_FillEncAlgCombo(HWND hwnd, IImnAccount *pAcct, PCCERT_CONTEXT * prgCerts);
  101. BOOL AdvSec_GetEncryptAlgCombo(HWND hwnd, IImnAccount *pAcct);
  102. void GetDigitalID(HWND hwnd);
  103. DWORD DwGenerateTrustedChain(
  104. HWND hwnd,
  105. DWORD dwFlags,
  106. PCCERT_CONTEXT pcCertToTest,
  107. DWORD dwToIgnore,
  108. BOOL fFullSearch,
  109. DWORD * pcChain,
  110. PCCERT_CONTEXT ** prgChain);
  111. #define SERVERPROP_PAGEMAX 7
  112. typedef struct tagSERVERPROP_PAGE
  113. {
  114. UINT uDlgId;
  115. DLGPROC pfnDlg;
  116. } SERVERPROP_PAGE;
  117. typedef struct tagSERVERPROP_PARAMS
  118. {
  119. UINT uIcon;
  120. UINT idsCaption;
  121. SERVERPROP_PAGE rgPage[SERVERPROP_PAGEMAX];
  122. } SERVERPROP_PARAMS;
  123. static const SERVERPROP_PARAMS c_rgServerPropParams[ACCT_LAST] = {
  124. // news
  125. { idiNewsServer,
  126. idsNewsAcctProperties,
  127. {{iddServerProp_General, ServerProp_GeneralDlgProc},
  128. {iddServerProp_Server, ServerProp_ServerDlgProc},
  129. {iddServerProp_Connect, ConnectPage_DlgProc},
  130. {iddServerProp_Advanced, ServerProp_AdvancedDlgProc},
  131. {0, NULL},
  132. {0, NULL},
  133. {0, NULL}}
  134. },
  135. // mail
  136. { idiMailServer,
  137. idsMailAcctProperties,
  138. {{iddMailSvrProp_General, MailServer_GeneralDlgProc},
  139. {iddMailSvrProp_Servers, MailServer_ServersDlgProc},
  140. {iddMailSvrProp_HttpServer, MailServer_ServersDlgProc},
  141. {iddServerProp_Connect, ConnectPage_DlgProc},
  142. {iddMailSvrProp_Security, MailServer_SecurityDlgProc},
  143. {iddMailSvrProp_Advanced, MailServer_AdvancedDlgProc},
  144. {iddMailSvrProp_IMAP, MailServer_IMAPDlgProc}}
  145. },
  146. // directory service
  147. { idiLDAPServer,
  148. idsDirSrvAcctProperties,
  149. {{iddDirServProp_General, DirServer_GeneralDlgProc},
  150. {iddDirServProp_Advanced, DirServer_AdvancedDlgProc},
  151. {0, NULL},
  152. {0, NULL},
  153. {0, NULL},
  154. {0, NULL},
  155. {0, NULL}}
  156. }
  157. };
  158. // generate static prop tables for each of the protocols
  159. #define GEN_PROPS(type) \
  160. { \
  161. AP_##type##_SERVER, \
  162. AP_##type##_USERNAME, \
  163. AP_##type##_PASSWORD, \
  164. AP_##type##_PROMPT_PASSWORD, \
  165. AP_##type##_USE_SICILY \
  166. }
  167. static MAILSERVERPROPSINFO c_rgMailServerProps[] =
  168. {
  169. GEN_PROPS(POP3),
  170. GEN_PROPS(IMAP),
  171. GEN_PROPS(HTTPMAIL),
  172. GEN_PROPS(NNTP),
  173. { AP_LDAP_SERVER, AP_LDAP_USERNAME, AP_LDAP_PASSWORD, 0, AP_LDAP_AUTHENTICATION }
  174. };
  175. #undef GEN_PROPS
  176. // Public constants
  177. BOOL GetServerProps(SERVER_TYPE serverType, LPMAILSERVERPROPSINFO *psp)
  178. {
  179. Assert(psp);
  180. switch (serverType)
  181. {
  182. case SERVER_MAIL:
  183. *psp = &c_rgMailServerProps[0];
  184. break;
  185. case SERVER_IMAP:
  186. *psp = &c_rgMailServerProps[1];
  187. break;
  188. case SERVER_HTTPMAIL:
  189. *psp = &c_rgMailServerProps[2];
  190. break;
  191. case SERVER_NEWS:
  192. *psp = &c_rgMailServerProps[3];
  193. break;
  194. case SERVER_LDAP:
  195. *psp = &c_rgMailServerProps[4];
  196. break;
  197. default:
  198. *psp = NULL;
  199. break;
  200. }
  201. return (NULL != *psp);
  202. }
  203. void MarkPageDirty(HWND hwnd, LPARAM page)
  204. {
  205. PropSheet_QuerySiblings(GetParent(hwnd), SM_SETDIRTY, page);
  206. PropSheet_Changed(GetParent(hwnd), hwnd);
  207. }
  208. int HandleQuerySiblings(HWND hwnd, SVRDLGINFO *psdi, IImnAccount *pAcct, WPARAM wParam, LPARAM lParam)
  209. {
  210. int fRet;
  211. DWORD dwPage, *pdw;
  212. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  213. HWND hwndT, hwndPage;
  214. ULONG uidsError, idCtrl, idd;
  215. Assert(psdi != NULL);
  216. Assert(pAcct != NULL);
  217. fRet = TRUE;
  218. switch (wParam)
  219. {
  220. case MSM_GETSERVERTYPE:
  221. Assert(lParam != NULL);
  222. Assert(psdi->sfType == SERVER_MAIL || psdi->sfType == SERVER_IMAP || psdi->sfType == SERVER_HTTPMAIL);
  223. *((SERVER_TYPE *)lParam) = psdi->sfType;
  224. break;
  225. case MSM_GETEMAILADDRESS:
  226. GetDlgItemText(hwnd, IDE_EMAIL_ADDRESS, sz, ARRAYSIZE(sz));
  227. StrCpyN((LPTSTR)lParam, sz, CCHMAX_EMAIL_ADDRESS);
  228. break;
  229. case MSM_GETDISPLAYNAME:
  230. GetDlgItemText(hwnd, IDE_DISPLAY_NAME, sz, ARRAYSIZE(sz));
  231. StrCpyN((LPTSTR)lParam, sz, CCHMAX_DISPLAY_NAME);
  232. break;
  233. case SM_SETDIRTY:
  234. if (!!(psdi->dwInit & lParam))
  235. psdi->dwDirty = (psdi->dwDirty | (DWORD) lParam);
  236. break;
  237. case SM_SAVECHANGES:
  238. pdw = (DWORD *)lParam;
  239. if (!!(psdi->dwInit & *pdw) && psdi->dwDirty != 0)
  240. {
  241. psdi->dwDirty = (psdi->dwDirty & ~(*pdw));
  242. if (psdi->dwDirty == 0)
  243. {
  244. uidsError = 0;
  245. dwPage = PAGE_SERVER;
  246. if (psdi->sfType == SERVER_MAIL || psdi->sfType == SERVER_IMAP)
  247. {
  248. if (FAILED(pAcct->GetPropSz(AP_SMTP_SERVER, sz, ARRAYSIZE(sz))))
  249. {
  250. uidsError = idsEnterSmtpServer;
  251. idCtrl = IDC_SMTP_EDIT;
  252. idd = iddMailSvrProp_Servers;
  253. }
  254. else if (psdi->sfType == SERVER_MAIL &&
  255. FAILED(pAcct->GetPropSz(AP_POP3_SERVER, sz, ARRAYSIZE(sz))))
  256. {
  257. uidsError = idsEnterPop3Server;
  258. idCtrl = IDC_POP3_EDIT;
  259. idd = iddMailSvrProp_Servers;
  260. }
  261. else if (psdi->sfType == SERVER_IMAP &&
  262. FAILED(pAcct->GetPropSz(AP_IMAP_SERVER, sz, ARRAYSIZE(sz))))
  263. {
  264. uidsError = idsEnterIMAPServer;
  265. idCtrl = IDC_POP3_EDIT;
  266. idd = iddMailSvrProp_Servers;
  267. }
  268. else if (psdi->sfType == SERVER_HTTPMAIL &&
  269. FAILED(pAcct->GetPropSz(AP_HTTPMAIL_SERVER, sz, ARRAYSIZE(sz))))
  270. {
  271. uidsError = idsEnterHTTPMailServer;
  272. idCtrl = IDC_POP3_EDIT;
  273. idd = iddMailSvrProp_Servers;
  274. }
  275. }
  276. else if (psdi->sfType == SERVER_NEWS)
  277. {
  278. if (FAILED(pAcct->GetPropSz(AP_NNTP_SERVER, sz, ARRAYSIZE(sz))))
  279. {
  280. uidsError = idsEnterIMAPServer;
  281. idCtrl = IDC_NEWSNAME_EDIT;
  282. idd = iddServerProp_Server;
  283. }
  284. }
  285. if (uidsError != 0)
  286. {
  287. AcctMessageBox(hwnd, MAKEINTRESOURCE(idsAccountManager),
  288. MAKEINTRESOURCE(uidsError), 0, MB_ICONEXCLAMATION | MB_OK);
  289. SendMessage(GetParent(hwnd), PSM_SETCURSELID, 0, (LPARAM)idd);
  290. hwndPage = PropSheet_GetCurrentPageHwnd(GetParent(hwnd));
  291. psdi->dwDirty = (psdi->dwDirty | dwPage);
  292. PropSheet_Changed(GetParent(hwnd), hwndPage);
  293. hwndT = GetDlgItem(hwndPage, idCtrl);
  294. SendMessage(hwndT, EM_SETSEL, 0, -1);
  295. SetFocus(hwndT);
  296. *pdw = (DWORD)-1;
  297. break;
  298. }
  299. pAcct->SaveChanges();
  300. }
  301. }
  302. break;
  303. case SM_INITIALIZED:
  304. psdi->dwInit = (psdi->dwInit | (DWORD) lParam);
  305. break;
  306. default:
  307. fRet = FALSE;
  308. break;
  309. }
  310. return(fRet);
  311. }
  312. BOOL InvalidAcctProp(HWND hwndPage, HWND hwndEdit, int idsError, UINT idPage)
  313. {
  314. HWND hwndCurr, hwndParent;
  315. Assert(hwndPage != NULL);
  316. Assert(idPage != 0);
  317. hwndParent = GetParent(hwndPage);
  318. if (idsError != 0)
  319. AcctMessageBox(hwndPage, MAKEINTRESOURCE(idsAccountManager), MAKEINTRESOURCE(idsError), 0, MB_ICONEXCLAMATION | MB_OK);
  320. hwndCurr = PropSheet_GetCurrentPageHwnd(hwndParent);
  321. if (hwndCurr != hwndPage)
  322. SendMessage(hwndParent, PSM_SETCURSELID, 0, (LPARAM)idPage);
  323. if (hwndEdit != NULL)
  324. {
  325. SendMessage(hwndEdit, EM_SETSEL, 0, -1);
  326. SetFocus(hwndEdit);
  327. }
  328. SetWindowLongPtr(hwndPage, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  329. return(TRUE);
  330. }
  331. void InitAcctPropEdit(HWND hwnd, IImnAccount *pAcct, DWORD dwProp, UINT cchMax)
  332. {
  333. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  334. Assert(pAcct != NULL);
  335. SetIntlFont(hwnd);
  336. if (SUCCEEDED(pAcct->GetPropSz(dwProp, sz, ARRAYSIZE(sz))))
  337. SetWindowText(hwnd, sz);
  338. SendMessage(hwnd, EM_LIMITTEXT, cchMax, 0L);
  339. }
  340. // -----------------------------------------------------------------------------
  341. // CAccount::ShowProperties
  342. // -----------------------------------------------------------------------------
  343. STDMETHODIMP CAccount::ShowProperties(HWND hwndParent, DWORD dwFlags)
  344. {
  345. HRESULT hr;
  346. int i, iReturn;
  347. PROPSHEETPAGE *ppsp, psp[SERVERPROP_PAGEMAX];
  348. PROPSHEETHEADER psh;
  349. SERVERPROP_PARAMS *pProp;
  350. SERVERPROP_PAGE *pPage;
  351. TCHAR szFmt[256], sz[512];
  352. DWORD dw = 0;
  353. BOOL fIMAP;
  354. BOOL fHttp;
  355. INITCOMMONCONTROLSEX icex = { sizeof(icex), ICC_FLAGS };
  356. Assert(m_AcctType < ACCT_LAST);
  357. // Find out if we're an IMAP server
  358. GetServerTypes(&dw);
  359. fIMAP = !!(dw & SRV_IMAP);
  360. fHttp = !!(dw & SRV_HTTPMAIL);
  361. if (0 != (dwFlags & ~ACCTDLG_ALL))
  362. return(E_INVALIDARG);
  363. if (m_fNoModifyAccts)
  364. return(S_FALSE);
  365. InitCommonControlsEx(&icex);
  366. pProp = (SERVERPROP_PARAMS *)&c_rgServerPropParams[m_AcctType];
  367. psh.nPages = 0;
  368. ppsp = psp;
  369. ZeroMemory(psp, sizeof(PROPSHEETPAGE) * 4);
  370. for (pPage = pProp->rgPage, i = 0; i < SERVERPROP_PAGEMAX; pPage++, i++)
  371. {
  372. if (pPage->pfnDlg == NULL)
  373. break;
  374. if (pPage->uDlgId == iddMailSvrProp_Security &&
  375. !!(dwFlags & ACCTDLG_NO_SECURITY))
  376. continue;
  377. if (pPage->uDlgId == iddMailSvrProp_IMAP && FALSE == fIMAP)
  378. continue;
  379. if (pPage->uDlgId == iddMailSvrProp_Advanced && fHttp)
  380. continue;
  381. if (pPage->uDlgId == iddMailSvrProp_Servers && fHttp)
  382. continue;
  383. if (pPage->uDlgId == iddMailSvrProp_HttpServer && !fHttp)
  384. continue;
  385. ppsp->dwSize = sizeof(PROPSHEETPAGE);
  386. ppsp->dwFlags = PSP_DEFAULT;
  387. ppsp->hInstance = g_hInstRes;
  388. if ((pPage->uDlgId == iddServerProp_Connect) &&
  389. (!!(dwFlags & ACCTDLG_BACKUP_CONNECT)))
  390. {
  391. ppsp->pszTemplate = MAKEINTRESOURCE(iddServerProp_Connect2);
  392. }
  393. else
  394. {
  395. ppsp->pszTemplate = MAKEINTRESOURCE(pPage->uDlgId);
  396. }
  397. ppsp->pfnDlgProc = pPage->pfnDlg;
  398. //swap out the dialog id and the function proc if
  399. if (((pPage->uDlgId == iddServerProp_Connect) ||
  400. (pPage->uDlgId == iddServerProp_Connect2)) &&
  401. (!!(dwFlags & ACCTDLG_INTERNETCONNECTION)))
  402. {
  403. ppsp->pszTemplate = MAKEINTRESOURCE(iddServerProp_ConnectOE);
  404. ppsp->pfnDlgProc = OEConnProp_DlgProc;
  405. }
  406. ppsp->lParam = (LPARAM)this;
  407. ppsp++;
  408. psh.nPages++;
  409. }
  410. psh.dwSize = sizeof(PROPSHEETHEADER);
  411. psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE;
  412. psh.hwndParent = hwndParent;
  413. psh.hInstance = g_hInstRes;
  414. psh.pszIcon = MAKEINTRESOURCE(pProp->uIcon);
  415. if (*m_szName != 0)
  416. {
  417. LoadString(g_hInstRes, idsAcctPropsFmt, szFmt, ARRAYSIZE(szFmt));
  418. wnsprintf(sz, ARRAYSIZE(sz), szFmt, m_szName);
  419. psh.pszCaption = sz;
  420. }
  421. else
  422. {
  423. psh.pszCaption = (LPTSTR)IntToPtr(pProp->idsCaption);
  424. }
  425. psh.nStartPage = 0;
  426. psh.ppsp = psp;
  427. // bug 21535
  428. psh.dwFlags |= PSH_USECALLBACK;
  429. psh.pfnCallback = PropSheetProc;
  430. m_dwDlgFlags = dwFlags;
  431. iReturn = (int) PropertySheet(&psh);
  432. if (iReturn < 0)
  433. hr = E_FAIL;
  434. else if (iReturn == 0)
  435. hr = S_FALSE;
  436. else
  437. hr = S_OK;
  438. return(hr);
  439. }
  440. //
  441. // FUNCTION: ServerProp_Create()
  442. //
  443. // PURPOSE: Invokes the news server property sheet.
  444. //
  445. // PARAMETERS:
  446. // <in> hwndParent - Handle that will be the parent of this dialog.
  447. // <in> stType - Type of server. Must be in the SERVER_TYPE enum.
  448. // <in> pszName - Friendly name for the server.
  449. // <in> fNew - TRUE to add a new server.
  450. //
  451. // RETURN VALUE:
  452. // TRUE if successful, or FALSE otherwise.
  453. //
  454. BOOL ServerProp_Create(HWND hwndParent, DWORD dwFlags, LPTSTR pszName, IImnAccount **ppAccount)
  455. {
  456. TCHAR szServer[CCHMAX_SERVER_NAME];
  457. IImnAccount *pAcct;
  458. BOOL fReturn = FALSE;
  459. Assert(IsWindow(hwndParent));
  460. Assert(pszName != NULL);
  461. // Get the server object from the account manager
  462. if (FAILED(g_pAcctMan->FindAccount(AP_ACCOUNT_NAME, pszName, &pAcct)))
  463. return (FALSE);
  464. Assert(pAcct != NULL);
  465. if (S_OK == pAcct->ShowProperties(hwndParent, dwFlags))
  466. {
  467. fReturn = TRUE;
  468. if (ppAccount)
  469. {
  470. *ppAccount = pAcct;
  471. (*ppAccount)->AddRef();
  472. }
  473. }
  474. SafeRelease(pAcct);
  475. return (fReturn);
  476. }
  477. void UpdateAcctTitle(HWND hwnd, int idCtrl, ACCTTYPE AcctType)
  478. {
  479. TCHAR sz[512], szAcct[CCHMAX_ACCOUNT_NAME], szFmt[256];
  480. int id, cch;
  481. cch = GetDlgItemText(hwnd, idCtrl, szAcct, ARRAYSIZE(szAcct));
  482. if (cch == 0)
  483. {
  484. LoadString(g_hInstRes, c_rgServerPropParams[AcctType].idsCaption, sz, ARRAYSIZE(sz));
  485. }
  486. else
  487. {
  488. LoadString(g_hInstRes, idsAcctPropsFmt, szFmt, ARRAYSIZE(szFmt));
  489. wnsprintf(sz, ARRAYSIZE(sz), szFmt, szAcct);
  490. }
  491. PropSheet_SetTitle(GetParent(hwnd), 0, sz);
  492. }
  493. const static HELPMAP g_rgCtxMapNewsGen[] = {
  494. {IDC_SERVERNAME_EDIT, IDH_MAIL_ACCOUNT},
  495. {IDE_DISPLAY_NAME, IDH_NEWS_SERV_NAME},
  496. {IDE_ORG_NAME, IDH_NEWS_SERV_ORG},
  497. {IDE_EMAIL_ADDRESS, IDH_NEWS_SERV_EMAIL_ADD},
  498. {IDE_REPLYTO_EMAIL_ADDRESS, IDH_MAIL_SERV_ADV_REPLY_TO},
  499. {IDC_NEWSPOLL_CHECK, IDH_INCLUDE_NEWS_ACCOUNT},
  500. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  501. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  502. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  503. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  504. {IDC_STATIC4, IDH_INETCOMM_GROUPBOX},
  505. {IDC_STATIC5, IDH_INETCOMM_GROUPBOX},
  506. {0, 0}};
  507. INT_PTR CALLBACK ServerProp_GeneralDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,
  508. LPARAM lParam)
  509. {
  510. BOOL fRet;
  511. DWORD dw;
  512. int idsError;
  513. HWND hwndT;
  514. NMHDR *pnmhdr;
  515. SVRDLGINFO *psdi;
  516. CAccount *pAcct;
  517. TCHAR szBuffer[CCHMAX_ACCOUNT_NAME];
  518. pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  519. psdi = (SVRDLGINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  520. switch (uMsg)
  521. {
  522. case WM_INITDIALOG:
  523. if (!MemAlloc((void **)&psdi, sizeof(SVRDLGINFO)))
  524. return(-1);
  525. ZeroMemory(psdi, sizeof(SVRDLGINFO));
  526. psdi->sfType = SERVER_NEWS;
  527. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)psdi);
  528. // Get the ServerParams and store them in our extra bytes
  529. pAcct = (CAccount*) ((PROPSHEETPAGE*) lParam)->lParam;
  530. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  531. InitUserInformation(hwnd, pAcct, TRUE);
  532. InitAcctPropEdit(GetDlgItem(hwnd, IDC_SERVERNAME_EDIT), pAcct, AP_ACCOUNT_NAME, CCHMAX_ACCOUNT_NAME - 1);
  533. // Poll this account...
  534. if (!!(pAcct->m_dwDlgFlags & ACCTDLG_NO_NEWSPOLL))
  535. ShowWindow(GetDlgItem(hwnd, IDC_NEWSPOLL_CHECK), SW_HIDE);
  536. if (SUCCEEDED(pAcct->GetPropDw(AP_NNTP_POLL, &dw)))
  537. CheckDlgButton(hwnd, IDC_NEWSPOLL_CHECK, dw ? BST_CHECKED : BST_UNCHECKED);
  538. else
  539. CheckDlgButton(hwnd, IDC_NEWSPOLL_CHECK, BST_UNCHECKED);
  540. psdi->dwInit = (psdi->dwInit | PAGE_GEN);
  541. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  542. return(TRUE);
  543. case WM_DESTROY:
  544. psdi = (SVRDLGINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  545. if (psdi != NULL)
  546. MemFree(psdi);
  547. break;
  548. case WM_HELP:
  549. case WM_CONTEXTMENU:
  550. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapNewsGen));
  551. case WM_COMMAND:
  552. if (LOWORD(wParam) == IDC_NEWSPOLL_CHECK)
  553. {
  554. MarkPageDirty(hwnd, PAGE_GEN);
  555. }
  556. else if (HIWORD(wParam) == EN_CHANGE)
  557. {
  558. if (LOWORD(wParam) == IDC_SERVERNAME_EDIT)
  559. UpdateAcctTitle(hwnd, IDC_SERVERNAME_EDIT, ACCT_NEWS);
  560. MarkPageDirty(hwnd, PAGE_GEN);
  561. }
  562. return (TRUE);
  563. case PSM_QUERYSIBLINGS:
  564. return(HandleQuerySiblings(hwnd, psdi, pAcct, wParam, lParam));
  565. case WM_NOTIFY:
  566. pnmhdr = (NMHDR *)lParam;
  567. switch (pnmhdr->code)
  568. {
  569. case PSN_APPLY:
  570. // BEGIN validation
  571. hwndT = GetDlgItem(hwnd, IDC_SERVERNAME_EDIT);
  572. if (!ValidateAccountName(hwnd, hwndT, pAcct, &idsError))
  573. return(InvalidAcctProp(hwnd, hwndT, idsError, iddServerProp_General));
  574. fRet = ValidateUserInformation(hwnd, pAcct, TRUE, &hwndT, &idsError, pnmhdr->code == PSN_APPLY);
  575. if (!fRet)
  576. return(InvalidAcctProp(hwnd, hwndT, idsError, iddServerProp_General));
  577. // END validation
  578. hwndT = GetDlgItem(hwnd, IDC_SERVERNAME_EDIT);
  579. GetAccountName(hwndT, pAcct);
  580. GetUserInformation(hwnd, pAcct, TRUE);
  581. // News Polling
  582. pAcct->SetPropDw(AP_NNTP_POLL, (DWORD) IsDlgButtonChecked(hwnd, IDC_NEWSPOLL_CHECK));
  583. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  584. dw = PAGE_GEN;
  585. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  586. if (dw == -1)
  587. {
  588. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  589. return(TRUE);
  590. }
  591. break;
  592. }
  593. return(TRUE);
  594. }
  595. return (FALSE);
  596. }
  597. BOOL ValidateServerName(HWND hwnd, HWND hwndEdit, IImnAccount *pAcct, DWORD dwPropSvr, int *pidsError, BOOL fApply)
  598. {
  599. HRESULT hr;
  600. int idsSvr, idsPrompt;
  601. ULONG cbSize;
  602. TCHAR sz[CCHMAX_SERVER_NAME];
  603. DWORD dw;
  604. Assert(hwndEdit != NULL);
  605. Assert(pAcct != NULL);
  606. Assert(pidsError != NULL);
  607. *pidsError = 0;
  608. switch(dwPropSvr)
  609. {
  610. case AP_LDAP_SERVER:
  611. idsSvr = idsEnterLdapServer;
  612. idsPrompt = idsInvalidLdapServer;
  613. break;
  614. case AP_IMAP_SERVER:
  615. idsSvr = idsEnterIMAPServer;
  616. idsPrompt = idsInvalidIMAPServer;
  617. break;
  618. case AP_NNTP_SERVER:
  619. idsSvr = idsEnterNntpServer;
  620. idsPrompt = idsInvalidNntpServer;
  621. break;
  622. case AP_POP3_SERVER:
  623. idsSvr = idsEnterPop3Server;
  624. idsPrompt = idsInvalidPop3Server;
  625. break;
  626. case AP_SMTP_SERVER:
  627. idsSvr = idsEnterSmtpServer;
  628. idsPrompt = idsInvalidSmtpServer;
  629. break;
  630. case AP_HTTPMAIL_SERVER:
  631. idsSvr = idsEnterHTTPMailServer;
  632. idsPrompt = idsInvalidHTTPMailServer;
  633. break;
  634. default:
  635. Assert(FALSE);
  636. break;
  637. }
  638. cbSize = GetWindowText(hwndEdit, sz, ARRAYSIZE(sz));
  639. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  640. if (cbSize == 0)
  641. {
  642. // it is legal to have no smtp server with httpmail
  643. if (dwPropSvr != AP_SMTP_SERVER || FAILED(pAcct->GetServerTypes(&dw)) || !(dw & SRV_HTTPMAIL))
  644. {
  645. *pidsError = idsSvr;
  646. return(FALSE);
  647. }
  648. }
  649. // if the server hasn't changed, we don't need to validate it
  650. if (0 == SendMessage(hwndEdit, EM_GETMODIFY, 0, 0))
  651. return(TRUE);
  652. hr = pAcct->ValidateProperty(dwPropSvr, (LPBYTE)sz, 0);
  653. if (FAILED(hr))
  654. {
  655. *pidsError = idsSvr;
  656. return(FALSE);
  657. }
  658. else if (hr == S_NonStandardValue && fApply)
  659. {
  660. if (IDNO == AcctMessageBox(hwnd, MAKEINTRESOURCE(idsAccountManager), MAKEINTRESOURCE(idsPrompt),
  661. NULL, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2))
  662. return(FALSE);
  663. }
  664. return(TRUE);
  665. }
  666. void GetServerName(HWND hwndEdit, IImnAccount *pAcct, DWORD dwPropSvr)
  667. {
  668. ULONG cbSize;
  669. TCHAR sz[CCHMAX_SERVER_NAME];
  670. Assert(hwndEdit != NULL);
  671. Assert(pAcct != NULL);
  672. if (0 != SendMessage(hwndEdit, EM_GETMODIFY, 0, 0))
  673. {
  674. cbSize = GetWindowText(hwndEdit, sz, ARRAYSIZE(sz));
  675. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  676. if (cbSize == 0)
  677. pAcct->SetProp(dwPropSvr, NULL, 0);
  678. else
  679. pAcct->SetPropSz(dwPropSvr, sz);
  680. if (dwPropSvr == AP_POP3_SERVER)
  681. pAcct->SetProp(AP_IMAP_SERVER, NULL, 0);
  682. else if (dwPropSvr == AP_IMAP_SERVER)
  683. {
  684. DWORD dw;
  685. pAcct->SetProp(AP_POP3_SERVER, NULL, 0);
  686. if (FAILED(pAcct->GetPropDw(AP_IMAP_DIRTY, &dw)))
  687. dw = 0;
  688. dw |= IMAP_FLDRLIST_DIRTY;
  689. pAcct->SetPropDw(AP_IMAP_DIRTY, dw);
  690. }
  691. SendMessage(hwndEdit, EM_SETMODIFY, 0, 0);
  692. }
  693. }
  694. BOOL ValidateLogonSettings(HWND hwnd, DWORD dwDlgFlags,
  695. HWND *phwndError, int *pidsError)
  696. {
  697. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  698. HWND hwndT;
  699. ULONG cbSize;
  700. Assert(hwnd != NULL);
  701. Assert(phwndError != NULL);
  702. Assert(pidsError != NULL);
  703. BOOL fOE = ISFLAGSET(dwDlgFlags, ACCTDLG_OE);
  704. BOOL fSPA = IsDlgButtonChecked(hwnd, IDC_LOGONSSPI_CHECK);
  705. *phwndError = NULL;
  706. *pidsError = 0;
  707. hwndT = GetDlgItem(hwnd, IDC_ACCTNAME_EDIT);
  708. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  709. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  710. if (fOE && cbSize == 0)
  711. {
  712. *phwndError = hwndT;
  713. *pidsError = idsEnterAcctName;
  714. return (FALSE);
  715. }
  716. return (TRUE);
  717. }
  718. BOOL fWarnDomainName(HWND hwnd, DWORD dwDlgFlags, LPTSTR pszPreviousLoginName)
  719. {
  720. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  721. HWND hwndT;
  722. ULONG cbSize;
  723. BOOL fret = TRUE;
  724. BOOL fOE = TRUE;
  725. fOE = ISFLAGSET(dwDlgFlags, ACCTDLG_OE);
  726. hwndT = GetDlgItem(hwnd, IDC_ACCTNAME_EDIT);
  727. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  728. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  729. if (fOE &&
  730. (lstrcmp(pszPreviousLoginName, sz) != 0))
  731. {
  732. if (ValidEmailAddressParts(sz, NULL, 0, NULL, 0) != S_OK)
  733. {
  734. if (IDNO == AcctMessageBox(hwnd, MAKEINTRESOURCE(idsAccountManager),
  735. MAKEINTRESOURCE(idsAccountNameErr),
  736. NULL, MB_YESNO))
  737. {
  738. fret = FALSE;
  739. goto exit;
  740. }
  741. }
  742. }
  743. exit:
  744. return fret;
  745. }
  746. void GetLogonSettings(HWND hwnd, IImnAccount *pAcct, BOOL fLogon, DWORD srv)
  747. {
  748. HWND hwndT;
  749. ULONG cbSize;
  750. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  751. DWORD dw, fOldSicily = FALSE;
  752. LPMAILSERVERPROPSINFO pServerProps = NULL;
  753. BOOL fIMAPDirty = FALSE;
  754. Assert(pAcct != NULL);
  755. switch (srv)
  756. {
  757. case SRV_POP3:
  758. GetServerProps(SERVER_MAIL, &pServerProps);
  759. break;
  760. case SRV_IMAP:
  761. GetServerProps(SERVER_IMAP, &pServerProps);
  762. break;
  763. case SRV_HTTPMAIL:
  764. GetServerProps(SERVER_HTTPMAIL, &pServerProps);
  765. break;
  766. case SRV_NNTP:
  767. GetServerProps(SERVER_NEWS, &pServerProps);
  768. break;
  769. case SRV_LDAP:
  770. GetServerProps(SERVER_LDAP, &pServerProps);
  771. break;
  772. default:
  773. break;
  774. }
  775. Assert(NULL != pServerProps);
  776. // Record old SPA setting so we can tell if user went between cleartext/SPA (IMAP dirty)
  777. pAcct->GetPropDw(pServerProps->useSicily, &fOldSicily);
  778. pAcct->SetProp(pServerProps->userName, NULL, 0);
  779. pAcct->SetProp(pServerProps->password, NULL, 0);
  780. pAcct->SetProp(pServerProps->useSicily, NULL, 0);
  781. if (0 != pServerProps->promptPassword)
  782. pAcct->SetProp(pServerProps->promptPassword, NULL, 0);
  783. if (fLogon)
  784. {
  785. // Get User Account Name
  786. hwndT = GetDlgItem(hwnd, IDC_ACCTNAME_EDIT);
  787. // For IMAP, set dirty flag if username changed or went from SPA to cleartext
  788. if (fOldSicily || (SRV_IMAP == srv && SendMessage(hwndT, EM_GETMODIFY, 0, 0)))
  789. fIMAPDirty = TRUE;
  790. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  791. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  792. pAcct->SetPropSz(pServerProps->userName, sz);
  793. // Get Password if user didn't tell us to always prompt for it
  794. if (0 != pServerProps->promptPassword)
  795. {
  796. dw = !IsDlgButtonChecked(hwnd, IDC_REMEMBER_PASSWORD);
  797. pAcct->SetPropDw(pServerProps->promptPassword, dw);
  798. }
  799. else
  800. // There is no LDAP setting to always prompt for password
  801. dw = FALSE;
  802. if (FALSE == dw)
  803. {
  804. cbSize = GetDlgItemText(hwnd, IDC_ACCTPASS_EDIT, sz, ARRAYSIZE(sz));
  805. if (cbSize > 0)
  806. pAcct->SetPropSz(pServerProps->password, sz);
  807. }
  808. if (!IsDlgButtonChecked(hwnd, IDC_LOGONSSPI_CHECK))
  809. {
  810. dw = LDAP_AUTH_PASSWORD;
  811. }
  812. else
  813. {
  814. if (srv != SRV_LDAP)
  815. pAcct->SetPropDw(pServerProps->useSicily, TRUE);
  816. // For IMAP, set dirty flag if we went from cleartext to SPA
  817. if (FALSE == fOldSicily)
  818. fIMAPDirty = TRUE;
  819. dw = LDAP_AUTH_MEMBER_SYSTEM;
  820. }
  821. }
  822. else
  823. {
  824. dw = LDAP_AUTH_ANONYMOUS;
  825. }
  826. if (srv == SRV_LDAP)
  827. pAcct->SetPropDw(pServerProps->useSicily, dw);
  828. if (fIMAPDirty)
  829. {
  830. if (FAILED(pAcct->GetPropDw(AP_IMAP_DIRTY, &dw)))
  831. dw = 0;
  832. dw |= IMAP_FLDRLIST_DIRTY;
  833. pAcct->SetPropDw(AP_IMAP_DIRTY, dw);
  834. }
  835. }
  836. void Server_EnableLogonWindows(HWND hwnd, BOOL fEnable)
  837. {
  838. HWND hwndT;
  839. BOOL fPromptPassword;
  840. hwndT = GetDlgItem(hwnd, IDC_REMEMBER_PASSWORD);
  841. if (hwndT != NULL)
  842. {
  843. fPromptPassword = (BST_CHECKED != SendMessage(hwndT, BM_GETCHECK, 0, 0));
  844. EnableWindow(hwndT, fEnable);
  845. }
  846. else
  847. {
  848. fPromptPassword = FALSE;
  849. }
  850. EnableWindow(GetDlgItem(hwnd, IDC_LOGONSSPI_CHECK), fEnable);
  851. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_EDIT), fEnable);
  852. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_STATIC), fEnable);
  853. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), fEnable && !fPromptPassword);
  854. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_STATIC), fEnable);
  855. }
  856. const static HELPMAP g_rgCtxMapNewsSvr[] = {
  857. {IDC_NEWSNAME_EDIT, IDH_NEWS_SERV_INCOMING},
  858. {IDC_LOGON_CHECK, IDH_INETCOMM_SERVER_REQ_LOGON},
  859. {IDC_ACCTNAME_EDIT, IDH_MAIL_SERV_POP3_ACCT},
  860. {IDC_ACCTNAME_STATIC, IDH_MAIL_SERV_POP3_ACCT},
  861. {IDC_ACCTPASS_EDIT, IDH_MAIL_SERV_PWORD},
  862. {IDC_ACCTPASS_STATIC, IDH_MAIL_SERV_PWORD},
  863. {IDC_LOGONSSPI_CHECK, IDH_MAIL_LOGON_USING_SICILY},
  864. {IDC_REMEMBER_PASSWORD, 503},
  865. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  866. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  867. {0, 0}};
  868. INT_PTR CALLBACK ServerProp_ServerDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  869. {
  870. HRESULT hr;
  871. int idsError;
  872. WORD wNotifyCode, wID;
  873. BOOL fRet, fLogon, fValid;
  874. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  875. CAccount *pAcct;
  876. DWORD flag;
  877. HWND hwndT;
  878. ULONG cbSize;
  879. NMHDR *pnmhdr;
  880. fRet = TRUE;
  881. pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  882. switch (uMsg)
  883. {
  884. case WM_INITDIALOG:
  885. // Get the ServerParams and store them in our extra bytes
  886. pAcct = (CAccount *)((PROPSHEETPAGE *) lParam)->lParam;
  887. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM)pAcct);
  888. InitAcctPropEdit(GetDlgItem(hwnd, IDC_NEWSNAME_EDIT), pAcct, AP_NNTP_SERVER, CCHMAX_SERVER_NAME - 1);
  889. fLogon = FALSE;
  890. if (SUCCEEDED(pAcct->GetPropDw(AP_NNTP_USE_SICILY, (LPDWORD)&flag)) && flag)
  891. {
  892. CheckDlgButton(hwnd, IDC_LOGONSSPI_CHECK, BST_CHECKED);
  893. fLogon = TRUE;
  894. }
  895. if (SUCCEEDED(pAcct->GetPropSz(AP_NNTP_USERNAME, sz, ARRAYSIZE(sz))) && *sz != 0)
  896. {
  897. SetDlgItemText(hwnd, IDC_ACCTNAME_EDIT, sz);
  898. if (SUCCEEDED(pAcct->GetPropSz(AP_NNTP_PASSWORD, sz, ARRAYSIZE(sz))))
  899. SetDlgItemText(hwnd, IDC_ACCTPASS_EDIT, sz);
  900. fLogon = TRUE;
  901. }
  902. if (FAILED(pAcct->GetPropDw(AP_NNTP_PROMPT_PASSWORD, &flag)))
  903. flag = FALSE;
  904. CheckDlgButton(hwnd, IDC_REMEMBER_PASSWORD, flag ? BST_UNCHECKED : BST_CHECKED);
  905. hwndT = GetDlgItem(hwnd, IDC_ACCTNAME_EDIT);
  906. SetIntlFont(hwndT);
  907. SendMessage(hwndT, EM_LIMITTEXT, CCHMAX_USERNAME - 1, 0L);
  908. SendDlgItemMessage(hwnd, IDC_ACCTPASS_EDIT, EM_LIMITTEXT, CCHMAX_PASSWORD - 1, 0L);
  909. CheckDlgButton(hwnd, IDC_LOGON_CHECK, fLogon);
  910. Server_EnableLogonWindows(hwnd, fLogon);
  911. if (SUCCEEDED(pAcct->GetPropDw(AP_SERVER_READ_ONLY, &flag)) && flag)
  912. EnableWindow(GetDlgItem(hwnd, IDC_NEWSNAME_EDIT), FALSE);
  913. PropSheet_QuerySiblings(GetParent(hwnd), SM_INITIALIZED, PAGE_SERVER);
  914. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  915. break;
  916. case WM_HELP:
  917. case WM_CONTEXTMENU:
  918. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapNewsSvr));
  919. case WM_COMMAND:
  920. wNotifyCode = HIWORD(wParam);
  921. wID = LOWORD(wParam);
  922. switch (wID)
  923. {
  924. case IDC_LOGON_CHECK:
  925. case IDC_LOGONSSPI_CHECK:
  926. Server_EnableLogonWindows(hwnd, IsDlgButtonChecked(hwnd, IDC_LOGON_CHECK));
  927. MarkPageDirty(hwnd, PAGE_SERVER);
  928. break;
  929. case IDC_REMEMBER_PASSWORD:
  930. flag = IsDlgButtonChecked(hwnd, IDC_REMEMBER_PASSWORD);
  931. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), flag);
  932. MarkPageDirty(hwnd, PAGE_SERVER);
  933. break;
  934. default:
  935. if (wNotifyCode == EN_CHANGE)
  936. MarkPageDirty(hwnd, PAGE_SERVER);
  937. break;
  938. }
  939. break;
  940. case WM_NOTIFY:
  941. pnmhdr = (NMHDR *)lParam;
  942. switch (pnmhdr->code)
  943. {
  944. case PSN_APPLY:
  945. // BEGIN validation
  946. hwndT = GetDlgItem(hwnd, IDC_NEWSNAME_EDIT);
  947. if (!ValidateServerName(hwnd, hwndT, pAcct, AP_NNTP_SERVER, &idsError, pnmhdr->code == PSN_APPLY))
  948. return(InvalidAcctProp(hwnd, hwndT, idsError, iddServerProp_Server));
  949. if (IsDlgButtonChecked(hwnd, IDC_LOGON_CHECK) &&
  950. !ValidateLogonSettings(hwnd, pAcct->m_dwDlgFlags, &hwndT, &idsError))
  951. return(InvalidAcctProp(hwnd, hwndT, idsError, iddServerProp_Server));
  952. // END validation
  953. hwndT = GetDlgItem(hwnd, IDC_NEWSNAME_EDIT);
  954. GetServerName(hwndT, pAcct, AP_NNTP_SERVER);
  955. GetLogonSettings(hwnd, pAcct, IsDlgButtonChecked(hwnd, IDC_LOGON_CHECK), SRV_NNTP);
  956. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  957. flag = PAGE_SERVER;
  958. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&flag);
  959. if (flag == -1)
  960. {
  961. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  962. return(TRUE);
  963. }
  964. break;
  965. }
  966. return(TRUE);
  967. default:
  968. fRet = FALSE;
  969. break;
  970. }
  971. return(fRet);
  972. }
  973. BOOL ValidateAccountName(HWND hwnd, HWND hwndT, IImnAccount *pAcct, int *pidsError)
  974. {
  975. ULONG cbSize;
  976. TCHAR szAccount[CCHMAX_ACCOUNT_NAME], szAcctOld[CCHMAX_ACCOUNT_NAME];
  977. IImnAccount *pAcctT;
  978. Assert(IsWindow(hwndT));
  979. Assert(pAcct != NULL);
  980. Assert(pidsError != NULL);
  981. *pidsError = 0;
  982. cbSize = GetWindowText(hwndT, szAccount, ARRAYSIZE(szAccount));
  983. if (cbSize == 0)
  984. {
  985. *pidsError = idsInvalidAccountName;
  986. return(FALSE);
  987. }
  988. if (0 == SendMessage(hwndT, EM_GETMODIFY, 0, 0))
  989. return(TRUE);
  990. if (FAILED(pAcct->ValidateProperty(AP_ACCOUNT_NAME, (LPBYTE)szAccount, 0)))
  991. {
  992. *pidsError = idsInvalidAccountName;
  993. return(FALSE);
  994. }
  995. *szAcctOld = 0;
  996. pAcct->GetPropSz(AP_ACCOUNT_NAME, szAcctOld, ARRAYSIZE(szAcctOld));
  997. if (*szAcctOld == 0 || 0 != lstrcmpi(szAccount, szAcctOld))
  998. {
  999. // if we're changing the name, then we need to make sure it's unique
  1000. if (SUCCEEDED(g_pAcctMan->FindAccount(AP_ACCOUNT_NAME, szAccount, &pAcctT)))
  1001. {
  1002. pAcctT->Release();
  1003. *pidsError = idsNeedUniqueAccountName;
  1004. return(FALSE);
  1005. }
  1006. }
  1007. return(TRUE);
  1008. }
  1009. void GetAccountName(HWND hwndEdit, IImnAccount *pAcct)
  1010. {
  1011. UINT cbSize;
  1012. TCHAR szAccount[CCHMAX_ACCOUNT_NAME];
  1013. Assert(IsWindow(hwndEdit));
  1014. if (0 != SendMessage(hwndEdit, EM_GETMODIFY, 0, 0))
  1015. {
  1016. cbSize = GetWindowText(hwndEdit, szAccount, ARRAYSIZE(szAccount));
  1017. Assert(cbSize > 0);
  1018. pAcct->SetPropSz(AP_ACCOUNT_NAME, szAccount);
  1019. SendMessage(hwndEdit, EM_SETMODIFY, 0, 0);
  1020. }
  1021. }
  1022. // TODO: move these to somewhere appropriate
  1023. #define TIMEOUT_SEC_MIN 30
  1024. #define TIMEOUT_SEC_MAX 5 * 60
  1025. #define TIMEOUT_DSEC 30
  1026. #define CTIMEOUT (((TIMEOUT_SEC_MAX - TIMEOUT_SEC_MIN) / TIMEOUT_DSEC) + 1)
  1027. void InitTimeoutSlider(HWND hwndSlider, HWND hwndText, DWORD dwTimeout)
  1028. {
  1029. DWORD dw;
  1030. if (dwTimeout < TIMEOUT_SEC_MIN)
  1031. dwTimeout = TIMEOUT_SEC_MIN;
  1032. else if (dwTimeout > TIMEOUT_SEC_MAX)
  1033. dwTimeout = TIMEOUT_SEC_MAX;
  1034. dw = (dwTimeout / TIMEOUT_DSEC) - 1;
  1035. SendMessage(hwndSlider, TBM_SETRANGE, 0, (LPARAM)MAKELONG(0, CTIMEOUT - 1));
  1036. SendMessage(hwndSlider, TBM_SETPOS, TRUE, (LPARAM)dw);
  1037. SetTimeoutString(hwndText, dw);
  1038. }
  1039. void SetTimeoutString(HWND hwnd, UINT pos)
  1040. {
  1041. UINT cch, csec, cmin;
  1042. TCHAR szOut[128], sz[128];
  1043. csec = TIMEOUT_SEC_MIN + (pos * TIMEOUT_DSEC);
  1044. Assert(csec >= TIMEOUT_SEC_MIN && csec <= TIMEOUT_SEC_MAX);
  1045. cmin = csec / 60;
  1046. csec = csec % 60;
  1047. if (cmin > 1)
  1048. {
  1049. LoadString(g_hInstRes, idsXMinutes, sz, ARRAYSIZE(sz));
  1050. wnsprintf(szOut, ARRAYSIZE(szOut), sz, cmin);
  1051. cch = lstrlen(szOut);
  1052. }
  1053. else if (cmin == 1)
  1054. {
  1055. cch = LoadString(g_hInstRes, ids1Minute, szOut, ARRAYSIZE(szOut));
  1056. }
  1057. else
  1058. {
  1059. cch = 0;
  1060. }
  1061. if (csec != 0)
  1062. {
  1063. if (cmin > 0)
  1064. {
  1065. szOut[cch] = ' ';
  1066. cch++;
  1067. }
  1068. LoadString(g_hInstRes, idsXSeconds, sz, ARRAYSIZE(sz));
  1069. wnsprintf(&szOut[cch], (ARRAYSIZE(szOut) - cch), sz, csec);
  1070. }
  1071. SetWindowText(hwnd, szOut);
  1072. }
  1073. DWORD GetTimeoutFromSlider(HWND hwnd)
  1074. {
  1075. DWORD dw;
  1076. dw = (DWORD) SendMessage(hwnd, TBM_GETPOS, 0, 0);
  1077. dw = TIMEOUT_SEC_MIN + (dw * TIMEOUT_DSEC);
  1078. return(dw);
  1079. }
  1080. const static HELPMAP g_rgCtxMapNewsAdv[] = {
  1081. {IDC_USEDEFAULTS_BUTTON, IDH_NEWS_SERV_ADV_USE_DEFAULTS},
  1082. {IDC_SECURECONNECT_BUTTON, IDH_MAIL_ADV_REQ_SSL},
  1083. {IDC_TIMEOUT_SLIDER, IDH_NEWS_SERV_ADV_TIMEOUT},
  1084. {IDC_TIMEOUT_STATIC, IDH_NEWS_SERV_ADV_TIMEOUT},
  1085. {IDC_USEDESC_CHECK, IDH_NEWS_SERV_ADV_DESC},
  1086. {IDC_SPLIT_CHECK, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  1087. {IDC_SPLIT_EDIT, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  1088. {IDC_SPLIT_SPIN, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  1089. {IDC_SPLIT_STATIC, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  1090. {IDC_NNTPPORT_EDIT, IDH_NEWS_PORT_NUMBER},
  1091. {IDC_FORMAT_CHECK, 691},
  1092. {IDC_HTML_RADIO, 692},
  1093. {IDC_TEXT_RADIO, 692},
  1094. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  1095. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  1096. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  1097. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  1098. {IDC_STATIC4, IDH_INETCOMM_GROUPBOX},
  1099. {IDC_STATIC5, IDH_INETCOMM_GROUPBOX},
  1100. {IDC_STATIC6, IDH_INETCOMM_GROUPBOX},
  1101. {IDC_STATIC7, IDH_INETCOMM_GROUPBOX},
  1102. {0, 0}};
  1103. INT_PTR CALLBACK ServerProp_AdvancedDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,
  1104. LPARAM lParam)
  1105. {
  1106. HWND hwndT;
  1107. NMHDR *pnmhdr;
  1108. DWORD dw, flag, dwPort, dwSplit;
  1109. WORD code;
  1110. BOOL fTrans, fSecure;
  1111. TCHAR szBuffer[CCHMAX_ACCOUNT_NAME];
  1112. CAccount *pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  1113. switch (uMsg)
  1114. {
  1115. case WM_INITDIALOG:
  1116. // Get the ServerParams and store them in our extra bytes
  1117. pAcct = (CAccount *) ((PROPSHEETPAGE*) lParam)->lParam;
  1118. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  1119. // Load the controls with what information we have
  1120. if (SUCCEEDED(pAcct->GetPropDw(AP_NNTP_PORT, &dw)))
  1121. SetDlgItemInt(hwnd, IDC_NNTPPORT_EDIT, dw, FALSE);
  1122. SendDlgItemMessage(hwnd, IDC_NNTPPORT_EDIT, EM_LIMITTEXT, PORT_CCHMAX, 0);
  1123. if (SUCCEEDED(pAcct->GetPropDw(AP_NNTP_SSL, (LPDWORD) &fSecure)) && fSecure)
  1124. {
  1125. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON), dw != DEF_SNNTPPORT);
  1126. CheckDlgButton(hwnd, IDC_SECURECONNECT_BUTTON, TRUE);
  1127. }
  1128. else
  1129. {
  1130. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON), dw != DEF_NNTPPORT);
  1131. }
  1132. dw = 0;
  1133. pAcct->GetPropDw(AP_NNTP_TIMEOUT, &dw);
  1134. InitTimeoutSlider(GetDlgItem(hwnd, IDC_TIMEOUT_SLIDER),
  1135. GetDlgItem(hwnd, IDC_TIMEOUT_STATIC), dw);
  1136. if (SUCCEEDED(pAcct->GetPropDw(AP_NNTP_USE_DESCRIPTIONS, &dw)))
  1137. CheckDlgButton(hwnd, IDC_USEDESC_CHECK, dw);
  1138. if (!!(pAcct->m_dwDlgFlags & ACCTDLG_NO_BREAKMESSAGES))
  1139. {
  1140. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_CHECK), SW_HIDE);
  1141. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_EDIT), SW_HIDE);
  1142. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_SPIN), SW_HIDE);
  1143. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_STATIC), SW_HIDE);
  1144. }
  1145. // Break Message Size
  1146. dw = OPTION_OFF; // default
  1147. if (SUCCEEDED(pAcct->GetPropDw(AP_NNTP_SPLIT_MESSAGES, (LPDWORD)&flag)) && flag)
  1148. pAcct->GetPropDw(AP_NNTP_SPLIT_SIZE, (LPDWORD)&dw);
  1149. InitCheckCounter(dw, hwnd, IDC_SPLIT_CHECK, IDC_SPLIT_EDIT, IDC_SPLIT_SPIN,
  1150. BREAKSIZE_MIN, BREAKSIZE_MAX, DEF_BREAKSIZE);
  1151. pAcct->GetPropDw(AP_NNTP_POST_FORMAT, &flag);
  1152. CheckDlgButton(hwnd, IDC_FORMAT_CHECK, flag != POST_USE_DEFAULT);
  1153. CheckDlgButton(hwnd, flag == POST_USE_HTML ? IDC_HTML_RADIO : IDC_TEXT_RADIO, TRUE);
  1154. if (flag == POST_USE_DEFAULT)
  1155. {
  1156. EnableWindow(GetDlgItem(hwnd, IDC_HTML_RADIO), FALSE);
  1157. EnableWindow(GetDlgItem(hwnd, IDC_TEXT_RADIO), FALSE);
  1158. }
  1159. PropSheet_QuerySiblings(GetParent(hwnd), SM_INITIALIZED, PAGE_ADV);
  1160. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  1161. return (TRUE);
  1162. case WM_HELP:
  1163. case WM_CONTEXTMENU:
  1164. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapNewsAdv));
  1165. case WM_HSCROLL:
  1166. // Update the text beside the slider
  1167. SetTimeoutString(GetDlgItem(hwnd, IDC_TIMEOUT_STATIC),
  1168. (UINT) SendMessage((HWND) lParam, TBM_GETPOS, 0, 0));
  1169. MarkPageDirty(hwnd, PAGE_ADV);
  1170. return (TRUE);
  1171. case WM_COMMAND:
  1172. // Any change to the edit controls would cause the "Apply" button
  1173. // to enable.
  1174. fSecure = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_BUTTON);
  1175. code = HIWORD(wParam);
  1176. switch (LOWORD(wParam))
  1177. {
  1178. case IDC_NNTPPORT_EDIT:
  1179. if (code == EN_CHANGE)
  1180. {
  1181. dw = GetDlgItemInt(hwnd, IDC_NNTPPORT_EDIT, &fTrans, FALSE);
  1182. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON),
  1183. !fTrans || (fSecure ? (dw != DEF_SNNTPPORT) : (dw != DEF_NNTPPORT)));
  1184. MarkPageDirty(hwnd, PAGE_ADV);
  1185. }
  1186. break;
  1187. case IDC_USEDESC_CHECK:
  1188. case IDC_TEXT_RADIO:
  1189. case IDC_HTML_RADIO:
  1190. MarkPageDirty(hwnd, PAGE_ADV);
  1191. break;
  1192. case IDC_SPLIT_EDIT:
  1193. if (code == EN_CHANGE)
  1194. MarkPageDirty(hwnd, PAGE_ADV);
  1195. break;
  1196. case IDC_FORMAT_CHECK:
  1197. fTrans = IsDlgButtonChecked(hwnd, IDC_FORMAT_CHECK);
  1198. EnableWindow(GetDlgItem(hwnd, IDC_HTML_RADIO), fTrans);
  1199. EnableWindow(GetDlgItem(hwnd, IDC_TEXT_RADIO), fTrans);
  1200. MarkPageDirty(hwnd, PAGE_ADV);
  1201. break;
  1202. case IDC_SPLIT_CHECK:
  1203. fTrans = IsDlgButtonChecked(hwnd, IDC_SPLIT_CHECK);
  1204. EnableWindow(GetDlgItem(hwnd, IDC_SPLIT_EDIT), fTrans);
  1205. EnableWindow(GetDlgItem(hwnd, IDC_SPLIT_SPIN), fTrans);
  1206. MarkPageDirty(hwnd, PAGE_ADV);
  1207. break;
  1208. case IDC_SECURECONNECT_BUTTON:
  1209. case IDC_USEDEFAULTS_BUTTON:
  1210. // Reset the settings on this page to the default values.
  1211. SetDlgItemInt(hwnd, IDC_NNTPPORT_EDIT, fSecure ? DEF_SNNTPPORT : DEF_NNTPPORT, FALSE);
  1212. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON), FALSE);
  1213. MarkPageDirty(hwnd, PAGE_ADV);
  1214. SetFocus(GetDlgItem(hwnd, IDC_NNTPPORT_EDIT));
  1215. break;
  1216. }
  1217. return (TRUE);
  1218. case WM_NOTIFY:
  1219. pnmhdr = (NMHDR *)lParam;
  1220. switch (pnmhdr->code)
  1221. {
  1222. case PSN_APPLY:
  1223. // BEGIN validation
  1224. dwPort = GetDlgItemInt(hwnd, IDC_NNTPPORT_EDIT, &fTrans, FALSE);
  1225. if (!fTrans || dwPort == 0)
  1226. {
  1227. hwndT = GetDlgItem(hwnd, IDC_NNTPPORT_EDIT);
  1228. return(InvalidAcctProp(hwnd, hwndT, idsErrPortNum, iddServerProp_Advanced));
  1229. }
  1230. dwSplit = 0;
  1231. dw = IsDlgButtonChecked(hwnd, IDC_SPLIT_CHECK);
  1232. if (dw != 0)
  1233. {
  1234. dwSplit = GetDlgItemInt(hwnd, IDC_SPLIT_EDIT, &fTrans, FALSE);
  1235. if (!fTrans || dwSplit < BREAKSIZE_MIN || dwSplit > BREAKSIZE_MAX)
  1236. {
  1237. hwndT = GetDlgItem(hwnd, IDC_SPLIT_EDIT);
  1238. return(InvalidAcctProp(hwnd, hwndT, idsEnterBreakSize, iddServerProp_Advanced));
  1239. }
  1240. }
  1241. // END validation
  1242. pAcct->SetPropDw(AP_NNTP_PORT, dwPort);
  1243. dw = IsDlgButtonChecked(hwnd, IDC_SPLIT_CHECK);
  1244. pAcct->SetPropDw(AP_NNTP_SPLIT_MESSAGES, dw);
  1245. if (dw != 0)
  1246. {
  1247. Assert(dwSplit != 0);
  1248. pAcct->SetPropDw(AP_NNTP_SPLIT_SIZE, dwSplit);
  1249. }
  1250. dw = GetTimeoutFromSlider(GetDlgItem(hwnd, IDC_TIMEOUT_SLIDER));
  1251. pAcct->SetPropDw(AP_NNTP_TIMEOUT, dw);
  1252. dw = IsDlgButtonChecked(hwnd, IDC_USEDESC_CHECK);
  1253. pAcct->SetPropDw(AP_NNTP_USE_DESCRIPTIONS, dw);
  1254. dw = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_BUTTON);
  1255. pAcct->SetPropDw(AP_NNTP_SSL, dw);
  1256. dw = POST_USE_DEFAULT;
  1257. if (IsDlgButtonChecked(hwnd, IDC_FORMAT_CHECK))
  1258. {
  1259. if (IsDlgButtonChecked(hwnd, IDC_HTML_RADIO))
  1260. dw = POST_USE_HTML;
  1261. else
  1262. dw = POST_USE_PLAIN_TEXT;
  1263. }
  1264. pAcct->SetPropDw(AP_NNTP_POST_FORMAT, dw);
  1265. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  1266. dw = PAGE_ADV;
  1267. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  1268. if (dw == -1)
  1269. {
  1270. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  1271. return(TRUE);
  1272. }
  1273. break;
  1274. }
  1275. return (TRUE);
  1276. }
  1277. return (FALSE);
  1278. }
  1279. void InitUserInformation(HWND hwnd, IImnAccount *pAcct, BOOL fNews)
  1280. {
  1281. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  1282. IImnAccount *pAccount;
  1283. DWORD dwProp;
  1284. HWND hwndT;
  1285. Assert(pAcct != NULL);
  1286. pAccount = NULL;
  1287. Assert(g_pAcctMan);
  1288. g_pAcctMan->GetDefaultAccount(fNews ? ACCT_NEWS : ACCT_MAIL, &pAccount);
  1289. // Get Display Name
  1290. hwndT = GetDlgItem(hwnd, IDE_DISPLAY_NAME);
  1291. SetIntlFont(hwndT);
  1292. dwProp = fNews ? AP_NNTP_DISPLAY_NAME : AP_SMTP_DISPLAY_NAME;
  1293. if (SUCCEEDED(pAcct->GetPropSz(dwProp, sz, ARRAYSIZE(sz))) ||
  1294. (pAccount != NULL && SUCCEEDED(pAccount->GetPropSz(dwProp, sz, ARRAYSIZE(sz)))))
  1295. {
  1296. SetWindowText(hwndT, sz);
  1297. }
  1298. SendMessage(hwndT, EM_LIMITTEXT, CCHMAX_DISPLAY_NAME - 1, 0L);
  1299. // Org Name
  1300. InitAcctPropEdit(GetDlgItem(hwnd, IDE_ORG_NAME), pAcct,
  1301. fNews ? AP_NNTP_ORG_NAME : AP_SMTP_ORG_NAME, CCHMAX_ORG_NAME - 1);
  1302. // Sender Email
  1303. hwndT = GetDlgItem(hwnd, IDE_EMAIL_ADDRESS);
  1304. SetIntlFont(hwndT);
  1305. dwProp = fNews ? AP_NNTP_EMAIL_ADDRESS : AP_SMTP_EMAIL_ADDRESS;
  1306. if (SUCCEEDED(pAcct->GetPropSz(dwProp, sz, ARRAYSIZE(sz))) ||
  1307. (pAccount != NULL && SUCCEEDED(pAccount->GetPropSz(dwProp, sz, ARRAYSIZE(sz)))))
  1308. {
  1309. SetWindowText(hwndT, sz);
  1310. }
  1311. SendMessage(hwndT, EM_LIMITTEXT, CCHMAX_EMAIL_ADDRESS - 1, 0L);
  1312. // Sender Reply Address
  1313. InitAcctPropEdit(GetDlgItem(hwnd, IDE_REPLYTO_EMAIL_ADDRESS), pAcct,
  1314. fNews ? AP_NNTP_REPLY_EMAIL_ADDRESS : AP_SMTP_REPLY_EMAIL_ADDRESS, CCHMAX_EMAIL_ADDRESS - 1);
  1315. if (pAccount != NULL)
  1316. pAccount->Release();
  1317. }
  1318. BOOL ValidateUserInformation(HWND hwnd, IImnAccount *pAcct, BOOL fNews, HWND *phwndErr, int *puIdsErr, BOOL fApply)
  1319. {
  1320. HRESULT hr;
  1321. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  1322. DWORD cbSize;
  1323. HWND hwndT;
  1324. *phwndErr = NULL;
  1325. *puIdsErr = 0;
  1326. // Display Name
  1327. hwndT = GetDlgItem(hwnd, IDE_DISPLAY_NAME);
  1328. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  1329. UlStripWhitespace(sz, FALSE, TRUE, &cbSize);
  1330. if (cbSize == 0)
  1331. {
  1332. *phwndErr = hwndT;
  1333. *puIdsErr = idsEnterDisplayName;
  1334. return(FALSE);
  1335. }
  1336. // Email Address
  1337. hwndT = GetDlgItem(hwnd, IDE_EMAIL_ADDRESS);
  1338. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  1339. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  1340. if (cbSize == 0)
  1341. {
  1342. *phwndErr = hwndT;
  1343. *puIdsErr = idsEnterEmailAddress;
  1344. return(FALSE);
  1345. }
  1346. if (0 != SendMessage(hwndT, EM_GETMODIFY, 0, 0))
  1347. {
  1348. hr = pAcct->ValidateProperty(fNews ? AP_NNTP_EMAIL_ADDRESS : AP_SMTP_EMAIL_ADDRESS, (LPBYTE)sz, 0);
  1349. if (hr != S_OK && fApply)
  1350. {
  1351. if (IDNO == AcctMessageBox(hwnd, MAKEINTRESOURCE(idsAccountManager), MAKEINTRESOURCE(idsInvalidEmailAddress), NULL, MB_YESNO|MB_ICONEXCLAMATION |MB_DEFBUTTON2))
  1352. {
  1353. *phwndErr = hwndT;
  1354. return(FALSE);
  1355. }
  1356. }
  1357. }
  1358. // Reply Toaddress
  1359. hwndT = GetDlgItem(hwnd, IDE_REPLYTO_EMAIL_ADDRESS);
  1360. if (0 != SendMessage(hwndT, EM_GETMODIFY, 0, 0))
  1361. {
  1362. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  1363. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  1364. if (cbSize > 0)
  1365. {
  1366. hr = pAcct->ValidateProperty(fNews ? AP_NNTP_REPLY_EMAIL_ADDRESS : AP_SMTP_REPLY_EMAIL_ADDRESS, (LPBYTE)sz, 0);
  1367. if (hr != S_OK && fApply)
  1368. {
  1369. if (IDNO == AcctMessageBox(hwnd, MAKEINTRESOURCE(idsAccountManager), MAKEINTRESOURCE(idsInvalidReplyToAddress), NULL, MB_YESNO|MB_ICONEXCLAMATION |MB_DEFBUTTON2))
  1370. {
  1371. *phwndErr = hwndT;
  1372. return(FALSE);
  1373. }
  1374. }
  1375. }
  1376. }
  1377. return(TRUE);
  1378. }
  1379. void GetUserInformation(HWND hwnd, IImnAccount *pAcct, BOOL fNews)
  1380. {
  1381. DWORD cbSize;
  1382. HWND hwndT;
  1383. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  1384. // Display Name
  1385. hwndT = GetDlgItem(hwnd, IDE_DISPLAY_NAME);
  1386. if (0 != SendMessage(hwndT, EM_GETMODIFY, 0, 0))
  1387. {
  1388. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  1389. UlStripWhitespace(sz, FALSE, TRUE, &cbSize);
  1390. Assert(cbSize > 0);
  1391. Assert(!FIsEmpty(sz));
  1392. pAcct->SetPropSz(fNews ? AP_NNTP_DISPLAY_NAME : AP_SMTP_DISPLAY_NAME, sz);
  1393. SendMessage(hwndT, EM_SETMODIFY, 0, 0);
  1394. }
  1395. // Organization
  1396. hwndT = GetDlgItem(hwnd, IDE_ORG_NAME);
  1397. if (0 != SendMessage(hwndT, EM_GETMODIFY, 0, 0))
  1398. {
  1399. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  1400. UlStripWhitespace(sz, FALSE, TRUE, &cbSize);
  1401. if (cbSize == 0)
  1402. pAcct->SetProp(fNews ? AP_NNTP_ORG_NAME : AP_SMTP_ORG_NAME, NULL, 0);
  1403. else
  1404. pAcct->SetPropSz(fNews ? AP_NNTP_ORG_NAME : AP_SMTP_ORG_NAME, sz);
  1405. SendMessage(hwndT, EM_SETMODIFY, 0, 0);
  1406. }
  1407. // Email Address
  1408. hwndT = GetDlgItem(hwnd, IDE_EMAIL_ADDRESS);
  1409. if (0 != SendMessage(hwndT, EM_GETMODIFY, 0, 0))
  1410. {
  1411. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  1412. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  1413. Assert(cbSize > 0);
  1414. pAcct->SetPropSz(fNews ? AP_NNTP_EMAIL_ADDRESS : AP_SMTP_EMAIL_ADDRESS, sz);
  1415. SendMessage(hwndT, EM_SETMODIFY, 0, 0);
  1416. }
  1417. // Reply Toaddress
  1418. hwndT = GetDlgItem(hwnd, IDE_REPLYTO_EMAIL_ADDRESS);
  1419. if (0 != SendMessage(hwndT, EM_GETMODIFY, 0, 0))
  1420. {
  1421. cbSize = GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  1422. UlStripWhitespace(sz, TRUE, TRUE, &cbSize);
  1423. if (cbSize == 0)
  1424. pAcct->SetProp(fNews ? AP_NNTP_REPLY_EMAIL_ADDRESS : AP_SMTP_REPLY_EMAIL_ADDRESS, NULL, 0);
  1425. else
  1426. pAcct->SetPropSz(fNews ? AP_NNTP_REPLY_EMAIL_ADDRESS : AP_SMTP_REPLY_EMAIL_ADDRESS, sz);
  1427. SendMessage(hwndT, EM_SETMODIFY, 0, 0);
  1428. }
  1429. }
  1430. void EnableCertControls(HWND hwnd)
  1431. {
  1432. EnableWindow(GetDlgItem(hwnd, idcCertButton), TRUE);
  1433. EnableWindow(GetDlgItem(hwnd, idcCertEdit), TRUE);
  1434. EnableWindow(GetDlgItem(hwnd, idcCryptEdit), TRUE);
  1435. EnableWindow(GetDlgItem(hwnd, idcCryptButton), TRUE);
  1436. }
  1437. BOOL ValidateCertificate(HWND hwnd, IImnAccount *pAcct, SECPAGEINFO *psdi, HWND *phwndErr, int *puIdsErr)
  1438. {
  1439. UINT cbSize;
  1440. BOOL fRet = TRUE;
  1441. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  1442. LPSTR szCertEmail = NULL;
  1443. *puIdsErr = 0;
  1444. *phwndErr = NULL;
  1445. cbSize = GetWindowTextLength(GetDlgItem(hwnd, idcCertEdit));
  1446. if (cbSize)
  1447. {
  1448. GetDlgItemText(hwnd, idcCertAddress, sz, ARRAYSIZE(sz));
  1449. Assert(psdi->pCert);
  1450. szCertEmail = SzGetCertificateEmailAddress(psdi->pCert);
  1451. if (!szCertEmail || lstrcmpi(szCertEmail, sz))
  1452. goto ErrExit;
  1453. }
  1454. // More checkings for 2 keys
  1455. if(!(psdi->pCert))
  1456. {
  1457. *puIdsErr = 0;
  1458. return FALSE;
  1459. }
  1460. // Check that signing certificate is really signing certificate
  1461. if(CheckKeyUsage(psdi->pCert, CERT_DIGITAL_SIGNATURE_KEY_USAGE) < 0)
  1462. goto ErrExit;
  1463. // Check email name in encryption certificate
  1464. if(szCertEmail)
  1465. {
  1466. MemFree(szCertEmail);
  1467. szCertEmail = NULL;
  1468. }
  1469. if(psdi->pEncryptCert)
  1470. {
  1471. szCertEmail = SzGetCertificateEmailAddress(psdi->pEncryptCert);
  1472. if (!szCertEmail || lstrcmpi(szCertEmail, sz))
  1473. goto ErrExit;
  1474. // Check that encryption certificate is really encryption certificate
  1475. if(CheckKeyUsage(psdi->pEncryptCert, CERT_KEY_ENCIPHERMENT_KEY_USAGE) < 0)
  1476. {
  1477. if(CheckKeyUsage(psdi->pEncryptCert, CERT_KEY_AGREEMENT_KEY_USAGE) < 1)
  1478. goto ErrExit;
  1479. }
  1480. }
  1481. if(szCertEmail)
  1482. MemFree(szCertEmail);
  1483. return fRet;
  1484. ErrExit:
  1485. // the certificate's email address does not match the
  1486. // current choice for the account
  1487. *puIdsErr = idsBadCertChoice;
  1488. *phwndErr = GetDlgItem(hwnd, idcCertButton);
  1489. if(szCertEmail)
  1490. MemFree(szCertEmail);
  1491. return FALSE;
  1492. }
  1493. void GetCertificate(HWND hwnd, IImnAccount *pAcct, SECPAGEINFO *psdi)
  1494. {
  1495. THUMBBLOB tb = {0,0};
  1496. if(psdi->pCert)
  1497. {
  1498. tb.pBlobData =(BYTE *)PVGetCertificateParam(psdi->pCert, CERT_HASH_PROP_ID, &tb.cbSize);
  1499. }
  1500. pAcct->SetProp(AP_SMTP_CERTIFICATE, tb.pBlobData, tb.cbSize);
  1501. THUMBBLOB tbEncrypt = {0,0};
  1502. if(psdi->pEncryptCert)
  1503. {
  1504. tbEncrypt.pBlobData =(BYTE *)PVGetCertificateParam(psdi->pEncryptCert, CERT_HASH_PROP_ID, &tbEncrypt.cbSize);
  1505. AdvSec_GetEncryptAlgCombo(hwnd, pAcct);
  1506. }
  1507. pAcct->SetProp(AP_SMTP_ENCRYPT_CERT, tbEncrypt.pBlobData, tbEncrypt.cbSize);
  1508. return;
  1509. }
  1510. /* InitCertificateData:
  1511. **
  1512. ** Purpose:
  1513. ** determine if the account has a cert set on it and also initialize
  1514. ** the SVRDLGINFO.
  1515. ** Takes:
  1516. ** [in/out] psdi - the hCertStore and pCert fields will be updated
  1517. ** [in] pAcct - account to check for currently selected cert
  1518. ** Returns:
  1519. ** DWORD(-1) - there was an error. don't ever enable any UI
  1520. ** 0 - no cert on the account, but no error
  1521. ** 1 - cert set on account and placed in psdi->pCert
  1522. */
  1523. DWORD InitCertificateData(TCHAR * szEmail, SECPAGEINFO *psdi, IImnAccount *pAcct)
  1524. {
  1525. THUMBBLOB tb;
  1526. DWORD dwRet = DWORD(-1);
  1527. Assert(psdi && pAcct);
  1528. if(!psdi->hCertStore)
  1529. psdi->hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A,
  1530. X509_ASN_ENCODING, NULL, CERT_SYSTEM_STORE_CURRENT_USER, "My");
  1531. if (psdi->hCertStore)
  1532. {
  1533. dwRet = 0;
  1534. if (SUCCEEDED(pAcct->GetProp(AP_SMTP_CERTIFICATE, NULL, &tb.cbSize)))
  1535. {
  1536. if (MemAlloc((void**)&tb.pBlobData, tb.cbSize))
  1537. {
  1538. if (SUCCEEDED(pAcct->GetProp(AP_SMTP_CERTIFICATE, tb.pBlobData, &tb.cbSize)))
  1539. {
  1540. psdi->pCert = CertFindCertificateInStore(
  1541. psdi->hCertStore,
  1542. X509_ASN_ENCODING,
  1543. 0,
  1544. CERT_FIND_HASH,
  1545. (void *)(CRYPT_DIGEST_BLOB *)&tb,
  1546. NULL);
  1547. if (psdi->pCert)
  1548. {
  1549. // Double check, we must be sure that certificate is OK
  1550. ACCTFILTERINFO FilterInfo;
  1551. FilterInfo.fEncryption = FALSE;
  1552. FilterInfo.dwFlags = CRYPTDLG_REVOCATION_NONE; // No revocation checking
  1553. FilterInfo.szEmail = szEmail;
  1554. if(CertFilterFunction(psdi->pCert, (LPARAM)(&FilterInfo), 0, 0))
  1555. {
  1556. dwRet = 1;
  1557. }
  1558. else
  1559. {
  1560. CertFreeCertificateContext(psdi->pCert);
  1561. psdi->pCert = NULL;
  1562. // remove wrong certificate from property
  1563. pAcct->SetProp(AP_SMTP_CERTIFICATE, NULL, 0);
  1564. }
  1565. }
  1566. }
  1567. }
  1568. MemFree(tb.pBlobData);
  1569. }
  1570. else if(psdi->pEncryptCert)
  1571. {
  1572. if(CheckKeyUsage(psdi->pEncryptCert, CERT_DIGITAL_SIGNATURE_KEY_USAGE) >= 0)
  1573. {
  1574. psdi->pCert = CertDuplicateCertificateContext(psdi->pEncryptCert);
  1575. dwRet = 1;
  1576. }
  1577. }
  1578. }
  1579. return dwRet;
  1580. }
  1581. /* InitEncryptData
  1582. **
  1583. ** Purpose:
  1584. ** determine if the account has a encryption cert set on it and also initialize
  1585. ** the SVRDLGINFO.
  1586. ** Takes:
  1587. ** [in/out] psdi - the hCertStore and pCert fields will be updated
  1588. ** [in] pAcct - account to check for currently selected cert
  1589. ** Returns:
  1590. ** DWORD(-1) - there was an error. don't ever enable any UI
  1591. ** 0 - no cert on the account, but no error
  1592. ** 1 - cert set on account and placed in psdi->pCert
  1593. */
  1594. DWORD InitEncryptData(TCHAR *szEmail, SECPAGEINFO *psdi, IImnAccount *pAcct)
  1595. {
  1596. THUMBBLOB tb;
  1597. DWORD dwRet = DWORD(-1);
  1598. DWORD dwUsage = 0;
  1599. if(!psdi->hCertStore)
  1600. psdi->hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A,
  1601. X509_ASN_ENCODING, NULL, CERT_SYSTEM_STORE_CURRENT_USER, "My");
  1602. if (psdi->hCertStore)
  1603. {
  1604. dwRet = 0;
  1605. if (SUCCEEDED(pAcct->GetProp(AP_SMTP_ENCRYPT_CERT, NULL, &tb.cbSize)))
  1606. {
  1607. if (MemAlloc((void**)&tb.pBlobData, tb.cbSize))
  1608. {
  1609. if (SUCCEEDED(pAcct->GetProp(AP_SMTP_ENCRYPT_CERT, tb.pBlobData, &tb.cbSize)))
  1610. {
  1611. psdi->pEncryptCert = CertFindCertificateInStore(
  1612. psdi->hCertStore,
  1613. X509_ASN_ENCODING,
  1614. 0,
  1615. CERT_FIND_HASH,
  1616. (void *)(CRYPT_DIGEST_BLOB *)&tb,
  1617. NULL);
  1618. if (psdi->pEncryptCert)
  1619. {
  1620. // Double check, we must be sure that certificate is OK
  1621. ACCTFILTERINFO FilterInfo;
  1622. FilterInfo.fEncryption = TRUE;
  1623. FilterInfo.dwFlags = CRYPTDLG_REVOCATION_NONE; // no revocation checking
  1624. FilterInfo.szEmail = szEmail;
  1625. if(CertFilterFunction(psdi->pEncryptCert, (LPARAM)(&FilterInfo), 0, 0))
  1626. {
  1627. dwRet = 1;
  1628. }
  1629. else
  1630. {
  1631. CertFreeCertificateContext(psdi->pEncryptCert);
  1632. psdi->pEncryptCert = NULL;
  1633. // remove wrong certificate from property
  1634. pAcct->SetProp(AP_SMTP_ENCRYPT_CERT, NULL, 0);
  1635. }
  1636. }
  1637. }
  1638. }
  1639. MemFree(tb.pBlobData);
  1640. }
  1641. // if encryption certificate was not set
  1642. // check that current signing certificate can be used for encryption
  1643. else if(psdi->pCert)
  1644. {
  1645. if((CheckKeyUsage(psdi->pCert, CERT_KEY_ENCIPHERMENT_KEY_USAGE) >= 0) ||
  1646. (CheckKeyUsage(psdi->pCert, CERT_KEY_AGREEMENT_KEY_USAGE) > 0))
  1647. {
  1648. psdi->pEncryptCert = CertDuplicateCertificateContext(psdi->pCert);
  1649. dwRet = 1;
  1650. }
  1651. }
  1652. }
  1653. return dwRet;
  1654. }
  1655. // Check key usage field in certificate.
  1656. // Usage:
  1657. // CheckKeyUsage(PCCERT_CONTEXT pCert, DWORD dwFlag);
  1658. // where dwFlag is tested flaf of KeyUsage field
  1659. //
  1660. // Return
  1661. // 1 - flag is set
  1662. // 0 - key usage field not found in certificate
  1663. // -1 - flag is NOT set in key usage field.
  1664. int CheckKeyUsage(PCCERT_CONTEXT pCert, DWORD dwFlag)
  1665. {
  1666. DWORD dwUsage = 0;
  1667. HRESULT hr = S_OK;
  1668. hr = HrGetCertKeyUsage(pCert, &dwUsage);
  1669. if(SUCCEEDED(hr))
  1670. {
  1671. if(dwUsage & dwFlag)
  1672. return(1);
  1673. else
  1674. return(-1);
  1675. }
  1676. else // Certificate doesn't have KeyUsage field (like VeriSign),
  1677. return(0);
  1678. }
  1679. BOOL DoCertDialog(HWND hwndOwner, HWND hwndEmail, PCCERT_CONTEXT *ppCert, HCERTSTORE hCertStore, int *puIdsErr, DWORD dwFlags, BOOL fEncription)
  1680. {
  1681. TCHAR szEmail[CCHMAX_ACCT_PROP_SZ];
  1682. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  1683. DWORD cchEmail;
  1684. CERT_SELECT_STRUCT css;
  1685. PCCERT_CONTEXT pCurCert;
  1686. BOOL fRet = FALSE;
  1687. ACCTFILTERINFO FilterInfo;
  1688. *puIdsErr = 0;
  1689. cchEmail = GetWindowText(hwndEmail, szEmail, ARRAYSIZE(szEmail));
  1690. if (cchEmail)
  1691. {
  1692. memset(&css, 0, sizeof(css));
  1693. pCurCert = CertDuplicateCertificateContext(*ppCert);
  1694. LoadString(g_hInstRes, idsSelectCertTitle, sz, ARRAYSIZE(sz));
  1695. css.dwSize = sizeof(css);
  1696. css.hwndParent = hwndOwner;
  1697. css.hInstance = g_hInstRes;
  1698. css.szTitle = sz;
  1699. css.dwFlags = dwFlags;
  1700. // hack
  1701. FilterInfo.fEncryption = fEncription;
  1702. FilterInfo.dwFlags = dwFlags;
  1703. FilterInfo.szEmail = szEmail;
  1704. css.lCustData = (LPARAM)(&FilterInfo);
  1705. css.arrayCertStore = &hCertStore;
  1706. css.cCertStore = 1;
  1707. css.szPurposeOid = szOID_PKIX_KP_EMAIL_PROTECTION;
  1708. css.arrayCertContext = ppCert;
  1709. css.cCertContext = 1;
  1710. #ifdef DEBUG
  1711. if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
  1712. css.pfnFilter = NULL;
  1713. else
  1714. css.pfnFilter = CertFilterFunction;
  1715. #else
  1716. css.pfnFilter = CertFilterFunction;
  1717. #endif
  1718. if (CertSelectCertificate(&css) && (pCurCert != *ppCert))
  1719. {
  1720. fRet = TRUE;
  1721. }
  1722. CertFreeCertificateContext(pCurCert);
  1723. }
  1724. else
  1725. *puIdsErr = idsNeedEmailForCert;
  1726. return fRet;
  1727. }
  1728. #define FILETIME_SECOND 10000000 // 100ns intervals per second
  1729. #define TIME_DELTA_SECONDS 600 // 10 minutes in seconds
  1730. BOOL CertFilterFunction(PCCERT_CONTEXT pCertContext, LPARAM lParam, DWORD dwFlags, DWORD)
  1731. {
  1732. // return TRUE to show, FALSE to hide
  1733. BOOL fRet = FALSE;
  1734. FILETIME FileTime;
  1735. SYSTEMTIME SysTime;
  1736. ACCTFILTERINFO * pFilterInfo = (ACCTFILTERINFO *) lParam;
  1737. LONG lRet = 0;
  1738. PCCERT_CONTEXT *rgCertChain = NULL;
  1739. DWORD cCertChain = 0;
  1740. const DWORD dwIgnore = CERT_VALIDITY_NO_CRL_FOUND | CERT_VALIDITY_BEFORE_START |
  1741. CERT_VALIDITY_AFTER_END | CERT_VALIDITY_NO_TRUST_DATA;
  1742. LPSTR szCertEmail = SzGetCertificateEmailAddress(pCertContext);
  1743. GetSystemTime(&SysTime);
  1744. if(SystemTimeToFileTime(&SysTime, &FileTime))
  1745. {
  1746. lRet = CertVerifyTimeValidity(&FileTime, pCertContext->pCertInfo);
  1747. if(lRet < 0)
  1748. {
  1749. FILETIME ftNow;
  1750. __int64 i64Offset;
  1751. union
  1752. {
  1753. FILETIME ftDelta;
  1754. __int64 i64Delta;
  1755. };
  1756. GetSystemTimeAsFileTime(&ftNow);
  1757. i64Delta = ftNow.dwHighDateTime;
  1758. i64Delta = i64Delta << 32;
  1759. i64Delta += ftNow.dwLowDateTime;
  1760. // Add the offset into the original time to get us a new time to check
  1761. i64Offset = FILETIME_SECOND;
  1762. i64Offset *= TIME_DELTA_SECONDS;
  1763. i64Delta += i64Offset;
  1764. lRet = CertVerifyTimeValidity(&ftDelta, pCertContext->pCertInfo);
  1765. }
  1766. if(lRet != 0)
  1767. return FALSE;
  1768. }
  1769. if (szCertEmail)
  1770. {
  1771. fRet = !(BOOL(lstrcmpi(szCertEmail, pFilterInfo->szEmail)));
  1772. MemFree(szCertEmail);
  1773. if(!fRet)
  1774. return(FALSE);
  1775. }
  1776. if(pFilterInfo->fEncryption)
  1777. {
  1778. if(CheckKeyUsage(pCertContext, CERT_KEY_ENCIPHERMENT_KEY_USAGE) < 0)
  1779. {
  1780. if(CheckKeyUsage(pCertContext, CERT_KEY_AGREEMENT_KEY_USAGE) < 1)
  1781. return(FALSE);
  1782. }
  1783. }
  1784. else {
  1785. if(CheckKeyUsage(pCertContext, CERT_DIGITAL_SIGNATURE_KEY_USAGE) < 0)
  1786. return(FALSE);
  1787. }
  1788. if(pFilterInfo->dwFlags) // if flags != 0 check certificate
  1789. {
  1790. DWORD dwErr = DwGenerateTrustedChain(NULL, pFilterInfo->dwFlags, pCertContext, dwIgnore, TRUE, &cCertChain, &rgCertChain);
  1791. if (rgCertChain)
  1792. {
  1793. for (cCertChain--; int(cCertChain) >= 0; cCertChain--)
  1794. CertFreeCertificateContext(rgCertChain[cCertChain]);
  1795. MemFree(rgCertChain);
  1796. }
  1797. if(dwErr != 0)
  1798. return(FALSE);
  1799. }
  1800. return(fRet);
  1801. }
  1802. static const TCHAR c_szOpen[] = TEXT("open");
  1803. static const TCHAR c_szIexplore[] = TEXT("iexplore.exe");
  1804. const static HELPMAP g_rgCtxMapMailSec[] =
  1805. {
  1806. {idcCertCheck, IDH_GENERAL_USE_CERTIFICATE},
  1807. {idcCertButton, IDH_GENERAL_SELECT_CERTIFICATE},
  1808. {IDC_GETCERT, IDH_INETCOM_GET_DIGITAL_ID},
  1809. {IDC_MOREINFO, IDH_INETCOM_MORE_ON_CERTIFICATES},
  1810. {idcCertEdit, IDH_SECURITY_SIGNING_CERT},
  1811. {idcCryptEdit, IDH_SECURITY_ENCRYPTING_CERT},
  1812. {idcCryptButton, IDH_SECURITY_SELECT_ENCRYPTCERT},
  1813. {IDC_ALGCOMBO, IDH_SECURITY_ADV_ENCRYPTION},
  1814. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  1815. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  1816. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  1817. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  1818. {IDC_STATIC4, IDH_INETCOMM_GROUPBOX},
  1819. {IDC_STATIC5, IDH_INETCOMM_GROUPBOX},
  1820. {IDC_STATIC6, IDH_INETCOMM_GROUPBOX},
  1821. {IDC_STATIC7, IDH_INETCOMM_GROUPBOX},
  1822. {IDC_STATIC8, IDH_INETCOMM_GROUPBOX},
  1823. {IDC_STATIC10, IDH_INETCOMM_GROUPBOX},
  1824. {IDC_STATIC11, IDH_INETCOMM_GROUPBOX},
  1825. {IDC_STATIC12, IDH_INETCOMM_GROUPBOX},
  1826. {IDC_STATIC13, IDH_INETCOMM_GROUPBOX},
  1827. {0, 0}
  1828. };
  1829. INT_PTR CALLBACK MailServer_SecurityDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1830. {
  1831. NMHDR *pnmhdr;
  1832. CAccount *pAcct;
  1833. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  1834. DWORD dw;
  1835. BOOL fRet;
  1836. int idsError;
  1837. HWND hwndT;
  1838. SECPAGEINFO *pcpi;
  1839. pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  1840. pcpi = (SECPAGEINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  1841. switch (uMsg)
  1842. {
  1843. case WM_INITDIALOG:
  1844. // Get the ServerParams and store them in our extra bytes
  1845. pAcct = (CAccount *)((PROPSHEETPAGE *)lParam)->lParam;
  1846. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  1847. Assert(pcpi == NULL);
  1848. if (!MemAlloc((void **)&pcpi, sizeof(SECPAGEINFO)))
  1849. return(-1);
  1850. ZeroMemory(pcpi, sizeof(SECPAGEINFO));
  1851. hwndT = GetDlgItem(hwnd, idcCertEdit);
  1852. SetIntlFont(hwndT);
  1853. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETEMAILADDRESS, (LPARAM)sz);
  1854. SetDlgItemText(hwnd, idcCertAddress, sz);
  1855. dw = InitCertificateData(sz, pcpi, pAcct);
  1856. if (1 == dw)
  1857. {
  1858. Assert(pcpi->pCert);
  1859. if (GetFriendlyNameOfCert(pcpi->pCert, sz, ARRAYSIZE(sz)))
  1860. SendMessage(hwndT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)sz);
  1861. }
  1862. else if (-1 == dw)
  1863. {
  1864. EnableWindow(GetDlgItem(hwnd, idcCertCheck), FALSE);
  1865. }
  1866. GetDlgItemText(hwnd, idcCertAddress, sz, ARRAYSIZE(sz));
  1867. dw = InitEncryptData(sz, pcpi, pAcct);
  1868. if(dw == 1)
  1869. {
  1870. Assert(pcpi->pEncryptCert);
  1871. hwndT = GetDlgItem(hwnd, idcCryptEdit);
  1872. SetIntlFont(hwndT);
  1873. if (GetFriendlyNameOfCert(pcpi->pEncryptCert, sz, ARRAYSIZE(sz)))
  1874. SendMessage(hwndT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)sz);
  1875. }
  1876. // Always fill this combo
  1877. AdvSec_FillEncAlgCombo(hwnd, pAcct, (dw == 1) ? &pcpi->pEncryptCert : NULL );
  1878. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pcpi);
  1879. EnableCertControls(hwnd);
  1880. PropSheet_QuerySiblings(GetParent(hwnd), SM_INITIALIZED, PAGE_SEC);
  1881. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  1882. return (TRUE);
  1883. case WM_DESTROY:
  1884. if (pcpi != NULL)
  1885. {
  1886. if (pcpi->pCert)
  1887. CertFreeCertificateContext(pcpi->pCert);
  1888. if (pcpi->pEncryptCert)
  1889. CertFreeCertificateContext(pcpi->pEncryptCert);
  1890. if (pcpi->hCertStore)
  1891. CertCloseStore(pcpi->hCertStore, 0);
  1892. MemFree(pcpi);
  1893. }
  1894. break;
  1895. case PSM_QUERYSIBLINGS:
  1896. if (wParam == MSM_GETCERTDATA)
  1897. {
  1898. if (IsDlgButtonChecked(hwnd, idcCertCheck))
  1899. {
  1900. ((SECPAGEINFO *)lParam)->pCert = pcpi->pCert;
  1901. ((SECPAGEINFO *)lParam)->hCertStore = pcpi->hCertStore;
  1902. }
  1903. return(TRUE);
  1904. }
  1905. break;
  1906. case WM_HELP:
  1907. case WM_CONTEXTMENU:
  1908. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapMailSec));
  1909. case WM_COMMAND:
  1910. switch(LOWORD(wParam))
  1911. {
  1912. case IDC_ALGCOMBO:
  1913. if(GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELENDOK)
  1914. MarkPageDirty(hwnd, PAGE_SEC);
  1915. break;
  1916. case idcCertCheck:
  1917. EnableCertControls(hwnd);
  1918. MarkPageDirty(hwnd, PAGE_SEC);
  1919. break;
  1920. case idcCertButton:
  1921. hwndT = GetDlgItem(hwnd, idcCertAddress);
  1922. if (DoCertDialog(hwnd, hwndT, &pcpi->pCert, pcpi->hCertStore, &idsError,
  1923. ((pAcct->m_dwDlgFlags & ACCTDLG_REVOCATION) ? CRYPTDLG_REVOCATION_ONLINE : CRYPTDLG_REVOCATION_NONE), FALSE))
  1924. {
  1925. if (GetFriendlyNameOfCert(pcpi->pCert, sz, ARRAYSIZE(sz)))
  1926. SetDlgItemText(hwnd, idcCertEdit, sz);
  1927. MarkPageDirty(hwnd, PAGE_SEC);
  1928. }
  1929. else if (idsError)
  1930. InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_Security);
  1931. break;
  1932. case idcCryptButton:
  1933. hwndT = GetDlgItem(hwnd, idcCertAddress);
  1934. if (DoCertDialog(hwnd, hwndT, &pcpi->pEncryptCert, pcpi->hCertStore, &idsError,
  1935. ((pAcct->m_dwDlgFlags & ACCTDLG_REVOCATION) ? CRYPTDLG_REVOCATION_ONLINE : CRYPTDLG_REVOCATION_NONE), TRUE))
  1936. {
  1937. if (GetFriendlyNameOfCert(pcpi->pEncryptCert, sz, ARRAYSIZE(sz)))
  1938. SetDlgItemText(hwnd, idcCryptEdit, sz);
  1939. MarkPageDirty(hwnd, PAGE_SEC);
  1940. }
  1941. else if (idsError)
  1942. InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_Security);
  1943. EnableCertControls(hwnd);
  1944. break;
  1945. case IDC_GETCERT:
  1946. GetDigitalID(hwnd);
  1947. break;
  1948. case IDC_MOREINFO:
  1949. OEHtmlHelp(hwnd, "%SYSTEMROOT%\\help\\msoe.chm>large_context", HH_DISPLAY_TOPIC, (ULONG_PTR) (LPCSTR) "mail_overview_send_secure_messages.htm");
  1950. break;
  1951. }
  1952. break;
  1953. case WM_NOTIFY:
  1954. pnmhdr = (NMHDR *)lParam;
  1955. switch (pnmhdr->code)
  1956. {
  1957. case PSN_SETACTIVE:
  1958. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETEMAILADDRESS, (LPARAM)sz);
  1959. SetDlgItemText(hwnd, idcCertAddress, sz);
  1960. break;
  1961. case PSN_APPLY:
  1962. // BEGIN validation
  1963. #ifdef DEBUG
  1964. if (!(GetAsyncKeyState(VK_SHIFT) & 0x8000))
  1965. {
  1966. #endif
  1967. fRet = ValidateCertificate(hwnd, pAcct, pcpi, &hwndT, &idsError);
  1968. if (!fRet)
  1969. {
  1970. if(idsError != 0)
  1971. return(InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_Security));
  1972. else
  1973. return FALSE;
  1974. }
  1975. #ifdef DEBUG
  1976. }
  1977. #endif
  1978. // END validation
  1979. GetCertificate(hwnd, pAcct, pcpi);
  1980. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  1981. dw = PAGE_SEC;
  1982. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  1983. if (dw == -1)
  1984. {
  1985. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  1986. return(TRUE);
  1987. }
  1988. break;
  1989. }
  1990. return(TRUE);
  1991. }
  1992. return (FALSE);
  1993. }
  1994. INT_PTR CALLBACK CertAddressErrorDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  1995. {
  1996. HICON hicon;
  1997. BOOL fRet = TRUE;
  1998. switch (msg)
  1999. {
  2000. case WM_INITDIALOG:
  2001. hicon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_EXCLAMATION));
  2002. if (hicon != NULL)
  2003. SendDlgItemMessage(hwnd, IDC_ERR_STATIC, STM_SETICON, (WPARAM)hicon, 0);
  2004. MessageBeep(MB_ICONEXCLAMATION);
  2005. break;
  2006. case WM_COMMAND:
  2007. if (HIWORD(wParam) == BN_CLICKED)
  2008. EndDialog(hwnd, LOWORD(wParam));
  2009. break;
  2010. default:
  2011. fRet = FALSE;
  2012. break;
  2013. }
  2014. return(fRet);
  2015. }
  2016. const static HELPMAP g_rgCtxMapMailGen[] = {
  2017. {IDC_SERVERNAME_EDIT, IDH_MAIL_ACCOUNT},
  2018. {IDE_DISPLAY_NAME, IDH_NEWS_SERV_NAME},
  2019. {IDE_ORG_NAME, IDH_NEWS_SERV_ORG},
  2020. {IDE_EMAIL_ADDRESS, IDH_NEWS_SERV_EMAIL_ADD},
  2021. {IDE_REPLYTO_EMAIL_ADDRESS, IDH_MAIL_SERV_ADV_REPLY_TO},
  2022. {IDC_RECVFULL_INCLUDE, IDH_INCLUDEACCT_IN_SENDREC},
  2023. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  2024. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  2025. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  2026. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  2027. {IDC_STATIC4, IDH_INETCOMM_GROUPBOX},
  2028. {IDC_STATIC5, IDH_INETCOMM_GROUPBOX},
  2029. {0, 0}};
  2030. INT_PTR CALLBACK MailServer_GeneralDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,
  2031. LPARAM lParam)
  2032. {
  2033. NMHDR *pnmhdr;
  2034. CAccount *pAcct;
  2035. TCHAR *pszEmail, sz[CCHMAX_ACCT_PROP_SZ];
  2036. DWORD dw;
  2037. BOOL fRet, fFree, fError;
  2038. SVRDLGINFO *psdi;
  2039. SECPAGEINFO cpi;
  2040. INT idsError;
  2041. HWND hwndT;
  2042. pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  2043. psdi = (SVRDLGINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  2044. switch (uMsg)
  2045. {
  2046. case WM_INITDIALOG:
  2047. // Get the ServerParams and store them in our extra bytes
  2048. pAcct = (CAccount *)((PROPSHEETPAGE *)lParam)->lParam;
  2049. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  2050. Assert(psdi == NULL);
  2051. if (!MemAlloc((void **)&psdi, sizeof(SVRDLGINFO)))
  2052. return(-1);
  2053. ZeroMemory(psdi, sizeof(SVRDLGINFO));
  2054. // figure out if we're a mail or imap account
  2055. psdi->sfType = SERVER_MAIL; // mail will be default for now...
  2056. if (SUCCEEDED(pAcct->GetServerTypes(&dw)))
  2057. {
  2058. if (!!(dw & SRV_IMAP))
  2059. psdi->sfType = SERVER_IMAP;
  2060. else if (!!(dw & SRV_HTTPMAIL))
  2061. psdi->sfType = SERVER_HTTPMAIL;
  2062. }
  2063. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)psdi);
  2064. InitUserInformation(hwnd, pAcct, FALSE);
  2065. // Set Account Name
  2066. InitAcctPropEdit(GetDlgItem(hwnd, IDC_SERVERNAME_EDIT), pAcct, AP_ACCOUNT_NAME, CCHMAX_ACCOUNT_NAME - 1);
  2067. // if the account is an msn-related http account, swap in the msn icon
  2068. if (SERVER_HTTPMAIL == psdi->sfType)
  2069. {
  2070. DWORD dwMsnDomain = 0;
  2071. if (SUCCEEDED(pAcct->GetPropDw(AP_HTTPMAIL_DOMAIN_MSN, &dwMsnDomain)) && dwMsnDomain)
  2072. {
  2073. HICON hicon = LoadIcon(g_hInstRes, MAKEINTRESOURCE(idiMsnServer));
  2074. if (NULL != hicon)
  2075. SendDlgItemMessage(hwnd, IDC_MAILSERVER_ICON, STM_SETICON, (WPARAM)hicon, 0);
  2076. }
  2077. }
  2078. // POP3 Skip Account/IMAP Poll Unread
  2079. if (SERVER_IMAP == psdi->sfType)
  2080. {
  2081. int iIMAPStringRes;
  2082. if (pAcct->m_dwDlgFlags & ACCTDLG_NO_IMAPPOLL)
  2083. iIMAPStringRes = idsIMAPPollInbox;
  2084. else
  2085. iIMAPStringRes = idsIMAPPollForUnread;
  2086. /*
  2087. // Replace default POP3 text with text that better suits IMAP
  2088. LoadString(g_hInstRes, iIMAPStringRes, sz, sizeof(sz));
  2089. SetWindowText(GetDlgItem(hwnd, IDC_RECVFULL_INCLUDE), sz);
  2090. */
  2091. // Load current setting and set checkbox to indicate it
  2092. if (FAILED(pAcct->GetPropDw(AP_IMAP_POLL, &dw)))
  2093. dw = FALSE; // By default, we don't poll for IMAP
  2094. CheckDlgButton(hwnd, IDC_RECVFULL_INCLUDE, dw ? BST_CHECKED : BST_UNCHECKED);
  2095. } // if
  2096. else if (SERVER_HTTPMAIL == psdi->sfType)
  2097. {
  2098. dw = FALSE;
  2099. pAcct->GetPropDw(AP_HTTPMAIL_POLL, &dw);
  2100. CheckDlgButton(hwnd, IDC_RECVFULL_INCLUDE, dw ? BST_CHECKED : BST_UNCHECKED);
  2101. }
  2102. else
  2103. {
  2104. if (!!(pAcct->m_dwDlgFlags & ACCTDLG_NO_SENDRECEIVE))
  2105. ShowWindow(GetDlgItem(hwnd, IDC_RECVFULL_INCLUDE), SW_HIDE);
  2106. else
  2107. {
  2108. if (SUCCEEDED(pAcct->GetPropDw(AP_POP3_SKIP, &dw)))
  2109. CheckDlgButton(hwnd, IDC_RECVFULL_INCLUDE, dw ? BST_UNCHECKED : BST_CHECKED);
  2110. else
  2111. CheckDlgButton(hwnd, IDC_RECVFULL_INCLUDE, BST_CHECKED);
  2112. } // else
  2113. } // else
  2114. psdi->dwInit = (psdi->dwInit | PAGE_GEN);
  2115. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  2116. return (TRUE);
  2117. case WM_DESTROY:
  2118. if (psdi != NULL)
  2119. MemFree(psdi);
  2120. break;
  2121. case WM_HELP:
  2122. case WM_CONTEXTMENU:
  2123. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapMailGen));
  2124. case PSM_QUERYSIBLINGS:
  2125. Assert(psdi != NULL);
  2126. Assert(pAcct != NULL);
  2127. return(HandleQuerySiblings(hwnd, psdi, pAcct, wParam, lParam));
  2128. case WM_COMMAND:
  2129. switch(GET_WM_COMMAND_ID(wParam, lParam))
  2130. {
  2131. case IDC_RECVFULL_INCLUDE:
  2132. MarkPageDirty(hwnd, PAGE_GEN);
  2133. break;
  2134. default:
  2135. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  2136. {
  2137. if (LOWORD(wParam) == IDC_SERVERNAME_EDIT)
  2138. UpdateAcctTitle(hwnd, IDC_SERVERNAME_EDIT, ACCT_MAIL);
  2139. MarkPageDirty(hwnd, PAGE_GEN);
  2140. }
  2141. break;
  2142. }
  2143. break;
  2144. case WM_NOTIFY:
  2145. pnmhdr = (NMHDR *)lParam;
  2146. switch (pnmhdr->code)
  2147. {
  2148. case PSN_APPLY:
  2149. // BEGIN validation
  2150. if (psdi->fNoValidate)
  2151. {
  2152. Assert(pnmhdr->code == PSN_KILLACTIVE);
  2153. break;
  2154. }
  2155. #ifdef DEBUG
  2156. if (!(GetAsyncKeyState(VK_SHIFT) & 0x8000))
  2157. {
  2158. #endif
  2159. hwndT = GetDlgItem(hwnd, IDC_SERVERNAME_EDIT);
  2160. if (!ValidateAccountName(hwnd, hwndT, pAcct, &idsError))
  2161. return(InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_General));
  2162. fRet = ValidateUserInformation(hwnd, pAcct, FALSE, &hwndT, &idsError, pnmhdr->code == PSN_APPLY);
  2163. if (!fRet)
  2164. return(InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_General));
  2165. if (0 == (pAcct->m_dwDlgFlags & ACCTDLG_NO_SECURITY))
  2166. {
  2167. fError = FALSE;
  2168. ZeroMemory(&cpi, sizeof(SECPAGEINFO));
  2169. hwndT = GetDlgItem(hwnd, IDE_EMAIL_ADDRESS);
  2170. GetWindowText(hwndT, sz, ARRAYSIZE(sz));
  2171. if (!!(psdi->dwInit & PAGE_SEC))
  2172. {
  2173. // the security page exists, so ask it for the cert info
  2174. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETCERTDATA, (LPARAM)&cpi);
  2175. fFree = FALSE;
  2176. }
  2177. else
  2178. {
  2179. // the security page hasn't been initialized yet,
  2180. // so we need to get this info from the acct
  2181. dw = InitCertificateData(sz, &cpi, pAcct);
  2182. Assert((dw != 1) ^ (cpi.pCert != NULL));
  2183. fFree = TRUE;
  2184. InitEncryptData(sz, &cpi, pAcct);
  2185. }
  2186. if (cpi.pCert != NULL)
  2187. {
  2188. pszEmail = SzGetCertificateEmailAddress(cpi.pCert);
  2189. if (lstrcmpi(pszEmail, sz) != 0)
  2190. {
  2191. idsError = (INT) DialogBox(g_hInstRes, MAKEINTRESOURCE(iddCertAddressError),
  2192. hwnd, CertAddressErrorDlgProc);
  2193. switch (idsError)
  2194. {
  2195. case IDCANCEL:
  2196. SendMessage(hwndT, EM_SETSEL, 0, -1);
  2197. SetFocus(hwndT);
  2198. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  2199. fError = TRUE;
  2200. break;
  2201. case IDC_CHANGE_ADDR:
  2202. SetWindowText(hwndT, pszEmail);
  2203. SendMessage(hwndT, EM_SETMODIFY, TRUE, 0);
  2204. break;
  2205. case IDC_NEW_CERT:
  2206. psdi->fNoValidate = TRUE;
  2207. SendMessage(GetParent(hwnd), PSM_SETCURSELID, 0, (LPARAM)iddMailSvrProp_Security);
  2208. psdi->fNoValidate = FALSE;
  2209. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  2210. fError = TRUE;
  2211. break;
  2212. }
  2213. }
  2214. if(pszEmail)
  2215. MemFree(pszEmail);
  2216. }
  2217. if (cpi.pCert != NULL && fFree)
  2218. CertFreeCertificateContext(cpi.pCert);
  2219. if (cpi.pEncryptCert != NULL && fFree)
  2220. CertFreeCertificateContext(cpi.pEncryptCert);
  2221. if (cpi.hCertStore != NULL && fFree)
  2222. CertCloseStore(cpi.hCertStore, 0);
  2223. if (fError)
  2224. return(TRUE);
  2225. }
  2226. #ifdef DEBUG
  2227. }
  2228. #endif
  2229. // END validation
  2230. hwndT = GetDlgItem(hwnd, IDC_SERVERNAME_EDIT);
  2231. GetAccountName(hwndT, pAcct);
  2232. GetUserInformation(hwnd, pAcct, FALSE);
  2233. // Skip During Send and Receive (POP) --OR--
  2234. // Poll for Unread Count (IMAP)
  2235. if (SERVER_IMAP == psdi->sfType)
  2236. pAcct->SetPropDw(AP_IMAP_POLL, (DWORD) IsDlgButtonChecked (hwnd, IDC_RECVFULL_INCLUDE));
  2237. else if (SERVER_HTTPMAIL == psdi->sfType)
  2238. pAcct->SetPropDw(AP_HTTPMAIL_POLL, (DWORD) IsDlgButtonChecked (hwnd, IDC_RECVFULL_INCLUDE));
  2239. else
  2240. pAcct->SetPropDw(AP_POP3_SKIP, (DWORD)!IsDlgButtonChecked(hwnd, IDC_RECVFULL_INCLUDE));
  2241. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  2242. dw = PAGE_GEN;
  2243. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  2244. if (dw == -1)
  2245. {
  2246. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  2247. return(TRUE);
  2248. }
  2249. break;
  2250. }
  2251. return(TRUE);
  2252. }
  2253. return (FALSE);
  2254. }
  2255. const static HELPMAP g_rgCtxMapMailSvr[] = {
  2256. {IDC_SMTP_EDIT, IDH_MAIL_SERV_OUTGOING},
  2257. {IDC_POP3_EDIT, IDH_MAIL_SERV_INCOMING},
  2258. {IDC_IN_MAIL_STATIC, IDH_MAIL_SERV_INCOMING},
  2259. {idcPOP_OR_IMAP, IDH_INETCOMM_MY_INCOMING_SERVER_IS},
  2260. {IDC_SERVER_STATIC, IDH_INETCOMM_MY_INCOMING_SERVER_IS},
  2261. {IDC_SERVER1_STATIC, IDH_INETCOMM_MY_INCOMING_SERVER_IS},
  2262. {IDC_LOGON_CHECK, IDH_INETCOMM_SERVER_REQ_LOGON},
  2263. {IDC_ACCTNAME_EDIT, IDH_MAIL_SERV_POP3_ACCT},
  2264. {IDC_ACCTNAME_STATIC, IDH_MAIL_SERV_POP3_ACCT},
  2265. {IDC_ACCTPASS_EDIT, IDH_MAIL_SERV_PWORD},
  2266. {IDC_ACCTPASS_STATIC, IDH_MAIL_SERV_PWORD},
  2267. {IDC_LOGONSSPI_CHECK, IDH_MAIL_LOGON_USING_SICILY},
  2268. {IDC_SMTP_SASL, IDH_MAIL_OUT_AUTH},
  2269. {IDC_SMTPLOGON, IDH_MAIL_OUT_SETTINGS},
  2270. {IDC_REMEMBER_PASSWORD, 503},
  2271. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  2272. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  2273. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  2274. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  2275. {IDC_STATIC4, IDH_INETCOMM_GROUPBOX},
  2276. {IDC_STATIC5, IDH_INETCOMM_GROUPBOX},
  2277. {0, 0}};
  2278. INT_PTR CALLBACK MailServer_ServersDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,
  2279. LPARAM lParam)
  2280. {
  2281. static SMTPAUTHINFO s_rAuth;
  2282. int idsError;
  2283. HWND hwndT;
  2284. ULONG cbSize;
  2285. NMHDR *pnmhdr;
  2286. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  2287. DWORD dw, dwPromptForPassword;
  2288. BOOL fEnable, fIMAP, fHTTPMail;
  2289. SERVER_TYPE sfType, sfTypeT;
  2290. LPMAILSERVERPROPSINFO pProps = NULL;
  2291. CAccount *pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  2292. TCHAR szPreviousLoginName[CCHMAX_ACCT_PROP_SZ];
  2293. switch (uMsg)
  2294. {
  2295. case WM_INITDIALOG:
  2296. // Get the ServerParams and store them in our extra bytes
  2297. pAcct = (CAccount *)((PROPSHEETPAGE *)lParam)->lParam;
  2298. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  2299. // figure out what kind of server we are
  2300. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETSERVERTYPE, (LPARAM)&sfType);
  2301. GetServerProps(sfType, &pProps);
  2302. Assert(pProps);
  2303. fIMAP = (sfType == SERVER_IMAP);
  2304. fHTTPMail = (SERVER_HTTPMAIL == sfType);
  2305. // Init
  2306. ZeroMemory(&s_rAuth, sizeof(SMTPAUTHINFO));
  2307. if (!fHTTPMail)
  2308. {
  2309. // Smtp Auth Type
  2310. Assert(sizeof(s_rAuth.authtype) == sizeof(DWORD));
  2311. if (FAILED(pAcct->GetPropDw(AP_SMTP_USE_SICILY, (LPDWORD)&s_rAuth.authtype)))
  2312. s_rAuth.authtype = SMTP_AUTH_NONE;
  2313. // If smtp auth...
  2314. if (SMTP_AUTH_NONE != s_rAuth.authtype)
  2315. {
  2316. // Check the button
  2317. CheckDlgButton(hwnd, IDC_SMTP_SASL, BST_CHECKED);
  2318. if (SUCCEEDED(pAcct->GetPropSz(AP_SMTP_USERNAME, sz, ARRAYSIZE(sz))))
  2319. StrCpyN(s_rAuth.szUserName, sz, ARRAYSIZE(s_rAuth.szUserName));
  2320. if (SUCCEEDED(pAcct->GetPropDw(AP_SMTP_PROMPT_PASSWORD, &dw)))
  2321. s_rAuth.fPromptPassword = dw;
  2322. if (SUCCEEDED(pAcct->GetPropSz(AP_SMTP_PASSWORD, sz, ARRAYSIZE(sz))))
  2323. StrCpyN(s_rAuth.szPassword, sz, ARRAYSIZE(s_rAuth.szPassword));
  2324. }
  2325. else
  2326. EnableWindow(GetDlgItem(hwnd, IDC_SMTPLOGON), FALSE);
  2327. }
  2328. if (!!(pAcct->m_dwDlgFlags & ACCTDLG_NO_IMAP) && !fIMAP)
  2329. {
  2330. ShowWindow(GetDlgItem(hwnd, idcPOP_OR_IMAP), SW_HIDE);
  2331. ShowWindow(GetDlgItem(hwnd, IDC_SERVER_STATIC), SW_HIDE);
  2332. ShowWindow(GetDlgItem(hwnd, IDC_SERVER1_STATIC), SW_HIDE);
  2333. }
  2334. if (!fHTTPMail)
  2335. {
  2336. LoadString(g_hInstRes, fIMAP ? idsIMAP : idsPOP, sz, ARRAYSIZE(sz));
  2337. SetDlgItemText(hwnd, idcPOP_OR_IMAP, sz);
  2338. }
  2339. // Set incoming Server
  2340. InitAcctPropEdit(GetDlgItem(hwnd, IDC_POP3_EDIT), pAcct, pProps->server, CCHMAX_SERVER_NAME - 1);
  2341. if (!fHTTPMail)
  2342. {
  2343. if (fIMAP)
  2344. LoadString(g_hInstRes, idsIncomingMailIMAP, sz, ARRAYSIZE(sz));
  2345. else
  2346. LoadString(g_hInstRes, idsIncomingMailPOP, sz, ARRAYSIZE(sz));
  2347. SetWindowText(GetDlgItem(hwnd, IDC_IN_MAIL_STATIC), sz);
  2348. }
  2349. if (!fHTTPMail)
  2350. {
  2351. // Set Smtp Server
  2352. InitAcctPropEdit(GetDlgItem(hwnd, IDC_SMTP_EDIT), pAcct, AP_SMTP_SERVER, CCHMAX_SERVER_NAME - 1);
  2353. }
  2354. if (!fHTTPMail)
  2355. {
  2356. // If Saving password
  2357. if (SUCCEEDED(pAcct->GetPropDw(pProps->useSicily, &dw)) && dw)
  2358. CheckDlgButton(hwnd, IDC_LOGONSSPI_CHECK, BST_CHECKED);
  2359. }
  2360. if (SUCCEEDED(pAcct->GetPropSz(pProps->userName, sz, ARRAYSIZE(sz))))
  2361. SetDlgItemText(hwnd, IDC_ACCTNAME_EDIT, sz);
  2362. if (SUCCEEDED(pAcct->GetPropSz(pProps->password, sz, ARRAYSIZE(sz))))
  2363. SetDlgItemText(hwnd, IDC_ACCTPASS_EDIT, sz);
  2364. if (FAILED(pAcct->GetPropDw(pProps->promptPassword, &dwPromptForPassword)))
  2365. dwPromptForPassword = 0;
  2366. CheckDlgButton(hwnd, IDC_REMEMBER_PASSWORD, dwPromptForPassword ? BST_UNCHECKED : BST_CHECKED);
  2367. // Enable/Disable account windows
  2368. Server_EnableLogonWindows(hwnd, TRUE);
  2369. hwndT = GetDlgItem(hwnd, IDC_ACCTNAME_EDIT);
  2370. SetIntlFont(hwndT);
  2371. SendMessage(hwndT, EM_LIMITTEXT, CCHMAX_USERNAME - 1, 0L);
  2372. if (fHTTPMail)
  2373. {
  2374. GetWindowText(hwndT, szPreviousLoginName, CCHMAX_ACCT_PROP_SZ);
  2375. }
  2376. SendDlgItemMessage(hwnd, IDC_ACCTPASS_EDIT, EM_LIMITTEXT, CCHMAX_PASSWORD - 1, 0L);
  2377. if (SUCCEEDED(pAcct->GetPropDw(AP_SERVER_READ_ONLY, &dw)) && dw)
  2378. {
  2379. EnableWindow(GetDlgItem(hwnd, IDC_POP3_EDIT), FALSE);
  2380. EnableWindow(GetDlgItem(hwnd, IDC_SMTP_EDIT), FALSE);
  2381. }
  2382. PropSheet_QuerySiblings(GetParent(hwnd), SM_INITIALIZED, PAGE_SERVER);
  2383. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  2384. return (TRUE);
  2385. case WM_HELP:
  2386. case WM_CONTEXTMENU:
  2387. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapMailSvr));
  2388. case WM_COMMAND:
  2389. switch(GET_WM_COMMAND_ID(wParam, lParam))
  2390. {
  2391. case IDC_LOGONSSPI_CHECK:
  2392. Server_EnableLogonWindows(hwnd, TRUE);
  2393. MarkPageDirty(hwnd, PAGE_SERVER);
  2394. break;
  2395. case IDC_REMEMBER_PASSWORD:
  2396. fEnable = IsDlgButtonChecked(hwnd, IDC_REMEMBER_PASSWORD);
  2397. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), fEnable);
  2398. MarkPageDirty(hwnd, PAGE_SERVER);
  2399. break;
  2400. case IDC_SMTP_SASL:
  2401. MarkPageDirty(hwnd, PAGE_SERVER);
  2402. EnableWindow(GetDlgItem(hwnd, IDC_SMTPLOGON), IsDlgButtonChecked(hwnd, IDC_SMTP_SASL));
  2403. if (!IsDlgButtonChecked(hwnd, IDC_SMTP_SASL) && SMTP_AUTH_NONE != s_rAuth.authtype)
  2404. {
  2405. s_rAuth.authtype = SMTP_AUTH_NONE;
  2406. s_rAuth.fDirty = TRUE;
  2407. }
  2408. else if (IsDlgButtonChecked(hwnd, IDC_SMTP_SASL) && SMTP_AUTH_NONE == s_rAuth.authtype)
  2409. {
  2410. s_rAuth.authtype = SMTP_AUTH_USE_POP3ORIMAP_SETTINGS;
  2411. s_rAuth.fDirty = TRUE;
  2412. }
  2413. break;
  2414. case IDC_SMTPLOGON:
  2415. if (IDOK == DialogBoxParam(g_hInstRes, MAKEINTRESOURCE(iddSmtpServerLogon), hwnd, SmtpLogonSettingsDlgProc, (LPARAM)&s_rAuth))
  2416. MarkPageDirty(hwnd, PAGE_SERVER);
  2417. break;
  2418. default:
  2419. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  2420. MarkPageDirty(hwnd, PAGE_SERVER);
  2421. break;
  2422. }
  2423. break;
  2424. case WM_NOTIFY:
  2425. pnmhdr = (NMHDR *)lParam;
  2426. switch (pnmhdr->code)
  2427. {
  2428. case PSN_APPLY:
  2429. // BEGIN validation
  2430. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETSERVERTYPE, (LPARAM)&sfType);
  2431. GetServerProps(sfType, &pProps);
  2432. Assert(pProps);
  2433. fHTTPMail = (SERVER_HTTPMAIL == sfType);
  2434. if (!fHTTPMail)
  2435. {
  2436. hwndT = GetDlgItem(hwnd, IDC_SMTP_EDIT);
  2437. if (!ValidateServerName(hwnd, hwndT, pAcct, AP_SMTP_SERVER, &idsError, pnmhdr->code == PSN_APPLY))
  2438. return(InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_Servers));
  2439. }
  2440. // gregfrie review (handle httpmail)
  2441. hwndT = GetDlgItem(hwnd, IDC_POP3_EDIT);
  2442. if (!ValidateServerName(hwnd, hwndT, pAcct,
  2443. pProps->server, &idsError, pnmhdr->code == PSN_APPLY))
  2444. return(InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_Servers));
  2445. if (!ValidateLogonSettings(hwnd, pAcct->m_dwDlgFlags, &hwndT, &idsError))
  2446. return(InvalidAcctProp(hwnd, hwndT, idsError, iddMailSvrProp_Servers));
  2447. if (fHTTPMail && !fWarnDomainName(hwnd, pAcct->m_dwDlgFlags, szPreviousLoginName))
  2448. {
  2449. //return (PSNRET_INVALID_NOCHANGEPAGE);
  2450. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  2451. return(TRUE);
  2452. }
  2453. // END validation
  2454. if (!fHTTPMail)
  2455. {
  2456. // Save SMTP Auth Info
  2457. if (s_rAuth.fDirty)
  2458. {
  2459. // Save Authentication Type
  2460. pAcct->SetPropDw(AP_SMTP_USE_SICILY, s_rAuth.authtype);
  2461. // Clear user name and password
  2462. pAcct->SetProp(AP_SMTP_PROMPT_PASSWORD, NULL, 0);
  2463. pAcct->SetProp(AP_SMTP_PASSWORD, NULL, 0);
  2464. Assert(SMTP_AUTH_USE_SMTP_SETTINGS == s_rAuth.authtype ? !FIsEmptyA(s_rAuth.szUserName) : TRUE);
  2465. pAcct->SetPropSz(AP_SMTP_USERNAME, s_rAuth.szUserName);
  2466. pAcct->SetPropDw(AP_SMTP_PROMPT_PASSWORD, s_rAuth.fPromptPassword);
  2467. if (FALSE == s_rAuth.fPromptPassword)
  2468. pAcct->SetPropSz(AP_SMTP_PASSWORD, s_rAuth.szPassword);
  2469. }
  2470. }
  2471. if (!fHTTPMail)
  2472. {
  2473. hwndT = GetDlgItem(hwnd, IDC_SMTP_EDIT);
  2474. GetServerName(hwndT, pAcct, AP_SMTP_SERVER);
  2475. }
  2476. hwndT = GetDlgItem(hwnd, IDC_POP3_EDIT);
  2477. GetServerName(hwndT, pAcct, pProps->server);
  2478. // gregfrie review (httpmail)
  2479. GetLogonSettings(hwnd, pAcct, TRUE,
  2480. (sfType == SERVER_IMAP) ? SRV_IMAP : (sfType == SERVER_HTTPMAIL) ? SRV_HTTPMAIL : SRV_POP3);
  2481. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  2482. dw = PAGE_SERVER;
  2483. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  2484. if (dw == -1)
  2485. {
  2486. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  2487. return(TRUE);
  2488. }
  2489. break;
  2490. }
  2491. return(TRUE);
  2492. }
  2493. return (FALSE);
  2494. }
  2495. void UpdateIncomingMailControls(HWND hwnd, SERVER_TYPE sfType, DWORD dwDlgFlags)
  2496. {
  2497. TCHAR sz[CCHMAX_STRINGRES];
  2498. int sw;
  2499. BOOL fIMAP;
  2500. Assert(sfType == SERVER_MAIL || sfType == SERVER_IMAP);
  2501. fIMAP = sfType == SERVER_IMAP;
  2502. LoadString(g_hInstRes, fIMAP ? idsIncomingMailIMAP : idsIncomingMailPOP, sz, ARRAYSIZE(sz));
  2503. SetWindowText(GetDlgItem(hwnd, IDC_IN_MAIL_STATIC), sz);
  2504. if (fIMAP)
  2505. {
  2506. ShowWindow(GetDlgItem(hwnd, IDC_STATIC6), SW_HIDE); // "Delivery" text
  2507. ShowWindow(GetDlgItem(hwnd, IDC_STATIC7), SW_HIDE); // Horizontal line
  2508. }
  2509. else
  2510. {
  2511. LoadString(g_hInstRes, idsDelivery, sz, ARRAYSIZE(sz));
  2512. SetWindowText(GetDlgItem(hwnd, IDC_STATIC6), sz);
  2513. }
  2514. ShowWindow(GetDlgItem(hwnd, IDC_LEAVE_CHECK), fIMAP ? SW_HIDE : SW_SHOW);
  2515. sw = (fIMAP || !!(dwDlgFlags & ACCTDLG_NO_REMOVEAFTER)) ? SW_HIDE : SW_SHOW;
  2516. ShowWindow(GetDlgItem(hwnd, IDC_REMOVE_CHECK), sw);
  2517. ShowWindow(GetDlgItem(hwnd, IDC_REMOVE_EDIT), sw);
  2518. ShowWindow(GetDlgItem(hwnd, IDC_REMOVE_SPIN), sw);
  2519. ShowWindow(GetDlgItem(hwnd, IDC_OPIE), sw);
  2520. ShowWindow(GetDlgItem(hwnd, IDC_REMOVEDELETE_CHECK), (fIMAP || !!(dwDlgFlags & ACCTDLG_NO_REMOVEDELETE)) ? SW_HIDE : SW_SHOW);
  2521. }
  2522. void EnableDeliveryControls(HWND hwnd)
  2523. {
  2524. BOOL fEnable;
  2525. fEnable = IsDlgButtonChecked(hwnd, IDC_LEAVE_CHECK);
  2526. EnableWindow(GetDlgItem(hwnd, IDC_OPIE), fEnable);
  2527. EnableWindow(GetDlgItem(hwnd, IDC_REMOVEDELETE_CHECK), fEnable);
  2528. EnableWindow(GetDlgItem(hwnd, IDC_REMOVE_CHECK), fEnable);
  2529. if (fEnable)
  2530. fEnable = IsDlgButtonChecked(hwnd, IDC_REMOVE_CHECK);
  2531. EnableWindow(GetDlgItem(hwnd, IDC_REMOVE_EDIT), fEnable);
  2532. EnableWindow(GetDlgItem(hwnd, IDC_REMOVE_SPIN), fEnable);
  2533. }
  2534. void EnableUseDefaultButton(HWND hwnd, SERVER_TYPE sfType)
  2535. {
  2536. BOOL fSecure, fTrans, fEnable;
  2537. DWORD dw;
  2538. Assert(sfType == SERVER_MAIL || sfType == SERVER_IMAP);
  2539. fSecure = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_SMTP_BUTTON);
  2540. dw = GetDlgItemInt(hwnd, IDC_SMTP_PORT_EDIT, &fTrans, FALSE);
  2541. fEnable = (!fTrans || (fSecure ? (dw != DEF_SSMTPPORT) : (dw != DEF_SMTPPORT)));
  2542. if (!fEnable)
  2543. {
  2544. fSecure = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_POP3_BUTTON);
  2545. dw = GetDlgItemInt(hwnd, IDC_POP3_PORT_EDIT, &fTrans, FALSE);
  2546. if (sfType == SERVER_IMAP)
  2547. fEnable = (!fTrans || (fSecure ? (dw != DEF_SIMAPPORT) : (dw != DEF_IMAPPORT)));
  2548. else
  2549. fEnable = (!fTrans || (fSecure ? (dw != DEF_SPOP3PORT) : (dw != DEF_POP3PORT)));
  2550. }
  2551. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON), fEnable);
  2552. }
  2553. const static HELPMAP g_rgCtxMapMailAdv[] = {
  2554. {IDC_SMTP_PORT_EDIT, IDH_MAIL_SERV_ADV_OUT_PORT},
  2555. {IDC_POP3_PORT_EDIT, IDH_MAIL_SERV_ADV_INC_PORT},
  2556. {IDC_IN_MAIL_STATIC, IDH_MAIL_SERV_ADV_INC_PORT},
  2557. {IDC_USEDEFAULTS_BUTTON, IDH_NEWS_SERV_ADV_USE_DEFAULTS},
  2558. {IDC_SECURECONNECT_SMTP_BUTTON, IDH_MAIL_ADV_REQ_SSL},
  2559. {IDC_SECURECONNECT_POP3_BUTTON, IDH_MAIL_ADV_REQ_SSL},
  2560. {IDC_TIMEOUT_SLIDER, IDH_MAIL_SERV_ADV_TIMEOUT},
  2561. {IDC_TIMEOUT_STATIC, IDH_MAIL_SERV_ADV_TIMEOUT},
  2562. {IDC_LEAVE_CHECK, IDH_MAIL_SERV_ADV_LEAVE_SERVER_COPY},
  2563. {IDC_REMOVE_CHECK, IDH_MAIL_SERV_ADV_REMOVE_AFTER5},
  2564. {IDC_REMOVE_EDIT, IDH_MAIL_SERV_ADV_REMOVE_AFTER5},
  2565. {IDC_REMOVE_SPIN, IDH_MAIL_SERV_ADV_REMOVE_AFTER5},
  2566. {IDC_OPIE, IDH_MAIL_SERV_ADV_REMOVE_AFTER5},
  2567. {IDC_REMOVEDELETE_CHECK, IDH_MAIL_SERV_ADV_REMOVE_WHEN_DELETED},
  2568. {IDC_SPLIT_CHECK, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  2569. {IDC_SPLIT_EDIT, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  2570. {IDC_SPLIT_SPIN, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  2571. {IDC_SPLIT_STATIC, IDH_NEWSMAIL_SEND_ADVSET_BREAK_UP},
  2572. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  2573. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  2574. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  2575. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  2576. {IDC_STATIC4, IDH_INETCOMM_GROUPBOX},
  2577. {IDC_STATIC5, IDH_INETCOMM_GROUPBOX},
  2578. {IDC_STATIC6, IDH_INETCOMM_GROUPBOX},
  2579. {IDC_STATIC7, IDH_INETCOMM_GROUPBOX},
  2580. {0, 0}};
  2581. INT_PTR CALLBACK MailServer_AdvancedDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,
  2582. LPARAM lParam)
  2583. {
  2584. NMHDR *pnmhdr;
  2585. TCHAR sz[MAX_PATH];
  2586. DWORD dw, dwPortSmtp, dwPortIn, dwRemove, dwSplit;
  2587. WORD code, id;
  2588. SERVER_TYPE sfType;
  2589. HWND hwndT;
  2590. BOOL fTrans, fSecure, fEnable, flag, fIMAP;
  2591. CAccount *pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  2592. switch (uMsg)
  2593. {
  2594. case WM_INITDIALOG:
  2595. // Get the ServerParams and store them in our extra bytes
  2596. pAcct = (CAccount *)((PROPSHEETPAGE *) lParam)->lParam;
  2597. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  2598. SendDlgItemMessage(hwnd, IDC_POP3_PORT_EDIT, EM_LIMITTEXT, PORT_CCHMAX, 0);
  2599. SendDlgItemMessage(hwnd, IDC_SMTP_PORT_EDIT, EM_LIMITTEXT, PORT_CCHMAX, 0);
  2600. // figure out what kind of server we are
  2601. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETSERVERTYPE, (LPARAM)&sfType);
  2602. Assert(sfType == SERVER_MAIL || sfType == SERVER_IMAP);
  2603. fIMAP = sfType == SERVER_IMAP;
  2604. UpdateIncomingMailControls(hwnd, sfType, pAcct->m_dwDlgFlags);
  2605. // incoming server Secure connect
  2606. if (FAILED(pAcct->GetPropDw(fIMAP ? AP_IMAP_SSL : AP_POP3_SSL, (LPDWORD)&fSecure)))
  2607. fSecure = FALSE; // default
  2608. CheckDlgButton(hwnd, IDC_SECURECONNECT_POP3_BUTTON, fSecure);
  2609. // incoming server Port
  2610. if (FAILED(pAcct->GetPropDw(fIMAP ? AP_IMAP_PORT : AP_POP3_PORT, &dw)))
  2611. {
  2612. // default
  2613. if (fSecure)
  2614. dw = fIMAP ? DEF_SIMAPPORT : DEF_SPOP3PORT;
  2615. else
  2616. dw = fIMAP ? DEF_IMAPPORT : DEF_POP3PORT;
  2617. }
  2618. SetDlgItemInt(hwnd, IDC_POP3_PORT_EDIT, dw, FALSE);
  2619. // SMTP Secure connect
  2620. if (FAILED(pAcct->GetPropDw(AP_SMTP_SSL, (LPDWORD) &fSecure)))
  2621. fSecure = FALSE; // default
  2622. CheckDlgButton(hwnd, IDC_SECURECONNECT_SMTP_BUTTON, fSecure);
  2623. // SMTP Port
  2624. if (FAILED(pAcct->GetPropDw(AP_SMTP_PORT, &dw)))
  2625. dw = fSecure ? DEF_SSMTPPORT : DEF_SMTPPORT; // default
  2626. SetDlgItemInt(hwnd, IDC_SMTP_PORT_EDIT, dw, FALSE);
  2627. EnableUseDefaultButton(hwnd, sfType);
  2628. // Server Timeout
  2629. dw = 0;
  2630. pAcct->GetPropDw(AP_SMTP_TIMEOUT, &dw);
  2631. InitTimeoutSlider(GetDlgItem(hwnd, IDC_TIMEOUT_SLIDER),
  2632. GetDlgItem(hwnd, IDC_TIMEOUT_STATIC), dw);
  2633. // Leave on Server
  2634. if (FAILED(pAcct->GetPropDw(AP_POP3_LEAVE_ON_SERVER, &dw)))
  2635. dw = FALSE; // default
  2636. CheckDlgButton(hwnd, IDC_LEAVE_CHECK, dw);
  2637. if (!!(pAcct->m_dwDlgFlags & ACCTDLG_NO_REMOVEAFTER))
  2638. {
  2639. ShowWindow(GetDlgItem(hwnd, IDC_REMOVE_CHECK), SW_HIDE);
  2640. ShowWindow(GetDlgItem(hwnd, IDC_REMOVE_EDIT), SW_HIDE);
  2641. ShowWindow(GetDlgItem(hwnd, IDC_REMOVE_SPIN), SW_HIDE);
  2642. ShowWindow(GetDlgItem(hwnd, IDC_OPIE), SW_HIDE);
  2643. }
  2644. // Remove from Server after xxx days
  2645. dw = OPTION_OFF; // default
  2646. if (SUCCEEDED(pAcct->GetPropDw(AP_POP3_REMOVE_EXPIRED, (LPDWORD)&flag)) && flag)
  2647. pAcct->GetPropDw(AP_POP3_EXPIRE_DAYS, &dw);
  2648. InitCheckCounter(dw, hwnd, IDC_REMOVE_CHECK, IDC_REMOVE_EDIT, IDC_REMOVE_SPIN,
  2649. EXPIRE_MIN, EXPIRE_MAX, EXPIRE_DEFAULT);
  2650. if (!!(pAcct->m_dwDlgFlags & ACCTDLG_NO_REMOVEDELETE))
  2651. ShowWindow(GetDlgItem(hwnd, IDC_REMOVEDELETE_CHECK), SW_HIDE);
  2652. // Remove when deleted locally
  2653. if (FAILED(pAcct->GetPropDw(AP_POP3_REMOVE_DELETED, &dw)))
  2654. dw = FALSE; // default
  2655. CheckDlgButton(hwnd, IDC_REMOVEDELETE_CHECK, dw);
  2656. EnableDeliveryControls(hwnd);
  2657. if (!!(pAcct->m_dwDlgFlags & ACCTDLG_NO_BREAKMESSAGES))
  2658. {
  2659. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_GROUPBOX), SW_HIDE);
  2660. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_CHECK), SW_HIDE);
  2661. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_EDIT), SW_HIDE);
  2662. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_SPIN), SW_HIDE);
  2663. ShowWindow(GetDlgItem(hwnd, IDC_SPLIT_STATIC), SW_HIDE);
  2664. }
  2665. // Break Message Size
  2666. dw = OPTION_OFF; // default
  2667. if (SUCCEEDED(pAcct->GetPropDw(AP_SMTP_SPLIT_MESSAGES, (LPDWORD)&flag)) && flag)
  2668. pAcct->GetPropDw(AP_SMTP_SPLIT_SIZE, (LPDWORD)&dw);
  2669. InitCheckCounter(dw, hwnd, IDC_SPLIT_CHECK, IDC_SPLIT_EDIT, IDC_SPLIT_SPIN,
  2670. BREAKSIZE_MIN, BREAKSIZE_MAX, DEF_BREAKSIZE);
  2671. PropSheet_QuerySiblings(GetParent(hwnd), SM_INITIALIZED, PAGE_ADV);
  2672. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  2673. return (TRUE);
  2674. case WM_HELP:
  2675. case WM_CONTEXTMENU:
  2676. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapMailAdv));
  2677. case WM_HSCROLL:
  2678. // Update the text beside the slider
  2679. SetTimeoutString(GetDlgItem(hwnd, IDC_TIMEOUT_STATIC),
  2680. (UINT) (SendMessage((HWND) lParam, TBM_GETPOS, 0, 0)));
  2681. MarkPageDirty(hwnd, PAGE_ADV);
  2682. return (TRUE);
  2683. case WM_COMMAND:
  2684. // Any change to the edit controls would cause the "Apply" button
  2685. // to enable.
  2686. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETSERVERTYPE, (LPARAM)&sfType);
  2687. code = GET_WM_COMMAND_CMD(wParam, lParam);
  2688. id = GET_WM_COMMAND_ID(wParam, lParam);
  2689. switch (id)
  2690. {
  2691. case IDC_SMTP_PORT_EDIT:
  2692. case IDC_POP3_PORT_EDIT:
  2693. if (code == EN_CHANGE)
  2694. {
  2695. EnableUseDefaultButton(hwnd, sfType);
  2696. MarkPageDirty(hwnd, PAGE_ADV);
  2697. }
  2698. break;
  2699. case IDC_SECURECONNECT_POP3_BUTTON:
  2700. case IDC_SECURECONNECT_SMTP_BUTTON:
  2701. case IDC_USEDEFAULTS_BUTTON:
  2702. if (id != IDC_SECURECONNECT_POP3_BUTTON)
  2703. {
  2704. fSecure = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_SMTP_BUTTON);
  2705. SetDlgItemInt(hwnd, IDC_SMTP_PORT_EDIT, fSecure ? DEF_SSMTPPORT : DEF_SMTPPORT, FALSE);
  2706. }
  2707. if (id != IDC_SECURECONNECT_SMTP_BUTTON)
  2708. {
  2709. fSecure = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_POP3_BUTTON);
  2710. if (sfType == SERVER_MAIL)
  2711. dw = fSecure ? DEF_SPOP3PORT : DEF_POP3PORT;
  2712. else
  2713. dw = fSecure ? DEF_SIMAPPORT : DEF_IMAPPORT;
  2714. SetDlgItemInt(hwnd, IDC_POP3_PORT_EDIT, dw, FALSE);
  2715. }
  2716. EnableUseDefaultButton(hwnd, sfType);
  2717. MarkPageDirty(hwnd, PAGE_ADV);
  2718. break;
  2719. case IDC_LEAVE_CHECK:
  2720. case IDC_REMOVE_CHECK:
  2721. EnableDeliveryControls(hwnd);
  2722. // fall through...
  2723. case IDC_REMOVEDELETE_CHECK:
  2724. MarkPageDirty(hwnd, PAGE_ADV);
  2725. break;
  2726. case IDC_SPLIT_CHECK:
  2727. fEnable = IsDlgButtonChecked(hwnd, IDC_SPLIT_CHECK);
  2728. EnableWindow(GetDlgItem(hwnd, IDC_SPLIT_EDIT), fEnable);
  2729. EnableWindow(GetDlgItem(hwnd, IDC_SPLIT_SPIN), fEnable);
  2730. MarkPageDirty(hwnd, PAGE_ADV);
  2731. break;
  2732. case IDC_SPLIT_EDIT:
  2733. case IDC_REMOVE_EDIT:
  2734. if (code == EN_CHANGE)
  2735. MarkPageDirty(hwnd, PAGE_ADV);
  2736. break;
  2737. }
  2738. return (TRUE);
  2739. case WM_NOTIFY:
  2740. pnmhdr = (NMHDR *)lParam;
  2741. switch (pnmhdr->code)
  2742. {
  2743. case PSN_APPLY:
  2744. // BEGIN validation
  2745. // figure out what kind of server we are
  2746. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETSERVERTYPE, (LPARAM)&sfType);
  2747. Assert(sfType == SERVER_MAIL || sfType == SERVER_IMAP);
  2748. fIMAP = sfType == SERVER_IMAP;
  2749. dwPortSmtp = GetDlgItemInt(hwnd, IDC_SMTP_PORT_EDIT, &fTrans, FALSE);
  2750. if (!fTrans || dwPortSmtp == 0)
  2751. {
  2752. hwndT = GetDlgItem(hwnd, IDC_SMTP_PORT_EDIT);
  2753. return(InvalidAcctProp(hwnd, hwndT, idsErrPortNum, iddMailSvrProp_Advanced));
  2754. }
  2755. dwPortIn = GetDlgItemInt(hwnd, IDC_POP3_PORT_EDIT, &fTrans, FALSE);
  2756. if (!fTrans || dwPortIn == 0)
  2757. {
  2758. hwndT = GetDlgItem(hwnd, IDC_POP3_PORT_EDIT);
  2759. return(InvalidAcctProp(hwnd, hwndT, idsErrPortNum, iddMailSvrProp_Advanced));
  2760. }
  2761. dwRemove = 0;
  2762. if (!fIMAP)
  2763. {
  2764. if (IsDlgButtonChecked(hwnd, IDC_LEAVE_CHECK) &&
  2765. IsDlgButtonChecked(hwnd, IDC_REMOVE_CHECK))
  2766. {
  2767. dwRemove = GetDlgItemInt(hwnd, IDC_REMOVE_EDIT, &fTrans, FALSE);
  2768. if (!fTrans || dwRemove < EXPIRE_MIN || dwRemove > EXPIRE_MAX)
  2769. {
  2770. hwndT = GetDlgItem(hwnd, IDC_REMOVE_EDIT);
  2771. return(InvalidAcctProp(hwnd, hwndT, idsEnterRemoveFromServerDays, iddMailSvrProp_Advanced));
  2772. }
  2773. }
  2774. }
  2775. dwSplit = 0;
  2776. if (IsDlgButtonChecked(hwnd, IDC_SPLIT_CHECK))
  2777. {
  2778. dwSplit = GetDlgItemInt(hwnd, IDC_SPLIT_EDIT, &fTrans, FALSE);
  2779. if (!fTrans || dwSplit < BREAKSIZE_MIN || dwSplit > BREAKSIZE_MAX)
  2780. {
  2781. hwndT = GetDlgItem(hwnd, IDC_SPLIT_EDIT);
  2782. return(InvalidAcctProp(hwnd, hwndT, idsEnterBreakSize, iddMailSvrProp_Advanced));
  2783. }
  2784. }
  2785. // END validation
  2786. pAcct->SetPropDw(AP_SMTP_PORT, dwPortSmtp);
  2787. if (fIMAP)
  2788. {
  2789. HRESULT hrTemp;
  2790. hrTemp = pAcct->GetPropDw(AP_IMAP_PORT, &dw);
  2791. if (FAILED(hrTemp) || dw != dwPortIn)
  2792. {
  2793. pAcct-> SetPropDw(AP_IMAP_PORT, dwPortIn);
  2794. if (FAILED(pAcct->GetPropDw(AP_IMAP_DIRTY, &dw)))
  2795. dw = 0;
  2796. dw |= IMAP_FLDRLIST_DIRTY;
  2797. pAcct->SetPropDw(AP_IMAP_DIRTY, dw);
  2798. }
  2799. }
  2800. else
  2801. {
  2802. pAcct->SetPropDw(AP_POP3_PORT, dwPortIn);
  2803. dw = IsDlgButtonChecked(hwnd, IDC_LEAVE_CHECK);
  2804. pAcct->SetPropDw(AP_POP3_LEAVE_ON_SERVER, dw);
  2805. if (dw != 0)
  2806. {
  2807. dw = IsDlgButtonChecked(hwnd, IDC_REMOVE_CHECK);
  2808. pAcct->SetPropDw(AP_POP3_REMOVE_EXPIRED, dw);
  2809. if (dw != 0)
  2810. {
  2811. Assert(dwRemove != 0);
  2812. pAcct->SetPropDw(AP_POP3_EXPIRE_DAYS, dwRemove);
  2813. }
  2814. dw = IsDlgButtonChecked(hwnd, IDC_REMOVEDELETE_CHECK);
  2815. pAcct->SetPropDw(AP_POP3_REMOVE_DELETED, dw);
  2816. }
  2817. }
  2818. dw = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_POP3_BUTTON);
  2819. pAcct->SetPropDw(fIMAP ? AP_IMAP_SSL : AP_POP3_SSL, dw);
  2820. dw = GetTimeoutFromSlider(GetDlgItem(hwnd, IDC_TIMEOUT_SLIDER));
  2821. pAcct->SetPropDw(AP_SMTP_TIMEOUT, dw);
  2822. pAcct->SetPropDw(fIMAP ? AP_IMAP_TIMEOUT : AP_POP3_TIMEOUT, dw);
  2823. dw = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_SMTP_BUTTON);
  2824. pAcct->SetPropDw(AP_SMTP_SSL, dw);
  2825. dw = IsDlgButtonChecked(hwnd, IDC_SPLIT_CHECK);
  2826. pAcct->SetPropDw(AP_SMTP_SPLIT_MESSAGES, dw);
  2827. if (dw != 0)
  2828. {
  2829. Assert(dwSplit != 0);
  2830. pAcct->SetPropDw(AP_SMTP_SPLIT_SIZE, dwSplit);
  2831. }
  2832. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  2833. dw = PAGE_ADV;
  2834. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  2835. if (dw == -1)
  2836. {
  2837. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  2838. return(TRUE);
  2839. }
  2840. break;
  2841. }
  2842. return (TRUE);
  2843. }
  2844. return (FALSE);
  2845. }
  2846. BOOL FIsDuplicateIMAPSpecialFldrs(LPSTR pszSentItems, LPSTR pszDrafts,
  2847. HWND hwnd, HWND *phwndOffender, int *piErrorStr)
  2848. {
  2849. Assert(NULL != phwndOffender);
  2850. Assert(NULL != piErrorStr);
  2851. // First compare both special folders to INBOX
  2852. if (0 == lstrcmpi(c_szInbox, pszSentItems))
  2853. {
  2854. *phwndOffender = GetDlgItem(hwnd, IDC_IMAPSENT_EDIT);
  2855. *piErrorStr = idsIMAPSpecialFldr_InboxDup;
  2856. return TRUE;
  2857. }
  2858. if (0 == lstrcmpi(c_szInbox, pszDrafts))
  2859. {
  2860. *phwndOffender = GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT);
  2861. *piErrorStr = idsIMAPSpecialFldr_InboxDup;
  2862. return TRUE;
  2863. }
  2864. // Now compare special folders to each other
  2865. if (0 == lstrcmpi(pszSentItems, pszDrafts))
  2866. {
  2867. *phwndOffender = GetDlgItem(hwnd, IDC_IMAPSENT_EDIT);
  2868. *piErrorStr = idsIMAPSpecialFldr_Duplicate;
  2869. return TRUE;
  2870. }
  2871. // If we reached this point, no problems found
  2872. *phwndOffender = NULL;
  2873. *piErrorStr = 0;
  2874. return FALSE;
  2875. }
  2876. BOOL FContainsHierarchyChars(LPSTR pszFldrName)
  2877. {
  2878. BOOL fSkipByte = FALSE;
  2879. while ('\0' != *pszFldrName)
  2880. {
  2881. if (fSkipByte)
  2882. fSkipByte = FALSE;
  2883. else if (IsDBCSLeadByte(*pszFldrName))
  2884. fSkipByte = TRUE; // Skip next byte (trail byte)
  2885. else
  2886. {
  2887. if ('/' == *pszFldrName || '\\' == *pszFldrName || '.' == *pszFldrName)
  2888. return TRUE;
  2889. }
  2890. // Advance char ptr
  2891. pszFldrName += 1;
  2892. }
  2893. // If we reached this point, no hierarchy chars found
  2894. return FALSE;
  2895. }
  2896. const static HELPMAP g_rgCtxMapIMAP[] = {
  2897. {IDC_ROOT_FOLDER_EDIT, IDH_IMAP_BASE_ROOT},
  2898. {IDC_IMAP_SVRSPECIALFLDRS, 760},
  2899. {IDC_IMAPSENT_EDIT, 765},
  2900. {IDC_IMAPSENT_STATIC, 765},
  2901. {IDC_IMAPDRAFT_EDIT, 770},
  2902. {IDC_IMAPDRAFT_STATIC, 770},
  2903. {IDC_IMAP_POLL_ALL_FOLDERS, 775},
  2904. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  2905. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  2906. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  2907. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  2908. {0, 0}};
  2909. INT_PTR CALLBACK MailServer_IMAPDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2910. {
  2911. NMHDR *pnmhdr;
  2912. TCHAR sz[MAX_PATH];
  2913. DWORD dw, dw2;
  2914. HWND hwndT;
  2915. WORD code, id;
  2916. UINT uiLen;
  2917. CAccount *pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  2918. HRESULT hrTemp;
  2919. switch (uMsg)
  2920. {
  2921. case WM_INITDIALOG:
  2922. // Get the ServerParams and store them in our extra bytes
  2923. pAcct = (CAccount *)((PROPSHEETPAGE *) lParam)->lParam;
  2924. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  2925. // Initialize edit controls
  2926. InitAcctPropEdit(GetDlgItem(hwnd, IDC_ROOT_FOLDER_EDIT), pAcct,
  2927. AP_IMAP_ROOT_FOLDER, CCHMAX_ROOT_FOLDER - 1);
  2928. if (FAILED(pAcct->GetPropDw(AP_IMAP_POLL_ALL_FOLDERS, &dw)))
  2929. dw = TRUE;
  2930. CheckDlgButton(hwnd, IDC_IMAP_POLL_ALL_FOLDERS, dw != 0);
  2931. // Initialize IMAP Special Folder Options IF we have the flag to do so
  2932. if (pAcct->m_dwDlgFlags & ACCTDLG_SHOWIMAPSPECIAL)
  2933. {
  2934. // Init special folder edit controls
  2935. InitAcctPropEdit(GetDlgItem(hwnd, IDC_IMAPSENT_EDIT), pAcct,
  2936. AP_IMAP_SENTITEMSFLDR, CCHMAX_ROOT_FOLDER - 1);
  2937. InitAcctPropEdit(GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT), pAcct,
  2938. AP_IMAP_DRAFTSFLDR, CCHMAX_ROOT_FOLDER - 1);
  2939. // IMAP server-side special folders
  2940. if (FAILED(pAcct->GetPropDw(AP_IMAP_SVRSPECIALFLDRS, &dw)))
  2941. dw = TRUE; // default
  2942. CheckDlgButton(hwnd, IDC_IMAP_SVRSPECIALFLDRS, dw);
  2943. EnableWindow(GetDlgItem(hwnd, IDC_IMAPSENT_EDIT), dw);
  2944. EnableWindow(GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT), dw);
  2945. }
  2946. else
  2947. {
  2948. // Hide all IMAP special folder options
  2949. ShowWindow(GetDlgItem(hwnd, IDC_IMAPSENT_EDIT), SW_HIDE);
  2950. ShowWindow(GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT), SW_HIDE);
  2951. ShowWindow(GetDlgItem(hwnd, IDC_IMAP_SVRSPECIALFLDRS), SW_HIDE);
  2952. ShowWindow(GetDlgItem(hwnd, IDC_STATIC2), SW_HIDE);
  2953. ShowWindow(GetDlgItem(hwnd, IDC_STATIC3), SW_HIDE);
  2954. ShowWindow(GetDlgItem(hwnd, IDC_IMAPSENT_STATIC), SW_HIDE);
  2955. ShowWindow(GetDlgItem(hwnd, IDC_IMAPDRAFT_STATIC), SW_HIDE);
  2956. }
  2957. PropSheet_QuerySiblings(GetParent(hwnd), SM_INITIALIZED, PAGE_IMAP);
  2958. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  2959. return (TRUE);
  2960. case WM_HELP:
  2961. case WM_CONTEXTMENU:
  2962. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapIMAP));
  2963. case WM_COMMAND:
  2964. // Any change to the edit controls would cause the "Apply" button
  2965. // to enable.
  2966. code = GET_WM_COMMAND_CMD(wParam, lParam);
  2967. id = GET_WM_COMMAND_ID(wParam, lParam);
  2968. switch (id)
  2969. {
  2970. //case IDC_IMAP_LISTLSUB:
  2971. case IDC_IMAP_POLL_ALL_FOLDERS:
  2972. MarkPageDirty(hwnd, PAGE_IMAP);
  2973. break;
  2974. case IDC_IMAP_SVRSPECIALFLDRS:
  2975. dw = IsDlgButtonChecked(hwnd, IDC_IMAP_SVRSPECIALFLDRS);
  2976. EnableWindow(GetDlgItem(hwnd, IDC_IMAPSENT_EDIT), dw);
  2977. EnableWindow(GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT), dw);
  2978. MarkPageDirty(hwnd, PAGE_IMAP);
  2979. break;
  2980. case IDC_ROOT_FOLDER_EDIT:
  2981. case IDC_IMAPSENT_EDIT:
  2982. case IDC_IMAPDRAFT_EDIT:
  2983. if (code == EN_CHANGE)
  2984. MarkPageDirty(hwnd, PAGE_IMAP);
  2985. break;
  2986. }
  2987. return (TRUE);
  2988. case WM_NOTIFY:
  2989. pnmhdr = (NMHDR *)lParam;
  2990. switch (pnmhdr->code)
  2991. {
  2992. case PSN_APPLY:
  2993. // BEGIN validation
  2994. // Check IMAP special folder paths
  2995. if (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_IMAP_SVRSPECIALFLDRS))
  2996. {
  2997. TCHAR sz2[MAX_PATH];
  2998. int iErrorStr;
  2999. // Check for 0-length special folder paths
  3000. if (0 == GetDlgItemText(hwnd, IDC_IMAPSENT_EDIT, sz, ARRAYSIZE(sz)) ||
  3001. FIsEmpty(sz))
  3002. {
  3003. hwndT = GetDlgItem(hwnd, IDC_IMAPSENT_EDIT);
  3004. return(InvalidAcctProp(hwnd, hwndT, idsIMAPBlankSpecialFldrs, iddMailSvrProp_IMAP));
  3005. }
  3006. if (0 == GetDlgItemText(hwnd, IDC_IMAPDRAFT_EDIT, sz2, ARRAYSIZE(sz2)) ||
  3007. FIsEmpty(sz))
  3008. {
  3009. hwndT = GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT);
  3010. return(InvalidAcctProp(hwnd, hwndT, idsIMAPBlankSpecialFldrs, iddMailSvrProp_IMAP));
  3011. }
  3012. // Check for duplicate special folder paths: these are not allowed
  3013. // If we got to this point, sz and sz2 are filled with sent items path
  3014. if (FIsDuplicateIMAPSpecialFldrs(sz, sz2, hwnd, &hwndT, &iErrorStr))
  3015. return(InvalidAcctProp(hwnd, hwndT, iErrorStr, iddMailSvrProp_IMAP));
  3016. // Check for hierarchy characters in special folder names
  3017. if (FContainsHierarchyChars(sz))
  3018. {
  3019. hwndT = GetDlgItem(hwnd, IDC_IMAPSENT_EDIT);
  3020. return(InvalidAcctProp(hwnd, hwndT, idsIMAPNoHierarchyChars, iddMailSvrProp_IMAP));
  3021. }
  3022. if (FContainsHierarchyChars(sz2))
  3023. {
  3024. hwndT = GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT);
  3025. return(InvalidAcctProp(hwnd, hwndT, idsIMAPNoHierarchyChars, iddMailSvrProp_IMAP));
  3026. }
  3027. }
  3028. // END validation
  3029. // Save IMAP root folder path, if it changed
  3030. if (0 != SendMessage(GetDlgItem(hwnd, IDC_ROOT_FOLDER_EDIT),
  3031. EM_GETMODIFY, 0, 0))
  3032. {
  3033. dw = GetDlgItemText(hwnd, IDC_ROOT_FOLDER_EDIT, sz, ARRAYSIZE(sz));
  3034. // TODO: figure out if it is a valid folder
  3035. UlStripWhitespace(sz, TRUE, TRUE, &dw);
  3036. pAcct->SetPropSz(AP_IMAP_ROOT_FOLDER, sz);
  3037. SendMessage(GetDlgItem(hwnd, IDC_ROOT_FOLDER_EDIT), EM_SETMODIFY, 0, 0);
  3038. if (FAILED(pAcct->GetPropDw(AP_IMAP_DIRTY, &dw)))
  3039. dw = 0;
  3040. dw |= IMAP_FLDRLIST_DIRTY;
  3041. pAcct->SetPropDw(AP_IMAP_DIRTY, dw);
  3042. }
  3043. dw = IsDlgButtonChecked(hwnd, IDC_IMAP_POLL_ALL_FOLDERS);
  3044. pAcct->SetPropDw(AP_IMAP_POLL_ALL_FOLDERS, dw);
  3045. // Save special folders checkbox
  3046. dw = IsDlgButtonChecked(hwnd, IDC_IMAP_SVRSPECIALFLDRS);
  3047. hrTemp = pAcct->GetPropDw(AP_IMAP_SVRSPECIALFLDRS, &dw2);
  3048. if (FAILED(hrTemp) || dw2 != dw)
  3049. {
  3050. pAcct->SetPropDw(AP_IMAP_SVRSPECIALFLDRS, dw);
  3051. if (FAILED(pAcct->GetPropDw(AP_IMAP_DIRTY, &dw2)))
  3052. dw2 = 0;
  3053. dw2 |= (IMAP_SENTITEMS_DIRTY | IMAP_DRAFTS_DIRTY);
  3054. pAcct->SetPropDw(AP_IMAP_DIRTY, dw2);
  3055. }
  3056. if (dw != 0)
  3057. {
  3058. // Save IMAP Sent Items folder path, if it changed
  3059. if (0 != SendMessage(GetDlgItem(hwnd, IDC_IMAPSENT_EDIT),
  3060. EM_GETMODIFY, 0, 0))
  3061. {
  3062. uiLen = GetDlgItemText(hwnd, IDC_IMAPSENT_EDIT, sz, ARRAYSIZE(sz));
  3063. ImapRemoveTrailingHC(sz, uiLen);
  3064. // TODO: figure out if it is a valid folder
  3065. pAcct->SetPropSz(AP_IMAP_SENTITEMSFLDR, sz);
  3066. SendMessage(GetDlgItem(hwnd, IDC_IMAPSENT_EDIT), EM_SETMODIFY, 0, 0);
  3067. if (FAILED(pAcct->GetPropDw(AP_IMAP_DIRTY, &dw)))
  3068. dw = 0;
  3069. dw |= IMAP_SENTITEMS_DIRTY;
  3070. pAcct->SetPropDw(AP_IMAP_DIRTY, dw);
  3071. }
  3072. // Save IMAP Drafts folder path, if it changed
  3073. if (0 != SendMessage(GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT),
  3074. EM_GETMODIFY, 0, 0))
  3075. {
  3076. uiLen = GetDlgItemText(hwnd, IDC_IMAPDRAFT_EDIT, sz, ARRAYSIZE(sz));
  3077. ImapRemoveTrailingHC(sz, uiLen);
  3078. // TODO: figure out if it is a valid folder
  3079. pAcct->SetPropSz(AP_IMAP_DRAFTSFLDR, sz);
  3080. SendMessage(GetDlgItem(hwnd, IDC_IMAPDRAFT_EDIT), EM_SETMODIFY, 0, 0);
  3081. if (FAILED(pAcct->GetPropDw(AP_IMAP_DIRTY, &dw)))
  3082. dw = 0;
  3083. dw |= IMAP_DRAFTS_DIRTY;
  3084. pAcct->SetPropDw(AP_IMAP_DIRTY, dw);
  3085. }
  3086. }
  3087. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  3088. dw = PAGE_IMAP;
  3089. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  3090. if (dw == -1)
  3091. {
  3092. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  3093. return(TRUE);
  3094. }
  3095. break;
  3096. }
  3097. return (TRUE);
  3098. }
  3099. return (FALSE);
  3100. } // MailServer_IMAPDlgProc
  3101. void ImapRemoveTrailingHC(LPSTR pszPath, UINT uiLen)
  3102. {
  3103. LPSTR pLastChar;
  3104. if (0 == uiLen)
  3105. return;
  3106. pLastChar = pszPath + uiLen - 1;
  3107. while (pLastChar >= pszPath && ('/' == *pLastChar || '\\' == *pLastChar || '.' == *pLastChar))
  3108. {
  3109. *pLastChar = '\0'; // Bye-bye, potential hierarchy char
  3110. pLastChar -= 1;
  3111. } // while
  3112. } // ImapRemoveTrailingHC
  3113. #ifdef DEAD
  3114. BOOL IsValidServerName(TCHAR *sz)
  3115. {
  3116. Assert(sz != NULL);
  3117. // bug 34513
  3118. if (FIsEmpty(sz))
  3119. return(FALSE);
  3120. // Bug #32532 - If the server name is the IP address, ie 157.54.44.183, then
  3121. // don't use this grammar to parse it.
  3122. if (-1 != inet_addr(sz))
  3123. return (TRUE);
  3124. while (*sz != 0)
  3125. {
  3126. if (!IsDBCSLeadByte(*sz))
  3127. {
  3128. if (*sz == _T(' '))
  3129. return(FALSE);
  3130. }
  3131. else
  3132. {
  3133. return(FALSE);
  3134. }
  3135. sz = CharNext(sz);
  3136. }
  3137. return(TRUE);
  3138. }
  3139. #endif // DEAD
  3140. /*
  3141. RFC 1034
  3142. <domain> ::= <subdomain> | " "
  3143. <subdomain> ::= <label> | <subdomain> "." <label>
  3144. <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
  3145. <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
  3146. <let-dig-hyp> ::= <let-dig> | "-"
  3147. <let-dig> ::= <letter> | <digit>
  3148. <letter> ::= any one of the 52 alphabetic characters A through Z
  3149. in upper case and a through z in lower case
  3150. <digit> ::= any one of the ten digits 0 through 9
  3151. */
  3152. #define ST_BOGUS -1
  3153. #define ST_LABEL 0
  3154. #define ST_DASH 1
  3155. #define ST_LD 2
  3156. #define ALPHABET 0
  3157. #define NUMERIC 1
  3158. #define DOT 2
  3159. #define DASH 3
  3160. static const int s_rgSvrState[4][3] =
  3161. {
  3162. // ST_LABEL ST_DASH ST_LD
  3163. // ALPHABET
  3164. {ST_LD, ST_LD, ST_LD},
  3165. // NUMERIC
  3166. {ST_LD, ST_LD, ST_LD},
  3167. // DOT
  3168. {ST_BOGUS, ST_BOGUS, ST_LABEL},
  3169. // DASH
  3170. {ST_BOGUS, ST_DASH, ST_DASH}
  3171. };
  3172. BOOL IsValidServerName(LPSTR sz)
  3173. {
  3174. int state, curr;
  3175. Assert(sz != NULL);
  3176. // bug 34513
  3177. if (FIsEmpty(sz))
  3178. return(FALSE);
  3179. // Bug #32532 - If the server name is the IP address, ie 157.54.44.183, then
  3180. // don't use this grammar to parse it.
  3181. if (-1 != inet_addr(sz))
  3182. return (TRUE);
  3183. state = ST_LABEL;
  3184. while (*sz != 0)
  3185. {
  3186. if (!IsDBCSLeadByte(*sz))
  3187. {
  3188. if (*sz == _T('.'))
  3189. curr = DOT;
  3190. else if (*sz == _T('-'))
  3191. curr = DASH;
  3192. else if ((*sz >= 'A' && *sz <= 'Z') || (*sz >= 'a' && *sz <= 'z'))
  3193. curr = ALPHABET;
  3194. else if (*sz >= '0' && *sz <= '9')
  3195. curr = NUMERIC;
  3196. else
  3197. return(FALSE);
  3198. state = s_rgSvrState[curr][state];
  3199. if (state == ST_BOGUS)
  3200. break;
  3201. }
  3202. else
  3203. {
  3204. state = ST_BOGUS;
  3205. break;
  3206. }
  3207. sz = CharNext(sz);
  3208. }
  3209. return(state == ST_LD);
  3210. }
  3211. HRESULT ValidServerName(LPSTR szServer)
  3212. {
  3213. HRESULT hr;
  3214. int cbT;
  3215. cbT = lstrlen(szServer);
  3216. if (cbT == 0 || cbT >= CCHMAX_SERVER_NAME)
  3217. return(E_InvalidValue);
  3218. if (!IsValidServerName(szServer))
  3219. hr = S_NonStandardValue;
  3220. else
  3221. hr = S_OK;
  3222. return(hr);
  3223. }
  3224. IMNACCTAPI ValidEmailAddressParts(LPSTR lpAddress, LPSTR lpszAcct, DWORD cchSizeAcct, LPSTR lpszDomain, DWORD cchSizeDomain)
  3225. {
  3226. int cbT;
  3227. LPSTR szAddr = lpAddress;
  3228. // Step through the address looking for '@'. If there's an at sign in the middle
  3229. // of a string, this is close enough to being an internet address for me.
  3230. Assert(lpAddress != NULL);
  3231. cbT = lstrlen(lpAddress);
  3232. if (cbT == 0 || cbT >= CCHMAX_EMAIL_ADDRESS)
  3233. return(E_InvalidValue);
  3234. // Can't start with '@'
  3235. if (*lpAddress != '@')
  3236. {
  3237. while (*lpAddress)
  3238. {
  3239. // Internet addresses only allow pure ASCII. No high bits!
  3240. if (IsDBCSLeadByte(*lpAddress) || (*lpAddress & 0x80))
  3241. break;
  3242. if (*lpAddress == '@')
  3243. {
  3244. if (lpszAcct)
  3245. {
  3246. StrCpyN(lpszAcct, szAddr, cchSizeAcct);
  3247. lpszAcct[(lpAddress - szAddr)] = 0;
  3248. }
  3249. if (lpszDomain)
  3250. {
  3251. StrCpyN(lpszDomain, lpAddress +1, cchSizeDomain);
  3252. }
  3253. // Found the at sign. Is there anything following?
  3254. lpAddress++;
  3255. if (!IsValidServerName(lpAddress))
  3256. break;
  3257. else
  3258. return(S_OK);
  3259. }
  3260. lpAddress++;
  3261. }
  3262. }
  3263. return(S_NonStandardValue);
  3264. }
  3265. IMNACCTAPI ValidEmailAddress(LPSTR lpAddress)
  3266. {
  3267. int cbT;
  3268. // Step through the address looking for '@'. If there's an at sign in the middle
  3269. // of a string, this is close enough to being an internet address for me.
  3270. Assert(lpAddress != NULL);
  3271. cbT = lstrlen(lpAddress);
  3272. if (cbT == 0 || cbT >= CCHMAX_EMAIL_ADDRESS)
  3273. return(E_InvalidValue);
  3274. // Can't start with '@'
  3275. if (*lpAddress != '@')
  3276. {
  3277. while (*lpAddress)
  3278. {
  3279. // Internet addresses only allow pure ASCII. No high bits!
  3280. if (IsDBCSLeadByte(*lpAddress) || (*lpAddress & 0x80))
  3281. break;
  3282. if (*lpAddress == '@')
  3283. {
  3284. // Found the at sign. Is there anything following?
  3285. lpAddress++;
  3286. if (!IsValidServerName(lpAddress))
  3287. break;
  3288. else
  3289. return(S_OK);
  3290. }
  3291. lpAddress++;
  3292. }
  3293. }
  3294. return(S_NonStandardValue);
  3295. }
  3296. const static HELPMAP g_rgCtxMapLdapGen[] = {
  3297. {IDC_ACCOUNT_EDIT, IDH_WABLDAP_DIRSSERV_FRIENDLY_NAME},
  3298. {IDC_SERVER_EDIT, IDH_WABLDAP_DIRSSERV_NAME},
  3299. {IDC_LOGON_CHECK, IDH_INETCOMM_SERVER_REQ_LOGON},
  3300. {IDC_LOGONSSPI_CHECK, IDH_WABLDAP_DIRSSERV_AUTH_SICILY},
  3301. {IDC_ACCTNAME_EDIT, IDH_WABLDAP_DIRSSERV_AUTH_PASS_UNAME},
  3302. {IDC_ACCTNAME_STATIC, IDH_WABLDAP_DIRSSERV_AUTH_PASS_UNAME},
  3303. {IDC_ACCTPASS_EDIT, IDH_WABLDAP_DIRSSERV_AUTH_PASS_PASS},
  3304. {IDC_ACCTPASS_STATIC, IDH_WABLDAP_DIRSSERV_AUTH_PASS_PASS},
  3305. {IDC_RESOLVE_CHECK, IDH_WABLDAP_DIRSSERV_CHECK_AGAINST},
  3306. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  3307. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  3308. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  3309. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  3310. {IDC_STATIC4, IDH_INETCOMM_GROUPBOX},
  3311. {IDC_STATIC5, IDH_INETCOMM_GROUPBOX},
  3312. {0, 0}};
  3313. INT_PTR CALLBACK DirServer_GeneralDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3314. {
  3315. BOOL fLogon;
  3316. int idsError;
  3317. ULONG cbSize;
  3318. HWND hwndT;
  3319. NMHDR *pnmhdr;
  3320. CAccount *pAcct;
  3321. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  3322. DWORD dw;
  3323. SVRDLGINFO *psdi;
  3324. pAcct = (CAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  3325. psdi = (SVRDLGINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  3326. switch (uMsg)
  3327. {
  3328. case WM_INITDIALOG:
  3329. // Get the ServerParams and store them in our extra bytes
  3330. pAcct = (CAccount *) ((PROPSHEETPAGE*) lParam)->lParam;
  3331. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  3332. Assert(psdi == NULL);
  3333. if (!MemAlloc((void **)&psdi, sizeof(SVRDLGINFO)))
  3334. return(-1);
  3335. ZeroMemory(psdi, sizeof(SVRDLGINFO));
  3336. psdi->sfType = SERVER_LDAP;
  3337. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)psdi);
  3338. // Set Account Name
  3339. InitAcctPropEdit(GetDlgItem(hwnd, IDC_ACCOUNT_EDIT), pAcct, AP_ACCOUNT_NAME, CCHMAX_ACCOUNT_NAME - 1);
  3340. // set server name
  3341. InitAcctPropEdit(GetDlgItem(hwnd, IDC_SERVER_EDIT), pAcct, AP_LDAP_SERVER, CCHMAX_SERVER_NAME - 1);
  3342. if (FAILED(pAcct->GetPropDw(AP_LDAP_AUTHENTICATION, &dw)))
  3343. dw = LDAP_AUTH_ANONYMOUS;
  3344. if (dw != LDAP_AUTH_ANONYMOUS)
  3345. {
  3346. CheckDlgButton(hwnd, IDC_LOGON_CHECK, BST_CHECKED);
  3347. if (SUCCEEDED(pAcct->GetPropSz(AP_LDAP_USERNAME, sz, ARRAYSIZE(sz))))
  3348. SetDlgItemText(hwnd, IDC_ACCTNAME_EDIT, sz);
  3349. if (SUCCEEDED(pAcct->GetPropSz(AP_LDAP_PASSWORD, sz, ARRAYSIZE(sz))))
  3350. SetDlgItemText(hwnd, IDC_ACCTPASS_EDIT, sz);
  3351. if (dw != LDAP_AUTH_PASSWORD)
  3352. {
  3353. CheckDlgButton(hwnd, IDC_LOGONSSPI_CHECK, BST_CHECKED);
  3354. }
  3355. fLogon = TRUE;
  3356. }
  3357. else
  3358. fLogon = FALSE;
  3359. Server_EnableLogonWindows(hwnd, fLogon);
  3360. hwndT = GetDlgItem(hwnd, IDC_ACCTNAME_EDIT);
  3361. SetIntlFont(hwndT);
  3362. SendMessage(hwndT, EM_LIMITTEXT, CCHMAX_USERNAME - 1, 0L);
  3363. SendDlgItemMessage(hwnd, IDC_ACCTPASS_EDIT, EM_LIMITTEXT, CCHMAX_PASSWORD - 1, 0L);
  3364. if (SUCCEEDED(pAcct->GetPropDw(AP_LDAP_RESOLVE_FLAG, &dw)))
  3365. CheckDlgButton(hwnd, IDC_RESOLVE_CHECK, dw ? BST_CHECKED : BST_UNCHECKED);
  3366. if (SUCCEEDED(pAcct->GetPropDw(AP_SERVER_READ_ONLY, &dw)) && dw)
  3367. EnableWindow(GetDlgItem(hwnd, IDC_SERVER_EDIT), FALSE);
  3368. psdi->dwInit = (psdi->dwInit | PAGE_GEN);
  3369. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  3370. return (TRUE);
  3371. case WM_HELP:
  3372. case WM_CONTEXTMENU:
  3373. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapLdapGen));
  3374. case WM_DESTROY:
  3375. if (psdi != NULL)
  3376. MemFree(psdi);
  3377. break;
  3378. case PSM_QUERYSIBLINGS:
  3379. Assert(psdi != NULL);
  3380. Assert(pAcct != NULL);
  3381. return(HandleQuerySiblings(hwnd, psdi, pAcct, wParam, lParam));
  3382. case WM_COMMAND:
  3383. switch(LOWORD(wParam))
  3384. {
  3385. case IDC_LOGONSSPI_CHECK:
  3386. case IDC_LOGON_CHECK:
  3387. Server_EnableLogonWindows(hwnd, IsDlgButtonChecked(hwnd, IDC_LOGON_CHECK));
  3388. // fall through...
  3389. case IDC_RESOLVE_CHECK:
  3390. MarkPageDirty(hwnd, PAGE_GEN);
  3391. break;
  3392. default:
  3393. if (HIWORD(wParam) == EN_CHANGE)
  3394. {
  3395. if (LOWORD(wParam) == IDC_ACCOUNT_EDIT)
  3396. UpdateAcctTitle(hwnd, IDC_ACCOUNT_EDIT, ACCT_DIR_SERV);
  3397. MarkPageDirty(hwnd, PAGE_GEN);
  3398. }
  3399. break;
  3400. }
  3401. break;
  3402. case WM_NOTIFY:
  3403. pnmhdr = (NMHDR *)lParam;
  3404. switch (pnmhdr->code)
  3405. {
  3406. case PSN_APPLY:
  3407. // BEGIN validation
  3408. hwndT = GetDlgItem(hwnd, IDC_ACCOUNT_EDIT);
  3409. if (!ValidateAccountName(hwnd, hwndT, pAcct, &idsError))
  3410. return(InvalidAcctProp(hwnd, hwndT, idsError, iddDirServProp_General));
  3411. hwndT = GetDlgItem(hwnd, IDC_SERVER_EDIT);
  3412. if (!ValidateServerName(hwnd, hwndT, pAcct, AP_LDAP_SERVER, &idsError, pnmhdr->code == PSN_APPLY))
  3413. return(InvalidAcctProp(hwnd, hwndT, idsError, iddDirServProp_General));
  3414. if (IsDlgButtonChecked(hwnd, IDC_LOGON_CHECK) &&
  3415. !ValidateLogonSettings(hwnd, pAcct->m_dwDlgFlags, &hwndT, &idsError))
  3416. return(InvalidAcctProp(hwnd, hwndT, idsError, iddDirServProp_General));
  3417. // END validation
  3418. hwndT = GetDlgItem(hwnd, IDC_ACCOUNT_EDIT);
  3419. GetAccountName(hwndT, pAcct);
  3420. hwndT = GetDlgItem(hwnd, IDC_SERVER_EDIT);
  3421. GetServerName(hwndT, pAcct, AP_LDAP_SERVER);
  3422. GetLogonSettings(hwnd, pAcct, IsDlgButtonChecked(hwnd, IDC_LOGON_CHECK), SRV_LDAP);
  3423. pAcct->SetPropDw(AP_LDAP_RESOLVE_FLAG, (DWORD)!!IsDlgButtonChecked(hwnd, IDC_RESOLVE_CHECK));
  3424. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  3425. dw = PAGE_GEN;
  3426. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  3427. if (dw == -1)
  3428. {
  3429. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  3430. return(TRUE);
  3431. }
  3432. break;
  3433. }
  3434. return(TRUE);
  3435. }
  3436. return (FALSE);
  3437. }
  3438. const static HELPMAP g_rgCtxMapLdapAdv[] = {
  3439. {IDC_LDAP_PORT_EDIT, IDH_LDAP_PORT_NUMBER},
  3440. {IDC_USEDEFAULTS_BUTTON, IDH_NEWS_SERV_ADV_USE_DEFAULTS},
  3441. {IDC_TIMEOUT_SLIDER, IDH_WABLDAP_SEARCH_TIMEOUT},
  3442. {IDC_MATCHES_EDIT, IDH_WABLDAP_SEARCH_LIMIT},
  3443. {IDC_SEARCHBASE_EDIT, IDH_LDAP_SEARCH_BASE},
  3444. {IDC_SECURECONNECT_BUTTON, IDH_MAIL_ADV_REQ_SSL},
  3445. {IDC_SIMPLESEARCH_BUTTON, IDH_WABLDAP_USE_SIMPLE_SEARCH},
  3446. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  3447. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  3448. {IDC_STATIC2, IDH_INETCOMM_GROUPBOX},
  3449. {IDC_STATIC3, IDH_INETCOMM_GROUPBOX},
  3450. {0, 0}};
  3451. INT_PTR CALLBACK DirServer_AdvancedDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3452. {
  3453. NMHDR *pnmhdr;
  3454. TCHAR sz[CCHMAX_ACCT_PROP_SZ];
  3455. DWORD dw, dwPort, dwMatches;
  3456. WORD code, id;
  3457. SERVER_TYPE sfType;
  3458. HWND hwndT;
  3459. BOOL fTrans, fSecure, fEnable, flag, fIMAP, fSimple;
  3460. IImnAccount *pAcct = (IImnAccount *)GetWindowLongPtr(hwnd, DWLP_USER);
  3461. switch (uMsg)
  3462. {
  3463. case WM_INITDIALOG:
  3464. // Get the ServerParams and store them in our extra bytes
  3465. pAcct = (IImnAccount*) ((PROPSHEETPAGE*) lParam)->lParam;
  3466. SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) pAcct);
  3467. // Load the controls with what information we have
  3468. if (SUCCEEDED(pAcct->GetPropDw(AP_LDAP_PORT, &dw)))
  3469. SetDlgItemInt(hwnd, IDC_LDAP_PORT_EDIT, dw, FALSE);
  3470. SendDlgItemMessage(hwnd, IDC_LDAP_PORT_EDIT, EM_LIMITTEXT, PORT_CCHMAX, 0);
  3471. if (SUCCEEDED(pAcct->GetPropDw(AP_LDAP_SIMPLE_SEARCH, (LPDWORD)&fSimple)) && fSimple)
  3472. CheckDlgButton(hwnd, IDC_SIMPLESEARCH_BUTTON, TRUE);
  3473. if (SUCCEEDED(pAcct->GetPropDw(AP_LDAP_SSL, (LPDWORD)&fSecure)) && fSecure)
  3474. {
  3475. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON), dw != DEF_SLDAPPORT);
  3476. CheckDlgButton(hwnd, IDC_SECURECONNECT_BUTTON, TRUE);
  3477. }
  3478. else
  3479. {
  3480. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON), dw != DEF_LDAPPORT);
  3481. }
  3482. if (FAILED(pAcct->GetPropDw(AP_LDAP_SEARCH_RETURN, (LPDWORD)&dw)))
  3483. dw = MATCHES_DEFAULT;
  3484. if (dw < MATCHES_MIN)
  3485. dw = MATCHES_MIN;
  3486. else if (dw > MATCHES_MAX)
  3487. dw = MATCHES_MAX;
  3488. InitCheckCounter(dw, hwnd, NULL, IDC_MATCHES_EDIT, IDC_MATCHES_SPIN,
  3489. MATCHES_MIN, MATCHES_MAX, MATCHES_DEFAULT);
  3490. // Server Timeout
  3491. dw = 0;
  3492. pAcct->GetPropDw(AP_LDAP_TIMEOUT, &dw);
  3493. InitTimeoutSlider(GetDlgItem(hwnd, IDC_TIMEOUT_SLIDER),
  3494. GetDlgItem(hwnd, IDC_TIMEOUT_STATIC), dw);
  3495. InitAcctPropEdit(GetDlgItem(hwnd, IDC_SEARCHBASE_EDIT), pAcct,
  3496. AP_LDAP_SEARCH_BASE, CCHMAX_SEARCH_BASE - 1);
  3497. PropSheet_QuerySiblings(GetParent(hwnd), SM_INITIALIZED, PAGE_ADV);
  3498. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  3499. return (TRUE);
  3500. case WM_HELP:
  3501. case WM_CONTEXTMENU:
  3502. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapLdapAdv));
  3503. case WM_HSCROLL:
  3504. // Update the text beside the slider
  3505. SetTimeoutString(GetDlgItem(hwnd, IDC_TIMEOUT_STATIC),
  3506. (UINT) SendMessage((HWND) lParam, TBM_GETPOS, 0, 0));
  3507. MarkPageDirty(hwnd, PAGE_ADV);
  3508. return (TRUE);
  3509. case WM_COMMAND:
  3510. code = HIWORD(wParam);
  3511. id = LOWORD(wParam);
  3512. fSecure = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_BUTTON);
  3513. fSimple = IsDlgButtonChecked(hwnd, IDC_SIMPLESEARCH_BUTTON);
  3514. switch (id)
  3515. {
  3516. case IDC_MATCHES_EDIT:
  3517. case IDC_SEARCHBASE_EDIT:
  3518. if (code == EN_CHANGE)
  3519. MarkPageDirty(hwnd, PAGE_ADV);
  3520. break;
  3521. case IDC_LDAP_PORT_EDIT:
  3522. if (code == EN_CHANGE)
  3523. {
  3524. dw = GetDlgItemInt(hwnd, IDC_LDAP_PORT_EDIT, &fTrans, FALSE);
  3525. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON),
  3526. !fTrans || (fSecure ? (dw != DEF_SLDAPPORT) : (dw != DEF_LDAPPORT)));
  3527. MarkPageDirty(hwnd, PAGE_ADV);
  3528. }
  3529. break;
  3530. case IDC_SIMPLESEARCH_BUTTON:
  3531. case IDC_SECURECONNECT_BUTTON:
  3532. case IDC_USEDEFAULTS_BUTTON:
  3533. // Reset the settings on this page to the default values.
  3534. SetDlgItemInt(hwnd, IDC_LDAP_PORT_EDIT, fSecure ? DEF_SLDAPPORT : DEF_LDAPPORT, FALSE);
  3535. EnableWindow(GetDlgItem(hwnd, IDC_USEDEFAULTS_BUTTON), FALSE);
  3536. MarkPageDirty(hwnd, PAGE_ADV);
  3537. SetFocus(GetDlgItem(hwnd, IDC_LDAP_PORT_EDIT));
  3538. break;
  3539. }
  3540. return (TRUE);
  3541. case WM_NOTIFY:
  3542. pnmhdr = (NMHDR *)lParam;
  3543. switch (pnmhdr->code)
  3544. {
  3545. case PSN_APPLY:
  3546. // BEGIN validation
  3547. dwPort = GetDlgItemInt(hwnd, IDC_LDAP_PORT_EDIT, &fTrans, FALSE);
  3548. if (!fTrans || dwPort == 0)
  3549. {
  3550. hwndT = GetDlgItem(hwnd, IDC_LDAP_PORT_EDIT);
  3551. return(InvalidAcctProp(hwnd, hwndT, idsErrPortNum, iddDirServProp_Advanced));
  3552. }
  3553. dwMatches = GetDlgItemInt(hwnd, IDC_MATCHES_EDIT, &fTrans, FALSE);
  3554. if (!fTrans || dwMatches < MATCHES_MIN || dwMatches > MATCHES_MAX)
  3555. {
  3556. hwndT = GetDlgItem(hwnd, IDC_MATCHES_EDIT);
  3557. return(InvalidAcctProp(hwnd, hwndT, idsErrMatches, iddDirServProp_Advanced));
  3558. }
  3559. // END validation
  3560. pAcct->SetPropDw(AP_LDAP_PORT, dwPort);
  3561. pAcct->SetPropDw(AP_LDAP_SEARCH_RETURN, dwMatches);
  3562. dw = IsDlgButtonChecked(hwnd, IDC_SECURECONNECT_BUTTON);
  3563. pAcct->SetPropDw(AP_LDAP_SSL, dw);
  3564. dw = IsDlgButtonChecked(hwnd, IDC_SIMPLESEARCH_BUTTON);
  3565. pAcct->SetPropDw(AP_LDAP_SIMPLE_SEARCH, dw);
  3566. dw = GetTimeoutFromSlider(GetDlgItem(hwnd, IDC_TIMEOUT_SLIDER));
  3567. pAcct->SetPropDw(AP_LDAP_TIMEOUT, dw);
  3568. dw = GetWindowText(GetDlgItem(hwnd, IDC_SEARCHBASE_EDIT), sz, ARRAYSIZE(sz));
  3569. UlStripWhitespace(sz, TRUE, TRUE, &dw);
  3570. if (dw == 0)
  3571. pAcct->SetProp(AP_LDAP_SEARCH_BASE, NULL, 0);
  3572. else
  3573. pAcct->SetPropSz(AP_LDAP_SEARCH_BASE, sz);
  3574. PropSheet_UnChanged(GetParent(hwnd), hwnd);
  3575. dw = PAGE_ADV;
  3576. PropSheet_QuerySiblings(GetParent(hwnd), SM_SAVECHANGES, (LPARAM)&dw);
  3577. if (dw == -1)
  3578. {
  3579. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  3580. return(TRUE);
  3581. }
  3582. break;
  3583. }
  3584. return (TRUE);
  3585. }
  3586. return (FALSE);
  3587. }
  3588. // BEGIN bug 21535
  3589. // Used for modifying propsheet template
  3590. const TCHAR c_szComctl[] = TEXT("comctl32.dll");
  3591. #define DLG_PROPSHEET 1006 // Bad hack...assumes comctl's res id
  3592. typedef struct
  3593. {
  3594. int inumLang;
  3595. WORD wLang;
  3596. } ENUMLANGDATA;
  3597. //
  3598. // EnumResLangProc
  3599. //
  3600. // purpose: a callback function for EnumResourceLanguages().
  3601. // look into the type passed in and if it is RT_DIALOG
  3602. // copy the lang of the first resource to our buffer
  3603. // this also counts # of lang if more than one of them
  3604. // are passed in
  3605. //
  3606. // IN: lparam: ENUMLANGDATA - defined at the top of this file
  3607. //
  3608. BOOL CALLBACK EnumResLangProc(HINSTANCE hinst, LPCTSTR lpszType, LPCTSTR lpszName, WORD wIdLang, LPARAM lparam)
  3609. {
  3610. ENUMLANGDATA *pel = (ENUMLANGDATA *)lparam;
  3611. Assert(pel);
  3612. if (lpszType == RT_DIALOG)
  3613. {
  3614. if (pel->inumLang == 0)
  3615. pel->wLang = wIdLang;
  3616. pel->inumLang++;
  3617. }
  3618. return TRUE; // continue until we get all langs...
  3619. }
  3620. //
  3621. // GetDialogLang
  3622. //
  3623. // purpose: fill out the ENUMLANGDATA (see top of this file) with the
  3624. // # of available langs in the module passed in, and the langid
  3625. // of what system enumerates first. i.e, the langid eq. to what
  3626. // the module localized if the module is localized in single
  3627. // language
  3628. //
  3629. // IN: hinstCpl - this is supposed to be a instance handle of inetcpl.
  3630. // pel - a pointer to the buffer we fill out
  3631. //
  3632. // RESULT: TRUE - everything cool, continue with adjusting property sheet
  3633. // FALSE - somethings wrong, abort adjusting property sheet.
  3634. //
  3635. BOOL GetDialogLang(HMODULE hinstCpl, ENUMLANGDATA *pel)
  3636. {
  3637. Assert(pel);
  3638. // Get the possible languages the template localized in.
  3639. EnumResourceLanguages(hinstCpl, RT_DIALOG, MAKEINTRESOURCE(iddMailSvrProp_General), (ENUMRESLANGPROC)EnumResLangProc, (LPARAM)pel);
  3640. return TRUE;
  3641. }
  3642. //
  3643. // PropSheetProc
  3644. //
  3645. // purpose: the callback function to modify resource template
  3646. // in order to make DLG_PROPSHEET's lang mathed with ours.
  3647. // there could be a general way but for now this is
  3648. // an ugly hack from inetcpl.
  3649. //
  3650. //
  3651. int CALLBACK PropSheetProc (HWND hwndDlg, UINT uMsg, LPARAM lParam)
  3652. {
  3653. LPVOID pTemplate = (LPVOID)lParam;
  3654. LPVOID pTmpInLang;
  3655. ENUMLANGDATA el = {0,0};
  3656. HINSTANCE hComctl;
  3657. HRSRC hrsrc;
  3658. HGLOBAL hgmem;
  3659. DWORD cbNewTmp;
  3660. // Comm ctrl gives us a chance to recreate resource by this msg.
  3661. if (uMsg==PSCB_PRECREATE && pTemplate)
  3662. {
  3663. // enumrate any possible language used in this cpl for dialogs
  3664. if (!GetDialogLang(g_hInstRes, &el))
  3665. return 0; // failed to get resouce name
  3666. if (el.inumLang > 1)
  3667. {
  3668. // we've got multi-language templates
  3669. // let comctl load the one that matches our thread langid.
  3670. return 0;
  3671. }
  3672. if (GetSystemDefaultLangID() != el.wLang)
  3673. {
  3674. // Get comctl32's module handle
  3675. hComctl = GetModuleHandle(c_szComctl);
  3676. if (hComctl)
  3677. {
  3678. // this is a horrible hack because we assume DLG_PROPSHEET
  3679. hrsrc = FindResourceEx(hComctl, RT_DIALOG, MAKEINTRESOURCE(DLG_PROPSHEET), el.wLang);
  3680. if (hrsrc)
  3681. {
  3682. if (hgmem = LoadResource(hComctl, hrsrc))
  3683. {
  3684. pTmpInLang = LockResource(hgmem);
  3685. }
  3686. if (pTmpInLang)
  3687. {
  3688. cbNewTmp = SizeofResource(hComctl, hrsrc);
  3689. CopyMemory(pTemplate, pTmpInLang, cbNewTmp);
  3690. }
  3691. if (hgmem && pTmpInLang)
  3692. {
  3693. UnlockResource(hgmem);
  3694. return 1; // everything went ok.
  3695. }
  3696. }
  3697. }
  3698. }
  3699. }
  3700. return 0;
  3701. }
  3702. // END bug 21535
  3703. const static HELPMAP g_rgCtxMapSmtpAuth[] = {
  3704. {IDC_USEMAILSETTINGS, IDH_MAIL_OUT_SERV_SAME},
  3705. {IDC_ACCTNAME_STATIC, IDH_MAIL_SERV_POP3_ACCT},
  3706. {IDC_ACCTNAME_EDIT, IDH_MAIL_SERV_POP3_ACCT},
  3707. {IDC_ACCTPASS_STATIC, IDH_MAIL_SERV_PWORD},
  3708. {IDC_ACCTPASS_EDIT, IDH_MAIL_SERV_PWORD},
  3709. {IDC_LOGONSSPI_CHECK, IDH_MAIL_LOGON_USING_SICILY},
  3710. {IDC_REMEMBER_PASSWORD, 503},
  3711. {IDC_STATIC0, IDH_INETCOMM_GROUPBOX},
  3712. {IDC_STATIC1, IDH_INETCOMM_GROUPBOX},
  3713. {0, 0}};
  3714. INT_PTR CALLBACK SmtpLogonSettingsDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3715. {
  3716. LPSMTPAUTHINFO pInfo=(LPSMTPAUTHINFO)GetWndThisPtr(hwnd);
  3717. CHAR szUserName[CCHMAX_USERNAME];
  3718. CHAR szPassword[CCHMAX_PASSWORD];
  3719. BOOL fPromptPassword, fEnable;
  3720. DWORD cbSize;
  3721. SMTPAUTHTYPE authtype;
  3722. switch(uMsg)
  3723. {
  3724. case WM_INITDIALOG:
  3725. // Get pInfo
  3726. pInfo = (LPSMTPAUTHINFO)lParam;
  3727. Assert(pInfo && pInfo->authtype != SMTP_AUTH_NONE);
  3728. // SMTP_AUTH_SICILY
  3729. if (SMTP_AUTH_SICILY == pInfo->authtype)
  3730. {
  3731. CheckDlgButton(hwnd, IDC_SPECIFYSETTINGS, BST_CHECKED);
  3732. CheckDlgButton(hwnd, IDC_LOGONSSPI_CHECK, BST_CHECKED);
  3733. SetDlgItemText(hwnd, IDC_ACCTNAME_EDIT, pInfo->szUserName);
  3734. SetDlgItemText(hwnd, IDC_ACCTPASS_EDIT, pInfo->szPassword);
  3735. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), !pInfo->fPromptPassword);
  3736. }
  3737. // SMTP_AUTH_USE_POP3ORIMAP_SETTINGS
  3738. else if (SMTP_AUTH_USE_POP3ORIMAP_SETTINGS == pInfo->authtype)
  3739. {
  3740. // Check Logon Using Radio
  3741. CheckDlgButton(hwnd, IDC_USEMAILSETTINGS, BST_CHECKED);
  3742. EnableWindow(GetDlgItem(hwnd, IDC_LOGONSSPI_CHECK), FALSE);
  3743. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_EDIT), FALSE);
  3744. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), FALSE);
  3745. EnableWindow(GetDlgItem(hwnd, IDC_REMEMBER_PASSWORD), FALSE);
  3746. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_STATIC), FALSE);
  3747. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_STATIC), FALSE);
  3748. }
  3749. // SMTP_AUTH_USE_SMTP_SETTINGS
  3750. else if (SMTP_AUTH_USE_SMTP_SETTINGS == pInfo->authtype)
  3751. {
  3752. CheckDlgButton(hwnd, IDC_SPECIFYSETTINGS, BST_CHECKED);
  3753. SetDlgItemText(hwnd, IDC_ACCTNAME_EDIT, pInfo->szUserName);
  3754. SetDlgItemText(hwnd, IDC_ACCTPASS_EDIT, pInfo->szPassword);
  3755. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), !pInfo->fPromptPassword);
  3756. }
  3757. else
  3758. Assert(FALSE);
  3759. CheckDlgButton(hwnd, IDC_REMEMBER_PASSWORD, FALSE == pInfo->fPromptPassword);
  3760. SetWndThisPtr(hwnd, pInfo);
  3761. break;
  3762. case WM_HELP:
  3763. case WM_CONTEXTMENU:
  3764. return(OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapSmtpAuth));
  3765. case WM_COMMAND:
  3766. switch(GET_WM_COMMAND_ID(wParam,lParam))
  3767. {
  3768. case IDC_LOGONSSPI_CHECK:
  3769. case IDC_SPECIFYSETTINGS:
  3770. case IDC_USEMAILSETTINGS:
  3771. if (IsDlgButtonChecked(hwnd, IDC_SPECIFYSETTINGS))
  3772. {
  3773. fPromptPassword = (FALSE == IsDlgButtonChecked(hwnd, IDC_REMEMBER_PASSWORD));
  3774. EnableWindow(GetDlgItem(hwnd, IDC_LOGONSSPI_CHECK), TRUE);
  3775. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_EDIT), TRUE);
  3776. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), (FALSE == fPromptPassword));
  3777. EnableWindow(GetDlgItem(hwnd, IDC_REMEMBER_PASSWORD), TRUE);
  3778. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_STATIC), TRUE);
  3779. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_STATIC), TRUE);
  3780. }
  3781. else if (IsDlgButtonChecked(hwnd, IDC_USEMAILSETTINGS))
  3782. {
  3783. EnableWindow(GetDlgItem(hwnd, IDC_LOGONSSPI_CHECK), FALSE);
  3784. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_EDIT), FALSE);
  3785. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT), FALSE);
  3786. EnableWindow(GetDlgItem(hwnd, IDC_REMEMBER_PASSWORD), FALSE);
  3787. EnableWindow(GetDlgItem(hwnd, IDC_ACCTNAME_STATIC), FALSE);
  3788. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_STATIC), FALSE);
  3789. }
  3790. break;
  3791. case IDC_REMEMBER_PASSWORD:
  3792. EnableWindow(GetDlgItem(hwnd, IDC_ACCTPASS_EDIT),
  3793. IsDlgButtonChecked(hwnd, IDC_REMEMBER_PASSWORD));
  3794. break;
  3795. case IDCANCEL:
  3796. EndDialog(hwnd, IDCANCEL);
  3797. return 1;
  3798. case IDOK:
  3799. // SMTP_AUTH_USE_POP3ORIMAP_SETTINGS
  3800. if (IsDlgButtonChecked(hwnd, IDC_USEMAILSETTINGS))
  3801. {
  3802. // No Change
  3803. if (SMTP_AUTH_USE_POP3ORIMAP_SETTINGS != pInfo->authtype)
  3804. {
  3805. pInfo->authtype = SMTP_AUTH_USE_POP3ORIMAP_SETTINGS;
  3806. pInfo->fDirty = TRUE;
  3807. EndDialog(hwnd, IDOK);
  3808. return 1;
  3809. }
  3810. }
  3811. // Otherwise, use specified settings
  3812. else
  3813. {
  3814. // Get User Name and Password
  3815. GetDlgItemText(hwnd, IDC_ACCTNAME_EDIT, szUserName, ARRAYSIZE(szUserName));
  3816. // Cleanup szUserName
  3817. cbSize = lstrlen(szUserName);
  3818. UlStripWhitespace(szUserName, TRUE, TRUE, &cbSize);
  3819. if (cbSize == 0)
  3820. {
  3821. // Error
  3822. AcctMessageBox(hwnd, MAKEINTRESOURCE(idsAccountManager), MAKEINTRESOURCE(idsEnterAcctName), 0, MB_ICONEXCLAMATION | MB_OK);
  3823. SetFocus(GetDlgItem(hwnd, IDC_ACCTNAME_EDIT));
  3824. return 1;
  3825. }
  3826. // SMTP_AUTH_SICILY
  3827. if (IsDlgButtonChecked(hwnd, IDC_LOGONSSPI_CHECK))
  3828. authtype = SMTP_AUTH_SICILY;
  3829. else
  3830. authtype = SMTP_AUTH_USE_SMTP_SETTINGS;
  3831. // Get the Password
  3832. GetDlgItemText(hwnd, IDC_ACCTPASS_EDIT, szPassword, ARRAYSIZE(szPassword));
  3833. fPromptPassword = (FALSE == IsDlgButtonChecked(hwnd, IDC_REMEMBER_PASSWORD));
  3834. // No Change ?
  3835. if (authtype != pInfo->authtype ||
  3836. lstrcmpi(pInfo->szUserName, szUserName) != 0 ||
  3837. fPromptPassword != pInfo->fPromptPassword ||
  3838. lstrcmpi(pInfo->szPassword, szPassword) != 0)
  3839. {
  3840. pInfo->authtype = authtype;
  3841. StrCpyN(pInfo->szUserName, szUserName, ARRAYSIZE(pInfo->szUserName));
  3842. StrCpyN(pInfo->szPassword, szPassword, ARRAYSIZE(pInfo->szPassword));
  3843. pInfo->fPromptPassword = fPromptPassword;
  3844. pInfo->fDirty = TRUE;
  3845. }
  3846. }
  3847. EndDialog(hwnd, IDOK);
  3848. return 1;
  3849. }
  3850. break;
  3851. }
  3852. return 0;
  3853. }
  3854. HRESULT EscapeSpaces(LPCSTR psz, LPSTR pszOut, DWORD *pcch)
  3855. {
  3856. LPCSTR pch;
  3857. LPSTR pchOut;
  3858. DWORD cch, cchOut;
  3859. pchOut = pszOut;
  3860. cch = *pcch;
  3861. cchOut = 0;
  3862. for (pch = psz; *pch; pch++)
  3863. {
  3864. if (*pch == ' ')
  3865. {
  3866. cchOut += 3;
  3867. if (cchOut > cch)
  3868. return(E_FAIL);
  3869. *pchOut++ = '%';
  3870. *pchOut++ = '2';
  3871. *pchOut++ = '0';
  3872. }
  3873. else
  3874. {
  3875. cchOut++;
  3876. if (cchOut > cch)
  3877. return(E_FAIL);
  3878. *pchOut++ = *pch;
  3879. }
  3880. }
  3881. cchOut++;
  3882. if (cchOut > cch)
  3883. return(E_FAIL);
  3884. *pchOut = 0;
  3885. *pcch = cchOut;
  3886. return(S_OK);
  3887. }
  3888. void GetDigitalID(HWND hwnd)
  3889. {
  3890. HRESULT hr;
  3891. TCHAR szName[CCHMAX_DISPLAY_NAME];
  3892. TCHAR szEmail[CCHMAX_EMAIL_ADDRESS];
  3893. TCHAR szTemp[INTERNET_MAX_URL_LENGTH];
  3894. TCHAR szURL[INTERNET_MAX_URL_LENGTH];
  3895. DWORD cchOut = ARRAYSIZE(szURL);
  3896. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETDISPLAYNAME, (LPARAM)szName);
  3897. PropSheet_QuerySiblings(GetParent(hwnd), MSM_GETEMAILADDRESS, (LPARAM)szEmail);
  3898. LoadString(g_hInstRes, idsGetCertURL, szURL, ARRAYSIZE(szURL));
  3899. wnsprintf(szTemp, ARRAYSIZE(szTemp), szURL, szName, szEmail);
  3900. // NOTE: we shellexec iexplore.exe here NOT the default handler for http://
  3901. // links. We have to make sure we launch this link with IE even if
  3902. // netscape is the browser. see georgeh for explanation of why.
  3903. if (SUCCEEDED(EscapeSpaces(szTemp, szURL, &cchOut)))
  3904. ShellExecuteA(NULL, c_szOpen, c_szIexplore, szURL, NULL, SW_SHOWNORMAL);
  3905. }
  3906. DWORD DwGenerateTrustedChain(
  3907. HWND hwnd,
  3908. DWORD dwFlags,
  3909. PCCERT_CONTEXT pcCertToTest,
  3910. DWORD dwToIgnore,
  3911. BOOL fFullSearch,
  3912. DWORD * pcChain,
  3913. PCCERT_CONTEXT ** prgChain)
  3914. {
  3915. DWORD dwErr = 0;
  3916. GUID guidAction = CERT_CERTIFICATE_ACTION_VERIFY;
  3917. CERT_VERIFY_CERTIFICATE_TRUST trust = {0};
  3918. WINTRUST_BLOB_INFO blob = {0};
  3919. WINTRUST_DATA data = {0};
  3920. IMimeBody * pBody;
  3921. PROPVARIANT var;
  3922. HCERTSTORE rgCAs[3] = {0};
  3923. HCERTSTORE *pCAs = NULL;
  3924. HCERTSTORE hMsg = NULL;
  3925. Assert(pcCertToTest);
  3926. data.cbStruct = sizeof(WINTRUST_DATA);
  3927. data.pPolicyCallbackData = NULL;
  3928. data.pSIPClientData = NULL;
  3929. data.dwUIChoice = WTD_UI_NONE;
  3930. data.fdwRevocationChecks = WTD_REVOKE_NONE;
  3931. data.dwUnionChoice = WTD_CHOICE_BLOB;
  3932. data.pBlob = &blob;
  3933. blob.cbStruct = sizeof(WINTRUST_BLOB_INFO);
  3934. blob.pcwszDisplayName = NULL;
  3935. blob.cbMemObject = sizeof(trust);
  3936. blob.pbMemObject = (LPBYTE)&trust;
  3937. trust.cbSize = sizeof(trust);
  3938. trust.pccert = pcCertToTest;
  3939. trust.dwFlags = (fFullSearch ? CERT_TRUST_DO_FULL_SEARCH : 0);
  3940. trust.pdwErrors = &dwErr;
  3941. trust.pszUsageOid = szOID_PKIX_KP_EMAIL_PROTECTION;
  3942. trust.pcChain = pcChain;
  3943. trust.prgChain = prgChain;
  3944. trust.dwFlags |= dwFlags;
  3945. //cvct.prgdwErrors
  3946. trust.dwIgnoreErr = dwToIgnore;
  3947. if (pCAs)
  3948. {
  3949. trust.dwFlags |= CERT_TRUST_ADD_CERT_STORES;
  3950. trust.rghstoreCAs = pCAs;
  3951. trust.cStores = 3;
  3952. }
  3953. LONG lr = WinVerifyTrust(hwnd, &guidAction, (void*)&data);
  3954. if(((LRESULT) lr) == CERT_E_REVOKED)
  3955. dwErr = CERT_VALIDITY_CERTIFICATE_REVOKED;
  3956. else if(((LRESULT) lr) == CERT_E_REVOCATION_FAILURE)
  3957. {
  3958. Assert(FALSE);
  3959. dwErr = CERT_VALIDITY_NO_CRL_FOUND;
  3960. }
  3961. else if (0 > lr) // WinVerifyTrust(hwnd, &guidAction, (void*)&data))
  3962. dwErr = CERT_VALIDITY_NO_TRUST_DATA;
  3963. if (dwErr)
  3964. DOUTL(DOUTL_CRYPT, "Trust provider returned 0x%.8lx", dwErr);
  3965. // Filter these out since the trust provider isn't.
  3966. dwErr &= ~dwToIgnore;
  3967. CertCloseStore(rgCAs[0], 0);
  3968. CertCloseStore(rgCAs[1], 0);
  3969. CertCloseStore(rgCAs[2], 0);
  3970. return dwErr;
  3971. }