Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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