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.

6626 lines
207 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: dialogs.cpp
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: This module contains the code for the implementing the Dialog UI
  8. // functionality of Connection Manager.
  9. //
  10. // Copyright (c) 1996-1999 Microsoft Corporation
  11. //
  12. // Author: quintinb Created Header 8/17/99
  13. //
  14. //+----------------------------------------------------------------------------
  15. #include "cmmaster.h"
  16. #include "dialogs.h"
  17. #include "pnpuverp.h"
  18. #include "dial_str.h"
  19. #include "mon_str.h"
  20. #include "stp_str.h"
  21. #include "ras_str.h"
  22. #include "profile_str.h"
  23. #include "log_str.h"
  24. #include "tunl_str.h"
  25. #include "userinfo_str.h"
  26. //
  27. // Get the common function HasSpecifiedAccessToFileOrDir
  28. //
  29. #include "hasfileaccess.cpp"
  30. #include <pshpack1.h>
  31. typedef struct DLGTEMPLATEEX
  32. {
  33. WORD dlgVer;
  34. WORD signature;
  35. DWORD helpID;
  36. DWORD exStyle;
  37. DWORD style;
  38. WORD cDlgItems;
  39. short x;
  40. short y;
  41. short cx;
  42. short cy;
  43. } DLGTEMPLATEEX, *LPDLGTEMPLATEEX;
  44. #include <poppack.h>
  45. //
  46. // Timeout for the write properties mutex, in milliseconds
  47. //
  48. const DWORD WRITE_PROPERTIES_MUTEX_TIMEOUT = 1000*10;
  49. //************************************************************************
  50. // Globals
  51. //************************************************************************
  52. //
  53. // Original edit control and property sheet window procedures
  54. //
  55. WNDPROC CGeneralPage::m_pfnOrgEditWndProc = NULL;
  56. WNDPROC CNewAccessPointDlg::m_pfnOrgEditWndProc = NULL;
  57. WNDPROC CPropertiesSheet::m_pfnOrgPropSheetProc = NULL; // prop sheet
  58. CPropertiesSheet* CPropertiesSheet::m_pThis = NULL;
  59. //+---------------------------------------------------------------------------
  60. //
  61. // Function: CGeneralPage::UpdateNumberDescription
  62. //
  63. // Synopsis: Helper function to deal with updating the description edit,
  64. // by appending to the Phone Number: and Backup Number: labels
  65. //
  66. // Arguments: int nPhoneIdx - index of phone number to which this applies
  67. //
  68. // Returns: Nothing
  69. //
  70. // History: nickball - Created - 7/17/97
  71. //
  72. //----------------------------------------------------------------------------
  73. void CGeneralPage::UpdateNumberDescription(int nPhoneIdx, LPCTSTR pszDesc)
  74. {
  75. MYDBGASSERT(pszDesc);
  76. if (NULL == pszDesc)
  77. {
  78. return;
  79. }
  80. UINT nDescID = !nPhoneIdx ? IDC_GENERAL_P1_STATIC: IDC_GENERAL_P2_STATIC;
  81. LPTSTR pszTmp;
  82. //
  83. // Load the appropriate label as a base string
  84. //
  85. if (nPhoneIdx)
  86. {
  87. pszTmp = CmLoadString(g_hInst, IDS_BACKUP_NUM_LABEL);
  88. }
  89. else
  90. {
  91. pszTmp = CmLoadString(g_hInst, IDS_PHONE_NUM_LABEL);
  92. }
  93. MYDBGASSERT(pszTmp);
  94. if (pszTmp)
  95. {
  96. //
  97. // Append the description and display
  98. //
  99. if (*pszDesc)
  100. {
  101. pszTmp = CmStrCatAlloc(&pszTmp, TEXT(" "));
  102. pszTmp = CmStrCatAlloc(&pszTmp, pszDesc);
  103. }
  104. SetDlgItemTextU(m_hWnd, nDescID, pszTmp);
  105. }
  106. CmFree(pszTmp);
  107. }
  108. //+---------------------------------------------------------------------------
  109. //
  110. // Function: CGeneralPage::ClearUseDialingRules
  111. //
  112. // Synopsis: Helper function to deal with disabling the check box and
  113. // reseting the state for UseDialingRules.
  114. //
  115. // Arguments: iPhoneNdx - index of phone number to which this applies
  116. //
  117. // Returns: Nothing
  118. //
  119. // History: nickball - Created - 7/17/97
  120. //
  121. //----------------------------------------------------------------------------
  122. void CGeneralPage::ClearUseDialingRules(int iPhoneNdx)
  123. {
  124. MYDBGASSERT(iPhoneNdx ==0 || iPhoneNdx ==1);
  125. //
  126. // Uncheck and disable the appropriate "Use Dialing Rules" checkbox
  127. //
  128. if (0 == iPhoneNdx)
  129. {
  130. CheckDlgButton(m_hWnd, IDC_GENERAL_UDR1_CHECKBOX, FALSE);
  131. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_UDR1_CHECKBOX), FALSE);
  132. }
  133. else
  134. {
  135. CheckDlgButton(m_hWnd, IDC_GENERAL_UDR2_CHECKBOX, FALSE);
  136. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_UDR2_CHECKBOX), FALSE);
  137. }
  138. m_DialInfo[iPhoneNdx].dwPhoneInfoFlags &= ~PIF_USE_DIALING_RULES;
  139. UpdateDialingRulesButton();
  140. }
  141. //+---------------------------------------------------------------------------
  142. //
  143. // Function: CGeneralPage::UpdateDialingRulesButton
  144. //
  145. // Synopsis: Helper function to deal with enabling/disabling the
  146. // DialingRules button according to whether dialing rules
  147. // is being applied to either primary or backup number.
  148. //
  149. // Arguments: None
  150. //
  151. // Returns: Nothing
  152. //
  153. // History: nickball - Created - 12/14/98
  154. //
  155. //----------------------------------------------------------------------------
  156. void CGeneralPage::UpdateDialingRulesButton(void)
  157. {
  158. BOOL fDialingRules = (IsDlgButtonChecked(m_hWnd, IDC_GENERAL_UDR1_CHECKBOX) &&
  159. IsWindowEnabled(GetDlgItem(m_hWnd, IDC_GENERAL_UDR1_CHECKBOX))
  160. ) ||
  161. (IsDlgButtonChecked(m_hWnd, IDC_GENERAL_UDR2_CHECKBOX) &&
  162. IsWindowEnabled(GetDlgItem(m_hWnd, IDC_GENERAL_UDR2_CHECKBOX))
  163. );
  164. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_TAPI_BUTTON), fDialingRules);
  165. }
  166. //+---------------------------------------------------------------------------
  167. //
  168. // Function: DoPropertiesPropSheets
  169. //
  170. // Synopsis: Pop up the Properties property sheets.
  171. //
  172. // Arguments: hwndDlg [dlg window handle]
  173. // pArgs [the ptr to ArgsStruct]
  174. //
  175. // Returns: PropertySheet return value
  176. //
  177. // History: henryt Created 3/5/97
  178. //
  179. //----------------------------------------------------------------------------
  180. int DoPropertiesPropSheets(
  181. HWND hwndDlg,
  182. ArgsStruct *pArgs
  183. )
  184. {
  185. CPropertiesSheet PropertiesSheet(pArgs);
  186. CInetPage* pInetPage = NULL;
  187. CAboutPage* pAboutPage = NULL;
  188. COptionPage* pOptionPage = NULL;
  189. CGeneralPage* pGeneralPage = NULL;
  190. CVpnPage* pVpnPage = NULL;
  191. HRESULT hr;
  192. BOOL bCOMInitialized = FALSE;
  193. HINSTANCE hinstDll = NULL;
  194. typedef HRESULT (*pfnGetPageFunction) (PROPSHEETPAGEW *, GUID *);
  195. CMTRACE(TEXT("Begin DoPropertiesPropSheets()"));
  196. //
  197. // Always start by adding the General page
  198. //
  199. if (pArgs->IsBothConnTypeSupported() || !pArgs->IsDirectConnect())
  200. {
  201. //
  202. // If both dial-up and direct is supported, use the appropriate
  203. // template for the general property page.
  204. //
  205. UINT uiMainDlgID;
  206. //
  207. // The general page is always access point aware
  208. //
  209. uiMainDlgID = pArgs->IsBothConnTypeSupported() ? IDD_GENERAL_DIRECT : IDD_GENERAL;
  210. pGeneralPage = new CGeneralPage(pArgs, uiMainDlgID);
  211. if (pGeneralPage)
  212. {
  213. PropertiesSheet.AddPage(pGeneralPage);
  214. //
  215. // Create the balloon tip object
  216. //
  217. pArgs->pBalloonTip = new CBalloonTip();
  218. }
  219. //
  220. // Show the Internet Sign-In tab if we're tunneling and
  221. // Inet username/password is different than main sign-on username/password
  222. // Also, if either the username or password are NOT to be hidden, we
  223. // display the tab.
  224. //
  225. if (IsTunnelEnabled(pArgs) && !pArgs->fUseSameUserName)
  226. {
  227. if (!pArgs->fHideInetUsername || !pArgs->fHideInetPassword)
  228. {
  229. //
  230. // Determine which template to use based hide flags
  231. //
  232. UINT uiTemplateID = IDD_INET_SIGNIN;
  233. if (pArgs->fHideInetUsername)
  234. {
  235. uiTemplateID = IDD_INET_SIGNIN_NO_UID;
  236. }
  237. else if (pArgs->fHideInetPassword)
  238. {
  239. uiTemplateID = IDD_INET_SIGNIN_NO_PWD;
  240. }
  241. //
  242. // Create the page
  243. //
  244. pInetPage = new CInetPage(pArgs, uiTemplateID);
  245. if (pInetPage)
  246. {
  247. PropertiesSheet.AddPage(pInetPage);
  248. if (pGeneralPage)
  249. {
  250. //
  251. // To receive event from General Page
  252. //
  253. pGeneralPage->SetEventListener(pInetPage);
  254. }
  255. }
  256. }
  257. }
  258. }
  259. //
  260. // Add the VPN selector tab if we are tunneling and have a VPN phonebook
  261. // specified.
  262. //
  263. if (IsTunnelEnabled(pArgs) && pArgs->pszVpnFile)
  264. {
  265. pVpnPage = new CVpnPage(pArgs, IDD_VPN);
  266. if (pVpnPage)
  267. {
  268. PropertiesSheet.AddPage(pVpnPage);
  269. }
  270. }
  271. //
  272. // Always include Options page
  273. //
  274. pOptionPage = new COptionPage(pArgs, IDD_OPTIONS);
  275. if (pOptionPage)
  276. {
  277. PropertiesSheet.AddPage(pOptionPage);
  278. }
  279. #ifndef _WIN64
  280. //
  281. // Add the Advanced (Internet Connection Firewall & Internet Connection
  282. // Sharing) property page. Display only on WindowsXP and x86. If an error occurs
  283. // fail gracefully & continue.
  284. //
  285. //
  286. // Check if this is WindowsXP and/or above and if we are allowed to display the tab
  287. //
  288. if (OS_NT51 && pArgs->bShowHNetCfgAdvancedTab && (FALSE == IsLogonAsSystem()))
  289. {
  290. PROPSHEETPAGEW psp;
  291. ZeroMemory (&psp, sizeof(psp));
  292. psp.dwSize = sizeof(psp);
  293. //
  294. // Make sure COM is initialized on this thread.
  295. // Win95 can't find an entry in ole32.dll for CoInitializeEx since we statically link
  296. // the lib. Need to use CoInitilize because it needs to run on plain vanilla
  297. // Win95. Possibly we should dynamically load the dll in this case.
  298. //
  299. hr = CoInitialize(NULL);
  300. if (S_OK == hr)
  301. {
  302. CMTRACE(TEXT("DoPropertiesPropSheets - Correctly Initialized COM."));
  303. bCOMInitialized = TRUE;
  304. }
  305. else if (S_FALSE == hr)
  306. {
  307. CMTRACE(TEXT("DoPropertiesPropSheets - This concurrency model is already initialized. CoInitialize returned S_FALSE."));
  308. bCOMInitialized = TRUE;
  309. hr = S_OK;
  310. }
  311. else if (RPC_E_CHANGED_MODE == hr)
  312. {
  313. CMTRACE1(TEXT("DoPropertiesPropSheets - Using different concurrency model. Did not initialize COM - RPC_E_CHANGED_MODE. hr=0x%x"), hr);
  314. hr = S_OK;
  315. }
  316. else
  317. {
  318. CMTRACE1(TEXT("DoPropertiesPropSheets - Failed to Initialized COM. hr=0x%x"), hr);
  319. }
  320. if (SUCCEEDED(hr))
  321. {
  322. CMTRACE(TEXT("DoPropertiesPropSheets - Get connection GUID."));
  323. GUID *pGuid = NULL;
  324. LPRASENTRY pRasEntry = MyRGEP(pArgs->pszRasPbk, pArgs->szServiceName, &pArgs->rlsRasLink);
  325. if (pRasEntry && sizeof(RASENTRY_V501) >= pRasEntry->dwSize)
  326. {
  327. //
  328. // Get the pGuid value
  329. //
  330. pGuid = &(((LPRASENTRY_V501)pRasEntry)->guidId);
  331. hinstDll = LoadLibrary (TEXT("hnetcfg.dll"));
  332. if (NULL == hinstDll)
  333. {
  334. CMTRACE1(TEXT("DoPropertiesPropSheets - could not LoadLibray hnetcfg.dll GetLastError() = 0x%x"),
  335. GetLastError());
  336. }
  337. else
  338. {
  339. CMTRACE(TEXT("DoPropertiesPropSheets - Loaded Library hnetcfg.dll"));
  340. pfnGetPageFunction pfnGetPage = (pfnGetPageFunction)GetProcAddress (hinstDll, "HNetGetFirewallSettingsPage");
  341. if (!pfnGetPage)
  342. {
  343. CMTRACE1(TEXT("DoPropertiesPropSheets - GetProcAddress for HNetGetFirewallSettingsPage failed! 0x%x"),
  344. GetLastError());
  345. }
  346. else
  347. {
  348. //
  349. // Get the actual Property Sheet Page
  350. // This function can fail if the user doesn't have the correct
  351. // security settings (eg. is not an Administrator) This is checked
  352. // internally in the hnetcfg.dll
  353. //
  354. CMTRACE(TEXT("DoPropertiesPropSheets - calling HNetGetFirewallSettingsPage"));
  355. hr = pfnGetPage(&psp, pGuid);
  356. if (S_OK == hr)
  357. {
  358. //
  359. // Add the Property Sheet Page into our PropertiesSheet object
  360. //
  361. PropertiesSheet.AddExternalPage(&psp);
  362. CMTRACE(TEXT("DoPropertiesPropSheets - Called AddExternalPage() "));
  363. }
  364. else
  365. {
  366. //
  367. // This error could be ERROR_ACCESS_DENIED which is ok
  368. // so just log this. The tab will not be displayed in this case
  369. //
  370. if (ERROR_ACCESS_DENIED == hr)
  371. {
  372. CMTRACE(TEXT("DoPropertiesPropSheets() - ERROR_ACCESS_DENIED. User does not have the security rights to view this tab."));
  373. }
  374. else
  375. {
  376. CMTRACE1(TEXT("DoPropertiesPropSheets() - Failed to get Propery Page. hr=0x%x"), hr);
  377. }
  378. }
  379. }
  380. }
  381. }
  382. else
  383. {
  384. CMTRACE(TEXT("DoPropertiesPropSheets - Failed to LoadRAS Entry."));
  385. }
  386. CmFree(pRasEntry);
  387. pRasEntry = NULL;
  388. }
  389. }
  390. #endif // _WIN64
  391. //
  392. // If NOT NT5, set the about page as the last property sheet
  393. //
  394. if (!(OS_NT5))
  395. {
  396. pAboutPage = new CAboutPage(pArgs, IDD_ABOUT);
  397. if (pAboutPage)
  398. {
  399. PropertiesSheet.AddPage(pAboutPage);
  400. }
  401. }
  402. //
  403. // The service name used as mutex name
  404. //
  405. PropertiesSheet.m_lpszServiceName = CmStrCpyAlloc(pArgs->szServiceName);
  406. //
  407. // Set the title for the sheet
  408. //
  409. LPTSTR pszTitle = GetPropertiesDlgTitle(pArgs->szServiceName);
  410. if (OS_W9X)
  411. {
  412. //
  413. // If this is Win9x then we will call the ANSI version of the
  414. // property sheet function. Thus we must pass it an ANSI title.
  415. // Since the ANSI and Unicode version of the Prop Sheet Header are
  416. // the same size (contains only string pointers not strings) whether
  417. // ANSI or Unicode and we only have one Unicode string, lets take
  418. // a shortcut and cast the title to an ANSI string and then call the
  419. // A version of the API. This saves us having to have a UtoA function
  420. // for the prop sheets when we would only be doing one string conversion.
  421. //
  422. LPSTR pszAnsiTitle = WzToSzWithAlloc(pszTitle);
  423. CmFree(pszTitle);
  424. pszTitle = (LPTSTR)pszAnsiTitle;
  425. }
  426. //
  427. // Show it!
  428. //
  429. int iRet = PropertiesSheet.DoPropertySheet(hwndDlg, pszTitle, g_hInst);
  430. CmFree(pszTitle);
  431. switch(iRet)
  432. {
  433. case -1:
  434. CMTRACE(TEXT("DoPropertiesPropSheets(): PropertySheet() failed"));
  435. break;
  436. case IDOK:
  437. CheckConnectionAndInformUser(hwndDlg, pArgs);
  438. break;
  439. case 0 : // Cancel
  440. break;
  441. default:
  442. MYDBGASSERT(FALSE);
  443. break;
  444. }
  445. delete pInetPage;
  446. delete pAboutPage;
  447. delete pOptionPage;
  448. delete pGeneralPage;
  449. delete pVpnPage;
  450. //
  451. // Clean up the BalloonTip object if we have one
  452. //
  453. delete pArgs->pBalloonTip;
  454. pArgs->pBalloonTip = NULL;
  455. CmFree (PropertiesSheet.m_lpszServiceName);
  456. PropertiesSheet.m_lpszServiceName = NULL;
  457. //
  458. // Clean up and Uninitilize COM
  459. //
  460. if (hinstDll)
  461. {
  462. FreeLibrary (hinstDll);
  463. }
  464. if (bCOMInitialized)
  465. {
  466. CoUninitialize();
  467. }
  468. CMTRACE(TEXT("End DoPropertiesPropSheets()"));
  469. return iRet;
  470. }
  471. //+----------------------------------------------------------------------------
  472. //
  473. // Function: CheckConnectionAndInformUser
  474. //
  475. // Synopsis: This function is called after the user clicked OK on the
  476. // Properties dialog. The Prop dialog can be up while the same
  477. // profile is connected and so we need to tell the user that
  478. // the changes won't be effective until the next she connects.
  479. //
  480. // Arguments: hwnDlg - hwnd of the main dlg
  481. // pArgs
  482. //
  483. // Returns: None
  484. //
  485. //+----------------------------------------------------------------------------
  486. void CheckConnectionAndInformUser(
  487. HWND hwndDlg,
  488. ArgsStruct *pArgs
  489. )
  490. {
  491. CM_CONNECTION Connection;
  492. ZeroMemory(&Connection, sizeof(CM_CONNECTION));
  493. if (SUCCEEDED(pArgs->pConnTable->GetEntry(pArgs->szServiceName, &Connection)) &&
  494. Connection.CmState == CM_CONNECTED)
  495. {
  496. LPTSTR pszTmp = CmLoadString(g_hInst, IDMSG_EFFECTIVE_NEXT_TIME);
  497. MessageBox(hwndDlg, pszTmp, pArgs->szServiceName, MB_OK | MB_ICONINFORMATION);
  498. CmFree(pszTmp);
  499. }
  500. }
  501. const DWORD CInetSignInDlg::m_dwHelp[] = {
  502. IDC_INET_USERNAME_STATIC, IDH_INTERNET_USER_NAME,
  503. IDC_INET_USERNAME, IDH_INTERNET_USER_NAME,
  504. IDC_INET_PASSWORD_STATIC, IDH_INTERNET_PASSWORD,
  505. IDC_INET_PASSWORD, IDH_INTERNET_PASSWORD,
  506. IDC_INET_REMEMBER, IDH_INTERNET_SAVEPASS,
  507. 0,0};
  508. //+----------------------------------------------------------------------------
  509. //
  510. // Function: CInetSignInDlg::OnInitDialog
  511. //
  512. // Synopsis: Virtual function. Call upon WM_INITDIALOG message
  513. //
  514. // Arguments: None
  515. //
  516. // Returns: BOOL - Return value of WM_INITDIALOG
  517. //
  518. // History: fengsun Created Header 2/26/98
  519. //
  520. //+----------------------------------------------------------------------------
  521. BOOL CInetSignInDlg::OnInitDialog()
  522. {
  523. //
  524. // Brand the dialog
  525. //
  526. if (m_pArgs->hSmallIcon)
  527. {
  528. SendMessageU(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM) m_pArgs->hSmallIcon);
  529. }
  530. if (m_pArgs->hBigIcon)
  531. {
  532. SendMessageU(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM) m_pArgs->hBigIcon);
  533. SendMessageU(GetDlgItem(m_hWnd, IDC_INET_ICON), STM_SETIMAGE, IMAGE_ICON, (LPARAM) m_pArgs->hBigIcon);
  534. }
  535. //
  536. // Use should not see this dialog, if the password is optional
  537. //
  538. MYDBGASSERT(!m_pArgs->piniService->GPPB(c_pszCmSection,c_pszCmEntryPwdOptional));
  539. UpdateFont(m_hWnd);
  540. CInetPage::OnInetInit(m_hWnd, m_pArgs);
  541. //
  542. // if the username is empty, then we disable the OK button.
  543. //
  544. if (GetDlgItem(m_hWnd, IDC_INET_USERNAME) &&
  545. !SendDlgItemMessageU(m_hWnd, IDC_INET_USERNAME, WM_GETTEXTLENGTH, 0, (LPARAM)0))
  546. {
  547. EnableWindow(GetDlgItem(m_hWnd, IDOK), FALSE);
  548. }
  549. if (GetDlgItem(m_hWnd, IDC_INET_PASSWORD) &&
  550. !SendDlgItemMessageU(m_hWnd, IDC_INET_PASSWORD, WM_GETTEXTLENGTH, 0, (LPARAM)0))
  551. {
  552. EnableWindow(GetDlgItem(m_hWnd, IDOK), FALSE);
  553. }
  554. //
  555. // We wouldn't be here unless data was missing, so set focus accordingly
  556. //
  557. if (!m_pArgs->fHideInetUsername && !*m_pArgs->szInetUserName)
  558. {
  559. SetFocus(GetDlgItem(m_hWnd, IDC_INET_USERNAME));
  560. }
  561. else
  562. {
  563. SetFocus(GetDlgItem(m_hWnd, IDC_INET_PASSWORD));
  564. }
  565. //
  566. // Must return FALSE when setting focus
  567. //
  568. return FALSE;
  569. }
  570. //+----------------------------------------------------------------------------
  571. //
  572. // Function: CInetSignInDlg::OnOK
  573. //
  574. // Synopsis: Virtual function. Called upon WM_COMMAND with IDOK
  575. //
  576. // Arguments: None
  577. //
  578. // Returns: Nothing
  579. //
  580. // History: fengsun Created Header 2/26/98
  581. //
  582. //+----------------------------------------------------------------------------
  583. void CInetSignInDlg::OnOK()
  584. {
  585. CInetPage::OnInetOk(m_hWnd, m_pArgs);
  586. EndDialog(m_hWnd, TRUE);
  587. }
  588. //+----------------------------------------------------------------------------
  589. //
  590. // Function: CInetSignInDlg::OnOtherCommand
  591. //
  592. // Synopsis: Virtual function. Call upon WM_COMMAND with command other than IDOK
  593. // and IDCANCEL
  594. //
  595. // Arguments: WPARAM wParam - wParam of WM_COMMAND
  596. // LPARAM -
  597. //
  598. // Returns: DWORD -
  599. //
  600. // History: fengsun Created Header 2/26/98
  601. //
  602. //+----------------------------------------------------------------------------
  603. DWORD CInetSignInDlg::OnOtherCommand(WPARAM wParam, LPARAM)
  604. {
  605. switch (LOWORD(wParam))
  606. {
  607. case IDC_INET_USERNAME:
  608. case IDC_INET_PASSWORD:
  609. //
  610. // User typed something in username or password
  611. //
  612. if (HIWORD(wParam) == EN_CHANGE)
  613. {
  614. BOOL fHasUserName = TRUE;
  615. if (GetDlgItem(m_hWnd, IDC_INET_USERNAME))
  616. {
  617. fHasUserName = !!SendDlgItemMessageU(m_hWnd,
  618. IDC_INET_USERNAME,
  619. WM_GETTEXTLENGTH, 0, 0);
  620. }
  621. BOOL fHasPassword = TRUE;
  622. if (GetDlgItem(m_hWnd, IDC_INET_PASSWORD))
  623. {
  624. fHasPassword = !!SendDlgItemMessageU(m_hWnd,
  625. IDC_INET_PASSWORD,
  626. WM_GETTEXTLENGTH, 0, 0);
  627. }
  628. //
  629. // Enable OK button only if both user name and password is available
  630. //
  631. EnableWindow(GetDlgItem(m_hWnd, IDOK), fHasUserName && fHasPassword);
  632. if (!m_pArgs->fHideRememberInetPassword && !m_pArgs->fHideInetPassword)
  633. {
  634. //
  635. // Enable/Disable check/uncheck the "Save Password" accordingly
  636. // fPasswordOptional is always FALSE for the dialog
  637. //
  638. CInetPage::AdjustSavePasswordCheckBox(GetDlgItem(m_hWnd, IDC_INET_REMEMBER),
  639. !fHasPassword, m_pArgs->fDialAutomatically, FALSE);
  640. }
  641. }
  642. break;
  643. }
  644. return FALSE;
  645. }
  646. //+---------------------------------------------------------------------------
  647. //
  648. // Function: CGeneralPage::SubClassEditProc
  649. //
  650. // Synopsis: Proc to subclass the edit controls in the Dial propsheet.
  651. //
  652. // Arguments: hwnd [wnd handle]
  653. // uMsg [wnd msg]
  654. // lParam [LPARAM]
  655. // wParam [WPARAM]
  656. //
  657. // Returns: NONE
  658. //
  659. // History: henryt Created 3/24/97
  660. // byao Modified 4/3/97 Added new code to handle description field,
  661. // phone number field, etc.
  662. // henryt Modified 5/1/97 New UI.
  663. // nickball Modified 6/18/97 Moved GetParent call and added
  664. // NC_DESTROY handling for CM16
  665. // nickball Modified 7/10/97 Commented out removal of description
  666. // nickball Modified 7/10/97 Implemented ClearDialAsLongDistance
  667. // fengsun Modified 11/3/97 Changed into static member function
  668. // nickball Modified 09/16/98 Renamed ClearDialAsLongDistance to ClearUseDialingRules
  669. //----------------------------------------------------------------------------
  670. LRESULT CALLBACK CGeneralPage::SubClassEditProc(HWND hwnd, UINT uMsg,
  671. WPARAM wParam, LPARAM lParam)
  672. {
  673. //
  674. // If user types a non-tapi character Beep and do not accept that character
  675. //
  676. if ((uMsg == WM_CHAR) && (VK_BACK != wParam))
  677. {
  678. if (!IsValidPhoneNumChar((TCHAR)wParam))
  679. {
  680. Beep(2000, 100);
  681. return 0;
  682. }
  683. }
  684. //
  685. // Call the original window procedure for default processing.
  686. //
  687. LRESULT lres = CallWindowProcU(m_pfnOrgEditWndProc, hwnd, uMsg, wParam, lParam);
  688. //
  689. // if the user is typing a phone # in the edit control, then there is
  690. // no phone book file associated with the #.
  691. // make sure we ignore CTRL-C(VK_CANCEL) because the user is just doing a copy.
  692. //
  693. if ( ( uMsg == WM_CHAR && wParam != VK_CANCEL ) ||
  694. ( uMsg == WM_KEYDOWN && wParam == VK_DELETE) ||
  695. ( uMsg == WM_PASTE))
  696. {
  697. //
  698. // Either primary or backup edit control
  699. //
  700. DWORD dwControlId = (DWORD) GetWindowLongU(hwnd, GWL_ID);
  701. MYDBGASSERT(dwControlId == IDC_GENERAL_PRIMARY_EDIT ||
  702. dwControlId == IDC_GENERAL_BACKUP_EDIT);
  703. //
  704. // Get the object pointer saved by SetWindowLong
  705. //
  706. CGeneralPage* pGeneralPage = (CGeneralPage*)GetWindowLongU(hwnd, GWLP_USERDATA);
  707. MYDBGASSERT(pGeneralPage);
  708. pGeneralPage->ClearUseDialingRules(dwControlId == IDC_GENERAL_PRIMARY_EDIT ? 0 : 1);
  709. }
  710. return lres;
  711. }
  712. //+---------------------------------------------------------------------------
  713. //
  714. // Function: SubClassPropSheetProc
  715. //
  716. // Synopsis: Proc to subclass the parent property sheet dlg.
  717. //
  718. // Arguments: hwnd [wnd handle]
  719. // uMsg [wnd msg]
  720. // lParam [LPARAM]
  721. // wParam [WPARAM]
  722. //
  723. // Returns: NONE
  724. //
  725. // History: henryt Created 6/11/97
  726. //----------------------------------------------------------------------------
  727. LRESULT CALLBACK CPropertiesSheet::SubClassPropSheetProc(HWND hwnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
  728. {
  729. switch (uMsg)
  730. {
  731. case WM_COMMAND:
  732. //
  733. // If ok is pressed, save the index of the tab
  734. // So, the next time user comes to properties, the same tab will be displayed
  735. //
  736. if (LOWORD(wParam) == IDOK && HIWORD(wParam) == BN_CLICKED)
  737. {
  738. CPropertiesSheet* pPropSheet = (CPropertiesSheet*)GetWindowLongU(hwnd, GWLP_USERDATA);
  739. MYDBGASSERT(pPropSheet);
  740. //
  741. // Declare a mutex to prevent multi-instance write to the same profile
  742. //
  743. CNamedMutex propertiesMutex;
  744. //
  745. // Use the profile name as the mutex name
  746. // If we lock timed out, go ahead and save the properties
  747. // The destructor of the mutex will release the lock
  748. //
  749. MYVERIFY(propertiesMutex.Lock(pPropSheet->m_lpszServiceName, TRUE, WRITE_PROPERTIES_MUTEX_TIMEOUT));
  750. LRESULT dwRes = CallWindowProcU(m_pfnOrgPropSheetProc, hwnd, uMsg, wParam, lParam);
  751. return dwRes;
  752. }
  753. case WM_MOVING:
  754. {
  755. CPropertiesSheet* pPropSheet = (CPropertiesSheet*)GetWindowLongU(hwnd, GWLP_USERDATA);
  756. if (pPropSheet && pPropSheet->m_pArgs && pPropSheet->m_pArgs->pBalloonTip)
  757. {
  758. pPropSheet->m_pArgs->pBalloonTip->HideBalloonTip();
  759. }
  760. }
  761. break;
  762. }
  763. //
  764. // Call the original window procedure for default processing.
  765. //
  766. return CallWindowProcU(m_pfnOrgPropSheetProc, hwnd, uMsg, wParam, lParam);
  767. }
  768. //+----------------------------------------------------------------------------
  769. //
  770. // Function: CPropertiesSheet::PropSheetProc
  771. //
  772. // Synopsis: Callback function for the propertysheet. PSCB_INITIALIZED is
  773. // called before any page is initialized. Initialize the property
  774. // page here
  775. //
  776. // Arguments: HWND hwndDlg - PropertySheet window handle
  777. // UINT uMsg - Message id
  778. // LPARAM -
  779. //
  780. // Returns: int CALLBACK -
  781. //
  782. // History: fengsun Created Header 2/26/98
  783. //
  784. //+----------------------------------------------------------------------------
  785. int CALLBACK CPropertiesSheet::PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
  786. {
  787. if (uMsg == PSCB_INITIALIZED)
  788. {
  789. MYDBGASSERT(hwndDlg);
  790. //
  791. // Save the m_pThis pointer, so it can be accessed by SubClassPropSheetProc
  792. //
  793. MYDBGASSERT(m_pThis);
  794. SetWindowLongU(hwndDlg, GWLP_USERDATA, (LONG_PTR)m_pThis);
  795. m_pThis = NULL;
  796. //
  797. // subclass the property sheet
  798. //
  799. m_pfnOrgPropSheetProc = (WNDPROC)SetWindowLongU(hwndDlg, GWLP_WNDPROC, (LONG_PTR)SubClassPropSheetProc);
  800. }
  801. return 0;
  802. }
  803. //+----------------------------------------------------------------------------
  804. //
  805. // Function CGeneralPage::DisplayMungedPhone
  806. //
  807. // Synopsis Apply TAPI rules to the phone number, and then display it
  808. // in the edit control
  809. //
  810. // Arguments uiPhoneIdx The index of the phone #
  811. //
  812. // Returns FALSE if the number can't be munged
  813. //
  814. // History 4/2/97 byao Modified to current implementation
  815. // 4/30/97 henryt added/deleted params
  816. // 5/17/97 VetriV Added functionality to return
  817. // displayable number
  818. // 11/3/97 fengsun Changed into member function
  819. //
  820. //-----------------------------------------------------------------------------
  821. BOOL CGeneralPage::DisplayMungedPhone(UINT uiPhoneIdx)
  822. {
  823. LPTSTR pszPhone;
  824. LPTSTR pszTmpDialableString = NULL;
  825. BOOL bRet = TRUE;
  826. //
  827. // If DialingRules is turned off, just use what we already have, no munge.
  828. //
  829. if (m_pArgs->fNoDialingRules)
  830. {
  831. lstrcpynU(m_DialInfo[uiPhoneIdx].szDisplayablePhoneNumber, m_DialInfo[uiPhoneIdx].szPhoneNumber,
  832. CELEMS(m_DialInfo[uiPhoneIdx].szDisplayablePhoneNumber));
  833. lstrcpynU(m_DialInfo[uiPhoneIdx].szDialablePhoneNumber, m_DialInfo[uiPhoneIdx].szPhoneNumber,
  834. CELEMS(m_DialInfo[uiPhoneIdx].szDialablePhoneNumber));
  835. m_DialInfo[uiPhoneIdx].szCanonical[0] = TEXT('\0');
  836. SetDlgItemTextU(m_hWnd, (uiPhoneIdx? IDC_GENERAL_BACKUP_EDIT : IDC_GENERAL_PRIMARY_EDIT), m_DialInfo[uiPhoneIdx].szPhoneNumber);
  837. return TRUE;
  838. }
  839. //
  840. // Retrieve the canonical form of the number for munging
  841. //
  842. pszPhone = CmStrCpyAlloc(m_DialInfo[uiPhoneIdx].szCanonical);
  843. if (pszPhone)
  844. {
  845. if (*pszPhone && m_szDeviceName[0])
  846. {
  847. //
  848. // Apply tapi rules only when there's a modem selected. We now munge the phone
  849. // even if there is no description because we want to pick up tone and pulse.
  850. //
  851. if (ERROR_SUCCESS != MungePhone(m_szDeviceName,
  852. &pszPhone,
  853. &m_pArgs->tlsTapiLink,
  854. g_hInst,
  855. m_DialInfo[uiPhoneIdx].dwPhoneInfoFlags & PIF_USE_DIALING_RULES,
  856. &pszTmpDialableString,
  857. m_pArgs->fAccessPointsEnabled))
  858. {
  859. //
  860. // Munge failed, make sure that ptrs are valid, albeit empty
  861. //
  862. CmFree(pszPhone);
  863. pszPhone = CmStrCpyAlloc(TEXT("")); // CmFmtMsg(g_hInst, IDMSG_CANTFORMAT);
  864. pszTmpDialableString = CmStrCpyAlloc(TEXT("")); // CmFmtMsg(g_hInst, IDMSG_CANTFORMAT);
  865. bRet = FALSE;
  866. }
  867. }
  868. //
  869. // Standard procedure. If Dialing rule are applied, then use the
  870. // canonical form (eg. pszPhone). Otherwise use the raw number form.
  871. //
  872. if (m_DialInfo[uiPhoneIdx].dwPhoneInfoFlags & PIF_USE_DIALING_RULES)
  873. {
  874. //
  875. // Unique situation in which we have read in a legacy hand-edited
  876. // phone number and the default dialing-rules state is TRUE/ON.
  877. // We fake out the standard procedure by slipping the raw number
  878. // into the otherwise blank pszPhone. Note: This occurs only the
  879. // first time the app. is run until a save is made at which time
  880. // the current storage format is used.
  881. //
  882. if (!*pszPhone)
  883. {
  884. pszPhone = CmStrCatAlloc(&pszPhone, m_DialInfo[uiPhoneIdx].szPhoneNumber);
  885. }
  886. //
  887. // In this case the pszPhone is dynamically allocated and can be very long. In order to
  888. // fix this, we need to trim the string if it's longer than what should fit in the UI.
  889. //
  890. LRESULT lEditLen = SendDlgItemMessageU(m_hWnd, (uiPhoneIdx? IDC_GENERAL_BACKUP_EDIT : IDC_GENERAL_PRIMARY_EDIT), EM_GETLIMITTEXT, 0, 0);
  891. if (lstrlenU(pszPhone) >= ((INT)lEditLen))
  892. {
  893. pszPhone[lEditLen] = TEXT('\0');
  894. }
  895. SetDlgItemTextU(m_hWnd, (uiPhoneIdx? IDC_GENERAL_BACKUP_EDIT : IDC_GENERAL_PRIMARY_EDIT), pszPhone);
  896. }
  897. else
  898. {
  899. //
  900. // No need to trim anything, since the structure is providing the phone number. Eventully the
  901. // number from the UI will go back into the phone number structure and we know it will fit
  902. // since it came from there.
  903. //
  904. SetDlgItemTextU(m_hWnd, (uiPhoneIdx? IDC_GENERAL_BACKUP_EDIT : IDC_GENERAL_PRIMARY_EDIT), m_DialInfo[uiPhoneIdx].szPhoneNumber);
  905. }
  906. }
  907. //
  908. // copy the munged phone to the caller's buffer.
  909. //
  910. if (pszTmpDialableString)
  911. {
  912. lstrcpynU(m_DialInfo[uiPhoneIdx].szDialablePhoneNumber, pszTmpDialableString,
  913. CELEMS(m_DialInfo[uiPhoneIdx].szDialablePhoneNumber));
  914. }
  915. if (pszPhone)
  916. {
  917. lstrcpynU(m_DialInfo[uiPhoneIdx].szDisplayablePhoneNumber, pszPhone,
  918. CELEMS(m_DialInfo[uiPhoneIdx].szDisplayablePhoneNumber));
  919. }
  920. CmFree(pszPhone);
  921. CmFree(pszTmpDialableString);
  922. return bRet;
  923. }
  924. //+----------------------------------------------------------------------------
  925. //
  926. // Function CGeneralPage::OnDialingProperties
  927. //
  928. // Synopsis Handler for handling the "Dialing Properties..." button-click
  929. // in the 'Dialing' tab.
  930. //
  931. // Arguments
  932. //
  933. // History 4/30/97 henryt modified for new UI
  934. // 11/3/97 fengsun Change the function name and make it
  935. // a member ffunction
  936. // 01/29/98 cleaned up memory leak, added comments.
  937. //
  938. //-----------------------------------------------------------------------------
  939. void CGeneralPage::OnDialingProperties()
  940. {
  941. LONG lRes;
  942. LPTSTR pszPhone = NULL;
  943. //
  944. // Use primary or backup to seed tapi dialog depending on whether dialing
  945. // rules are being applied to the number. We use the check state rather
  946. // than the phone-info flag because of the anomolous first time case in
  947. // which the flag is set, but the controls aren't checked.
  948. //
  949. if (IsDlgButtonChecked(m_hWnd, IDC_GENERAL_UDR1_CHECKBOX))
  950. {
  951. pszPhone = CmStrCpyAlloc(m_DialInfo[0].szCanonical);//szPhoneNumber);
  952. }
  953. else if (IsDlgButtonChecked(m_hWnd, IDC_GENERAL_UDR2_CHECKBOX))
  954. {
  955. pszPhone = CmStrCpyAlloc(m_DialInfo[1].szCanonical);//szPhoneNumber);
  956. }
  957. else
  958. {
  959. pszPhone = CmStrCpyAlloc(TEXT(" "));
  960. }
  961. //
  962. // Launch TAPI dialog for DialingRules configuration
  963. //
  964. if (!m_pArgs->tlsTapiLink.pfnlineTranslateDialog)
  965. {
  966. return;
  967. }
  968. if (!SetTapiDevice(g_hInst,&m_pArgs->tlsTapiLink,m_szDeviceName))
  969. {
  970. MYDBGASSERT(FALSE);
  971. return;
  972. }
  973. if (OS_W9X)
  974. {
  975. //
  976. // On win9x, we are linked to the ANSI version of lineTranslateDialog, thus
  977. // we need to convert the string. In order to keep things simpler, we just
  978. // cast the converted LPSTR as an LPWSTR and pass it on.
  979. //
  980. LPSTR pszAnsiPhone = WzToSzWithAlloc(pszPhone);
  981. CmFree(pszPhone);
  982. pszPhone = (LPTSTR)pszAnsiPhone;
  983. }
  984. lRes = m_pArgs->tlsTapiLink.pfnlineTranslateDialog(m_pArgs->tlsTapiLink.hlaLine,
  985. m_pArgs->tlsTapiLink.dwDeviceId,
  986. m_pArgs->tlsTapiLink.dwApiVersion,
  987. m_hWnd,
  988. pszPhone);
  989. CmFree(pszPhone);
  990. CMTRACE1(TEXT("OnDialingProperties() lineTranslateDialog() returns %u"), lRes);
  991. //
  992. // We do not know whether user changed anything (WIN32), so re-munge anyway
  993. //
  994. if (lRes == ERROR_SUCCESS)
  995. {
  996. DWORD dwCurrentTapiLoc = GetCurrentTapiLocation(&m_pArgs->tlsTapiLink);
  997. if (-1 != dwCurrentTapiLoc)
  998. {
  999. if (dwCurrentTapiLoc != m_pArgs->tlsTapiLink.dwTapiLocationForAccessPoint)
  1000. {
  1001. m_bAPInfoChanged = TRUE;
  1002. }
  1003. m_pArgs->tlsTapiLink.dwTapiLocationForAccessPoint = dwCurrentTapiLoc;
  1004. for (UINT i = 0; i < m_NumPhones; i++)
  1005. {
  1006. //
  1007. // Only munge if Use Dialing Rules is available
  1008. //
  1009. if (m_DialInfo[i].dwPhoneInfoFlags & PIF_USE_DIALING_RULES)
  1010. {
  1011. DisplayMungedPhone(i);
  1012. }
  1013. }
  1014. }
  1015. }
  1016. }
  1017. //+----------------------------------------------------------------------------
  1018. //
  1019. // Function CGeneralPage::OnPhoneBookButton
  1020. //
  1021. // Synopsis Handler for handling the "Phone Book..." button-click
  1022. // in the 'Dialing' tab.
  1023. //
  1024. // Arguments nPhoneIdx phone index
  1025. //
  1026. // History 4/30/97 henryt modified for new UI
  1027. // 11/3/97 fengsun Change to a member function
  1028. //
  1029. //-----------------------------------------------------------------------------
  1030. void CGeneralPage::OnPhoneBookButton(UINT nPhoneIdx)
  1031. {
  1032. PBArgs sArgs;
  1033. LPTSTR pszTmp;
  1034. UINT nEditID = !nPhoneIdx ? IDC_GENERAL_PRIMARY_EDIT: IDC_GENERAL_BACKUP_EDIT;
  1035. //UINT nDescID = !nPhoneIdx ? IDC_GENERAL_PRIMARYDESC_DISPLAY: IDC_GENERAL_BACKUPDESC_DISPLAY;
  1036. UINT nUdrID = !nPhoneIdx? IDC_GENERAL_UDR1_CHECKBOX : IDC_GENERAL_UDR2_CHECKBOX;
  1037. BOOL bRes;
  1038. UINT uiSrc;
  1039. BOOL bBlankPhone = FALSE;
  1040. memset(&sArgs,0,sizeof(sArgs));
  1041. sArgs.pszCMSFile = m_pArgs->piniService->GetFile();
  1042. //
  1043. // Update the attributes of the users phone number selection to reflect
  1044. // any interim changes. This ensures that we will default to the correct
  1045. // service, country and region of the current phone number selection. (4397)
  1046. //
  1047. if (nPhoneIdx && !GetWindowTextLengthU(GetDlgItem(m_hWnd, nEditID)))
  1048. {
  1049. //
  1050. // if we're changing the backup # and currently the backup # is empty,
  1051. // we use the state and country info of the primary #.
  1052. //
  1053. uiSrc = 0;
  1054. }
  1055. else
  1056. {
  1057. uiSrc = nPhoneIdx;
  1058. }
  1059. lstrcpynU(sArgs.szServiceType, m_DialInfo[uiSrc].szServiceType, CELEMS(sArgs.szServiceType));
  1060. sArgs.dwCountryId = m_DialInfo[uiSrc].dwCountryID;
  1061. lstrcpynU(sArgs.szRegionName, m_DialInfo[uiSrc].szRegionName, CELEMS(sArgs.szRegionName));
  1062. sArgs.pszMessage = m_pArgs->piniService->GPPS(c_pszCmSection, c_pszCmEntryPbMessage);
  1063. //
  1064. // Check to see if the phone number is blank. We need to save this off for
  1065. // balloon tips to use later.
  1066. //
  1067. if(0 == GetWindowTextLengthU(GetDlgItem(m_hWnd,nEditID)))
  1068. {
  1069. bBlankPhone = TRUE;
  1070. }
  1071. //
  1072. // Make sure that bitmap path is complete
  1073. //
  1074. pszTmp = m_pArgs->piniService->GPPS(c_pszCmSection, c_pszCmEntryPbLogo);
  1075. if (pszTmp && *pszTmp)
  1076. {
  1077. sArgs.pszBitmap = CmConvertRelativePath(m_pArgs->piniService->GetFile(), pszTmp);
  1078. }
  1079. CmFree(pszTmp);
  1080. //
  1081. // Include the help file name
  1082. //
  1083. sArgs.pszHelpFile = m_pArgs->pszHelpFile;
  1084. //
  1085. // Need the master palette handle also.
  1086. //
  1087. sArgs.phMasterPalette = &m_pArgs->hMasterPalette;
  1088. //
  1089. // Launch the phonebook dlg
  1090. //
  1091. bRes = DisplayPhoneBook(m_hWnd,&sArgs, m_pArgs->fHasValidTopLevelPBK, m_pArgs->fHasValidReferencedPBKs);
  1092. CmFree(sArgs.pszMessage);
  1093. CmFree(sArgs.pszBitmap);
  1094. if (!bRes)
  1095. {
  1096. return;
  1097. }
  1098. //
  1099. // We have a new phone number selected, update phone number buffers.
  1100. // and configure UI accordingly. If no dialing rules, the its a non
  1101. // issue, leave it as is.
  1102. //
  1103. m_bAPInfoChanged = TRUE;
  1104. if (!m_pArgs->fNoDialingRules)
  1105. {
  1106. EnableWindow(GetDlgItem(m_hWnd, nUdrID), TRUE);
  1107. CheckDlgButton(m_hWnd, nUdrID, (m_DialInfo[nPhoneIdx].dwPhoneInfoFlags & PIF_USE_DIALING_RULES));
  1108. //
  1109. // Set TAPI button display according to dialing rules use.
  1110. //
  1111. UpdateDialingRulesButton();
  1112. }
  1113. //
  1114. // Copy the new info in the tmp phone info array. First we
  1115. // Get the new phonebook name, which should be a full path
  1116. //
  1117. MYDBGASSERT(FileExists(sArgs.szPhoneBookFile));
  1118. lstrcpynU(m_DialInfo[nPhoneIdx].szPhoneBookFile, sArgs.szPhoneBookFile,
  1119. CELEMS(m_DialInfo[nPhoneIdx].szPhoneBookFile));
  1120. lstrcpynU(m_DialInfo[nPhoneIdx].szDUN, sArgs.szDUNFile,
  1121. CELEMS(m_DialInfo[nPhoneIdx].szDUN));
  1122. //
  1123. // Remove the first element (country code) from the non-canonical number
  1124. //
  1125. StripFirstElement(sArgs.szNonCanonical);
  1126. //
  1127. // If there was no area code, then we'll have a leading space, trim it
  1128. //
  1129. CmStrTrim(sArgs.szNonCanonical);
  1130. //
  1131. // Update our buffers
  1132. //
  1133. lstrcpynU(m_DialInfo[nPhoneIdx].szPhoneNumber, sArgs.szNonCanonical, CELEMS(m_DialInfo[nPhoneIdx].szPhoneNumber));
  1134. lstrcpynU(m_DialInfo[nPhoneIdx].szCanonical, sArgs.szCanonical, CELEMS(m_DialInfo[nPhoneIdx].szCanonical));
  1135. lstrcpynU(m_DialInfo[nPhoneIdx].szDesc, sArgs.szDesc, CELEMS(m_DialInfo[nPhoneIdx].szDesc));
  1136. m_DialInfo[nPhoneIdx].dwCountryID = sArgs.dwCountryId;
  1137. //
  1138. // Store attributes of user selection (ie.service, country, region)
  1139. // We will store this data permanently if the user exits with an OK.
  1140. // It is also used if the user returns to the PB dialog (4397)
  1141. //
  1142. lstrcpynU(m_DialInfo[nPhoneIdx].szServiceType,
  1143. sArgs.szServiceType, CELEMS(m_DialInfo[nPhoneIdx].szServiceType));
  1144. lstrcpynU(m_DialInfo[nPhoneIdx].szRegionName,
  1145. sArgs.szRegionName, CELEMS(m_DialInfo[nPhoneIdx].szRegionName));
  1146. //
  1147. // Display the current phone number and update the description.
  1148. //
  1149. DisplayMungedPhone(nPhoneIdx);
  1150. //
  1151. // Update the description display
  1152. //
  1153. UpdateNumberDescription(nPhoneIdx, sArgs.szDesc);
  1154. //SetDlgItemText(m_hWnd, nDescID, sArgs.szDesc);
  1155. //
  1156. // Check for and display balloon tips if enabled
  1157. //
  1158. if (m_pArgs->fHideBalloonTips)
  1159. {
  1160. CMTRACE(TEXT("Balloon tips are disabled."));
  1161. }
  1162. else
  1163. {
  1164. RECT rect;
  1165. POINT point = {0,0};
  1166. LPTSTR pszBalloonTitle = NULL;
  1167. LPTSTR pszBalloonMsg = NULL;
  1168. HWND hwndParent = GetParent(m_hWnd);
  1169. HWND hwndTAPIButton = GetDlgItem(m_hWnd, IDC_GENERAL_TAPI_BUTTON);
  1170. HWND hwndPrimaryDRCheckbox = GetDlgItem(m_hWnd, IDC_GENERAL_UDR1_CHECKBOX);
  1171. HWND hwndNewAPButton = GetDlgItem(m_hWnd, IDC_GENERAL_NEWAP_BUTTON);
  1172. MYDBGASSERT(hwndParent);
  1173. MYDBGASSERT(hwndTAPIButton);
  1174. MYDBGASSERT(hwndPrimaryDRCheckbox);
  1175. MYDBGASSERT(hwndNewAPButton);
  1176. if (hwndParent && hwndTAPIButton && hwndPrimaryDRCheckbox && hwndNewAPButton)
  1177. {
  1178. //
  1179. // Get the BalloonTipsDisplayed flags from the registry
  1180. //
  1181. DWORD dwBalloonTipsDisplayed = m_pArgs->piniBothNonFav->GPPI(c_pszCmSection, c_pszCmEntryBalloonTipsDisplayed, NULL);
  1182. //
  1183. // If the primary button was clicked and the edit control is blank, we will try to display the Dialing Rules balloon tip,
  1184. // else we will try to display the access point balloon tip.
  1185. //
  1186. if (bBlankPhone)
  1187. {
  1188. //
  1189. // We only display if the primary Dialing Rules checkbox is enabled. Then if the Dialing Rules button is enabled,
  1190. // we point the balloon tip to the button, otherwise we will point it to the checkbox.
  1191. //
  1192. if (IsWindowEnabled(hwndPrimaryDRCheckbox) && !nPhoneIdx)
  1193. {
  1194. pszBalloonTitle = CmLoadString(g_hInst, IDMSG_BALLOON_TITLE_DIALINGRULES);
  1195. pszBalloonMsg = CmLoadString(g_hInst, IDMSG_BALLOON_MSG_DIALINGRULES);
  1196. if (IsWindowEnabled(hwndTAPIButton))
  1197. {
  1198. if (GetWindowRect(hwndTAPIButton, &rect))
  1199. {
  1200. //
  1201. // Get the coordinates of the Dialing Rules button. We want the balloon tip to point
  1202. // to half way up the button and 10px left of the right edge.
  1203. //
  1204. point.x = rect.right - 10;
  1205. point.y = ((rect.bottom - rect.top) / 2) + rect.top;
  1206. }
  1207. }
  1208. else
  1209. {
  1210. if (GetWindowRect(hwndPrimaryDRCheckbox, &rect))
  1211. {
  1212. //
  1213. // Get the coordinates of the Primary Dialing Rules checkbox. We want the balloon tip to point
  1214. // to the center of the checkbox.
  1215. //
  1216. point.x = rect.left + 10;
  1217. point.y = ((rect.bottom - rect.top) / 2) + rect.top;
  1218. }
  1219. }
  1220. //
  1221. // Update the registry flag to reset the Access Point balloon tip if the dialing rules balloon tip is displayed
  1222. //
  1223. if (dwBalloonTipsDisplayed & BT_ACCESS_POINTS)
  1224. {
  1225. dwBalloonTipsDisplayed = dwBalloonTipsDisplayed & ~BT_ACCESS_POINTS;
  1226. }
  1227. }
  1228. }
  1229. else
  1230. {
  1231. // We display only if Access Points are not enabled and the phone number
  1232. // edit control is not blank.
  1233. //
  1234. if(!m_pArgs->fAccessPointsEnabled && !nPhoneIdx)
  1235. {
  1236. //
  1237. // Check to see if we have displayed this balloon tip before.
  1238. //
  1239. if (!(dwBalloonTipsDisplayed & BT_ACCESS_POINTS))
  1240. {
  1241. pszBalloonTitle = CmLoadString(g_hInst, IDMSG_BALLOON_TITLE_ACCESSPOINT);
  1242. pszBalloonMsg = CmLoadString(g_hInst, IDMSG_BALLOON_MSG_ACCESSPOINT);
  1243. if (GetWindowRect(hwndNewAPButton, &rect))
  1244. {
  1245. //
  1246. // Get the coordinates for the New Access Point button. We want the balloon tip to point
  1247. // to half way up the button and 10px left of the right edge.
  1248. //
  1249. point.x = rect.right - 10;
  1250. point.y = ((rect.bottom - rect.top) / 2) + rect.top;
  1251. //
  1252. // Update registry value
  1253. //
  1254. dwBalloonTipsDisplayed = dwBalloonTipsDisplayed | BT_ACCESS_POINTS;
  1255. }
  1256. }
  1257. }
  1258. }
  1259. //
  1260. // Verify we have the info we need and display the balloon tip
  1261. //
  1262. if (pszBalloonTitle && pszBalloonMsg && point.x && point.y)
  1263. {
  1264. if (m_pArgs && m_pArgs->pBalloonTip)
  1265. {
  1266. if (m_pArgs->pBalloonTip->DisplayBalloonTip(&point, TTI_INFO, pszBalloonTitle, pszBalloonMsg, hwndParent))
  1267. {
  1268. //
  1269. // Write the updated BalloonTipsDisplay flag to the registry
  1270. //
  1271. m_pArgs->piniBothNonFav->WPPI(c_pszCmSection, c_pszCmEntryBalloonTipsDisplayed, dwBalloonTipsDisplayed);
  1272. }
  1273. else
  1274. {
  1275. CMTRACE3(TEXT("BalloonTip failed to display - %s; at coordinates{%li,%li}"),pszBalloonTitle,point.x,point.y);
  1276. }
  1277. }
  1278. }
  1279. CmFree(pszBalloonTitle);
  1280. CmFree(pszBalloonMsg);
  1281. }
  1282. }
  1283. }
  1284. //+---------------------------------------------------------------------------
  1285. //
  1286. // Function: HaveContextHelp
  1287. //
  1288. // Synopsis: Whether a specific control id has context help
  1289. // This function very easily introducce inconsistance
  1290. // Every dialog should manage its own control, instead having this
  1291. // function keep track of all the controls.
  1292. //
  1293. // Arguments: hwndDlg the hwnd of parent dlg
  1294. // hwndCtrl the hwnd of control
  1295. //
  1296. // Returns: NONE
  1297. //
  1298. // History: henryt Created 6/26/97
  1299. //
  1300. //----------------------------------------------------------------------------
  1301. BOOL HaveContextHelp(
  1302. HWND hwndDlg,
  1303. HWND hwndCtrl
  1304. )
  1305. {
  1306. //
  1307. // list of controls that we don't provide context help for
  1308. //
  1309. static const int rgiNoContextHelpCtrlId[] =
  1310. {
  1311. IDC_MAIN_BITMAP,
  1312. IDC_PHONEBOOK_BITMAP,
  1313. IDC_GENERAL_PHONENUMBERS_GROUPBOX,
  1314. // IDC_GENERAL_PRIMARYDESC_DISPLAY,
  1315. // IDC_GENERAL_BACKUPDESC_DISPLAY,
  1316. // IDC_ABOUT_BITMAP,
  1317. IDC_ABOUT_FRAME,
  1318. IDC_ABOUT_VERSION,
  1319. IDC_ABOUT_WARNING,
  1320. IDC_ABOUT_CM_STATIC,
  1321. IDC_ABOUT_VERSION_STATIC,
  1322. IDC_ABOUT_COPYRIGHT_STATIC,
  1323. IDC_ABOUT_SHOCKWAVE_STATIC,
  1324. IDC_INET_ICON,
  1325. IDC_CONNSTAT_ICON,
  1326. IDC_CONNSTAT_DURATION_DISPLAY,
  1327. IDC_CONNSTAT_SPEED_DISPLAY,
  1328. IDC_CONNSTAT_RECEIVED_DISPLAY,
  1329. IDC_CONNSTAT_SENT_DISPLAY,
  1330. IDC_CONNSTAT_DISCONNECT_DISPLAY,
  1331. IDC_DETAILINFO,
  1332. IDC_CONNSTAT_STATIC_CALL_DURATION,
  1333. IDC_CONNSTAT_STATIC_CONNECT_SPEED,
  1334. IDC_CONNSTAT_STATIC_BYTES_RECEIVED,
  1335. IDC_CONNSTAT_STATIC_BYTES_SENT
  1336. };
  1337. UINT uIdx, uLast;
  1338. MYDBGASSERT(hwndDlg);
  1339. MYDBGASSERT(hwndCtrl);
  1340. for (uIdx=0, uLast=sizeof(rgiNoContextHelpCtrlId)/sizeof(rgiNoContextHelpCtrlId[0]);
  1341. uIdx < uLast; uIdx++)
  1342. {
  1343. if (GetDlgItem(hwndDlg, rgiNoContextHelpCtrlId[uIdx]) == hwndCtrl)
  1344. {
  1345. break;
  1346. }
  1347. }
  1348. return (uIdx == uLast);
  1349. }
  1350. // check if TAPI has its information, put up dialog if not
  1351. BOOL CGeneralPage::CheckTapi(TapiLinkageStruct *ptlsTapiLink, HINSTANCE hInst)
  1352. {
  1353. LONG lRes;
  1354. LPLINETRANSLATEOUTPUT pltoOutput = NULL;
  1355. DWORD dwLen;
  1356. BOOL bRet = FALSE;
  1357. if (!SetTapiDevice(hInst,ptlsTapiLink,m_szDeviceName))
  1358. {
  1359. return bRet;
  1360. }
  1361. dwLen = sizeof(*pltoOutput) + (1024 * sizeof(TCHAR));
  1362. pltoOutput = (LPLINETRANSLATEOUTPUT) CmMalloc(dwLen);
  1363. if (NULL == pltoOutput)
  1364. {
  1365. return bRet;
  1366. }
  1367. pltoOutput->dwTotalSize = dwLen;
  1368. lRes = ptlsTapiLink->pfnlineTranslateAddress(ptlsTapiLink->hlaLine,
  1369. ptlsTapiLink->dwDeviceId,
  1370. ptlsTapiLink->dwApiVersion,
  1371. TEXT("1234"),
  1372. 0,
  1373. LINETRANSLATEOPTION_CANCELCALLWAITING,
  1374. pltoOutput);
  1375. //
  1376. // If the line translate failed, then execute the Dialing Rules UI by calling
  1377. // lineTranslateDialog (inside OnDialingProperties). Providing that the user
  1378. // completes the UI, TAPI will be initialized and ready for use.
  1379. //
  1380. if (ERROR_SUCCESS != lRes)
  1381. {
  1382. OnDialingProperties();
  1383. //
  1384. // The user may have canceled, so test again before declaring success
  1385. //
  1386. lRes = ptlsTapiLink->pfnlineTranslateAddress(ptlsTapiLink->hlaLine,
  1387. ptlsTapiLink->dwDeviceId,
  1388. ptlsTapiLink->dwApiVersion,
  1389. TEXT("1234"),
  1390. 0,
  1391. LINETRANSLATEOPTION_CANCELCALLWAITING,
  1392. pltoOutput);
  1393. }
  1394. if (ERROR_SUCCESS == lRes)
  1395. {
  1396. bRet = TRUE;
  1397. }
  1398. CmFree(pltoOutput);
  1399. m_pArgs->fNeedConfigureTapi = !(bRet);
  1400. return bRet;
  1401. }
  1402. //+----------------------------------------------------------------------------
  1403. //
  1404. // Function: CPropertiesSheet::AddExternalPage
  1405. //
  1406. // Synopsis: Add a page to the property sheet.
  1407. //
  1408. // Arguments: PROPSHEETPAGE * pPsp - The page to add
  1409. //
  1410. // Returns: Nothing
  1411. //
  1412. // History: tomkel Created 01/09/2001
  1413. //
  1414. //+----------------------------------------------------------------------------
  1415. void CPropertiesSheet::AddExternalPage(PROPSHEETPAGE *pPsp)
  1416. {
  1417. //
  1418. // This version of AddExternalPage only work before calling DoPropertySheet
  1419. //
  1420. MYDBGASSERT(pPsp);
  1421. if (!pPsp)
  1422. {
  1423. return;
  1424. }
  1425. CMTRACE1(TEXT("CPropertiesSheet::AddExternalPage - sizeof(PROPSHEETPAGE) = %d"),sizeof(PROPSHEETPAGE));
  1426. MYDBGASSERT(m_numPages < MAX_PAGES);
  1427. CopyMemory((LPVOID)&m_pages[m_numPages], (LPVOID)pPsp, sizeof(PROPSHEETPAGE));
  1428. m_adwPageType[m_numPages] = CPROP_SHEET_TYPE_EXTERNAL;
  1429. m_numPages++;
  1430. }
  1431. //+----------------------------------------------------------------------------
  1432. //
  1433. // Function: CPropertiesSheet::AddPage
  1434. //
  1435. // Synopsis: Add a page to the property sheet.
  1436. //
  1437. // Arguments: const CPropertiesPage* pPage - The page to add
  1438. //
  1439. // Returns: Nothing
  1440. //
  1441. // History: fengsun Created Header 2/26/98
  1442. //
  1443. //+----------------------------------------------------------------------------
  1444. void CPropertiesSheet::AddPage(const CPropertiesPage* pPage)
  1445. {
  1446. //
  1447. // This version of AddPage only work before calling DoPropertySheet
  1448. //
  1449. MYDBGASSERT(pPage);
  1450. MYDBGASSERT(pPage->m_pszTemplate);
  1451. if (!pPage)
  1452. {
  1453. return;
  1454. }
  1455. MYDBGASSERT(m_numPages < MAX_PAGES);
  1456. m_pages[m_numPages].pszTemplate = pPage->m_pszTemplate;
  1457. m_pages[m_numPages].lParam = (LPARAM)pPage; // save the property page object
  1458. m_adwPageType[m_numPages] = CPROP_SHEET_TYPE_INTERNAL;
  1459. m_numPages++;
  1460. }
  1461. //+----------------------------------------------------------------------------
  1462. //
  1463. // Function: CPropertiesSheet::DoPropertySheet
  1464. //
  1465. // Synopsis: Call PropertySheet to create a modal property sheet
  1466. //
  1467. // Arguments: HWND hWndParent - Parent window
  1468. // LPTSTR pszCaption - Title string
  1469. // HINSTANCE hInst - The resource instance
  1470. // UINT nStartPage - The start page
  1471. //
  1472. // Returns: int - return value of PropertySheet()
  1473. //
  1474. // History: fengsun Created Header 2/26/98
  1475. //
  1476. //+----------------------------------------------------------------------------
  1477. int CPropertiesSheet::DoPropertySheet(HWND hWndParent, LPTSTR pszCaption, HINSTANCE hInst)
  1478. {
  1479. for (UINT i=0; i<m_numPages; i++)
  1480. {
  1481. //
  1482. // Only do this for our CM property pages that are classes
  1483. //
  1484. if (m_adwPageType[i] == CPROP_SHEET_TYPE_INTERNAL)
  1485. {
  1486. m_pages[i].dwSize = sizeof(PROPSHEETPAGE);
  1487. m_pages[i].hInstance = hInst;
  1488. m_pages[i].dwFlags = 0; // No help button or F1
  1489. m_pages[i].pfnDlgProc = (DLGPROC)CPropertiesPage::PropPageProc;
  1490. }
  1491. }
  1492. m_psh.dwSize = sizeof(PROPSHEETHEADER);
  1493. m_psh.hwndParent = hWndParent;
  1494. m_psh.hInstance = hInst;
  1495. m_psh.pszIcon = 0;
  1496. m_psh.pszCaption = pszCaption; // MAKEINTRESOURCE(nCaption);
  1497. m_psh.nPages = m_numPages;
  1498. m_psh.nStartPage = 0;
  1499. m_psh.ppsp = m_pages;
  1500. m_psh.dwFlags = PSH_PROPSHEETPAGE|PSH_NOAPPLYNOW|PSH_USECALLBACK;
  1501. m_psh.pfnCallback = PropSheetProc;
  1502. //
  1503. // Dynamiclly load comctl32.dll
  1504. //
  1505. int iRet = -1;
  1506. HINSTANCE hComCtl = LoadLibraryExA("comctl32.dll", NULL, 0);
  1507. CMASSERTMSG(hComCtl, TEXT("LoadLibrary - comctl32 failed"));
  1508. if (hComCtl != NULL)
  1509. {
  1510. typedef int (*PROPERTYSHEETPROC)(LPCPROPSHEETHEADER lppsph);
  1511. typedef void (*INITCOMMONCONTROLSPROC)(VOID);
  1512. PROPERTYSHEETPROC fnPropertySheet;
  1513. INITCOMMONCONTROLSPROC fnInitCommonControls;
  1514. LPSTR pszPropSheetFuncName = OS_NT ? "PropertySheetW" : "PropertySheetA";
  1515. fnPropertySheet = (PROPERTYSHEETPROC)GetProcAddress(hComCtl, pszPropSheetFuncName);
  1516. fnInitCommonControls = (INITCOMMONCONTROLSPROC)GetProcAddress(hComCtl, "InitCommonControls");
  1517. if (fnPropertySheet == NULL || fnInitCommonControls == NULL)
  1518. {
  1519. CMTRACE(TEXT("GetProcAddress of comctl32 failed"));
  1520. }
  1521. else
  1522. {
  1523. fnInitCommonControls();
  1524. //
  1525. // Set m_pThis right before we call PropertySheet
  1526. // It will be used by PropSheetProc.
  1527. // Note: this is not multi-thread safe. However, there is very little chance
  1528. // that another thread is trying to bring up settings at the same time, and
  1529. // a context switch happens before PropSheetProc got called
  1530. //
  1531. MYDBGASSERT(m_pThis == NULL);
  1532. m_pThis = this;
  1533. if ((iRet = fnPropertySheet(&m_psh)) == -1)
  1534. {
  1535. CMTRACE(TEXT("DoPropertySheet: PropertySheet() failed"));
  1536. }
  1537. }
  1538. FreeLibrary(hComCtl);
  1539. }
  1540. return iRet;
  1541. }
  1542. //
  1543. // Implementation of class CPropertiesPage
  1544. //
  1545. //+----------------------------------------------------------------------------
  1546. //
  1547. // Function: CPropertiesPage::CPropertiesPage
  1548. //
  1549. // Synopsis: Constructor
  1550. //
  1551. // Arguments: UINT nIDTemplate - Resource ID of the page
  1552. // const DWORD* pHelpPairs - The pairs of ControlID/HelpID
  1553. // const TCHAR* lpszHelpFile - The help file name
  1554. //
  1555. // Returns: Nothing
  1556. //
  1557. // History: fengsun Created Header 2/26/98
  1558. //
  1559. //+----------------------------------------------------------------------------
  1560. CPropertiesPage::CPropertiesPage(UINT nIDTemplate, const DWORD* pHelpPairs, const TCHAR* lpszHelpFile )
  1561. :CWindowWithHelp(pHelpPairs, lpszHelpFile)
  1562. {
  1563. m_pszTemplate = MAKEINTRESOURCE(nIDTemplate);
  1564. }
  1565. CPropertiesPage::CPropertiesPage(LPCTSTR lpszTemplateName, const DWORD* pHelpPairs,
  1566. const TCHAR* lpszHelpFile)
  1567. :CWindowWithHelp(pHelpPairs, lpszHelpFile)
  1568. {
  1569. m_pszTemplate = lpszTemplateName;
  1570. }
  1571. //+----------------------------------------------------------------------------
  1572. //
  1573. // Function: CPropertiesPage::OnInitDialog
  1574. //
  1575. // Synopsis: Virtual function. Called upon WM_INITDIALOG message
  1576. //
  1577. // Arguments: None
  1578. //
  1579. // Returns: BOOL - return value of the message
  1580. //
  1581. // History: fengsun Created Header 2/26/98
  1582. //
  1583. //+----------------------------------------------------------------------------
  1584. BOOL CPropertiesPage::OnInitDialog()
  1585. {
  1586. return TRUE;
  1587. }
  1588. //+----------------------------------------------------------------------------
  1589. //
  1590. // Function: CPropertiesPage::OnCommand
  1591. //
  1592. // Synopsis: Virtual function. Called upon WM_COMMAND
  1593. //
  1594. // Arguments: WPARAM - wParam of the message
  1595. // LPARAM - lParam of the message
  1596. //
  1597. // Returns: DWORD - return value of the message
  1598. //
  1599. // History: fengsun Created Header 2/26/98
  1600. //
  1601. //+----------------------------------------------------------------------------
  1602. DWORD CPropertiesPage::OnCommand(WPARAM , LPARAM )
  1603. {
  1604. return 0;
  1605. }
  1606. //+----------------------------------------------------------------------------
  1607. //
  1608. // Function: CPropertiesPage::OnSetActive
  1609. //
  1610. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_SETACTIVE
  1611. //
  1612. // Arguments: None
  1613. //
  1614. // Returns: BOOL - return value of the message
  1615. //
  1616. // History: fengsun Created Header 2/26/98
  1617. //
  1618. //+----------------------------------------------------------------------------
  1619. BOOL CPropertiesPage::OnSetActive()
  1620. {
  1621. return 0;
  1622. }
  1623. //+----------------------------------------------------------------------------
  1624. //
  1625. // Function: CPropertiesPage::OnKillActive
  1626. //
  1627. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_KILLACTIVE
  1628. // Notifies a page that it is about to lose activation either because
  1629. // another page is being activated or the user has clicked the OK button.
  1630. //
  1631. // Arguments: None
  1632. //
  1633. // Returns: BOOL - return value of the message
  1634. //
  1635. // History: fengsun Created Header 2/26/98
  1636. //
  1637. //+----------------------------------------------------------------------------
  1638. BOOL CPropertiesPage::OnKillActive()
  1639. {
  1640. return FALSE;
  1641. }
  1642. //+----------------------------------------------------------------------------
  1643. //
  1644. // Function: CPropertiesPage::OnApply
  1645. //
  1646. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_APPLY
  1647. // Indicates that the user clicked the OK or Apply Now button
  1648. // and wants all changes to take effect.
  1649. //
  1650. // Arguments: None
  1651. //
  1652. // Returns: NONE
  1653. //
  1654. // History: fengsun Created Header 2/26/98
  1655. //
  1656. //+----------------------------------------------------------------------------
  1657. void CPropertiesPage::OnApply()
  1658. {
  1659. SetPropSheetResult(PSNRET_NOERROR);
  1660. }
  1661. //+----------------------------------------------------------------------------
  1662. //
  1663. // Function: CPropertiesPage::OnReset
  1664. //
  1665. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_RESET
  1666. // Notifies a page that the user has clicked the Cancel button and
  1667. // the property sheet is about to be destroyed.
  1668. //
  1669. // Arguments: None
  1670. //
  1671. // Returns: NONE
  1672. //
  1673. // History: fengsun Created Header 2/26/98
  1674. //
  1675. //+----------------------------------------------------------------------------
  1676. void CPropertiesPage::OnReset()
  1677. {
  1678. }
  1679. //+----------------------------------------------------------------------------
  1680. //
  1681. // Function: CPropertiesPage::OnPsnHelp
  1682. //
  1683. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_HELP
  1684. //
  1685. // Arguments: HWND - Window handle to the control sending a message
  1686. // UINT - Identifier of the control sending a message
  1687. //
  1688. // Returns: Nothing
  1689. //
  1690. // History: Created Header 2/26/98
  1691. //
  1692. //+----------------------------------------------------------------------------
  1693. void CPropertiesPage::OnPsnHelp(HWND , UINT_PTR)
  1694. {
  1695. if (m_lpszHelpFile && m_lpszHelpFile[0])
  1696. {
  1697. CmWinHelp(m_hWnd, m_hWnd, m_lpszHelpFile, HELP_FORCEFILE, 0);
  1698. }
  1699. }
  1700. //+----------------------------------------------------------------------------
  1701. //
  1702. // Function: CPropertiesPage::OnOtherMessage
  1703. //
  1704. // Synopsis: Callup opun message other than WM_INITDIALOG and WM_COMMAND
  1705. //
  1706. // Arguments: UINT - Message Id
  1707. // WPARAM - wParam of the message
  1708. // LPARAM - lParam of the message
  1709. //
  1710. // Returns: DWORD - return value of the message
  1711. //
  1712. // History: fengsun Created Header 2/26/98
  1713. //
  1714. //+----------------------------------------------------------------------------
  1715. DWORD CPropertiesPage::OnOtherMessage(UINT , WPARAM , LPARAM )
  1716. {
  1717. return FALSE;
  1718. }
  1719. //+----------------------------------------------------------------------------
  1720. //
  1721. // Function: CPropertiesPage::PropPageProc
  1722. //
  1723. // Synopsis: The call back dialog procedure for all the property pages
  1724. //
  1725. // Arguments: HWND hwndDlg - Property page window handle
  1726. // UINT uMsg - Message ID
  1727. // WPARAM wParam - wParam of the message
  1728. // LPARAM lParam - lParam of the message
  1729. //
  1730. // Returns: BOOL - return value of the message
  1731. //
  1732. // History: fengsun Created Header 2/26/98
  1733. //
  1734. //+----------------------------------------------------------------------------
  1735. INT_PTR CALLBACK CPropertiesPage::PropPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam, LPARAM lParam)
  1736. {
  1737. CPropertiesPage* pPage;
  1738. NMHDR* pnmHeader = (NMHDR*)lParam;
  1739. //
  1740. // Save the object pointer on the first message,
  1741. // The first message is not necessarily WM_INITDIALOG
  1742. //
  1743. if (uMsg == WM_INITDIALOG)
  1744. {
  1745. pPage = (CPropertiesPage*) ((PROPSHEETPAGE *)lParam)->lParam;
  1746. //
  1747. // Save the object pointer, this is implementation detail
  1748. // The user of this class should not be aware of this
  1749. //
  1750. ::SetWindowLongU(hwndDlg, DWLP_USER, (LONG_PTR)pPage);
  1751. MYDBGASSERT(pPage);
  1752. MYDBGASSERT(pPage->m_hWnd == NULL);
  1753. pPage->m_hWnd = hwndDlg;
  1754. }
  1755. else
  1756. {
  1757. pPage = (CPropertiesPage*) GetWindowLongU(hwndDlg,DWLP_USER);
  1758. if (pPage == NULL)
  1759. {
  1760. return FALSE;
  1761. }
  1762. MYDBGASSERT(pPage->m_hWnd == hwndDlg);
  1763. }
  1764. ASSERT_VALID(pPage);
  1765. switch(uMsg)
  1766. {
  1767. case WM_INITDIALOG:
  1768. return pPage->OnInitDialog();
  1769. case WM_COMMAND:
  1770. return (BOOL)pPage->OnCommand(wParam, lParam);
  1771. case WM_NOTIFY:
  1772. {
  1773. if (NULL == pnmHeader)
  1774. {
  1775. return FALSE;
  1776. }
  1777. switch (pnmHeader->code)
  1778. {
  1779. case PSN_SETACTIVE:
  1780. pPage->OnSetActive();
  1781. break;
  1782. case PSN_KILLACTIVE:
  1783. pPage->OnKillActive();
  1784. break;
  1785. case PSN_APPLY:
  1786. pPage->OnApply();
  1787. return TRUE;
  1788. case PSN_RESET:
  1789. pPage->OnReset();
  1790. break;
  1791. case PSN_HELP:
  1792. pPage->OnPsnHelp(pnmHeader->hwndFrom , pnmHeader->idFrom);
  1793. break;
  1794. default:
  1795. break;
  1796. }
  1797. break;
  1798. } // WM_NOTIFY
  1799. case WM_HELP:
  1800. pPage->OnHelp((LPHELPINFO)lParam);
  1801. return TRUE;
  1802. case WM_CONTEXTMENU:
  1803. {
  1804. POINT pos = {LOWORD(lParam), HIWORD(lParam)};
  1805. CMTRACE3(TEXT("\r\nPropPageProc() - WM_CONTEXTMENU wParam = %u pos.x = %u, pos.y = %u"),
  1806. wParam, pos.x, pos.y);
  1807. pPage->OnContextMenu((HWND) wParam, pos);
  1808. return TRUE;
  1809. }
  1810. default:
  1811. return (BOOL)pPage->OnOtherMessage(uMsg, wParam, lParam);
  1812. }
  1813. return (FALSE);
  1814. }
  1815. //
  1816. // Help id pairs for dialing page
  1817. //
  1818. const DWORD CGeneralPage::m_dwHelp[] = {
  1819. IDC_GENERAL_PHONENUMBERS_GROUPBOX, IDH_GENERAL_PHONENUM,
  1820. IDC_RADIO_DIRECT, IDH_GENERAL_ALREADY,
  1821. IDC_RADIO_DIALUP, IDH_GENERAL_DIALTHIS,
  1822. IDC_GENERAL_P1_STATIC, IDH_GENERAL_PHONENUM,
  1823. IDC_GENERAL_PRIMARY_EDIT, IDH_GENERAL_PHONENUM,
  1824. IDC_GENERAL_PRIMARYPB_BUTTON, IDH_GENERAL_PHONEBOOK,
  1825. IDC_GENERAL_UDR1_CHECKBOX, IDH_GENERAL_USE_DIAL_RULE,
  1826. IDC_GENERAL_P2_STATIC, IDH_GENERAL_BACKUPNUM,
  1827. IDC_GENERAL_BACKUP_EDIT, IDH_GENERAL_BACKUPNUM,
  1828. IDC_GENERAL_BACKUPPB_BUTTON, IDH_GENERAL_PHONEBOOKB,
  1829. IDC_GENERAL_UDR2_CHECKBOX, IDH_GENERAL_USE_DIAL_RULEB,
  1830. IDC_GENERAL_TAPI_BUTTON, IDH_GENERAL_DIALRULE,
  1831. IDC_GENERAL_MODEM_COMBO, IDH_GENERAL_CONNECT_MODEM,
  1832. IDC_CONNECT_USING, IDH_GENERAL_CONNECT_MODEM,
  1833. IDC_GENERAL_ACCESSPOINT_COMBO, IDH_GENERAL_ACCESSPOINTS,
  1834. IDC_GENERAL_ACCESSPOINT_STATIC, IDH_GENERAL_ACCESSPOINTS,
  1835. IDC_GENERAL_NEWAP_BUTTON, IDH_GENERAL_NEWAP,
  1836. IDC_GENERAL_DELETEAP_BUTTON, IDH_GENERAL_DELETEAP,
  1837. 0,0};
  1838. //+----------------------------------------------------------------------------
  1839. //
  1840. // Function: CGeneralPage::CGeneralPage
  1841. //
  1842. // Synopsis: Constructor
  1843. //
  1844. // Arguments: ArgsStruct* pArgs - Information needed for the page
  1845. // UINT nIDTemplate - Resource ID
  1846. //
  1847. // Returns: Nothing
  1848. //
  1849. // History: fengsun Created Header 2/26/98
  1850. //
  1851. //+----------------------------------------------------------------------------
  1852. CGeneralPage::CGeneralPage(ArgsStruct* pArgs, UINT nIDTemplate)
  1853. : CPropertiesPage(nIDTemplate, m_dwHelp, pArgs->pszHelpFile)
  1854. {
  1855. MYDBGASSERT(pArgs);
  1856. m_pArgs = pArgs;
  1857. m_pEventListener = NULL;
  1858. m_NumPhones = MAX_PHONE_NUMBERS;
  1859. m_szDeviceName[0] = TEXT('\0');
  1860. m_szDeviceType[0] = TEXT('\0');
  1861. m_bDialInfoInit = FALSE;
  1862. }
  1863. //+---------------------------------------------------------------------------
  1864. //
  1865. // Function: CGeneralPage::OnInitDialog
  1866. //
  1867. // Synopsis: Init the General properties property sheet.
  1868. //
  1869. // Arguments: hwndDlg [dlg window handle]
  1870. // pArgs [the ptr to ArgsStruct]
  1871. //
  1872. // Returns: NONE
  1873. //
  1874. // History: henryt Created 4/30/97
  1875. // byao Modified 5/12/97 - disable backup phone no. in
  1876. // 'Dialing with Connectoid' mode
  1877. //----------------------------------------------------------------------------
  1878. BOOL CGeneralPage::OnInitDialog()
  1879. {
  1880. UpdateFont(m_hWnd);
  1881. //
  1882. // Load the Access Points from the registry
  1883. //
  1884. if (FALSE == ShowAccessPointInfoFromReg(m_pArgs, m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO))
  1885. {
  1886. //
  1887. // If the above function fails then there is no Access Point in the registry.
  1888. // Need to figure out if this is the default access point.
  1889. //
  1890. LPTSTR pszTempDefaultAccessPointName = CmLoadString(g_hInst, IDS_DEFAULT_ACCESSPOINT);
  1891. if (pszTempDefaultAccessPointName)
  1892. {
  1893. if (0 == lstrcmpiU(m_pArgs->pszCurrentAccessPoint, pszTempDefaultAccessPointName))
  1894. {
  1895. //
  1896. // This must be an old (1.0 or 1.2) profile since it's the default Access Point and it isn't
  1897. // in the registry yet. Need to properly display the Access Point combobox and
  1898. // create the reg key. Calling AddNewAPToReg does that.
  1899. //
  1900. AddNewAPToReg(m_pArgs->pszCurrentAccessPoint, TRUE);
  1901. //
  1902. // Need to clear the AccessPointEnabled Flag. This is a side effect of calling AddNewAPToReg
  1903. // thus it needs to be cleared (set to FALSE) since we only have one Access Point and
  1904. // the this flag is only set if we have 1+ Access Points
  1905. //
  1906. m_pArgs->fAccessPointsEnabled = FALSE;
  1907. WriteUserInfoToReg(m_pArgs, UD_ID_ACCESSPOINTENABLED, (PVOID) &m_pArgs->fAccessPointsEnabled);
  1908. }
  1909. CmFree(pszTempDefaultAccessPointName);
  1910. }
  1911. }
  1912. //
  1913. // Set phone number descriptions
  1914. //
  1915. UpdateForNewAccessPoint(TRUE);
  1916. //
  1917. // Subclass the Phone Number edit controls
  1918. //
  1919. HWND hwndPrimary = GetDlgItem(m_hWnd, IDC_GENERAL_PRIMARY_EDIT);
  1920. HWND hwndBackup = GetDlgItem(m_hWnd, IDC_GENERAL_BACKUP_EDIT);
  1921. MYDBGASSERT(hwndPrimary && hwndBackup);
  1922. m_pfnOrgEditWndProc = (WNDPROC)SetWindowLongU(hwndPrimary,
  1923. GWLP_WNDPROC, (LONG_PTR)SubClassEditProc);
  1924. WNDPROC lpEditProc = (WNDPROC)SetWindowLongU(hwndBackup,
  1925. GWLP_WNDPROC, (LONG_PTR)SubClassEditProc);
  1926. MYDBGASSERT(lpEditProc == m_pfnOrgEditWndProc);
  1927. //
  1928. // Save the object with the window handle
  1929. //
  1930. SetWindowLongU(hwndPrimary, GWLP_USERDATA, (LONG_PTR)this);
  1931. SetWindowLongU(hwndBackup, GWLP_USERDATA, (LONG_PTR)this);
  1932. return (TRUE);
  1933. }
  1934. //+---------------------------------------------------------------------------
  1935. //
  1936. // Function: CGeneralPage::UpdateForNewAccessPoint
  1937. //
  1938. // Synopsis: Set the phone number description from pArgs.
  1939. //
  1940. // Notes: This function was originally part of OnInitDialog.
  1941. // It was made into a separate function for access points
  1942. //
  1943. // Arguments: fSetPhoneNumberDescriptions [update phone numbers as well]
  1944. //
  1945. // Returns: NONE
  1946. //
  1947. // History: t-urama Created 07/31/2000
  1948. //----------------------------------------------------------------------------
  1949. void CGeneralPage::UpdateForNewAccessPoint(BOOL fSetPhoneNumberDescriptions)
  1950. {
  1951. m_bAPInfoChanged = FALSE;
  1952. LPTSTR pszDefaultAccessPointName = CmLoadString(g_hInst, IDS_DEFAULT_ACCESSPOINT);
  1953. if (pszDefaultAccessPointName && m_pArgs->pszCurrentAccessPoint)
  1954. {
  1955. if (!lstrcmpiU(m_pArgs->pszCurrentAccessPoint, pszDefaultAccessPointName))
  1956. {
  1957. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_DELETEAP_BUTTON), FALSE);
  1958. }
  1959. else
  1960. {
  1961. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_DELETEAP_BUTTON), TRUE);
  1962. }
  1963. }
  1964. else
  1965. {
  1966. CMASSERTMSG(FALSE, TEXT("UpdateForNewAccessPoint -- either CmLoadString of IDS_DEFAULT_ACCESSPOINT failed or pszCurrentAccessPoint is NULL."));
  1967. }
  1968. CmFree(pszDefaultAccessPointName);
  1969. if (fSetPhoneNumberDescriptions)
  1970. {
  1971. UpdateNumberDescription(0, m_pArgs->aDialInfo[0].szDesc);
  1972. UpdateNumberDescription(1, m_pArgs->aDialInfo[1].szDesc);
  1973. if (m_pArgs->IsBothConnTypeSupported())
  1974. {
  1975. //
  1976. // Set radio button according to AlwaysOn state
  1977. //
  1978. if (m_pArgs->IsDirectConnect())
  1979. {
  1980. CheckDlgButton(m_hWnd, IDC_RADIO_DIRECT, BST_CHECKED);
  1981. CheckDlgButton(m_hWnd, IDC_RADIO_DIALUP, BST_UNCHECKED);
  1982. EnableDialupControls(FALSE);
  1983. }
  1984. else
  1985. {
  1986. CheckDlgButton(m_hWnd, IDC_RADIO_DIALUP, BST_CHECKED);
  1987. CheckDlgButton(m_hWnd, IDC_RADIO_DIRECT, BST_UNCHECKED);
  1988. PostMessageU(m_hWnd, WM_INITDIALINFO, 0,0);
  1989. }
  1990. }
  1991. else
  1992. {
  1993. //
  1994. // Note: It is assumed that this page will never be loaded in a pure direct
  1995. // case, thus the deduction that NOT IsBothConnTypeSupported means dial only.
  1996. //
  1997. MYDBGASSERT(!m_pArgs->IsDirectConnect());
  1998. PostMessageU(m_hWnd, WM_INITDIALINFO, 0,0);
  1999. }
  2000. }
  2001. }
  2002. //+----------------------------------------------------------------------------
  2003. //
  2004. // Function: CGeneralPage::EnableDialupControls
  2005. //
  2006. // Synopsis: Sets the enabled state of ALL the dialup controls on the tab
  2007. //
  2008. // Arguments: BOOL fEnable - flag indicating enable state of dial-up controls
  2009. //
  2010. // Returns: Nothing
  2011. //
  2012. // History: nickball Created 04/21/98
  2013. //
  2014. //+----------------------------------------------------------------------------
  2015. void CGeneralPage::EnableDialupControls(BOOL fEnable)
  2016. {
  2017. BOOL fState = fEnable;
  2018. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_P1_STATIC), fState);
  2019. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_PRIMARY_EDIT), fState);
  2020. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_P2_STATIC), fState);
  2021. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_BACKUP_EDIT), fState);
  2022. EnableWindow(GetDlgItem(m_hWnd, IDC_CONNECT_USING), fState);
  2023. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_MODEM_COMBO), fState);
  2024. //
  2025. // We are enabling controls check PB buttons
  2026. //
  2027. fState = FALSE;
  2028. if (fEnable)
  2029. {
  2030. //
  2031. // No phonebooks, no button access
  2032. //
  2033. if (m_pArgs->fHasValidTopLevelPBK || m_pArgs->fHasValidReferencedPBKs)
  2034. {
  2035. fState = TRUE;
  2036. }
  2037. }
  2038. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_PRIMARYPB_BUTTON), fState);
  2039. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_BACKUPPB_BUTTON), fState);
  2040. //
  2041. // Examine the canonical phone number, we must have a canonical form
  2042. // of the number available for Use Dailing Rules to be enabled.
  2043. //
  2044. if (fEnable && *m_DialInfo[0].szCanonical)
  2045. {
  2046. fState = TRUE;
  2047. }
  2048. else
  2049. {
  2050. fState = FALSE;
  2051. }
  2052. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_UDR1_CHECKBOX), fState);
  2053. //
  2054. // Examine the canonical phone number, we must have a canonical form
  2055. // of the number available for Use Dailing Rules to be enabled.
  2056. //
  2057. if (fEnable && *m_DialInfo[1].szCanonical)
  2058. {
  2059. fState = TRUE;
  2060. }
  2061. else
  2062. {
  2063. fState = FALSE;
  2064. }
  2065. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_UDR2_CHECKBOX), fState);
  2066. //
  2067. // Update dialing rules state
  2068. //
  2069. if (fEnable)
  2070. {
  2071. UpdateDialingRulesButton();
  2072. }
  2073. else
  2074. {
  2075. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_TAPI_BUTTON), fEnable);
  2076. }
  2077. }
  2078. //+----------------------------------------------------------------------------
  2079. //
  2080. // Function: CGeneralPage::OnOtherMessage
  2081. //
  2082. // Synopsis: Callup opun message other than WM_INITDIALOG and WM_COMMAND
  2083. //
  2084. // Arguments: UINT - Message Id
  2085. // WPARAM - wParam of the message
  2086. // LPARAM - lParam of the message
  2087. //
  2088. // Returns: DWORD - return value of the message
  2089. //
  2090. // History: fengsun Created Header 2/26/98
  2091. //
  2092. //+----------------------------------------------------------------------------
  2093. DWORD CGeneralPage::OnOtherMessage(UINT uMsg, WPARAM , LPARAM )
  2094. {
  2095. if (uMsg == WM_INITDIALINFO)
  2096. {
  2097. InitDialInfo();
  2098. }
  2099. return FALSE;
  2100. }
  2101. //+----------------------------------------------------------------------------
  2102. //
  2103. // Function: IsUniqueIsdnDevice
  2104. //
  2105. // Synopsis: Checks to see if this is an ISDN device and if it was already added
  2106. // to the ComboBox control identified by hWnd and nId
  2107. //
  2108. // Arguments: None
  2109. //
  2110. // Returns: BOOL - Returns TRUE if a Unique ISDN Device
  2111. //
  2112. // History: quintinb 7/14/99 created
  2113. //
  2114. //+----------------------------------------------------------------------------
  2115. BOOL IsUniqueIsdnDevice(HWND hWnd, UINT nId, LPRASDEVINFO pRasDevInfo)
  2116. {
  2117. BOOL bReturn = FALSE;
  2118. if (hWnd && nId && pRasDevInfo)
  2119. {
  2120. //
  2121. // First lets check to make sure that this is even an ISDN device
  2122. //
  2123. if (0 == lstrcmpiU(pRasDevInfo->szDeviceType, RASDT_Isdn))
  2124. {
  2125. //
  2126. // Okay, it is an ISDN device, do we have one with that name already?
  2127. //
  2128. if (CB_ERR == SendDlgItemMessageU(hWnd, nId, CB_FINDSTRINGEXACT,
  2129. -1, (LPARAM)pRasDevInfo->szDeviceName))
  2130. {
  2131. bReturn = TRUE;
  2132. }
  2133. }
  2134. }
  2135. return bReturn;
  2136. }
  2137. //+----------------------------------------------------------------------------
  2138. //
  2139. // Function: CGeneralPage::InitDialInfo
  2140. //
  2141. // Synopsis: The dialing page can not call LoadDialInfo directly on WM_INITDIALOG
  2142. // LoadDialInfo might popup some UI to install modem. The property
  2143. // sheet and the property page will not be disabled, if a dialog is
  2144. // poped up on WM_INITDIALOG message. Instead, we post a message
  2145. // on WM_INITDIALOG and call LoadDialInfo here.
  2146. // On a slow machine, there might be a period that all the control
  2147. // are gray.
  2148. //
  2149. // Arguments: None
  2150. //
  2151. // Returns: DWORD - Return code from LoadDialInfo
  2152. //
  2153. // History: fengsun 2/26/98 Created Header
  2154. // nickball 4/24/98 Added return code
  2155. //
  2156. //+----------------------------------------------------------------------------
  2157. DWORD CGeneralPage::InitDialInfo()
  2158. {
  2159. HCURSOR hPrev = SetCursor(LoadCursorU(NULL,IDC_WAIT));
  2160. //
  2161. // Make sure the dial info is loaded
  2162. //
  2163. DWORD dwRet = LoadDialInfo(m_pArgs, m_hWnd);
  2164. if (dwRet == ERROR_PORT_NOT_AVAILABLE)
  2165. {
  2166. //
  2167. // No modem avaliable, update direct/dial controls if any
  2168. //
  2169. if (m_pArgs->IsBothConnTypeSupported())
  2170. {
  2171. CheckDlgButton(m_hWnd, IDC_RADIO_DIALUP, BST_UNCHECKED);
  2172. CheckDlgButton(m_hWnd, IDC_RADIO_DIRECT, BST_CHECKED);
  2173. SetFocus(GetDlgItem(m_hWnd, IDC_RADIO_DIRECT));
  2174. }
  2175. else
  2176. {
  2177. //
  2178. // Make sure user can exit using keyboard by explicitly
  2179. // setting cancel button as default and giving it focus.
  2180. //
  2181. HWND hwndParent = GetParent(m_hWnd);
  2182. MYDBGASSERT(hwndParent);
  2183. if (hwndParent)
  2184. {
  2185. SendMessageU(hwndParent, DM_SETDEFID, (WPARAM)IDCANCEL, 0);
  2186. SetFocus(GetDlgItem(hwndParent, IDCANCEL));
  2187. }
  2188. }
  2189. //
  2190. // Disable everything dial-up
  2191. //
  2192. EnableDialupControls(FALSE);
  2193. SetCursor(hPrev);
  2194. return dwRet;
  2195. }
  2196. lstrcpynU(m_szDeviceName, m_pArgs->szDeviceName, CELEMS(m_szDeviceName));
  2197. //
  2198. // Init the tmp phone array, it'll possibly be modified
  2199. //
  2200. m_DialInfo[0] = m_pArgs->aDialInfo[0];
  2201. m_DialInfo[1] = m_pArgs->aDialInfo[1];
  2202. EnableDialupControls(TRUE);
  2203. //
  2204. // Check TAPI before translating address
  2205. //
  2206. CheckTapi(&m_pArgs->tlsTapiLink, g_hInst);
  2207. //
  2208. // Set limit for phone # length. Use OS to determine intial default, but
  2209. // allow admin override.
  2210. //
  2211. UINT i = (OS_NT ? MAX_PHONE_LENNT : MAX_PHONE_LEN95);
  2212. i = (int) m_pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryMaxPhoneNumber, i);
  2213. //
  2214. // Even override is limited, in this case by our storage at RAS_MaxPhoneNumber
  2215. //
  2216. i = __min(i, RAS_MaxPhoneNumber);
  2217. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_PRIMARY_EDIT, EM_SETLIMITTEXT, i, 0);
  2218. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_BACKUP_EDIT, EM_SETLIMITTEXT, i, 0);
  2219. //
  2220. // display the munged phone #'s
  2221. //
  2222. for (i = 0; i < m_NumPhones; i++)
  2223. {
  2224. DisplayMungedPhone(i);
  2225. int iCtrl = (i? IDC_GENERAL_UDR2_CHECKBOX : IDC_GENERAL_UDR1_CHECKBOX);
  2226. //
  2227. // Set "Use Dialing Rules". If there is a canonical value then honor
  2228. // the USE_DIALING_RULES flag. Otherwise, its a hand edited number,
  2229. // so we disable the check for dialing rules. Note: this logic is also
  2230. // used in EnableDialupControls().
  2231. //
  2232. if (!m_DialInfo[i].szCanonical[0])
  2233. {
  2234. EnableWindow(GetDlgItem(m_hWnd, iCtrl), FALSE);
  2235. }
  2236. else
  2237. {
  2238. CheckDlgButton(m_hWnd,
  2239. iCtrl,
  2240. (m_DialInfo[i].dwPhoneInfoFlags & PIF_USE_DIALING_RULES));
  2241. }
  2242. }
  2243. //
  2244. // Set TAPI button display according to dialing rules use.
  2245. //
  2246. UpdateDialingRulesButton();
  2247. //
  2248. // Standard dial: If we have no phone books, disable the buttons
  2249. //
  2250. if (!m_pArgs->fHasValidTopLevelPBK && !m_pArgs->fHasValidReferencedPBKs)
  2251. {
  2252. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_PRIMARYPB_BUTTON), FALSE);
  2253. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_BACKUPPB_BUTTON), FALSE);
  2254. }
  2255. DWORD dwCnt;
  2256. DWORD dwIdx;
  2257. if (!m_bDialInfoInit)
  2258. {
  2259. // Initialize the modem combo box only once. This does not use any of the
  2260. // access point info.
  2261. //
  2262. //
  2263. // Init the modem combo box. ISDN devices are a special case because they
  2264. // have two channels and thus usually enumerate each channel as a device.
  2265. // The old style handling was to only show the first ISDN device on the machine.
  2266. // This worked but won't allow a user to use a second ISDN device with CM should
  2267. // they have one. We will keep the old behavior on legacy platforms but on NT5
  2268. // we will try to do the right thing and only not enumerate a second device if
  2269. // we already have one of those in the list. This will filter out second channels
  2270. // and will give the user access to another ISDN device as long as it isn't of the same
  2271. // name as the first. Definitely not a great solution but this close to ship it is the
  2272. // best we can do. Note that for ISDN devices we want to only show
  2273. // one device even though RAS may enumerate two (one for each channe
  2274. //
  2275. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_MODEM_COMBO, CB_RESETCONTENT, 0, 0L);
  2276. LPRASDEVINFO prdiRasDevInfo;
  2277. if (GetRasModems(&m_pArgs->rlsRasLink, &prdiRasDevInfo, &dwCnt))
  2278. {
  2279. //
  2280. // add modem list to modem-combo
  2281. //
  2282. for (dwIdx=0; dwIdx < dwCnt; dwIdx++)
  2283. {
  2284. //
  2285. // filter out tunnel device, IRDA, and Parallel ports.
  2286. //
  2287. if (!lstrcmpiU(prdiRasDevInfo[dwIdx].szDeviceType, RASDT_Modem) || // a modem
  2288. !lstrcmpiU(prdiRasDevInfo[dwIdx].szDeviceType, RASDT_Atm) || // an ATM device
  2289. IsUniqueIsdnDevice(m_hWnd, IDC_GENERAL_MODEM_COMBO, &prdiRasDevInfo[dwIdx])) // an ISDN modem, note we
  2290. // filter out the channels
  2291. // and show only one device
  2292. {
  2293. //
  2294. // Add the device to the Device Combo Box
  2295. //
  2296. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_MODEM_COMBO, CB_ADDSTRING,
  2297. 0, (LPARAM)prdiRasDevInfo[dwIdx].szDeviceName);
  2298. }
  2299. }
  2300. }
  2301. CmFree(prdiRasDevInfo);
  2302. }
  2303. dwCnt = (DWORD)SendDlgItemMessageU(m_hWnd, IDC_GENERAL_MODEM_COMBO, CB_GETCOUNT, 0, 0);
  2304. if (dwCnt == 0)
  2305. {
  2306. dwIdx = (DWORD)CB_ERR;
  2307. }
  2308. else if (dwCnt == 1)
  2309. {
  2310. dwIdx = 0;
  2311. }
  2312. else
  2313. {
  2314. dwIdx = (DWORD)SendDlgItemMessageU(m_hWnd,
  2315. IDC_GENERAL_MODEM_COMBO,
  2316. CB_FINDSTRINGEXACT,
  2317. 0,
  2318. (LPARAM)m_szDeviceName);
  2319. }
  2320. if (dwIdx != CB_ERR)
  2321. {
  2322. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_MODEM_COMBO, CB_SETCURSEL, (WPARAM)dwIdx, 0L);
  2323. //
  2324. // Reset the tmp modem var
  2325. //
  2326. GetDlgItemTextU(m_hWnd, IDC_GENERAL_MODEM_COMBO, m_szDeviceName, RAS_MaxDeviceName+1);
  2327. //
  2328. // GetDeviceType will fill the szDeviceType according to szDeviceName
  2329. //
  2330. if (!GetDeviceType(m_pArgs, m_szDeviceType, CELEMS(m_szDeviceType), m_szDeviceName))
  2331. {
  2332. //
  2333. // if GetDeviceType() failed, something's wrong. just use the devicetype
  2334. // that we've been using.
  2335. //
  2336. lstrcpynU(m_szDeviceType, m_pArgs->szDeviceType, CELEMS(m_szDeviceType));
  2337. }
  2338. }
  2339. //
  2340. // Disable DialingProperties button if no modem selected
  2341. //
  2342. if (IsWindowEnabled(GetDlgItem(m_hWnd, IDC_GENERAL_TAPI_BUTTON)))
  2343. {
  2344. EnableWindow(GetDlgItem(m_hWnd, IDC_GENERAL_TAPI_BUTTON), m_szDeviceName[0] != 0);
  2345. }
  2346. m_bDialInfoInit = TRUE;
  2347. SetCursor(hPrev);
  2348. return dwRet;
  2349. }
  2350. //+----------------------------------------------------------------------------
  2351. //
  2352. // Function: CGeneralPage::OnCommand
  2353. //
  2354. // Synopsis: Virtual function. Called upon WM_COMMAND
  2355. //
  2356. // Arguments: WPARAM - wParam of the message
  2357. // LPARAM - lParam of the message
  2358. //
  2359. // Returns: DWORD - return value of the message
  2360. //
  2361. // History: fengsun Created Header 2/26/98
  2362. //
  2363. //+----------------------------------------------------------------------------
  2364. DWORD CGeneralPage::OnCommand(WPARAM wParam, LPARAM)
  2365. {
  2366. //
  2367. // Hide any open balloon tips
  2368. //
  2369. if (m_pArgs->pBalloonTip)
  2370. {
  2371. m_pArgs->pBalloonTip->HideBalloonTip();
  2372. }
  2373. switch (LOWORD(wParam))
  2374. {
  2375. case IDC_GENERAL_UDR1_CHECKBOX:
  2376. case IDC_GENERAL_UDR2_CHECKBOX:
  2377. {
  2378. int i = (LOWORD(wParam) == IDC_GENERAL_UDR1_CHECKBOX? 0 : 1);
  2379. if (IsDlgButtonChecked(m_hWnd, LOWORD(wParam)))
  2380. {
  2381. int iEditID = i ? IDC_GENERAL_BACKUP_EDIT : IDC_GENERAL_PRIMARY_EDIT;
  2382. m_DialInfo[i].dwPhoneInfoFlags |= PIF_USE_DIALING_RULES;
  2383. }
  2384. else
  2385. {
  2386. m_DialInfo[i].dwPhoneInfoFlags &= ~PIF_USE_DIALING_RULES;
  2387. }
  2388. //
  2389. // If neither dialing rule is on, disable button.
  2390. //
  2391. UpdateDialingRulesButton();
  2392. DisplayMungedPhone(i);
  2393. m_bAPInfoChanged = TRUE;
  2394. return TRUE;
  2395. }
  2396. case IDC_GENERAL_PRIMARYPB_BUTTON:
  2397. case IDC_GENERAL_BACKUPPB_BUTTON:
  2398. OnPhoneBookButton(LOWORD(wParam) == IDC_GENERAL_PRIMARYPB_BUTTON ? 0 : 1);
  2399. return (TRUE);
  2400. case IDC_GENERAL_TAPI_BUTTON:
  2401. OnDialingProperties();
  2402. return (TRUE);
  2403. case IDC_RADIO_DIRECT:
  2404. MYDBGASSERT(m_pArgs->IsBothConnTypeSupported());
  2405. m_bAPInfoChanged = TRUE;
  2406. if (BN_CLICKED == HIWORD(wParam)) // notification code
  2407. {
  2408. EnableDialupControls(FALSE);
  2409. }
  2410. return TRUE;
  2411. case IDC_RADIO_DIALUP:
  2412. MYDBGASSERT(m_pArgs->IsBothConnTypeSupported());
  2413. m_bAPInfoChanged = TRUE;
  2414. if (BN_CLICKED == HIWORD(wParam)) // notification code
  2415. {
  2416. //
  2417. // NT #356821 - nickball
  2418. //
  2419. // Make sure we don't respond until the click is fully
  2420. // registered as we only want to respond once and in
  2421. // the case of keyboard navigation a BN_CLICKED
  2422. // notification is sent before the button takes the
  2423. // click and afterwards. Mouse navigation causes
  2424. // one notification once the button already has the
  2425. // click. Responding to both clicks get us into a nasty
  2426. // little re-entrancy in IntiDialInfo, so we filter out
  2427. // the first notification
  2428. //
  2429. if (IsDlgButtonChecked(m_hWnd, IDC_RADIO_DIALUP))
  2430. {
  2431. //
  2432. // Load dialing information, and enable dial-up controls
  2433. //
  2434. if (ERROR_PORT_NOT_AVAILABLE != InitDialInfo())
  2435. {
  2436. EnableDialupControls(TRUE);
  2437. SetFocus(GetDlgItem(m_hWnd, IDC_GENERAL_PRIMARY_EDIT));
  2438. }
  2439. }
  2440. }
  2441. return TRUE;
  2442. case IDC_GENERAL_DELETEAP_BUTTON:
  2443. {
  2444. if (m_pArgs->pszCurrentAccessPoint)
  2445. {
  2446. LPTSTR pszMsg = CmFmtMsg(g_hInst, IDMSG_DELETE_ACCESSPOINT, m_pArgs->pszCurrentAccessPoint);
  2447. if (pszMsg)
  2448. {
  2449. if (IDYES == MessageBox(m_hWnd,
  2450. pszMsg,
  2451. m_pArgs->szServiceName,
  2452. MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_APPLMODAL))
  2453. {
  2454. this->DeleteAccessPoint();
  2455. }
  2456. }
  2457. CmFree(pszMsg);
  2458. }
  2459. return TRUE;
  2460. }
  2461. case IDC_GENERAL_NEWAP_BUTTON:
  2462. {
  2463. //
  2464. // We need to allow for the case where the user has made a change
  2465. // to a phone number and has now decided to save this to a *new*
  2466. // Access Point (AP). The dialog below asks the user if he/she wants
  2467. // to save the current changes to the "old" AP (i.e. the AP we're
  2468. // just leaving). If the user says No, this means they want to
  2469. // use these settings for the new AP (the one we're about to ask
  2470. // them to name). For this case, we apply all the current phone
  2471. // number information to the new AP, i.e we _don't_ clear out the
  2472. // old phone number settings. See NT bug 301054 for more.
  2473. //
  2474. BOOL bClearOldPhoneNumberSettings = TRUE;
  2475. BOOL bRes = AccessPointInfoChanged();
  2476. if (bRes && m_pArgs->pszCurrentAccessPoint)
  2477. {
  2478. LPTSTR pszMsg = CmFmtMsg(g_hInst, IDMSG_SAVE_ACCESSPOINT, m_pArgs->pszCurrentAccessPoint);
  2479. if (pszMsg)
  2480. {
  2481. int iRet = MessageBox(m_hWnd,
  2482. pszMsg,
  2483. m_pArgs->szServiceName,
  2484. MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON1 | MB_APPLMODAL);
  2485. if (IDYES == iRet)
  2486. {
  2487. OnApply();
  2488. }
  2489. else if (IDNO == iRet)
  2490. {
  2491. bClearOldPhoneNumberSettings = FALSE;
  2492. }
  2493. else
  2494. {
  2495. MYDBGASSERT(0);
  2496. }
  2497. }
  2498. CmFree(pszMsg);
  2499. }
  2500. LPTSTR pszAPName = NULL;
  2501. CNewAccessPointDlg NewAccessPointDlg(m_pArgs, &pszAPName);
  2502. if (IDOK == NewAccessPointDlg.DoDialogBox(g_hInst, IDD_NEW_ACCESSPOINT, m_hWnd))
  2503. {
  2504. MYDBGASSERT(pszAPName);
  2505. AddNewAPToReg(pszAPName, bClearOldPhoneNumberSettings);
  2506. if (FALSE == bClearOldPhoneNumberSettings)
  2507. {
  2508. //
  2509. // Since we didn't clear the phone number settings, we've
  2510. // left them in place as initial values for the new AP. We
  2511. // need to mark the new AP as 'dirty' so that when the current
  2512. // AP changes, the UI will ask the user to save changes.
  2513. // (there's no significance attached to choosing IDC_GENERAL_PRIMARY_EDIT, I
  2514. // could just as well have used the other edit control.)
  2515. //
  2516. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_PRIMARY_EDIT, EM_SETMODIFY, TRUE, 0);
  2517. }
  2518. }
  2519. CmFree(pszAPName);
  2520. return TRUE;
  2521. }
  2522. default:
  2523. break;
  2524. }
  2525. switch (HIWORD(wParam))
  2526. {
  2527. case CBN_SELENDOK:
  2528. if (IDC_GENERAL_MODEM_COMBO == LOWORD(wParam))
  2529. {
  2530. TCHAR szModem[RAS_MaxDeviceName+1];
  2531. TCHAR szDeviceType[RAS_MaxDeviceType+1];
  2532. MYDBGASSERT(IDC_GENERAL_MODEM_COMBO == LOWORD(wParam));
  2533. GetWindowTextU(GetDlgItem(m_hWnd, IDC_GENERAL_MODEM_COMBO),
  2534. szModem, RAS_MaxDeviceName+1);
  2535. if (lstrcmpU(m_szDeviceName, szModem) == 0)
  2536. {
  2537. // there's no change in the modem
  2538. return FALSE;
  2539. }
  2540. m_bAPInfoChanged = TRUE;
  2541. //
  2542. // If GetDeviceType fails we won't in fact change the
  2543. // modem even though the user thinks that we did.
  2544. // Logic could possibly be added to notify the user
  2545. // and refresh the device list, but this is a fair
  2546. // amount of work for little gain.
  2547. //
  2548. if (GetDeviceType(m_pArgs, szDeviceType, CELEMS(szDeviceType), szModem))
  2549. {
  2550. lstrcpyU(m_szDeviceName, szModem);
  2551. lstrcpyU(m_szDeviceType, szDeviceType);
  2552. //
  2553. // CheckTapi will check (m_szDeviceName)
  2554. //
  2555. CheckTapi(&m_pArgs->tlsTapiLink, g_hInst);
  2556. }
  2557. }
  2558. else
  2559. {
  2560. //
  2561. // The selection in the Access Point combo box
  2562. // has changed. Now we have to load the dialing information for
  2563. // the newly selected Access Point
  2564. //
  2565. MYDBGASSERT(IDC_GENERAL_ACCESSPOINT_COMBO == LOWORD(wParam));
  2566. BOOL bRes = AccessPointInfoChanged();
  2567. if (bRes && m_pArgs->pszCurrentAccessPoint)
  2568. {
  2569. //
  2570. // If the dialing info. for the previous Access Point has changed, ask the
  2571. // user if he wants to save the changes
  2572. //
  2573. LPTSTR pszMsg = CmFmtMsg(g_hInst, IDMSG_SAVE_ACCESSPOINT, m_pArgs->pszCurrentAccessPoint);
  2574. if (pszMsg)
  2575. {
  2576. if (IDYES == MessageBox(m_hWnd,
  2577. pszMsg,
  2578. m_pArgs->szServiceName,
  2579. MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON1 | MB_APPLMODAL))
  2580. {
  2581. OnApply();
  2582. }
  2583. }
  2584. CmFree(pszMsg);
  2585. }
  2586. //
  2587. // Now call the function to change the Access Point in the combo box
  2588. // and load its parameters into pArgs
  2589. //
  2590. if (ChangedAccessPoint(m_pArgs, m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO))
  2591. {
  2592. //
  2593. // Load new dialing info. into controls on the general page
  2594. //
  2595. this->UpdateForNewAccessPoint(TRUE);
  2596. }
  2597. }
  2598. break;
  2599. default:
  2600. break;
  2601. }
  2602. return 0;
  2603. }
  2604. //+---------------------------------------------------------------------------
  2605. //
  2606. // Function: CheckAccessToCmpAndRasPbk
  2607. //
  2608. // Synopsis: Check to see if the user has the necessary security permissions
  2609. // to make changes to properties. Notifies user if they do not.
  2610. //
  2611. // Arguments: HWND hwndDlg - The hwnd of the calling app.
  2612. // ArgsStruct *pArgs - Ptr to our global args struct.
  2613. //
  2614. // Returns: HRESULT - indicating the particular success or failure.
  2615. //
  2616. // History: nickball 03/14/00 Created header
  2617. //
  2618. //----------------------------------------------------------------------------
  2619. HRESULT CheckAccessToCmpAndRasPbk(HWND hwndDlg, ArgsStruct *pArgs)
  2620. {
  2621. MYDBGASSERT(pArgs); // hwndDlg can be NULL
  2622. if (NULL == pArgs)
  2623. {
  2624. return E_INVALIDARG;
  2625. }
  2626. //
  2627. // Check the cmp, note this could be locked with NTFS perms or just with
  2628. // attrib. HasSpecifiedAccessToFileOrDir should catch both as appropriate.
  2629. //
  2630. LPTSTR pszCmp = CmStrCpyAlloc(pArgs->piniProfile->GetFile());
  2631. LPTSTR pszHiddenRasPbk = NULL;
  2632. LPTSTR pszRasPbk = NULL;
  2633. DWORD dwDesiredAccess = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
  2634. BOOL bHasMainRasPbkAccess = FALSE;
  2635. BOOL bHasHiddenRasPbkAccess = FALSE;
  2636. if (pszCmp && pszCmp[0])
  2637. {
  2638. //
  2639. // Now check the RAS phonebook
  2640. //
  2641. if (OS_W9X)
  2642. {
  2643. //
  2644. // No phonebook on 9x so skip this check
  2645. //
  2646. bHasMainRasPbkAccess = TRUE;
  2647. bHasHiddenRasPbkAccess = TRUE;
  2648. }
  2649. else
  2650. {
  2651. pszRasPbk = GetPathToPbk((LPCTSTR)pszCmp, pArgs);
  2652. MYDBGASSERT(pszRasPbk);
  2653. CmStrCatAlloc(&pszRasPbk, c_pszRasPhonePbk);
  2654. MYDBGASSERT(pszRasPbk);
  2655. if (pszRasPbk && pszRasPbk[0])
  2656. {
  2657. bHasMainRasPbkAccess = HasSpecifiedAccessToFileOrDir(pszRasPbk, dwDesiredAccess);
  2658. if ((FALSE == bHasMainRasPbkAccess) && (FALSE == FileExists(pszRasPbk)))
  2659. {
  2660. //
  2661. // if the file doesn't exist, give them the
  2662. // benefit of the doubt. We won't get very far if
  2663. // the file doesn't exist and they don't have permissions
  2664. // to create it.
  2665. //
  2666. bHasMainRasPbkAccess = TRUE;
  2667. }
  2668. }
  2669. //
  2670. // Now check the hidden RAS phonebook
  2671. //
  2672. if (DOUBLE_DIAL_CONNECTION == pArgs->GetTypeOfConnection())
  2673. {
  2674. pszHiddenRasPbk = CreateRasPrivatePbk(pArgs);
  2675. if (pszHiddenRasPbk && HasSpecifiedAccessToFileOrDir(pszHiddenRasPbk, dwDesiredAccess))
  2676. {
  2677. bHasHiddenRasPbkAccess = TRUE;
  2678. }
  2679. }
  2680. else
  2681. {
  2682. bHasHiddenRasPbkAccess = TRUE;
  2683. }
  2684. }
  2685. }
  2686. //
  2687. // Only set hr to success if we have access to both
  2688. //
  2689. HRESULT hr;
  2690. if (bHasMainRasPbkAccess && bHasHiddenRasPbkAccess)
  2691. {
  2692. hr = S_OK;
  2693. }
  2694. else
  2695. {
  2696. hr = E_ACCESSDENIED;
  2697. LPTSTR pszProblemFile = NULL;
  2698. if (!bHasMainRasPbkAccess)
  2699. {
  2700. pszProblemFile = pszRasPbk;
  2701. }
  2702. else if (!bHasHiddenRasPbkAccess)
  2703. {
  2704. pszProblemFile = pszHiddenRasPbk;
  2705. }
  2706. if (NULL != pszProblemFile)
  2707. {
  2708. LPTSTR pszMsg = CmFmtMsg(g_hInst, IDMSG_NO_CMP_PBK_ACCESS, pszProblemFile);
  2709. if (pszMsg)
  2710. {
  2711. MessageBox(hwndDlg, pszMsg, pArgs->szServiceName, MB_OK | MB_ICONERROR);
  2712. CmFree(pszMsg);
  2713. }
  2714. }
  2715. }
  2716. //
  2717. // Cleanup
  2718. //
  2719. CmFree(pszCmp);
  2720. CmFree(pszRasPbk);
  2721. CmFree(pszHiddenRasPbk);
  2722. return hr;
  2723. }
  2724. //+---------------------------------------------------------------------------
  2725. //
  2726. // Function: CGeneralPage::OnApply()
  2727. //
  2728. // Synopsis: Save the data associated with the 'Dialing' property sheet.
  2729. // when the user clicks OK.
  2730. //
  2731. // Returns: NONE
  2732. //
  2733. // History: henryt Created 4/30/97
  2734. // byao Modified 5/23/97
  2735. // Always update modem when user selected OK from
  2736. // 'Properties' button
  2737. //----------------------------------------------------------------------------
  2738. void CGeneralPage::OnApply()
  2739. {
  2740. BOOL fDirect = IsDlgButtonChecked(m_hWnd, IDC_RADIO_DIRECT);
  2741. LPTSTR pszTmp = NULL;
  2742. //
  2743. // If access points are enabled save the current access point to the registry
  2744. //
  2745. if (m_pArgs->fAccessPointsEnabled)
  2746. {
  2747. WriteUserInfoToReg(m_pArgs, UD_ID_CURRENTACCESSPOINT, (PVOID)(m_pArgs->pszCurrentAccessPoint));
  2748. }
  2749. if (!fDirect)
  2750. {
  2751. //
  2752. // Before we go anywhere, make sure that the device is acceptable
  2753. // otherwise, we won't be able to munge the phone number
  2754. //
  2755. if (!SetTapiDevice(g_hInst, &m_pArgs->tlsTapiLink, m_szDeviceName))
  2756. {
  2757. pszTmp = CmFmtMsg(g_hInst, IDMSG_UNSUPPORTED_DEVICE);
  2758. MessageBoxEx(m_hWnd, pszTmp, m_pArgs->szServiceName,
  2759. MB_OK | MB_ICONINFORMATION, LANG_USER_DEFAULT);
  2760. CmFree(pszTmp);
  2761. SetPropSheetResult(PSNRET_INVALID_NOCHANGEPAGE);
  2762. return;
  2763. }
  2764. //
  2765. // Device is ok, see if TAPI is properly intialized.
  2766. // Don't proceed unless it is.
  2767. //
  2768. if (!CheckTapi(&m_pArgs->tlsTapiLink, g_hInst))
  2769. {
  2770. SetPropSheetResult(PSNRET_INVALID_NOCHANGEPAGE);
  2771. return;
  2772. }
  2773. }
  2774. //
  2775. // Save connection type information
  2776. //
  2777. m_pArgs->SetDirectConnect(fDirect);
  2778. m_pArgs->piniProfile->WPPI(c_pszCmSection, c_pszCmEntryConnectionType, fDirect);
  2779. //
  2780. // If dial-up data was not initialized, there
  2781. // is no need to update phone number info.
  2782. //
  2783. if (m_bDialInfoInit)
  2784. {
  2785. //
  2786. // Store the current TAPI location
  2787. //
  2788. DWORD dwCurrentTapiLoc = GetCurrentTapiLocation(&m_pArgs->tlsTapiLink);
  2789. if (-1 != dwCurrentTapiLoc)
  2790. {
  2791. m_pArgs->tlsTapiLink.dwTapiLocationForAccessPoint = dwCurrentTapiLoc;
  2792. m_pArgs->piniProfile->WPPI(c_pszCmSection, c_pszCmEntryTapiLocation, dwCurrentTapiLoc);
  2793. }
  2794. //
  2795. // Update device name and type
  2796. //
  2797. lstrcpynU(m_pArgs->szDeviceName, m_szDeviceName, CELEMS(m_pArgs->szDeviceName));
  2798. lstrcpynU(m_pArgs->szDeviceType, m_szDeviceType, CELEMS(m_pArgs->szDeviceType));
  2799. //
  2800. // Update the CMP
  2801. //
  2802. m_pArgs->piniProfile->WPPS(c_pszCmSection,
  2803. c_pszCmEntryDialDevice,
  2804. m_pArgs->szDeviceName);
  2805. //
  2806. // Check each number to see if we need to update CMP or connectoids
  2807. //
  2808. for (UINT i = 0; i < m_NumPhones; i++)
  2809. {
  2810. int iEditID = i ? IDC_GENERAL_BACKUP_EDIT : IDC_GENERAL_PRIMARY_EDIT;
  2811. //
  2812. // If Dialing Rules aren't used, it is likely that the user has
  2813. // modified the phone number, get number and munge it. In the
  2814. // case of fNoDialingRules we skip this test to be certain that
  2815. // we pick up any user changes.
  2816. //
  2817. if (!(m_DialInfo[i].dwPhoneInfoFlags & PIF_USE_DIALING_RULES))
  2818. {
  2819. pszTmp = CmGetWindowTextAlloc(m_hWnd, iEditID);
  2820. if (*pszTmp)
  2821. {
  2822. //
  2823. // Ensure that phone number doesn't exceed storage size
  2824. // Note: On W2K the edit limits prevent pasting an excess
  2825. // amount of data, but we truncate to be positive across
  2826. // all versions of Windows.
  2827. //
  2828. if (lstrlenU(pszTmp) > RAS_MaxPhoneNumber)
  2829. {
  2830. pszTmp[RAS_MaxPhoneNumber] = TEXT('\0');
  2831. }
  2832. //
  2833. // If we're ignoring dialing rules, just get our data directly
  2834. //
  2835. if (m_pArgs->fNoDialingRules)
  2836. {
  2837. lstrcpynU(m_DialInfo[i].szPhoneNumber, pszTmp, CELEMS(m_DialInfo[i].szPhoneNumber));
  2838. lstrcpynU(m_DialInfo[i].szDisplayablePhoneNumber, pszTmp, CELEMS(m_DialInfo[i].szDisplayablePhoneNumber));
  2839. lstrcpynU(m_DialInfo[i].szDialablePhoneNumber, pszTmp, CELEMS(m_DialInfo[i].szDialablePhoneNumber));
  2840. m_DialInfo[i].szCanonical[0] = TEXT('\0');
  2841. }
  2842. else
  2843. {
  2844. LPTSTR pszPhone = CmStrCpyAlloc(pszTmp);
  2845. LPTSTR pszDialable = NULL;
  2846. MYDBGASSERT(m_szDeviceName[0]);
  2847. //
  2848. // Munge the number to ensure that we have the correct dialable
  2849. //
  2850. if (ERROR_SUCCESS != MungePhone(m_szDeviceName,
  2851. &pszPhone,
  2852. &m_pArgs->tlsTapiLink,
  2853. g_hInst,
  2854. m_DialInfo[i].dwPhoneInfoFlags & PIF_USE_DIALING_RULES,
  2855. &pszDialable,
  2856. m_pArgs->fAccessPointsEnabled))
  2857. {
  2858. CmFree(pszTmp);
  2859. //
  2860. // Can't format the number, notify user of the problem
  2861. //
  2862. pszTmp = CmFmtMsg(g_hInst, IDMSG_CANTFORMAT);
  2863. MessageBoxEx(m_hWnd, pszTmp, m_pArgs->szServiceName,
  2864. MB_OK | MB_ICONINFORMATION, LANG_USER_DEFAULT);
  2865. CmFree(pszTmp);
  2866. CmFree(pszPhone);
  2867. SetPropSheetResult(PSNRET_INVALID_NOCHANGEPAGE);
  2868. return;
  2869. }
  2870. //
  2871. // Update buffers
  2872. //
  2873. if (pszDialable)
  2874. {
  2875. lstrcpynU(m_DialInfo[i].szDialablePhoneNumber, pszDialable, CELEMS(m_DialInfo[i].szDialablePhoneNumber));
  2876. }
  2877. if (pszPhone)
  2878. {
  2879. lstrcpynU(m_DialInfo[i].szDisplayablePhoneNumber, pszPhone, CELEMS(m_DialInfo[i].szDisplayablePhoneNumber));
  2880. }
  2881. //
  2882. // If we find a plus in the first char, assume that the user is
  2883. // attempting canonical format by hand and treat as a dialing
  2884. // rules number. Either way, update the szPhoneNumber buffer.
  2885. //
  2886. if (pszTmp == CmStrchr(pszTmp, TEXT('+')))
  2887. {
  2888. //
  2889. // Its hand-edited canonical. Store the canonical
  2890. // form in szCanonical, then strip the canonical
  2891. // formatting before we store the number normally
  2892. //
  2893. m_DialInfo[i].dwPhoneInfoFlags |= PIF_USE_DIALING_RULES;
  2894. lstrcpynU(m_DialInfo[i].szCanonical, pszTmp, CELEMS(m_DialInfo[i].szCanonical));
  2895. StripCanonical(pszTmp);
  2896. }
  2897. else
  2898. {
  2899. //
  2900. // If UDR check is disabled, then its a hand edited number,
  2901. // so remove canonical form of the number - as an indicator.
  2902. //
  2903. if (!IsWindowEnabled(GetDlgItem(m_hWnd, i ?
  2904. IDC_GENERAL_UDR2_CHECKBOX :
  2905. IDC_GENERAL_UDR1_CHECKBOX)))
  2906. {
  2907. m_DialInfo[i].szCanonical[0] = TEXT('\0');
  2908. }
  2909. }
  2910. lstrcpynU(m_DialInfo[i].szPhoneNumber, pszTmp, CELEMS(m_DialInfo[i].szPhoneNumber));
  2911. CmFree(pszDialable);
  2912. CmFree(pszPhone);
  2913. }
  2914. }
  2915. else
  2916. {
  2917. //
  2918. // No number, clear everything
  2919. //
  2920. ZeroMemory(&m_DialInfo[i], sizeof(PHONEINFO));
  2921. }
  2922. CmFree(pszTmp);
  2923. }
  2924. //
  2925. // Copy the new phone #'s back to our global struct
  2926. //
  2927. lstrcpynU(m_pArgs->aDialInfo[i].szPhoneBookFile,
  2928. m_DialInfo[i].szPhoneBookFile, CELEMS(m_pArgs->aDialInfo[i].szPhoneBookFile));
  2929. lstrcpynU(m_pArgs->aDialInfo[i].szDUN,
  2930. m_DialInfo[i].szDUN, CELEMS(m_pArgs->aDialInfo[i].szDUN));
  2931. lstrcpynU(m_pArgs->aDialInfo[i].szPhoneNumber,
  2932. m_DialInfo[i].szPhoneNumber, CELEMS(m_pArgs->aDialInfo[i].szPhoneNumber));
  2933. //
  2934. // Always store canonical as canonical
  2935. //
  2936. lstrcpynU(m_pArgs->aDialInfo[i].szCanonical,
  2937. m_DialInfo[i].szCanonical, CELEMS(m_pArgs->aDialInfo[i].szCanonical));
  2938. lstrcpynU(m_pArgs->aDialInfo[i].szDialablePhoneNumber,
  2939. m_DialInfo[i].szDialablePhoneNumber, CELEMS(m_pArgs->aDialInfo[i].szDialablePhoneNumber));
  2940. lstrcpynU(m_pArgs->aDialInfo[i].szDisplayablePhoneNumber,
  2941. m_DialInfo[i].szDisplayablePhoneNumber, CELEMS(m_pArgs->aDialInfo[i].szDisplayablePhoneNumber));
  2942. lstrcpynU(m_pArgs->aDialInfo[i].szDesc, m_DialInfo[i].szDesc, CELEMS(m_pArgs->aDialInfo[i].szDesc));
  2943. m_pArgs->aDialInfo[i].dwCountryID = m_DialInfo[i].dwCountryID;
  2944. lstrcpynU(m_pArgs->aDialInfo[i].szServiceType,
  2945. m_DialInfo[i].szServiceType, CELEMS(m_pArgs->aDialInfo[i].szServiceType));
  2946. lstrcpynU(m_pArgs->aDialInfo[i].szRegionName,
  2947. m_DialInfo[i].szRegionName, CELEMS(m_pArgs->aDialInfo[i].szRegionName));
  2948. m_pArgs->aDialInfo[i].dwPhoneInfoFlags = m_DialInfo[i].dwPhoneInfoFlags;
  2949. //
  2950. // Write them out to cmp
  2951. //
  2952. PutPhoneByIdx(m_pArgs,
  2953. i,
  2954. m_pArgs->aDialInfo[i].szPhoneNumber,
  2955. m_pArgs->aDialInfo[i].szDesc,
  2956. m_pArgs->aDialInfo[i].szDUN,
  2957. m_pArgs->aDialInfo[i].dwCountryID,
  2958. m_pArgs->aDialInfo[i].szRegionName,
  2959. m_pArgs->aDialInfo[i].szServiceType,
  2960. m_pArgs->aDialInfo[i].szPhoneBookFile,
  2961. m_pArgs->aDialInfo[i].szCanonical,
  2962. m_pArgs->aDialInfo[i].dwPhoneInfoFlags);
  2963. } // for {}
  2964. }
  2965. //
  2966. // Update fUseTunneling by examining first phonenumber.
  2967. //
  2968. if (fDirect)
  2969. {
  2970. m_pArgs->fUseTunneling = TRUE;
  2971. }
  2972. else
  2973. {
  2974. m_pArgs->fUseTunneling = UseTunneling(m_pArgs, 0);
  2975. }
  2976. if (FAILED(CheckAccessToCmpAndRasPbk(m_hWnd, m_pArgs)))
  2977. {
  2978. SetPropSheetResult(PSNRET_INVALID_NOCHANGEPAGE);
  2979. return;
  2980. }
  2981. else
  2982. {
  2983. SetPropSheetResult(PSNRET_NOERROR);
  2984. }
  2985. return;
  2986. }
  2987. //+----------------------------------------------------------------------------
  2988. //
  2989. // Function: CGeneralPage::OnKillActive
  2990. //
  2991. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_KILLACTIVE
  2992. // Notifies a page that it is about to lose activation either because
  2993. // another page is being activated or the user has clicked the OK button.
  2994. // Arguments: None
  2995. //
  2996. // Returns: BOOL - return value of the message
  2997. //
  2998. // History: fengsun Created Header 2/26/98
  2999. //
  3000. //+----------------------------------------------------------------------------
  3001. BOOL CGeneralPage::OnKillActive()
  3002. {
  3003. //
  3004. // Notify the event listener for the current connection type selection
  3005. //
  3006. if (m_pEventListener)
  3007. {
  3008. m_pEventListener->OnGeneralPageKillActive(
  3009. IsDlgButtonChecked(m_hWnd, IDC_RADIO_DIRECT));
  3010. }
  3011. //
  3012. // Hide any open balloon tips
  3013. //
  3014. if (m_pArgs->pBalloonTip)
  3015. {
  3016. m_pArgs->pBalloonTip->HideBalloonTip();
  3017. }
  3018. return 0;
  3019. }
  3020. //
  3021. // Help id pairs for the page
  3022. //
  3023. const DWORD CInetPage::m_dwHelp[] = {
  3024. IDC_INET_USERNAME_STATIC, IDH_INTERNET_USER_NAME,
  3025. IDC_INET_USERNAME, IDH_INTERNET_USER_NAME,
  3026. IDC_INET_PASSWORD_STATIC, IDH_INTERNET_PASSWORD,
  3027. IDC_INET_PASSWORD, IDH_INTERNET_PASSWORD,
  3028. IDC_INET_REMEMBER, IDH_INTERNET_SAVEPASS,
  3029. 0,0};
  3030. //+----------------------------------------------------------------------------
  3031. //
  3032. // Function: CInetPage::CInetPage
  3033. //
  3034. // Synopsis: Constructor
  3035. //
  3036. // Arguments: ArgsStruct* pArgs - Information needed for the page
  3037. // UINT nIDTemplate - Resource ID
  3038. //
  3039. // Returns: Nothing
  3040. //
  3041. // History: fengsun Created Header 2/26/98
  3042. //
  3043. //+----------------------------------------------------------------------------
  3044. CInetPage::CInetPage(ArgsStruct* pArgs, UINT nIDTemplate)
  3045. : CPropertiesPage(nIDTemplate, m_dwHelp, pArgs->pszHelpFile)
  3046. {
  3047. MYDBGASSERT(pArgs);
  3048. m_pArgs = pArgs;
  3049. m_fDirect = pArgs->IsDirectConnect();
  3050. }
  3051. //+---------------------------------------------------------------------------
  3052. //
  3053. // Function: OnInetInit
  3054. //
  3055. // Synopsis: Init the 'Internet Sign-In' properties property sheet.
  3056. //
  3057. // Arguments: hwndDlg [dlg window handle]
  3058. // pArgs [the ptr to ArgsStruct]
  3059. //
  3060. // Returns: NONE
  3061. //
  3062. // History: henryt Created 4/30/97
  3063. //
  3064. //----------------------------------------------------------------------------
  3065. void CInetPage::OnInetInit(
  3066. HWND hwndDlg,
  3067. ArgsStruct *pArgs
  3068. )
  3069. {
  3070. //
  3071. // The inet dialog/page is displayed only if fUseSameUserName is FALSE
  3072. //
  3073. MYDBGASSERT( pArgs->fUseSameUserName == FALSE);
  3074. //
  3075. // set the length limit for the edit controls
  3076. //
  3077. UINT i;
  3078. HWND hwndUserName = GetDlgItem(hwndDlg, IDC_INET_USERNAME);
  3079. if (hwndUserName)
  3080. {
  3081. i = (UINT)pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryMaxUserName, UNLEN);
  3082. SendDlgItemMessageU(hwndDlg, IDC_INET_USERNAME, EM_SETLIMITTEXT, __min(UNLEN, i), 0);
  3083. SetDlgItemTextU(hwndDlg, IDC_INET_USERNAME, pArgs->szInetUserName);
  3084. SendMessageU(hwndUserName, EM_SETMODIFY, (WPARAM)FALSE, 0L);
  3085. }
  3086. HWND hwndInetPassword = GetDlgItem(hwndDlg, IDC_INET_PASSWORD);
  3087. if (hwndInetPassword)
  3088. {
  3089. i = (UINT)pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryMaxPassword, PWLEN);
  3090. SendDlgItemMessageU(hwndDlg, IDC_INET_PASSWORD, EM_SETLIMITTEXT, __min(PWLEN, i), 0);
  3091. CmDecodePassword(pArgs->szInetPassword);
  3092. SetDlgItemTextU(hwndDlg, IDC_INET_PASSWORD, pArgs->szInetPassword);
  3093. CmEncodePassword(pArgs->szInetPassword);
  3094. SendMessageU(hwndInetPassword, EM_SETMODIFY, (WPARAM)FALSE, 0L);
  3095. //
  3096. // hide and the "remember password checkbox if needed
  3097. //
  3098. if (pArgs->fHideRememberInetPassword)
  3099. {
  3100. ShowWindow(GetDlgItem(hwndDlg, IDC_INET_REMEMBER), SW_HIDE);
  3101. }
  3102. else
  3103. {
  3104. //
  3105. // Check the button first, then adjust it.
  3106. //
  3107. CheckDlgButton(hwndDlg, IDC_INET_REMEMBER, pArgs->fRememberInetPassword);
  3108. BOOL fPasswordOptional = pArgs->piniService->GPPB(c_pszCmSection,c_pszCmEntryPwdOptional);
  3109. BOOL fEmptyPassword = (pArgs->szInetPassword[0] == TEXT('\0') );
  3110. //
  3111. // Enable/Disable check/uncheck the "Save Password" accordingly
  3112. // fPasswordOptional is always FALSE for the dialog
  3113. //
  3114. AdjustSavePasswordCheckBox(GetDlgItem(hwndDlg, IDC_INET_REMEMBER),
  3115. fEmptyPassword, pArgs->fDialAutomatically, fPasswordOptional);
  3116. }
  3117. }
  3118. }
  3119. //+---------------------------------------------------------------------------
  3120. //
  3121. // Function: OnInetOk
  3122. //
  3123. // Synopsis: Save the data associated with the 'Internet Sign-In' property sheet.
  3124. // when the user clicks OK.
  3125. //
  3126. // Arguments: hwndDlg [dlg window handle]
  3127. // pArgs [the ptr to ArgsStruct]
  3128. //
  3129. // Returns: NONE
  3130. //
  3131. // History: henryt Created 4/30/97
  3132. //
  3133. //----------------------------------------------------------------------------
  3134. void CInetPage::OnInetOk(
  3135. HWND hwndDlg,
  3136. ArgsStruct *pArgs
  3137. )
  3138. {
  3139. LPTSTR pszTmp = NULL;
  3140. //
  3141. // update password
  3142. //
  3143. if (GetDlgItem(hwndDlg, IDC_INET_PASSWORD))
  3144. {
  3145. pszTmp = CmGetWindowTextAlloc(hwndDlg, IDC_INET_PASSWORD);
  3146. if (!pArgs->fHideRememberInetPassword)
  3147. {
  3148. pArgs->fRememberInetPassword = IsDlgButtonChecked(hwndDlg, IDC_INET_REMEMBER);
  3149. SaveUserInfo(pArgs,
  3150. UD_ID_REMEMBER_INET_PASSWORD,
  3151. (PVOID)&pArgs->fRememberInetPassword);
  3152. }
  3153. //
  3154. // If don't remember password, then store an empty string, but keep
  3155. // the existing one in memory. Otherwise, save the user's password.
  3156. //
  3157. if (pArgs->fRememberInetPassword)
  3158. {
  3159. if (OS_NT5)
  3160. {
  3161. //
  3162. // If we are saving user creds, we can leave globals
  3163. //
  3164. if (CM_CREDS_GLOBAL == pArgs->dwCurrentCredentialType)
  3165. {
  3166. //
  3167. // Delete local/user since we are saving global credentials
  3168. //
  3169. DeleteSavedCredentials(pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  3170. pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_INET_USER;
  3171. }
  3172. }
  3173. SaveUserInfo(pArgs, UD_ID_INET_PASSWORD, (PVOID)pszTmp);
  3174. }
  3175. else
  3176. {
  3177. if (OS_NT5)
  3178. {
  3179. if (CM_CREDS_GLOBAL == pArgs->dwCurrentCredentialType)
  3180. {
  3181. //
  3182. // Deleting Internet Globals
  3183. //
  3184. if (CM_EXIST_CREDS_INET_GLOBAL & pArgs->dwExistingCredentials)
  3185. {
  3186. DeleteSavedCredentials(pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_DELETE_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  3187. pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_INET_GLOBAL;
  3188. }
  3189. }
  3190. else
  3191. {
  3192. //
  3193. // Deleting Internet User
  3194. //
  3195. if (CM_EXIST_CREDS_INET_USER & pArgs->dwExistingCredentials)
  3196. {
  3197. DeleteSavedCredentials(pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_KEEP_IDENTITY);
  3198. pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_INET_USER;
  3199. }
  3200. }
  3201. }
  3202. else
  3203. {
  3204. DeleteUserInfo(pArgs, UD_ID_INET_PASSWORD);
  3205. }
  3206. }
  3207. //
  3208. // Update pArgs
  3209. //
  3210. lstrcpyU(pArgs->szInetPassword, pszTmp);
  3211. CmEncodePassword(pArgs->szInetPassword);
  3212. CmWipePassword(pszTmp);
  3213. CmFree(pszTmp);
  3214. pszTmp = NULL;
  3215. }
  3216. DWORD dwCurrentCreds = pArgs->dwCurrentCredentialType;
  3217. //
  3218. // If the user isn't saving his password and the credential
  3219. // store is global, then we need to switch to the user
  3220. // credential store in order to cache the user name for next use
  3221. //
  3222. if ((FALSE == pArgs->fRememberInetPassword) &&
  3223. (CM_CREDS_GLOBAL == pArgs->dwCurrentCredentialType))
  3224. {
  3225. pArgs->dwCurrentCredentialType = CM_CREDS_USER;
  3226. }
  3227. //
  3228. // Get User name
  3229. //
  3230. if (GetDlgItem(hwndDlg, IDC_INET_USERNAME))
  3231. {
  3232. pszTmp = CmGetWindowTextAlloc(hwndDlg, IDC_INET_USERNAME);
  3233. lstrcpyU(pArgs->szInetUserName, pszTmp);
  3234. //
  3235. // update username if we are saving credentials or
  3236. // we are saving to the user/local credential store.
  3237. //
  3238. if ((pArgs->fRememberInetPassword) || (CM_CREDS_USER == pArgs->dwCurrentCredentialType))
  3239. {
  3240. SaveUserInfo(pArgs, UD_ID_INET_USERNAME, (PVOID)pszTmp);
  3241. }
  3242. CmFree(pszTmp);
  3243. pszTmp = NULL;
  3244. }
  3245. //
  3246. // In case the current credential store was changed to user, we now
  3247. // need to switch it back to global.
  3248. //
  3249. pArgs->dwCurrentCredentialType = dwCurrentCreds;
  3250. //
  3251. // Need to refresh to see which creds now exist since we could have saved or deleted some
  3252. //
  3253. BOOL fReturn = RefreshCredentialTypes(pArgs, FALSE);
  3254. CmWipePassword(pszTmp);
  3255. CmFree(pszTmp);
  3256. }
  3257. //+----------------------------------------------------------------------------
  3258. //
  3259. // Function: CInetPage::AdjustSavePasswordCheckBox
  3260. //
  3261. // Synopsis: Enable/Disable, Check/Uncheck the "save Password" check box
  3262. // according to other information
  3263. //
  3264. // Arguments: HWND hwndCheckBox - The window handle of "Save Password" check box
  3265. // BOOL fEmptyPassword - Whether the password edit box is empty
  3266. // BOOL fDialAutomatically - Whether dial automatically is checked
  3267. // BOOL fPasswordOptional - Whether the password is optional
  3268. //
  3269. // Returns: Nothing
  3270. //
  3271. // History: fengsun Created Header 4/24/98
  3272. //
  3273. //+----------------------------------------------------------------------------
  3274. void CInetPage::AdjustSavePasswordCheckBox(HWND hwndCheckBox, BOOL fEmptyPassword,
  3275. BOOL fDialAutomatically, BOOL fPasswordOptional)
  3276. {
  3277. MYDBGASSERT(IsWindow(hwndCheckBox)); // if password hidden, no need to adjust
  3278. //
  3279. // Enable/Disable the check box
  3280. //
  3281. if (fDialAutomatically)
  3282. {
  3283. EnableWindow(hwndCheckBox, FALSE);
  3284. }
  3285. else if (fEmptyPassword && !fPasswordOptional)
  3286. {
  3287. EnableWindow(hwndCheckBox, FALSE);
  3288. }
  3289. else
  3290. {
  3291. EnableWindow(hwndCheckBox, TRUE);
  3292. }
  3293. //
  3294. // Check/Uncheck the check box
  3295. //
  3296. if (fEmptyPassword && !fPasswordOptional)
  3297. {
  3298. //
  3299. // If there is no password and password is not optional,
  3300. // uncheck the checkbox
  3301. //
  3302. SendMessageU(hwndCheckBox, BM_SETCHECK, BST_UNCHECKED, 0);
  3303. }
  3304. else if (fDialAutomatically)
  3305. {
  3306. //
  3307. // If dial automaticly, which means the checkbox is disabled,
  3308. // check the box if has password or password is optional
  3309. //
  3310. SendMessageU(hwndCheckBox, BM_SETCHECK, BST_CHECKED, 0);
  3311. }
  3312. }
  3313. //+----------------------------------------------------------------------------
  3314. //
  3315. // Function: CInetPage::OnInitDialog
  3316. //
  3317. // Synopsis: Virtual function. Called upon WM_INITDIALOG message
  3318. //
  3319. // Arguments: None
  3320. //
  3321. // Returns: BOOL - return value of the message
  3322. //
  3323. // History: fengsun Created Header 2/26/98
  3324. //
  3325. //+----------------------------------------------------------------------------
  3326. BOOL CInetPage::OnInitDialog()
  3327. {
  3328. UpdateFont(m_hWnd);
  3329. m_fPasswordOptional = m_pArgs->piniService->GPPB(c_pszCmSection, c_pszCmEntryPwdOptional);
  3330. //
  3331. // Initialize all the controls
  3332. //
  3333. OnInetInit(m_hWnd, m_pArgs);
  3334. return TRUE;
  3335. }
  3336. //+----------------------------------------------------------------------------
  3337. //
  3338. // Function: CInetPage::OnCommand
  3339. //
  3340. // Synopsis: Virtual function. Called upon WM_COMMAND
  3341. //
  3342. // Arguments: WPARAM - wParam of the message
  3343. // LPARAM - lParam of the message
  3344. //
  3345. // Returns: DWORD - return value of the message
  3346. //
  3347. // History: fengsun Created Header 2/26/98
  3348. //
  3349. //+----------------------------------------------------------------------------
  3350. DWORD CInetPage::OnCommand(WPARAM wParam, LPARAM)
  3351. {
  3352. switch (LOWORD(wParam))
  3353. {
  3354. case IDC_INET_PASSWORD:
  3355. if ((HIWORD(wParam) == EN_CHANGE))
  3356. {
  3357. if (!m_pArgs->fHideRememberInetPassword && !m_pArgs->fHideInetPassword)
  3358. {
  3359. //
  3360. // if there's no password, disable and uncheck "remember password"
  3361. //
  3362. BOOL fEmptyPassword = !SendDlgItemMessageU(m_hWnd, IDC_INET_PASSWORD,
  3363. WM_GETTEXTLENGTH, 0, (LPARAM)0);
  3364. //
  3365. // Enable/Disable check/uncheck the "Save Password" accordingly
  3366. // fPasswordOptional is always FALSE for the dialog
  3367. //
  3368. AdjustSavePasswordCheckBox(GetDlgItem(m_hWnd, IDC_INET_REMEMBER),
  3369. fEmptyPassword, m_pArgs->fDialAutomatically, m_fPasswordOptional);
  3370. return TRUE;
  3371. }
  3372. }
  3373. break;
  3374. case IDC_INET_REMEMBER:
  3375. {
  3376. //
  3377. // If the password wasn't modified by the user we want to clear
  3378. // the edit box. Once the password edit box is empty the
  3379. // Save Password option is disabled, thus we don't ever need to
  3380. // reload the password from memory like on the main dialog.
  3381. //
  3382. BOOL fSavePW = IsDlgButtonChecked(m_hWnd, IDC_INET_REMEMBER);
  3383. HWND hwndInetPW = GetDlgItem(m_hWnd, IDC_INET_PASSWORD);
  3384. if (hwndInetPW)
  3385. {
  3386. BOOL fInetPWChanged = (BOOL)SendMessageU(hwndInetPW, EM_GETMODIFY, 0L, 0L);
  3387. if (FALSE == fSavePW && FALSE == fInetPWChanged)
  3388. {
  3389. //
  3390. // Didn't change thus clear the edit box
  3391. //
  3392. SetDlgItemTextU(m_hWnd, IDC_INET_PASSWORD, TEXT(""));
  3393. }
  3394. }
  3395. }
  3396. break;
  3397. default:
  3398. break;
  3399. }
  3400. return 0;
  3401. }
  3402. //+----------------------------------------------------------------------------
  3403. //
  3404. // Function: CInetPage::OnApply
  3405. //
  3406. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_APPLY
  3407. // Indicates that the user clicked the OK or Apply Now button
  3408. // and wants all changes to take effect.
  3409. //
  3410. // Arguments: None
  3411. //
  3412. // Returns: NONE
  3413. //
  3414. // History: fengsun Created Header 2/26/98
  3415. //
  3416. //+----------------------------------------------------------------------------
  3417. void CInetPage::OnApply()
  3418. {
  3419. //
  3420. // Save information only if user chose dial-up
  3421. //
  3422. OnInetOk(m_hWnd, m_pArgs);
  3423. SetPropSheetResult(PSNRET_NOERROR);
  3424. }
  3425. //+----------------------------------------------------------------------------
  3426. //
  3427. // Function: CInetPage::OnGeneralPageKillActive
  3428. //
  3429. // Synopsis: Receive the KillActive event from General page
  3430. //
  3431. // Arguments: BOOL fDirect - Whehter the current connection type selection in
  3432. // General page is Direct
  3433. //
  3434. // Returns: Nothing
  3435. //
  3436. // History: Created Header 4/24/98
  3437. //
  3438. //+----------------------------------------------------------------------------
  3439. void CInetPage::OnGeneralPageKillActive(BOOL fDirect)
  3440. {
  3441. m_fDirect = fDirect;
  3442. }
  3443. //+----------------------------------------------------------------------------
  3444. //
  3445. // Function: CInetPage::OnSetActive
  3446. //
  3447. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_SETACTIVE
  3448. //
  3449. // Arguments: None
  3450. //
  3451. // Returns: BOOL - return value of the message
  3452. //
  3453. // History: fengsun Created Header 2/26/98
  3454. //
  3455. //+----------------------------------------------------------------------------
  3456. BOOL CInetPage::OnSetActive()
  3457. {
  3458. //
  3459. // Enable/Disable the control according to the current connection type
  3460. //
  3461. EnableWindow(GetDlgItem(m_hWnd,IDC_INET_USERNAME_STATIC), !m_fDirect);
  3462. EnableWindow(GetDlgItem(m_hWnd,IDC_INET_USERNAME), !m_fDirect);
  3463. EnableWindow(GetDlgItem(m_hWnd,IDC_INET_PASSWORD_STATIC), !m_fDirect);
  3464. EnableWindow(GetDlgItem(m_hWnd,IDC_INET_PASSWORD), !m_fDirect);
  3465. if (m_fDirect)
  3466. {
  3467. EnableWindow(GetDlgItem(m_hWnd,IDC_INET_REMEMBER), FALSE);
  3468. }
  3469. else if (!m_pArgs->fHideRememberInetPassword && !m_pArgs->fHideInetPassword)
  3470. {
  3471. BOOL fEmptyPassword = !SendDlgItemMessageU(m_hWnd,
  3472. IDC_INET_PASSWORD,
  3473. WM_GETTEXTLENGTH,
  3474. 0,
  3475. (LPARAM)0);
  3476. //
  3477. // Enable/Disable check/uncheck the "Save Password" accordingly
  3478. // fPasswordOptional is always FALSE for the dialog
  3479. //
  3480. AdjustSavePasswordCheckBox(GetDlgItem(m_hWnd, IDC_INET_REMEMBER),
  3481. fEmptyPassword, m_pArgs->fDialAutomatically, m_fPasswordOptional);
  3482. }
  3483. return 0;
  3484. }
  3485. //
  3486. // Help id pairs
  3487. //
  3488. const DWORD COptionPage::m_dwHelp[] = {
  3489. IDC_OPTIONS_IDLETIME_LIST, IDH_OPTIONS_IDLEDIS,
  3490. IDC_STATIC_MINUTES, IDH_OPTIONS_IDLEDIS,
  3491. IDC_OPTIONS_REDIALCOUNT_SPIN, IDH_OPTIONS_REDIAL,
  3492. IDC_OPTIONS_REDIALCOUNT_EDIT, IDH_OPTIONS_REDIAL,
  3493. IDC_STATIC_TIMES, IDH_OPTIONS_REDIAL,
  3494. IDC_OPTIONS_LOGGING, IDH_OPTIONS_LOGGING,
  3495. IDC_OPTIONS_CLEAR_LOG, IDH_OPTIONS_CLEAR_LOG,
  3496. IDC_OPTIONS_VIEW_LOG, IDH_OPTIONS_VIEW_LOG,
  3497. 0,0};
  3498. const DWORD COptionPage::m_adwTimeConst[] = {0,1, 5, 10, 30, 1*60, 2*60, 4*60, 8*60, 24*60};
  3499. const int COptionPage::m_nTimeConstElements = sizeof(m_adwTimeConst)/sizeof(m_adwTimeConst[0]);
  3500. //+----------------------------------------------------------------------------
  3501. //
  3502. // Function: COptionPage::COptionPage
  3503. //
  3504. // Synopsis: Constructor
  3505. //
  3506. // Arguments: ArgsStruct* pArgs - Information needed for the page
  3507. // UINT nIDTemplate - Resource ID
  3508. //
  3509. // Returns: Nothing
  3510. //
  3511. // History: fengsun Created Header 2/26/98
  3512. //
  3513. //+----------------------------------------------------------------------------
  3514. COptionPage::COptionPage(ArgsStruct* pArgs, UINT nIDTemplate)
  3515. : CPropertiesPage(nIDTemplate, m_dwHelp, pArgs->pszHelpFile)
  3516. {
  3517. MYDBGASSERT(pArgs);
  3518. m_pArgs = pArgs;
  3519. m_fEnableLog = FALSE;
  3520. }
  3521. //+----------------------------------------------------------------------------
  3522. //
  3523. // Function: COptionPage::InitIdleTimeList
  3524. //
  3525. // Synopsis: Populate the IdleTime combo box and set the initial selection
  3526. //
  3527. // Arguments: HWND hwndList - Combo box window handle
  3528. // DWORD dwMinutes - Time in minutes
  3529. //
  3530. // Returns: Nothing
  3531. //
  3532. // History: fengsun Created Header 4/22/98
  3533. //
  3534. //+----------------------------------------------------------------------------
  3535. void COptionPage::InitIdleTimeList(HWND hwndList, DWORD dwMinutes)
  3536. {
  3537. MYDBGASSERT(hwndList);
  3538. MYDBGASSERT(IsWindow(hwndList));
  3539. //
  3540. // Load the string from resource and populate the idle timeout list
  3541. //
  3542. MYDBGASSERT(IDS_IDLETIME_24HOURS - IDS_IDLETIME_NEVER == m_nTimeConstElements-1);
  3543. for (int i= IDS_IDLETIME_NEVER; i<= IDS_IDLETIME_24HOURS; i++)
  3544. {
  3545. LPTSTR pszText = CmLoadString(g_hInst, i);
  3546. MYDBGASSERT(pszText);
  3547. SendMessageU(hwndList, CB_ADDSTRING, 0, (LPARAM)pszText);
  3548. CmFree(pszText);
  3549. }
  3550. //
  3551. // Value are round down for 1.0 profile
  3552. // Note 0 means never. We are safe, since there is no gap between 0 and 1 minute.
  3553. //
  3554. int nSel; // the initial selection
  3555. for (nSel=m_nTimeConstElements-1; nSel>=0;nSel--)
  3556. {
  3557. if (dwMinutes >= m_adwTimeConst[nSel])
  3558. {
  3559. break;
  3560. }
  3561. }
  3562. SendMessageU(hwndList, CB_SETCURSEL, nSel, 0);
  3563. }
  3564. //+----------------------------------------------------------------------------
  3565. //
  3566. // Function: COptionPage::GetIdleTimeList
  3567. //
  3568. // Synopsis: Retrieve the IdleTime value selected
  3569. //
  3570. // Arguments: HWND hwndList - Combo box window handle
  3571. //
  3572. // Returns: DWORD - User selected timeout value in minutes
  3573. //
  3574. // History: fengsun Created Header 4/22/98
  3575. //
  3576. //+----------------------------------------------------------------------------
  3577. DWORD COptionPage::GetIdleTimeList(HWND hwndList)
  3578. {
  3579. //
  3580. // Get the current selection and convert it into minutes
  3581. //
  3582. DWORD dwSel = (DWORD)SendMessageU(hwndList, CB_GETCURSEL, 0, 0);
  3583. MYDBGASSERT(dwSel < m_nTimeConstElements);
  3584. if (dwSel >= m_nTimeConstElements) // in case of CB_ERR
  3585. {
  3586. dwSel = 0;
  3587. }
  3588. return m_adwTimeConst[dwSel];
  3589. }
  3590. //+---------------------------------------------------------------------------
  3591. //
  3592. // Function: COptionPage::OnInitDialog()
  3593. //
  3594. // Synopsis: Init the Options property sheet.
  3595. //
  3596. // Returns: NONE
  3597. //
  3598. // History: henryt Created 4/30/97
  3599. // byao Modified 5/12/97 - disable all controls in
  3600. // 'Dialing with connectoid' mode
  3601. //----------------------------------------------------------------------------
  3602. BOOL COptionPage::OnInitDialog()
  3603. {
  3604. UpdateFont(m_hWnd);
  3605. //
  3606. // init the "Idle timeout before hangup"
  3607. //
  3608. InitIdleTimeList(GetDlgItem(m_hWnd, IDC_OPTIONS_IDLETIME_LIST), m_pArgs->dwIdleTimeout);
  3609. //
  3610. // init the "Number of redial attempt"
  3611. // Limit Redial edit field to 3 characters, redial spin 0-999
  3612. //
  3613. const int MAX_REDIAL_CHARS = 3;
  3614. SendDlgItemMessageU(m_hWnd, IDC_OPTIONS_REDIALCOUNT_EDIT, EM_SETLIMITTEXT, MAX_REDIAL_CHARS, 0);
  3615. SendDlgItemMessageU(m_hWnd, IDC_OPTIONS_REDIALCOUNT_SPIN, UDM_SETRANGE , 0, MAKELONG(999,0));
  3616. SetDlgItemInt(m_hWnd, IDC_OPTIONS_REDIALCOUNT_EDIT, m_pArgs->nMaxRedials, FALSE);
  3617. //
  3618. // set logging state
  3619. //
  3620. m_fEnableLog = m_pArgs->Log.IsEnabled();
  3621. CheckDlgButton(m_hWnd, IDC_OPTIONS_LOGGING, m_fEnableLog);
  3622. if (IsLogonAsSystem() || (FALSE == m_fEnableLog))
  3623. {
  3624. EnableWindow(GetDlgItem(m_hWnd, IDC_OPTIONS_VIEW_LOG), FALSE);
  3625. EnableWindow(GetDlgItem(m_hWnd, IDC_OPTIONS_CLEAR_LOG), FALSE);
  3626. }
  3627. return TRUE;
  3628. }
  3629. //+----------------------------------------------------------------------------
  3630. //
  3631. // Function: COptionPage::OnCommand
  3632. //
  3633. // Synopsis: Virtual function. Called upon WM_COMMAND
  3634. //
  3635. // Arguments: WPARAM - wParam of the message
  3636. // LPARAM - lParam of the message
  3637. //
  3638. // Returns: DWORD - return value of the message
  3639. //
  3640. // History: SumitC Created 7/18/00
  3641. //
  3642. //+----------------------------------------------------------------------------
  3643. DWORD COptionPage::OnCommand(WPARAM wParam, LPARAM)
  3644. {
  3645. switch (LOWORD(wParam))
  3646. {
  3647. case IDC_OPTIONS_LOGGING:
  3648. {
  3649. BOOL fEnabled = ToggleLogging();
  3650. if (FALSE == IsLogonAsSystem())
  3651. {
  3652. EnableWindow(GetDlgItem(m_hWnd, IDC_OPTIONS_VIEW_LOG), fEnabled);
  3653. EnableWindow(GetDlgItem(m_hWnd, IDC_OPTIONS_CLEAR_LOG), fEnabled);
  3654. }
  3655. }
  3656. break;
  3657. case IDC_OPTIONS_CLEAR_LOG:
  3658. MYDBGASSERT(FALSE == IsLogonAsSystem());
  3659. if (FALSE == IsLogonAsSystem())
  3660. {
  3661. m_pArgs->Log.Clear();
  3662. m_pArgs->Log.Log(CLEAR_LOG_EVENT);
  3663. }
  3664. break;
  3665. case IDC_OPTIONS_VIEW_LOG:
  3666. MYDBGASSERT(FALSE == IsLogonAsSystem());
  3667. if (FALSE == IsLogonAsSystem())
  3668. {
  3669. LPCTSTR pszLogFile = m_pArgs->Log.GetLogFilePath();
  3670. HANDLE hFile = CreateFile(pszLogFile, 0,
  3671. FILE_SHARE_READ,
  3672. NULL, OPEN_EXISTING,
  3673. FILE_ATTRIBUTE_NORMAL, NULL);
  3674. if (INVALID_HANDLE_VALUE != hFile)
  3675. {
  3676. BOOL bReturn;
  3677. SHELLEXECUTEINFO sei;
  3678. ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
  3679. //
  3680. // Fill in the Execute Struct
  3681. //
  3682. sei.cbSize = sizeof(SHELLEXECUTEINFO);
  3683. sei.hwnd = NULL;
  3684. sei.lpVerb = TEXT("open");
  3685. sei.lpFile = TEXT("notepad.exe");
  3686. sei.lpParameters = pszLogFile;
  3687. sei.nShow = SW_SHOWNORMAL;
  3688. bReturn = m_pArgs->m_ShellDll.ExecuteEx(&sei);
  3689. if (FALSE == bReturn)
  3690. {
  3691. CMTRACE1(TEXT("COptionPage::OnCommand, failed to View Log, GLE=%d"), GetLastError());
  3692. LPTSTR pszMsg = CmFmtMsg(g_hInst, IDMSG_CANT_VIEW_LOG, pszLogFile);
  3693. if (pszMsg)
  3694. {
  3695. MessageBox(m_hWnd, pszMsg, m_pArgs->szServiceName, MB_OK | MB_ICONERROR);
  3696. CmFree(pszMsg);
  3697. }
  3698. }
  3699. CloseHandle(hFile);
  3700. }
  3701. else
  3702. {
  3703. CMTRACE(TEXT("COptionPage::OnCommand, no log file, nothing to view"));
  3704. LPTSTR pszMsg = CmFmtMsg(g_hInst, IDMSG_NO_LOG_FILE);
  3705. if (pszMsg)
  3706. {
  3707. MessageBox(m_hWnd, pszMsg, m_pArgs->szServiceName, MB_OK | MB_ICONERROR);
  3708. CmFree(pszMsg);
  3709. }
  3710. }
  3711. }
  3712. break;
  3713. }
  3714. return 0;
  3715. }
  3716. //+---------------------------------------------------------------------------
  3717. //
  3718. // Function: COptionPage::OnApply()
  3719. //
  3720. // Synopsis: Save the data associated with the 'Options' property sheet.
  3721. // when the user clicks OK.
  3722. //
  3723. // Returns: NONE
  3724. //
  3725. // History: henryt Created 4/30/97
  3726. //
  3727. //----------------------------------------------------------------------------
  3728. void COptionPage::OnApply()
  3729. {
  3730. //
  3731. // Accessing RedialCount and IdleTimeout. Make sure to use piniBothNonFav
  3732. // because these settings are per user, per profile.
  3733. //
  3734. //
  3735. // save the "Idle timeout before hangup"
  3736. //
  3737. m_pArgs->dwIdleTimeout = GetIdleTimeList(GetDlgItem(m_hWnd, IDC_OPTIONS_IDLETIME_LIST));
  3738. m_pArgs->piniBothNonFav->WPPI(c_pszCmSection, c_pszCmEntryIdleTimeout, m_pArgs->dwIdleTimeout);
  3739. //
  3740. // save the redial settings
  3741. //
  3742. m_pArgs->nMaxRedials = GetDlgItemInt(m_hWnd, IDC_OPTIONS_REDIALCOUNT_EDIT, NULL, FALSE);
  3743. m_pArgs->piniBothNonFav->WPPI(c_pszCmSection, c_pszCmEntryRedialCount, m_pArgs->nMaxRedials);
  3744. //
  3745. // NOTE: Logging is enabled/disabled immediately when the logging checkbox
  3746. // is clicked. Thus there is no code here to handle the Apply.
  3747. //
  3748. SetPropSheetResult(PSNRET_NOERROR);
  3749. }
  3750. //+----------------------------------------------------------------------------
  3751. //
  3752. // Function: COptionPage::ToggleLogging
  3753. //
  3754. // Synopsis: Helper function, responds to logging being enabled/disabled.
  3755. //
  3756. // Arguments: none
  3757. //
  3758. // Returns: BOOL - Is logging now enabled or disabled?
  3759. //
  3760. // History: SumitC Created 11/07/00
  3761. //
  3762. //+----------------------------------------------------------------------------
  3763. BOOL COptionPage::ToggleLogging()
  3764. {
  3765. //
  3766. // save the Logging settings
  3767. //
  3768. BOOL fEnableLog = IsDlgButtonChecked(m_hWnd, IDC_OPTIONS_LOGGING);
  3769. m_pArgs->piniBothNonFav->WPPB(c_pszCmSection, c_pszCmEntryEnableLogging, fEnableLog);
  3770. if ((!!fEnableLog != !!m_fEnableLog))
  3771. {
  3772. // if the value has changed
  3773. if (fEnableLog)
  3774. {
  3775. DWORD dwMaxSize = m_pArgs->piniService->GPPI(c_pszCmSectionLogging, c_pszCmEntryMaxLogFileSize, c_dwMaxFileSize);
  3776. LPTSTR pszFileDir = m_pArgs->piniService->GPPS(c_pszCmSectionLogging, c_pszCmEntryLogFileDirectory, c_szLogFileDirectory);
  3777. m_pArgs->Log.SetParams(TRUE, dwMaxSize, pszFileDir); // TRUE == fEnabled
  3778. CmFree(pszFileDir);
  3779. m_pArgs->Log.Start(TRUE); // TRUE => write a banner as well
  3780. m_pArgs->Log.Log(LOGGING_ENABLED_EVENT);
  3781. }
  3782. else
  3783. {
  3784. m_pArgs->Log.Log(LOGGING_DISABLED_EVENT);
  3785. m_pArgs->Log.Stop();
  3786. }
  3787. m_fEnableLog = fEnableLog;
  3788. }
  3789. return m_fEnableLog;
  3790. }
  3791. //+----------------------------------------------------------------------------
  3792. //
  3793. // Function: CAboutPage::CAboutPage
  3794. //
  3795. // Synopsis: Constructor
  3796. //
  3797. // Arguments: UINT nIDTemplate - Dialog resource ID
  3798. //
  3799. // Returns: Nothing
  3800. //
  3801. // History: fengsun Created Header 2/26/98
  3802. //
  3803. //+----------------------------------------------------------------------------
  3804. CAboutPage::CAboutPage(ArgsStruct* pArgs, UINT nIDTemplate)
  3805. : CPropertiesPage(nIDTemplate)
  3806. {
  3807. MYDBGASSERT(pArgs);
  3808. m_pArgs = pArgs;
  3809. }
  3810. //+---------------------------------------------------------------------------
  3811. //
  3812. // Function: CAboutPage::OnInitDialog()
  3813. //
  3814. // Synopsis: Init the About property sheet.
  3815. //
  3816. // Arguments: m_hWnd [dlg window handle]
  3817. //
  3818. // Returns: NONE
  3819. //
  3820. // History: henryt Created 4/30/97
  3821. // byao Modified 5/12/97 - disable all controls in
  3822. // 'Dialing with connectoid' mode
  3823. //----------------------------------------------------------------------------
  3824. BOOL CAboutPage::OnInitDialog()
  3825. {
  3826. UpdateFont(m_hWnd);
  3827. LPTSTR pszTmp;
  3828. LPTSTR pszExt;
  3829. //
  3830. // Set the warning text. We can't put it the dialog template because it's
  3831. // longer than 256 chars.
  3832. //
  3833. if (!(pszTmp = CmLoadString(g_hInst, IDMSG_ABOUT_WARNING_PART1)))
  3834. {
  3835. pszTmp = CmStrCpyAlloc(NULL);
  3836. }
  3837. if (!(pszExt = CmLoadString(g_hInst, IDMSG_ABOUT_WARNING_PART2)))
  3838. {
  3839. pszExt = CmStrCpyAlloc(NULL);
  3840. }
  3841. pszTmp = CmStrCatAlloc(&pszTmp, pszExt);
  3842. SetDlgItemTextU(m_hWnd, IDC_ABOUT_WARNING, pszTmp);
  3843. CmFree(pszTmp);
  3844. CmFree(pszExt);
  3845. //#150147
  3846. LPTSTR pszVersion = (LPTSTR)CmMalloc(sizeof(TCHAR)*(lstrlenA(VER_PRODUCTVERSION_STR) + 1));
  3847. if (pszVersion)
  3848. {
  3849. wsprintfU(pszVersion, TEXT("%S"), VER_PRODUCTVERSION_STR);
  3850. if (!(pszTmp = CmFmtMsg(g_hInst, IDMSG_ABOUT_BUILDVERSION, pszVersion)))
  3851. {
  3852. pszTmp = CmStrCpyAlloc(pszVersion);
  3853. }
  3854. CmFree(pszVersion);
  3855. if (pszTmp)
  3856. {
  3857. SetDlgItemTextU(m_hWnd, IDC_ABOUT_VERSION, pszTmp);
  3858. CmFree(pszTmp);
  3859. }
  3860. }
  3861. return (TRUE);
  3862. }
  3863. //+----------------------------------------------------------------------------
  3864. //
  3865. // Function: CAboutPage::OnOtherMessage
  3866. //
  3867. // Synopsis: Callup opun message other than WM_INITDIALOG and WM_COMMAND
  3868. //
  3869. // Arguments: UINT - Message Id
  3870. // WPARAM - wParam of the message
  3871. // LPARAM - lParam of the message
  3872. //
  3873. // Returns: DWORD - return value of the message
  3874. //
  3875. // History: fengsun Created Header 2/26/98
  3876. //
  3877. //+----------------------------------------------------------------------------
  3878. DWORD CAboutPage::OnOtherMessage(UINT uMsg, WPARAM wParam, LPARAM )
  3879. {
  3880. return 0;
  3881. }
  3882. //+---------------------------------------------------------------------------
  3883. //
  3884. // Function: CAboutPage::OnSetActive()
  3885. //
  3886. // Synopsis: Creates DI bitmap, etc. for about tab bitmap
  3887. //
  3888. // Arguments: None
  3889. //
  3890. //
  3891. // Returns: NONE
  3892. //
  3893. // History: nickball Created 7/14/97
  3894. //
  3895. //----------------------------------------------------------------------------
  3896. BOOL CAboutPage::OnSetActive()
  3897. {
  3898. return 0;
  3899. }
  3900. //+----------------------------------------------------------------------------
  3901. //
  3902. // Function: CAboutPage::OnKillActive
  3903. //
  3904. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_KILLACTIVE
  3905. // Notifies a page that it is about to lose activation either because
  3906. // another page is being activated or the user has clicked the OK button.
  3907. // Arguments: None
  3908. //
  3909. // Returns: BOOL - return value of the message
  3910. //
  3911. // History: fengsun Created Header 2/26/98
  3912. //
  3913. //+----------------------------------------------------------------------------
  3914. BOOL CAboutPage::OnKillActive()
  3915. {
  3916. return 0;
  3917. }
  3918. //+----------------------------------------------------------------------------
  3919. //
  3920. // Function: CAboutPage::OnApply
  3921. //
  3922. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_APPLY
  3923. // Indicates that the user clicked the OK or Apply Now button
  3924. // and wants all changes to take effect.
  3925. //
  3926. // Arguments: None
  3927. //
  3928. // Returns: NONE
  3929. //
  3930. // History: fengsun Created Header 2/26/98
  3931. //
  3932. //+----------------------------------------------------------------------------
  3933. void CAboutPage::OnApply()
  3934. {
  3935. SetPropSheetResult(PSNRET_NOERROR);
  3936. }
  3937. //+----------------------------------------------------------------------------
  3938. //
  3939. // Function: CAboutPage::OnReset
  3940. //
  3941. // Synopsis: Virtual function. Called upon WM_NOTIFY with PSN_RESET
  3942. // Notifies a page that the user has clicked the Cancel button and
  3943. // the property sheet is about to be destroyed.
  3944. //
  3945. // Arguments: None
  3946. //
  3947. // Returns: NONE
  3948. //
  3949. // History: fengsun Created Header 2/26/98
  3950. //
  3951. //+----------------------------------------------------------------------------
  3952. void CAboutPage::OnReset()
  3953. {
  3954. //nothing
  3955. }
  3956. //+----------------------------------------------------------------------------
  3957. //
  3958. // Function: CChangePasswordDlg::OnInitDialog
  3959. //
  3960. // Synopsis: Virtual function. Call upon WM_INITDIALOG message
  3961. //
  3962. // Arguments: None
  3963. //
  3964. // Returns: BOOL - Return value of WM_INITDIALOG
  3965. //
  3966. // History: v-vijayb Created Header 7/3/99
  3967. //
  3968. //+----------------------------------------------------------------------------
  3969. BOOL CChangePasswordDlg::OnInitDialog()
  3970. {
  3971. DWORD cMaxPassword;
  3972. SetForegroundWindow(m_hWnd);
  3973. m_pArgs->hWndChangePassword = m_hWnd;
  3974. UpdateFont(m_hWnd);
  3975. int iMaxPasswordFromCMS = m_pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryMaxPassword, PWLEN);
  3976. if (InBetween(0, iMaxPasswordFromCMS, PWLEN))
  3977. {
  3978. cMaxPassword = iMaxPasswordFromCMS;
  3979. }
  3980. else
  3981. {
  3982. cMaxPassword = PWLEN;
  3983. }
  3984. SendDlgItemMessageU(m_hWnd, IDC_NEW_PASSWORD, EM_SETLIMITTEXT, cMaxPassword, 0);
  3985. SendDlgItemMessageU(m_hWnd, IDC_CONFIRMNEWPASSWORD, EM_SETLIMITTEXT, cMaxPassword, 0);
  3986. SetFocus(GetDlgItem(m_hWnd, IDC_NEW_PASSWORD));
  3987. //
  3988. // Must return FALSE when setting focus
  3989. //
  3990. return FALSE;
  3991. }
  3992. //+----------------------------------------------------------------------------
  3993. //
  3994. // Function: CChangePasswordDlg::OnOK
  3995. //
  3996. // Synopsis: Virtual function. Called upon WM_COMMAND with IDOK
  3997. //
  3998. // Arguments: None
  3999. //
  4000. // Returns: Nothing
  4001. //
  4002. // History: v-vijayb Created Header 7/3/99
  4003. //
  4004. //+----------------------------------------------------------------------------
  4005. void CChangePasswordDlg::OnOK()
  4006. {
  4007. TCHAR szNewConfirmPassword[PWLEN+1];
  4008. TCHAR szNewPassword[PWLEN+1];
  4009. GetDlgItemText(m_hWnd, IDC_NEW_PASSWORD, szNewPassword, PWLEN+1);
  4010. GetDlgItemText(m_hWnd, IDC_CONFIRMNEWPASSWORD, szNewConfirmPassword, PWLEN+1);
  4011. //
  4012. // Both must match exactly
  4013. //
  4014. if (lstrcmpU(szNewPassword, szNewConfirmPassword) == 0)
  4015. {
  4016. //
  4017. // Process password according to our handling rules
  4018. //
  4019. ApplyPasswordHandlingToBuffer(m_pArgs, szNewPassword);
  4020. //
  4021. // Encode password when comitting to internal storage.
  4022. //
  4023. lstrcpyU(m_pArgs->szPassword, szNewPassword);
  4024. CmEncodePassword(m_pArgs->szPassword);
  4025. lstrcpyU(m_pArgs->pRasDialParams->szPassword, szNewPassword);
  4026. CmEncodePassword(m_pArgs->pRasDialParams->szPassword);
  4027. m_pArgs->fChangedPassword = TRUE;
  4028. m_pArgs->hWndChangePassword = NULL;
  4029. m_pArgs->Log.Log(PASSWORD_EXPIRED_EVENT, TEXT("ok"));
  4030. EndDialog(m_hWnd, TRUE);
  4031. }
  4032. else
  4033. {
  4034. HWND hWnd = GetDlgItem(m_hWnd, IDC_NEW_PASSWORD);
  4035. TCHAR *pszTmp;
  4036. MYDBGASSERT(hWnd);
  4037. pszTmp = CmFmtMsg(g_hInst, IDMSG_NOMATCHPASSWORD);
  4038. MYDBGASSERT(pszTmp);
  4039. if (pszTmp)
  4040. {
  4041. MessageBoxEx(m_hWnd, pszTmp, m_pArgs->szServiceName, MB_OK | MB_ICONERROR, LANG_USER_DEFAULT);
  4042. CmFree(pszTmp);
  4043. }
  4044. SetFocus(hWnd);
  4045. SendMessageU(hWnd, EM_SETSEL, 0, MAKELONG(0, -1));
  4046. }
  4047. CmWipePassword(szNewConfirmPassword);
  4048. CmWipePassword(szNewPassword);
  4049. }
  4050. //+----------------------------------------------------------------------------
  4051. //
  4052. // Function: CChangePasswordDlg::OnCancel
  4053. //
  4054. // Synopsis: Virtual function. Called upon WM_COMMAND with IDCANCEL
  4055. //
  4056. // Arguments: None
  4057. //
  4058. // Returns: Nothing
  4059. //
  4060. // History: v-vijayb Created Header 7/16/99
  4061. //
  4062. //+----------------------------------------------------------------------------
  4063. void CChangePasswordDlg::OnCancel()
  4064. {
  4065. m_pArgs->fChangedPassword = FALSE;
  4066. m_pArgs->hWndChangePassword = NULL;
  4067. m_pArgs->Log.Log(PASSWORD_EXPIRED_EVENT, TEXT("cancel"));
  4068. EndDialog(m_hWnd, FALSE);
  4069. }
  4070. //+----------------------------------------------------------------------------
  4071. //
  4072. // Function: CChangePasswordDlg::OnOtherCommand
  4073. //
  4074. // Synopsis: Virtual function. Call upon WM_COMMAND with command other than IDOK
  4075. // and IDCANCEL
  4076. //
  4077. // Arguments: WPARAM wParam - wParam of WM_COMMAND
  4078. // LPARAM -
  4079. //
  4080. // Returns: DWORD -
  4081. //
  4082. // History: v-vijayb Created Header 7/3/99
  4083. //
  4084. //+----------------------------------------------------------------------------
  4085. DWORD CChangePasswordDlg::OnOtherCommand(WPARAM wParam, LPARAM)
  4086. {
  4087. return FALSE;
  4088. }
  4089. //+----------------------------------------------------------------------------
  4090. //
  4091. // Function: CCallbackNumberDlg::OnInitDialog
  4092. //
  4093. // Synopsis: Virtual function. Call upon WM_INITDIALOG message
  4094. //
  4095. // Arguments: None
  4096. //
  4097. // Returns: BOOL - Return value of WM_INITDIALOG
  4098. //
  4099. // History: nickball created 03/01/00
  4100. //
  4101. //+----------------------------------------------------------------------------
  4102. BOOL CCallbackNumberDlg::OnInitDialog()
  4103. {
  4104. SetForegroundWindow(m_hWnd);
  4105. //
  4106. // Store window handle globally and setup edit control
  4107. //
  4108. m_pArgs->hWndCallbackNumber = m_hWnd;
  4109. UpdateFont(m_hWnd);
  4110. SendDlgItemMessageU(m_hWnd, IDC_CALLBACK_NUM_EDIT, EM_SETLIMITTEXT, RAS_MaxCallbackNumber , 0);
  4111. //
  4112. // See if we have anything from previous use. If so, add it to the control.
  4113. //
  4114. SetWindowTextU(GetDlgItem(m_hWnd, IDC_CALLBACK_NUM_EDIT), m_pArgs->pRasDialParams->szCallbackNumber);
  4115. //
  4116. // Set focus, must return FALSE when doing so.
  4117. //
  4118. SetFocus(GetDlgItem(m_hWnd, IDC_CALLBACK_NUM_EDIT));
  4119. return FALSE;
  4120. }
  4121. //+----------------------------------------------------------------------------
  4122. //
  4123. // Function: CCallbackNumberDlg::OnOK
  4124. //
  4125. // Synopsis: Virtual function. Called upon WM_COMMAND with IDOK
  4126. // Retrieves the number for callback and stores in dial params.
  4127. //
  4128. // Arguments: None
  4129. //
  4130. // Returns: Nothing
  4131. //
  4132. // History: nickball created 03/01/00
  4133. //
  4134. //+----------------------------------------------------------------------------
  4135. void CCallbackNumberDlg::OnOK()
  4136. {
  4137. TCHAR szNumber[RAS_MaxCallbackNumber+1];
  4138. GetDlgItemText(m_hWnd, IDC_CALLBACK_NUM_EDIT, szNumber, RAS_MaxCallbackNumber);
  4139. //
  4140. // Although one would expect that the length of the number would be
  4141. // verified, this is not the case with RAS. In the interests of
  4142. // behavioral parity we will allow an empty number field.
  4143. //
  4144. //
  4145. // We're good to go, fill in Dial Params and ski-dadle.
  4146. //
  4147. lstrcpyU(m_pArgs->pRasDialParams->szCallbackNumber, szNumber);
  4148. //
  4149. // Succesful callback, store the number in the .CMP
  4150. //
  4151. m_pArgs->piniProfile->WPPS(c_pszCmSection, c_pszCmEntryCallbackNumber, m_pArgs->pRasDialParams->szCallbackNumber);
  4152. m_pArgs->hWndCallbackNumber = NULL;
  4153. m_pArgs->Log.Log(CALLBACK_NUMBER_EVENT, TEXT("ok"), m_pArgs->pRasDialParams->szCallbackNumber);
  4154. EndDialog(m_hWnd, TRUE);
  4155. }
  4156. //+----------------------------------------------------------------------------
  4157. //
  4158. // Function: CCallbackNumberDlg::OnCancel
  4159. //
  4160. // Synopsis: Virtual function. Called upon WM_COMMAND with IDCANCEL
  4161. //
  4162. // Arguments: None
  4163. //
  4164. // Returns: Nothing
  4165. //
  4166. // History: nickball created 03/01/00
  4167. //
  4168. //+----------------------------------------------------------------------------
  4169. void CCallbackNumberDlg::OnCancel()
  4170. {
  4171. m_pArgs->fWaitingForCallback = FALSE;
  4172. m_pArgs->hWndCallbackNumber = NULL;
  4173. m_pArgs->Log.Log(CALLBACK_NUMBER_EVENT, TEXT("cancel"), TEXT("none"));
  4174. EndDialog(m_hWnd, FALSE);
  4175. }
  4176. //+----------------------------------------------------------------------------
  4177. //
  4178. // Function: CCallbackNumberDlg::OnOtherCommand
  4179. //
  4180. // Synopsis: Virtual function. Call upon WM_COMMAND with command other than IDOK
  4181. // and IDCANCEL
  4182. //
  4183. // Arguments: WPARAM wParam - wParam of WM_COMMAND
  4184. // LPARAM -
  4185. //
  4186. // Returns: DWORD -
  4187. //
  4188. // History: nickball created 03/01/00
  4189. //
  4190. //+----------------------------------------------------------------------------
  4191. DWORD CCallbackNumberDlg::OnOtherCommand(WPARAM wParam, LPARAM)
  4192. {
  4193. return FALSE;
  4194. }
  4195. //
  4196. // No help on OK or Cancel button
  4197. //
  4198. const DWORD CRetryAuthenticationDlg::m_dwHelp[] = {
  4199. IDC_RETRY_REMEMBER, IDH_RETRY_REMEMBER,
  4200. IDC_RETRY_USERNAME_STATIC, IDH_RETRY_USERNAME_STATIC,
  4201. IDC_RETRY_USERNAME, IDH_RETRY_USERNAME,
  4202. IDC_RETRY_PASSWORD_STATIC, IDH_RETRY_PASSWORD_STATIC,
  4203. IDC_RETRY_PASSWORD, IDH_RETRY_PASSWORD,
  4204. IDC_RETRY_DOMAIN_STATIC, IDH_RETRY_DOMAIN_STATIC,
  4205. IDC_RETRY_DOMAIN, IDH_RETRY_DOMAIN,
  4206. IDOK, IDH_RETRY_OK,
  4207. IDCANCEL, IDH_RETRY_CANCEL,
  4208. 0,0};
  4209. //+----------------------------------------------------------------------------
  4210. //
  4211. // Function: CRetryAuthenticationDlg::OnInitDialog
  4212. //
  4213. // Synopsis: Virtual function. Call upon WM_INITDIALOG message to intialize
  4214. // the dialog.
  4215. //
  4216. // Arguments: None
  4217. //
  4218. // Returns: BOOL - Return value of WM_INITDIALOG
  4219. //
  4220. // History: nickball created 03/01/00
  4221. //
  4222. //+----------------------------------------------------------------------------
  4223. BOOL CRetryAuthenticationDlg::OnInitDialog()
  4224. {
  4225. DWORD dwMax = MAX_PATH;
  4226. m_pArgs->Log.Log(RETRY_AUTH_EVENT);
  4227. SetForegroundWindow(m_hWnd);
  4228. //
  4229. // Brand the dialog
  4230. //
  4231. if (m_pArgs->hSmallIcon)
  4232. {
  4233. SendMessageU(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM) m_pArgs->hSmallIcon);
  4234. }
  4235. if (m_pArgs->hBigIcon)
  4236. {
  4237. SendMessageU(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM) m_pArgs->hBigIcon);
  4238. SendMessageU(GetDlgItem(m_hWnd, IDC_INET_ICON), STM_SETIMAGE, IMAGE_ICON, (LPARAM) m_pArgs->hBigIcon);
  4239. }
  4240. //
  4241. // Store window handle globally and setup edit control
  4242. //
  4243. m_pArgs->hWndRetryAuthentication = m_hWnd;
  4244. UpdateFont(m_hWnd);
  4245. //
  4246. // If not Inet dial, then use the service as the title
  4247. //
  4248. if (!m_fInetCredentials)
  4249. {
  4250. LPTSTR pszTitle = CmStrCpyAlloc(m_pArgs->szServiceName);
  4251. SetWindowTextU(m_hWnd, pszTitle);
  4252. CmFree(pszTitle);
  4253. }
  4254. //
  4255. // Fill password as appropriate to the template and dial type.
  4256. //
  4257. HWND hwndPassword = GetDlgItem(m_hWnd, IDC_RETRY_PASSWORD);
  4258. if (hwndPassword)
  4259. {
  4260. //
  4261. // Limit user entry according to current config.
  4262. //
  4263. int iMaxPasswordFromCMS = m_pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryMaxPassword, PWLEN);
  4264. if (InBetween(0, iMaxPasswordFromCMS, PWLEN))
  4265. {
  4266. dwMax = iMaxPasswordFromCMS;
  4267. }
  4268. else
  4269. {
  4270. dwMax = PWLEN;
  4271. }
  4272. SendDlgItemMessageU(m_hWnd, IDC_RETRY_PASSWORD, EM_SETLIMITTEXT, dwMax, 0);
  4273. MYDBGASSERT(dwMax <= PWLEN && dwMax > 0);
  4274. //
  4275. // Do we have any data to display?
  4276. //
  4277. BOOL fHasPassword = FALSE;
  4278. if (m_fInetCredentials)
  4279. {
  4280. if (lstrlenU(m_pArgs->szInetPassword))
  4281. {
  4282. CmDecodePassword(m_pArgs->szInetPassword);
  4283. SetDlgItemTextU(m_hWnd, IDC_RETRY_PASSWORD, m_pArgs->szInetPassword);
  4284. CmEncodePassword(m_pArgs->szInetPassword);
  4285. fHasPassword = TRUE;
  4286. }
  4287. }
  4288. else
  4289. {
  4290. if (lstrlenU(m_pArgs->szPassword))
  4291. {
  4292. CmDecodePassword(m_pArgs->szPassword);
  4293. SetDlgItemTextU(m_hWnd, IDC_RETRY_PASSWORD, m_pArgs->szPassword);
  4294. CmEncodePassword(m_pArgs->szPassword);
  4295. fHasPassword = TRUE;
  4296. }
  4297. }
  4298. //
  4299. // Decide what to do with "Save Password" check-box
  4300. //
  4301. HWND hwndSavePassword = GetDlgItem(m_hWnd, IDC_RETRY_REMEMBER);
  4302. if (hwndSavePassword)
  4303. {
  4304. //
  4305. // We have a save password control, see if we should hide it.
  4306. //
  4307. if ((m_fInetCredentials && m_pArgs->fHideRememberInetPassword) ||
  4308. (!m_fInetCredentials && m_pArgs->fHideRememberPassword))
  4309. {
  4310. ShowWindow(hwndSavePassword, SW_HIDE);
  4311. }
  4312. else
  4313. {
  4314. //
  4315. // We're not hiding, so adjust its state as needed. If no data
  4316. // then disable the control. Otherwise check according to current
  4317. // user setting.
  4318. //
  4319. if (!fHasPassword)
  4320. {
  4321. EnableWindow(GetDlgItem(m_hWnd, IDC_RETRY_REMEMBER), FALSE);
  4322. }
  4323. else
  4324. {
  4325. if ((m_fInetCredentials && m_pArgs->fRememberInetPassword) ||
  4326. (!m_fInetCredentials && m_pArgs->fRememberMainPassword))
  4327. {
  4328. SendMessageU(hwndSavePassword, BM_SETCHECK, BST_CHECKED, 0);
  4329. }
  4330. }
  4331. }
  4332. }
  4333. }
  4334. //
  4335. // Fill username as appropriate to the template and dial type.
  4336. //
  4337. HWND hwndUsername = GetDlgItem(m_hWnd, IDC_RETRY_USERNAME);
  4338. if (hwndUsername)
  4339. {
  4340. int iMaxUserNameFromCMS = m_pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryMaxUserName, UNLEN);
  4341. if (InBetween(0, iMaxUserNameFromCMS, UNLEN))
  4342. {
  4343. dwMax = iMaxUserNameFromCMS;
  4344. }
  4345. else
  4346. {
  4347. dwMax = UNLEN;
  4348. }
  4349. SendDlgItemMessageU(m_hWnd, IDC_RETRY_USERNAME, EM_SETLIMITTEXT, dwMax, 0);
  4350. MYDBGASSERT(dwMax <= UNLEN);
  4351. if (m_fInetCredentials)
  4352. {
  4353. if (lstrlenU(m_pArgs->szInetUserName))
  4354. {
  4355. SetDlgItemTextU(m_hWnd, IDC_RETRY_USERNAME, m_pArgs->szInetUserName);
  4356. }
  4357. }
  4358. else
  4359. {
  4360. if (lstrlenU(m_pArgs->szUserName))
  4361. {
  4362. SetDlgItemTextU(m_hWnd, IDC_RETRY_USERNAME, m_pArgs->szUserName);
  4363. }
  4364. }
  4365. }
  4366. //
  4367. // Fill domain as appropriate to the template.
  4368. //
  4369. HWND hwndDomain = GetDlgItem(m_hWnd, IDC_RETRY_DOMAIN);
  4370. if (hwndDomain)
  4371. {
  4372. int iMaxDomainFromCMS = m_pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryMaxDomain, DNLEN);
  4373. if (InBetween(0, iMaxDomainFromCMS, DNLEN))
  4374. {
  4375. dwMax = iMaxDomainFromCMS;
  4376. }
  4377. else
  4378. {
  4379. dwMax = DNLEN;
  4380. }
  4381. SendDlgItemMessageU(m_hWnd, IDC_RETRY_DOMAIN, EM_SETLIMITTEXT, dwMax, 0);
  4382. MYDBGASSERT(dwMax <= DNLEN);
  4383. if (lstrlenU(m_pArgs->szDomain))
  4384. {
  4385. SetDlgItemTextU(m_hWnd, IDC_RETRY_DOMAIN, m_pArgs->szDomain);
  4386. }
  4387. }
  4388. //
  4389. // Drop focus in the first available control
  4390. //
  4391. HWND hwndFocus = hwndUsername;
  4392. if (!hwndFocus)
  4393. {
  4394. hwndFocus = hwndPassword ? hwndPassword : hwndDomain;
  4395. }
  4396. SetFocus(hwndFocus);
  4397. //
  4398. // Must return FALSE when setting focus
  4399. //
  4400. return FALSE;
  4401. }
  4402. //+----------------------------------------------------------------------------
  4403. //
  4404. // Function: CRetryAuthenticationDlg::OnOK
  4405. //
  4406. // Synopsis: Virtual function. Called upon WM_COMMAND with IDOK
  4407. // Retrieves the cerdentials and stores them in dial params.
  4408. //
  4409. // Arguments: None
  4410. //
  4411. // Returns: Nothing
  4412. //
  4413. // History: nickball created 03/01/00
  4414. //
  4415. //+----------------------------------------------------------------------------
  4416. void CRetryAuthenticationDlg::OnOK()
  4417. {
  4418. LPTSTR pszBuf = NULL;
  4419. BOOL fSave = FALSE;
  4420. //
  4421. // Check Save Password (if any) to see how we should proceed
  4422. //
  4423. BOOL fSwitchToUserCredentials = FALSE;
  4424. BOOL fNeedToResaveUserName = FALSE;
  4425. BOOL fNeedToResaveDomain = FALSE;
  4426. BOOL fChecked = FALSE;
  4427. HWND hwndMainDlgSavePW = GetDlgItem(m_pArgs->hwndMainDlg, IDC_MAIN_NOPASSWORD_CHECKBOX);
  4428. HWND hwndMainDlgDialAutomatically = GetDlgItem(m_pArgs->hwndMainDlg, IDC_MAIN_NOPROMPT_CHECKBOX);
  4429. BOOL fMainDlgSavePWEnabled = FALSE;
  4430. BOOL fMainDlgDialAutoEnabled = FALSE;
  4431. //
  4432. // In order not to trigger change notification when updating Main dialog controls.
  4433. // This is set back to FALSE at the bottom of the funtion.
  4434. //
  4435. m_pArgs->fIgnoreChangeNotification = TRUE;
  4436. //
  4437. // Gets the inital state of the checkboxes
  4438. //
  4439. if (hwndMainDlgSavePW)
  4440. {
  4441. fMainDlgSavePWEnabled = IsWindowEnabled(hwndMainDlgSavePW);
  4442. }
  4443. if (hwndMainDlgDialAutomatically)
  4444. {
  4445. fMainDlgDialAutoEnabled = IsWindowEnabled(hwndMainDlgDialAutomatically);
  4446. }
  4447. if (GetDlgItem(m_hWnd, IDC_RETRY_REMEMBER))
  4448. {
  4449. fChecked = IsDlgButtonChecked(m_hWnd, IDC_RETRY_REMEMBER);
  4450. if (m_fInetCredentials)
  4451. {
  4452. if (m_pArgs->fRememberInetPassword != fChecked)
  4453. {
  4454. if (fChecked && (FALSE == m_pArgs->fRememberInetPassword))
  4455. {
  4456. //
  4457. // This time around the user wants to save credentials,
  4458. // but before (in main dialog) he didn't want to save anything.
  4459. // Thus we should resave username and domain
  4460. //
  4461. fNeedToResaveUserName = TRUE;
  4462. }
  4463. m_pArgs->fRememberInetPassword = fChecked;
  4464. if (CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4465. {
  4466. SaveUserInfo(m_pArgs,
  4467. UD_ID_REMEMBER_INET_PASSWORD,
  4468. (PVOID)&m_pArgs->fRememberInetPassword);
  4469. }
  4470. }
  4471. }
  4472. else
  4473. {
  4474. if (m_pArgs->fRememberMainPassword != fChecked)
  4475. {
  4476. if (fChecked && (FALSE == m_pArgs->fRememberMainPassword))
  4477. {
  4478. //
  4479. // This time around the user wants to save credentials,
  4480. // but before (in main dialog) he didn't want to save anything.
  4481. // Thus we should resave username and domain
  4482. //
  4483. fNeedToResaveUserName = TRUE;
  4484. fNeedToResaveDomain = TRUE;
  4485. }
  4486. m_pArgs->fRememberMainPassword = fChecked;
  4487. if (CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4488. {
  4489. SaveUserInfo(m_pArgs,
  4490. UD_ID_REMEMBER_PWD,
  4491. (PVOID)&m_pArgs->fRememberMainPassword);
  4492. }
  4493. //
  4494. // There has been a change to main creds, update main display
  4495. //
  4496. CheckDlgButton(m_pArgs->hwndMainDlg,
  4497. IDC_MAIN_NOPASSWORD_CHECKBOX,
  4498. m_pArgs->fRememberMainPassword);
  4499. }
  4500. }
  4501. }
  4502. //
  4503. // If the password field is enabled & the save pw checkbox is unchecked then delete creds.
  4504. // Only if the user is logged on.
  4505. //
  4506. HWND hwndPassword = GetDlgItem(m_hWnd, IDC_RETRY_PASSWORD);
  4507. if (hwndPassword && OS_NT51 && (FALSE == fChecked) && (CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType))
  4508. {
  4509. if (CM_CREDS_GLOBAL == m_pArgs->dwCurrentCredentialType)
  4510. {
  4511. //
  4512. // Since the user has unchecked the 'Save Password' flag and the current credential type is global,
  4513. // we are deleting globals, but we need to save the userinfo into the USER (local) credential store
  4514. // in order for CM to correctly pick up the username and password on next launch.
  4515. //
  4516. fSwitchToUserCredentials = TRUE;
  4517. }
  4518. if (m_fInetCredentials)
  4519. {
  4520. //
  4521. // Unsaving Internet credentials
  4522. // Even if we are using the same username, we shouldn't delete main credentials
  4523. // on this dialog, since we are re-authing for Internet credentials
  4524. //
  4525. if (CM_CREDS_GLOBAL == m_pArgs->dwCurrentCredentialType)
  4526. {
  4527. //
  4528. // Unsaving Internet Global
  4529. //
  4530. //
  4531. // Local Inet shouldn't exist in this case, so we shouldn't delete the Identity,
  4532. // but for globals, we don't support just deleting password. This is from the RAS
  4533. // code base and the delete function actually enforces this.
  4534. //
  4535. if (CM_EXIST_CREDS_INET_GLOBAL & m_pArgs->dwExistingCredentials)
  4536. {
  4537. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_DELETE_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  4538. m_pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_INET_GLOBAL;
  4539. }
  4540. }
  4541. else
  4542. {
  4543. //
  4544. // Unsaving Internet local (user)
  4545. // Even if we are using the same username, we shouldn't delete main credentials
  4546. // on this dialog, since we are just re-authing for Internet password
  4547. //
  4548. if (CM_EXIST_CREDS_INET_USER & m_pArgs->dwExistingCredentials)
  4549. {
  4550. //
  4551. // Internet user credentials exist, so now delete the identity based on if the
  4552. // global inet creds exist
  4553. //
  4554. if (CM_EXIST_CREDS_INET_GLOBAL & m_pArgs->dwExistingCredentials)
  4555. {
  4556. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  4557. }
  4558. else
  4559. {
  4560. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_KEEP_IDENTITY);
  4561. }
  4562. m_pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_INET_USER;
  4563. }
  4564. }
  4565. }
  4566. else
  4567. {
  4568. //
  4569. // ReAuth for Main credentials & Delete main set of credentials
  4570. // Most of this code is taken from a section in TryToDeleteAndSaveCredentials
  4571. // since most of the logic remains the same if the user unchecks the 'Save Password'
  4572. // option on the main dialog, except that here we don't prompt the user.
  4573. // If the user got promted it happened on the main dialog and the creds were either
  4574. // kept or deleted according to his selection. Thus we don't need to ask here.
  4575. //
  4576. //
  4577. // Check which option button is currently selected
  4578. //
  4579. if (CM_CREDS_GLOBAL == m_pArgs->dwCurrentCredentialType)
  4580. {
  4581. //
  4582. // Since global is selected then we actually want to delete both sets of credentials
  4583. //
  4584. if (CM_EXIST_CREDS_MAIN_GLOBAL & m_pArgs->dwExistingCredentials)
  4585. {
  4586. //
  4587. // Delete the global credentials.
  4588. // Note from RAS codebase: Note that we have to delete the global identity
  4589. // as well because we do not support deleting
  4590. // just the global password. This is so that
  4591. // RasSetCredentials can emulate RasSetDialParams.
  4592. //
  4593. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_MAIN, CM_DELETE_SAVED_CREDS_DELETE_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  4594. m_pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_MAIN_GLOBAL;
  4595. }
  4596. if (CM_EXIST_CREDS_INET_GLOBAL & m_pArgs->dwExistingCredentials)
  4597. {
  4598. if (m_pArgs->fUseSameUserName || (FALSE == m_pArgs->fRememberInetPassword))
  4599. {
  4600. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_DELETE_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  4601. m_pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_INET_GLOBAL;
  4602. }
  4603. }
  4604. }
  4605. else
  4606. {
  4607. //
  4608. // Delete the password saved per-user. Keep the user name
  4609. // and domain saved, however unless global credentials exist.
  4610. // Whenever global credential exist, and we are deleting user credentials
  4611. // we must always delete all of the information (identity + password) associated
  4612. // with the user credentials.
  4613. //
  4614. if (CM_EXIST_CREDS_MAIN_USER & m_pArgs->dwExistingCredentials)
  4615. {
  4616. if (CM_EXIST_CREDS_MAIN_GLOBAL & m_pArgs->dwExistingCredentials)
  4617. {
  4618. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_MAIN, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  4619. }
  4620. else
  4621. {
  4622. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_MAIN, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_KEEP_IDENTITY);
  4623. }
  4624. m_pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_MAIN_USER;
  4625. }
  4626. if (CM_EXIST_CREDS_INET_USER & m_pArgs->dwExistingCredentials)
  4627. {
  4628. if (m_pArgs->fUseSameUserName || (FALSE == m_pArgs->fRememberInetPassword))
  4629. {
  4630. if (CM_EXIST_CREDS_INET_GLOBAL & m_pArgs->dwExistingCredentials)
  4631. {
  4632. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_DELETE_IDENTITY);
  4633. }
  4634. else
  4635. {
  4636. DeleteSavedCredentials(m_pArgs, CM_CREDS_TYPE_INET, CM_DELETE_SAVED_CREDS_KEEP_GLOBALS, CM_DELETE_SAVED_CREDS_KEEP_IDENTITY);
  4637. }
  4638. m_pArgs->dwExistingCredentials &= ~CM_EXIST_CREDS_INET_USER;
  4639. }
  4640. }
  4641. }
  4642. }
  4643. }
  4644. if (fSwitchToUserCredentials)
  4645. {
  4646. //
  4647. // Since this flag was set when we deleted global credentials, we need
  4648. // to save the userinfo into the USER (local) credential store
  4649. // in order for CM to correctly pick up the username and password on next launch.
  4650. // We cannnot store userinfo w/o a password in the global store, because the RAS API
  4651. // doesn't support that. (From rasdlg code).
  4652. //
  4653. m_pArgs->dwCurrentCredentialType = CM_CREDS_USER;
  4654. }
  4655. if (hwndPassword)
  4656. {
  4657. pszBuf = CmGetWindowTextAlloc(m_hWnd, IDC_RETRY_PASSWORD);
  4658. if (pszBuf)
  4659. {
  4660. //
  4661. // Process password according to our handling and encoding rules.
  4662. //
  4663. ApplyPasswordHandlingToBuffer(m_pArgs, pszBuf);
  4664. //
  4665. // Password is prepped, update our memory based storage.
  4666. //
  4667. if (m_fInetCredentials)
  4668. {
  4669. lstrcpyU(m_pArgs->szInetPassword, pszBuf);
  4670. CmEncodePassword(m_pArgs->szInetPassword);
  4671. }
  4672. else
  4673. {
  4674. lstrcpyU(m_pArgs->szPassword, pszBuf);
  4675. CmEncodePassword(m_pArgs->szPassword);
  4676. }
  4677. lstrcpyU(m_pArgs->pRasDialParams->szPassword, pszBuf);
  4678. CmEncodePassword(m_pArgs->pRasDialParams->szPassword);
  4679. //
  4680. // Make sure we set the persistent user info store correctly.
  4681. // Blank if save password is not checked or if we aren't using ras
  4682. // cred store. On Win2K+ the creds we marked and deleted so passwords
  4683. // doesn't need to be set to blank.
  4684. //
  4685. if (m_fInetCredentials)
  4686. {
  4687. if (OS_NT5 && m_pArgs->bUseRasCredStore)
  4688. {
  4689. //
  4690. // For Win2K+ we have the ras store. If the checkbox is checked
  4691. // and a user is logged in then we want to save it.
  4692. //
  4693. if (fChecked && CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4694. {
  4695. SaveUserInfo(m_pArgs,
  4696. UD_ID_INET_PASSWORD,
  4697. (PVOID)pszBuf);
  4698. }
  4699. }
  4700. else
  4701. {
  4702. //
  4703. // We don't have to ras cred store so we either save the password
  4704. // or set it to an empty string since deleting marked credentials
  4705. // doesn't do anything on no Win2K+ platforms
  4706. //
  4707. SaveUserInfo(m_pArgs,
  4708. UD_ID_INET_PASSWORD,
  4709. (PVOID) (fChecked ? pszBuf : TEXT("")));
  4710. }
  4711. }
  4712. else
  4713. {
  4714. if (OS_NT5 && m_pArgs->bUseRasCredStore)
  4715. {
  4716. //
  4717. // For Win2K+ we have the ras store. If the checkbox is checked
  4718. // and a user is logged in then we want to save it.
  4719. //
  4720. if (fChecked && CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4721. {
  4722. SaveUserInfo(m_pArgs,
  4723. UD_ID_PASSWORD,
  4724. (PVOID)pszBuf);
  4725. }
  4726. }
  4727. else
  4728. {
  4729. //
  4730. // We don't have to ras cred store so we either save the password
  4731. // or set it to an empty string since deleting marked credentials
  4732. // doesn't do anything on no Win2K+ platforms
  4733. //
  4734. SaveUserInfo(m_pArgs,
  4735. UD_ID_PASSWORD,
  4736. (PVOID) (fChecked ? pszBuf : TEXT("")));
  4737. }
  4738. //
  4739. // If there's been a change to main creds, update main display.
  4740. //
  4741. if (SendMessageU(hwndPassword, EM_GETMODIFY, 0L, 0L))
  4742. {
  4743. SetDlgItemTextU(m_pArgs->hwndMainDlg, IDC_MAIN_PASSWORD_EDIT, pszBuf);
  4744. }
  4745. }
  4746. CmEncodePassword(pszBuf); // Encode before release
  4747. CmFree(pszBuf);
  4748. }
  4749. }
  4750. //
  4751. // Retrieve Domain and copy to CM data store and RasDialParams. We process
  4752. // the domain first because the construction of the username that we hand
  4753. // to RAS depends on it.
  4754. //
  4755. // Note: RAS updates its store whenever the users selects OK. We will too.
  4756. //
  4757. HWND hwndDomain = GetDlgItem(m_hWnd, IDC_RETRY_DOMAIN);
  4758. //
  4759. // If the checkbox is false, the creds were
  4760. // deleted above so we now need to re-save the domain.
  4761. //
  4762. if ((hwndDomain && SendMessageU(hwndDomain, EM_GETMODIFY, 0L, 0L)) ||
  4763. (hwndDomain && FALSE == fChecked) ||
  4764. (hwndDomain && fNeedToResaveDomain))
  4765. {
  4766. pszBuf = CmGetWindowTextAlloc(m_hWnd, IDC_RETRY_DOMAIN);
  4767. if (pszBuf)
  4768. {
  4769. lstrcpyU(m_pArgs->szDomain, pszBuf);
  4770. lstrcpyU(m_pArgs->pRasDialParams->szDomain, pszBuf);
  4771. if (CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4772. {
  4773. SaveUserInfo(m_pArgs, UD_ID_DOMAIN, (PVOID)pszBuf);
  4774. }
  4775. //
  4776. // There has been a change to main creds, update main display
  4777. //
  4778. SetDlgItemTextU(m_pArgs->hwndMainDlg, IDC_MAIN_DOMAIN_EDIT, pszBuf);
  4779. CmFree(pszBuf);
  4780. }
  4781. }
  4782. if (NULL == hwndDomain && FALSE == m_fInetCredentials)
  4783. {
  4784. //
  4785. // The domain field is hidden, but we still need to save the domain info from the
  4786. // pArgs structure in order for us to pre-populate later if it's not internet creds.
  4787. //
  4788. if (CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4789. {
  4790. SaveUserInfo(m_pArgs, UD_ID_DOMAIN, (PVOID)m_pArgs->szDomain);
  4791. }
  4792. }
  4793. //
  4794. // Retrieve UserName and copy to CM data store and the RasDialParams struct
  4795. //
  4796. HWND hwndUsername = GetDlgItem(m_hWnd, IDC_RETRY_USERNAME);
  4797. //
  4798. // If the checkbox is false, the creds were
  4799. // deleted above so we now need to re-save the username.
  4800. //
  4801. if ((hwndUsername && SendMessageU(hwndUsername, EM_GETMODIFY, 0L, 0L)) ||
  4802. (hwndUsername && FALSE == fChecked) ||
  4803. (hwndUsername && fNeedToResaveUserName))
  4804. {
  4805. pszBuf = CmGetWindowTextAlloc(m_hWnd, IDC_RETRY_USERNAME);
  4806. if (pszBuf)
  4807. {
  4808. if (m_fInetCredentials)
  4809. {
  4810. lstrcpyU(m_pArgs->szInetUserName, pszBuf);
  4811. SaveUserInfo(m_pArgs, UD_ID_INET_USERNAME, (PVOID)pszBuf);
  4812. }
  4813. else
  4814. {
  4815. lstrcpyU(m_pArgs->szUserName, pszBuf);
  4816. if (CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4817. {
  4818. SaveUserInfo(m_pArgs, UD_ID_USERNAME, (PVOID)pszBuf);
  4819. }
  4820. //
  4821. // There has been a change to main creds, update main display
  4822. //
  4823. SetDlgItemTextU(m_pArgs->hwndMainDlg, IDC_MAIN_USERNAME_EDIT, pszBuf);
  4824. }
  4825. //
  4826. // We'll need the service file for the current number. If we're actively
  4827. // tunneling, make sure that we get the top-level service files, so we
  4828. // don't pick up any settings from a referenced dial-up service.
  4829. //
  4830. CIni *piniService = NULL;
  4831. BOOL bNeedToFree = FALSE;
  4832. if (IsDialingTunnel(m_pArgs))
  4833. {
  4834. piniService = m_pArgs->piniService;
  4835. }
  4836. else
  4837. {
  4838. piniService = GetAppropriateIniService(m_pArgs, m_pArgs->nDialIdx);
  4839. bNeedToFree = TRUE;
  4840. }
  4841. MYDBGASSERT(piniService);
  4842. if (piniService)
  4843. {
  4844. //
  4845. // Apply suffix, prefix, to username as necessary
  4846. //
  4847. LPTSTR pszTmp = ApplyPrefixSuffixToBufferAlloc(m_pArgs, piniService, pszBuf);
  4848. if (pszTmp)
  4849. {
  4850. //
  4851. // Apply domain to username as necessary. Note that we only want to do this on modem calls,
  4852. // not tunnels.
  4853. //
  4854. LPTSTR pszUsername = NULL;
  4855. if (IsDialingTunnel(m_pArgs))
  4856. {
  4857. lstrcpynU(m_pArgs->pRasDialParams->szUserName, pszTmp, sizeof(m_pArgs->pRasDialParams->szUserName)/sizeof(TCHAR));
  4858. }
  4859. else
  4860. {
  4861. pszUsername = ApplyDomainPrependToBufferAlloc(m_pArgs, piniService, pszTmp, (m_pArgs->aDialInfo[m_pArgs->nDialIdx].szDUN));
  4862. if (pszUsername)
  4863. {
  4864. lstrcpynU(m_pArgs->pRasDialParams->szUserName, pszUsername, sizeof(m_pArgs->pRasDialParams->szUserName)/sizeof(TCHAR));
  4865. }
  4866. }
  4867. CmFree(pszUsername);
  4868. CmFree(pszTmp);
  4869. }
  4870. if (bNeedToFree)
  4871. {
  4872. delete piniService;
  4873. }
  4874. }
  4875. }
  4876. CmFree(pszBuf);
  4877. }
  4878. if (NULL == hwndUsername)
  4879. {
  4880. //
  4881. // The username field is hidden, but we still need to save it
  4882. // in order for us to pre-populate later.
  4883. //
  4884. if (CM_LOGON_TYPE_USER == m_pArgs->dwWinLogonType)
  4885. {
  4886. SaveUserInfo(m_pArgs, UD_ID_USERNAME, (PVOID)m_pArgs->szUserName);
  4887. }
  4888. }
  4889. m_pArgs->fIgnoreChangeNotification = FALSE;
  4890. if (fSwitchToUserCredentials)
  4891. {
  4892. //
  4893. // Now that we saved the user name to the local/user cred store
  4894. // we need to switch the credential type back to global in order
  4895. // to maintain the correct state.
  4896. //
  4897. m_pArgs->dwCurrentCredentialType = CM_CREDS_GLOBAL;
  4898. }
  4899. //
  4900. // Resets the state of the checkboxes
  4901. //
  4902. if (hwndMainDlgSavePW)
  4903. {
  4904. EnableWindow(hwndMainDlgSavePW, fMainDlgSavePWEnabled);
  4905. }
  4906. if (hwndMainDlgDialAutomatically)
  4907. {
  4908. EnableWindow(hwndMainDlgDialAutomatically, fMainDlgDialAutoEnabled);
  4909. }
  4910. //
  4911. // Need to refresh to see which creds exist
  4912. //
  4913. BOOL fReturn = RefreshCredentialTypes(m_pArgs, FALSE);
  4914. //
  4915. // Cleanup state and go.
  4916. //
  4917. m_pArgs->hWndRetryAuthentication = NULL;
  4918. EndDialog(m_hWnd, TRUE);
  4919. }
  4920. //+----------------------------------------------------------------------------
  4921. //
  4922. // Function: CRetryAuthenticationDlg::OnCancel
  4923. //
  4924. // Synopsis: Virtual function. Called upon WM_COMMAND with IDCANCEL
  4925. //
  4926. // Arguments: None
  4927. //
  4928. // Returns: Nothing
  4929. //
  4930. // History: nickball created 03/01/00
  4931. //
  4932. //+----------------------------------------------------------------------------
  4933. void CRetryAuthenticationDlg::OnCancel()
  4934. {
  4935. m_pArgs->hWndRetryAuthentication = NULL;
  4936. EndDialog(m_hWnd, FALSE);
  4937. }
  4938. //+----------------------------------------------------------------------------
  4939. //
  4940. // Function: CRetryAuthenticationDlg::OnOtherCommand
  4941. //
  4942. // Synopsis: Virtual function. Call upon WM_COMMAND with command other than IDOK
  4943. // and IDCANCEL
  4944. //
  4945. // Arguments: WPARAM wParam - wParam of WM_COMMAND
  4946. // LPARAM -
  4947. //
  4948. // Returns: DWORD -
  4949. //
  4950. // History: nickball created 03/01/00
  4951. //
  4952. //+----------------------------------------------------------------------------
  4953. DWORD CRetryAuthenticationDlg::OnOtherCommand(WPARAM wParam, LPARAM)
  4954. {
  4955. switch (LOWORD(wParam))
  4956. {
  4957. case IDC_RETRY_PASSWORD:
  4958. {
  4959. if (HIWORD(wParam) == EN_CHANGE)
  4960. {
  4961. HWND hwndSavePassword = GetDlgItem(m_hWnd, IDC_RETRY_REMEMBER);
  4962. MYDBGASSERT(hwndSavePassword);
  4963. //
  4964. // There has been a change to the password edit control, see
  4965. // if there is any text and set the check-box accordingly.
  4966. //
  4967. if (0 == SendDlgItemMessageU(m_hWnd,
  4968. IDC_RETRY_PASSWORD,
  4969. WM_GETTEXTLENGTH,
  4970. 0,
  4971. 0))
  4972. {
  4973. //
  4974. // No text. If the control is checked, then uncheck it.
  4975. // Also, disable it.
  4976. //
  4977. if (IsDlgButtonChecked(m_hWnd, IDC_RETRY_REMEMBER))
  4978. {
  4979. SendMessageU(hwndSavePassword, BM_SETCHECK, BST_UNCHECKED, 0);
  4980. }
  4981. EnableWindow(hwndSavePassword, FALSE);
  4982. }
  4983. else
  4984. {
  4985. //
  4986. // There is data, if disabled, then enable appropriately
  4987. //
  4988. if (FALSE == IsWindowEnabled(GetDlgItem(m_hWnd, IDC_RETRY_REMEMBER)))
  4989. {
  4990. EnableWindow(GetDlgItem(m_hWnd, IDC_RETRY_REMEMBER), TRUE);
  4991. }
  4992. }
  4993. break;
  4994. }
  4995. }
  4996. }
  4997. return FALSE;
  4998. }
  4999. //+----------------------------------------------------------------------------
  5000. //
  5001. // Function: CRetryAuthenticationDlg::GetDlgTemplate
  5002. //
  5003. // Synopsis: Encapsulates determining which template is to be used
  5004. // for the Retry dialog. Same model a MainDlg, but the
  5005. // determinants are slightly different as the dialog proc
  5006. // and templates serve double-duty for Inet and VPN.
  5007. //
  5008. // Arguments: ArgsStruct *pArgs - Ptr to global Args struct
  5009. //
  5010. // Returns: UINT - Dlg template ID.
  5011. //
  5012. // History: nickball Created 03/04/00
  5013. //
  5014. //+----------------------------------------------------------------------------
  5015. UINT CRetryAuthenticationDlg::GetDlgTemplate()
  5016. {
  5017. MYDBGASSERT(m_pArgs);
  5018. //
  5019. // First set the mask according to the .CMS flags for each value.
  5020. //
  5021. UINT uiMainDlgID = 0;
  5022. DWORD dwTemplateMask = 0;
  5023. //
  5024. // If Inet and not UseSameUserName, then honor Inet flags for Username
  5025. //
  5026. if (m_fInetCredentials)
  5027. {
  5028. if (!m_pArgs->fHideInetUsername)
  5029. {
  5030. dwTemplateMask |= CMTM_UID;
  5031. }
  5032. }
  5033. else
  5034. {
  5035. //
  5036. // Otherwise, the main Username display rules apply.
  5037. //
  5038. if (!m_pArgs->fHideUserName)
  5039. {
  5040. dwTemplateMask |= CMTM_UID;
  5041. }
  5042. }
  5043. //
  5044. // If Inet and not UseSameUserName, then honor Inet flags for password
  5045. //
  5046. if (m_fInetCredentials)
  5047. {
  5048. if (!m_pArgs->fHideInetPassword)
  5049. {
  5050. dwTemplateMask |= CMTM_PWD;
  5051. }
  5052. }
  5053. else
  5054. {
  5055. //
  5056. // Otherwise, the main password display rules apply.
  5057. //
  5058. if (!m_pArgs->fHidePassword)
  5059. {
  5060. dwTemplateMask |= CMTM_PWD;
  5061. }
  5062. }
  5063. //
  5064. // Previously, the OS was the determinant for domain display.
  5065. // Nowadays, we want to display a domain when:
  5066. //
  5067. // a) Its not a straight Inet dial
  5068. //
  5069. // AND
  5070. //
  5071. // b) The domain field is not explicitly hidden
  5072. //
  5073. if (!m_fInetCredentials && !m_pArgs->fHideDomain)
  5074. {
  5075. dwTemplateMask |= CMTM_DMN;
  5076. }
  5077. switch (dwTemplateMask)
  5078. {
  5079. case CMTM_U_P_D:
  5080. uiMainDlgID = IDD_RETRY_UID_PWD_DMN;
  5081. break;
  5082. case CMTM_UID:
  5083. uiMainDlgID = IDD_RETRY_UID_ONLY;
  5084. break;
  5085. case CMTM_PWD:
  5086. uiMainDlgID = IDD_RETRY_PWD_ONLY;
  5087. break;
  5088. case CMTM_DMN:
  5089. uiMainDlgID = IDD_RETRY_DMN_ONLY;
  5090. break;
  5091. case CMTM_UID_AND_PWD:
  5092. uiMainDlgID = IDD_RETRY_UID_AND_PWD;
  5093. break;
  5094. case CMTM_UID_AND_DMN:
  5095. uiMainDlgID = IDD_RETRY_UID_AND_DMN;
  5096. break;
  5097. case CMTM_PWD_AND_DMN:
  5098. uiMainDlgID = IDD_RETRY_PWD_AND_DMN;
  5099. break;
  5100. default:
  5101. MYDBGASSERT(FALSE);
  5102. uiMainDlgID = 0;
  5103. break;
  5104. }
  5105. return uiMainDlgID;
  5106. }
  5107. //+----------------------------------------------------------------------------
  5108. //
  5109. // Func: AccessPointInfoChanged
  5110. //
  5111. // Desc: Checks all the controls to determine if any changes have been made
  5112. //
  5113. // Args: NONE
  5114. //
  5115. // Return: BOOL - True if any information has changed
  5116. //
  5117. // Notes:
  5118. //
  5119. // History: t-urama 07/31/2000 Created
  5120. //-----------------------------------------------------------------------------
  5121. BOOL CGeneralPage::AccessPointInfoChanged()
  5122. {
  5123. if (m_bAPInfoChanged)
  5124. {
  5125. return TRUE;
  5126. }
  5127. if (0 != SendDlgItemMessageU(m_hWnd, IDC_GENERAL_PRIMARY_EDIT, EM_GETMODIFY, 0, 0))
  5128. {
  5129. return TRUE;
  5130. }
  5131. if (0 != SendDlgItemMessageU(m_hWnd, IDC_GENERAL_BACKUP_EDIT, EM_GETMODIFY, 0, 0))
  5132. {
  5133. return TRUE;
  5134. }
  5135. return FALSE;
  5136. }
  5137. //+----------------------------------------------------------------------------
  5138. //
  5139. // Func: CGeneralPage::DeleteAccessPoint
  5140. //
  5141. // Desc: Handler for the delete Access Point button
  5142. //
  5143. // Args: NONE
  5144. //
  5145. // Return: NONE
  5146. //
  5147. // Notes:
  5148. //
  5149. // History: t-urama 07/31/2000 Created
  5150. //-----------------------------------------------------------------------------
  5151. void CGeneralPage::DeleteAccessPoint()
  5152. {
  5153. // Now try to delete the key for the access point from the registry
  5154. LPTSTR pszRegPath = BuildUserInfoSubKey(m_pArgs->szServiceName, m_pArgs->fAllUser);
  5155. MYDBGASSERT(pszRegPath);
  5156. if (NULL == pszRegPath)
  5157. {
  5158. return;
  5159. }
  5160. CmStrCatAlloc(&pszRegPath, TEXT("\\"));
  5161. CmStrCatAlloc(&pszRegPath, c_pszRegKeyAccessPoints);
  5162. CmStrCatAlloc(&pszRegPath, TEXT("\\"));
  5163. MYDBGASSERT(pszRegPath);
  5164. if (NULL == pszRegPath)
  5165. {
  5166. return;
  5167. }
  5168. CmStrCatAlloc(&pszRegPath, m_pArgs->pszCurrentAccessPoint);
  5169. MYDBGASSERT(pszRegPath);
  5170. if (NULL == pszRegPath)
  5171. {
  5172. return;
  5173. }
  5174. if (pszRegPath)
  5175. {
  5176. DWORD dwRes;
  5177. HKEY hKeyCm;
  5178. dwRes = RegOpenKeyExU(HKEY_CURRENT_USER,
  5179. pszRegPath,
  5180. 0,
  5181. KEY_ALL_ACCESS,
  5182. &hKeyCm);
  5183. if (ERROR_SUCCESS == dwRes)
  5184. {
  5185. RegCloseKey(hKeyCm);
  5186. dwRes = RegDeleteKeyU(HKEY_CURRENT_USER, pszRegPath);
  5187. if (ERROR_SUCCESS != dwRes)
  5188. {
  5189. CMTRACE1(TEXT("Delete AP failed, GLE=%d"), GetLastError());
  5190. }
  5191. else
  5192. {
  5193. CMTRACE1(TEXT("Deleted Access Point - %s"), m_pArgs->pszCurrentAccessPoint);
  5194. }
  5195. // First delete the Accesspoint from the combo box and load the new settings
  5196. DWORD dwIdx = (DWORD)SendDlgItemMessageU(m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO, CB_GETCURSEL, 0, 0);
  5197. if (CB_ERR != dwIdx)
  5198. {
  5199. if (0 == dwIdx)
  5200. {
  5201. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO, CB_SETCURSEL, dwIdx+1, 0);
  5202. }
  5203. else
  5204. {
  5205. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO, CB_SETCURSEL, dwIdx-1, 0);
  5206. }
  5207. if (ChangedAccessPoint(m_pArgs, m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO))
  5208. {
  5209. UpdateForNewAccessPoint(TRUE);
  5210. }
  5211. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO, CB_DELETESTRING, dwIdx, 0);
  5212. }
  5213. //
  5214. // If the number of APs becomes 1, then make the AccessPointsEnabled Flag FAlSE
  5215. //
  5216. DWORD dwCnt = (DWORD)SendDlgItemMessageU(m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO, CB_GETCOUNT, 0, 0);
  5217. if (dwCnt == 1)
  5218. {
  5219. m_pArgs->fAccessPointsEnabled = FALSE;
  5220. WriteUserInfoToReg(m_pArgs, UD_ID_ACCESSPOINTENABLED, (PVOID) &m_pArgs->fAccessPointsEnabled);
  5221. WriteUserInfoToReg(m_pArgs, UD_ID_CURRENTACCESSPOINT, (PVOID) m_pArgs->pszCurrentAccessPoint);
  5222. }
  5223. }
  5224. CmFree(pszRegPath);
  5225. }
  5226. }
  5227. //+----------------------------------------------------------------------------
  5228. //
  5229. // Function: CNewAccessPointDlg::OnInitDialog
  5230. //
  5231. // Synopsis: Virtual function. Call upon WM_INITDIALOG message to intialize
  5232. // the dialog.
  5233. //
  5234. // Arguments: None
  5235. //
  5236. // Returns: BOOL - Return value of WM_INITDIALOG
  5237. //
  5238. // History: t-urama created 08/02/00
  5239. //
  5240. //+----------------------------------------------------------------------------
  5241. BOOL CNewAccessPointDlg::OnInitDialog()
  5242. {
  5243. SetForegroundWindow(m_hWnd);
  5244. //
  5245. // Brand the dialog
  5246. //
  5247. LPTSTR pszTitle = CmStrCpyAlloc(m_pArgs->szServiceName);
  5248. MYDBGASSERT(pszTitle);
  5249. if (pszTitle)
  5250. {
  5251. SetWindowTextU(m_hWnd, pszTitle);
  5252. }
  5253. CmFree(pszTitle);
  5254. if (m_pArgs->hSmallIcon)
  5255. {
  5256. SendMessageU(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM) m_pArgs->hSmallIcon);
  5257. }
  5258. if (m_pArgs->hBigIcon)
  5259. {
  5260. SendMessageU(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM) m_pArgs->hBigIcon);
  5261. SendMessageU(GetDlgItem(m_hWnd, IDC_INET_ICON), STM_SETIMAGE, IMAGE_ICON, (LPARAM) m_pArgs->hBigIcon);
  5262. }
  5263. UpdateFont(m_hWnd);
  5264. EnableWindow(GetDlgItem(m_hWnd, IDOK), FALSE);
  5265. HWND hwndEdit = GetDlgItem(m_hWnd, IDC_NEWAP_NAME_EDIT);
  5266. if (hwndEdit)
  5267. {
  5268. //
  5269. // Subclass the edit control
  5270. //
  5271. m_pfnOrgEditWndProc = (WNDPROC)SetWindowLongU(hwndEdit, GWLP_WNDPROC, (LONG_PTR)SubClassEditProc);
  5272. //
  5273. // Set focus to the edit control
  5274. //
  5275. SetFocus(hwndEdit);
  5276. //
  5277. // Limit the text length of the control
  5278. //
  5279. SendMessageU(hwndEdit, EM_SETLIMITTEXT, MAX_ACCESSPOINT_LENGTH, 0);
  5280. }
  5281. //
  5282. // Must return FALSE when setting focus
  5283. //
  5284. return FALSE;
  5285. }
  5286. //+----------------------------------------------------------------------------
  5287. //
  5288. // Function: CNewAccessPointDlg::SubClassEditProc
  5289. //
  5290. // Synopsis: Subclassed edit proc so that back slash chars can be prevented from
  5291. // being entered into the new access point name edit control.
  5292. //
  5293. // Arguments: standard win32 window proc params
  5294. //
  5295. // Returns: standard win32 window proc return value
  5296. //
  5297. // History: quintinb created 08/22/00
  5298. //
  5299. //+----------------------------------------------------------------------------
  5300. LRESULT CALLBACK CNewAccessPointDlg::SubClassEditProc(HWND hwnd, UINT uMsg,
  5301. WPARAM wParam, LPARAM lParam)
  5302. {
  5303. //
  5304. // If user types a back slash character, Beep and do not accept that character
  5305. //
  5306. if ((uMsg == WM_CHAR) && (VK_BACK != wParam))
  5307. {
  5308. if (TEXT('\\') == (TCHAR)wParam)
  5309. {
  5310. Beep(2000, 100);
  5311. return 0;
  5312. }
  5313. }
  5314. //
  5315. // Call the original window procedure for default processing.
  5316. //
  5317. return CallWindowProcU(m_pfnOrgEditWndProc, hwnd, uMsg, wParam, lParam);
  5318. }
  5319. //+----------------------------------------------------------------------------
  5320. //
  5321. // Function: CNewAccessPointDlg::OnOK
  5322. //
  5323. // Synopsis: Virtual function. Call when user hits the OK button
  5324. //
  5325. // Arguments: None
  5326. //
  5327. // Returns: None
  5328. //
  5329. // History: t-urama created 08/02/00
  5330. //
  5331. //+----------------------------------------------------------------------------
  5332. void CNewAccessPointDlg::OnOK()
  5333. {
  5334. LPTSTR pszNewAPName = CmGetWindowTextAlloc(m_hWnd, IDC_NEWAP_NAME_EDIT);
  5335. MYDBGASSERT(pszNewAPName);
  5336. if (pszNewAPName && TEXT('\0') != pszNewAPName[0])
  5337. {
  5338. if (m_ppszAPName)
  5339. {
  5340. CmFree(*m_ppszAPName);
  5341. *m_ppszAPName = pszNewAPName;
  5342. }
  5343. EndDialog(m_hWnd, TRUE);
  5344. }
  5345. else
  5346. {
  5347. CmFree(pszNewAPName);
  5348. }
  5349. }
  5350. //+----------------------------------------------------------------------------
  5351. //
  5352. // Function: CNewAccessPointDlg::OnOtherCommand
  5353. //
  5354. // Synopsis: Virtual function. Enables the OK button once the user enters
  5355. // a name for the Access Point
  5356. //
  5357. // Arguments: None
  5358. //
  5359. // Returns: None
  5360. //
  5361. // History: t-urama created 08/02/00
  5362. //
  5363. //+----------------------------------------------------------------------------
  5364. DWORD CNewAccessPointDlg::OnOtherCommand(WPARAM wParam, LPARAM)
  5365. {
  5366. switch (LOWORD(wParam))
  5367. {
  5368. case IDC_NEWAP_NAME_EDIT:
  5369. {
  5370. HWND hwndEdit = GetDlgItem(m_hWnd, IDC_NEWAP_NAME_EDIT);
  5371. if (hwndEdit)
  5372. {
  5373. size_t nLen = GetWindowTextLengthU(hwndEdit);
  5374. HWND hwndOK = GetDlgItem(m_hWnd, IDOK);
  5375. if (nLen > 0)
  5376. {
  5377. EnableWindow(hwndOK, TRUE);
  5378. }
  5379. else
  5380. {
  5381. EnableWindow(hwndOK, FALSE);
  5382. }
  5383. }
  5384. }
  5385. break;
  5386. }
  5387. return FALSE;
  5388. }
  5389. //+----------------------------------------------------------------------------
  5390. //
  5391. // Func: CGeneralPage::AddNewAPToReg
  5392. //
  5393. // Desc: Adds an AP under the Access Points key in the registry and also to the
  5394. // combo box
  5395. //
  5396. // Args: LPTSTR pszNewAPName - New access point name to add
  5397. // BOOL fRefreshUiWwithCurrentValues - overwrite the values currently in UI dlg boxes
  5398. //
  5399. // Return: Nothing
  5400. //
  5401. // Notes:
  5402. //
  5403. // History: t-urama 07/31/2000 Created
  5404. //-----------------------------------------------------------------------------
  5405. void CGeneralPage::AddNewAPToReg(LPTSTR pszNewAPName, BOOL fRefreshUiWwithCurrentValues)
  5406. {
  5407. MYDBGASSERT(pszNewAPName);
  5408. if (!pszNewAPName)
  5409. {
  5410. return;
  5411. }
  5412. LPTSTR pszNewAPNameTmp = CmStrCpyAlloc(pszNewAPName);
  5413. DWORD dwIdx = (DWORD)SendDlgItemMessageU(m_hWnd,
  5414. IDC_GENERAL_ACCESSPOINT_COMBO,
  5415. CB_FINDSTRINGEXACT,
  5416. 0,
  5417. (LPARAM)pszNewAPName);
  5418. if (CB_ERR != dwIdx)
  5419. {
  5420. UINT iSuffix = 1;
  5421. TCHAR szAPNameTemp[MAX_PATH + 10];
  5422. do
  5423. {
  5424. wsprintfU(szAPNameTemp, TEXT("%s%u"), pszNewAPNameTmp, iSuffix);
  5425. dwIdx = (DWORD)SendDlgItemMessageU(m_hWnd,
  5426. IDC_GENERAL_ACCESSPOINT_COMBO,
  5427. CB_FINDSTRINGEXACT,
  5428. 0,
  5429. (LPARAM)szAPNameTemp);
  5430. iSuffix++;
  5431. } while(dwIdx != CB_ERR);
  5432. CmFree(pszNewAPNameTmp);
  5433. pszNewAPNameTmp = CmStrCpyAlloc(szAPNameTemp);
  5434. }
  5435. MYDBGASSERT(pszNewAPNameTmp);
  5436. if (pszNewAPNameTmp)
  5437. {
  5438. LPTSTR pszRegPath = BuildUserInfoSubKey(m_pArgs->szServiceName, m_pArgs->fAllUser);
  5439. MYDBGASSERT(pszRegPath);
  5440. if (NULL == pszRegPath)
  5441. {
  5442. return;
  5443. }
  5444. CmStrCatAlloc(&pszRegPath, TEXT("\\"));
  5445. CmStrCatAlloc(&pszRegPath, c_pszRegKeyAccessPoints);
  5446. CmStrCatAlloc(&pszRegPath, TEXT("\\"));
  5447. MYDBGASSERT(pszRegPath);
  5448. if (NULL == pszRegPath)
  5449. {
  5450. return;
  5451. }
  5452. CmStrCatAlloc(&pszRegPath,pszNewAPNameTmp);
  5453. MYDBGASSERT(pszRegPath);
  5454. if (NULL == pszRegPath)
  5455. {
  5456. return;
  5457. }
  5458. if (pszRegPath)
  5459. {
  5460. DWORD dwRes;
  5461. HKEY hKeyCm;
  5462. DWORD dwDisposition;
  5463. dwRes = RegCreateKeyExU(HKEY_CURRENT_USER,
  5464. pszRegPath,
  5465. 0,
  5466. TEXT(""),
  5467. REG_OPTION_NON_VOLATILE,
  5468. KEY_ALL_ACCESS,
  5469. NULL,
  5470. &hKeyCm,
  5471. &dwDisposition);
  5472. if (ERROR_SUCCESS == dwRes)
  5473. {
  5474. dwRes = (DWORD)SendDlgItemMessageU(m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO, CB_ADDSTRING,
  5475. 0, (LPARAM)pszNewAPNameTmp);
  5476. if (CB_ERR != dwRes)
  5477. {
  5478. CMTRACE1(TEXT("Added new Access point - %s"), pszNewAPNameTmp);
  5479. SendDlgItemMessageU(m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO, CB_SETCURSEL, (WPARAM)dwRes, 0L);
  5480. if (ChangedAccessPoint(m_pArgs, m_hWnd, IDC_GENERAL_ACCESSPOINT_COMBO))
  5481. {
  5482. this->UpdateForNewAccessPoint(fRefreshUiWwithCurrentValues);
  5483. }
  5484. //
  5485. // if access points are enabled for the first time, make the AccessPointsEnabled flag TRUE
  5486. //
  5487. if (!m_pArgs->fAccessPointsEnabled)
  5488. {
  5489. m_pArgs->fAccessPointsEnabled = TRUE;
  5490. WriteUserInfoToReg(m_pArgs, UD_ID_ACCESSPOINTENABLED, (PVOID) &m_pArgs->fAccessPointsEnabled);
  5491. }
  5492. }
  5493. RegCloseKey(hKeyCm);
  5494. }
  5495. }
  5496. CmFree(pszRegPath);
  5497. }
  5498. CmFree(pszNewAPNameTmp);
  5499. }
  5500. //
  5501. // Help id pairs
  5502. //
  5503. const DWORD CVpnPage::m_dwHelp[] = {
  5504. IDC_VPN_SEL_COMBO, IDH_VPN_SELECTOR,
  5505. 0,0};
  5506. //+----------------------------------------------------------------------------
  5507. //
  5508. // Func: CVpnPage::CVpnPage
  5509. //
  5510. // Desc: Constructor for the CVpnPage class.
  5511. //
  5512. // Args: ArgsStruct* pArgs - pointer to the Args structure
  5513. // UINT nIDTemplate - template ID of the VPN page, passed to its parent
  5514. //
  5515. // Return: Nothing
  5516. //
  5517. // Notes:
  5518. //
  5519. // History: quintinb 11/01/2000 Created
  5520. //-----------------------------------------------------------------------------
  5521. CVpnPage::CVpnPage(ArgsStruct* pArgs, UINT nIDTemplate)
  5522. : CPropertiesPage(nIDTemplate, m_dwHelp, pArgs->pszHelpFile)
  5523. {
  5524. MYDBGASSERT(pArgs);
  5525. m_pArgs = pArgs;
  5526. }
  5527. //+----------------------------------------------------------------------------
  5528. //
  5529. // Func: CVpnPage::OnInitDialog
  5530. //
  5531. // Desc: Handles the WM_INITDLG processing for the VPN page of the CM
  5532. // property sheet. Basically fills the VPN message text, fills the
  5533. // VPN selector combo and selects an item in the list as necessary.
  5534. //
  5535. // Args: None
  5536. //
  5537. // Return: BOOL - TRUE if it initialized successfully.
  5538. //
  5539. // Notes:
  5540. //
  5541. // History: quintinb 11/01/2000 Created
  5542. //-----------------------------------------------------------------------------
  5543. BOOL CVpnPage::OnInitDialog()
  5544. {
  5545. if (m_pArgs->pszVpnFile)
  5546. {
  5547. //
  5548. // Add the VPN friendly names to the combo
  5549. //
  5550. AddAllKeysInCurrentSectionToCombo(m_hWnd, IDC_VPN_SEL_COMBO, c_pszCmSectionVpnServers, m_pArgs->pszVpnFile);
  5551. //
  5552. // Now we need to select a friendly name in the combo box if the user has already selected something or
  5553. // if the user has yet to select something but their Admin specified a default.
  5554. //
  5555. LPTSTR pszDefault = m_pArgs->piniBothNonFav->GPPS(c_pszCmSection, c_pszCmEntryTunnelDesc);
  5556. if ((NULL == pszDefault) || (TEXT('\0') == pszDefault[0]))
  5557. {
  5558. CmFree(pszDefault);
  5559. pszDefault = GetPrivateProfileStringWithAlloc(c_pszCmSectionSettings, c_pszCmEntryVpnDefault, TEXT(""), m_pArgs->pszVpnFile);
  5560. }
  5561. if (pszDefault && pszDefault[0])
  5562. {
  5563. LONG_PTR lPtr = SendDlgItemMessageU(m_hWnd, IDC_VPN_SEL_COMBO, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)pszDefault);
  5564. if (CB_ERR != lPtr)
  5565. {
  5566. SendDlgItemMessageU(m_hWnd, IDC_VPN_SEL_COMBO, CB_SETCURSEL, (WPARAM)lPtr, (LPARAM)0);
  5567. }
  5568. }
  5569. CmFree(pszDefault);
  5570. //
  5571. // If the Admin specified a message, let's read that and set the static text control
  5572. //
  5573. LPTSTR pszMessage = GetPrivateProfileStringWithAlloc(c_pszCmSectionSettings, c_pszCmEntryVpnMessage, TEXT(""), m_pArgs->pszVpnFile);
  5574. if (pszMessage && pszMessage[0])
  5575. {
  5576. SendDlgItemMessageU(m_hWnd, IDC_VPN_MSG, WM_SETTEXT, (WPARAM)0, (LPARAM)pszMessage);
  5577. }
  5578. CmFree(pszMessage);
  5579. }
  5580. return TRUE;
  5581. }
  5582. //+----------------------------------------------------------------------------
  5583. //
  5584. // Func: CVpnPage::OnApply
  5585. //
  5586. // Desc: Called when the user hits the OK button for the CM property sheet.
  5587. // Handles saving the VPN server address and DUN setting name.
  5588. //
  5589. // Args: None
  5590. //
  5591. // Return: Nothing
  5592. //
  5593. // Notes:
  5594. //
  5595. // History: quintinb 11/01/2000 Created
  5596. //-----------------------------------------------------------------------------
  5597. void CVpnPage::OnApply()
  5598. {
  5599. //
  5600. // Okay, let's figure out what the user selected in the combo
  5601. //
  5602. LONG_PTR lPtr = SendDlgItemMessageU(m_hWnd, IDC_VPN_SEL_COMBO, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
  5603. if (CB_ERR != lPtr)
  5604. {
  5605. LONG_PTR lTextLen = SendDlgItemMessageU(m_hWnd, IDC_VPN_SEL_COMBO, CB_GETLBTEXTLEN, (WPARAM)lPtr, (LPARAM)0);
  5606. if (CB_ERR != lTextLen)
  5607. {
  5608. LPTSTR pszFriendlyName = (LPTSTR)CmMalloc(sizeof(TCHAR)*(lTextLen+1));
  5609. if (pszFriendlyName)
  5610. {
  5611. lPtr = SendDlgItemMessageU(m_hWnd, IDC_VPN_SEL_COMBO, CB_GETLBTEXT, (WPARAM)lPtr, (LPARAM)pszFriendlyName);
  5612. if (CB_ERR != lPtr)
  5613. {
  5614. //
  5615. // Write the friendly name as the TunnelDesc
  5616. //
  5617. m_pArgs->piniBothNonFav->WPPS(c_pszCmSection, c_pszCmEntryTunnelDesc, pszFriendlyName);
  5618. //
  5619. // Now get the actual data and write it
  5620. //
  5621. LPTSTR pszVpnAddress = GetPrivateProfileStringWithAlloc(c_pszCmSectionVpnServers, pszFriendlyName, TEXT(""), m_pArgs->pszVpnFile);
  5622. //
  5623. // Now parse the line into the server name/IP and the DUN name if it exists.
  5624. //
  5625. if (pszVpnAddress)
  5626. {
  5627. LPTSTR pszVpnSetting = CmStrchr(pszVpnAddress, TEXT(','));
  5628. if (pszVpnSetting)
  5629. {
  5630. *pszVpnSetting = TEXT('\0');
  5631. pszVpnSetting++;
  5632. CmStrTrim(pszVpnSetting);
  5633. } // else it is NULL and we want to clear the existing key if it exists.
  5634. m_pArgs->piniBothNonFav->WPPS(c_pszCmSection, c_pszCmEntryTunnelDun, pszVpnSetting);
  5635. CmStrTrim(pszVpnAddress);
  5636. m_pArgs->piniBothNonFav->WPPS(c_pszCmSection, c_pszCmEntryTunnelAddress, pszVpnAddress);
  5637. }
  5638. else
  5639. {
  5640. CMASSERTMSG(FALSE, TEXT("CVpnPage::OnApply -- GetPrivateProfileStringWithAlloc failed for pszVpnAddress"));
  5641. }
  5642. CmFree(pszVpnAddress);
  5643. }
  5644. }
  5645. else
  5646. {
  5647. CMASSERTMSG(FALSE, TEXT("CVpnPage::OnApply -- CmMalloc failed for pszFriendlyName"));
  5648. }
  5649. CmFree(pszFriendlyName);
  5650. }
  5651. }
  5652. }