Source code of Windows XP (NT5)
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.

1241 lines
39 KiB

  1. /*****************************************************************************\
  2. FILE: AutoDiscovery.cpp
  3. DESCRIPTION:
  4. This is AutoDiscovery progress UI for the Outlook Express's email
  5. configuration wizard.
  6. BryanSt 1/18/2000
  7. Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
  8. \*****************************************************************************/
  9. #include "pch.hxx"
  10. #include <prsht.h>
  11. #include <imnact.h>
  12. #include <icwacct.h>
  13. #include <acctimp.h>
  14. #include "icwwiz.h"
  15. #include "acctui.h"
  16. #include "acctman.h"
  17. #include <dllmain.h>
  18. #include <resource.h>
  19. #include "server.h"
  20. #include "connect.h"
  21. #include <Shlwapi.h>
  22. #include "strconst.h"
  23. #include "demand.h"
  24. #include "hotwiz.h"
  25. #include "shared.h"
  26. #include <AutoDiscovery.h>
  27. #include "AutoDiscoveryUI.h"
  28. ASSERTDATA
  29. #define RECTWIDTH(rect) (rect.right - rect.left)
  30. #define RECTHEIGHT(rect) (rect.bottom - rect.top)
  31. #define MAX_URL_STRING 2048
  32. #define SIZE_STR_AUTODISC_DESC 2048
  33. // These are the wizard control IDs for the Back, Next, and Finished buttons.
  34. #define IDD_WIZARD_BACK_BUTTON 0x3023
  35. #define IDD_WIZARD_NEXT_BUTTON 0x3024
  36. #define IDD_WIZARD_FINISH_BUTTON 0x3025
  37. #define SZ_DLL_AUTODISC TEXT("autodisc.dll")
  38. #define IDA_DOWNLOADINGSETTINGS 801 // In autodisc.dll
  39. #define ATOMICRELEASE(punk) {if (punk) { punk->Release(); punk = NULL;} }
  40. WCHAR g_szInfoURL[MAX_URL_STRING] = {0};
  41. WCHAR g_szWebMailURL[MAX_URL_STRING] = {0};
  42. typedef struct
  43. {
  44. // Default Protocol (POP3, IMAP, DAV, WEB)
  45. int nProtocol; // What is the email protocol? POP3 vs. IMAP vs. DAV vs. WEB
  46. BSTR bstrDisplayName; // What is the user's display name.
  47. BSTR bstrServer1Name; // What is the downloading email server name (POP3, IMAP, DAV, or WEB)
  48. int nServer1Port; // What is that server's port number?
  49. BSTR bstrLoginName; // What is the login name for the POP3 server. (Normall the same as the email address w/out the domain)
  50. BOOL fUsesSSL; // Use SSL when connecting to the POP3 or IMAP server?
  51. BOOL fUsesSPA; // Use SPA when connecting to the POP3 or IMAP server?
  52. // SMTP Protocol (If used)
  53. BSTR bstrServer2Name; // What is the uploading email server name (SMTP)
  54. int nServer2Port; // What is that server's port number?
  55. BOOL fSMTPUsesSSL; // Use SSL when connecting to the SMTP server?
  56. BOOL fAuthSMTP; // Does SMTP need Authentication?
  57. BOOL fAuthSMTPPOP; // Use POP3's auth for SMTP?
  58. BOOL fAuthSMTPSPA; // Use SPA auth for SMTP?
  59. BOOL fUseWebMail; // Is Web Bassed mail the only protocol we recognizer?
  60. BSTR bstrSMTPLoginName; // What is the login name for the SMTP server.
  61. BOOL fDisplayInfoURL; // Is there an URL for Info about the email server/services?
  62. BSTR bstrInfoURL; // If fDisplayInfoURL, this is the URL.
  63. } EMAIL_SERVER_SETTINGS;
  64. class CICWApprentice;
  65. /*****************************************************************************\
  66. Class: CAutoDiscoveryHelper
  67. DESCRIPTION:
  68. StartAutoDiscovery:
  69. hwndParent: This is the caller's hwnd. If we need to display UI, we
  70. will parent it off this hwnd. We also send this hwnd messages on
  71. progress.
  72. \*****************************************************************************/
  73. class CAutoDiscoveryHelper
  74. {
  75. public:
  76. // Public Methods
  77. HRESULT StartAutoDiscovery(IN CICWApprentice *pApp, IN HWND hDlg, IN BOOL fFirstInit);
  78. HRESULT OnCompleted(IN CICWApprentice *pApp, IN ACCTDATA * pData);
  79. HRESULT SetNextButton(HWND hwndButton);
  80. HRESULT RestoreNextButton(HWND hwndButton);
  81. CAutoDiscoveryHelper();
  82. ~CAutoDiscoveryHelper(void);
  83. private:
  84. // Private Member Variables
  85. // Other internal state.
  86. HWND _hwndDlgParent; // parent window for message boxes
  87. TCHAR _szNextText[MAX_PATH]; //
  88. IMailAutoDiscovery * _pMailAutoDiscovery; //
  89. HINSTANCE _hInstAutoDisc; // We use this to get the animation
  90. // Private Member Functions
  91. HRESULT _GetAccountInformation(EMAIL_SERVER_SETTINGS * pEmailServerSettings);
  92. };
  93. CAutoDiscoveryHelper * g_pAutoDiscoveryObject = NULL; // This is the AutoDisc obj used while downloading the settings.
  94. BOOL g_fRequestCancelled = TRUE;
  95. UINT g_uNextPage = ORD_PAGE_AD_MAILNAME; // ORD_PAGE_AD_MAILNAME, ORD_PAGE_AD_MAILSERVER, ORD_PAGE_AD_USEWEBMAIL, ORD_PAGE_AD_GOTOSERVERINFO
  96. //===========================
  97. // *** Class Internals & Helpers ***
  98. //===========================
  99. HRESULT FreeEmailServerSettings(EMAIL_SERVER_SETTINGS * pEmailServerSettings)
  100. {
  101. SysFreeString(pEmailServerSettings->bstrDisplayName); // It's okay to pass NULL to this API
  102. SysFreeString(pEmailServerSettings->bstrServer1Name);
  103. SysFreeString(pEmailServerSettings->bstrLoginName);
  104. SysFreeString(pEmailServerSettings->bstrServer2Name);
  105. SysFreeString(pEmailServerSettings->bstrSMTPLoginName);
  106. SysFreeString(pEmailServerSettings->bstrInfoURL);
  107. return S_OK;
  108. }
  109. void SHAnsiToUnicode(LPCSTR pszAnsi, LPWSTR pwzUnicode, DWORD cchSize)
  110. {
  111. if (pszAnsi == NULL)
  112. {
  113. pszAnsi = "";
  114. }
  115. MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, pwzUnicode, cchSize);
  116. }
  117. void SHUnicodeToAnsi(LPCWSTR pwzUnicode, LPSTR pszAnsi, DWORD cchSize)
  118. {
  119. if (pwzUnicode == NULL)
  120. {
  121. pwzUnicode = L"";
  122. }
  123. WideCharToMultiByte(CP_ACP, 0, pwzUnicode, -1, pszAnsi, cchSize, NULL, NULL);
  124. }
  125. BSTR SysAllocStringA(LPCSTR pszStr)
  126. {
  127. BSTR bstrOut = NULL;
  128. if (pszStr)
  129. {
  130. DWORD cchSize = (lstrlenA(pszStr) + 1);
  131. LPWSTR pwszThunkTemp = (LPWSTR) LocalAlloc(LPTR, (sizeof(pwszThunkTemp[0]) * cchSize)); // assumes INFOTIPSIZE number of chars max
  132. if (pwszThunkTemp)
  133. {
  134. SHAnsiToUnicode(pszStr, pwszThunkTemp, cchSize);
  135. bstrOut = SysAllocString(pwszThunkTemp);
  136. LocalFree(pwszThunkTemp);
  137. }
  138. }
  139. return bstrOut;
  140. }
  141. HRESULT ADRestoreNextButton(CICWApprentice *pApp, HWND hDlg)
  142. {
  143. HRESULT hr = S_OK;
  144. g_fRequestCancelled = TRUE;
  145. if (g_pAutoDiscoveryObject)
  146. {
  147. g_pAutoDiscoveryObject->RestoreNextButton(GetDlgItem(GetParent(hDlg), IDD_WIZARD_NEXT_BUTTON));
  148. delete g_pAutoDiscoveryObject;
  149. g_pAutoDiscoveryObject = NULL;
  150. }
  151. return hr;
  152. }
  153. HRESULT CreateAccountName(IN CICWApprentice *pApp, IN ACCTDATA * pData);
  154. HRESULT OnADCompleted(CICWApprentice *pApp, HWND hDlg)
  155. {
  156. HRESULT hr = E_OUTOFMEMORY;
  157. if (g_pAutoDiscoveryObject)
  158. {
  159. ACCTDATA * pData = pApp->GetAccountData();
  160. hr = g_pAutoDiscoveryObject->OnCompleted(pApp, pData);
  161. if (SUCCEEDED(hr))
  162. {
  163. // Set the display name for the account.
  164. CreateAccountName(pApp, pData);
  165. }
  166. else
  167. {
  168. // TODO: If _fUseWebMail is set, we will probably want
  169. // to navigate to a page telling the user to use a web
  170. // page to get their email.
  171. }
  172. }
  173. return hr;
  174. }
  175. #define SZ_HOTMAILDOMAIN "@hotmail.com"
  176. #define CH_EMAILDOMAINSEPARATOR '@'
  177. HRESULT CAutoDiscoveryHelper::StartAutoDiscovery(IN CICWApprentice *pApp, IN HWND hDlg, IN BOOL fFirstInit)
  178. {
  179. HRESULT hr = E_OUTOFMEMORY;
  180. ACCTDATA * pData = pApp->GetAccountData();
  181. if (pData && pData->szEmail)
  182. {
  183. LPCSTR pszEmailDomain = StrChrA(pData->szEmail, CH_EMAILDOMAINSEPARATOR);
  184. if (pszEmailDomain && !StrCmpI(SZ_HOTMAILDOMAIN, pszEmailDomain)) // Is this a HOTMAIL.COM account?
  185. {
  186. // Yes, so skip AutoDiscovery since we don't require the user
  187. // to enter hard settings in that case. (Protocol and server settings never
  188. // change)
  189. hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
  190. }
  191. else
  192. {
  193. WCHAR szEmail[1024];
  194. SHAnsiToUnicode(pData->szEmail, szEmail, ARRAYSIZE(szEmail));
  195. _hwndDlgParent = hDlg;
  196. // Set Animation.
  197. HWND hwndAnimation = GetDlgItem(hDlg, IDC_AUTODISCOVERY_ANIMATION);
  198. if (hwndAnimation)
  199. {
  200. _hInstAutoDisc = LoadLibrary(SZ_DLL_AUTODISC);
  201. if (_hInstAutoDisc)
  202. {
  203. Animate_OpenEx(hwndAnimation, _hInstAutoDisc, IDA_DOWNLOADINGSETTINGS);
  204. }
  205. }
  206. HWND hwndWizard = GetParent(hDlg);
  207. if (hwndWizard)
  208. {
  209. SetNextButton(GetDlgItem(hwndWizard, IDD_WIZARD_NEXT_BUTTON));
  210. }
  211. ATOMICRELEASE(_pMailAutoDiscovery);
  212. // Start the background task.
  213. hr = CoCreateInstance(CLSID_MailAutoDiscovery, NULL, CLSCTX_INPROC_SERVER, IID_IMailAutoDiscovery, (void **)&_pMailAutoDiscovery);
  214. if (SUCCEEDED(hr))
  215. {
  216. hr = _pMailAutoDiscovery->WorkAsync(hDlg, WM_AUTODISCOVERY_FINISHED);
  217. if (SUCCEEDED(hr))
  218. {
  219. BSTR bstrEmail = SysAllocString(szEmail);
  220. if (bstrEmail)
  221. {
  222. hr = _pMailAutoDiscovery->DiscoverMail(bstrEmail);
  223. if (SUCCEEDED(hr))
  224. {
  225. g_fRequestCancelled = FALSE;
  226. }
  227. SysFreeString(bstrEmail);
  228. }
  229. else
  230. {
  231. hr = E_OUTOFMEMORY;
  232. }
  233. }
  234. }
  235. }
  236. }
  237. else
  238. {
  239. hr = E_FAIL;
  240. }
  241. if (FAILED(hr))
  242. {
  243. PropSheet_PressButton(GetParent(hDlg), PSBTN_NEXT);
  244. }
  245. return hr;
  246. }
  247. HRESULT CAutoDiscoveryHelper::SetNextButton(HWND hwndButton)
  248. {
  249. HRESULT hr = S_OK;
  250. TCHAR szSkipButton[MAX_PATH];
  251. // First, change the "Next" button into "Skip"
  252. // Save the text on the next button before we rename it.
  253. if (hwndButton && !GetWindowText(hwndButton, _szNextText, ARRAYSIZE(_szNextText)))
  254. {
  255. _szNextText[0] = 0; // terminate string in failure case.
  256. }
  257. // Set the next text.
  258. LoadString(g_hInstRes, idsADSkipButton, szSkipButton, ARRAYSIZE(szSkipButton));
  259. SetWindowText(hwndButton, szSkipButton);
  260. return hr;
  261. }
  262. HRESULT CAutoDiscoveryHelper::RestoreNextButton(HWND hwndButton)
  263. {
  264. HRESULT hr = S_OK;
  265. if (_szNextText[0])
  266. {
  267. // Restore the Next button text.
  268. SetWindowText(hwndButton, _szNextText);
  269. }
  270. return hr;
  271. }
  272. /****************************************************\
  273. DESCRIPTION:
  274. \****************************************************/
  275. HRESULT CAutoDiscoveryHelper::OnCompleted(IN CICWApprentice *pApp, IN ACCTDATA *pData)
  276. {
  277. // Step 1. Get all the settings from IMailAutoDiscovery to EMAIL_SERVER_SETTINGS
  278. EMAIL_SERVER_SETTINGS emailServerSettings = {0};
  279. emailServerSettings.nProtocol = -1;
  280. emailServerSettings.nServer1Port = -1;
  281. emailServerSettings.nServer2Port = -1;
  282. HRESULT hr = _GetAccountInformation(&emailServerSettings);
  283. g_uNextPage = ORD_PAGE_AD_MAILSERVER; // Assume we fail and we need to ask for the server settings.
  284. // Did the AutoDiscovery process succeed?
  285. if (SUCCEEDED(hr))
  286. {
  287. if (emailServerSettings.fDisplayInfoURL)
  288. {
  289. g_uNextPage = ORD_PAGE_AD_GOTOSERVERINFO;
  290. StrCpyNW(g_szInfoURL, emailServerSettings.bstrInfoURL, ARRAYSIZE(g_szInfoURL));
  291. }
  292. else if (emailServerSettings.fUseWebMail)
  293. {
  294. g_uNextPage = ORD_PAGE_AD_USEWEBMAIL;
  295. StrCpyNW(g_szWebMailURL, emailServerSettings.bstrServer1Name, ARRAYSIZE(g_szWebMailURL));
  296. }
  297. else
  298. {
  299. g_uNextPage = ORD_PAGE_AD_MAILNAME;
  300. if (pApp && pData && pApp->m_pAcct)
  301. {
  302. // Step 2. Move all the settings from EMAIL_SERVER_SETTINGS to the OE mail account (ACCTDATA).
  303. IImnAccount * pAcct = pApp->m_pAcct;
  304. pData->fLogon = FALSE; // BUGBUG: When is this needed? DAV?
  305. pData->fSPA = emailServerSettings.fUsesSPA;
  306. pData->fServerTypes = emailServerSettings.nProtocol;
  307. Assert(!pData->fCreateNewAccount);
  308. if (emailServerSettings.bstrDisplayName)
  309. {
  310. SHUnicodeToAnsi(emailServerSettings.bstrDisplayName, pData->szName, ARRAYSIZE(pData->szName));
  311. }
  312. if (emailServerSettings.bstrServer1Name)
  313. {
  314. SHUnicodeToAnsi(emailServerSettings.bstrServer1Name, pData->szSvr1, ARRAYSIZE(pData->szSvr1));
  315. }
  316. if (emailServerSettings.bstrLoginName)
  317. {
  318. SHUnicodeToAnsi(emailServerSettings.bstrLoginName, pData->szUsername, ARRAYSIZE(pData->szUsername));
  319. }
  320. if (emailServerSettings.nProtocol & (SRV_POP3 | SRV_IMAP))
  321. {
  322. pAcct->SetPropDw(((emailServerSettings.nProtocol & SRV_POP3) ? AP_POP3_SSL : AP_IMAP_SSL), emailServerSettings.fUsesSSL);
  323. if (-1 != emailServerSettings.nServer1Port)
  324. {
  325. pAcct->SetPropDw(((emailServerSettings.nProtocol & SRV_POP3) ? AP_POP3_PORT : AP_IMAP_PORT), emailServerSettings.nServer1Port);
  326. }
  327. }
  328. if (emailServerSettings.nProtocol & SRV_SMTP)
  329. {
  330. if (emailServerSettings.bstrServer2Name)
  331. {
  332. SHUnicodeToAnsi(emailServerSettings.bstrServer2Name, pData->szSvr2, ARRAYSIZE(pData->szSvr2));
  333. }
  334. if (-1 != emailServerSettings.nServer2Port)
  335. {
  336. pAcct->SetPropDw(AP_SMTP_PORT, emailServerSettings.nServer2Port);
  337. }
  338. pAcct->SetPropDw(AP_SMTP_SSL, emailServerSettings.fSMTPUsesSSL);
  339. if (!emailServerSettings.fAuthSMTP)
  340. {
  341. pAcct->SetPropDw(AP_SMTP_USE_SICILY, SMTP_AUTH_NONE);
  342. }
  343. else
  344. {
  345. if (emailServerSettings.fAuthSMTPPOP)
  346. {
  347. pAcct->SetPropDw(AP_SMTP_USE_SICILY, SMTP_AUTH_USE_POP3ORIMAP_SETTINGS);
  348. }
  349. else
  350. {
  351. if (emailServerSettings.fAuthSMTPSPA)
  352. {
  353. pAcct->SetPropDw(AP_SMTP_USE_SICILY, SMTP_AUTH_SICILY);
  354. }
  355. else
  356. {
  357. pAcct->SetPropDw(AP_SMTP_USE_SICILY, SMTP_AUTH_USE_SMTP_SETTINGS);
  358. }
  359. if (emailServerSettings.bstrSMTPLoginName)
  360. {
  361. TCHAR szSMTPUserName[CCHMAX_ACCT_PROP_SZ];
  362. WideCharToMultiByte(CP_ACP, 0, emailServerSettings.bstrSMTPLoginName, -1, szSMTPUserName, ARRAYSIZE(szSMTPUserName), NULL, NULL);
  363. pAcct->SetPropSz(AP_SMTP_USERNAME, szSMTPUserName);
  364. }
  365. pAcct->SetPropDw(AP_SMTP_PROMPT_PASSWORD, TRUE);
  366. }
  367. }
  368. }
  369. }
  370. }
  371. // Step 3. Free all the memory in EMAIL_SERVER_SETTINGS
  372. FreeEmailServerSettings(&emailServerSettings);
  373. }
  374. return hr;
  375. }
  376. /****************************************************\
  377. DESCRIPTION:
  378. \****************************************************/
  379. HRESULT CAutoDiscoveryHelper::_GetAccountInformation(EMAIL_SERVER_SETTINGS * pEmailServerSettings)
  380. {
  381. BSTR bstrPreferedProtocol;
  382. HRESULT hr = S_OK;
  383. // We ignore hr because getting the display name is optinal.
  384. _pMailAutoDiscovery->get_DisplayName(&pEmailServerSettings->bstrDisplayName);
  385. hr = _pMailAutoDiscovery->get_PreferedProtocolType(&bstrPreferedProtocol);
  386. // Loop thru the list looking for the first instance of a protocol
  387. // that we support.
  388. if (StrCmpIW(bstrPreferedProtocol, STR_PT_POP) &&
  389. StrCmpIW(bstrPreferedProtocol, STR_PT_IMAP) &&
  390. StrCmpIW(bstrPreferedProtocol, STR_PT_DAVMAIL))
  391. {
  392. long nSize;
  393. hr = _pMailAutoDiscovery->get_length(&nSize);
  394. if (SUCCEEDED(hr))
  395. {
  396. VARIANT varIndex;
  397. varIndex.vt = VT_I4;
  398. SysFreeString(bstrPreferedProtocol);
  399. for (long nIndex = 1; (nIndex < nSize); nIndex++)
  400. {
  401. IMailProtocolADEntry * pMailProtocol;
  402. varIndex.lVal = nIndex;
  403. if (SUCCEEDED(_pMailAutoDiscovery->get_item(varIndex, &pMailProtocol)))
  404. {
  405. hr = pMailProtocol->get_Protocol(&bstrPreferedProtocol);
  406. pMailProtocol->Release();
  407. pMailProtocol = NULL;
  408. if (SUCCEEDED(hr))
  409. {
  410. // Is this protocol one of the ones we support?
  411. if (!StrCmpIW(bstrPreferedProtocol, STR_PT_POP) ||
  412. !StrCmpIW(bstrPreferedProtocol, STR_PT_IMAP) ||
  413. !StrCmpIW(bstrPreferedProtocol, STR_PT_DAVMAIL))
  414. {
  415. hr = S_OK;
  416. break;
  417. }
  418. SysFreeString(bstrPreferedProtocol);
  419. bstrPreferedProtocol = NULL;
  420. }
  421. }
  422. }
  423. }
  424. }
  425. // TODO: Handle the Web Based mail case.
  426. if (!StrCmpIW(bstrPreferedProtocol, STR_PT_POP)) pEmailServerSettings->nProtocol = (SRV_POP3 | SRV_SMTP);
  427. else if (!StrCmpIW(bstrPreferedProtocol, STR_PT_IMAP)) pEmailServerSettings->nProtocol = (SRV_IMAP | SRV_SMTP);
  428. else if (!StrCmpIW(bstrPreferedProtocol, STR_PT_DAVMAIL)) pEmailServerSettings->nProtocol = SRV_HTTPMAIL;
  429. // We need to reject Web Base Mail. In the future, we may want to give a page
  430. // for them to launch the web browser to read their mail.
  431. if (SUCCEEDED(hr) && bstrPreferedProtocol &&
  432. (!StrCmpIW(bstrPreferedProtocol, STR_PT_POP) ||
  433. !StrCmpIW(bstrPreferedProtocol, STR_PT_IMAP) ||
  434. !StrCmpIW(bstrPreferedProtocol, STR_PT_DAVMAIL)))
  435. {
  436. VARIANT varIndex;
  437. IMailProtocolADEntry * pMailProtocol;
  438. varIndex.vt = VT_BSTR;
  439. varIndex.bstrVal = bstrPreferedProtocol;
  440. hr = _pMailAutoDiscovery->get_item(varIndex, &pMailProtocol);
  441. if (SUCCEEDED(hr))
  442. {
  443. hr = pMailProtocol->get_ServerName(&pEmailServerSettings->bstrServer1Name);
  444. if (SUCCEEDED(hr))
  445. {
  446. BSTR bstrPortNum;
  447. // Having a custom port number is optional.
  448. if (SUCCEEDED(pMailProtocol->get_ServerPort(&bstrPortNum)))
  449. {
  450. pEmailServerSettings->nServer1Port = StrToIntW(bstrPortNum);
  451. SysFreeString(bstrPortNum);
  452. }
  453. if (SUCCEEDED(hr))
  454. {
  455. VARIANT_BOOL vfSPA = VARIANT_FALSE;
  456. if (SUCCEEDED(pMailProtocol->get_UseSPA(&vfSPA)))
  457. {
  458. pEmailServerSettings->fUsesSPA = (VARIANT_TRUE == vfSPA);
  459. }
  460. pMailProtocol->get_LoginName(&pEmailServerSettings->bstrLoginName);
  461. }
  462. VARIANT_BOOL vfSSL = VARIANT_FALSE;
  463. if (SUCCEEDED(pMailProtocol->get_UseSSL(&vfSSL)))
  464. {
  465. pEmailServerSettings->fUsesSSL = (VARIANT_TRUE == vfSSL);
  466. }
  467. }
  468. pMailProtocol->Release();
  469. }
  470. // Is this one of the protocols that requires a second server?
  471. if (!StrCmpIW(bstrPreferedProtocol, STR_PT_POP) ||
  472. !StrCmpIW(bstrPreferedProtocol, STR_PT_IMAP))
  473. {
  474. varIndex.bstrVal = STR_PT_SMTP;
  475. hr = _pMailAutoDiscovery->get_item(varIndex, &pMailProtocol);
  476. if (SUCCEEDED(hr))
  477. {
  478. hr = pMailProtocol->get_ServerName(&pEmailServerSettings->bstrServer2Name);
  479. if (SUCCEEDED(hr))
  480. {
  481. BSTR bstrPortNum;
  482. // Having a custom port number is optional.
  483. if (SUCCEEDED(pMailProtocol->get_ServerPort(&bstrPortNum)))
  484. {
  485. pEmailServerSettings->nServer2Port = StrToIntW(bstrPortNum);
  486. SysFreeString(bstrPortNum);
  487. }
  488. // TODO: Read in _fAuthSMTP and _fAuthSMTPPOP
  489. VARIANT_BOOL vfSPA = VARIANT_FALSE;
  490. if (SUCCEEDED(pMailProtocol->get_UseSPA(&vfSPA)))
  491. {
  492. pEmailServerSettings->fAuthSMTPSPA = (VARIANT_TRUE == vfSPA);
  493. }
  494. VARIANT_BOOL vfAuthSMTP = VARIANT_FALSE;
  495. if (SUCCEEDED(pMailProtocol->get_IsAuthRequired(&vfAuthSMTP)))
  496. {
  497. pEmailServerSettings->fAuthSMTP = (VARIANT_TRUE == vfAuthSMTP);
  498. }
  499. VARIANT_BOOL vfAuthFromPOP = VARIANT_FALSE;
  500. if (SUCCEEDED(pMailProtocol->get_SMTPUsesPOP3Auth(&vfAuthFromPOP)))
  501. {
  502. pEmailServerSettings->fAuthSMTPPOP = (VARIANT_TRUE == vfAuthFromPOP);
  503. }
  504. VARIANT_BOOL vfSSL = VARIANT_FALSE;
  505. if (SUCCEEDED(pMailProtocol->get_UseSSL(&vfSSL)))
  506. {
  507. pEmailServerSettings->fSMTPUsesSSL = (VARIANT_TRUE == vfSSL);
  508. }
  509. pMailProtocol->get_LoginName(&pEmailServerSettings->bstrSMTPLoginName);
  510. }
  511. pMailProtocol->Release();
  512. }
  513. }
  514. SysFreeString(bstrPreferedProtocol);
  515. }
  516. if (SUCCEEDED(hr) && (-1 == pEmailServerSettings->nProtocol))
  517. {
  518. hr = E_FAIL;
  519. }
  520. if (FAILED(hr) && (-1 == pEmailServerSettings->nProtocol))
  521. {
  522. // Does this email account work with web based email?
  523. VARIANT varIndex;
  524. varIndex.vt = VT_BSTR;
  525. varIndex.bstrVal = SysAllocString(STR_PT_WEBBASED);
  526. if (varIndex.bstrVal)
  527. {
  528. IMailProtocolADEntry * pMailProtocol;
  529. if (SUCCEEDED(_pMailAutoDiscovery->get_item(varIndex, &pMailProtocol)))
  530. {
  531. // Yes, web bases mail is supported. So remember that for later.
  532. pEmailServerSettings->fUseWebMail = TRUE;
  533. hr = pMailProtocol->get_ServerName(&pEmailServerSettings->bstrServer1Name);
  534. pMailProtocol->Release();
  535. }
  536. VariantClear(&varIndex);
  537. }
  538. }
  539. if (FAILED(hr) && (-1 == pEmailServerSettings->nProtocol))
  540. {
  541. // Did the server provide an INFO URL for the user?
  542. hr = _pMailAutoDiscovery->get_InfoURL(&pEmailServerSettings->bstrInfoURL);
  543. if (SUCCEEDED(hr))
  544. {
  545. pEmailServerSettings->fDisplayInfoURL = TRUE;
  546. }
  547. }
  548. return hr;
  549. }
  550. /****************************************************\
  551. Constructor
  552. \****************************************************/
  553. CAutoDiscoveryHelper::CAutoDiscoveryHelper()
  554. {
  555. DllAddRef();
  556. // ASSERT zero initialized because we can only be created in the heap. (Private destructor)
  557. _hwndDlgParent = NULL;
  558. _szNextText[0] = 0;
  559. _pMailAutoDiscovery = NULL;
  560. _hInstAutoDisc = NULL;
  561. }
  562. /****************************************************\
  563. Destructor
  564. \****************************************************/
  565. CAutoDiscoveryHelper::~CAutoDiscoveryHelper()
  566. {
  567. if (_pMailAutoDiscovery)
  568. {
  569. _pMailAutoDiscovery->Release();
  570. _pMailAutoDiscovery = NULL;
  571. }
  572. if (_hInstAutoDisc)
  573. {
  574. FreeLibrary(_hInstAutoDisc);
  575. }
  576. DllRelease();
  577. }
  578. //===========================
  579. // *** Public APIs ***
  580. //===========================
  581. BOOL CALLBACK AutoDiscoveryInitProc(CICWApprentice *pApp, HWND hDlg, BOOL fFirstInit)
  582. {
  583. if (fFirstInit)
  584. {
  585. g_fRequestCancelled = TRUE;
  586. g_uNextPage = ORD_PAGE_AD_MAILSERVER; // Assume we fail and we need to ask for the server settings.
  587. }
  588. if (!g_pAutoDiscoveryObject)
  589. {
  590. Assert(!g_pAutoDiscoveryObject);
  591. g_pAutoDiscoveryObject = new CAutoDiscoveryHelper();
  592. if (g_pAutoDiscoveryObject)
  593. {
  594. g_pAutoDiscoveryObject->StartAutoDiscovery(pApp, hDlg, fFirstInit);
  595. }
  596. }
  597. return TRUE;
  598. }
  599. BOOL CALLBACK AutoDiscoveryOKProc(CICWApprentice *pApp, HWND hDlg, BOOL fForward, UINT *puNextPage)
  600. {
  601. g_fRequestCancelled = TRUE;
  602. if (fForward)
  603. {
  604. *puNextPage = g_uNextPage;
  605. }
  606. else
  607. {
  608. // If we have the passifier page turned off, we want to skip that page.
  609. if (!SHRegGetBoolUSValue(SZ_REGKEY_AUTODISCOVERY, SZ_REGVALUE_AUTODISCOVERY_PASSIFIER, FALSE, TRUE))
  610. {
  611. *puNextPage = ORD_PAGE_AD_MAILADDRESS;
  612. }
  613. }
  614. ADRestoreNextButton(pApp, hDlg);
  615. g_uNextPage = ORD_PAGE_AD_MAILSERVER; // Assume we fail and we need to ask for the server settings.
  616. return(TRUE);
  617. }
  618. BOOL CALLBACK AutoDiscoveryCmdProc(CICWApprentice *pApp, HWND hDlg, WPARAM wParam, LPARAM lParam)
  619. {
  620. return(TRUE);
  621. }
  622. BOOL CALLBACK AutoDiscoveryWMUserProc(CICWApprentice *pApp, HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  623. {
  624. switch (uMsg)
  625. {
  626. case WM_AUTODISCOVERY_FINISHED:
  627. if (FALSE == g_fRequestCancelled)
  628. {
  629. // This is WM_AUTODISCOVERY_FINISHED
  630. BSTR bstXML = (BSTR) lParam;
  631. HRESULT hrAutoDiscoverySucceeded = (HRESULT) wParam;
  632. if (bstXML)
  633. {
  634. SysFreeString(bstXML); // We don't need the XML. This works if NULL
  635. }
  636. if (SUCCEEDED(hrAutoDiscoverySucceeded))
  637. {
  638. OnADCompleted(pApp, hDlg);
  639. }
  640. // Go to the next page.
  641. ADRestoreNextButton(pApp, hDlg);
  642. PropSheet_PressButton(GetParent(hDlg), PSBTN_NEXT);
  643. }
  644. break;
  645. case WM_AUTODISCOVERY_STATUSMSG:
  646. {
  647. // This is WM_AUTODISCOVERY_STATUSMSG
  648. LPWSTR pwzStatusMsg = (BSTR) wParam;
  649. if (pwzStatusMsg)
  650. {
  651. HWND hwndStatusText = GetDlgItem(hDlg, IDC_AUTODISCOVERY_STATUS);
  652. if (hwndStatusText)
  653. {
  654. SetWindowTextW(hwndStatusText, pwzStatusMsg);
  655. }
  656. LocalFree(pwzStatusMsg);
  657. }
  658. }
  659. break;
  660. }
  661. return(TRUE);
  662. }
  663. BOOL CALLBACK AutoDiscoveryCancelProc(CICWApprentice *pApp, HWND hDlg)
  664. {
  665. // This call will clean up our state and retore the back button.
  666. ADRestoreNextButton(pApp, hDlg);
  667. g_uNextPage = ORD_PAGE_AD_MAILSERVER; // Assume we fail and we need to ask for the server settings.
  668. return TRUE;
  669. }
  670. typedef BOOL (* PFN_LINKWINDOW_REGISTERCLASS) (void);
  671. typedef BOOL (* PFN_LINKWINDOW_UNREGISTERCLASS) (IN HINSTANCE hInst);
  672. #define ORD_LINKWINDOW_REGISTERCLASS 258
  673. #define ORD_LINKWINDOW_UNREGISTERCLASS 259
  674. BOOL LinkWindow_RegisterClass_DelayLoad(void)
  675. {
  676. BOOL returnValue = FALSE;
  677. // Delay load the SHELL32.DLL export (ordinal #258). This only works on Win2k and later.
  678. HINSTANCE hInstSHELL32 = LoadLibrary(TEXT("SHELL32.DLL"));
  679. if (hInstSHELL32)
  680. {
  681. PFN_LINKWINDOW_REGISTERCLASS pfnDelayLoad = (PFN_LINKWINDOW_REGISTERCLASS)GetProcAddress(hInstSHELL32, (LPCSTR)ORD_LINKWINDOW_REGISTERCLASS);
  682. if (pfnDelayLoad)
  683. {
  684. returnValue = pfnDelayLoad();
  685. }
  686. FreeLibrary(hInstSHELL32);
  687. }
  688. return returnValue;
  689. }
  690. void LinkWindow_UnregisterClass_DelayLoad(IN HINSTANCE hInst)
  691. {
  692. // Delay load the SHELL32.DLL export (ordinal #259). This only works on Win2k and later.
  693. HINSTANCE hInstSHELL32 = LoadLibrary(TEXT("SHELL32.DLL"));
  694. if (hInstSHELL32)
  695. {
  696. PFN_LINKWINDOW_UNREGISTERCLASS pfnDelayLoad = (PFN_LINKWINDOW_UNREGISTERCLASS)GetProcAddress(hInstSHELL32, (LPCSTR)ORD_LINKWINDOW_UNREGISTERCLASS);
  697. if (pfnDelayLoad)
  698. {
  699. BOOL returnValue = pfnDelayLoad(hInst);
  700. }
  701. FreeLibrary(hInstSHELL32);
  702. }
  703. }
  704. #define LINKWINDOW_CLASSW L"Link Window"
  705. BOOL IsOSNT(void)
  706. {
  707. OSVERSIONINFOA osVerInfoA;
  708. osVerInfoA.dwOSVersionInfoSize = sizeof(osVerInfoA);
  709. if (!GetVersionExA(&osVerInfoA))
  710. return VER_PLATFORM_WIN32_WINDOWS; // Default to this.
  711. return (VER_PLATFORM_WIN32_NT == osVerInfoA.dwPlatformId);
  712. }
  713. DWORD GetOSVer(void)
  714. {
  715. OSVERSIONINFOA osVerInfoA;
  716. osVerInfoA.dwOSVersionInfoSize = sizeof(osVerInfoA);
  717. if (!GetVersionExA(&osVerInfoA))
  718. return VER_PLATFORM_WIN32_WINDOWS; // Default to this.
  719. return osVerInfoA.dwMajorVersion;
  720. }
  721. HRESULT ConvertTextToLinkWindow(HWND hDlg, int idControl, int idStringID)
  722. {
  723. WCHAR szTempString[MAX_URL_STRING];
  724. HRESULT hr = S_OK;
  725. HWND hwndText = GetDlgItem(hDlg, idControl);
  726. RECT rcWindow;
  727. HMENU hMenu = (HMENU)IntToPtr(idControl + 10);
  728. LoadStringW(g_hInstRes, idStringID, szTempString, ARRAYSIZE(szTempString));
  729. GetClientRect(hwndText, &rcWindow);
  730. MapWindowPoints(hwndText, hDlg, (POINT*)&rcWindow, 2);
  731. HWND hwndLink = CreateWindowW(LINKWINDOW_CLASSW, szTempString, (WS_TABSTOP | WS_CHILDWINDOW),
  732. rcWindow.left, rcWindow.top, RECTWIDTH(rcWindow), RECTHEIGHT(rcWindow), hDlg, hMenu, g_hInstRes, NULL);
  733. DWORD dwError = GetLastError(); //todo;
  734. if (hwndLink)
  735. {
  736. SetWindowTextW(hwndLink, szTempString);
  737. ShowWindow(hwndLink, SW_SHOW);
  738. }
  739. EnableWindow(hwndText, FALSE);
  740. ShowWindow(hwndText, SW_HIDE);
  741. return hr;
  742. }
  743. HRESULT GetEmailAddress(CICWApprentice *pApp, LPSTR pszEmailAddress, int cchSize)
  744. {
  745. ACCTDATA * pData = pApp->GetAccountData();
  746. StrCpyNA(pszEmailAddress, "", cchSize); // Initialize the string to empty.
  747. if (pData && pData->szEmail)
  748. {
  749. StrCpyNA(pszEmailAddress, pData->szEmail, cchSize); // Initialize the string to empty.
  750. }
  751. return S_OK;
  752. }
  753. HRESULT GetEmailAddressDomain(CICWApprentice *pApp, LPSTR pszEmailAddress, int cchSize)
  754. {
  755. ACCTDATA * pData = pApp->GetAccountData();
  756. StrCpyNA(pszEmailAddress, "", cchSize); // Initialize the string to empty.
  757. if (pData && pData->szEmail)
  758. {
  759. LPCSTR pszEmailDomain = StrChrA(pData->szEmail, CH_EMAILDOMAINSEPARATOR);
  760. if (pszEmailDomain)
  761. {
  762. StrCpyNA(pszEmailAddress, CharNext(pszEmailDomain), cchSize); // Initialize the string to empty.
  763. }
  764. }
  765. return S_OK;
  766. }
  767. BOOL CALLBACK TheInitProc(CICWApprentice *pApp, HWND hDlg, BOOL fFirstInit, int idControlFirst, LPWSTR pszURL, int cchURLSize)
  768. {
  769. BOOL fReset = fFirstInit;
  770. if (!fReset)
  771. {
  772. WCHAR szPreviousURL[MAX_URL_STRING];
  773. GetWindowTextW(GetDlgItem(hDlg, idControlFirst+1), szPreviousURL, ARRAYSIZE(szPreviousURL));
  774. // If the URL has changed, we need to reload the info.
  775. if (StrCmpIW(pszURL, szPreviousURL))
  776. {
  777. DestroyWindow(GetDlgItem(hDlg, idControlFirst+1+10));
  778. DestroyWindow(GetDlgItem(hDlg, idControlFirst+2+10));
  779. fReset = TRUE;
  780. }
  781. }
  782. if (fReset)
  783. {
  784. // TODO: This won't work on downlevel. So use plain text.
  785. BOOL fLinksSupported = LinkWindow_RegisterClass_DelayLoad();
  786. TCHAR szTempStr1[MAX_URL_STRING*3];
  787. TCHAR szTempStr2[MAX_URL_STRING*3];
  788. CHAR szTempStr3[MAX_PATH];
  789. // Replace the %s in the first line to the domain name.
  790. GetWindowText(GetDlgItem(hDlg, idControlFirst), szTempStr1, ARRAYSIZE(szTempStr1));
  791. GetEmailAddress(pApp, szTempStr3, ARRAYSIZE(szTempStr3));
  792. wnsprintf(szTempStr2, ARRAYSIZE(szTempStr2), szTempStr1, szTempStr3, szTempStr3);
  793. SetWindowText(GetDlgItem(hDlg, idControlFirst), szTempStr2);
  794. SetWindowTextW(GetDlgItem(hDlg, idControlFirst+1), pszURL);
  795. // We only support Win2k and later because we don't want to worry about
  796. // the fact that the "LinkWindow" class doesn't have an "W" and "A" version.
  797. if (fLinksSupported && IsOSNT() && (5 <= GetOSVer()))
  798. {
  799. ConvertTextToLinkWindow(hDlg, idControlFirst+1, idsADURLLink);
  800. ConvertTextToLinkWindow(hDlg, idControlFirst+2, idsADUseWebMsg);
  801. // Replace the %s in the second line to the URL.
  802. GetWindowText(GetDlgItem(hDlg, idControlFirst+1+10), szTempStr1, ARRAYSIZE(szTempStr1));
  803. wnsprintf(szTempStr2, ARRAYSIZE(szTempStr2), szTempStr1, pszURL, pszURL);
  804. SetWindowText(GetDlgItem(hDlg, idControlFirst+1+10), szTempStr2);
  805. // Set the hyperlink URL in the Click here link.
  806. GetWindowText(GetDlgItem(hDlg, idControlFirst+2+10), szTempStr1, ARRAYSIZE(szTempStr1));
  807. wnsprintf(szTempStr2, ARRAYSIZE(szTempStr2), szTempStr1, pszURL);
  808. SetWindowText(GetDlgItem(hDlg, idControlFirst+2+10), szTempStr2);
  809. }
  810. }
  811. return TRUE;
  812. }
  813. BOOL CALLBACK UseWebMailInitProc(CICWApprentice *pApp, HWND hDlg, BOOL fFirstInit)
  814. {
  815. return TheInitProc(pApp, hDlg, fFirstInit, IDC_USEWEB_LINE1, g_szWebMailURL, ARRAYSIZE(g_szWebMailURL));
  816. }
  817. BOOL CALLBACK UseWebMailOKProc(CICWApprentice *pApp, HWND hDlg, BOOL fForward, UINT *puNextPage)
  818. {
  819. if (fForward)
  820. {
  821. *puNextPage = ORD_PAGE_AD_MAILSERVER;
  822. }
  823. else
  824. {
  825. *puNextPage = ORD_PAGE_AD_MAILADDRESS;
  826. }
  827. LinkWindow_UnregisterClass_DelayLoad(g_hInstRes);
  828. return(TRUE);
  829. }
  830. BOOL CALLBACK UseWebMailCmdProc(CICWApprentice *pApp, HWND hDlg, WPARAM wParam, LPARAM lParam)
  831. {
  832. LinkWindow_UnregisterClass_DelayLoad(g_hInstRes);
  833. return(TRUE);
  834. }
  835. BOOL CALLBACK GotoServerInfoInitProc(CICWApprentice *pApp, HWND hDlg, BOOL fFirstInit)
  836. {
  837. return TheInitProc(pApp, hDlg, fFirstInit, IDC_GETINFO_LINE1, g_szInfoURL, ARRAYSIZE(g_szInfoURL));
  838. }
  839. BOOL CALLBACK GotoServerInfoOKProc(CICWApprentice *pApp, HWND hDlg, BOOL fForward, UINT *puNextPage)
  840. {
  841. if (fForward)
  842. {
  843. *puNextPage = ORD_PAGE_AD_MAILSERVER;
  844. }
  845. else
  846. {
  847. *puNextPage = ORD_PAGE_AD_MAILADDRESS;
  848. }
  849. return(TRUE);
  850. }
  851. BOOL CALLBACK GotoServerInfoCmdProc(CICWApprentice *pApp, HWND hDlg, WPARAM wParam, LPARAM lParam)
  852. {
  853. LinkWindow_UnregisterClass_DelayLoad(g_hInstRes);
  854. return(TRUE);
  855. }
  856. BOOL CALLBACK PassifierInitProc(CICWApprentice *pApp, HWND hDlg, BOOL fFirstInit)
  857. {
  858. TCHAR szTemplate[1024];
  859. TCHAR szPrivacyText[1024];
  860. TCHAR szEmail[MAX_PATH];
  861. TCHAR szDomain[MAX_PATH];
  862. if (FAILED(GetEmailAddressDomain(pApp, szDomain, ARRAYSIZE(szDomain))))
  863. {
  864. szDomain[0] = 0;
  865. }
  866. // Set the next text.
  867. LoadString(g_hInstRes, ids_ADPassifier_Warning, szTemplate, ARRAYSIZE(szTemplate));
  868. wnsprintf(szPrivacyText, ARRAYSIZE(szPrivacyText), szTemplate, szDomain);
  869. SetWindowText(GetDlgItem(hDlg, IDC_PASSIFIER_PRIVACYWARNING), szPrivacyText);
  870. // Load up the list boxes
  871. IMailAutoDiscovery * pMailAutoDiscovery;
  872. HWND hwndListBox;
  873. if (FAILED(GetEmailAddress(pApp, szEmail, ARRAYSIZE(szEmail))))
  874. {
  875. szEmail[0] = 0;
  876. }
  877. HRESULT hr = CoCreateInstance(CLSID_MailAutoDiscovery, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IMailAutoDiscovery, &pMailAutoDiscovery));
  878. if (SUCCEEDED(hr))
  879. {
  880. IAutoDiscoveryProvider * pProviders;
  881. BSTR bstrEmail = SysAllocStringA(szEmail);
  882. hr = pMailAutoDiscovery->getPrimaryProviders(bstrEmail, &pProviders);
  883. if (SUCCEEDED(hr))
  884. {
  885. long nTotal = 0;
  886. VARIANT varIndex;
  887. hwndListBox = GetDlgItem(hDlg, IDC_PASSIFIER_PRIMARYLIST);
  888. if (hwndListBox)
  889. {
  890. varIndex.vt = VT_I4;
  891. pProviders->get_length(&nTotal);
  892. for (varIndex.lVal = 0; (varIndex.lVal < nTotal) && (varIndex.lVal <= 3); varIndex.lVal++)
  893. {
  894. BSTR bstrDomain;
  895. if (SUCCEEDED(pProviders->get_item(varIndex, &bstrDomain)))
  896. {
  897. CHAR szDomain[MAX_PATH];
  898. SHUnicodeToAnsi(bstrDomain, szDomain, ARRAYSIZE(szDomain));
  899. SetWindowTextA(GetDlgItem(hDlg, IDC_PASSIFIER_PRIMARYLIST + varIndex.lVal), szDomain);
  900. SysFreeString(bstrDomain);
  901. }
  902. }
  903. }
  904. pProviders->Release();
  905. }
  906. hr = pMailAutoDiscovery->getSecondaryProviders(bstrEmail, &pProviders);
  907. if (SUCCEEDED(hr))
  908. {
  909. long nTotal = 0;
  910. VARIANT varIndex;
  911. hwndListBox = GetDlgItem(hDlg, IDC_PASSIFIER_SECONDARYLIST);
  912. if (hwndListBox)
  913. {
  914. varIndex.vt = VT_I4;
  915. pProviders->get_length(&nTotal);
  916. for (varIndex.lVal = 0; (varIndex.lVal < nTotal) && (varIndex.lVal <= 3); varIndex.lVal++)
  917. {
  918. BSTR bstrURL; // The secondary servers are URLs
  919. if (SUCCEEDED(pProviders->get_item(varIndex, &bstrURL)))
  920. {
  921. CHAR szURL[MAX_PATH];
  922. CHAR szDomain[MAX_PATH];
  923. DWORD cchSize = ARRAYSIZE(szDomain);
  924. SHUnicodeToAnsi(bstrURL, szURL, ARRAYSIZE(szURL));
  925. UrlGetPart(szURL, szDomain, &cchSize, URL_PART_HOSTNAME, 0);
  926. SetWindowTextA(GetDlgItem(hDlg, IDC_PASSIFIER_SECONDARYLIST + varIndex.lVal), szDomain);
  927. SysFreeString(bstrURL);
  928. }
  929. }
  930. }
  931. pProviders->Release();
  932. }
  933. SysFreeString(bstrEmail);
  934. pMailAutoDiscovery->Release();
  935. }
  936. // Set the manual checkbox
  937. BOOL fManuallyConfigure = SHRegGetBoolUSValue(SZ_REGKEY_AUTODISCOVERY, SZ_REGVALUE_AUTODISCOVERY_OEMANUAL, FALSE, FALSE);
  938. CheckDlgButton(hDlg, IDC_PASSIFIER_SKIPCHECKBOX, (fManuallyConfigure ? BST_CHECKED : BST_UNCHECKED));
  939. return TRUE;
  940. }
  941. #define SZ_TRUE TEXT("TRUE")
  942. #define SZ_FALSE TEXT("FALSE")
  943. BOOL CALLBACK PassifierOKProc(CICWApprentice *pApp, HWND hDlg, BOOL fForward, UINT *puNextPage)
  944. {
  945. if (fForward)
  946. {
  947. BOOL fManuallyConfigure = (BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_PASSIFIER_SKIPCHECKBOX));
  948. SHSetValue(HKEY_CURRENT_USER, SZ_REGKEY_AUTODISCOVERY, SZ_REGVALUE_AUTODISCOVERY_OEMANUAL, REG_SZ,
  949. (LPCVOID)(fManuallyConfigure ? SZ_TRUE : SZ_FALSE), (fManuallyConfigure ? sizeof(SZ_TRUE) : sizeof(SZ_FALSE)));
  950. *puNextPage = (fManuallyConfigure ? ORD_PAGE_AD_MAILSERVER : ORD_PAGE_AD_AUTODISCOVERY);
  951. }
  952. else
  953. {
  954. *puNextPage = ORD_PAGE_AD_MAILADDRESS;
  955. }
  956. return TRUE;
  957. }
  958. BOOL CALLBACK PassifierCmdProc(CICWApprentice *pApp, HWND hDlg, WPARAM wParam, LPARAM lParam)
  959. {
  960. return TRUE;
  961. }