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.

2093 lines
54 KiB

  1. /* Copyright (c) 1995, Microsoft Corporation, all rights reserved
  2. **
  3. ** pref.c
  4. ** Remote Access Common Dialog APIs
  5. ** User Preferences property sheet
  6. **
  7. ** 08/22/95 Steve Cobb
  8. */
  9. #include "rasdlgp.h"
  10. #include "pref.h"
  11. /* Page definitions.
  12. */
  13. #define UP_AdPage 0
  14. #define UP_CbPage 1
  15. #define UP_DgPage 2
  16. //#define UP_GpPage 2
  17. //#define UP_PlPage 3
  18. // For whistler 460931 gangz
  19. //
  20. #define UP_PageCount 3 //2
  21. /*----------------------------------------------------------------------------
  22. ** Help maps
  23. **----------------------------------------------------------------------------
  24. */
  25. static DWORD g_adwAdHelp[] =
  26. {
  27. CID_AD_ST_Enable, HID_AD_LV_Enable,
  28. CID_AD_LV_Enable, HID_AD_LV_Enable,
  29. CID_AD_CB_AskBeforeAutodial, HID_AD_CB_AskBeforeAutodial,
  30. CID_AD_CB_AskBeforeAutodial, HID_AD_CB_AskBeforeAutodial,
  31. CID_AD_CB_DisableThisSession, HID_AD_CB_DisableThisSession,
  32. 0, 0
  33. };
  34. static DWORD g_adwCbHelp[] =
  35. {
  36. CID_CB_RB_No, HID_CB_RB_No,
  37. CID_CB_RB_Maybe, HID_CB_RB_Maybe,
  38. CID_CB_RB_Yes, HID_CB_RB_Yes,
  39. CID_CB_LV_Numbers, HID_CB_LV_Numbers,
  40. CID_CB_PB_Edit, HID_CB_PB_Edit,
  41. CID_CB_PB_Delete, HID_CB_PB_Delete,
  42. 0, 0
  43. };
  44. static DWORD g_adwCoHelp[] =
  45. {
  46. CID_CO_GB_LogonPrivileges, HID_CO_GB_LogonPrivileges,
  47. CID_CO_ST_AllowConnectionModification, HID_CO_CB_AllowConnectionModification,
  48. CID_CO_CB_AllowConnectionModification, HID_CO_CB_AllowConnectionModification,
  49. 0, 0
  50. };
  51. static DWORD g_adwPlHelp[] =
  52. {
  53. CID_PL_ST_Open, HID_PL_ST_Open,
  54. CID_PL_RB_SystemList, HID_PL_RB_SystemList,
  55. CID_PL_RB_PersonalList, HID_PL_RB_PersonalList,
  56. CID_PL_RB_AlternateList, HID_PL_RB_AlternateList,
  57. CID_PL_CL_Lists, HID_PL_CL_Lists,
  58. CID_PL_PB_Browse, HID_PL_PB_Browse,
  59. 0, 0
  60. };
  61. /*----------------------------------------------------------------------------
  62. ** Local prototypes (alphabetically)
  63. **----------------------------------------------------------------------------
  64. */
  65. VOID
  66. AdApply(
  67. IN UPINFO* pInfo );
  68. INT_PTR CALLBACK
  69. AdDlgProc(
  70. IN HWND hwnd,
  71. IN UINT unMsg,
  72. IN WPARAM wparam,
  73. IN LPARAM lparam );
  74. BOOL
  75. AdFillLvEnable(
  76. IN UPINFO* pInfo );
  77. BOOL
  78. AdInit(
  79. IN HWND hwndPage,
  80. IN OUT UPARGS* pArgs );
  81. LVXDRAWINFO*
  82. AdLvEnableCallback(
  83. IN HWND hwndLv,
  84. IN DWORD dwItem );
  85. VOID
  86. CbApply(
  87. IN UPINFO* pInfo );
  88. void DgApply(
  89. IN UPINFO* pInfo );
  90. BOOL
  91. CbCommand(
  92. IN UPINFO* pInfo,
  93. IN WORD wNotification,
  94. IN WORD wId,
  95. IN HWND hwndCtrl );
  96. INT_PTR CALLBACK
  97. CbDlgProc(
  98. IN HWND hwnd,
  99. IN UINT unMsg,
  100. IN WPARAM wparam,
  101. IN LPARAM lparam );
  102. BOOL
  103. CbInit(
  104. IN HWND hwndPage );
  105. VOID
  106. CbUpdateLvAndPbState(
  107. IN UPINFO* pInfo );
  108. BOOL
  109. CoApply(
  110. IN UPINFO* pInfo );
  111. INT_PTR CALLBACK
  112. CoDlgProc(
  113. IN HWND hwnd,
  114. IN UINT unMsg,
  115. IN WPARAM wparam,
  116. IN LPARAM lparam );
  117. BOOL
  118. CoInit(
  119. IN HWND hwndPage,
  120. IN OUT UPARGS* pArgs );
  121. VOID
  122. GpApply(
  123. IN UPINFO* pInfo );
  124. BOOL
  125. GpCommand(
  126. IN UPINFO* pInfo,
  127. IN WORD wNotification,
  128. IN WORD wId,
  129. IN HWND hwndCtrl );
  130. INT_PTR CALLBACK
  131. GpDlgProc(
  132. IN HWND hwnd,
  133. IN UINT unMsg,
  134. IN WPARAM wparam,
  135. IN LPARAM lparam );
  136. BOOL
  137. GpInit(
  138. IN HWND hwndPage );
  139. VOID
  140. GpUpdateCbStates(
  141. IN UPINFO* pInfo );
  142. BOOL
  143. PlApply(
  144. IN UPINFO* pInfo );
  145. VOID
  146. PlBrowse(
  147. IN UPINFO* pInfo );
  148. BOOL
  149. PlCommand(
  150. IN UPINFO* pInfo,
  151. IN WORD wNotification,
  152. IN WORD wId,
  153. IN HWND hwndCtrl );
  154. INT_PTR CALLBACK
  155. PlDlgProc(
  156. IN HWND hwnd,
  157. IN UINT unMsg,
  158. IN WPARAM wparam,
  159. IN LPARAM lparam );
  160. BOOL
  161. PlInit(
  162. IN HWND hwndPage );
  163. BOOL
  164. UpApply(
  165. IN HWND hwndPage );
  166. VOID
  167. UpCancel(
  168. IN HWND hwndPage );
  169. VOID
  170. UpExit(
  171. IN UPINFO* pInfo );
  172. UPINFO*
  173. UpInit(
  174. IN HWND hwndFirstPage,
  175. IN UPARGS* pArgs );
  176. VOID
  177. UpTerm(
  178. IN HWND hwndPage );
  179. // Allows the editing of ras user preferences
  180. DWORD
  181. APIENTRY
  182. RasUserPrefsDlgInternal (
  183. HWND hwndParent,
  184. DWORD dwFlags);
  185. // For whistler 460931
  186. BOOL CALLBACK PrefDisableAllChildWindows(
  187. IN HWND hwnd, // handle to child window
  188. IN LPARAM lParam )
  189. {
  190. BOOL fEnable = (BOOL)lParam;
  191. EnableWindow( hwnd, fEnable);
  192. return TRUE;
  193. }
  194. /*----------------------------------------------------------------------------
  195. ** User Preferences property sheet entry point
  196. **----------------------------------------------------------------------------
  197. */
  198. BOOL
  199. UserPreferencesDlg(
  200. IN HLINEAPP hlineapp,
  201. IN HWND hwndOwner,
  202. IN DWORD dwFlags,
  203. OUT PBUSER* pUser,
  204. OUT PBFILE** ppFile )
  205. /* Pops up the User Preferences property sheet, reading and storing the
  206. ** result in the USER registry. 'HwndOwner' is the handle of the owning
  207. ** window. 'Hlineapp' is an open TAPI session handle or NULL if none.
  208. ** 'Puser' is caller's buffer to receive the
  209. ** result. 'PpFile' is address of caller's file block which is filled in,
  210. ** if user chooses to open a new phonebook file, with the information
  211. ** about the newly open file. It is caller's responsibility to
  212. ** ClosePhonebookFile and Free the returned block.
  213. **
  214. ** Returns true if user pressed OK and settings were saved successfully,
  215. ** or false if user pressed Cancel or an error occurred. The routine
  216. ** handles the display of an appropriate error popup.
  217. */
  218. {
  219. PROPSHEETHEADER header;
  220. PROPSHEETPAGE* apage;
  221. PROPSHEETPAGE* ppage;
  222. TCHAR* pszTitle;
  223. UPARGS args;
  224. BOOL bIsAdmin;
  225. DWORD dwPageCount, i;
  226. INT nStartPage, nEndPage, nTotalPage; // For whistler 460931
  227. TRACE("UpPropertySheet");
  228. // If the user doesn't have administrative priveleges, then
  229. // we don't allow the Connections tab to show.
  230. ZeroMemory(&args, sizeof(args));
  231. args.fIsUserAdmin = FIsUserAdminOrPowerUser();
  232. dwPageCount = UP_PageCount;
  233. // Initialize the array of pages
  234. apage = Malloc (dwPageCount * sizeof (PROPSHEETPAGE));
  235. if (!apage)
  236. return FALSE;
  237. /* Initialize OUT parameter and property sheet argument block.
  238. */
  239. ZeroMemory( pUser, sizeof(*pUser) );
  240. args.pUser = pUser;
  241. args.ppFile = ppFile;
  242. args.hlineapp = hlineapp;
  243. args.fResult = FALSE;
  244. args.dwFlags = dwFlags;
  245. if (ppFile)
  246. *ppFile = NULL;
  247. ZeroMemory( apage, dwPageCount * sizeof (PROPSHEETPAGE) );
  248. i = 0;
  249. // Add the autodial page
  250. ppage = &apage[ i ];
  251. ppage->dwSize = sizeof(PROPSHEETPAGE);
  252. ppage->hInstance = g_hinstDll;
  253. ppage->pszTemplate = MAKEINTRESOURCE( PID_AD_AutoDial );
  254. ppage->pfnDlgProc = AdDlgProc;
  255. ppage->lParam = (LPARAM )&args;
  256. i++;
  257. ppage = &apage[ i ];
  258. ppage->dwSize = sizeof(PROPSHEETPAGE);
  259. ppage->hInstance = g_hinstDll;
  260. ppage->pszTemplate = MAKEINTRESOURCE( PID_CB_CallbackSettings );
  261. ppage->pfnDlgProc = CbDlgProc;
  262. i++;
  263. // For whistler 460931 gangz
  264. // Diagnostic page.
  265. //
  266. ppage = &apage[ UP_DgPage ];
  267. ppage->dwSize = sizeof(PROPSHEETPAGE);
  268. ppage->hInstance = g_hinstDll;
  269. ppage->pszTemplate = MAKEINTRESOURCE( PID_DG_Diagnostics);
  270. ppage->pfnDlgProc = DgDlgProc;
  271. if ( dwFlags & UP_F_ShowOnlyDiagnostic)
  272. {
  273. ppage->lParam = (LPARAM)&args;
  274. }
  275. else
  276. {
  277. ppage->lParam = (LPARAM) NULL;
  278. }
  279. // For whistler 460931
  280. // Set showing pages
  281. //
  282. if( dwFlags & UP_F_ShowOnlyDiagnostic )
  283. {
  284. nStartPage = 0;
  285. nEndPage = dwPageCount - 1;
  286. // nStartPage = UP_DgPage;
  287. // nEndPage = UP_DgPage;
  288. }
  289. else
  290. {
  291. nStartPage = 0;
  292. nEndPage = dwPageCount - 1;
  293. }
  294. nTotalPage = nEndPage - nStartPage + 1;
  295. pszTitle = PszFromId(g_hinstDll, SID_UpTitle);
  296. ZeroMemory( &header, sizeof(header) );
  297. header.dwSize = sizeof(PROPSHEETHEADER);
  298. header.dwFlags = PSH_PROPSHEETPAGE + PSH_NOAPPLYNOW;
  299. header.hwndParent = hwndOwner;
  300. header.hInstance = g_hinstDll;
  301. header.pszCaption = (pszTitle) ? pszTitle : TEXT("");
  302. header.nPages = nTotalPage;
  303. header.ppsp = &apage[nStartPage];
  304. if (PropertySheet( &header ) == -1)
  305. {
  306. TRACE("PropertySheet failed");
  307. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  308. }
  309. Free0( pszTitle );
  310. return args.fResult;
  311. }
  312. // Allows the editing of ras user preferences
  313. DWORD
  314. APIENTRY
  315. RasUserPrefDiagOnly (
  316. HWND hwndParent,
  317. BOOL * pbCommit)
  318. {
  319. PBFILE * pPbFile = NULL;
  320. PBUSER pbuser;
  321. DWORD dwErr;
  322. if( NULL == pbCommit )
  323. {
  324. return ERROR_INVALID_PARAMETER;
  325. }
  326. // Load ras if neccessary
  327. dwErr = LoadRas( g_hinstDll, hwndParent );
  328. if (dwErr != 0)
  329. {
  330. ErrorDlg( hwndParent, SID_OP_LoadRas, dwErr, NULL );
  331. return dwErr;
  332. }
  333. // Launch the user preferences dialog
  334. *pbCommit = UserPreferencesDlg(
  335. 0,
  336. hwndParent,
  337. UP_F_ShowOnlyDiagnostic,
  338. &pbuser,
  339. &pPbFile );
  340. return NO_ERROR;
  341. }
  342. // Allows the editing of ras user preferences
  343. DWORD
  344. APIENTRY
  345. RasUserPrefsDlgInternal (
  346. HWND hwndParent,
  347. DWORD dwFlags)
  348. {
  349. BOOL bCommit = FALSE;
  350. PBFILE * pPbFile = NULL;
  351. PBUSER pbuser;
  352. DWORD dwErr;
  353. // Load ras if neccessary
  354. dwErr = LoadRas( g_hinstDll, hwndParent );
  355. if (dwErr != 0)
  356. {
  357. ErrorDlg( hwndParent, SID_OP_LoadRas, dwErr, NULL );
  358. return dwErr;
  359. }
  360. // Launch the user preferences dialog
  361. bCommit = UserPreferencesDlg(
  362. 0,
  363. hwndParent,
  364. dwFlags,
  365. &pbuser,
  366. &pPbFile );
  367. // Commit any neccessary changes
  368. if (bCommit)
  369. {
  370. }
  371. return NO_ERROR;
  372. }
  373. DWORD
  374. APIENTRY
  375. RasUserPrefsDlgAutodial (
  376. HWND hwndParent)
  377. {
  378. return RasUserPrefsDlgInternal(hwndParent, UP_F_AutodialMode);
  379. }
  380. DWORD
  381. APIENTRY
  382. RasUserPrefsDlg (
  383. HWND hwndParent)
  384. {
  385. return RasUserPrefsDlgInternal(hwndParent, 0);
  386. }
  387. DWORD
  388. APIENTRY
  389. RasUserEnableManualDial (
  390. IN HWND hwndParent,
  391. IN BOOL bLogon,
  392. IN BOOL bEnable )
  393. /* Called when the "operator dial" menu item is checked.
  394. */
  395. {
  396. return SetUserManualDialEnabling (
  397. bEnable,
  398. (bLogon) ? UPM_Logon : UPM_Normal);
  399. }
  400. DWORD
  401. APIENTRY
  402. RasUserGetManualDial (
  403. IN HWND hwndParent, // parent for error dialogs
  404. IN BOOL bLogon, // whether a user is logged in
  405. IN PBOOL pbEnabled ) // whether to enable or not
  406. /* Called when the "operator dial" menu item is checked.
  407. */
  408. {
  409. return GetUserManualDialEnabling (
  410. pbEnabled,
  411. (bLogon) ? UPM_Logon : UPM_Normal );
  412. }
  413. /*----------------------------------------------------------------------------
  414. ** User Preferences property sheet
  415. ** Listed alphabetically
  416. **----------------------------------------------------------------------------
  417. */
  418. BOOL
  419. UpApply(
  420. IN HWND hwndPage )
  421. /* Saves the contents of the property sheet. 'hwndPage' is the property
  422. ** sheet page. Pops up any errors that occur.
  423. **
  424. ** Returns false if invalid, true otherwise.
  425. */
  426. {
  427. DWORD dwErr;
  428. UPINFO* pInfo;
  429. TRACE("UpApply");
  430. pInfo = UpContext( hwndPage );
  431. if (!pInfo)
  432. return TRUE;
  433. if ( pInfo->hwndAd )
  434. AdApply( pInfo );
  435. if (pInfo->hwndCb)
  436. CbApply( pInfo );
  437. if(pInfo->hwndDg )
  438. {
  439. DgApply( pInfo );
  440. }
  441. #if 0
  442. if (pInfo->hwndGp)
  443. GpApply( pInfo );
  444. #endif
  445. if (pInfo->hwndCo)
  446. CoApply ( pInfo );
  447. #if 0
  448. if (pInfo->hwndPl)
  449. {
  450. if (!PlApply( pInfo ))
  451. return FALSE;
  452. }
  453. #endif
  454. pInfo->user.fDirty = TRUE;
  455. // Save off the user preferences
  456. //
  457. dwErr = g_pSetUserPreferences(
  458. NULL,
  459. &pInfo->user,
  460. UPM_Normal );
  461. if (dwErr != 0)
  462. {
  463. if (*pInfo->pArgs->ppFile)
  464. {
  465. ClosePhonebookFile( *pInfo->pArgs->ppFile );
  466. *pInfo->pArgs->ppFile = NULL;
  467. }
  468. ErrorDlg( pInfo->hwndDlg, SID_OP_WritePrefs, dwErr, NULL );
  469. UpExit( pInfo );
  470. return TRUE;
  471. }
  472. // Save off the logon preferences if we loaded them.
  473. //
  474. dwErr = g_pSetUserPreferences(
  475. NULL,
  476. &pInfo->userLogon,
  477. UPM_Logon );
  478. if (dwErr != 0)
  479. {
  480. ErrorDlg( pInfo->hwndDlg, SID_OP_WritePrefs, dwErr, NULL );
  481. UpExit( pInfo );
  482. return TRUE;
  483. }
  484. CopyMemory( pInfo->pArgs->pUser, &pInfo->user, sizeof(PBUSER) );
  485. pInfo->pArgs->fResult = TRUE;
  486. return TRUE;
  487. }
  488. VOID
  489. UpCancel(
  490. IN HWND hwndPage )
  491. /* Cancel was pressed. 'HwndPage' is the handle of a property page.
  492. */
  493. {
  494. TRACE("UpCancel");
  495. }
  496. UPINFO*
  497. UpContext(
  498. IN HWND hwndPage )
  499. /* Retrieve the property sheet context from a property page handle.
  500. */
  501. {
  502. return (UPINFO* )GetProp( GetParent( hwndPage ), g_contextId );
  503. }
  504. VOID
  505. UpExit(
  506. IN UPINFO* pInfo )
  507. /* Forces an exit from the dialog. 'PInfo' is the property sheet context.
  508. **
  509. ** Note: This cannot be called during initialization of the first page.
  510. ** See UpExitInit.
  511. */
  512. {
  513. TRACE("UpExit");
  514. PropSheet_PressButton( pInfo->hwndDlg, PSBTN_CANCEL );
  515. }
  516. VOID
  517. UpExitInit(
  518. IN HWND hwndDlg )
  519. /* Utility to report errors within UpInit and other first page
  520. ** initialization. 'HwndDlg' is the dialog window.
  521. */
  522. {
  523. SetOffDesktop( hwndDlg, SOD_MoveOff, NULL );
  524. SetOffDesktop( hwndDlg, SOD_Free, NULL );
  525. PostMessage( hwndDlg, WM_COMMAND,
  526. MAKEWPARAM( IDCANCEL , BN_CLICKED ),
  527. (LPARAM )GetDlgItem( hwndDlg, IDCANCEL ) );
  528. }
  529. UPINFO*
  530. UpInit(
  531. IN HWND hwndFirstPage,
  532. IN UPARGS* pArgs )
  533. /* Property sheet level initialization. 'HwndPage' is the handle of the
  534. ** first page. 'PArgs' is the API argument block.
  535. **
  536. ** Returns address of the context block if successful, NULL otherwise. If
  537. ** NULL is returned, an appropriate message has been displayed, and the
  538. ** property sheet has been cancelled.
  539. */
  540. {
  541. UPINFO* pInfo;
  542. DWORD dwErr;
  543. HWND hwndDlg;
  544. TRACE("UpInit");
  545. hwndDlg = GetParent( hwndFirstPage );
  546. ASSERT(hwndDlg);
  547. /* Allocate the context information block.
  548. */
  549. pInfo = Malloc( sizeof(*pInfo) );
  550. if (!pInfo)
  551. {
  552. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  553. UpExitInit( hwndDlg );
  554. return NULL;
  555. }
  556. /* Initialize the context block.
  557. */
  558. ZeroMemory( pInfo, sizeof(*pInfo) );
  559. pInfo->hwndDlg = hwndDlg;
  560. pInfo->pArgs = pArgs;
  561. pInfo->hwndFirstPage = hwndFirstPage;
  562. /* Read in the user preferences
  563. */
  564. dwErr = g_pGetUserPreferences(
  565. NULL,
  566. &pInfo->user,
  567. UPM_Normal);
  568. if (dwErr != 0)
  569. {
  570. Free( pInfo );
  571. ErrorDlg( hwndDlg, SID_OP_LoadPrefs, dwErr, NULL );
  572. UpExitInit( hwndDlg );
  573. return NULL;
  574. }
  575. /* If the fNoUser option was not selected, then load in the
  576. logon preferences separately, since we allow them to be
  577. modificed in this UI
  578. */
  579. dwErr = g_pGetUserPreferences(
  580. NULL,
  581. &pInfo->userLogon,
  582. UPM_Logon);
  583. if (dwErr != 0)
  584. {
  585. Free( pInfo );
  586. ErrorDlg( hwndDlg, SID_OP_LoadPrefs, dwErr, NULL );
  587. UpExitInit( hwndDlg );
  588. return NULL;
  589. }
  590. /* Associate the context with the property sheet window.
  591. */
  592. if (!SetProp( hwndDlg, g_contextId, pInfo ))
  593. {
  594. Free( pInfo );
  595. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  596. UpExitInit( hwndDlg );
  597. return NULL;
  598. }
  599. /* Use caller's TAPI session handle, if any.
  600. */
  601. if (pArgs->hlineapp)
  602. pInfo->pHlineapp = &pArgs->hlineapp;
  603. else
  604. pInfo->pHlineapp = &pInfo->hlineapp;
  605. TRACE("Context set");
  606. /* Set even fixed tab widths, per spec.
  607. */
  608. // SetEvenTabWidths( hwndDlg, UP_PageCount );
  609. /* Position property sheet at standard offset from parent.
  610. {
  611. RECT rect;
  612. GetWindowRect( GetParent( hwndDlg ), &rect );
  613. SetWindowPos( hwndDlg, NULL,
  614. rect.left + DXSHEET, rect.top + DYSHEET, 0, 0,
  615. SWP_NOZORDER + SWP_NOSIZE );
  616. UnclipWindow( hwndDlg );
  617. }
  618. */
  619. CenterWindow ( hwndDlg, GetParent ( hwndDlg ) );
  620. //
  621. // pmay: 292069
  622. //
  623. // If the autodialer dialog has called into us, set focus to the
  624. // autodial tab.
  625. //
  626. // For whistler 460931
  627. //
  628. if (pArgs->dwFlags & UP_F_ShowOnlyDiagnostic)
  629. {
  630. PostMessage(
  631. hwndDlg,
  632. PSM_SETCURSELID,
  633. 0,
  634. (LPARAM)(INT)PID_DG_Diagnostics);
  635. }
  636. else
  637. if (pArgs->dwFlags & UP_F_AutodialMode)
  638. {
  639. PostMessage(
  640. hwndDlg,
  641. PSM_SETCURSELID,
  642. 0,
  643. (LPARAM)(INT)PID_AD_AutoDial);
  644. }
  645. return pInfo;
  646. }
  647. VOID
  648. UpTerm(
  649. IN HWND hwndPage )
  650. /* Property sheet level termination. Releases the context block.
  651. ** 'HwndPage' is the handle of a property page.
  652. */
  653. {
  654. UPINFO* pInfo;
  655. TRACE("UpTerm");
  656. pInfo = UpContext( hwndPage );
  657. // Only terminate for once by making sure that we
  658. // only terminate if this is the first page.
  659. if ( (pInfo) && (pInfo->hwndFirstPage == hwndPage) )
  660. {
  661. // For whistler 460931
  662. // Clean up the diagnostic library
  663. //
  664. UnLoadDiagnosticDll( &pInfo->diagInfo);
  665. // Cleanup the list view
  666. if ( pInfo->hwndLvNumbers )
  667. {
  668. CbutilLvNumbersCleanup( pInfo->hwndLvNumbers );
  669. }
  670. if (pInfo->fChecksInstalled)
  671. {
  672. ListView_UninstallChecks( pInfo->hwndLvEnable );
  673. }
  674. if (pInfo->pHlineapp && *pInfo->pHlineapp != pInfo->pArgs->hlineapp)
  675. {
  676. TapiShutdown( *pInfo->pHlineapp );
  677. }
  678. Free( pInfo );
  679. TRACE("Context freed");
  680. }
  681. RemoveProp( GetParent( hwndPage ), g_contextId );
  682. }
  683. /*----------------------------------------------------------------------------
  684. ** Auto Dial property page
  685. ** Listed alphabetically following dialog proc
  686. **----------------------------------------------------------------------------
  687. */
  688. INT_PTR CALLBACK
  689. AdDlgProc(
  690. IN HWND hwnd,
  691. IN UINT unMsg,
  692. IN WPARAM wparam,
  693. IN LPARAM lparam )
  694. /* DialogProc callback for the Auto Dial page of the User Preferences
  695. ** property sheet. Parameters and return value are as described for
  696. ** standard windows 'DialogProc's.
  697. */
  698. {
  699. #if 0
  700. TRACE4("AdDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  701. (DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
  702. #endif
  703. if (ListView_OwnerHandler(
  704. hwnd, unMsg, wparam, lparam, AdLvEnableCallback ))
  705. {
  706. return TRUE;
  707. }
  708. switch (unMsg)
  709. {
  710. case WM_INITDIALOG:
  711. return
  712. AdInit( hwnd, (UPARGS* )(((PROPSHEETPAGE* )lparam)->lParam) );
  713. case WM_HELP:
  714. case WM_CONTEXTMENU:
  715. ContextHelp( g_adwAdHelp, hwnd, unMsg, wparam, lparam );
  716. break;
  717. case WM_NOTIFY:
  718. {
  719. switch (((NMHDR* )lparam)->code)
  720. {
  721. case PSN_APPLY:
  722. {
  723. BOOL fValid;
  724. UPINFO* pInfo = UpContext ( hwnd );
  725. TRACE("AdAPPLY");
  726. // We have to apply if we are the first page...
  727. if (pInfo->hwndFirstPage == hwnd)
  728. {
  729. /* Call UpApply only on first page.
  730. */
  731. fValid = UpApply( hwnd );
  732. SetWindowLong(
  733. hwnd, DWLP_MSGRESULT,
  734. (fValid)
  735. ? PSNRET_NOERROR
  736. : PSNRET_INVALID_NOCHANGEPAGE );
  737. return TRUE;
  738. }
  739. }
  740. case PSN_RESET:
  741. {
  742. /* Call UpCancel only on first page.
  743. */
  744. TRACE("AdRESET");
  745. UpCancel( hwnd );
  746. SetWindowLong( hwnd, DWLP_MSGRESULT, FALSE );
  747. break;
  748. }
  749. }
  750. }
  751. break;
  752. case WM_DESTROY:
  753. {
  754. /* UpTerm will handle making sure it only does its
  755. ** thing once
  756. */
  757. UpTerm( hwnd );
  758. break;
  759. }
  760. }
  761. return FALSE;
  762. }
  763. VOID
  764. AdApply(
  765. IN UPINFO* pInfo )
  766. /* Saves the contents of the property page. 'PInfo' is the property sheet
  767. ** context.
  768. */
  769. {
  770. DWORD dwErr, dwFlag;
  771. UINT unValue;
  772. LV_ITEM item;
  773. INT i, iCount;
  774. BOOL f;
  775. TRACE("AdApply");
  776. ZeroMemory( &item, sizeof(item) );
  777. item.mask = LVIF_PARAM + LVIF_STATE;
  778. iCount = ListView_GetItemCount( pInfo->hwndLvEnable );
  779. for (i = 0; i < iCount; ++i)
  780. {
  781. BOOL fCheck;
  782. item.iItem = i;
  783. if (!ListView_GetItem( pInfo->hwndLvEnable, &item ))
  784. break;
  785. fCheck = ListView_GetCheck( pInfo->hwndLvEnable, i );
  786. ASSERT(g_pRasSetAutodialEnable);
  787. dwErr = g_pRasSetAutodialEnable( (DWORD )item.lParam, fCheck );
  788. if (dwErr != 0)
  789. ErrorDlg( pInfo->hwndDlg, SID_OP_SetADialInfo, dwErr, NULL );
  790. }
  791. /* Set the autodial prompt information.
  792. * Flip it because the API wants true to mean "disable".
  793. */
  794. dwFlag = (DWORD )!IsDlgButtonChecked(
  795. pInfo->hwndAd, CID_AD_CB_AskBeforeAutodial );
  796. TRACE1("RasSetAutodialParam(%d)",dwFlag);
  797. dwErr = g_pRasSetAutodialParam( RASADP_DisableConnectionQuery,
  798. &dwFlag, sizeof(dwFlag) );
  799. TRACE1("RasSetAutodialParam=%d",dwErr);
  800. //
  801. // pmay: 209762
  802. //
  803. // Save the "disable current session" checkbox
  804. //
  805. dwFlag = (DWORD )
  806. IsDlgButtonChecked(pInfo->hwndAd, CID_AD_CB_DisableThisSession );
  807. dwErr = g_pRasSetAutodialParam(
  808. RASADP_LoginSessionDisable,
  809. &dwFlag,
  810. sizeof(dwFlag) );
  811. }
  812. BOOL
  813. AdFillLvEnable(
  814. IN UPINFO* pInfo )
  815. /* Initialize the listview of checkboxes. 'PInfo' is the property sheet
  816. ** context.
  817. **
  818. ** Note: This routine must only be called once.
  819. **
  820. ** Returns true if focus is set, false otherwise.
  821. */
  822. {
  823. DWORD dwErr;
  824. LOCATION* pLocations;
  825. DWORD cLocations;
  826. DWORD dwCurLocation;
  827. BOOL fFocusSet;
  828. fFocusSet = FALSE;
  829. ListView_DeleteAllItems( pInfo->hwndLvEnable );
  830. /* Install "listview of check boxes" handling.
  831. */
  832. pInfo->fChecksInstalled =
  833. ListView_InstallChecks( pInfo->hwndLvEnable, g_hinstDll );
  834. if (!pInfo->fChecksInstalled)
  835. return FALSE;
  836. /* Insert an item for each location.
  837. */
  838. pLocations = NULL;
  839. cLocations = 0;
  840. dwCurLocation = 0xFFFFFFFF;
  841. dwErr = GetLocationInfo( g_hinstDll, pInfo->pHlineapp,
  842. &pLocations, &cLocations, &dwCurLocation );
  843. if (dwErr != 0)
  844. ErrorDlg( pInfo->hwndDlg, SID_OP_LoadTapiInfo, dwErr, NULL );
  845. else
  846. {
  847. LV_ITEM item;
  848. LOCATION* pLocation;
  849. TCHAR* pszCurLoc;
  850. DWORD i;
  851. pszCurLoc = PszFromId( g_hinstDll, SID_IsCurLoc );
  852. ZeroMemory( &item, sizeof(item) );
  853. item.mask = LVIF_TEXT + LVIF_PARAM;
  854. for (i = 0, pLocation = pLocations;
  855. i < cLocations;
  856. ++i, ++pLocation)
  857. {
  858. TCHAR* psz;
  859. TCHAR* pszText;
  860. DWORD cb;
  861. pszText = NULL;
  862. psz = StrDup( pLocation->pszName );
  863. if (psz)
  864. {
  865. if (dwCurLocation == pLocation->dwId && pszCurLoc)
  866. {
  867. /* This is the current globally selected location. Append
  868. ** the " (the current location)" text.
  869. */
  870. cb = lstrlen( psz ) + lstrlen(pszCurLoc) + 1;
  871. pszText = Malloc( cb * sizeof(TCHAR) );
  872. if (pszText)
  873. {
  874. // Whistler bug 224074 use only lstrcpyn's to prevent
  875. // maliciousness
  876. //
  877. lstrcpyn(
  878. pszText,
  879. psz,
  880. cb );
  881. lstrcat( pszText, pszCurLoc );
  882. }
  883. Free( psz );
  884. }
  885. else
  886. pszText = psz;
  887. }
  888. if (pszText)
  889. {
  890. BOOL fCheck;
  891. /* Get the initial check value for this location.
  892. */
  893. ASSERT(g_pRasGetAutodialEnable);
  894. dwErr = g_pRasGetAutodialEnable( pLocation->dwId, &fCheck );
  895. if (dwErr != 0)
  896. {
  897. ErrorDlg( pInfo->hwndDlg, SID_OP_GetADialInfo,
  898. dwErr, NULL );
  899. fCheck = FALSE;
  900. }
  901. item.iItem = i;
  902. item.lParam = pLocation->dwId;
  903. item.pszText = pszText;
  904. ListView_InsertItem( pInfo->hwndLvEnable, &item );
  905. ListView_SetCheck( pInfo->hwndLvEnable, i, fCheck );
  906. if (dwCurLocation == pLocation->dwId)
  907. {
  908. /* Initial selection is the current location.
  909. */
  910. ListView_SetItemState( pInfo->hwndLvEnable, i,
  911. LVIS_SELECTED + LVIS_FOCUSED,
  912. LVIS_SELECTED + LVIS_FOCUSED );
  913. fFocusSet = TRUE;
  914. }
  915. Free( pszText );
  916. }
  917. }
  918. Free0( pszCurLoc );
  919. FreeLocationInfo( pLocations, cLocations );
  920. /* Add a single column exactly wide enough to fully display the widest
  921. ** member of the list.
  922. */
  923. {
  924. LV_COLUMN col;
  925. ZeroMemory( &col, sizeof(col) );
  926. col.mask = LVCF_FMT;
  927. col.fmt = LVCFMT_LEFT;
  928. ListView_InsertColumn( pInfo->hwndLvEnable, 0, &col );
  929. ListView_SetColumnWidth(
  930. pInfo->hwndLvEnable, 0, LVSCW_AUTOSIZE_USEHEADER );
  931. }
  932. }
  933. return fFocusSet;
  934. }
  935. BOOL
  936. AdInit(
  937. IN HWND hwndPage,
  938. IN OUT UPARGS* pArgs )
  939. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  940. ** page. 'PArgs' is the arguments from the PropertySheet caller.
  941. **
  942. ** Return false if focus was set, true otherwise.
  943. */
  944. {
  945. UPINFO* pInfo;
  946. BOOL fFocusSet;
  947. HWND hwndUdAttempts;
  948. HWND hwndUdSeconds;
  949. HWND hwndUdIdle;
  950. DWORD dwErr = NO_ERROR;
  951. DWORD dwFlag;
  952. DWORD cb;
  953. TRACE("AdInit");
  954. /* We're first page, if the user isn't
  955. * an admin.
  956. */
  957. pInfo = UpInit( hwndPage, pArgs );
  958. if (!pInfo)
  959. return TRUE;
  960. // For whistler bug 460931 gangz
  961. //
  962. if ( pArgs->dwFlags & UP_F_ShowOnlyDiagnostic)
  963. {
  964. pInfo->fShowOnlyDiagnostic = TRUE;
  965. EnumChildWindows( hwndPage,
  966. PrefDisableAllChildWindows,
  967. (LPARAM)FALSE);
  968. }
  969. else
  970. {
  971. pInfo->fShowOnlyDiagnostic = FALSE;
  972. }
  973. // Make sure that a default location is created if there isn't one. bug
  974. // 168631
  975. //
  976. dwErr = TapiNoLocationDlg( g_hinstDll, &(pInfo->pArgs->hlineapp), hwndPage );
  977. if (dwErr != 0)
  978. {
  979. // Error here is treated as a "cancel" per bug 288385.
  980. //
  981. return TRUE;
  982. }
  983. /* Initialize page-specific context information.
  984. */
  985. pInfo->hwndAd = hwndPage;
  986. pInfo->hwndLvEnable = GetDlgItem( hwndPage, CID_AD_LV_Enable );
  987. ASSERT(pInfo->hwndLvEnable);
  988. /* Initialize the listview.
  989. */
  990. fFocusSet = AdFillLvEnable( pInfo );
  991. /* Initialize autodial parameters.
  992. */
  993. dwFlag = FALSE;
  994. cb = sizeof(dwFlag);
  995. TRACE("RasGetAutodialParam(DCQ)");
  996. dwErr = g_pRasGetAutodialParam(
  997. RASADP_DisableConnectionQuery, &dwFlag, &cb );
  998. TRACE1("RasGetAutodialParam=%d",dwErr);
  999. /* Flip it because the API wants true to mean "disable".
  1000. */
  1001. CheckDlgButton( hwndPage, CID_AD_CB_AskBeforeAutodial, (BOOL )!dwFlag );
  1002. //
  1003. // pmay: 209762
  1004. //
  1005. // Initialize the "disable current session" checkbox
  1006. //
  1007. dwFlag = FALSE;
  1008. cb = sizeof(dwFlag);
  1009. dwErr = g_pRasGetAutodialParam(
  1010. RASADP_LoginSessionDisable, &dwFlag, &cb );
  1011. CheckDlgButton(
  1012. hwndPage,
  1013. CID_AD_CB_DisableThisSession,
  1014. (BOOL )dwFlag );
  1015. return !fFocusSet;
  1016. }
  1017. LVXDRAWINFO*
  1018. AdLvEnableCallback(
  1019. IN HWND hwndLv,
  1020. IN DWORD dwItem )
  1021. /* Enhanced list view callback to report drawing information. 'HwndLv' is
  1022. ** the handle of the list view control. 'DwItem' is the index of the item
  1023. ** being drawn.
  1024. **
  1025. ** Returns the address of the draw information.
  1026. */
  1027. {
  1028. /* The enhanced list view is used only to get the "wide selection bar"
  1029. ** feature so our option list is not very interesting.
  1030. **
  1031. ** Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
  1032. */
  1033. static LVXDRAWINFO info = { 1, 0, 0, { 0 } };
  1034. return &info;
  1035. }
  1036. /*----------------------------------------------------------------------------
  1037. ** Callback property page
  1038. ** Listed alphabetically following dialog proc
  1039. **----------------------------------------------------------------------------
  1040. */
  1041. INT_PTR CALLBACK
  1042. CbDlgProc(
  1043. IN HWND hwnd,
  1044. IN UINT unMsg,
  1045. IN WPARAM wparam,
  1046. IN LPARAM lparam )
  1047. /* DialogProc callback for the Callback page of the User Preferences
  1048. ** property sheet. Parameters and return value are as described for
  1049. ** standard windows 'DialogProc's.
  1050. */
  1051. {
  1052. #if 0
  1053. TRACE4("CbDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  1054. (DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
  1055. #endif
  1056. if (ListView_OwnerHandler(
  1057. hwnd, unMsg, wparam, lparam, CbutilLvNumbersCallback ))
  1058. {
  1059. return TRUE;
  1060. }
  1061. switch (unMsg)
  1062. {
  1063. case WM_INITDIALOG:
  1064. return CbInit( hwnd );
  1065. case WM_HELP:
  1066. case WM_CONTEXTMENU:
  1067. ContextHelp( g_adwCbHelp, hwnd, unMsg, wparam, lparam );
  1068. break;
  1069. case WM_NOTIFY:
  1070. {
  1071. switch (((NMHDR* )lparam)->code)
  1072. {
  1073. case NM_DBLCLK:
  1074. {
  1075. UPINFO* pInfo = UpContext( hwnd );
  1076. ASSERT(pInfo);
  1077. SendMessage( pInfo->hwndPbEdit, BM_CLICK, 0, 0 );
  1078. return TRUE;
  1079. }
  1080. case LVN_ITEMCHANGED:
  1081. {
  1082. UPINFO* pInfo = UpContext( hwnd );
  1083. ASSERT(pInfo);
  1084. CbUpdateLvAndPbState( pInfo );
  1085. return TRUE;
  1086. }
  1087. }
  1088. break;
  1089. }
  1090. case WM_COMMAND:
  1091. {
  1092. UPINFO* pInfo = UpContext( hwnd );
  1093. ASSERT(pInfo);
  1094. return CbCommand(
  1095. pInfo, HIWORD( wparam ), LOWORD( wparam ),(HWND )lparam );
  1096. }
  1097. }
  1098. return FALSE;
  1099. }
  1100. VOID
  1101. CbApply(
  1102. IN UPINFO* pInfo )
  1103. /* Saves the contents of the property page. 'PInfo' is the property sheet
  1104. ** context.
  1105. */
  1106. {
  1107. TRACE("CbApply");
  1108. if (IsDlgButtonChecked( pInfo->hwndCb, CID_CB_RB_No ))
  1109. pInfo->user.dwCallbackMode = CBM_No;
  1110. else if (IsDlgButtonChecked( pInfo->hwndCb, CID_CB_RB_Maybe ))
  1111. pInfo->user.dwCallbackMode = CBM_Maybe;
  1112. else
  1113. pInfo->user.dwCallbackMode = CBM_Yes;
  1114. CbutilSaveLv( pInfo->hwndLvNumbers, pInfo->user.pdtllistCallback );
  1115. }
  1116. BOOL
  1117. CbCommand(
  1118. IN UPINFO* pInfo,
  1119. IN WORD wNotification,
  1120. IN WORD wId,
  1121. IN HWND hwndCtrl )
  1122. /* Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  1123. ** is the notification code of the command. 'wId' is the control/menu
  1124. ** identifier of the command. 'HwndCtrl' is the control window handle of
  1125. ** the command.
  1126. **
  1127. ** Returns true if processed message, false otherwise.
  1128. */
  1129. {
  1130. TRACE3("CbCommand(n=%d,i=%d,c=$%x)",
  1131. (DWORD)wNotification,(DWORD)wId,(ULONG_PTR )hwndCtrl);
  1132. switch (wId)
  1133. {
  1134. case CID_CB_RB_No:
  1135. case CID_CB_RB_Maybe:
  1136. case CID_CB_RB_Yes:
  1137. {
  1138. if (wNotification == BN_CLICKED)
  1139. {
  1140. CbUpdateLvAndPbState( pInfo );
  1141. if (wId == CID_CB_RB_Yes
  1142. && ListView_GetSelectedCount( pInfo->hwndLvNumbers ) == 0)
  1143. {
  1144. /* Nothing's selected, so select the first item, if any.
  1145. */
  1146. ListView_SetItemState( pInfo->hwndLvNumbers, 0,
  1147. LVIS_SELECTED, LVIS_SELECTED );
  1148. }
  1149. }
  1150. break;
  1151. }
  1152. case CID_CB_PB_Edit:
  1153. {
  1154. if (wNotification == BN_CLICKED)
  1155. CbutilEdit( pInfo->hwndCb, pInfo->hwndLvNumbers );
  1156. break;
  1157. }
  1158. case CID_CB_PB_Delete:
  1159. {
  1160. if (wNotification == BN_CLICKED)
  1161. CbutilDelete( pInfo->hwndCb, pInfo->hwndLvNumbers );
  1162. break;
  1163. }
  1164. }
  1165. return FALSE;
  1166. }
  1167. BOOL
  1168. CbInit(
  1169. IN HWND hwndPage )
  1170. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  1171. ** page.
  1172. **
  1173. ** Return false if focus was set, true otherwise.
  1174. */
  1175. {
  1176. UPINFO* pInfo;
  1177. TRACE("CbInit");
  1178. pInfo = UpContext( hwndPage );
  1179. if (!pInfo)
  1180. return TRUE;
  1181. // For whistler 460931
  1182. //
  1183. if( TRUE == pInfo->fShowOnlyDiagnostic )
  1184. {
  1185. EnumChildWindows( hwndPage,
  1186. PrefDisableAllChildWindows,
  1187. (LPARAM)FALSE);
  1188. }
  1189. /* Initialize page-specific context information.
  1190. */
  1191. pInfo->hwndCb = hwndPage;
  1192. pInfo->hwndRbNo = GetDlgItem( hwndPage, CID_CB_RB_No );
  1193. ASSERT(pInfo->hwndRbNo);
  1194. pInfo->hwndRbMaybe = GetDlgItem( hwndPage, CID_CB_RB_Maybe );
  1195. ASSERT(pInfo->hwndRbMaybe);
  1196. pInfo->hwndRbYes = GetDlgItem( hwndPage, CID_CB_RB_Yes );
  1197. ASSERT(pInfo->hwndRbYes);
  1198. pInfo->hwndLvNumbers = GetDlgItem( hwndPage, CID_CB_LV_Numbers );
  1199. ASSERT(pInfo->hwndLvNumbers);
  1200. pInfo->hwndPbEdit = GetDlgItem( hwndPage, CID_CB_PB_Edit );
  1201. ASSERT(pInfo->hwndPbEdit);
  1202. pInfo->hwndPbDelete = GetDlgItem( hwndPage, CID_CB_PB_Delete );
  1203. ASSERT(pInfo->hwndPbDelete);
  1204. /* Initialize the listview.
  1205. */
  1206. CbutilFillLvNumbers(
  1207. pInfo->hwndCb, pInfo->hwndLvNumbers,
  1208. pInfo->user.pdtllistCallback, FALSE );
  1209. /* Set the radio button selection, which triggers appropriate
  1210. ** enabling/disabling.
  1211. */
  1212. {
  1213. HWND hwndRb;
  1214. if (pInfo->user.dwCallbackMode == CBM_No)
  1215. hwndRb = pInfo->hwndRbNo;
  1216. else if (pInfo->user.dwCallbackMode == CBM_Maybe)
  1217. hwndRb = pInfo->hwndRbMaybe;
  1218. else
  1219. {
  1220. ASSERT(pInfo->user.dwCallbackMode==CBM_Yes);
  1221. hwndRb = pInfo->hwndRbYes;
  1222. }
  1223. SendMessage( hwndRb, BM_CLICK, 0, 0 );
  1224. }
  1225. // pmay: If there are no devices available for callback,
  1226. // add some explanatory text and disable appropriate
  1227. // controls. Bug 168830
  1228. if (ListView_GetItemCount(pInfo->hwndLvNumbers) == 0)
  1229. {
  1230. // Uncheck if needed
  1231. if (Button_GetCheck(pInfo->hwndRbYes))
  1232. {
  1233. Button_SetCheck(pInfo->hwndRbMaybe, TRUE);
  1234. }
  1235. // Disable the windows.
  1236. EnableWindow(pInfo->hwndRbYes, FALSE);
  1237. EnableWindow(pInfo->hwndLvNumbers, FALSE);
  1238. }
  1239. return TRUE;
  1240. }
  1241. VOID
  1242. CbUpdateLvAndPbState(
  1243. IN UPINFO* pInfo )
  1244. /* Enables/disables the list view and associated buttons. ListView is
  1245. ** gray unless auto-callback is selected. Buttons gray unless
  1246. ** auto-callback selected and there is an item selected.
  1247. */
  1248. {
  1249. BOOL fEnableList;
  1250. BOOL fEnableEditButton, fEnableDeleteButton;
  1251. INT iSel;
  1252. HWND hwndLv;
  1253. // By default, we don't enable any buttons
  1254. fEnableDeleteButton = FALSE;
  1255. fEnableEditButton = FALSE;
  1256. // Only enable the list view if Yes is selected
  1257. //
  1258. fEnableList = Button_GetCheck( pInfo->hwndRbYes );
  1259. if (fEnableList)
  1260. {
  1261. hwndLv = pInfo->hwndLvNumbers;
  1262. if ( ListView_GetSelectedCount( hwndLv ) )
  1263. {
  1264. // The edit button should only be enabled if the
  1265. // listview is enabled and if one or more
  1266. // items is selected.
  1267. fEnableEditButton = TRUE;
  1268. //
  1269. // pmay: 213060
  1270. //
  1271. // The delete button is only enabled if all of the selected
  1272. // devices are not configured on the system. (since only
  1273. // non-installed devices can be removed from the list).
  1274. //
  1275. fEnableDeleteButton = TRUE;
  1276. for (iSel = ListView_GetNextItem( hwndLv, -1, LVNI_SELECTED );
  1277. iSel >= 0;
  1278. iSel = ListView_GetNextItem( hwndLv, iSel, LVNI_SELECTED )
  1279. )
  1280. {
  1281. LV_ITEM item;
  1282. ZeroMemory(&item, sizeof(item));
  1283. item.iItem = iSel;
  1284. item.mask = LVIF_PARAM;
  1285. if ( ListView_GetItem(hwndLv, &item) )
  1286. {
  1287. if (((CBCONTEXT*)item.lParam)->fConfigured)
  1288. {
  1289. fEnableDeleteButton = FALSE;
  1290. }
  1291. }
  1292. }
  1293. }
  1294. }
  1295. EnableWindow( pInfo->hwndLvNumbers, fEnableList );
  1296. EnableWindow( pInfo->hwndPbEdit, fEnableEditButton );
  1297. EnableWindow( pInfo->hwndPbDelete, fEnableDeleteButton );
  1298. }
  1299. /*-----------------------------------------------------
  1300. ** Utilities shared with router version of the listview
  1301. **-----------------------------------------------------
  1302. */
  1303. VOID
  1304. CbutilDelete(
  1305. IN HWND hwndDlg,
  1306. IN HWND hwndLvNumbers )
  1307. /* Called when the Delete button is pressed. 'PInfo' is the dialog
  1308. ** context.
  1309. */
  1310. {
  1311. MSGARGS msgargs;
  1312. INT nResponse;
  1313. TRACE("CbDelete");
  1314. ZeroMemory( &msgargs, sizeof(msgargs) );
  1315. msgargs.dwFlags = MB_YESNO + MB_ICONEXCLAMATION;
  1316. nResponse = MsgDlg( hwndDlg, SID_ConfirmDelDevice, &msgargs );
  1317. if (nResponse == IDYES)
  1318. {
  1319. INT iSel;
  1320. /* User has confirmed deletion of selected devices, so do it.
  1321. */
  1322. while ((iSel = ListView_GetNextItem(
  1323. hwndLvNumbers, -1, LVNI_SELECTED )) >= 0)
  1324. {
  1325. ListView_DeleteItem( hwndLvNumbers, iSel );
  1326. }
  1327. }
  1328. }
  1329. VOID
  1330. CbutilEdit(
  1331. IN HWND hwndDlg,
  1332. IN HWND hwndLvNumbers )
  1333. /* Called when the Edit button is pressed. 'HwndDlg' is the page/dialog
  1334. ** window. 'HwndLvNumbers' is the callback number listview window.
  1335. */
  1336. {
  1337. INT iSel;
  1338. TCHAR szBuf[ RAS_MaxCallbackNumber + 1 ];
  1339. TCHAR* pszNumber;
  1340. TRACE("CbutilEdit");
  1341. /* Load 'szBuf' with the current phone number of the first selected item.
  1342. */
  1343. iSel = ListView_GetNextItem( hwndLvNumbers, -1, LVNI_SELECTED );
  1344. if (iSel < 0)
  1345. return;
  1346. szBuf[ 0 ] = TEXT('\0');
  1347. ListView_GetItemText( hwndLvNumbers, iSel, 1,
  1348. szBuf, RAS_MaxCallbackNumber + 1 );
  1349. /* Popup dialog to edit the number.
  1350. */
  1351. pszNumber = NULL;
  1352. if (StringEditorDlg( hwndDlg, szBuf,
  1353. SID_EcbnTitle, SID_EcbnLabel, RAS_MaxCallbackNumber,
  1354. HID_ZE_ST_CallbackNumber, &pszNumber ))
  1355. {
  1356. /* OK pressed, so change the number on all selected items.
  1357. */
  1358. ASSERT(pszNumber);
  1359. do
  1360. {
  1361. ListView_SetItemText( hwndLvNumbers, iSel, 1, pszNumber );
  1362. }
  1363. while ((iSel = ListView_GetNextItem(
  1364. hwndLvNumbers, iSel, LVNI_SELECTED )) >= 0);
  1365. }
  1366. }
  1367. VOID
  1368. CbutilFillLvNumbers(
  1369. IN HWND hwndDlg,
  1370. IN HWND hwndLvNumbers,
  1371. IN DTLLIST* pListCallback,
  1372. IN BOOL fRouter )
  1373. /* Fill the listview with devices and phone numbers. 'HwndDlg' is the
  1374. ** page/dialog window. 'HwndLvNumbers' is the callback listview.
  1375. ** 'PListCallback' is the list of CALLBACKINFO. 'FRouter' is true if the
  1376. ** router ports should be enumerated, or false for regular dial-out ports.
  1377. **
  1378. ** Note: This routine should be called only once.
  1379. */
  1380. {
  1381. DWORD dwErr;
  1382. DTLLIST* pListPorts;
  1383. DTLNODE* pNodeCbi;
  1384. DTLNODE* pNodePort;
  1385. INT iItem;
  1386. TCHAR* psz;
  1387. TRACE("CbutilFillLvNumbers");
  1388. ListView_DeleteAllItems( hwndLvNumbers );
  1389. /* Add columns.
  1390. */
  1391. {
  1392. LV_COLUMN col;
  1393. TCHAR* pszHeader0;
  1394. TCHAR* pszHeader1;
  1395. pszHeader0 = PszFromId( g_hinstDll, SID_DeviceColHead );
  1396. pszHeader1 = PszFromId( g_hinstDll, SID_PhoneNumberColHead );
  1397. ZeroMemory( &col, sizeof(col) );
  1398. col.mask = LVCF_FMT + LVCF_TEXT;
  1399. col.fmt = LVCFMT_LEFT;
  1400. col.pszText = (pszHeader0) ? pszHeader0 : TEXT("");
  1401. ListView_InsertColumn( hwndLvNumbers, 0, &col );
  1402. ZeroMemory( &col, sizeof(col) );
  1403. col.mask = LVCF_FMT + LVCF_SUBITEM + LVCF_TEXT;
  1404. col.fmt = LVCFMT_LEFT;
  1405. col.pszText = (pszHeader1) ? pszHeader1 : TEXT("");
  1406. col.iSubItem = 1;
  1407. ListView_InsertColumn( hwndLvNumbers, 1, &col );
  1408. Free0( pszHeader0 );
  1409. Free0( pszHeader1 );
  1410. }
  1411. /* Add the modem and adapter images.
  1412. */
  1413. ListView_SetDeviceImageList( hwndLvNumbers, g_hinstDll );
  1414. /* Load listview with callback device/number pairs saved as user
  1415. ** preferences.
  1416. */
  1417. iItem = 0;
  1418. ASSERT(pListCallback);
  1419. for (pNodeCbi = DtlGetFirstNode( pListCallback );
  1420. pNodeCbi;
  1421. pNodeCbi = DtlGetNextNode( pNodeCbi ), ++iItem)
  1422. {
  1423. CALLBACKINFO* pCbi;
  1424. LV_ITEM item;
  1425. pCbi = (CALLBACKINFO* )DtlGetData( pNodeCbi );
  1426. ASSERT(pCbi);
  1427. ASSERT(pCbi->pszPortName);
  1428. ASSERT(pCbi->pszDeviceName);
  1429. ASSERT(pCbi->pszNumber);
  1430. if (pCbi->dwDeviceType != RASET_Vpn) {
  1431. psz = PszFromDeviceAndPort( pCbi->pszDeviceName, pCbi->pszPortName );
  1432. if (psz)
  1433. {
  1434. // pmay: 213060
  1435. //
  1436. // Allocate and initialize the context.
  1437. //
  1438. CBCONTEXT * pCbCtx;
  1439. pCbCtx = (CBCONTEXT*) Malloc (sizeof(CBCONTEXT));
  1440. if (pCbCtx == NULL)
  1441. {
  1442. continue;
  1443. }
  1444. pCbCtx->pszPortName = pCbi->pszPortName;
  1445. pCbCtx->pszDeviceName = pCbi->pszDeviceName;
  1446. pCbCtx->dwDeviceType = pCbi->dwDeviceType;
  1447. pCbCtx->fConfigured = FALSE;
  1448. ZeroMemory( &item, sizeof(item) );
  1449. item.mask = LVIF_TEXT + LVIF_IMAGE + LVIF_PARAM;
  1450. item.iItem = iItem;
  1451. item.pszText = psz;
  1452. item.iImage =
  1453. ((PBDEVICETYPE )pCbi->dwDeviceType == PBDT_Modem)
  1454. ? DI_Modem : DI_Adapter;
  1455. item.lParam = (LPARAM )pCbCtx;
  1456. ListView_InsertItem( hwndLvNumbers, &item );
  1457. ListView_SetItemText( hwndLvNumbers, iItem, 1, pCbi->pszNumber );
  1458. Free( psz );
  1459. }
  1460. }
  1461. }
  1462. /* Add any devices installed but not already in the list.
  1463. */
  1464. dwErr = LoadPortsList2( NULL, &pListPorts, fRouter );
  1465. if (dwErr != 0)
  1466. {
  1467. ErrorDlg( hwndDlg, SID_OP_LoadPortInfo, dwErr, NULL );
  1468. }
  1469. else
  1470. {
  1471. for (pNodePort = DtlGetFirstNode( pListPorts );
  1472. pNodePort;
  1473. pNodePort = DtlGetNextNode( pNodePort ))
  1474. {
  1475. PBPORT* pPort = (PBPORT* )DtlGetData( pNodePort );
  1476. INT i = -1;
  1477. BOOL bPortAlreadyInLv = FALSE;
  1478. ASSERT(pPort);
  1479. // pmay: 213060
  1480. //
  1481. // Search for the configured item in the list view
  1482. //
  1483. while ((i = ListView_GetNextItem(
  1484. hwndLvNumbers,
  1485. i,
  1486. LVNI_ALL )) >= 0)
  1487. {
  1488. LV_ITEM item;
  1489. CBCONTEXT * pCbCtx;
  1490. ZeroMemory( &item, sizeof(item) );
  1491. item.mask = LVIF_PARAM;
  1492. item.iItem = i;
  1493. if (!ListView_GetItem( hwndLvNumbers, &item ))
  1494. {
  1495. continue;
  1496. }
  1497. // Get the context
  1498. //
  1499. pCbCtx = (CBCONTEXT*)item.lParam;
  1500. if (! pCbCtx)
  1501. {
  1502. continue;
  1503. }
  1504. // If the current item in the list view matches the
  1505. // current port, then we know that the current item
  1506. // is configured on the system.
  1507. if ((lstrcmpi( pPort->pszPort, pCbCtx->pszPortName ) == 0) &&
  1508. (lstrcmpi( pPort->pszDevice, pCbCtx->pszDeviceName ) == 0)
  1509. )
  1510. {
  1511. bPortAlreadyInLv = TRUE;
  1512. pCbCtx->fConfigured = TRUE;
  1513. break;
  1514. }
  1515. }
  1516. if (! bPortAlreadyInLv)
  1517. {
  1518. LV_ITEM item;
  1519. PBDEVICETYPE pbdt;
  1520. /* The device/port was not in the callback list. Append it
  1521. ** to the listview with empty phone number.
  1522. */
  1523. if ((pPort->dwType != RASET_Vpn) &&
  1524. (pPort->dwType != RASET_Direct) &&
  1525. (pPort->dwType != RASET_Broadband)
  1526. )
  1527. {
  1528. psz = PszFromDeviceAndPort(
  1529. pPort->pszDevice,
  1530. pPort->pszPort );
  1531. if (psz)
  1532. {
  1533. // pmay: 213060
  1534. //
  1535. // Allocate and initialize the context.
  1536. //
  1537. CBCONTEXT * pCbCtx;
  1538. pCbCtx = (CBCONTEXT*) Malloc (sizeof(CBCONTEXT));
  1539. if (pCbCtx == NULL)
  1540. {
  1541. continue;
  1542. }
  1543. pCbCtx->pszPortName = pPort->pszPort;
  1544. pCbCtx->pszDeviceName = pPort->pszDevice;
  1545. pCbCtx->dwDeviceType = (DWORD) pPort->pbdevicetype;
  1546. pCbCtx->fConfigured = TRUE;
  1547. ZeroMemory( &item, sizeof(item) );
  1548. item.mask = LVIF_TEXT + LVIF_IMAGE + LVIF_PARAM;
  1549. item.iItem = iItem;
  1550. item.pszText = psz;
  1551. item.iImage =
  1552. (pPort->pbdevicetype == PBDT_Modem)
  1553. ? DI_Modem : DI_Adapter;
  1554. item.lParam = (LPARAM ) pCbCtx;
  1555. ListView_InsertItem( hwndLvNumbers, &item );
  1556. ListView_SetItemText(
  1557. hwndLvNumbers,
  1558. iItem,
  1559. 1,
  1560. TEXT(""));
  1561. ++iItem;
  1562. Free( psz );
  1563. }
  1564. }
  1565. }
  1566. }
  1567. DtlDestroyList( pListPorts, DestroyPortNode );
  1568. }
  1569. /* Auto-size columns to look good with the text they contain.
  1570. */
  1571. ListView_SetColumnWidth( hwndLvNumbers, 0, LVSCW_AUTOSIZE_USEHEADER );
  1572. ListView_SetColumnWidth( hwndLvNumbers, 1, LVSCW_AUTOSIZE_USEHEADER );
  1573. }
  1574. VOID
  1575. CbutilLvNumbersCleanup(
  1576. IN HWND hwndLvNumbers )
  1577. /* Cleans up after CbutilFillLvNumbers.
  1578. */
  1579. {
  1580. INT i;
  1581. i = -1;
  1582. while ((i = ListView_GetNextItem( hwndLvNumbers, i, LVNI_ALL )) >= 0)
  1583. {
  1584. LV_ITEM item;
  1585. ZeroMemory( &item, sizeof(item) );
  1586. item.mask = LVIF_PARAM;
  1587. item.iItem = i;
  1588. if (!ListView_GetItem( hwndLvNumbers, &item ))
  1589. continue;
  1590. // Free the context
  1591. Free0( (PVOID) item.lParam );
  1592. }
  1593. }
  1594. LVXDRAWINFO*
  1595. CbutilLvNumbersCallback(
  1596. IN HWND hwndLv,
  1597. IN DWORD dwItem )
  1598. /* Enhanced list view callback to report drawing information. 'HwndLv' is
  1599. ** the handle of the list view control. 'DwItem' is the index of the item
  1600. ** being drawn.
  1601. **
  1602. ** Returns the address of the column information.
  1603. */
  1604. {
  1605. /* Use "wide selection bar" feature and the other recommended options.
  1606. **
  1607. ** Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
  1608. */
  1609. static LVXDRAWINFO info =
  1610. { 2, 0, LVXDI_Blend50Dis + LVXDI_DxFill, { 0, 0 } };
  1611. return &info;
  1612. }
  1613. VOID
  1614. CbutilSaveLv(
  1615. IN HWND hwndLvNumbers,
  1616. OUT DTLLIST* pListCallback )
  1617. /* Replace list 'pListCallback' contents with that of the listview
  1618. ** 'hwndLvNumbers'.
  1619. */
  1620. {
  1621. DTLNODE* pNode;
  1622. INT i;
  1623. TRACE("CbutilSaveLv");
  1624. /* Empty the list of callback info, then re-populate from the listview.
  1625. */
  1626. while (pNode = DtlGetFirstNode( pListCallback ))
  1627. {
  1628. DtlRemoveNode( pListCallback, pNode );
  1629. DestroyCallbackNode( pNode );
  1630. }
  1631. i = -1;
  1632. while ((i = ListView_GetNextItem( hwndLvNumbers, i, LVNI_ALL )) >= 0)
  1633. {
  1634. LV_ITEM item;
  1635. TCHAR* pszDevice;
  1636. TCHAR* pszPort;
  1637. TCHAR szDP[ RAS_MaxDeviceName + 2 + MAX_PORT_NAME + 1 + 1 ];
  1638. TCHAR szNumber[ RAS_MaxCallbackNumber + 1 ];
  1639. szDP[ 0 ] = TEXT('\0');
  1640. ZeroMemory( &item, sizeof(item) );
  1641. item.mask = LVIF_TEXT | LVIF_PARAM;
  1642. item.iItem = i;
  1643. item.pszText = szDP;
  1644. item.cchTextMax = sizeof(szDP) / sizeof(TCHAR);
  1645. if (!ListView_GetItem( hwndLvNumbers, &item ))
  1646. continue;
  1647. szNumber[ 0 ] = TEXT('\0');
  1648. ListView_GetItemText( hwndLvNumbers, i, 1,
  1649. szNumber, RAS_MaxCallbackNumber + 1 );
  1650. if (!DeviceAndPortFromPsz( szDP, &pszDevice, &pszPort ))
  1651. continue;
  1652. pNode = CreateCallbackNode(
  1653. pszPort,
  1654. pszDevice,
  1655. szNumber,
  1656. ((CBCONTEXT*)item.lParam)->dwDeviceType );
  1657. if (pNode)
  1658. DtlAddNodeLast( pListCallback, pNode );
  1659. Free( pszDevice );
  1660. Free( pszPort );
  1661. }
  1662. }
  1663. /*----------------------------------------------------------------------------
  1664. ** Connections Preferences property page
  1665. ** Listed alphabetically following dialog proc
  1666. **----------------------------------------------------------------------------
  1667. */
  1668. INT_PTR CALLBACK
  1669. CoDlgProc(
  1670. IN HWND hwnd,
  1671. IN UINT unMsg,
  1672. IN WPARAM wparam,
  1673. IN LPARAM lparam )
  1674. {
  1675. switch (unMsg)
  1676. {
  1677. case WM_INITDIALOG:
  1678. return CoInit( hwnd, (UPARGS* )(((PROPSHEETPAGE* )lparam)->lParam) );
  1679. case WM_HELP:
  1680. case WM_CONTEXTMENU:
  1681. ContextHelp( g_adwCoHelp, hwnd, unMsg, wparam, lparam );
  1682. break;
  1683. case WM_NOTIFY:
  1684. {
  1685. switch (((NMHDR* )lparam)->code)
  1686. {
  1687. case PSN_APPLY:
  1688. {
  1689. BOOL fValid;
  1690. UPINFO *pUpInfo;
  1691. TRACE("CoAPPLY");
  1692. pUpInfo = UpContext(hwnd);
  1693. if(NULL != pUpInfo)
  1694. {
  1695. CoApply( pUpInfo );
  1696. }
  1697. /* Call UpApply only on first page.
  1698. */
  1699. fValid = UpApply( hwnd );
  1700. SetWindowLong(
  1701. hwnd, DWLP_MSGRESULT,
  1702. (fValid)
  1703. ? PSNRET_NOERROR
  1704. : PSNRET_INVALID_NOCHANGEPAGE );
  1705. return TRUE;
  1706. }
  1707. }
  1708. break;
  1709. }
  1710. }
  1711. return FALSE;
  1712. }
  1713. BOOL
  1714. CoApply(
  1715. IN UPINFO* pInfo )
  1716. // Return true to allow application of property sheet, false
  1717. // to refuse.
  1718. {
  1719. BOOL bAllow;
  1720. bAllow = IsDlgButtonChecked(
  1721. pInfo->hwndCo,
  1722. CID_CO_CB_AllowConnectionModification );
  1723. if ( (!!bAllow) != (!!pInfo->userLogon.fAllowLogonPhonebookEdits) )
  1724. {
  1725. pInfo->userLogon.fAllowLogonPhonebookEdits = !!bAllow;
  1726. pInfo->userLogon.fDirty = TRUE;
  1727. }
  1728. return TRUE;
  1729. }
  1730. BOOL
  1731. CoInit(
  1732. IN HWND hwndPage,
  1733. IN OUT UPARGS* pArgs )
  1734. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  1735. ** page. 'PArgs' is the arguments from the PropertySheet caller.
  1736. **
  1737. ** Return false if focus was set, true otherwise.
  1738. */
  1739. {
  1740. UPINFO * pInfo = NULL;
  1741. /* We're first page, so initialize the property sheet.
  1742. */
  1743. pInfo = UpInit( hwndPage, pArgs );
  1744. if (!pInfo)
  1745. return TRUE;
  1746. pInfo->hwndCo = hwndPage;
  1747. // Set the flag for allowing phonebook edits
  1748. Button_SetCheck (
  1749. GetDlgItem (pInfo->hwndCo, CID_CO_CB_AllowConnectionModification),
  1750. pInfo->userLogon.fAllowLogonPhonebookEdits);
  1751. return TRUE;
  1752. }