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.

11093 lines
308 KiB

  1. // Copyright (c) 1995, Microsoft Corporation, all rights reserved
  2. //
  3. // dial.c
  4. // Remote Access Common Dialog APIs
  5. // RasDialDlg APIs
  6. //
  7. // 11/19/95 Steve Cobb
  8. #include "rasdlgp.h"
  9. #include "raseapif.h"
  10. #include "inetcfgp.h"
  11. #include "netconp.h"
  12. #include "pref.h"
  13. // Posted message codes for tasks that should not or cannot occur in the
  14. // RasDial callback.
  15. //
  16. #define WM_RASEVENT 0xCCCC
  17. #define WM_RASERROR 0xCCCD
  18. #define WM_RASDIAL 0xCCCE
  19. #define WM_RASBUNDLEERROR 0xCCCF
  20. #define WM_DPENDDIALOG 0xCCD0
  21. // Dialer dialog mode bits
  22. //
  23. #define DR_U 0x00000001 // Username and password present
  24. #define DR_D 0x00000002 // Domain present
  25. #define DR_N 0x00000004 // Phone number present
  26. #define DR_L 0x00000008 // Location controls present
  27. #define DR_I 0x00000010 // Eap identity dialog
  28. // For whistler bug 500731
  29. #define DR_B 0x00000020 // No User name No Password(Basic)Eap dialog
  30. // Internal constants used by DrXxx routines to implement the "manual edit"
  31. // combo-box.
  32. //
  33. #define DR_WM_SETTEXT 0xCCC0
  34. #define DR_BOGUSWIDTH 19591
  35. #define EAP_RASTLS 13
  36. // For whistler 460931 459793 gangz
  37. extern BOOL WINAPI LinkWindow_RegisterClass();
  38. //----------------------------------------------------------------------------
  39. // Help maps
  40. //----------------------------------------------------------------------------
  41. static DWORD g_adwDrHelp[] =
  42. {
  43. CID_DR_BM_Useless, HID_DR_BM_Useless,
  44. CID_DR_ST_User, HID_DR_EB_User,
  45. CID_DR_EB_User, HID_DR_EB_User,
  46. CID_DR_ST_Password, HID_DR_EB_Password,
  47. CID_DR_EB_Password, HID_DR_EB_Password,
  48. CID_DR_ST_Domain, HID_DR_EB_Domain,
  49. CID_DR_EB_Domain, HID_DR_EB_Domain,
  50. CID_DR_CB_SavePassword, HID_DR_CB_SavePassword,
  51. CID_DR_ST_Numbers, HID_DR_CLB_Numbers,
  52. CID_DR_CLB_Numbers, HID_DR_CLB_Numbers,
  53. CID_DR_ST_Locations, HID_DR_LB_Locations,
  54. CID_DR_LB_Locations, HID_DR_LB_Locations,
  55. CID_DR_PB_Rules, HID_DR_PB_Rules,
  56. CID_DR_PB_Properties, HID_DR_PB_Properties,
  57. CID_DR_PB_DialConnect, HID_DR_PB_DialConnect,
  58. CID_DR_PB_Cancel, HID_DR_PB_Cancel,
  59. CID_DR_PB_Help, HID_DR_PB_Help,
  60. CID_DR_RB_SaveForMe, HID_DR_RB_SaveForMe,
  61. CID_DR_RB_SaveForEveryone, HID_DR_RB_SaveForEveryone,
  62. 0, 0
  63. };
  64. static DWORD g_adwCpHelp[] =
  65. {
  66. CID_CP_ST_Explain, HID_CP_ST_Explain,
  67. CID_CP_ST_OldPassword, HID_CP_EB_OldPassword,
  68. CID_CP_EB_OldPassword, HID_CP_EB_OldPassword,
  69. CID_CP_ST_Password, HID_CP_EB_Password,
  70. CID_CP_EB_Password, HID_CP_EB_Password,
  71. CID_CP_ST_ConfirmPassword, HID_CP_EB_ConfirmPassword,
  72. CID_CP_EB_ConfirmPassword, HID_CP_EB_ConfirmPassword,
  73. 0, 0
  74. };
  75. static DWORD g_adwDcHelp[] =
  76. {
  77. CID_DC_ST_Explain, HID_DC_ST_Explain,
  78. CID_DC_ST_Number, HID_DC_EB_Number,
  79. CID_DC_EB_Number, HID_DC_EB_Number,
  80. 0, 0
  81. };
  82. static DWORD g_adwDeHelp[] =
  83. {
  84. CID_DE_CB_EnableDiag, HID_DE_CB_EnableDiag,
  85. CID_DE_ST_ConfigureLnk, HID_DE_ST_ConfigureLnk,
  86. CID_DE_PB_More, HID_DE_PB_More,
  87. IDOK, HID_DE_PB_Redial,
  88. 0, 0
  89. };
  90. static DWORD g_adwPrHelp[] =
  91. {
  92. CID_PR_ST_Text, HID_PR_ST_Text,
  93. CID_PR_CB_DisableProtocols, CID_PR_CB_DisableProtocols,
  94. IDOK, HID_PR_PB_Accept,
  95. IDCANCEL, HID_PR_PB_HangUp,
  96. 0, 0
  97. };
  98. static DWORD g_adwUaHelp[] =
  99. {
  100. CID_UA_ST_UserName, HID_UA_EB_UserName,
  101. CID_UA_EB_UserName, HID_UA_EB_UserName,
  102. CID_UA_ST_Password, HID_UA_EB_Password,
  103. CID_UA_EB_Password, HID_UA_EB_Password,
  104. CID_UA_ST_Domain, HID_UA_EB_Domain,
  105. CID_UA_EB_Domain, HID_UA_EB_Domain,
  106. CID_UA_CB_SavePassword, HID_UA_CB_SavePassword,
  107. 0, 0
  108. };
  109. CONST WCHAR g_pszSavedPasswordToken[] = L"****************";
  110. #define g_dwSavedPasswordTokenLength \
  111. ( sizeof(g_pszSavedPasswordToken) / sizeof(TCHAR) )
  112. // Save password macro, determines if either User or Global password is saved
  113. // (p) must be a pointer to a DINFO struct (see dial.c)
  114. //
  115. // Whistler bug: 288234 When switching back and forth from "I connect" and
  116. // "Any user connects" password is not caching correctly
  117. //
  118. #define HaveSavedPw(p) \
  119. ((p)->fHaveSavedPwUser || (p)->fHaveSavedPwGlobal)
  120. //----------------------------------------------------------------------------
  121. // Local datatypes
  122. //----------------------------------------------------------------------------
  123. // Dial dialogs common context block. This block contains information common
  124. // to more than one dialog in the string of dial-related dialogs.
  125. //
  126. typedef struct
  127. _DINFO
  128. {
  129. // Caller's arguments to the RAS API. Outputs in 'pArgs' are visible to
  130. // the API which has the address of same. Careful using 'pszEntry' as
  131. // 'pEntry->pszEntryName' is generally more appropriate, the latter
  132. // reflecting the name of any prerequisite entry while the prequisite is
  133. // being dialed.
  134. //
  135. LPTSTR pszPhonebook;
  136. LPTSTR pszEntry;
  137. LPTSTR pszPhoneNumber;
  138. RASDIALDLG* pArgs;
  139. // Phonebook settings read from the phonebook file. All access should be
  140. // thru 'pFile'. 'PFile' is set to either '&filePrereq' or 'pFileMain'
  141. // depending on 'fFilePrereqOpen'. 'File' will only be used in cases
  142. // where the open phonebook is not passed thru the reserved word hack, and
  143. // in that case 'pFileMain' will point to it. 'FilePrereq' is the
  144. // phonebook file of the prequisite entry which may be different from the
  145. // main entry. During prerequisite dial 'pFile' points to 'filePrereq'
  146. // rather than 'file' and 'fFilePrereqOpen is true. Otherwise, 'pFile'
  147. // points to whatever 'pFileMain' points at.
  148. //
  149. PBFILE* pFile;
  150. PBFILE* pFileMain;
  151. PBFILE file;
  152. PBFILE filePrereq;
  153. BOOL fFilePrereqOpen;
  154. BOOL fIsPublicPbk;
  155. // Global preferences read via phonebook library. All access should be
  156. // thru 'pUser' as 'user' will only be used in cases where the preferences
  157. // are not passed thru the reserved word hack.
  158. //
  159. PBUSER* pUser;
  160. PBUSER user;
  161. // User credentials provided by API caller for "during logon" dialing
  162. // where there is no current user. If user changes the credentials
  163. // *pfNoUserChanged is set and the 'pNoUser' credentials updated.
  164. //
  165. RASNOUSER* pNoUser;
  166. BOOL* pfNoUserChanged;
  167. // Set if the call is unattended, i.e. a call by RASAUTO to redial a
  168. // failed link.
  169. //
  170. BOOL fUnattended;
  171. // Private flags from calling RAS API, the first informing us he wants to
  172. // be hidden off the desktop while we dial, and the second that he will
  173. // close if we return "connected" so we can avoid flicker and not bother
  174. // restoring him.
  175. //
  176. BOOL fMoveOwnerOffDesktop;
  177. BOOL fForceCloseOnDial;
  178. // Set when something occurs during dial that affects the phonebook entry.
  179. // The entry is re-read after a successful connection.
  180. //
  181. BOOL fResetAutoLogon;
  182. DWORD dwfExcludedProtocols;
  183. DTLLIST* pListPortsToDelete;
  184. // The entry node and a shortcut pointer to the entry inside.
  185. //
  186. DTLNODE* pNode;
  187. PBENTRY* pEntry;
  188. // The entry of the main entry that referred to any prerequisite entry
  189. // that might be contained by 'pEntry'. If no prerequisite entry is
  190. // involved this is the same as 'pEntry'.
  191. //
  192. PBENTRY* pEntryMain;
  193. // Set is admin has disabled the save password feature in the registry.
  194. //
  195. BOOL fDisableSavePw;
  196. // Set true if a cached password is available for the entry.
  197. //
  198. BOOL fHaveSavedPwUser; // whether there are saved per-user creds
  199. BOOL fHaveSavedPwGlobal; // whether there are saved per-connect creds
  200. // Set when the dial in progress is the prerequisite entry, rather than
  201. // the main entry.
  202. //
  203. BOOL fPrerequisiteDial;
  204. // Set when calling RasDial on a connected entry to add a reference only.
  205. // All interaction with user is skipped in this case. See bug 272794.
  206. //
  207. BOOL fDialForReferenceOnly;
  208. // The dial parameters used on this connection attempt. Initialized in
  209. // RasDialDlgW. Credentials are updated by DialerDlg. Callback number is
  210. // updated by DialProgressDlg.
  211. //
  212. RASDIALPARAMS rdp; // actual dial parameters passed to RasDial
  213. RASDIALPARAMS rdpu; // per-user credentials
  214. RASDIALPARAMS rdpg; // per-connection credentials
  215. // The dial parameter extensions used on this connection attempt. Set in
  216. // RasDialDlgW, except hwndOwner which is set in DialProgressDlg.
  217. //
  218. RASDIALEXTENSIONS rde;
  219. }
  220. DINFO;
  221. // Dialer dialogs argument block. Used for all 5 variations of the dialer.
  222. //
  223. typedef struct
  224. _DRARGS
  225. {
  226. DINFO* pDinfo;
  227. DWORD dwfMode;
  228. DWORD fReload;
  229. }
  230. DRARGS;
  231. // Dialer dialogs context block. Used for all 5 variations of the dialer.
  232. //
  233. typedef struct
  234. DRINFO
  235. {
  236. // Common dial context information including the RAS API arguments.
  237. //
  238. DRARGS* pArgs;
  239. // Handle of the dialog and some of it's controls.
  240. //
  241. HWND hwndDlg;
  242. HWND hwndEbUser;
  243. HWND hwndEbPw;
  244. HWND hwndEbDomain;
  245. HWND hwndCbSavePw;
  246. HWND hwndRbSaveForMe;
  247. HWND hwndRbSaveForEveryone;
  248. HWND hwndClbNumbers;
  249. HWND hwndStLocations;
  250. HWND hwndLbLocations;
  251. HWND hwndPbRules;
  252. HWND hwndPbProperties;
  253. HWND hwndBmDialer;
  254. // Whistler bug: 195480 Dial-up connection dialog - Number of
  255. // asterisks does not match the length of the password and causes
  256. // confusion
  257. //
  258. WCHAR szPasswordChar;
  259. HFONT hNormalFont;
  260. HFONT hItalicFont;
  261. // TAPI session handle.
  262. //
  263. HLINEAPP hlineapp;
  264. // The phonebook entry link containing the displayed phone number list.
  265. // Set up only when DR_N mode bit is set.
  266. //
  267. DTLNODE* pLinkNode;
  268. PBLINK* pLink;
  269. // The index of the item initially selected in the phone number list.
  270. //
  271. DWORD iFirstSelectedPhone;
  272. // Window handles and original window procedure of the subclassed
  273. // 'hwndClbNumbers' control's edit-box and list-box child windows.
  274. //
  275. HWND hwndClbNumbersEb;
  276. HWND hwndClbNumbersLb;
  277. WNDPROC wndprocClbNumbersEb;
  278. WNDPROC wndprocClbNumbersLb;
  279. INetConnectionUiUtilities * pNetConUtilities;
  280. // Set if COM has been initialized (necessary for calls to netshell).
  281. //
  282. BOOL fComInitialized;
  283. // Handle to the original bitmap for the dialer if it is modified
  284. // in DrSetBitmap
  285. //
  286. HBITMAP hbmOrig;
  287. }
  288. DRINFO;
  289. // Context of an item in the dialer's 'ClbNumbers' list.
  290. //
  291. typedef struct
  292. _DRNUMBERSITEM
  293. {
  294. TCHAR* pszNumber;
  295. PBPHONE* pPhone;
  296. }
  297. DRNUMBERSITEM;
  298. // Subentry state information.
  299. //
  300. typedef struct
  301. _DPSTATE
  302. {
  303. RASCONNSTATE state;
  304. DWORD dwError;
  305. DWORD dwExtendedError;
  306. TCHAR szExtendedError[ NETBIOS_NAME_LEN + 1 ];
  307. TCHAR* pszStatusArg;
  308. TCHAR* pszFormatArg;
  309. PBDEVICETYPE pbdt;
  310. DWORD sidState;
  311. DWORD sidFormatMsg;
  312. DWORD sidPrevState;
  313. BOOL fNotPreSwitch;
  314. HRASCONN hrasconnLink;
  315. }
  316. DPSTATE;
  317. // Dial Progress dialog context block.
  318. //
  319. typedef struct
  320. _DPINFO
  321. {
  322. // When the block is valid contains the value 0xC0BBC0DE, otherwise 0.
  323. // Used as a workaround until RasDial is fixed to stop calling
  324. // RasDialFunc2 after being told not to, see bug 49469.
  325. //
  326. DWORD dwValid;
  327. // RAS API arguments.
  328. //
  329. DINFO* pArgs;
  330. // Handle of this dialog and some of it's controls.
  331. //
  332. HWND hwndDlg;
  333. HWND hwndStState;
  334. // The saved username and password that authenticated but resulted in a
  335. // change password event. If the change password operation fails these
  336. // are restored to make the redial button work properly.
  337. //
  338. TCHAR* pszGoodUserName;
  339. TCHAR* pszGoodPassword;
  340. // The handle to the RAS connection being initiated.
  341. //
  342. HRASCONN hrasconn;
  343. // The original window proc we subclassed.
  344. //
  345. WNDPROC pOldWndProc;
  346. // Number of auto-redials not yet attempted on the connection.
  347. //
  348. DWORD dwRedialAttemptsLeft;
  349. // Array of RasDial states, one per subentry, set by DpRasDialFunc2 and
  350. // used by DpRasDialEvent.
  351. //
  352. DPSTATE* pStates;
  353. DWORD cStates;
  354. // The number of the most advanced subentry and the "latest" state it has
  355. // reached. Note that certain states, like RASCS_AuthNotify, are
  356. // revisited after reaching a "later" state. Such changes are ignored.
  357. //
  358. RASCONNSTATE state;
  359. DWORD dwSubEntry;
  360. // UI thread, Call back function synchronization members
  361. // for XPSP2 511810, .Net 668164, 668164 gangz
  362. CRITICAL_SECTION * pcsActiveLock;
  363. //Add a per-thread Terminate flag for whistler bug 277365,291613 gangz
  364. //
  365. // Flag indicating that RasDial callbacks are active. The callback
  366. // context must not be destroyed when this flag is set. Access to this
  367. // field is protected by g_csCallbacks, see Get/SetCallbackActive .
  368. //
  369. BOOL fCallbacksActive;
  370. BOOL fTerminateAsap;
  371. //for whistler bug 381337
  372. //
  373. BOOL fCancelPressed;
  374. }
  375. DPINFO;
  376. // Dial Error dialog argument block.
  377. //
  378. typedef struct
  379. _DEARGS
  380. {
  381. DINFO* pDinfo; // For whistler 474514
  382. TCHAR* pszPhonebook; // For whistler 460931
  383. TCHAR* pszEntry;
  384. DWORD dwError;
  385. DWORD sidState;
  386. TCHAR* pszStatusArg;
  387. DWORD sidFormatMsg;
  388. TCHAR* pszFormatArg;
  389. LONG lRedialCountdown;
  390. BOOL fPopupOnTop;
  391. }
  392. DEARGS;
  393. // Dial Error dialog context block.
  394. //
  395. typedef struct
  396. _DEINFO
  397. {
  398. // Caller's arguments to the stub API.
  399. //
  400. DEARGS* pArgs;
  401. // Handle of dialog and controls.
  402. //
  403. HWND hwndDlg;
  404. HWND hwndStText;
  405. HWND hwndPbRedial;
  406. HWND hwndPbCancel;
  407. HWND hwndPbMore;
  408. // For whistler 460931 459793
  409. //
  410. DiagnosticInfo diagInfo;
  411. HWND hwndCbEnableDiagLog;
  412. HWND hwndStConfigureLnk;
  413. HWND hwndStEnableHelp;
  414. HWND hwndStLinkHelp;
  415. // Number of seconds remaining in "Redial=x" countdown or -1 if inactive.
  416. //
  417. LONG lRedialCountdown;
  418. }
  419. DEINFO;
  420. // Projection Result dialog argument block.
  421. //
  422. typedef struct
  423. _PRARGS
  424. {
  425. TCHAR* pszLines;
  426. BOOL* pfDisableFailedProtocols;
  427. }
  428. PRARGS;
  429. // Change Password dialog argument block.
  430. //
  431. typedef struct
  432. _CPARGS
  433. {
  434. BOOL fOldPassword;
  435. TCHAR* pszOldPassword;
  436. TCHAR* pszNewPassword;
  437. }
  438. CPARGS;
  439. // Change Password dialog context block.
  440. // (unconventional name because CPINFO conflicts with a system header)
  441. //
  442. typedef struct
  443. _CPWINFO
  444. {
  445. // Caller's arguments to the stub API.
  446. //
  447. CPARGS* pArgs;
  448. // Handle of dialog and controls.
  449. //
  450. HWND hwndDlg;
  451. HWND hwndEbOldPassword;
  452. HWND hwndEbNewPassword;
  453. HWND hwndEbNewPassword2;
  454. }
  455. CPWINFO;
  456. // Retry Authentication dialog context block.
  457. //
  458. typedef struct
  459. UAINFO
  460. {
  461. // Commond dial context including original RAS API arguments.
  462. //
  463. DINFO* pArgs;
  464. // Handle of this dialog and some of it's controls.
  465. //
  466. HWND hwndDlg;
  467. HWND hwndEbUserName;
  468. HWND hwndEbPassword;
  469. HWND hwndEbDomain;
  470. HWND hwndCbSavePw;
  471. // Set when the password field contains a phony password in place of the
  472. // "" one we don't really know.
  473. //
  474. BOOL fAutoLogonPassword;
  475. // Set when the Domain field is present.
  476. //
  477. BOOL fDomain;
  478. }
  479. UAINFO;
  480. //-----------------------------------------------------------------------------
  481. // Local prototypes (alphabetically)
  482. //-----------------------------------------------------------------------------
  483. BOOL
  484. BeCommand(
  485. IN HWND hwnd,
  486. IN WORD wNotification,
  487. IN WORD wId,
  488. IN HWND hwndCtrl );
  489. INT_PTR CALLBACK
  490. BeDlgProc(
  491. IN HWND hwnd,
  492. IN UINT unMsg,
  493. IN WPARAM wparam,
  494. IN LPARAM lparam );
  495. VOID
  496. BeFillLvErrors(
  497. IN HWND hwndLv,
  498. IN DPINFO* pInfo );
  499. TCHAR*
  500. BeGetErrorPsz(
  501. IN DWORD dwError );
  502. BOOL
  503. BeInit(
  504. IN HWND hwndDlg,
  505. IN DPINFO* pArgs );
  506. LVXDRAWINFO*
  507. BeLvErrorsCallback(
  508. IN HWND hwndLv,
  509. IN DWORD dwItem );
  510. BOOL
  511. BundlingErrorsDlg(
  512. IN OUT DPINFO* pInfo );
  513. BOOL
  514. ChangePasswordDlg(
  515. IN HWND hwndOwner,
  516. IN BOOL fOldPassword,
  517. OUT TCHAR* pszOldPassword,
  518. OUT TCHAR* pszNewPassword );
  519. BOOL
  520. CpCommand(
  521. IN HWND hwnd,
  522. IN WORD wNotification,
  523. IN WORD wId,
  524. IN HWND hwndCtrl );
  525. INT_PTR CALLBACK
  526. CpDlgProc(
  527. IN HWND hwnd,
  528. IN UINT unMsg,
  529. IN WPARAM wparam,
  530. IN LPARAM lparam );
  531. BOOL
  532. CpInit(
  533. IN HWND hwndDlg,
  534. IN CPARGS* pArgs );
  535. BOOL
  536. CcCommand(
  537. IN HWND hwnd,
  538. IN WORD wNotification,
  539. IN WORD wId,
  540. IN HWND hwndCtrl );
  541. INT_PTR CALLBACK
  542. CcDlgProc(
  543. IN HWND hwnd,
  544. IN UINT unMsg,
  545. IN WPARAM wparam,
  546. IN LPARAM lparam );
  547. BOOL
  548. CcInit(
  549. IN HWND hwndDlg,
  550. IN DINFO* pInfo );
  551. VOID
  552. ConnectCompleteDlg(
  553. IN HWND hwndOwner,
  554. IN DINFO* pInfo );
  555. BOOL
  556. DcCommand(
  557. IN HWND hwnd,
  558. IN WORD wNotification,
  559. IN WORD wId,
  560. IN HWND hwndCtrl );
  561. INT_PTR CALLBACK
  562. DcDlgProc(
  563. IN HWND hwnd,
  564. IN UINT unMsg,
  565. IN WPARAM wparam,
  566. IN LPARAM lparam );
  567. BOOL
  568. DcInit(
  569. IN HWND hwndDlg,
  570. IN TCHAR* pszNumber );
  571. VOID
  572. DeAdjustPbRedial(
  573. IN DEINFO* pInfo );
  574. BOOL
  575. DeCommand(
  576. IN HWND hwnd,
  577. IN WORD wNotification,
  578. IN WORD wId,
  579. IN HWND hwndCtrl );
  580. INT_PTR CALLBACK
  581. DeDlgProc(
  582. IN HWND hwnd,
  583. IN UINT unMsg,
  584. IN WPARAM wparam,
  585. IN LPARAM lparam );
  586. void DeEnableDiagnostic(
  587. IN HWND hwnd );
  588. BOOL
  589. DeInit(
  590. IN HWND hwndDlg,
  591. IN DEARGS* pArgs );
  592. DWORD
  593. DeleteSavedCredentials(
  594. IN DINFO* pDinfo,
  595. IN HWND hwndDlg,
  596. IN BOOL fDefault,
  597. IN BOOL fDeleteIdentity );
  598. VOID
  599. DeTerm(
  600. IN HWND hwndDlg );
  601. BOOL
  602. DialCallbackDlg(
  603. IN HWND hwndOwner,
  604. IN OUT TCHAR* pszNumber );
  605. BOOL
  606. DialErrorDlg(
  607. IN HWND hwndOwner,
  608. IN DINFO * pDinfo, // For whistler bug 474514
  609. IN TCHAR* pszPhonebook, // For whistler 460931
  610. IN TCHAR* pszEntry,
  611. IN DWORD dwError,
  612. IN DWORD sidState,
  613. IN TCHAR* pszStatusArg,
  614. IN DWORD sidFormatMsg,
  615. IN TCHAR* pszFormatArg,
  616. IN LONG lRedialCountdown,
  617. IN BOOL fPopupOnTop );
  618. BOOL
  619. DialerDlg(
  620. IN HWND hwndOwner,
  621. IN OUT DINFO* pInfo );
  622. BOOL
  623. DialProgressDlg(
  624. IN DINFO* pInfo );
  625. VOID
  626. DpAppendBlankLine(
  627. IN OUT TCHAR* pszLines );
  628. VOID
  629. DpAppendConnectErrorLine(
  630. IN OUT TCHAR* pszLines,
  631. IN DWORD sidProtocol,
  632. IN DWORD dwError );
  633. VOID
  634. DpAppendConnectOkLine(
  635. IN OUT TCHAR* pszLines,
  636. IN DWORD sidProtocol );
  637. VOID
  638. DpAppendFailCodeLine(
  639. IN OUT TCHAR* pszLines,
  640. IN DWORD dw );
  641. VOID
  642. DpAppendNameLine(
  643. IN OUT TCHAR* pszLines,
  644. IN TCHAR* psz );
  645. VOID
  646. DpAuthNotify(
  647. IN DPINFO* pInfo,
  648. IN DPSTATE* pState );
  649. VOID
  650. DpCallbackSetByCaller(
  651. IN DPINFO* pInfo,
  652. IN DPSTATE* pState );
  653. VOID
  654. DpCancel(
  655. IN DPINFO* pInfo );
  656. BOOL
  657. DpCommand(
  658. IN DPINFO* pInfo,
  659. IN WORD wNotification,
  660. IN WORD wId,
  661. IN HWND hwndCtrl );
  662. VOID
  663. DpConnectDevice(
  664. IN DPINFO* pInfo,
  665. IN DPSTATE* pState );
  666. VOID
  667. DpDeviceConnected(
  668. IN DPINFO* pInfo,
  669. IN DPSTATE* pState );
  670. VOID
  671. DpDial(
  672. IN DPINFO* pInfo,
  673. IN BOOL fPauseRestart );
  674. INT_PTR CALLBACK
  675. DpDlgProc(
  676. IN HWND hwnd,
  677. IN UINT unMsg,
  678. IN WPARAM wparam,
  679. IN LPARAM lparam );
  680. //For whistler 435725
  681. void
  682. DpEndDialog(
  683. IN DPINFO * pInfo,
  684. IN BOOL fFlag);
  685. VOID
  686. DpError(
  687. IN DPINFO* pInfo,
  688. IN DPSTATE* pState );
  689. DWORD
  690. DpEvent(
  691. IN DPINFO* pInfo,
  692. IN DWORD dwSubEntry );
  693. BOOL
  694. DpInit(
  695. IN HWND hwndDlg,
  696. IN DINFO* pArgs );
  697. VOID
  698. DpInitStates(
  699. DPINFO* pInfo );
  700. BOOL
  701. DpInteractive(
  702. IN DPINFO* pInfo,
  703. IN DPSTATE* pState,
  704. OUT BOOL* pfChange );
  705. BOOL
  706. DpIsLaterState(
  707. IN RASCONNSTATE stateNew,
  708. IN RASCONNSTATE stateOld );
  709. BOOL
  710. DpPasswordExpired(
  711. IN DPINFO* pInfo,
  712. IN DPSTATE* pState );
  713. BOOL
  714. DpProjected(
  715. IN DPINFO* pInfo,
  716. IN DPSTATE* pState );
  717. BOOL
  718. DpProjectionError(
  719. IN RASPPPNBF* pnbf,
  720. IN RASPPPIPX* pipx,
  721. IN RASPPPIP* pip,
  722. OUT BOOL* pfIncomplete,
  723. OUT DWORD* pdwfFailedProtocols,
  724. OUT TCHAR** ppszLines,
  725. OUT DWORD* pdwError );
  726. DWORD WINAPI
  727. DpRasDialFunc2(
  728. ULONG_PTR dwCallbackId,
  729. DWORD dwSubEntry,
  730. HRASCONN hrasconn,
  731. UINT unMsg,
  732. RASCONNSTATE state,
  733. DWORD dwError,
  734. DWORD dwExtendedError );
  735. VOID
  736. DpTerm(
  737. IN HWND hwndDlg );
  738. INT_PTR CALLBACK
  739. DrDlgProc(
  740. IN HWND hwnd,
  741. IN UINT unMsg,
  742. IN WPARAM wparam,
  743. IN LPARAM lparam );
  744. BOOL CALLBACK
  745. DrClbNumbersEnumChildProc(
  746. IN HWND hwnd,
  747. IN LPARAM lparam );
  748. BOOL CALLBACK
  749. DrClbNumbersEnumWindowsProc(
  750. IN HWND hwnd,
  751. IN LPARAM lparam );
  752. BOOL
  753. DrCommand(
  754. IN DRINFO* pInfo,
  755. IN WORD wNotification,
  756. IN WORD wId,
  757. IN HWND hwndCtrl );
  758. VOID
  759. DrEditSelectedLocation(
  760. IN DRINFO* pInfo );
  761. DWORD
  762. DrFillLocationList(
  763. IN DRINFO* pInfo );
  764. VOID
  765. DrFillNumbersList(
  766. IN DRINFO* pInfo );
  767. DWORD
  768. DrFindAndSubclassClbNumbersControls(
  769. IN DRINFO* pInfo );
  770. VOID
  771. DrFreeClbNumbers(
  772. IN DRINFO* pInfo );
  773. BOOL
  774. DrInit(
  775. IN HWND hwndDlg,
  776. IN DRARGS* pArgs );
  777. VOID
  778. DrLocationsSelChange(
  779. IN DRINFO* pInfo );
  780. VOID
  781. DrNumbersSelChange(
  782. IN DRINFO* pInfo );
  783. DWORD
  784. DrPopulateIdentificationFields(
  785. IN DRINFO* pInfo,
  786. IN BOOL fForMe);
  787. DWORD
  788. DrPopulatePasswordField(
  789. IN DRINFO* pInfo,
  790. IN BOOL fInit,
  791. IN BOOL fDisable,
  792. OUT BOOL * pfUseDefaultFocus
  793. );
  794. VOID
  795. DrProperties(
  796. IN DRINFO* pInfo );
  797. VOID
  798. DrSave(
  799. IN DRINFO* pInfo );
  800. DWORD
  801. DrSetBitmap(
  802. IN DRINFO* pInfo);
  803. VOID
  804. DrSetClbNumbersText(
  805. IN DRINFO* pInfo,
  806. IN TCHAR* pszText );
  807. VOID
  808. DrTerm(
  809. IN HWND hwndDlg );
  810. LRESULT APIENTRY
  811. DpWndProc(
  812. HWND hwnd,
  813. UINT unMsg,
  814. WPARAM wParam,
  815. LPARAM lParam );
  816. DWORD
  817. FindEntryAndSetDialParams(
  818. IN DINFO* pInfo );
  819. BOOL GetTerminateFlag(
  820. IN DPINFO * pInfo);
  821. BOOL SetTerminateFlag(
  822. IN DPINFO * pInfo);
  823. BOOL ResetTerminateFlag(
  824. IN DPINFO * pInfo);
  825. BOOL GetCallbackActive(
  826. IN DPINFO * pInfo);
  827. BOOL SetCallbackActive(
  828. IN DPINFO * pInfo);
  829. BOOL ResetCallbackActive(
  830. IN DPINFO * pInfo);
  831. INT_PTR CALLBACK
  832. PrDlgProc(
  833. IN HWND hwnd,
  834. IN UINT unMsg,
  835. IN WPARAM wparam,
  836. IN LPARAM lparam );
  837. BOOL
  838. PrCommand(
  839. IN HWND hwnd,
  840. IN WORD wNotification,
  841. IN WORD wId,
  842. IN HWND hwndCtrl );
  843. BOOL
  844. PrInit(
  845. IN HWND hwndDlg,
  846. IN PRARGS* pArgs );
  847. BOOL
  848. ProjectionResultDlg(
  849. IN HWND hwndOwner,
  850. IN TCHAR* pszLines,
  851. OUT BOOL* pfDisableFailedProtocols );
  852. BOOL
  853. RetryAuthenticationDlg(
  854. IN HWND hwndOwner,
  855. IN DINFO* pDinfo );
  856. INT_PTR CALLBACK
  857. UaDlgProc(
  858. IN HWND hwnd,
  859. IN UINT unMsg,
  860. IN WPARAM wparam,
  861. IN LPARAM lparam );
  862. BOOL
  863. UaCommand(
  864. IN UAINFO* pInfo,
  865. IN WORD wNotification,
  866. IN WORD wId,
  867. IN HWND hwndCtrl );
  868. BOOL
  869. UaInit(
  870. IN HWND hwndDlg,
  871. IN DINFO* pArgs );
  872. VOID
  873. UaSave(
  874. IN UAINFO* pInfo );
  875. VOID
  876. UaTerm(
  877. IN HWND hwndDlg );
  878. BOOL
  879. VpnDoubleDialDlg(
  880. IN HWND hwndOwner,
  881. IN DINFO* pInfo );
  882. INT_PTR CALLBACK
  883. ViDlgProc(
  884. IN HWND hwnd,
  885. IN UINT unMsg,
  886. IN WPARAM wparam,
  887. IN LPARAM lparam );
  888. BOOL
  889. ViCommand(
  890. IN HWND hwnd,
  891. IN WORD wNotification,
  892. IN WORD wId,
  893. IN HWND hwndCtrl );
  894. BOOL
  895. ViInit(
  896. IN HWND hwndDlg,
  897. IN DINFO* pInfo );
  898. //-----------------------------------------------------------------------------
  899. // External entry points
  900. //-----------------------------------------------------------------------------
  901. typedef struct EAPFREE_DATA {
  902. BOOL bInitialized;
  903. HINSTANCE hLib;
  904. RASEAPFREE pFreeFunc;
  905. } EAPFREE_DATA;
  906. //Add those OutputDebug_XXXX() functions for debug use when debugging 291613
  907. // gangz
  908. //
  909. void OutputDebug_DWCODE(DWORD dwCode)
  910. {
  911. WCHAR tmpBuf[100];
  912. wsprintf(tmpBuf,
  913. L"The dwCode returned is %x\n", dwCode);
  914. OutputDebugStringW(tmpBuf);
  915. }
  916. void OutputDebug_NumOfCallbacksActive(ULONG ulCallbacksActive)
  917. {
  918. WCHAR tmpBuf[100];
  919. wsprintf(tmpBuf,
  920. L"Current CallbacksActive is %x\n",
  921. ulCallbacksActive);
  922. OutputDebugStringW(tmpBuf);
  923. }
  924. void OutputDebug_ThreadId()
  925. {
  926. DWORD dwId;
  927. WCHAR tmpBuf[100];
  928. dwId = GetCurrentThreadId();
  929. wsprintf(tmpBuf, L"Current Thread is %x\n", dwId);
  930. OutputDebugStringW(tmpBuf);
  931. }
  932. void OutputDebug_ProcessThreadId()
  933. {
  934. DWORD dwIdProc, dwIdThread;
  935. WCHAR tmpBuf[100];
  936. dwIdProc = GetCurrentProcessId();
  937. dwIdThread = GetCurrentThreadId();
  938. wsprintf(tmpBuf, L"Current Proc is: %x , Thread is: %x\n", dwIdProc, dwIdThread);
  939. OutputDebugStringW(tmpBuf);
  940. }
  941. //
  942. // Raises the appriate eap indentity dialog
  943. //
  944. DWORD
  945. DialerDlgEap (
  946. IN HWND hwndOwner,
  947. IN PWCHAR lpszPhonebook,
  948. IN PWCHAR lpszEntry,
  949. IN PBENTRY * pEntry,
  950. IN DINFO *pInfo,
  951. OUT PBYTE * ppUserDataOut,
  952. OUT DWORD * lpdwSizeOfUserDataOut,
  953. OUT LPWSTR * lplpwszIdentity,
  954. OUT PHANDLE phFree
  955. )
  956. {
  957. DWORD dwErr = NO_ERROR, dwInSize = 0;
  958. PBYTE pbUserIn = NULL;
  959. HINSTANCE hLib = NULL;
  960. EAPFREE_DATA * pFreeData = NULL;
  961. DTLLIST * pListEaps = NULL;
  962. DTLNODE * pEapcfgNode = NULL;
  963. EAPCFG * pEapcfg = NULL;
  964. RASEAPFREE pFreeFunc = NULL;
  965. RASEAPGETIDENTITY pIdenFunc = NULL;
  966. DWORD dwFlags;
  967. DWORD cbData = 0;
  968. PBYTE pbData = NULL;
  969. // Initialize the free data handle we'll return
  970. pFreeData = Malloc ( sizeof(EAPFREE_DATA) );
  971. if (pFreeData == NULL)
  972. return ERROR_NOT_ENOUGH_MEMORY;
  973. ZeroMemory( pFreeData, sizeof(EAPFREE_DATA) );
  974. // Make sure we're configured with some list of
  975. // eap configuration options
  976. pListEaps = ReadEapcfgList( NULL );
  977. if (pListEaps == NULL)
  978. {
  979. Free(pFreeData);
  980. return ERROR_CAN_NOT_COMPLETE;
  981. }
  982. // for whistler 522872, use __leave instead of directly return in the __try
  983. // ..__finally block
  984. //
  985. __try {
  986. // Find the eap node we're interested in
  987. pEapcfgNode = EapcfgNodeFromKey(
  988. pListEaps,
  989. pEntry->dwCustomAuthKey );
  990. if (pEapcfgNode)
  991. pEapcfg = (EAPCFG*)DtlGetData( pEapcfgNode );
  992. else
  993. {
  994. dwErr = ERROR_CAN_NOT_COMPLETE;
  995. __leave;
  996. }
  997. // Only call eap identity ui if we're told not to
  998. // get the user name through the standard credentials
  999. // dialog
  1000. if (pEapcfg->dwStdCredentialFlags &
  1001. EAPCFG_FLAG_RequireUsername)
  1002. {
  1003. dwErr = NO_ERROR;
  1004. __leave;
  1005. }
  1006. if(!pInfo->pNoUser)
  1007. {
  1008. // Get the size of the input user data
  1009. dwErr = RasGetEapUserData(
  1010. NULL,
  1011. lpszPhonebook,
  1012. lpszEntry,
  1013. NULL,
  1014. &dwInSize);
  1015. // Read in the user data
  1016. if (dwErr != NO_ERROR)
  1017. {
  1018. if (dwErr == ERROR_BUFFER_TOO_SMALL)
  1019. {
  1020. if (dwInSize == 0)
  1021. {
  1022. pbUserIn = NULL;
  1023. // return ERROR_CAN_NOT_COMPLETE;
  1024. }
  1025. else
  1026. {
  1027. // Allocate a blob to hold the data
  1028. pbUserIn = Malloc (dwInSize);
  1029. if (pbUserIn == NULL)
  1030. {
  1031. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1032. __leave;
  1033. }
  1034. // Read in the new blob
  1035. dwErr = RasGetEapUserData(
  1036. NULL,
  1037. lpszPhonebook,
  1038. lpszEntry,
  1039. pbUserIn,
  1040. &dwInSize);
  1041. if (dwErr != NO_ERROR)
  1042. {
  1043. __leave;
  1044. }
  1045. }
  1046. }
  1047. else
  1048. {
  1049. __leave;
  1050. }
  1051. }
  1052. }
  1053. else
  1054. {
  1055. INTERNALARGS *piargs;
  1056. piargs = (INTERNALARGS *) pInfo->pArgs->reserved;
  1057. if( (NULL != piargs)
  1058. && (NULL != piargs->pvEapInfo)
  1059. // pmay: 386489
  1060. //
  1061. && (pEntry->dwCustomAuthKey == EAPCFG_DefaultKey))
  1062. {
  1063. pbUserIn = (BYTE *) piargs->pvEapInfo;
  1064. dwInSize = ((EAPLOGONINFO *) piargs->pvEapInfo)->dwSize;
  1065. }
  1066. else
  1067. {
  1068. pbUserIn = NULL;
  1069. dwInSize = 0;
  1070. }
  1071. }
  1072. // Load the identity library
  1073. hLib = LoadLibrary (pEapcfg->pszIdentityDll);
  1074. if (hLib == NULL)
  1075. {
  1076. dwErr = GetLastError();
  1077. __leave;
  1078. }
  1079. // Get pointers to the functions we'll be needing
  1080. pIdenFunc = (RASEAPGETIDENTITY)
  1081. GetProcAddress(hLib, "RasEapGetIdentity");
  1082. pFreeFunc = (RASEAPFREE) GetProcAddress(hLib, "RasEapFreeMemory");
  1083. if ( (pFreeFunc == NULL) || (pIdenFunc == NULL) )
  1084. {
  1085. dwErr = ERROR_CAN_NOT_COMPLETE;
  1086. __leave;
  1087. }
  1088. dwFlags = (pInfo->pNoUser) ? RAS_EAP_FLAG_LOGON : 0;
  1089. if (!pEntry->fAutoLogon && pEntry->fPreviewUserPw)
  1090. {
  1091. dwFlags |= RAS_EAP_FLAG_PREVIEW;
  1092. }
  1093. if(pInfo->fUnattended)
  1094. {
  1095. dwFlags &= ~RAS_EAP_FLAG_PREVIEW;
  1096. }
  1097. dwErr = DwGetCustomAuthData(
  1098. pEntry,
  1099. &cbData,
  1100. &pbData);
  1101. if(ERROR_SUCCESS != dwErr)
  1102. {
  1103. __leave;
  1104. }
  1105. // Call the eap-provided identity UI
  1106. dwErr = (*(pIdenFunc))(
  1107. pEntry->dwCustomAuthKey,
  1108. hwndOwner,
  1109. dwFlags,
  1110. lpszPhonebook,
  1111. lpszEntry,
  1112. pbData,
  1113. cbData,
  1114. pbUserIn,
  1115. dwInSize,
  1116. ppUserDataOut,
  1117. lpdwSizeOfUserDataOut,
  1118. lplpwszIdentity);
  1119. if (dwErr != NO_ERROR)
  1120. {
  1121. __leave;
  1122. }
  1123. // Assign the data used to cleanup later
  1124. pFreeData->bInitialized = TRUE;
  1125. pFreeData->hLib = hLib;
  1126. pFreeData->pFreeFunc = pFreeFunc;
  1127. *phFree = (HANDLE)pFreeData;
  1128. }
  1129. __finally {
  1130. if (pListEaps)
  1131. {
  1132. DtlDestroyList(pListEaps, NULL);
  1133. }
  1134. if ( (!pInfo->pNoUser)
  1135. && (pbUserIn))
  1136. {
  1137. Free0(pbUserIn);
  1138. }
  1139. if ((pFreeData) && (!pFreeData->bInitialized))
  1140. {
  1141. Free(pFreeData);
  1142. if(NULL != hLib)
  1143. {
  1144. FreeLibrary(hLib);
  1145. }
  1146. }
  1147. }
  1148. return dwErr;
  1149. }
  1150. DWORD
  1151. DialerEapCleanup (
  1152. IN HANDLE hEapFree,
  1153. IN PBYTE pUserDataOut,
  1154. IN LPWSTR lpwszIdentity)
  1155. {
  1156. EAPFREE_DATA * pFreeData = (EAPFREE_DATA*)hEapFree;
  1157. if (pFreeData == NULL)
  1158. return ERROR_INVALID_PARAMETER;
  1159. if (pFreeData->pFreeFunc) {
  1160. if (pUserDataOut)
  1161. (*(pFreeData->pFreeFunc))(pUserDataOut);
  1162. if (lpwszIdentity)
  1163. (*(pFreeData->pFreeFunc))((BYTE*)lpwszIdentity);
  1164. }
  1165. if (pFreeData->hLib)
  1166. FreeLibrary(pFreeData->hLib);
  1167. Free (pFreeData);
  1168. return NO_ERROR;
  1169. }
  1170. //
  1171. // Customizes the dialer flags for the eap provider
  1172. // of the given entry;
  1173. //
  1174. // TODO -- try to optimize this. The list of eaps
  1175. // may not need to be read if we keep enough state
  1176. // in the phonebook.
  1177. //
  1178. DWORD DialerEapAssignMode(
  1179. IN DINFO* pInfo,
  1180. OUT LPDWORD lpdwfMode)
  1181. {
  1182. DWORD dwfMode = *lpdwfMode;
  1183. DTLLIST * pListEaps;
  1184. DTLNODE * pEapcfgNode;
  1185. EAPCFG * pEapcfg;
  1186. // If eap is not used in this entry,
  1187. // then no action is required
  1188. if (! (pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP))
  1189. return NO_ERROR;
  1190. // Make sure we're configured with some list of
  1191. // eap configuration options
  1192. pListEaps = ReadEapcfgList( NULL );
  1193. if (pListEaps == NULL)
  1194. return ERROR_CAN_NOT_COMPLETE;
  1195. // Find the eap node we're interested in
  1196. pEapcfgNode = EapcfgNodeFromKey(
  1197. pListEaps,
  1198. pInfo->pEntry->dwCustomAuthKey );
  1199. if (pEapcfgNode)
  1200. pEapcfg = (EAPCFG*)DtlGetData( pEapcfgNode );
  1201. else
  1202. {
  1203. if (pListEaps)
  1204. DtlDestroyList(pListEaps, NULL);
  1205. return ERROR_CAN_NOT_COMPLETE;
  1206. }
  1207. // If eap provider requests user name then
  1208. // request identity.
  1209. if (pEapcfg->dwStdCredentialFlags &
  1210. EAPCFG_FLAG_RequireUsername
  1211. )
  1212. {
  1213. // Use the "I" flavors if the eap wants a user
  1214. // name but no password.
  1215. //
  1216. if (!(pEapcfg->dwStdCredentialFlags &
  1217. EAPCFG_FLAG_RequirePassword)
  1218. )
  1219. {
  1220. // Clear the username+password property (DR_U) if it
  1221. // exists and replace it with the username property
  1222. // (DR_I). Only do this if DR_U is already set. It
  1223. // wont be set for autodial connections or for connections
  1224. // where that option was specifically disabled as can
  1225. // be seen in the DialerDlg function.
  1226. //
  1227. // See whistler bug 30841
  1228. //
  1229. if (dwfMode & DR_U)
  1230. {
  1231. dwfMode &= ~DR_U;
  1232. dwfMode |= DR_I;
  1233. }
  1234. }
  1235. }
  1236. else
  1237. {
  1238. // Otherwise, make sure that we request neither user name nor password
  1239. // Since domain cannot appear without username clear that also.
  1240. //
  1241. dwfMode &= ~(DR_U | DR_D);
  1242. // For whistler bug 500731 gangz
  1243. if ( 0 == dwfMode &&
  1244. (pInfo->pEntry->fPreviewUserPw)
  1245. )
  1246. {
  1247. dwfMode |= DR_B;
  1248. }
  1249. }
  1250. // Cleanup
  1251. if (pListEaps)
  1252. DtlDestroyList(pListEaps, NULL);
  1253. // Assign the correct mode
  1254. *lpdwfMode = dwfMode;
  1255. return NO_ERROR;
  1256. }
  1257. BOOL APIENTRY
  1258. RasDialDlgA(
  1259. IN LPSTR lpszPhonebook,
  1260. IN LPSTR lpszEntry,
  1261. IN LPSTR lpszPhoneNumber,
  1262. IN OUT LPRASDIALDLG lpInfo )
  1263. // Win32 ANSI entrypoint that displays the dial progress and related
  1264. // dialogs, including authentication, error w/redial, callback, and retry
  1265. // authentication. 'LpszPhonebook' is the full path the phonebook or NULL
  1266. // indicating the default phonebook. 'LpszEntry' is the entry to dial.
  1267. // 'LpszPhoneNumber' is caller's override phone number or NULL to use the
  1268. // one in the entry. 'LpInfo' is caller's additional input/output
  1269. // parameters.
  1270. //
  1271. // Returns true if user establishes a connection, false otherwise.
  1272. //
  1273. {
  1274. WCHAR* pszPhonebookW;
  1275. WCHAR* pszEntryW;
  1276. WCHAR* pszPhoneNumberW;
  1277. BOOL fStatus;
  1278. TRACE( "RasDialDlgA" );
  1279. if (!lpInfo)
  1280. {
  1281. SetLastError( ERROR_INVALID_PARAMETER );
  1282. return FALSE;
  1283. }
  1284. if (!lpszEntry)
  1285. {
  1286. lpInfo->dwError = ERROR_INVALID_PARAMETER;
  1287. return FALSE;
  1288. }
  1289. if (lpInfo->dwSize != sizeof(RASDIALDLG))
  1290. {
  1291. lpInfo->dwError = ERROR_INVALID_SIZE;
  1292. return FALSE;
  1293. }
  1294. // Thunk "A" arguments to "W" arguments.
  1295. //
  1296. if (lpszPhonebook)
  1297. {
  1298. pszPhonebookW = StrDupTFromAUsingAnsiEncoding( lpszPhonebook );
  1299. if (!pszPhonebookW)
  1300. {
  1301. lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
  1302. return FALSE;
  1303. }
  1304. }
  1305. else
  1306. {
  1307. pszPhonebookW = NULL;
  1308. }
  1309. pszEntryW = StrDupTFromAUsingAnsiEncoding( lpszEntry );
  1310. if (!pszEntryW)
  1311. {
  1312. Free0( pszPhonebookW );
  1313. lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
  1314. return FALSE;
  1315. }
  1316. if (lpszPhoneNumber)
  1317. {
  1318. pszPhoneNumberW = StrDupTFromAUsingAnsiEncoding( lpszPhoneNumber );
  1319. if (!pszPhoneNumberW)
  1320. {
  1321. Free0( pszPhonebookW );
  1322. Free( pszEntryW );
  1323. lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
  1324. return FALSE;
  1325. }
  1326. }
  1327. else
  1328. {
  1329. pszPhoneNumberW = NULL;
  1330. }
  1331. // Thunk to the equivalent "W" API.
  1332. //
  1333. fStatus = RasDialDlgW( pszPhonebookW, pszEntryW, pszPhoneNumberW, lpInfo );
  1334. Free0( pszPhonebookW );
  1335. Free( pszEntryW );
  1336. return fStatus;
  1337. }
  1338. DWORD
  1339. DoEapProcessing(
  1340. LPRASDIALDLG lpInfo,
  1341. DINFO *pInfo,
  1342. PBYTE *ppbEapUserData,
  1343. WCHAR **ppwszEapIdentity,
  1344. HANDLE *phEapFree,
  1345. BOOL *pfStatus
  1346. )
  1347. {
  1348. // If this is an eap connection, then use the eap identity
  1349. // ui to get the user name and password.
  1350. //
  1351. DWORD dwSize = 0;
  1352. DWORD dwErr = NO_ERROR;
  1353. *pfStatus = TRUE;
  1354. // Bring up the Eap dialer dialog
  1355. dwErr = DialerDlgEap(
  1356. lpInfo->hwndOwner,
  1357. pInfo->pFile->pszPath,
  1358. pInfo->pEntry->pszEntryName,
  1359. pInfo->pEntry,
  1360. pInfo,
  1361. ppbEapUserData,
  1362. &dwSize,
  1363. ppwszEapIdentity,
  1364. phEapFree);
  1365. if (dwErr != NO_ERROR)
  1366. {
  1367. if (ERROR_CANCELLED == dwErr)
  1368. {
  1369. dwErr = NO_ERROR;
  1370. }
  1371. *pfStatus = FALSE;
  1372. goto done;
  1373. }
  1374. if(!pInfo->pNoUser)
  1375. {
  1376. // Set the extended dial params accordingly
  1377. pInfo->rde.RasEapInfo.dwSizeofEapInfo = dwSize;
  1378. pInfo->rde.RasEapInfo.pbEapInfo = *ppbEapUserData;
  1379. }
  1380. else if ( (*ppbEapUserData != NULL)
  1381. && (dwSize != 0))
  1382. {
  1383. pInfo->rde.RasEapInfo.dwSizeofEapInfo = dwSize;
  1384. pInfo->rde.RasEapInfo.pbEapInfo = *ppbEapUserData;
  1385. }
  1386. else
  1387. {
  1388. INTERNALARGS *piargs;
  1389. piargs = (INTERNALARGS *) (pInfo->pArgs->reserved);
  1390. if( (NULL != piargs)
  1391. && (NULL != piargs->pvEapInfo)
  1392. // pmay: 386489
  1393. //
  1394. && (pInfo->pEntry->dwCustomAuthKey == EAPCFG_DefaultKey))
  1395. {
  1396. pInfo->rde.RasEapInfo.dwSizeofEapInfo =
  1397. ((EAPLOGONINFO *) piargs->pvEapInfo)->dwSize;
  1398. pInfo->rde.RasEapInfo.pbEapInfo = (BYTE *) piargs->pvEapInfo;
  1399. }
  1400. else
  1401. {
  1402. pInfo->rde.RasEapInfo.dwSizeofEapInfo = 0;
  1403. pInfo->rde.RasEapInfo.pbEapInfo = NULL;
  1404. }
  1405. }
  1406. if (*ppwszEapIdentity)
  1407. {
  1408. DWORD dwSizeTmp =
  1409. sizeof(pInfo->rdp.szUserName) / sizeof(WCHAR);
  1410. wcsncpy(pInfo->rdp.szUserName, *ppwszEapIdentity,
  1411. dwSizeTmp - 1);
  1412. pInfo->rdp.szUserName[dwSizeTmp - 1] = 0;
  1413. // Ignore the domain setting if the EAP supplied the
  1414. // identity.
  1415. pInfo->rdp.szDomain[ 0 ] = L'\0';
  1416. }
  1417. done:
  1418. return dwErr;
  1419. }
  1420. INT
  1421. DialDlgDisplayError(
  1422. IN LPRASDIALDLG pInfo,
  1423. IN HWND hwndOwner,
  1424. IN DWORD dwSid,
  1425. IN DWORD dwError,
  1426. IN ERRORARGS* pArgs)
  1427. {
  1428. if (pInfo->dwFlags & RASDDFLAG_NoPrompt)
  1429. {
  1430. return 0;
  1431. }
  1432. return ErrorDlg(hwndOwner, dwSid, dwError, pArgs);
  1433. }
  1434. BOOL APIENTRY
  1435. RasDialDlgW(
  1436. IN LPWSTR lpszPhonebook,
  1437. IN LPWSTR lpszEntry,
  1438. IN LPWSTR lpszPhoneNumber,
  1439. IN OUT LPRASDIALDLG lpInfo )
  1440. // Win32 UNICODE entrypoint that displays the dial progress and related
  1441. // dialogs, including authentication, error w/redial, callback, and retry
  1442. // authentication. 'LpszPhonebook' is the full path the phonebook or NULL
  1443. // indicating the default phonebook. 'LpszEntry' is the entry to dial.
  1444. // 'LpszPhoneNumber' is caller's override phone number or NULL to use the
  1445. // one in the entry. 'LpInfo' is caller's additional input/output
  1446. // parameters.
  1447. //
  1448. // Returns true if user establishes a connection, false otherwise. If
  1449. // 'RASDDFLAG_AutoDialQueryOnly' is set, returns true if user pressed
  1450. // "Dial", false otherwise.
  1451. //
  1452. {
  1453. DWORD dwErr;
  1454. BOOL fStatus;
  1455. BOOL fFirstPass;
  1456. DINFO* pInfo;
  1457. LPWSTR pwszEapIdentity = NULL;
  1458. PBYTE pbEapUserData = NULL;
  1459. HANDLE hEapFree = NULL;
  1460. BOOL fCustom = FALSE;
  1461. PVOID pvInfo = NULL;
  1462. HRASCONN hrasconnPrereq = NULL;
  1463. TRACE( "RasDialDlgW" );
  1464. if (!lpInfo)
  1465. {
  1466. SetLastError( ERROR_INVALID_PARAMETER );
  1467. return FALSE;
  1468. }
  1469. if (!lpszEntry)
  1470. {
  1471. lpInfo->dwError = ERROR_INVALID_PARAMETER;
  1472. return FALSE;
  1473. }
  1474. if (lpInfo->dwSize != sizeof(RASDIALDLG))
  1475. {
  1476. lpInfo->dwError = ERROR_INVALID_SIZE;
  1477. return FALSE;
  1478. }
  1479. if (lpszPhoneNumber && lstrlen( lpszPhoneNumber ) > RAS_MaxPhoneNumber)
  1480. {
  1481. lpInfo->dwError = ERROR_INVALID_PARAMETER;
  1482. return FALSE;
  1483. }
  1484. // Load RAS DLL entrypoints which starts RASMAN, if necessary.
  1485. //
  1486. lpInfo->dwError = LoadRas( g_hinstDll, lpInfo->hwndOwner );
  1487. if (lpInfo->dwError != 0)
  1488. {
  1489. // Whistler bug 301784
  1490. //
  1491. // Check specifically for access denied.
  1492. //
  1493. if (lpInfo->dwError == ERROR_ACCESS_DENIED)
  1494. {
  1495. DialDlgDisplayError(
  1496. lpInfo,
  1497. lpInfo->hwndOwner,
  1498. SID_OP_LoadRasAccessDenied,
  1499. lpInfo->dwError,
  1500. NULL );
  1501. }
  1502. else
  1503. {
  1504. DialDlgDisplayError(
  1505. lpInfo,
  1506. lpInfo->hwndOwner,
  1507. SID_OP_LoadRas,
  1508. lpInfo->dwError,
  1509. NULL );
  1510. }
  1511. return FALSE;
  1512. }
  1513. // Allocate the context information block and initialize it enough so that
  1514. // it can be destroyed properly.
  1515. //
  1516. pInfo = Malloc( sizeof(*pInfo) );
  1517. if (!pInfo)
  1518. {
  1519. DialDlgDisplayError(
  1520. lpInfo,
  1521. lpInfo->hwndOwner,
  1522. SID_OP_LoadDlg,
  1523. ERROR_NOT_ENOUGH_MEMORY,
  1524. NULL );
  1525. lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
  1526. return FALSE;
  1527. }
  1528. ZeroMemory( pInfo, sizeof(*pInfo) );
  1529. pInfo->pszPhonebook = lpszPhonebook;
  1530. pInfo->pszEntry = lpszEntry;
  1531. pInfo->pszPhoneNumber = lpszPhoneNumber;
  1532. pInfo->pArgs = lpInfo;
  1533. fStatus = FALSE;
  1534. dwErr = 0;
  1535. do
  1536. {
  1537. // Load the phonebook file and user preferences, or figure out that
  1538. // caller has already loaded them.
  1539. //
  1540. if (lpInfo->reserved)
  1541. {
  1542. INTERNALARGS* piargs;
  1543. // We've received an open phonebook file and user preferences via
  1544. // the secret hack.
  1545. //
  1546. piargs = (INTERNALARGS* )lpInfo->reserved;
  1547. pInfo->pFile = pInfo->pFileMain = piargs->pFile;
  1548. pInfo->pUser = piargs->pUser;
  1549. pInfo->pNoUser = piargs->pNoUser;
  1550. pInfo->pfNoUserChanged = &piargs->fNoUserChanged;
  1551. pInfo->fMoveOwnerOffDesktop = piargs->fMoveOwnerOffDesktop;
  1552. pInfo->fForceCloseOnDial = piargs->fForceCloseOnDial;
  1553. }
  1554. else
  1555. {
  1556. // Read user preferences from registry.
  1557. //
  1558. dwErr = g_pGetUserPreferences( NULL, &pInfo->user, UPM_Normal );
  1559. if (dwErr != 0)
  1560. {
  1561. DialDlgDisplayError(
  1562. lpInfo,
  1563. lpInfo->hwndOwner,
  1564. SID_OP_LoadPrefs,
  1565. dwErr,
  1566. NULL );
  1567. break;
  1568. }
  1569. pInfo->pUser = &pInfo->user;
  1570. // Load and parse the phonebook file.
  1571. //
  1572. dwErr = ReadPhonebookFile(
  1573. lpszPhonebook, &pInfo->user, NULL, 0, &pInfo->file );
  1574. if (dwErr != 0)
  1575. {
  1576. DialDlgDisplayError(
  1577. lpInfo,
  1578. lpInfo->hwndOwner,
  1579. SID_OP_LoadPhonebook,
  1580. dwErr,
  1581. NULL );
  1582. break;
  1583. }
  1584. pInfo->pFile = pInfo->pFileMain = &pInfo->file;
  1585. }
  1586. // Record whether this is a for-all-users phonebook
  1587. //
  1588. // Whistler bug 288596 Autodial has wrong save password option marked -
  1589. // prompts user to save password for all users
  1590. //
  1591. pInfo->fIsPublicPbk =
  1592. (!pInfo->pszPhonebook) || IsPublicPhonebook(pInfo->pszPhonebook);
  1593. if (!pInfo->pNoUser)
  1594. {
  1595. DWORD dwErrR;
  1596. HKEY hkey;
  1597. // See if admin has disabled the "save password" feature.
  1598. //
  1599. pInfo->fDisableSavePw = FALSE;
  1600. dwErrR = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1601. TEXT("SYSTEM\\CurrentControlSet\\Services\\RasMan\\Parameters"),
  1602. 0, KEY_READ, &hkey );
  1603. if (dwErrR == 0)
  1604. {
  1605. DWORD dwResult;
  1606. dwResult = (DWORD )pInfo->fDisableSavePw;
  1607. GetRegDword( hkey, TEXT("DisableSavePassword"), &dwResult );
  1608. pInfo->fDisableSavePw = (BOOL )dwResult;
  1609. RegCloseKey( hkey );
  1610. }
  1611. }
  1612. // Hide parent dialog when initiated by another RAS API that requests
  1613. // it. This is the first stage of "close on dial" behavior, allowing
  1614. // the parent to appear closed to user though, as owner, it must
  1615. // really stay open until the dial dialogs complete. At that point it
  1616. // can silently close or reappear as desired.
  1617. //
  1618. if (lpInfo->hwndOwner && pInfo->fMoveOwnerOffDesktop)
  1619. {
  1620. SetOffDesktop( lpInfo->hwndOwner, SOD_MoveOff, NULL );
  1621. }
  1622. // Set true initially, but will be set false by
  1623. // FindEntryAndSetDialParams if the entry has no "dial first" entry
  1624. // associated with it.
  1625. //
  1626. pInfo->fPrerequisiteDial = TRUE;
  1627. fFirstPass = TRUE;
  1628. for (;;)
  1629. {
  1630. pInfo->fDialForReferenceOnly = FALSE;
  1631. // Look up the entry and fill in the RASDIALPARAMS structure
  1632. // accordingly. This done as a routine so it can be re-done
  1633. // should user press the Properties button.
  1634. //
  1635. dwErr = FindEntryAndSetDialParams( pInfo );
  1636. if (dwErr != 0)
  1637. {
  1638. // we need to maintain 2 phonebooks
  1639. // but we need to do this in case we break existing
  1640. // apps which look specifically in system\ras dir.
  1641. // Feel free to rip this code off, if you feel
  1642. // strongly about it.
  1643. //
  1644. if( (ERROR_CANNOT_FIND_PHONEBOOK_ENTRY == dwErr)
  1645. && (NULL == lpszPhonebook))
  1646. {
  1647. DTLNODE *pNode;
  1648. //
  1649. // Close the all users phonebook file
  1650. //
  1651. ClosePhonebookFile(&pInfo->file);
  1652. dwErr = GetPbkAndEntryName(
  1653. lpszPhonebook,
  1654. lpszEntry,
  1655. 0,
  1656. &pInfo->file,
  1657. &pNode);
  1658. if( (NULL == pNode)
  1659. || (ERROR_SUCCESS != dwErr))
  1660. {
  1661. dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
  1662. break;
  1663. }
  1664. pInfo->pFile = pInfo->pFileMain = &pInfo->file;
  1665. dwErr = FindEntryAndSetDialParams(pInfo);
  1666. if(dwErr != 0)
  1667. {
  1668. break;
  1669. }
  1670. }
  1671. else
  1672. {
  1673. break;
  1674. }
  1675. }
  1676. if(lpInfo->reserved)
  1677. {
  1678. INTERNALARGS *piargs = (INTERNALARGS *) lpInfo->reserved;
  1679. if (pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP)
  1680. {
  1681. pvInfo = piargs->pvEapInfo;
  1682. }
  1683. else
  1684. {
  1685. pvInfo = piargs->pNoUser;
  1686. }
  1687. }
  1688. if(pInfo->fPrerequisiteDial
  1689. && (NULL != pInfo->pEntry->pszCustomDialerName)
  1690. && (TEXT('\0') != pInfo->pEntry->pszCustomDialerName[0]))
  1691. {
  1692. RASDIALDLG Info;
  1693. DWORD dwCustomFlags = 0;
  1694. RASNOUSER nouser, *pNoUser = NULL;
  1695. ZeroMemory(&Info, sizeof(RASDIALDLG));
  1696. ZeroMemory(&nouser, sizeof(RASNOUSER));
  1697. Info.dwSize = sizeof(RASDIALDLG);
  1698. Info.hwndOwner = lpInfo->hwndOwner;
  1699. Info.xDlg = lpInfo->xDlg;
  1700. Info.yDlg = lpInfo->yDlg;
  1701. fCustom = TRUE;
  1702. if(pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP)
  1703. {
  1704. dwCustomFlags |= RCD_Eap;
  1705. }
  1706. if( (NULL != pInfo->pNoUser)
  1707. && (RASNOUSER_SmartCard & pInfo->pNoUser->dwFlags)
  1708. && ( (0 == (dwCustomFlags & RCD_Eap))
  1709. || (EAP_RASTLS != pInfo->pEntry->dwCustomAuthKey)
  1710. ))
  1711. {
  1712. CopyMemory(&nouser, pInfo->pNoUser, sizeof(RASNOUSER));
  1713. RtlSecureZeroMemory(nouser.szPassword, (PWLEN+1) * sizeof(TCHAR));
  1714. pvInfo = &nouser;
  1715. }
  1716. // DwCustomDialDlg returns ERROR_SUCCESS if it handled
  1717. // the CustomRasDial. returns E_NOINTERFACE otherwise
  1718. // which implies that there is no custom dlg interface
  1719. // supported for this entry and the default dial should
  1720. // happen
  1721. //
  1722. // Whistler bug 314578 When connecting with CM via Winlogon I
  1723. // get the following error "Error 1: Incorrect function"
  1724. //
  1725. // This is a case where we call into a custom dialer, ie CM,
  1726. // and we are using creds that we got from winlogon. They are
  1727. // currently encoded and must be decoded before we call out.
  1728. // We have to assume that the Custom Dialer leaves the password
  1729. // un-encoded upon return.
  1730. //
  1731. if ( !(pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP) )
  1732. {
  1733. // pNoUser is used to encode/decode passwords. If this
  1734. // is an EAP connection, then pvInfo will point to an
  1735. // eap blob, not a "no user" blob.
  1736. //
  1737. pNoUser = pvInfo;
  1738. }
  1739. if ( pNoUser )
  1740. {
  1741. DecodePassword( pNoUser->szPassword );
  1742. }
  1743. if(pInfo->pNoUser)
  1744. {
  1745. dwCustomFlags |= RCD_Logon;
  1746. }
  1747. dwErr = DwCustomDialDlg(pInfo->pFile->pszPath,
  1748. pInfo->pEntry->pszEntryName,
  1749. NULL,
  1750. &Info,
  1751. dwCustomFlags,
  1752. &fStatus,
  1753. pvInfo,
  1754. pInfo->pEntry->pszCustomDialerName);
  1755. if ( pNoUser )
  1756. {
  1757. EncodePassword( pNoUser->szPassword );
  1758. }
  1759. if(!fStatus)
  1760. {
  1761. lpInfo->dwError = Info.dwError;
  1762. break;
  1763. }
  1764. else
  1765. {
  1766. pInfo->fPrerequisiteDial = FALSE;
  1767. fCustom = FALSE;
  1768. continue;
  1769. }
  1770. }
  1771. else if ((NULL != pInfo->pEntry->pszCustomDialerName)
  1772. && (TEXT('\0') != pInfo->pEntry->pszCustomDialerName[0]))
  1773. {
  1774. DWORD dwCustomFlags = 0;
  1775. RASNOUSER nouser, *pNoUser = NULL;
  1776. ZeroMemory(&nouser, sizeof(RASNOUSER));
  1777. if(pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP)
  1778. {
  1779. dwCustomFlags |= RCD_Eap;
  1780. }
  1781. if( (NULL != pInfo->pNoUser)
  1782. && (RASNOUSER_SmartCard & pInfo->pNoUser->dwFlags)
  1783. && ( (0 == (dwCustomFlags & RCD_Eap))
  1784. || (EAP_RASTLS != pInfo->pEntry->dwCustomAuthKey))
  1785. )
  1786. {
  1787. CopyMemory(&nouser, pInfo->pNoUser, sizeof(RASNOUSER));
  1788. RtlSecureZeroMemory(nouser.szPassword, (PWLEN+1) * sizeof(TCHAR));
  1789. pvInfo = &nouser;
  1790. }
  1791. fCustom = TRUE;
  1792. // DwCustomDialDlg returns ERROR_SUCCESS if it handled
  1793. // the CustomRasDial. returns E_NOINTERFACE otherwise
  1794. // which implies that there is no custom dlg interface
  1795. // supported for this entry and the default dial should
  1796. // happen
  1797. //
  1798. // Whistler bug 314578 When connecting with CM via Winlogon I
  1799. // get the following error "Error 1: Incorrect function"
  1800. //
  1801. // This is a case where we call into a custom dialer, ie CM,
  1802. // and we are using creds that we got from winlogon. They are
  1803. // currently encoded and must be decoded before we call out.
  1804. // We have to assume that the Custom Dialer leaves the password
  1805. // un-encoded upon return.
  1806. //
  1807. if ( !(pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP) )
  1808. {
  1809. // pNoUser is used to encode/decode passwords. If this
  1810. // is an EAP connection, then pvInfo will point to an
  1811. // eap blob, not a "no user" blob.
  1812. //
  1813. pNoUser = pvInfo;
  1814. }
  1815. if ( pNoUser )
  1816. {
  1817. DecodePassword( pNoUser->szPassword );
  1818. }
  1819. if(pInfo->pNoUser)
  1820. {
  1821. dwCustomFlags |= RCD_Logon;
  1822. }
  1823. dwErr = DwCustomDialDlg(lpszPhonebook,
  1824. lpszEntry,
  1825. lpszPhoneNumber,
  1826. lpInfo,
  1827. dwCustomFlags,
  1828. &fStatus,
  1829. pvInfo,
  1830. pInfo->pEntry->pszCustomDialerName);
  1831. if ( pNoUser )
  1832. {
  1833. EncodePassword( pNoUser->szPassword );
  1834. }
  1835. break;
  1836. }
  1837. // If a prerequisite entry is already connected, there's no need
  1838. // for any UI but the dial must occur to set the reference in the
  1839. // RASAPI level.
  1840. //
  1841. if (pInfo->fPrerequisiteDial
  1842. && HrasconnFromEntry(
  1843. pInfo->pFile->pszPath, pInfo->pEntry->pszEntryName ))
  1844. {
  1845. pInfo->fDialForReferenceOnly = TRUE;
  1846. }
  1847. // Set up extension parameter block, except 'hwndOwner' which is
  1848. // set to the Dial Progress dialog window later.
  1849. //
  1850. {
  1851. RASDIALEXTENSIONS* prde = &pInfo->rde;
  1852. ZeroMemory( prde, sizeof(*prde) );
  1853. prde->dwSize = sizeof(*prde);
  1854. prde->dwfOptions = RDEOPT_PausedStates | RDEOPT_PauseOnScript;
  1855. if (pInfo->pNoUser)
  1856. {
  1857. prde->dwfOptions |= RDEOPT_NoUser;
  1858. }
  1859. if (!pInfo->pszPhoneNumber)
  1860. {
  1861. prde->dwfOptions |= RDEOPT_UsePrefixSuffix;
  1862. }
  1863. }
  1864. if ( (pInfo->fUnattended)
  1865. && ((HaveSavedPw( pInfo ))
  1866. || (pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP)))
  1867. {
  1868. // Popup the countdown to link failure redial version of the
  1869. // dial error dialog, which will lead to a dial unless user
  1870. // stops it.
  1871. //
  1872. fStatus = DialErrorDlg(
  1873. lpInfo->hwndOwner,
  1874. pInfo, // For whistler 474514
  1875. pInfo->pszPhonebook, // For whislter 460931
  1876. pInfo->pEntry->pszEntryName,
  1877. 0, 0, NULL, 0, NULL,
  1878. GetOverridableParam(
  1879. pInfo->pUser, pInfo->pEntry, RASOR_RedialSeconds ),
  1880. GetOverridableParam(
  1881. pInfo->pUser, pInfo->pEntry,
  1882. RASOR_PopupOnTopWhenRedialing ) );
  1883. if(!fStatus)
  1884. {
  1885. break;
  1886. }
  1887. if (pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP)
  1888. {
  1889. dwErr = DoEapProcessing(
  1890. lpInfo,
  1891. pInfo,
  1892. &pbEapUserData,
  1893. &pwszEapIdentity,
  1894. &hEapFree,
  1895. &fStatus);
  1896. if( (NO_ERROR != dwErr)
  1897. || (!fStatus))
  1898. {
  1899. break;
  1900. }
  1901. }
  1902. }
  1903. else if (!pInfo->fDialForReferenceOnly)
  1904. {
  1905. if (!pInfo->fUnattended && fFirstPass)
  1906. {
  1907. // Warn about active NWC LAN connections being blown away,
  1908. // if indicated.
  1909. //
  1910. if (!NwConnectionCheck(
  1911. lpInfo->hwndOwner,
  1912. (pInfo->pArgs->dwFlags & RASDDFLAG_PositionDlg),
  1913. pInfo->pArgs->xDlg, pInfo->pArgs->yDlg,
  1914. pInfo->pFile, pInfo->pEntry ))
  1915. {
  1916. break;
  1917. }
  1918. // Popup the double-dial help popup, if indicated.
  1919. //
  1920. if (!VpnDoubleDialDlg( lpInfo->hwndOwner, pInfo ))
  1921. {
  1922. break;
  1923. }
  1924. }
  1925. // Check to see if its smartcardlogon case and blank
  1926. // out the password if its not an eap tls connectoid
  1927. //
  1928. if( (NULL != pInfo->pNoUser)
  1929. && (RASNOUSER_SmartCard & pInfo->pNoUser->dwFlags)
  1930. && (pInfo->pEntry->dwCustomAuthKey != EAP_RASTLS))
  1931. {
  1932. RtlSecureZeroMemory(pInfo->rdp.szPassword, (PWLEN+1) * sizeof(TCHAR));
  1933. }
  1934. // Prompt for credentials and/or phone number (or not)
  1935. // as configured in the entry properties.
  1936. //
  1937. if (!DialerDlg( lpInfo->hwndOwner, pInfo ))
  1938. {
  1939. if(!fFirstPass)
  1940. {
  1941. fStatus = FALSE;
  1942. }
  1943. break;
  1944. }
  1945. if (pInfo->pEntry->dwAuthRestrictions & AR_F_AuthEAP)
  1946. {
  1947. dwErr = DoEapProcessing(
  1948. lpInfo,
  1949. pInfo,
  1950. &pbEapUserData,
  1951. &pwszEapIdentity,
  1952. &hEapFree,
  1953. &fStatus);
  1954. if( (NO_ERROR != dwErr)
  1955. || (!fStatus))
  1956. {
  1957. break;
  1958. }
  1959. }
  1960. fStatus = TRUE;
  1961. }
  1962. else
  1963. {
  1964. fStatus = TRUE;
  1965. }
  1966. // Dial and show progress.
  1967. //
  1968. if (fStatus
  1969. && !fCustom)
  1970. {
  1971. // Clear this here because beyond this rasman
  1972. // will take care of dropping the prereq link
  1973. // since beyond this point rasdial api will get
  1974. // called. [raos]
  1975. //
  1976. hrasconnPrereq = NULL;
  1977. fStatus = DialProgressDlg( pInfo );
  1978. // Show connect complete dialog unless user has nixed it or
  1979. // it's a prerequisite dial.
  1980. // (AboladeG) Also suppress the dialog in no-prompt mode.
  1981. //
  1982. if (!pInfo->fPrerequisiteDial
  1983. && fStatus
  1984. && !pInfo->pUser->fSkipConnectComplete
  1985. && !(pInfo->pArgs->dwFlags & RASDDFLAG_NoPrompt))
  1986. {
  1987. //For whistler bug 378078 gangz
  1988. //We will comment out this status explaination dialog
  1989. //box because some users complained that it is confusing
  1990. //
  1991. // ConnectCompleteDlg( lpInfo->hwndOwner, pInfo );
  1992. }
  1993. }
  1994. // Don't loop a second time to dial the main entry if the
  1995. // prerequisite dial failed.
  1996. //
  1997. if (!fStatus || !pInfo->fPrerequisiteDial)
  1998. {
  1999. break;
  2000. }
  2001. // Save the rasconn of the prereq dial in case we need to hang
  2002. // it up for the case where the vpn dialog fails before rasdial
  2003. // gets called. [raos]
  2004. //
  2005. if (pInfo->fPrerequisiteDial)
  2006. {
  2007. hrasconnPrereq = HrasconnFromEntry(
  2008. pInfo->pFile->pszPath, pInfo->pEntry->pszEntryName);
  2009. }
  2010. pInfo->fPrerequisiteDial = FALSE;
  2011. fFirstPass = FALSE;
  2012. // Cleanup eap stuff
  2013. if (hEapFree)
  2014. {
  2015. DialerEapCleanup(hEapFree, pbEapUserData, pwszEapIdentity);
  2016. hEapFree = NULL;
  2017. pbEapUserData = NULL;
  2018. pwszEapIdentity = NULL;
  2019. }
  2020. }
  2021. }
  2022. while (FALSE);
  2023. // Unhide parent dialog when initiated by another RAS API.
  2024. //
  2025. if (lpInfo->hwndOwner && pInfo->fMoveOwnerOffDesktop
  2026. && (!fStatus
  2027. || !(pInfo->pUser->fCloseOnDial || pInfo->fForceCloseOnDial)))
  2028. {
  2029. SetOffDesktop( lpInfo->hwndOwner, SOD_MoveBackFree, NULL );
  2030. }
  2031. if(!fCustom)
  2032. {
  2033. // Save the several little user preferences adjustments we may have made.
  2034. //
  2035. g_pSetUserPreferences(
  2036. NULL, pInfo->pUser, (pInfo->pNoUser) ? UPM_Logon : UPM_Normal );
  2037. // Report error, if any.
  2038. //
  2039. if (dwErr)
  2040. {
  2041. DialDlgDisplayError(
  2042. lpInfo,
  2043. lpInfo->hwndOwner,
  2044. SID_OP_LoadDlg,
  2045. dwErr,
  2046. NULL );
  2047. lpInfo->dwError = dwErr;
  2048. }
  2049. TRACE1("hrasconnPrereq=0x%x",hrasconnPrereq);
  2050. //
  2051. // Drop the connection if we failed to connect the vpn connection
  2052. //
  2053. if( !fStatus
  2054. && (NULL != hrasconnPrereq)
  2055. && (pInfo->pEntry)
  2056. && (pInfo->pEntry->pszPrerequisiteEntry)
  2057. && *(pInfo->pEntry->pszPrerequisiteEntry))
  2058. {
  2059. g_pRasHangUp(hrasconnPrereq);
  2060. }
  2061. }
  2062. // Clean up.
  2063. //
  2064. if (!lpInfo->reserved)
  2065. {
  2066. if (pInfo->pFileMain)
  2067. {
  2068. ClosePhonebookFile( pInfo->pFileMain );
  2069. }
  2070. if (pInfo->pUser)
  2071. {
  2072. DestroyUserPreferences( pInfo->pUser );
  2073. }
  2074. }
  2075. if (pInfo->fFilePrereqOpen)
  2076. {
  2077. ClosePhonebookFile( &pInfo->filePrereq );
  2078. }
  2079. RtlSecureZeroMemory( pInfo->rdp.szPassword, sizeof(pInfo->rdp.szPassword) );
  2080. if (pInfo->pListPortsToDelete)
  2081. {
  2082. DtlDestroyList( pInfo->pListPortsToDelete, DestroyPszNode );
  2083. }
  2084. if (hEapFree)
  2085. DialerEapCleanup(hEapFree, pbEapUserData, pwszEapIdentity);
  2086. Free( pInfo );
  2087. pInfo = NULL;
  2088. return fStatus;
  2089. }
  2090. //----------------------------------------------------------------------------
  2091. // Local utilities
  2092. // Listed alphabetically
  2093. //----------------------------------------------------------------------------
  2094. DWORD
  2095. RasCredToDialParam(
  2096. IN TCHAR* pszDefaultUserName,
  2097. IN TCHAR* pszDefaultDomain,
  2098. IN RASCREDENTIALS* pCreds,
  2099. OUT RASDIALPARAMS* pParams)
  2100. {
  2101. TCHAR* pszComputer = NULL;
  2102. TCHAR* pszLogonDomain = NULL;
  2103. TCHAR* pszUser = NULL;
  2104. // Set the user name, defaulting it if needed
  2105. //
  2106. if (pCreds->dwMask & RASCM_UserName)
  2107. {
  2108. lstrcpyn(
  2109. pParams->szUserName,
  2110. pCreds->szUserName,
  2111. sizeof(pParams->szUserName) / sizeof(TCHAR));
  2112. }
  2113. else if (pszDefaultUserName)
  2114. {
  2115. lstrcpyn(
  2116. pParams->szUserName,
  2117. pszDefaultUserName,
  2118. sizeof(pParams->szUserName) / sizeof(TCHAR));
  2119. }
  2120. else
  2121. {
  2122. pszUser = GetLogonUser();
  2123. if (pszUser)
  2124. {
  2125. lstrcpyn(
  2126. pParams->szUserName,
  2127. pszUser,
  2128. sizeof(pParams->szUserName) / sizeof(TCHAR));
  2129. }
  2130. }
  2131. // Set the domain name, defaulting it if needed
  2132. //
  2133. if (pCreds->dwMask & RASCM_Domain)
  2134. {
  2135. lstrcpyn(
  2136. pParams->szDomain,
  2137. pCreds->szDomain,
  2138. sizeof(pParams->szDomain) / sizeof(TCHAR));
  2139. }
  2140. else if ( pszDefaultDomain )
  2141. {
  2142. lstrcpyn(
  2143. pParams->szDomain,
  2144. pszDefaultDomain,
  2145. sizeof(pParams->szDomain) / sizeof(TCHAR));
  2146. }
  2147. else
  2148. {
  2149. pszComputer = GetComputer();
  2150. pszLogonDomain = GetLogonDomain();
  2151. if ( (pszComputer) &&
  2152. (pszLogonDomain) &&
  2153. (lstrcmp( pszComputer, pszLogonDomain ) != 0))
  2154. {
  2155. lstrcpyn(
  2156. pParams->szDomain,
  2157. pszLogonDomain,
  2158. sizeof(pParams->szDomain) / sizeof(TCHAR));
  2159. }
  2160. }
  2161. // Fill in the password field
  2162. //
  2163. if (pCreds->dwMask & RASCM_Password)
  2164. {
  2165. // Whistler bug 254385 encode password when not being used
  2166. // Assumed password was encoded previously
  2167. //
  2168. DecodePassword( pCreds->szPassword );
  2169. lstrcpyn(
  2170. pParams->szPassword,
  2171. pCreds->szPassword,
  2172. sizeof(pParams->szPassword) / sizeof(TCHAR) );
  2173. EncodePassword( pCreds->szPassword );
  2174. EncodePassword( pParams->szPassword );
  2175. }
  2176. return NO_ERROR;
  2177. }
  2178. DWORD
  2179. FindEntryCredentials(
  2180. IN TCHAR* pszPath,
  2181. IN TCHAR* pszEntryName,
  2182. IN TCHAR* pszDefaultUserName,
  2183. IN TCHAR* pszDefaultDomain,
  2184. OUT RASDIALPARAMS* pUser, // per user credentials
  2185. OUT RASDIALPARAMS* pGlobal, // global credentials
  2186. OUT BOOL* pfUser, // set true if per user creds found
  2187. OUT BOOL* pfGlobal // set true if global creds found
  2188. )
  2189. // Loads the credentials for the given entry into memory. This routine
  2190. // determines whether per-user or per-connection credentials exist or
  2191. // both.
  2192. //
  2193. // The logic is a little complicated because RasGetCredentials had to
  2194. // support legacy usage of the API.
  2195. //
  2196. // Here's how it works. If only one set of credentials is stored for a
  2197. // connection, then RasGetCredentials will return that set regardless of
  2198. // whether the RASCM_DefalutCreds flag is set. If two sets of credentials
  2199. // are saved, then RasGetCredentials will return the per-user credentials
  2200. // if the RASCM_DefaultCreds bit is set, and the per-connection credentials
  2201. // otherwise.
  2202. //
  2203. // Here is the algorithm for loading the credentials
  2204. //
  2205. // 1. Call RasGetCredentials with the RASCM_DefaultCreds bit cleared
  2206. // 1a. If nothing is returned, no credentials are saved
  2207. // 1b. If the RASCM_DefaultCreds bit is set on return, then only
  2208. // global credentials are saved.
  2209. //
  2210. // 2. Call RasGetCredentials with the RASCM_DefaultCreds bit set
  2211. // 2a. If the RASCM_DefaultCreds bit is set on return, then
  2212. // both global and per-connection credentials are saved.
  2213. // 2b. Otherwise, only per-user credentials are saved.
  2214. //
  2215. {
  2216. DWORD dwErr;
  2217. RASCREDENTIALS rc1, rc2;
  2218. BOOL fUseLogonDomain;
  2219. TRACE( "FindEntryCredentials" );
  2220. // Initialize
  2221. //
  2222. *pfUser = FALSE;
  2223. *pfGlobal = FALSE;
  2224. ZeroMemory( &rc1, sizeof(rc1) );
  2225. ZeroMemory( &rc2, sizeof(rc2) );
  2226. rc1.dwSize = sizeof(rc1);
  2227. rc2.dwSize = sizeof(rc2);
  2228. do
  2229. {
  2230. // Look up per-user cached username, password, and domain.
  2231. // See comment '1.' in the function header
  2232. //
  2233. rc1.dwMask = RASCM_UserName | RASCM_Password | RASCM_Domain;
  2234. ASSERT( g_pRasGetCredentials );
  2235. TRACE( "RasGetCredentials per-user" );
  2236. dwErr = g_pRasGetCredentials(pszPath, pszEntryName, &rc1 );
  2237. TRACE2( "RasGetCredentials=%d,m=%d", dwErr, rc1.dwMask );
  2238. if (dwErr != NO_ERROR)
  2239. {
  2240. break;
  2241. }
  2242. // See 1a. in the function header comments
  2243. //
  2244. if (rc1.dwMask == 0)
  2245. {
  2246. // No credentials are saved. pUser will be used for the
  2247. // connection in this case so initialize it to use the default
  2248. // user name and domain name. XP 446571
  2249. //
  2250. ZeroMemory(&rc1, sizeof(rc1));
  2251. RasCredToDialParam(
  2252. pszDefaultUserName,
  2253. pszDefaultDomain,
  2254. &rc1,
  2255. pUser );
  2256. dwErr = NO_ERROR;
  2257. break;
  2258. }
  2259. // See 1b. in the function header comments
  2260. //
  2261. else if (rc1.dwMask & RASCM_DefaultCreds)
  2262. {
  2263. *pfGlobal = TRUE;
  2264. // Whistler bug 254385 encode password when not being used
  2265. // Assumed password was not encoded by RasGetCredentials()
  2266. //
  2267. EncodePassword( rc1.szPassword );
  2268. RasCredToDialParam(
  2269. pszDefaultUserName,
  2270. pszDefaultDomain,
  2271. &rc1,
  2272. pGlobal );
  2273. dwErr = NO_ERROR;
  2274. break;
  2275. }
  2276. // Look up global per-user cached username, password, domain.
  2277. // See comment 2. in the function header
  2278. //
  2279. rc2.dwMask =
  2280. RASCM_UserName | RASCM_Password | RASCM_Domain | RASCM_DefaultCreds;
  2281. ASSERT( g_pRasGetCredentials );
  2282. TRACE( "RasGetCredentials global" );
  2283. dwErr = g_pRasGetCredentials(pszPath, pszEntryName, &rc2 );
  2284. TRACE2( "RasGetCredentials=%d,m=%d", dwErr, rc2.dwMask );
  2285. if (dwErr != NO_ERROR)
  2286. {
  2287. break;
  2288. }
  2289. // See 2a. in the function header comments
  2290. //
  2291. if (rc2.dwMask & RASCM_DefaultCreds)
  2292. {
  2293. *pfGlobal = TRUE;
  2294. if (rc1.dwMask & RASCM_Password)
  2295. {
  2296. *pfUser = TRUE;
  2297. }
  2298. // Whistler bug 254385 encode password when not being used
  2299. // Assumed password was not encoded by RasGetCredentials()
  2300. //
  2301. EncodePassword( rc1.szPassword );
  2302. RasCredToDialParam(
  2303. pszDefaultUserName,
  2304. pszDefaultDomain,
  2305. &rc1,
  2306. pUser );
  2307. EncodePassword( rc2.szPassword );
  2308. RasCredToDialParam(
  2309. pszDefaultUserName,
  2310. pszDefaultDomain,
  2311. &rc2,
  2312. pGlobal );
  2313. }
  2314. // See 2b. in the function header comments
  2315. //
  2316. else
  2317. {
  2318. if (rc1.dwMask & RASCM_Password)
  2319. {
  2320. *pfUser = TRUE;
  2321. }
  2322. // Whistler bug 254385 encode password when not being used
  2323. // Assumed password was not encoded by RasGetCredentials()
  2324. //
  2325. EncodePassword( rc1.szPassword );
  2326. RasCredToDialParam(
  2327. pszDefaultUserName,
  2328. pszDefaultDomain,
  2329. &rc1,
  2330. pUser );
  2331. }
  2332. }while (FALSE);
  2333. // Cleanup
  2334. //
  2335. {
  2336. // Whistler bug 254385 encode password when not being used
  2337. //
  2338. RtlSecureZeroMemory( rc1.szPassword, sizeof(rc1.szPassword) );
  2339. RtlSecureZeroMemory( rc2.szPassword, sizeof(rc2.szPassword) );
  2340. }
  2341. return dwErr;
  2342. }
  2343. DWORD
  2344. FindEntryAndSetDialParams(
  2345. IN DINFO* pInfo )
  2346. // Look up the entry and fill in the RASDIALPARAMS parameters accordingly.
  2347. // This routine contains all DINFO context initialization that can be
  2348. // affected by user actions on the property sheet. 'PInfo' is the
  2349. // partially initialized common dial dialog context.
  2350. //
  2351. // 'pInfo->fPrerequisiteDial'is set at entry if the prerequisite entry, if
  2352. // any, should be dialed first. If there is no prerequisite entry, the
  2353. // flag is cleared and the main entry dialed.
  2354. //
  2355. {
  2356. DWORD dwErr = NO_ERROR;
  2357. RASDIALPARAMS* prdp, *prdpu, *prdpg;
  2358. if (pInfo->fFilePrereqOpen)
  2359. {
  2360. ClosePhonebookFile( pInfo->pFile );
  2361. pInfo->pFile = pInfo->pFileMain;
  2362. pInfo->fFilePrereqOpen = FALSE;
  2363. }
  2364. // Lookup entry node specified by caller and save reference for
  2365. // convenience elsewhere.
  2366. //
  2367. pInfo->pNode = EntryNodeFromName(
  2368. pInfo->pFile->pdtllistEntries, pInfo->pszEntry );
  2369. if (!pInfo->pNode)
  2370. {
  2371. dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
  2372. return dwErr;
  2373. }
  2374. pInfo->pEntry = pInfo->pEntryMain = (PBENTRY* )DtlGetData( pInfo->pNode );
  2375. ASSERT( pInfo->pEntry );
  2376. // Switch to the prerequisite entry, if indicated.
  2377. //
  2378. if (pInfo->fPrerequisiteDial)
  2379. {
  2380. if (pInfo->pEntry->pszPrerequisiteEntry
  2381. && *(pInfo->pEntry->pszPrerequisiteEntry))
  2382. {
  2383. ASSERT( !pInfo->fFilePrereqOpen );
  2384. // GetPbkAndEntryName first looks in the All Users phonebook file
  2385. // if a phonebook file is not specified. If the entry is not
  2386. // found there it looks in files present in the Users profile.
  2387. // This needs to be done since we are discontinuing the per-user
  2388. // pbk file being set through user preferences.
  2389. //
  2390. dwErr = GetPbkAndEntryName(
  2391. pInfo->pEntry->pszPrerequisitePbk,
  2392. pInfo->pEntry->pszPrerequisiteEntry,
  2393. 0,
  2394. &pInfo->filePrereq,
  2395. &pInfo->pNode);
  2396. if (dwErr != 0)
  2397. {
  2398. return dwErr;
  2399. }
  2400. pInfo->pFile = &pInfo->filePrereq;
  2401. pInfo->fFilePrereqOpen = TRUE;
  2402. pInfo->pEntry = (PBENTRY* )DtlGetData( pInfo->pNode );
  2403. ASSERT( pInfo->pEntry );
  2404. }
  2405. else
  2406. {
  2407. pInfo->fPrerequisiteDial = FALSE;
  2408. }
  2409. }
  2410. // Set up RasDial parameter blocks.
  2411. //
  2412. prdp = &pInfo->rdp;
  2413. prdpu = &pInfo->rdpu;
  2414. prdpg = &pInfo->rdpg;
  2415. ZeroMemory( prdp, sizeof(*prdp) );
  2416. pInfo->fUnattended = FALSE;
  2417. prdp->dwSize = sizeof(*prdp);
  2418. lstrcpyn(
  2419. prdp->szEntryName,
  2420. pInfo->pEntry->pszEntryName,
  2421. sizeof(prdp->szEntryName) / sizeof(TCHAR));
  2422. if (pInfo->pszPhoneNumber)
  2423. {
  2424. lstrcpyn(
  2425. prdp->szPhoneNumber,
  2426. pInfo->pszPhoneNumber,
  2427. RAS_MaxPhoneNumber + 1);
  2428. }
  2429. // Whistler bug 272819 Not prompted for callback number
  2430. // We must do this before the init of per-user and global variants
  2431. //
  2432. if (!pInfo->fUnattended)
  2433. {
  2434. // '*' means "behave as defined in user preferences", while leaving it
  2435. // zero would mean "don't request callback if server offers".
  2436. //
  2437. // Whistler bug 224074 use only lstrcpyn's to prevent maliciousness
  2438. //
  2439. lstrcpyn(
  2440. prdp->szCallbackNumber,
  2441. TEXT("*"),
  2442. sizeof(prdp->szCallbackNumber) / sizeof(TCHAR) );
  2443. }
  2444. // Initialze the per-user and global variants
  2445. //
  2446. CopyMemory(prdpu, prdp, sizeof(*prdp));
  2447. CopyMemory(prdpg, prdp, sizeof(*prdp));
  2448. // Set the subentry link to whatever the RasDialDlg caller specified. See
  2449. // bug 200351.
  2450. //
  2451. prdp->dwSubEntry = pInfo->pArgs->dwSubEntry;
  2452. // If running in "unattended" mode, i.e. called by RASAUTO to redial on
  2453. // link failure, read the user/password/domain and callback number used on
  2454. // the original call. (Actually found a use for the crappy
  2455. // RasGetEntryDialParams API)
  2456. //
  2457. if (pInfo->pArgs->dwFlags & RASDDFLAG_LinkFailure)
  2458. {
  2459. RASDIALPARAMS rdp;
  2460. BOOL fSavedPw = HaveSavedPw( pInfo );
  2461. ZeroMemory( &rdp, sizeof(rdp) );
  2462. rdp.dwSize = sizeof(rdp);
  2463. lstrcpyn(
  2464. rdp.szEntryName,
  2465. pInfo->pEntry->pszEntryName,
  2466. sizeof(rdp.szEntryName) / sizeof(TCHAR)
  2467. );
  2468. //For whistler bug 313509 gangz
  2469. //We use FindEntryCredentials() to get saved password perUser and
  2470. //perConnection inforation, use RasGetEntryDialParams() to get back
  2471. //Callback Numbers
  2472. //
  2473. {
  2474. RASDIALPARAMS rdTemp;
  2475. TCHAR * pszTempUser, * pszTempDomain;
  2476. pszTempUser = pszTempDomain = NULL;
  2477. TRACE("FindEntryCredentials");
  2478. dwErr = FindEntryCredentials(
  2479. pInfo->pFile->pszPath,
  2480. pInfo->pEntry->pszEntryName,
  2481. pszTempUser,
  2482. pszTempDomain,
  2483. &rdTemp,
  2484. &rdTemp,
  2485. &(pInfo->fHaveSavedPwUser),
  2486. &(pInfo->fHaveSavedPwGlobal));
  2487. TRACE1("FindEntryCredentials=%d", dwErr);
  2488. ZeroMemory( &rdTemp, sizeof(rdTemp) );
  2489. Free0(pszTempUser);
  2490. Free0(pszTempDomain);
  2491. }
  2492. TRACE( "RasGetEntryDialParams" );
  2493. ASSERT( g_pRasGetEntryDialParams );
  2494. dwErr = g_pRasGetEntryDialParams(
  2495. pInfo->pFile->pszPath, &rdp, &fSavedPw );
  2496. TRACE2( "RasGetEntryDialParams=%d,f=%d", dwErr, &fSavedPw );
  2497. TRACEW1( "u=%s", rdp.szUserName );
  2498. //TRACEW1( "p=%s", rdp.szPassword );
  2499. TRACEW1( "d=%s", rdp.szDomain );
  2500. TRACEW1( "c=%s", rdp.szCallbackNumber );
  2501. if (dwErr == 0)
  2502. {
  2503. lstrcpyn(
  2504. prdp->szUserName,
  2505. rdp.szUserName,
  2506. sizeof(prdp->szUserName) / sizeof(TCHAR));
  2507. // Whistler bug 254385 encode password when not being used
  2508. // Assumed password was not encoded by RasGetEntryDialParams()
  2509. //
  2510. lstrcpyn(
  2511. prdp->szPassword,
  2512. rdp.szPassword,
  2513. sizeof(prdp->szPassword) / sizeof(TCHAR) );
  2514. EncodePassword( prdp->szPassword );
  2515. lstrcpyn(
  2516. prdp->szDomain,
  2517. rdp.szDomain,
  2518. sizeof(prdp->szDomain) / sizeof(TCHAR));
  2519. lstrcpyn(
  2520. prdp->szCallbackNumber,
  2521. rdp.szCallbackNumber,
  2522. sizeof(prdp->szCallbackNumber) / sizeof(TCHAR));
  2523. pInfo->fUnattended = TRUE;
  2524. }
  2525. RtlSecureZeroMemory( rdp.szPassword, sizeof(rdp.szPassword) );
  2526. }
  2527. if (pInfo->pNoUser)
  2528. {
  2529. // Use the credentials we got from API caller, presumably the ones
  2530. // entered at Ctrl-Alt-Del.
  2531. //
  2532. lstrcpyn(
  2533. prdp->szUserName,
  2534. pInfo->pNoUser->szUserName,
  2535. sizeof(prdp->szUserName) / sizeof(TCHAR));
  2536. //
  2537. // Don't copy the password if its smartcard logon
  2538. // and the entry being used is a non-eap connectoid
  2539. //
  2540. // Whistler bug 254385 encode password when not being used
  2541. // Assumed password was encoded by caller of RasDialDlg()
  2542. //
  2543. DecodePassword( pInfo->pNoUser->szPassword );
  2544. lstrcpyn(
  2545. prdp->szPassword,
  2546. pInfo->pNoUser->szPassword,
  2547. sizeof(prdp->szPassword) / sizeof(TCHAR) );
  2548. EncodePassword( pInfo->pNoUser->szPassword );
  2549. EncodePassword( prdp->szPassword );
  2550. if (pInfo->pEntry->fPreviewDomain)
  2551. {
  2552. lstrcpyn(
  2553. prdp->szDomain,
  2554. pInfo->pNoUser->szDomain,
  2555. sizeof(prdp->szDomain) / sizeof(TCHAR));
  2556. }
  2557. else
  2558. {
  2559. // Don't use Winlogon domain unless "include domain" option is
  2560. // selected. See bug 387266.
  2561. //
  2562. // Whistler bug 224074 use only lstrcpyn's to prevent maliciousness
  2563. //
  2564. lstrcpyn(
  2565. prdp->szDomain,
  2566. TEXT(""),
  2567. sizeof(prdp->szDomain) / sizeof(TCHAR) );
  2568. }
  2569. }
  2570. else if (!pInfo->fUnattended)
  2571. {
  2572. DWORD dwErrRc;
  2573. BOOL fUseLogonDomain;
  2574. TCHAR* pszDefaultUser;
  2575. dwErrRc = FindEntryCredentials(
  2576. pInfo->pFile->pszPath,
  2577. pInfo->pEntry->pszEntryName,
  2578. pInfo->pEntry->pszOldUser,
  2579. pInfo->pEntry->pszOldDomain,
  2580. prdpu,
  2581. prdpg,
  2582. &(pInfo->fHaveSavedPwUser),
  2583. &(pInfo->fHaveSavedPwGlobal));
  2584. if (! pInfo->pEntry->fAutoLogon)
  2585. {
  2586. // If saved passwords are disabled, clear here
  2587. //
  2588. if (pInfo->fDisableSavePw)
  2589. {
  2590. pInfo->fHaveSavedPwUser = FALSE;
  2591. pInfo->fHaveSavedPwGlobal = FALSE;
  2592. RtlSecureZeroMemory(prdp->szPassword, sizeof(prdp->szPassword));
  2593. RtlSecureZeroMemory(prdpu->szPassword, sizeof(prdpu->szPassword));
  2594. RtlSecureZeroMemory(prdpg->szPassword, sizeof(prdpg->szPassword));
  2595. }
  2596. // If including domains is disabled, clear here
  2597. //
  2598. if (! pInfo->pEntry->fPreviewDomain)
  2599. {
  2600. // (SteveC) Don't do this in the 'fAutoLogon' case. See bug
  2601. // 207611.
  2602. //
  2603. ZeroMemory(prdp->szDomain, sizeof(prdp->szDomain));
  2604. ZeroMemory(prdpu->szDomain, sizeof(prdpu->szDomain));
  2605. ZeroMemory(prdpg->szDomain, sizeof(prdpg->szDomain));
  2606. }
  2607. }
  2608. if(!pInfo->pEntry->fAutoLogon)
  2609. {
  2610. // Initialize the dial params that will be passed to RasDial.
  2611. //
  2612. // Note that per-user credentials are always used when both
  2613. // per-user and global credentials are saved. The per-user
  2614. // credentials should be copied even if there is no saved
  2615. // password since there may be a saved identity.
  2616. //
  2617. CopyMemory(prdp, prdpu, sizeof(*prdp));
  2618. if (pInfo->fHaveSavedPwGlobal && !pInfo->fHaveSavedPwUser)
  2619. {
  2620. CopyMemory(prdp, prdpg, sizeof(*prdp));
  2621. }
  2622. }
  2623. }
  2624. return 0;
  2625. }
  2626. //----------------------------------------------------------------------------
  2627. // Bundling Errors dialog
  2628. // Listed alphabetically following stub API and dialog proc
  2629. //----------------------------------------------------------------------------
  2630. BOOL
  2631. BundlingErrorsDlg(
  2632. IN OUT DPINFO* pInfo )
  2633. // Popup the Bundling Errors dialog. 'PInfo' is the dialing progress
  2634. // dialog context.
  2635. //
  2636. // Returns true if user chooses to accept the results or false if he
  2637. // chooses to hang up.
  2638. //
  2639. {
  2640. INT_PTR nStatus;
  2641. TRACE( "BundlingErrorsDlg" );
  2642. nStatus =
  2643. (BOOL )DialogBoxParam(
  2644. g_hinstDll,
  2645. MAKEINTRESOURCE( DID_BE_BundlingErrors ),
  2646. pInfo->hwndDlg,
  2647. BeDlgProc,
  2648. (LPARAM )pInfo );
  2649. if (nStatus == -1)
  2650. {
  2651. ErrorDlg( pInfo->hwndDlg, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  2652. nStatus = FALSE;
  2653. }
  2654. return (BOOL )nStatus;
  2655. }
  2656. INT_PTR CALLBACK
  2657. BeDlgProc(
  2658. IN HWND hwnd,
  2659. IN UINT unMsg,
  2660. IN WPARAM wparam,
  2661. IN LPARAM lparam )
  2662. // DialogProc callback for the Bundling Errors dialog. Parameters and
  2663. // return value are as described for standard windows 'DialogProc's.
  2664. //
  2665. {
  2666. #if 0
  2667. TRACE4( "BeDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  2668. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  2669. #endif
  2670. if (ListView_OwnerHandler(
  2671. hwnd, unMsg, wparam, lparam, BeLvErrorsCallback ))
  2672. {
  2673. return TRUE;
  2674. }
  2675. switch (unMsg)
  2676. {
  2677. case WM_INITDIALOG:
  2678. {
  2679. return BeInit( hwnd, (DPINFO* )lparam );
  2680. }
  2681. case WM_COMMAND:
  2682. {
  2683. return BeCommand(
  2684. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  2685. }
  2686. }
  2687. return FALSE;
  2688. }
  2689. BOOL
  2690. BeCommand(
  2691. IN HWND hwnd,
  2692. IN WORD wNotification,
  2693. IN WORD wId,
  2694. IN HWND hwndCtrl )
  2695. // Called on WM_COMMAND. 'Hwnd' is the dialog window. 'WNotification' is
  2696. // the notification code of the command. 'wId' is the control/menu
  2697. // identifier of the command. 'HwndCtrl' is the control window handle of
  2698. // the command.
  2699. //
  2700. // Returns true if processed message, false otherwise.
  2701. //
  2702. {
  2703. DWORD dwErr;
  2704. TRACE3( "BeCommand(n=%d,i=%d,c=$%x)",
  2705. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  2706. switch (wId)
  2707. {
  2708. case IDOK:
  2709. case IDCANCEL:
  2710. {
  2711. TRACE1( "%s pressed", (wId==IDOK) ? "OK" : "Cancel" );
  2712. if (IsDlgButtonChecked( hwnd, CID_BE_CB_DisableLink ))
  2713. {
  2714. DWORD i;
  2715. DPINFO* pInfo;
  2716. DPSTATE* pState;
  2717. // Caller says to delete the links that failed in the entry.
  2718. // Create a list of Psz nodes containing the unique port name
  2719. // of each failed link so they can be removed after the state
  2720. // information is freed.
  2721. //
  2722. pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  2723. for (i = 0, pState = pInfo->pStates;
  2724. i < pInfo->cStates;
  2725. ++i, ++pState)
  2726. {
  2727. DTLNODE* pNode;
  2728. DTLNODE* pNodePtd;
  2729. PBLINK* pLink;
  2730. if (pState->dwError != 0)
  2731. {
  2732. if (!pInfo->pArgs->pListPortsToDelete)
  2733. {
  2734. pInfo->pArgs->pListPortsToDelete =
  2735. DtlCreateList( 0L );
  2736. if (!pInfo->pArgs->pListPortsToDelete)
  2737. {
  2738. continue;
  2739. }
  2740. }
  2741. pNode = DtlNodeFromIndex(
  2742. pInfo->pArgs->pEntry->pdtllistLinks, (LONG )i );
  2743. if (!pNode)
  2744. {
  2745. continue;
  2746. }
  2747. pLink = (PBLINK* )DtlGetData( pNode );
  2748. pNodePtd = CreatePszNode( pLink->pbport.pszPort );
  2749. if (!pNodePtd)
  2750. {
  2751. continue;
  2752. }
  2753. DtlAddNodeLast(
  2754. pInfo->pArgs->pListPortsToDelete, pNodePtd );
  2755. }
  2756. }
  2757. }
  2758. EndDialog( hwnd, (wId == IDOK) );
  2759. return TRUE;
  2760. }
  2761. }
  2762. return FALSE;
  2763. }
  2764. VOID
  2765. BeFillLvErrors(
  2766. IN HWND hwndLv,
  2767. IN DPINFO* pInfo )
  2768. // Fill the listview 'hwndLv' with devices and error strings and select
  2769. // the first item. 'PInfo' is the dialing progress dialog context.
  2770. //
  2771. {
  2772. INT iItem;
  2773. DWORD i;
  2774. DPSTATE* pState;
  2775. TRACE( "BeFillLvErrors" );
  2776. ListView_DeleteAllItems( hwndLv );
  2777. // Add columns.
  2778. //
  2779. {
  2780. LV_COLUMN col;
  2781. TCHAR* pszHeader0;
  2782. TCHAR* pszHeader1;
  2783. pszHeader0 = PszFromId( g_hinstDll, SID_DeviceColHead );
  2784. pszHeader1 = PszFromId( g_hinstDll, SID_StatusColHead );
  2785. ZeroMemory( &col, sizeof(col) );
  2786. col.mask = LVCF_FMT + LVCF_TEXT;
  2787. col.fmt = LVCFMT_LEFT;
  2788. col.pszText = (pszHeader0) ? pszHeader0 : TEXT("");
  2789. ListView_InsertColumn( hwndLv, 0, &col );
  2790. ZeroMemory( &col, sizeof(col) );
  2791. col.mask = LVCF_FMT + LVCF_SUBITEM + LVCF_TEXT;
  2792. col.fmt = LVCFMT_LEFT;
  2793. col.pszText = (pszHeader1) ? pszHeader1 : TEXT("");
  2794. col.iSubItem = 1;
  2795. ListView_InsertColumn( hwndLv, 1, &col );
  2796. Free0( pszHeader0 );
  2797. Free0( pszHeader1 );
  2798. }
  2799. // Add the modem and adapter images.
  2800. //
  2801. ListView_SetDeviceImageList( hwndLv, g_hinstDll );
  2802. // Load listview with device/status pairs.
  2803. //
  2804. iItem = 0;
  2805. for (i = 0, pState = pInfo->pStates; i < pInfo->cStates; ++i, ++pState)
  2806. {
  2807. LV_ITEM item;
  2808. DTLNODE* pNode;
  2809. PBLINK* pLink;
  2810. TCHAR* psz;
  2811. pNode = DtlNodeFromIndex(
  2812. pInfo->pArgs->pEntry->pdtllistLinks, (LONG )i );
  2813. if (pNode)
  2814. {
  2815. pLink = (PBLINK* )DtlGetData( pNode );
  2816. psz = DisplayPszFromDeviceAndPort(
  2817. pLink->pbport.pszDevice, pLink->pbport.pszPort );
  2818. if (psz)
  2819. {
  2820. ZeroMemory( &item, sizeof(item) );
  2821. item.mask = LVIF_TEXT + LVIF_IMAGE;
  2822. item.iItem = iItem;
  2823. item.pszText = psz;
  2824. item.iImage =
  2825. (pLink->pbport.pbdevicetype == PBDT_Modem)
  2826. ? DI_Modem : DI_Adapter;
  2827. ListView_InsertItem( hwndLv, &item );
  2828. Free( psz );
  2829. if (pState->dwError == 0)
  2830. {
  2831. psz = PszFromId( g_hinstDll, SID_Connected );
  2832. ListView_SetItemText( hwndLv, iItem, 1, psz );
  2833. Free( psz );
  2834. }
  2835. else
  2836. {
  2837. psz = BeGetErrorPsz( pState->dwError );
  2838. ListView_SetItemText( hwndLv, iItem, 1, psz );
  2839. LocalFree( psz );
  2840. }
  2841. ++iItem;
  2842. }
  2843. }
  2844. }
  2845. // Auto-size columns to look good with the text they contain.
  2846. //
  2847. ListView_SetColumnWidth( hwndLv, 0, LVSCW_AUTOSIZE_USEHEADER );
  2848. ListView_SetColumnWidth( hwndLv, 1, LVSCW_AUTOSIZE_USEHEADER );
  2849. // Select the first item.
  2850. //
  2851. ListView_SetItemState( hwndLv, 0, LVIS_SELECTED, LVIS_SELECTED );
  2852. }
  2853. TCHAR*
  2854. BeGetErrorPsz(
  2855. IN DWORD dwError )
  2856. // Returns a string suitable for the Status column with error 'dwError' or
  2857. // NULL on error. 'DwError' is assumed to be non-0. It is caller's
  2858. // responsiblility to LocalFree the returned string.
  2859. //
  2860. {
  2861. TCHAR* pszErrStr;
  2862. TCHAR szErrNumBuf[ MAXLTOTLEN + 1 ];
  2863. TCHAR* pszLineFormat;
  2864. TCHAR* pszLine;
  2865. TCHAR* apszArgs[ 2 ];
  2866. LToT( dwError, szErrNumBuf, 10 );
  2867. pszErrStr = NULL;
  2868. GetErrorText( dwError, &pszErrStr );
  2869. pszLine = NULL;
  2870. pszLineFormat = PszFromId( g_hinstDll, SID_FMT_Error );
  2871. if (pszLineFormat)
  2872. {
  2873. apszArgs[ 0 ] = szErrNumBuf;
  2874. apszArgs[ 1 ] = (pszErrStr) ? pszErrStr : TEXT("");
  2875. FormatMessage(
  2876. FORMAT_MESSAGE_FROM_STRING
  2877. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  2878. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  2879. pszLineFormat, 0, 0, (LPTSTR )&pszLine, 1,
  2880. (va_list* )apszArgs );
  2881. Free( pszLineFormat );
  2882. }
  2883. Free0( pszErrStr );
  2884. return pszLine;
  2885. }
  2886. BOOL
  2887. BeInit(
  2888. IN HWND hwndDlg,
  2889. IN DPINFO* pArgs )
  2890. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
  2891. // 'PArgs' is caller's arguments to the stub API.
  2892. //
  2893. // Return false if focus was set, true otherwise, i.e. as defined for
  2894. // WM_INITDIALOG.
  2895. //
  2896. {
  2897. DWORD dwErr;
  2898. HWND hwndLvErrors;
  2899. HWND hwndCbDisableLink;
  2900. TRACE( "BeInit" );
  2901. hwndLvErrors = GetDlgItem( hwndDlg, CID_BE_LV_Errors );
  2902. ASSERT( hwndLvErrors );
  2903. hwndCbDisableLink = GetDlgItem( hwndDlg, CID_BE_CB_DisableLink );
  2904. ASSERT( hwndCbDisableLink );
  2905. // Save Dial Progress context as dialog context.
  2906. //
  2907. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pArgs );
  2908. // Load listview with device/error information.
  2909. //
  2910. BeFillLvErrors( hwndLvErrors, pArgs );
  2911. // Display the finished window above all other windows. The window
  2912. // position is set to "topmost" then immediately set to "not topmost"
  2913. // because we want it on top but not always-on-top. Always-on-top alone
  2914. // is incredibly annoying, e.g. it is always on top of the on-line help if
  2915. // user presses the Help button.
  2916. //
  2917. SetWindowPos(
  2918. hwndDlg, HWND_TOPMOST, 0, 0, 0, 0,
  2919. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
  2920. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  2921. ShowWindow( hwndDlg, SW_SHOW );
  2922. SetWindowPos(
  2923. hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
  2924. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
  2925. SetFocus( hwndCbDisableLink );
  2926. return FALSE;
  2927. }
  2928. LVXDRAWINFO*
  2929. BeLvErrorsCallback(
  2930. IN HWND hwndLv,
  2931. IN DWORD dwItem )
  2932. // Enhanced list view callback to report drawing information. 'HwndLv' is
  2933. // the handle of the list view control. 'DwItem' is the index of the item
  2934. // being drawn.
  2935. //
  2936. // Returns the address of the column information.
  2937. //
  2938. {
  2939. // Use "wide selection bar" feature and the other recommended options.
  2940. //
  2941. // Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
  2942. //
  2943. static LVXDRAWINFO info =
  2944. { 2, 0, LVXDI_Blend50Dis + LVXDI_DxFill, { 0, 0 } };
  2945. return &info;
  2946. }
  2947. //----------------------------------------------------------------------------
  2948. // Change Password dialog
  2949. // Listed alphabetically following stub API and dialog proc
  2950. //----------------------------------------------------------------------------
  2951. BOOL
  2952. ChangePasswordDlg(
  2953. IN HWND hwndOwner,
  2954. IN BOOL fOldPassword,
  2955. OUT TCHAR* pszOldPassword,
  2956. OUT TCHAR* pszNewPassword )
  2957. // Popup the Change Password dialog. 'HwndOwner' is the owning window.
  2958. // 'FOldPassword' is set true if user must supply an old password, false
  2959. // if no old password is required. 'PszOldPassword' and 'pszNewPassword'
  2960. // are caller's buffers for the returned passwords.
  2961. //
  2962. // Returns true if user presses OK and succeeds, false otherwise.
  2963. //
  2964. {
  2965. INT_PTR nStatus;
  2966. CPARGS args;
  2967. TRACE( "ChangePasswordDlg" );
  2968. args.fOldPassword = fOldPassword;
  2969. args.pszOldPassword = pszOldPassword;
  2970. args.pszNewPassword = pszNewPassword;
  2971. nStatus =
  2972. (BOOL )DialogBoxParam(
  2973. g_hinstDll,
  2974. (fOldPassword)
  2975. ? MAKEINTRESOURCE( DID_CP_ChangePassword2 )
  2976. : MAKEINTRESOURCE( DID_CP_ChangePassword ),
  2977. hwndOwner,
  2978. CpDlgProc,
  2979. (LPARAM )&args );
  2980. if (nStatus == -1)
  2981. {
  2982. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  2983. nStatus = FALSE;
  2984. }
  2985. return (BOOL )nStatus;
  2986. }
  2987. INT_PTR CALLBACK
  2988. CpDlgProc(
  2989. IN HWND hwnd,
  2990. IN UINT unMsg,
  2991. IN WPARAM wparam,
  2992. IN LPARAM lparam )
  2993. // DialogProc callback for the Change Password dialog. Parameters and
  2994. // return value are as described for standard windows 'DialogProc's.
  2995. //
  2996. {
  2997. #if 0
  2998. TRACE4( "CpDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  2999. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  3000. #endif
  3001. switch (unMsg)
  3002. {
  3003. case WM_INITDIALOG:
  3004. {
  3005. return CpInit( hwnd, (CPARGS* )lparam );
  3006. }
  3007. case WM_HELP:
  3008. case WM_CONTEXTMENU:
  3009. {
  3010. ContextHelp( g_adwCpHelp, hwnd, unMsg, wparam, lparam );
  3011. break;
  3012. }
  3013. case WM_COMMAND:
  3014. {
  3015. return CpCommand(
  3016. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  3017. }
  3018. }
  3019. return FALSE;
  3020. }
  3021. BOOL
  3022. CpCommand(
  3023. IN HWND hwnd,
  3024. IN WORD wNotification,
  3025. IN WORD wId,
  3026. IN HWND hwndCtrl )
  3027. // Called on WM_COMMAND. 'Hwnd' is the dialog window. 'WNotification' is
  3028. // the notification code of the command. 'wId' is the control/menu
  3029. // identifier of the command. 'HwndCtrl' is the control window handle of
  3030. // the command.
  3031. //
  3032. // Returns true if processed message, false otherwise.
  3033. //
  3034. {
  3035. DWORD dwErr;
  3036. TRACE3( "CpCommand(n=%d,i=%d,c=$%x)",
  3037. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  3038. switch (wId)
  3039. {
  3040. case IDOK:
  3041. {
  3042. CPWINFO* pInfo;
  3043. TCHAR szNewPassword[ PWLEN + 1 ];
  3044. TCHAR szNewPassword2[ PWLEN + 1 ];
  3045. TRACE( "OK pressed" );
  3046. pInfo = (CPWINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  3047. ASSERT( pInfo );
  3048. szNewPassword[ 0 ] = TEXT('\0');
  3049. GetWindowText(
  3050. pInfo->hwndEbNewPassword, szNewPassword, PWLEN + 1 );
  3051. szNewPassword2[ 0 ] = TEXT('\0');
  3052. GetWindowText(
  3053. pInfo->hwndEbNewPassword2, szNewPassword2, PWLEN + 1 );
  3054. if (lstrcmp( szNewPassword, szNewPassword2 ) != 0)
  3055. {
  3056. // The two passwords don't match, i.e. user made a typo. Make
  3057. // him re-enter.
  3058. //
  3059. MsgDlg( hwnd, SID_PasswordsDontMatch, NULL );
  3060. SetWindowText( pInfo->hwndEbNewPassword, TEXT("") );
  3061. SetWindowText( pInfo->hwndEbNewPassword2, TEXT("") );
  3062. SetFocus( pInfo->hwndEbNewPassword );
  3063. RtlSecureZeroMemory( szNewPassword, sizeof(szNewPassword) );
  3064. RtlSecureZeroMemory( szNewPassword2, sizeof(szNewPassword2) );
  3065. return TRUE;
  3066. }
  3067. if (pInfo->pArgs->fOldPassword)
  3068. {
  3069. pInfo->pArgs->pszOldPassword[ 0 ] = TEXT('\0');
  3070. // Whistler bug 254385 encode password when not being used
  3071. // Assumed password was not encoded by GetWindowText()
  3072. //
  3073. GetWindowText(
  3074. pInfo->hwndEbOldPassword,
  3075. pInfo->pArgs->pszOldPassword,
  3076. PWLEN + 1 );
  3077. EncodePassword( pInfo->pArgs->pszOldPassword );
  3078. }
  3079. // Whistler bug 224074 use only lstrcpyn's to prevent maliciousness
  3080. //
  3081. // pInfo->pArgs->pszNewPassword points back to RASDIALPARAMS->
  3082. // szPassword[ PWLEN + 1 ]
  3083. //
  3084. // Whistler bug 254385 encode password when not being used
  3085. // Assumed password was not encoded by GetWindowText()
  3086. //
  3087. lstrcpyn(
  3088. pInfo->pArgs->pszNewPassword,
  3089. szNewPassword,
  3090. PWLEN + 1 );
  3091. EncodePassword( pInfo->pArgs->pszNewPassword );
  3092. RtlSecureZeroMemory( szNewPassword, sizeof(szNewPassword) );
  3093. RtlSecureZeroMemory( szNewPassword2, sizeof(szNewPassword2) );
  3094. EndDialog( hwnd, TRUE );
  3095. return TRUE;
  3096. }
  3097. case IDCANCEL:
  3098. {
  3099. TRACE( "Cancel pressed" );
  3100. EndDialog( hwnd, FALSE );
  3101. return TRUE;
  3102. }
  3103. }
  3104. return FALSE;
  3105. }
  3106. BOOL
  3107. CpInit(
  3108. IN HWND hwndDlg,
  3109. IN CPARGS* pArgs )
  3110. // Called on WM_INITDIALOG. 'HwndDlg' is the handle of the dialog window.
  3111. // 'PArgs' is caller's arguments to the stub API.
  3112. //
  3113. // Return false if focus was set, true otherwise, i.e. as defined for
  3114. // WM_INITDIALOG.
  3115. //
  3116. {
  3117. DWORD dwErr;
  3118. CPWINFO* pInfo;
  3119. TRACE( "CpInit" );
  3120. // Allocate the dialog context block. Initialize minimally for proper
  3121. // cleanup, then attach to the dialog window.
  3122. //
  3123. {
  3124. pInfo = Malloc( sizeof(*pInfo) );
  3125. if (!pInfo)
  3126. {
  3127. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  3128. EndDialog( hwndDlg, FALSE );
  3129. return TRUE;
  3130. }
  3131. ZeroMemory( pInfo, sizeof(*pInfo) );
  3132. pInfo->pArgs = pArgs;
  3133. pInfo->hwndDlg = hwndDlg;
  3134. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  3135. TRACE( "Context set" );
  3136. }
  3137. if (pArgs->fOldPassword)
  3138. {
  3139. pInfo->hwndEbOldPassword =
  3140. GetDlgItem( hwndDlg, CID_CP_EB_OldPassword );
  3141. ASSERT( pInfo->hwndEbOldPassword );
  3142. Edit_LimitText( pInfo->hwndEbOldPassword, PWLEN );
  3143. }
  3144. pInfo->hwndEbNewPassword =
  3145. GetDlgItem( hwndDlg, CID_CP_EB_Password );
  3146. ASSERT( pInfo->hwndEbNewPassword );
  3147. Edit_LimitText( pInfo->hwndEbNewPassword, PWLEN );
  3148. pInfo->hwndEbNewPassword2 =
  3149. GetDlgItem( hwndDlg, CID_CP_EB_ConfirmPassword );
  3150. ASSERT( pInfo->hwndEbNewPassword2 );
  3151. Edit_LimitText( pInfo->hwndEbNewPassword2, PWLEN );
  3152. // Add context help button to title bar.
  3153. //
  3154. AddContextHelpButton( hwndDlg );
  3155. // Display finished window.
  3156. //
  3157. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  3158. SetForegroundWindow( hwndDlg );
  3159. return TRUE;
  3160. }
  3161. //----------------------------------------------------------------------------
  3162. // Connect Complete dialog
  3163. // Listed alphabetically following stub API and dialog proc
  3164. //----------------------------------------------------------------------------
  3165. VOID
  3166. ConnectCompleteDlg(
  3167. IN HWND hwndOwner,
  3168. IN DINFO* pInfo )
  3169. // Popup the connection complete dialog. 'HwndOwner' is the owning
  3170. // window. 'PUser' is the user preferences.
  3171. //
  3172. {
  3173. INT_PTR nStatus;
  3174. TRACE( "ConnectCompleteDlg" );
  3175. nStatus =
  3176. (BOOL )DialogBoxParam(
  3177. g_hinstDll,
  3178. MAKEINTRESOURCE( DID_CC_ConnectComplete ),
  3179. hwndOwner,
  3180. CcDlgProc,
  3181. (LPARAM )pInfo );
  3182. }
  3183. INT_PTR CALLBACK
  3184. CcDlgProc(
  3185. IN HWND hwnd,
  3186. IN UINT unMsg,
  3187. IN WPARAM wparam,
  3188. IN LPARAM lparam )
  3189. // DialogProc callback for the dialog. Parameters and return value are as
  3190. // described for standard windows 'DialogProc's.
  3191. //
  3192. {
  3193. #if 0
  3194. TRACE4( "CcDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  3195. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  3196. #endif
  3197. switch (unMsg)
  3198. {
  3199. case WM_INITDIALOG:
  3200. {
  3201. return CcInit( hwnd, (DINFO* )lparam );
  3202. }
  3203. case WM_COMMAND:
  3204. {
  3205. return CcCommand(
  3206. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  3207. }
  3208. case WM_DESTROY:
  3209. //For whistler bug 372078
  3210. //GetCurrentIconEntryType() loads Icon from netshell where the icon is loaded
  3211. //by LoadImage() without LR_SHARED, so I have to destroy it when we are done
  3212. //with it
  3213. //
  3214. {
  3215. HICON hIcon=NULL;
  3216. hIcon = (HICON)SendMessage( GetDlgItem( hwnd, CID_CC_I_Rasmon ),
  3217. STM_GETICON,
  3218. (WPARAM)0,
  3219. (LPARAM)0);
  3220. ASSERT(hIcon);
  3221. if( hIcon )
  3222. {
  3223. DestroyIcon(hIcon);
  3224. }
  3225. else
  3226. {
  3227. TRACE("CcDlgProc:Destroy Icon");
  3228. }
  3229. }
  3230. break;
  3231. }
  3232. return FALSE;
  3233. }
  3234. BOOL
  3235. CcCommand(
  3236. IN HWND hwnd,
  3237. IN WORD wNotification,
  3238. IN WORD wId,
  3239. IN HWND hwndCtrl )
  3240. // Called on WM_COMMAND. 'Hwnd' is the dialog window. 'WNotification' is
  3241. // the notification code of the command. 'wId' is the control/menu
  3242. // identifier of the command. 'HwndCtrl' is the control window handle of
  3243. // the command.
  3244. //
  3245. // Returns true if processed message, false otherwise.
  3246. //
  3247. {
  3248. TRACE3( "CcCommand(n=%d,i=%d,c=$%x)",
  3249. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  3250. switch (wId)
  3251. {
  3252. case IDOK:
  3253. {
  3254. DINFO * pInfo = (DINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  3255. PBUSER* pUser = pInfo->pUser;
  3256. ASSERT( pUser );
  3257. if (IsDlgButtonChecked( hwnd, CID_CC_CB_SkipMessage ))
  3258. {
  3259. pUser->fSkipConnectComplete = TRUE;
  3260. pUser->fDirty = TRUE;
  3261. }
  3262. }
  3263. // ...fall thru...
  3264. case IDCANCEL:
  3265. {
  3266. EndDialog( hwnd, TRUE );
  3267. return TRUE;
  3268. }
  3269. }
  3270. return FALSE;
  3271. }
  3272. BOOL
  3273. CcInit(
  3274. IN HWND hwndDlg,
  3275. IN DINFO* pInfo )
  3276. // Called on WM_INITDIALOG. 'HwndDlg' is the handle of dialog. 'PUser'
  3277. // is caller's argument to the stub API.
  3278. //
  3279. // Return false if focus was set, true otherwise, i.e. as defined for
  3280. // WM_INITDIALOG.
  3281. //
  3282. {
  3283. TRACE( "CcInit" );
  3284. // Set the dialog context.
  3285. //
  3286. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  3287. // Set the explanatory text.
  3288. //
  3289. {
  3290. MSGARGS msgargs;
  3291. ZeroMemory( &msgargs, sizeof(msgargs) );
  3292. msgargs.apszArgs[ 0 ] = pInfo->pEntry->pszEntryName;
  3293. msgargs.fStringOutput = TRUE;
  3294. MsgDlgUtil( NULL, SID_ConnectComplete, &msgargs, g_hinstDll, 0 );
  3295. if (msgargs.pszOutput)
  3296. {
  3297. SetDlgItemText( hwndDlg, CID_CC_ST_Text, msgargs.pszOutput );
  3298. Free( msgargs.pszOutput );
  3299. }
  3300. }
  3301. // Set the correct icon. For whistler bug 372078
  3302. //
  3303. SetIconFromEntryType(
  3304. GetDlgItem( hwndDlg, CID_CC_I_Rasmon ),
  3305. pInfo->pEntry->dwType,
  3306. FALSE); //FALSE means Large Icon
  3307. // Display finished window.
  3308. //
  3309. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  3310. SetForegroundWindow( hwndDlg );
  3311. return TRUE;
  3312. }
  3313. //----------------------------------------------------------------------------
  3314. // Dial Callback dialog
  3315. // Listed alphabetically following stub API and dialog proc
  3316. //----------------------------------------------------------------------------
  3317. BOOL
  3318. DialCallbackDlg(
  3319. IN HWND hwndOwner,
  3320. IN OUT TCHAR* pszNumber )
  3321. // Popup the Dial Callback dialog. 'HwndOwner' is the owning window.
  3322. // 'PszNumber' is caller's buffer for the number of the local machine that
  3323. // the server will be told to callback. It contains the default number on
  3324. // entry and the user-edited number on exit.
  3325. //
  3326. // Returns true if user OK and succeeds, false if Cancel or error.
  3327. //
  3328. {
  3329. INT_PTR nStatus;
  3330. TRACE( "DialCallbackDlg" );
  3331. nStatus =
  3332. (BOOL )DialogBoxParam(
  3333. g_hinstDll,
  3334. MAKEINTRESOURCE( DID_DC_DialCallback ),
  3335. hwndOwner,
  3336. DcDlgProc,
  3337. (LPARAM )pszNumber );
  3338. if (nStatus == -1)
  3339. {
  3340. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  3341. nStatus = FALSE;
  3342. }
  3343. return (BOOL )nStatus;
  3344. }
  3345. INT_PTR CALLBACK
  3346. DcDlgProc(
  3347. IN HWND hwnd,
  3348. IN UINT unMsg,
  3349. IN WPARAM wparam,
  3350. IN LPARAM lparam )
  3351. // DialogProc callback for the Dial Callback dialog. Parameters and
  3352. // return value are as described for standard windows 'DialogProc's.
  3353. //
  3354. {
  3355. #if 0
  3356. TRACE4( "DcDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  3357. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  3358. #endif
  3359. switch (unMsg)
  3360. {
  3361. case WM_INITDIALOG:
  3362. {
  3363. return DcInit( hwnd, (TCHAR* )lparam );
  3364. }
  3365. case WM_HELP:
  3366. case WM_CONTEXTMENU:
  3367. {
  3368. ContextHelp( g_adwDcHelp, hwnd, unMsg, wparam, lparam );
  3369. break;
  3370. }
  3371. case WM_COMMAND:
  3372. {
  3373. return DcCommand(
  3374. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  3375. }
  3376. }
  3377. return FALSE;
  3378. }
  3379. BOOL
  3380. DcCommand(
  3381. IN HWND hwnd,
  3382. IN WORD wNotification,
  3383. IN WORD wId,
  3384. IN HWND hwndCtrl )
  3385. // Called on WM_COMMAND. 'Hwnd' is the dialog window. 'WNotification' is
  3386. // the notification code of the command. 'wId' is the control/menu
  3387. // identifier of the command. 'HwndCtrl' is the control window handle of
  3388. // the command.
  3389. //
  3390. // Returns true if processed message, false otherwise.
  3391. //
  3392. {
  3393. DWORD dwErr;
  3394. TRACE3( "DcCommand(n=%d,i=%d,c=$%x)",
  3395. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  3396. switch (wId)
  3397. {
  3398. case IDOK:
  3399. {
  3400. BOOL fStatus;
  3401. HWND hwndEbNumber;
  3402. TCHAR* pszNumber;
  3403. TRACE( "OK pressed" );
  3404. hwndEbNumber = GetDlgItem( hwnd, CID_DC_EB_Number );
  3405. ASSERT( hwndEbNumber );
  3406. pszNumber = (TCHAR* )GetWindowLongPtr( hwnd, DWLP_USER );
  3407. ASSERT( pszNumber );
  3408. GetWindowText( hwndEbNumber, pszNumber, RAS_MaxCallbackNumber + 1 );
  3409. if (IsAllWhite( pszNumber ))
  3410. {
  3411. // OK with blank callback number is same as Cancel.
  3412. //
  3413. TRACE( "Blank number cancel" );
  3414. fStatus = FALSE;
  3415. }
  3416. else
  3417. {
  3418. fStatus = TRUE;
  3419. }
  3420. EndDialog( hwnd, fStatus );
  3421. return TRUE;
  3422. }
  3423. case IDCANCEL:
  3424. {
  3425. TRACE( "Cancel pressed" );
  3426. EndDialog( hwnd, FALSE );
  3427. return TRUE;
  3428. }
  3429. }
  3430. return FALSE;
  3431. }
  3432. BOOL
  3433. DcInit(
  3434. IN HWND hwndDlg,
  3435. IN TCHAR* pszNumber )
  3436. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
  3437. // 'PszNumber' is the callback number.
  3438. //
  3439. // Return false if focus was set, true otherwise, i.e. as defined for
  3440. // WM_INITDIALOG.
  3441. //
  3442. {
  3443. DWORD dwErr;
  3444. HWND hwndEbNumber;
  3445. TRACE( "DcInit" );
  3446. // Stash address of caller's buffer for OK processing.
  3447. //
  3448. ASSERT( pszNumber );
  3449. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pszNumber );
  3450. // Initialize edit field to caller's default.
  3451. //
  3452. hwndEbNumber = GetDlgItem( hwndDlg, CID_DC_EB_Number );
  3453. ASSERT( hwndEbNumber );
  3454. Edit_LimitText( hwndEbNumber, RAS_MaxCallbackNumber );
  3455. SetWindowText( hwndEbNumber, pszNumber );
  3456. // Add context help button to title bar.
  3457. //
  3458. AddContextHelpButton( hwndDlg );
  3459. // Display finished window.
  3460. //
  3461. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  3462. SetForegroundWindow( hwndDlg );
  3463. return TRUE;
  3464. }
  3465. //----------------------------------------------------------------------------
  3466. // Dial Error dialog
  3467. // Listed alphabetically following stub API and dialog proc
  3468. //----------------------------------------------------------------------------
  3469. BOOL
  3470. DialErrorDlg(
  3471. IN HWND hwndOwner,
  3472. IN DINFO * pDinfo, // For whistler bug 474514
  3473. IN TCHAR* pszPhonebook, // For whistler 460931
  3474. IN TCHAR* pszEntry,
  3475. IN DWORD dwError,
  3476. IN DWORD sidState,
  3477. IN TCHAR* pszStatusArg,
  3478. IN DWORD sidFormatMsg,
  3479. IN TCHAR* pszFormatArg,
  3480. IN LONG lRedialCountdown,
  3481. IN BOOL fPopupOnTop )
  3482. // Popup the Dial Error dialog. 'HwndOwner' is the owning window.
  3483. // 'PszEntry' is the entry being dialed. 'DwError' is the error that
  3484. // occurred or 0 if redialing after a link failure. 'sidStatusArg' is the
  3485. // argument to the 'sidState' 'SidState' is the string ID of the dial
  3486. // state executing when the error occurred. string or NULL if none.
  3487. // 'SidFormatMsg' is the string containing the format of the error message
  3488. // or 0 to use the default. 'PszFormatArg' is the additional argument to
  3489. // the format message or NULL if none. 'LRedialCountdown' is the number
  3490. // of seconds before auto-redial, or -1 to disable countdown, or -2 to
  3491. // hide the "Redial" button entirely. 'FPopupOnTop' indicates the status
  3492. // window should be brought to the front when redialing.
  3493. //
  3494. // Returns true if user chooses to redial or lets it timeout, false if
  3495. // cancels.
  3496. //
  3497. {
  3498. INT_PTR nStatus;
  3499. DEARGS args;
  3500. TRACE( "DialErrorDlg" );
  3501. // For whistler 460931 459793 gangz
  3502. //
  3503. LinkWindow_RegisterClass();
  3504. args.pszPhonebook = pszPhonebook; // For whistler 460931
  3505. args.pDinfo = pDinfo; // For whislter 474514
  3506. args.pszEntry = pszEntry;
  3507. args.dwError = dwError;
  3508. args.sidState = sidState;
  3509. args.pszStatusArg = pszStatusArg;
  3510. args.sidFormatMsg = sidFormatMsg;
  3511. args.pszFormatArg = pszFormatArg;
  3512. args.lRedialCountdown = lRedialCountdown;
  3513. args.fPopupOnTop = fPopupOnTop;
  3514. nStatus =
  3515. (BOOL )DialogBoxParam(
  3516. g_hinstDll,
  3517. MAKEINTRESOURCE( DID_DE_DialError ),
  3518. hwndOwner,
  3519. DeDlgProc,
  3520. (LPARAM )&args );
  3521. if (nStatus == -1)
  3522. {
  3523. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  3524. nStatus = FALSE;
  3525. }
  3526. return (BOOL )nStatus;
  3527. }
  3528. INT_PTR CALLBACK
  3529. DeDlgProc(
  3530. IN HWND hwnd,
  3531. IN UINT unMsg,
  3532. IN WPARAM wparam,
  3533. IN LPARAM lparam )
  3534. // DialogProc callback for the Dial Error dialog. Parameters and return
  3535. // value are as described for standard windows 'DialogProc's.
  3536. //
  3537. {
  3538. #if 0
  3539. TRACE4( "DeDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  3540. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  3541. #endif
  3542. switch (unMsg)
  3543. {
  3544. case WM_INITDIALOG:
  3545. {
  3546. return DeInit( hwnd, (DEARGS* )lparam );
  3547. }
  3548. case WM_HELP:
  3549. case WM_CONTEXTMENU:
  3550. {
  3551. ContextHelp( g_adwDeHelp, hwnd, unMsg, wparam, lparam );
  3552. break;
  3553. }
  3554. case WM_COMMAND:
  3555. {
  3556. return DeCommand(
  3557. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  3558. }
  3559. case WM_TIMER:
  3560. {
  3561. DEINFO* pInfo = (DEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  3562. ASSERT( pInfo );
  3563. KillTimer( pInfo->hwndDlg, 1 );
  3564. if (pInfo->lRedialCountdown > 0)
  3565. {
  3566. --pInfo->lRedialCountdown;
  3567. }
  3568. DeAdjustPbRedial( pInfo );
  3569. if (pInfo->lRedialCountdown == 0)
  3570. {
  3571. // Fake a press of the Redial button. Note that BM_CLICK
  3572. // cannot be used because it doesn't generate the WM_COMMAND
  3573. // when the thread is not the foreground window, due to
  3574. // SetCapture use and restriction.
  3575. //
  3576. SendMessage( pInfo->hwndDlg, WM_COMMAND,
  3577. MAKEWPARAM( IDOK, BN_CLICKED ),
  3578. (LPARAM )pInfo->hwndPbRedial );
  3579. }
  3580. else
  3581. {
  3582. SetTimer( pInfo->hwndDlg, 1, 1000L, NULL );
  3583. }
  3584. return TRUE;
  3585. }
  3586. case WM_DESTROY:
  3587. {
  3588. DeTerm( hwnd );
  3589. break;
  3590. }
  3591. // For whistler bug 460931 459793 gangz
  3592. //
  3593. case WM_NOTIFY:
  3594. {
  3595. switch (((NMHDR* )lparam)->code)
  3596. {
  3597. case NM_CLICK:
  3598. case NM_RETURN:
  3599. {
  3600. DEINFO* pInfo = (DEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  3601. BOOL bCommit = FALSE;
  3602. ASSERT(pInfo);
  3603. KillTimer( pInfo->hwndDlg, 1 );
  3604. DeAdjustPbRedial( pInfo );
  3605. TRACE( "RasUserPrefsDlgInternal");
  3606. // Because the launched property pages will do the
  3607. // Load/UnLoad too.
  3608. RasUserPrefDiagOnly ( hwnd, &bCommit );
  3609. if( bCommit )
  3610. {
  3611. if ( NULL == pInfo->diagInfo.pfnGetDiagFunc ||
  3612. NULL == pInfo->diagInfo.strDiagFuncs.GetState
  3613. )
  3614. {
  3615. break;
  3616. }
  3617. else
  3618. {
  3619. BOOL fEnable = FALSE;
  3620. fEnable = pInfo->diagInfo.strDiagFuncs.GetState();
  3621. Button_SetCheck( pInfo->hwndCbEnableDiagLog,
  3622. fEnable);
  3623. }
  3624. }
  3625. SetTimer( pInfo->hwndDlg, 1, 1000L, NULL );
  3626. break;
  3627. }
  3628. }
  3629. }
  3630. break;
  3631. }
  3632. return FALSE;
  3633. }
  3634. VOID
  3635. DeAdjustPbRedial(
  3636. IN DEINFO* pInfo )
  3637. // Set the label of the Redial button or disable it as indicated by the
  3638. // redial countdown. If enabled, the button shows the number of seconds
  3639. // to auto-redial unless this is not the final redial. 'PInfo' is the
  3640. // dialog context block.
  3641. //
  3642. {
  3643. TCHAR* psz;
  3644. if (pInfo->lRedialCountdown == -2)
  3645. {
  3646. // Redial button is to be hidden. See bug 230594.
  3647. //
  3648. SetFocus( pInfo->hwndPbCancel );
  3649. ShowWindow( pInfo->hwndPbRedial, SW_HIDE );
  3650. EnableWindow( pInfo->hwndPbRedial, FALSE );
  3651. }
  3652. else
  3653. {
  3654. // Go ahead and change the label "Redial" or "Redial=%d" as
  3655. // appropriate.
  3656. //
  3657. psz = PszFromId( g_hinstDll, SID_RedialLabel );
  3658. if (psz)
  3659. {
  3660. TCHAR szBuf[ 128 ];
  3661. lstrcpyn(
  3662. szBuf,
  3663. psz,
  3664. (sizeof(szBuf) / sizeof(TCHAR)) - 4);
  3665. Free( psz );
  3666. if (pInfo->lRedialCountdown >= 0)
  3667. {
  3668. TCHAR szNum[ MAXLTOTLEN + 1 ];
  3669. DWORD dwLen, dwSize = sizeof(szBuf)/sizeof(TCHAR);
  3670. LToT( pInfo->lRedialCountdown, szNum, 10 );
  3671. lstrcat( szBuf, TEXT(" = ") );
  3672. dwLen = lstrlen(szBuf) + 1;
  3673. lstrcpyn( szBuf + (dwLen - 1), szNum, dwSize - dwLen );
  3674. }
  3675. SetWindowText( pInfo->hwndPbRedial, szBuf );
  3676. }
  3677. }
  3678. }
  3679. void DeEnableDiagnostic(
  3680. IN HWND hwnd )
  3681. {
  3682. DEINFO* pInfo = NULL;
  3683. do
  3684. {
  3685. pInfo = (DEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  3686. ASSERT( pInfo );
  3687. if( NULL == pInfo )
  3688. {
  3689. break;
  3690. }
  3691. // For whistler bug 474514 gangz
  3692. //
  3693. if( pInfo->pArgs->pDinfo->pNoUser )
  3694. {
  3695. break;
  3696. }
  3697. if ( NULL == pInfo->diagInfo.pfnGetDiagFunc ||
  3698. NULL == pInfo->diagInfo.strDiagFuncs.SetAll
  3699. )
  3700. {
  3701. // ErrorDlg( hwnd, SID_DG_LoadDiag, ERROR_UNKNOWN, NULL );
  3702. break;
  3703. }
  3704. else
  3705. {
  3706. BOOL fEnable = FALSE;
  3707. fEnable = Button_GetCheck( pInfo->hwndCbEnableDiagLog );
  3708. pInfo->diagInfo.strDiagFuncs.SetAll( fEnable );
  3709. }
  3710. }
  3711. while(FALSE);
  3712. return;
  3713. }
  3714. BOOL
  3715. DeCommand(
  3716. IN HWND hwnd,
  3717. IN WORD wNotification,
  3718. IN WORD wId,
  3719. IN HWND hwndCtrl )
  3720. // Called on WM_COMMAND. 'Hwnd' is the dialog window. 'WNotification' is
  3721. // the notification code of the command. 'wId' is the control/menu
  3722. // identifier of the command. 'HwndCtrl' is the control window handle of
  3723. // the command.
  3724. //
  3725. // Returns true if processed message, false otherwise.
  3726. //
  3727. {
  3728. DWORD dwErr;
  3729. TRACE3( "DeCommand(n=%d,i=%d,c=$%x)",
  3730. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  3731. TRACE2("Current proces:(0x%d), Current Thread:(0x%d)",
  3732. GetCurrentProcessId(),
  3733. GetCurrentThreadId());
  3734. switch (wId)
  3735. {
  3736. case IDOK:
  3737. {
  3738. TRACE( "Redial pressed" );
  3739. DeEnableDiagnostic( hwnd );
  3740. EndDialog( hwnd, TRUE );
  3741. return TRUE;
  3742. }
  3743. case IDCANCEL:
  3744. {
  3745. TRACE( "Cancel pressed" );
  3746. DeEnableDiagnostic( hwnd );
  3747. EndDialog( hwnd, FALSE );
  3748. return TRUE;
  3749. }
  3750. case CID_DE_PB_More:
  3751. {
  3752. DEINFO* pInfo;
  3753. DWORD dwContext;
  3754. pInfo = (DEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  3755. ASSERT( pInfo );
  3756. if (pInfo->pArgs->dwError >= RASBASE
  3757. && pInfo->pArgs->dwError <= RASBASEEND)
  3758. {
  3759. dwContext = HID_RASERRORBASE - RASBASE + pInfo->pArgs->dwError;
  3760. }
  3761. else if (pInfo->pArgs->dwError == 0)
  3762. {
  3763. dwContext = HID_RECONNECTING;
  3764. }
  3765. else
  3766. {
  3767. dwContext = HID_NONRASERROR;
  3768. }
  3769. WinHelp( hwnd, g_pszHelpFile, HELP_CONTEXTPOPUP, dwContext );
  3770. }
  3771. break;
  3772. // For whistler 460931
  3773. //
  3774. case CID_DE_CB_EnableDiag:
  3775. {
  3776. DEINFO* pInfo = NULL;
  3777. pInfo = (DEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  3778. ASSERT( pInfo );
  3779. if( NULL == pInfo )
  3780. {
  3781. break;
  3782. }
  3783. if ( NULL == pInfo->diagInfo.pfnGetDiagFunc ||
  3784. NULL == pInfo->diagInfo.strDiagFuncs.SetAll
  3785. )
  3786. {
  3787. ErrorDlg( hwnd, SID_DG_LoadDiag, ERROR_UNKNOWN, NULL );
  3788. break;
  3789. }
  3790. }
  3791. break;
  3792. }
  3793. return FALSE;
  3794. }
  3795. BOOL
  3796. DeInit(
  3797. IN HWND hwndDlg,
  3798. IN DEARGS* pArgs )
  3799. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
  3800. // 'PArgs' is caller's arguments to the stub API.
  3801. //
  3802. // Return false if focus was set, true otherwise, i.e. as defined for
  3803. // WM_INITDIALOG.
  3804. //
  3805. {
  3806. DWORD dwErr;
  3807. DEINFO* pInfo;
  3808. TRACE( "DeInit" );
  3809. // Allocate the dialog context block. Initialize minimally for proper
  3810. // cleanup, then attach to the dialog window.
  3811. //
  3812. {
  3813. pInfo = Malloc( sizeof(*pInfo) );
  3814. if (!pInfo)
  3815. {
  3816. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  3817. EndDialog( hwndDlg, FALSE );
  3818. return TRUE;
  3819. }
  3820. ZeroMemory( pInfo, sizeof(*pInfo) );
  3821. pInfo->pArgs = pArgs;
  3822. pInfo->hwndDlg = hwndDlg;
  3823. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  3824. TRACE( "Context set" );
  3825. }
  3826. pInfo->hwndStText = GetDlgItem( hwndDlg, CID_DE_ST_Text );
  3827. ASSERT( pInfo->hwndStText );
  3828. pInfo->hwndPbRedial = GetDlgItem( hwndDlg, IDOK );
  3829. ASSERT( pInfo->hwndPbRedial );
  3830. pInfo->hwndPbCancel = GetDlgItem( hwndDlg, IDCANCEL );
  3831. ASSERT( pInfo->hwndPbCancel );
  3832. pInfo->hwndPbMore = GetDlgItem( hwndDlg, CID_DE_PB_More );
  3833. ASSERT( pInfo->hwndPbMore );
  3834. // For whistler 460931 459793
  3835. //
  3836. pInfo->hwndCbEnableDiagLog= GetDlgItem( hwndDlg, CID_DE_CB_EnableDiag);
  3837. ASSERT( pInfo->hwndCbEnableDiagLog );
  3838. pInfo->hwndStConfigureLnk= GetDlgItem( hwndDlg, CID_DE_ST_ConfigureLnk);
  3839. ASSERT( pInfo->hwndStConfigureLnk);
  3840. pInfo->hwndStEnableHelp = GetDlgItem( hwndDlg, CID_DE_ST_EnableHelp );
  3841. ASSERT( pInfo->hwndStEnableHelp );
  3842. pInfo->hwndStLinkHelp = GetDlgItem( hwndDlg, CID_DE_ST_LinkHelp );
  3843. ASSERT( pInfo->hwndStLinkHelp );
  3844. // For whistler 474514 gangz
  3845. // Have to block the diagnostic functionality from winlogon
  3846. // For .Net 530448, diagnostic functionality is only availabe for
  3847. // Administrator or Power users
  3848. if( pInfo->pArgs->pDinfo->pNoUser ||
  3849. !FIsUserAdminOrPowerUser() )
  3850. {
  3851. EnableWindow(pInfo->hwndCbEnableDiagLog, FALSE);
  3852. EnableWindow(pInfo->hwndStConfigureLnk, FALSE);
  3853. ShowWindow(pInfo->hwndStConfigureLnk, SW_HIDE);
  3854. EnableWindow(pInfo->hwndStEnableHelp, FALSE);
  3855. EnableWindow(pInfo->hwndStLinkHelp, FALSE);
  3856. }
  3857. else
  3858. {
  3859. // For whistler bug 460931 gangz
  3860. // Load the Diagnostic functions
  3861. //
  3862. // Have to zero memory, or else LoadDiagnosticDll may fail
  3863. ZeroMemory( &pInfo->diagInfo, sizeof(pInfo->diagInfo ) );
  3864. if ( NO_ERROR == LoadDiagnosticDll( &pInfo->diagInfo ) )
  3865. {
  3866. BOOL fEnable = FALSE;
  3867. fEnable = pInfo->diagInfo.strDiagFuncs.GetState();
  3868. Button_SetCheck( pInfo->hwndCbEnableDiagLog,
  3869. fEnable
  3870. );
  3871. }
  3872. else
  3873. {
  3874. ;
  3875. // EnableWindow( pInfo->hwndCbEnableDiagLog, FALSE );
  3876. // EnableWindow( pInfo->hwndStConfigureLnk, FALSE );
  3877. }
  3878. }
  3879. // Hide/disable "more info" button if WinHelp won't work. See
  3880. // common\uiutil\ui.c.
  3881. //
  3882. {
  3883. extern BOOL g_fNoWinHelp;
  3884. if (g_fNoWinHelp)
  3885. {
  3886. ShowWindow( pInfo->hwndPbMore, SW_HIDE );
  3887. EnableWindow( pInfo->hwndPbMore, FALSE );
  3888. }
  3889. }
  3890. if (pArgs->dwError == 0)
  3891. {
  3892. TCHAR* pszFormat;
  3893. TCHAR* psz;
  3894. TCHAR* apszArgs[ 1 ];
  3895. // Redialing on link failure. Set title to "Dial-Up Networking".
  3896. //
  3897. psz = PszFromId( g_hinstDll, SID_PopupTitle );
  3898. if (psz)
  3899. {
  3900. SetWindowText( hwndDlg, psz );
  3901. Free( psz );
  3902. }
  3903. // Set static placeholder text control to "Link to <entry> failed.
  3904. // Reconnect pending...".
  3905. //
  3906. pszFormat = PszFromId( g_hinstDll, SID_DE_LinkFailed );
  3907. if (pszFormat)
  3908. {
  3909. apszArgs[ 0 ] = pArgs->pszEntry;
  3910. psz = NULL;
  3911. FormatMessage(
  3912. FORMAT_MESSAGE_FROM_STRING
  3913. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  3914. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  3915. pszFormat, 0, 0, (LPTSTR )&psz, 1,
  3916. (va_list* )apszArgs );
  3917. Free( pszFormat );
  3918. if (psz)
  3919. {
  3920. SetWindowText( pInfo->hwndStText, psz );
  3921. LocalFree( psz );
  3922. }
  3923. }
  3924. }
  3925. else
  3926. {
  3927. TCHAR* pszTitleFormat;
  3928. TCHAR* pszTitle;
  3929. TCHAR* apszArgs[ 1 ];
  3930. ERRORARGS args;
  3931. // Set title to "Error Connecting to <entry>".
  3932. //
  3933. pszTitleFormat = GetText( hwndDlg );
  3934. if (pszTitleFormat)
  3935. {
  3936. apszArgs[ 0 ] = pArgs->pszEntry;
  3937. pszTitle = NULL;
  3938. FormatMessage(
  3939. FORMAT_MESSAGE_FROM_STRING
  3940. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  3941. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  3942. pszTitleFormat, 0, 0, (LPTSTR )&pszTitle, 1,
  3943. (va_list* )apszArgs );
  3944. Free( pszTitleFormat );
  3945. if (pszTitle)
  3946. {
  3947. SetWindowText( hwndDlg, pszTitle );
  3948. LocalFree( pszTitle );
  3949. }
  3950. }
  3951. // Build the error text and load it into the placeholder text control.
  3952. //
  3953. ZeroMemory( &args, sizeof(args) );
  3954. if (pArgs->pszStatusArg)
  3955. args.apszOpArgs[ 0 ] = pArgs->pszStatusArg;
  3956. if (pArgs->pszFormatArg)
  3957. args.apszAuxFmtArgs[ 0 ] = pArgs->pszFormatArg;
  3958. args.fStringOutput = TRUE;
  3959. ErrorDlgUtil( hwndDlg,
  3960. pArgs->sidState, pArgs->dwError, &args, g_hinstDll, 0,
  3961. (pArgs->sidFormatMsg) ? pArgs->sidFormatMsg : SID_FMT_ErrorMsg );
  3962. if (args.pszOutput)
  3963. {
  3964. SetWindowText( pInfo->hwndStText, args.pszOutput );
  3965. LocalFree( args.pszOutput );
  3966. }
  3967. }
  3968. // Stretch the dialog window to a vertical size appropriate for the text
  3969. // we loaded.
  3970. //
  3971. {
  3972. HDC hdc;
  3973. RECT rect;
  3974. RECT rectNew;
  3975. HFONT hfont;
  3976. LONG dyGrow;
  3977. TCHAR* psz;
  3978. psz = GetText( pInfo->hwndStText );
  3979. if (psz)
  3980. {
  3981. GetClientRect( pInfo->hwndStText, &rect );
  3982. hdc = GetDC( pInfo->hwndStText );
  3983. if(NULL != hdc)
  3984. {
  3985. hfont = (HFONT )SendMessage( pInfo->hwndStText,
  3986. WM_GETFONT, 0, 0 );
  3987. if (hfont)
  3988. {
  3989. SelectObject( hdc, hfont );
  3990. }
  3991. rectNew = rect;
  3992. DrawText( hdc, psz, -1, &rectNew,
  3993. DT_CALCRECT | DT_WORDBREAK | DT_EXPANDTABS | DT_NOPREFIX );
  3994. ReleaseDC( pInfo->hwndStText, hdc );
  3995. }
  3996. dyGrow = rectNew.bottom - rect.bottom;
  3997. ExpandWindow( pInfo->hwndDlg, 0, dyGrow );
  3998. ExpandWindow( pInfo->hwndStText, 0, dyGrow );
  3999. // For whistler 460931 459793
  4000. //
  4001. SlideWindow( pInfo->hwndCbEnableDiagLog, pInfo->hwndDlg, 0, dyGrow );
  4002. SlideWindow( pInfo->hwndStLinkHelp, pInfo->hwndDlg, 0, dyGrow );
  4003. SlideWindow( pInfo->hwndStConfigureLnk, pInfo->hwndDlg, 0, dyGrow );
  4004. SlideWindow( pInfo->hwndStEnableHelp, pInfo->hwndDlg, 0, dyGrow );
  4005. SlideWindow( pInfo->hwndPbRedial, pInfo->hwndDlg, 0, dyGrow );
  4006. SlideWindow( pInfo->hwndPbCancel, pInfo->hwndDlg, 0, dyGrow );
  4007. SlideWindow( pInfo->hwndPbMore, pInfo->hwndDlg, 0, dyGrow );
  4008. Free( psz );
  4009. }
  4010. }
  4011. // Set Redial button label or disable the button. Always choose to redial
  4012. // after 5 seconds for the biplex error, since this will normally solve
  4013. // the problem. Otherwise, no countdown is used.
  4014. //
  4015. if (pArgs->dwError == ERROR_BIPLEX_PORT_NOT_AVAILABLE)
  4016. {
  4017. pInfo->lRedialCountdown = 5;
  4018. }
  4019. else
  4020. {
  4021. pInfo->lRedialCountdown = pArgs->lRedialCountdown;
  4022. }
  4023. DeAdjustPbRedial( pInfo );
  4024. if (pInfo->lRedialCountdown >= 0)
  4025. {
  4026. SetTimer( pInfo->hwndDlg, 1, 1000L, NULL );
  4027. }
  4028. // Add context help button to title bar.
  4029. //
  4030. AddContextHelpButton( hwndDlg );
  4031. if (pArgs->fPopupOnTop)
  4032. {
  4033. // Display the finished window above all other windows. The window
  4034. // position is set to "topmost" then immediately set to "not topmost"
  4035. // because we want it on top but not always-on-top. Always-on-top
  4036. // alone is too annoying.
  4037. //
  4038. SetWindowPos(
  4039. hwndDlg, HWND_TOPMOST, 0, 0, 0, 0,
  4040. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
  4041. }
  4042. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  4043. ShowWindow( hwndDlg, SW_SHOW );
  4044. if (pArgs->fPopupOnTop)
  4045. {
  4046. SetForegroundWindow( hwndDlg );
  4047. SetWindowPos(
  4048. hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
  4049. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
  4050. }
  4051. return TRUE;
  4052. }
  4053. // Helper function to delete credentials
  4054. //
  4055. // fDeleteDefault specifies whether it is the default credentials that
  4056. // should be deleted.
  4057. //
  4058. // fDeleteIdentity specifies whether to delete the user and domain names
  4059. // in addition to the password.
  4060. //
  4061. DWORD
  4062. DeleteSavedCredentials(
  4063. IN DINFO* pDinfo,
  4064. IN HWND hwndDlg,
  4065. IN BOOL fDefault,
  4066. IN BOOL fDeleteIdentity )
  4067. {
  4068. RASCREDENTIALS rc;
  4069. DWORD dwErr = NO_ERROR;
  4070. TRACE2( "DeleteSavedCredentials: %d %d", fDefault, fDeleteIdentity );
  4071. ZeroMemory(&rc, sizeof(rc));
  4072. rc.dwSize = sizeof(RASCREDENTIALS);
  4073. rc.dwMask = RASCM_Password;
  4074. if (fDeleteIdentity)
  4075. {
  4076. rc.dwMask |= (RASCM_UserName | RASCM_Domain);
  4077. }
  4078. if ( (fDefault)
  4079. && (IsPublicPhonebook(pDinfo->pFile->pszPath)))
  4080. {
  4081. rc.dwMask |= RASCM_DefaultCreds;
  4082. }
  4083. dwErr = g_pRasSetCredentials(
  4084. pDinfo->pFile->pszPath,
  4085. pDinfo->pEntry->pszEntryName,
  4086. &rc,
  4087. TRUE );
  4088. if (dwErr != 0)
  4089. {
  4090. ErrorDlg( hwndDlg, SID_OP_UncachePw, dwErr, NULL );
  4091. }
  4092. TRACE1( "DeleteSavedCredentials: RasSetCredentials=%d", dwErr );
  4093. return dwErr;
  4094. }
  4095. VOID
  4096. DeTerm(
  4097. IN HWND hwndDlg )
  4098. // Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
  4099. //
  4100. {
  4101. DEINFO* pInfo = (DEINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  4102. TRACE( "DeTerm" );
  4103. if (pInfo)
  4104. {
  4105. if(! pInfo->pArgs->pDinfo->pNoUser )
  4106. {
  4107. UnLoadDiagnosticDll( &pInfo->diagInfo);
  4108. }
  4109. Free( pInfo );
  4110. pInfo = NULL;
  4111. }
  4112. }
  4113. //----------------------------------------------------------------------------
  4114. // Dial Progress dialog
  4115. // Listed alphabetically following stub API dialog proc
  4116. //----------------------------------------------------------------------------
  4117. BOOL
  4118. DialProgressDlg(
  4119. IN DINFO* pInfo )
  4120. // Popup the Dial Progress dialog. 'PInfo' is the dialog context.
  4121. //
  4122. // Returns true if user connected successfully, false is he cancelled or
  4123. // hit an error.
  4124. //
  4125. {
  4126. INT_PTR nStatus;
  4127. // Run the dialog.
  4128. //
  4129. nStatus =
  4130. DialogBoxParam(
  4131. g_hinstDll,
  4132. MAKEINTRESOURCE( DID_DP_DialProgress ),
  4133. pInfo->pArgs->hwndOwner,
  4134. DpDlgProc,
  4135. (LPARAM )pInfo );
  4136. if (nStatus == -1)
  4137. {
  4138. ErrorDlg( pInfo->pArgs->hwndOwner, SID_OP_LoadDlg,
  4139. ERROR_UNKNOWN, NULL );
  4140. pInfo->pArgs->dwError = ERROR_UNKNOWN;
  4141. nStatus = FALSE;
  4142. }
  4143. if (nStatus)
  4144. {
  4145. DWORD dwErr;
  4146. PBFILE file;
  4147. // Connected successfully, so read possible changes to the entry made
  4148. // by RasDial.
  4149. //
  4150. dwErr = ReadPhonebookFile( pInfo->pFile->pszPath, pInfo->pUser,
  4151. pInfo->pEntry->pszEntryName, RPBF_ReadOnly, &file );
  4152. if (dwErr == 0)
  4153. {
  4154. DTLNODE* pNodeNew;
  4155. pNodeNew = DtlGetFirstNode( file.pdtllistEntries );
  4156. if (pNodeNew)
  4157. {
  4158. DtlRemoveNode( pInfo->pFile->pdtllistEntries, pInfo->pNode );
  4159. DestroyEntryNode( pInfo->pNode );
  4160. DtlRemoveNode( file.pdtllistEntries, pNodeNew );
  4161. DtlAddNodeLast( pInfo->pFile->pdtllistEntries, pNodeNew );
  4162. pInfo->pNode = pNodeNew;
  4163. pInfo->pEntry = (PBENTRY* )DtlGetData( pNodeNew );
  4164. }
  4165. ClosePhonebookFile( &file );
  4166. }
  4167. }
  4168. // See if we need to change the entry based on what happened while
  4169. // dialing.
  4170. //
  4171. {
  4172. BOOL fChange = FALSE;
  4173. if (pInfo->fResetAutoLogon)
  4174. {
  4175. ASSERT( !pInfo->pNoUser );
  4176. pInfo->pEntry->fAutoLogon = FALSE;
  4177. fChange = TRUE;
  4178. }
  4179. if (pInfo->dwfExcludedProtocols)
  4180. {
  4181. pInfo->pEntry->dwfExcludedProtocols
  4182. |= pInfo->dwfExcludedProtocols;
  4183. fChange = TRUE;
  4184. }
  4185. if (pInfo->pListPortsToDelete)
  4186. {
  4187. DTLNODE* pNode;
  4188. pNode = DtlGetFirstNode( pInfo->pEntry->pdtllistLinks );
  4189. while (pNode)
  4190. {
  4191. DTLNODE* pNodeNext;
  4192. DTLNODE* pNodePtd;
  4193. PBLINK* pLink;
  4194. TCHAR* pszPort;
  4195. pNodeNext = DtlGetNextNode( pNode );
  4196. pLink = (PBLINK* )DtlGetData( pNode );
  4197. pszPort = pLink->pbport.pszPort;
  4198. for (pNodePtd = DtlGetFirstNode( pInfo->pListPortsToDelete );
  4199. pNodePtd;
  4200. pNodePtd = DtlGetNextNode( pNodePtd ))
  4201. {
  4202. TCHAR* pszPtd = (TCHAR* )DtlGetData( pNodePtd );
  4203. if (lstrcmp( pszPtd, pszPort ) == 0)
  4204. {
  4205. pNode = DtlRemoveNode(
  4206. pInfo->pEntry->pdtllistLinks, pNode );
  4207. DestroyLinkNode( pNode );
  4208. fChange = TRUE;
  4209. break;
  4210. }
  4211. }
  4212. pNode = pNodeNext;
  4213. }
  4214. }
  4215. if (fChange)
  4216. {
  4217. pInfo->pEntry->fDirty = TRUE;
  4218. WritePhonebookFile( pInfo->pFile, NULL );
  4219. }
  4220. }
  4221. return (BOOL )nStatus;
  4222. }
  4223. INT_PTR CALLBACK
  4224. DpDlgProc(
  4225. IN HWND hwnd,
  4226. IN UINT unMsg,
  4227. IN WPARAM wparam,
  4228. IN LPARAM lparam )
  4229. // DialogProc callback for the User Authentication dialog. Parameters and
  4230. // return value are as described for standard windows 'DialogProc's.
  4231. //
  4232. {
  4233. #if 0
  4234. TRACE4( "DpDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  4235. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  4236. #endif
  4237. switch (unMsg)
  4238. {
  4239. case WM_INITDIALOG:
  4240. {
  4241. return DpInit( hwnd, (DINFO* )lparam );
  4242. }
  4243. case WM_COMMAND:
  4244. {
  4245. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  4246. ASSERT( pInfo );
  4247. return DpCommand(
  4248. pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  4249. }
  4250. case WM_RASDIAL:
  4251. {
  4252. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  4253. ASSERT( pInfo );
  4254. Sleep( 0 );
  4255. DpDial( pInfo, (BOOL)wparam );
  4256. return TRUE;
  4257. }
  4258. case WM_RASERROR:
  4259. {
  4260. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  4261. ASSERT( pInfo );
  4262. Sleep( 0 );
  4263. //For whistler bug 381337
  4264. //
  4265. if ( !pInfo->fCancelPressed )
  4266. {
  4267. DpError( pInfo, (DPSTATE* )lparam );
  4268. }
  4269. else
  4270. {
  4271. TRACE("DpDlgProc is already canceled, wont respond to WM_RASERROR");
  4272. }
  4273. return TRUE;
  4274. }
  4275. case WM_RASBUNDLEERROR:
  4276. {
  4277. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  4278. ASSERT( pInfo );
  4279. Sleep( 0 );
  4280. if (BundlingErrorsDlg( pInfo ))
  4281. {
  4282. EndDialog( pInfo->hwndDlg, TRUE );
  4283. }
  4284. else
  4285. {
  4286. DpCancel( pInfo );
  4287. }
  4288. return TRUE;
  4289. }
  4290. case WM_DPENDDIALOG:
  4291. {
  4292. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  4293. ASSERT( pInfo );
  4294. // XPSP2 511810, .Net 668164
  4295. if ( GetCallbackActive(pInfo))
  4296. {
  4297. // Callbacks are active. Stall until they complete.
  4298. //
  4299. // SetTerminateFlag(pInfo);
  4300. TRACE( "Stall until callbacks disabled" );
  4301. PostMessage( hwnd, WM_DPENDDIALOG, wparam, lparam );
  4302. }
  4303. else
  4304. {
  4305. EndDialog( hwnd, (BOOL)lparam);
  4306. }
  4307. }
  4308. return TRUE;
  4309. case WM_DESTROY:
  4310. {
  4311. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  4312. ASSERT( pInfo );
  4313. // Whistler Bugs: 344019 SECBUGBASH: leaving leaked password in
  4314. // memory when user changes password over RAS
  4315. //
  4316. // 289587 Failed RAS connections reset password to blank
  4317. //
  4318. if (pInfo->pszGoodPassword)
  4319. {
  4320. ZeroMemory(
  4321. pInfo->pszGoodPassword,
  4322. (lstrlen( pInfo->pszGoodPassword ) + 1) * sizeof(TCHAR) );
  4323. Free( pInfo->pszGoodPassword );
  4324. pInfo->pszGoodPassword = NULL;
  4325. }
  4326. if (pInfo->pszGoodUserName)
  4327. {
  4328. Free( pInfo->pszGoodUserName );
  4329. pInfo->pszGoodUserName = NULL;
  4330. }
  4331. if (GetCallbackActive(pInfo))
  4332. {
  4333. // Callbacks are active. Stall until they complete.
  4334. //
  4335. TRACE( "Stall until callbacks disabled" );
  4336. SetTerminateFlag(pInfo);
  4337. PostMessage( hwnd, WM_DESTROY, wparam, lparam );
  4338. return TRUE;
  4339. }
  4340. DpTerm( hwnd );
  4341. break;
  4342. }
  4343. }
  4344. return FALSE;
  4345. }
  4346. VOID
  4347. DpAppendBlankLine(
  4348. IN OUT TCHAR* pszLines )
  4349. // Append a blank line on the end of 'pszLines'.
  4350. //
  4351. {
  4352. lstrcat( pszLines, TEXT("\n") );
  4353. }
  4354. VOID
  4355. DpAppendConnectErrorLine(
  4356. IN OUT TCHAR* pszLines,
  4357. IN DWORD sidProtocol,
  4358. IN DWORD dwError )
  4359. // Append a connect error line for protocol 'sidProtocol' and error
  4360. // 'dwError' onto the end of 'pszLines'.
  4361. //
  4362. {
  4363. #define MAXRASERRORLEN 256
  4364. TCHAR* pszProtocol;
  4365. TCHAR* pszErrStr;
  4366. TCHAR szErrNumBuf[ MAXLTOTLEN + 1 ];
  4367. // Gather the argument strings.
  4368. //
  4369. pszProtocol = PszFromId( g_hinstDll, sidProtocol );
  4370. if (!pszProtocol)
  4371. {
  4372. return;
  4373. }
  4374. LToT( dwError, szErrNumBuf, 10 );
  4375. pszErrStr = NULL;
  4376. GetErrorText( dwError, &pszErrStr );
  4377. // Format the line and append it to caller's line buffer.
  4378. //
  4379. {
  4380. TCHAR* pszLineFormat;
  4381. TCHAR* pszLine;
  4382. TCHAR* apszArgs[ 3 ];
  4383. pszLineFormat = PszFromId( g_hinstDll, SID_FMT_ProjectError );
  4384. if (pszLineFormat)
  4385. {
  4386. apszArgs[ 0 ] = pszProtocol;
  4387. apszArgs[ 1 ] = szErrNumBuf;
  4388. apszArgs[ 2 ] = (pszErrStr) ? pszErrStr : TEXT("");
  4389. pszLine = NULL;
  4390. FormatMessage(
  4391. FORMAT_MESSAGE_FROM_STRING
  4392. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  4393. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  4394. pszLineFormat, 0, 0, (LPTSTR )&pszLine, 1,
  4395. (va_list* )apszArgs );
  4396. Free( pszLineFormat );
  4397. if (pszLine)
  4398. {
  4399. lstrcat( pszLines, pszLine );
  4400. LocalFree( pszLine );
  4401. }
  4402. }
  4403. }
  4404. Free( pszProtocol );
  4405. Free0( pszErrStr );
  4406. }
  4407. VOID
  4408. DpAppendConnectOkLine(
  4409. IN OUT TCHAR* pszLines,
  4410. IN DWORD sidProtocol )
  4411. // Append a "connected successfully" line for protocol 'sidProtocol' onto
  4412. // the end of 'pszLines'.
  4413. //
  4414. {
  4415. TCHAR* pszProtocol;
  4416. // Get the argument string.
  4417. //
  4418. pszProtocol = PszFromId( g_hinstDll, sidProtocol );
  4419. if (!pszProtocol)
  4420. {
  4421. return;
  4422. }
  4423. // Format the line and append it to caller's line buffer.
  4424. //
  4425. {
  4426. TCHAR* pszLineFormat;
  4427. TCHAR* pszLine;
  4428. TCHAR* apszArgs[ 1 ];
  4429. pszLineFormat = PszFromId( g_hinstDll, SID_FMT_ProjectOk );
  4430. if (pszLineFormat)
  4431. {
  4432. apszArgs[ 0 ] = pszProtocol;
  4433. pszLine = NULL;
  4434. FormatMessage(
  4435. FORMAT_MESSAGE_FROM_STRING
  4436. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  4437. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  4438. pszLineFormat, 0, 0, (LPTSTR )&pszLine, 1,
  4439. (va_list* )apszArgs );
  4440. Free( pszLineFormat );
  4441. if (pszLine)
  4442. {
  4443. lstrcat( pszLines, pszLine );
  4444. LocalFree( pszLine );
  4445. }
  4446. }
  4447. }
  4448. Free( pszProtocol );
  4449. }
  4450. VOID
  4451. DpAppendFailCodeLine(
  4452. IN OUT TCHAR* pszLines,
  4453. IN DWORD dw )
  4454. // Append hexidecimal fail code 'dw' as an extended error line on the end
  4455. // of 'pszLines'.
  4456. //
  4457. {
  4458. TCHAR szNumBuf[ MAXLTOTLEN + 1 ];
  4459. // Get the argument string.
  4460. //
  4461. LToT( dw, szNumBuf, 16 );
  4462. // Format the line and append it to caller's line buffer.
  4463. //
  4464. {
  4465. TCHAR* pszLineFormat;
  4466. TCHAR* pszLine;
  4467. TCHAR* apszArgs[ 1 ];
  4468. pszLineFormat = PszFromId( g_hinstDll, SID_FMT_FailCode );
  4469. if (pszLineFormat)
  4470. {
  4471. apszArgs[ 0 ] = szNumBuf;
  4472. pszLine = NULL;
  4473. FormatMessage(
  4474. FORMAT_MESSAGE_FROM_STRING
  4475. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  4476. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  4477. pszLineFormat, 0, 0, (LPTSTR )&pszLine, 1,
  4478. (va_list* )apszArgs );
  4479. Free( pszLineFormat );
  4480. if (pszLine)
  4481. {
  4482. lstrcat( pszLines, pszLine );
  4483. LocalFree( pszLine );
  4484. }
  4485. }
  4486. }
  4487. }
  4488. VOID
  4489. DpAppendNameLine(
  4490. IN OUT TCHAR* pszLines,
  4491. IN TCHAR* psz )
  4492. // Append NetBIOS name 'psz' as an extended error line on the end of
  4493. // 'pszLines'.
  4494. //
  4495. {
  4496. TCHAR* pszLineFormat;
  4497. TCHAR* pszLine;
  4498. TCHAR* apszArgs[ 1 ];
  4499. pszLineFormat = PszFromId( g_hinstDll, SID_FMT_Name );
  4500. if (pszLineFormat)
  4501. {
  4502. apszArgs[ 0 ] = psz;
  4503. pszLine = NULL;
  4504. FormatMessage(
  4505. FORMAT_MESSAGE_FROM_STRING
  4506. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  4507. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  4508. pszLineFormat, 0, 0, (LPTSTR )&pszLine, 1,
  4509. (va_list* )apszArgs );
  4510. Free( pszLineFormat );
  4511. if (pszLine)
  4512. {
  4513. lstrcat( pszLines, pszLine );
  4514. LocalFree( pszLine );
  4515. }
  4516. }
  4517. }
  4518. VOID
  4519. DpAuthNotify(
  4520. IN DPINFO* pInfo,
  4521. IN DPSTATE* pState )
  4522. // Called on an authentication notify, i.e. a message from RASCAUTH.DLL or
  4523. // RASPPPEN.DLL. 'PInfo' is the dialog context. 'PState' is the current
  4524. // link's context.
  4525. //
  4526. {
  4527. PBENTRY* pEntry;
  4528. TRACE( "DpAuthNotify" );
  4529. pEntry = pInfo->pArgs->pEntry;
  4530. if (pState->dwError == ERROR_ACCESS_DENIED && pEntry->fAutoLogon)
  4531. {
  4532. // A third party box has negotiated an authentication protocol that
  4533. // can't deal with the NT one-way-hashed password, i.e. something
  4534. // besides MS-extended CHAP or AMB. Map the error to a more
  4535. // informative error message.
  4536. //
  4537. pState->dwError = ERROR_CANNOT_USE_LOGON_CREDENTIALS;
  4538. if (!pInfo->pArgs->pNoUser)
  4539. {
  4540. TRACE( "Disable auto-logon" );
  4541. pEntry->fAutoLogon = FALSE;
  4542. pInfo->pArgs->fResetAutoLogon = TRUE;
  4543. }
  4544. }
  4545. if (pState->dwError == ERROR_CHANGING_PASSWORD)
  4546. {
  4547. TRACE( "DpAuthNotify - ERROR_CHANGING_PASSWORD" );
  4548. // Change password failed. Restore the password that worked for the
  4549. // "button" redial.
  4550. //
  4551. if (pInfo->pszGoodPassword)
  4552. {
  4553. // Whistler bug 254385 encode password when not being used
  4554. // Assumed password was encoded by DpPasswordExpired()
  4555. //
  4556. DecodePassword( pInfo->pszGoodPassword );
  4557. lstrcpyn(
  4558. pInfo->pArgs->rdp.szPassword,
  4559. pInfo->pszGoodPassword,
  4560. sizeof(pInfo->pArgs->rdp.szPassword) / sizeof(TCHAR) );
  4561. EncodePassword( pInfo->pArgs->rdp.szPassword );
  4562. ZeroMemory(
  4563. pInfo->pszGoodPassword,
  4564. (lstrlen( pInfo->pszGoodPassword ) + 1) * sizeof(TCHAR) );
  4565. Free( pInfo->pszGoodPassword );
  4566. pInfo->pszGoodPassword = NULL;
  4567. }
  4568. if (pInfo->pszGoodUserName)
  4569. {
  4570. lstrcpyn(
  4571. pInfo->pArgs->rdp.szUserName,
  4572. pInfo->pszGoodUserName,
  4573. sizeof(pInfo->pArgs->rdp.szUserName) / sizeof(TCHAR) );
  4574. Free( pInfo->pszGoodUserName );
  4575. pInfo->pszGoodUserName = NULL;
  4576. }
  4577. }
  4578. // Update cached credentials, if any, with new password.
  4579. //
  4580. // Whistler Bugs: 344019 SECBUGBASH: leaving leaked password in memory when
  4581. // user changes password over RAS
  4582. //
  4583. // 289587 Failed RAS connections reset password to blank
  4584. //
  4585. if ((pState->sidState == SID_S_Projected) &&
  4586. (pInfo->pszGoodPassword) &&
  4587. (pInfo->pszGoodUserName))
  4588. {
  4589. DWORD dwErr;
  4590. RASCREDENTIALS rc;
  4591. TRACE( "DpAuthNotify - Success changing password, caching if necessary" );
  4592. ZeroMemory( &rc, sizeof(rc) );
  4593. rc.dwSize = sizeof(rc);
  4594. // Look up cached password. Since we are only calling in with the
  4595. // RASCM_Password flag here, with the current implementation of
  4596. // RasGet/SetCredentials, this works for the Set below whether we are
  4597. // saving a Per-User, Global, or the special case of having both saved
  4598. // at the same time. Whew, complicated!
  4599. //
  4600. rc.dwMask = RASCM_Password;
  4601. ASSERT( g_pRasGetCredentials );
  4602. TRACE( "RasGetCredentials" );
  4603. dwErr = g_pRasGetCredentials(
  4604. pInfo->pArgs->pFile->pszPath,
  4605. pInfo->pArgs->pEntry->pszEntryName,
  4606. &rc );
  4607. TRACE2( "RasGetCredentials=%d,m=%x", dwErr, rc.dwMask );
  4608. if (dwErr == 0 && (rc.dwMask & RASCM_Password))
  4609. {
  4610. // Password was cached, so update it.
  4611. //
  4612. DecodePassword( pInfo->pArgs->rdp.szPassword );
  4613. lstrcpyn(
  4614. rc.szPassword,
  4615. pInfo->pArgs->rdp.szPassword,
  4616. sizeof(rc.szPassword) / sizeof(TCHAR) );
  4617. EncodePassword( pInfo->pArgs->rdp.szPassword );
  4618. ASSERT( g_pRasSetCredentials );
  4619. TRACE( "RasSetCredentials(p,FALSE)" );
  4620. dwErr = g_pRasSetCredentials(
  4621. pInfo->pArgs->pFile->pszPath,
  4622. pInfo->pArgs->pEntry->pszEntryName, &rc, FALSE );
  4623. TRACE1( "RasSetCredentials=%d", dwErr );
  4624. if (dwErr != 0)
  4625. {
  4626. ErrorDlg( pInfo->hwndDlg, SID_OP_UncachePw, dwErr, NULL );
  4627. }
  4628. }
  4629. // Clean up
  4630. //
  4631. RtlSecureZeroMemory( rc.szPassword, sizeof(rc.szPassword) );
  4632. RtlSecureZeroMemory(
  4633. pInfo->pszGoodPassword,
  4634. (lstrlen( pInfo->pszGoodPassword ) + 1) * sizeof(TCHAR) );
  4635. Free( pInfo->pszGoodPassword );
  4636. pInfo->pszGoodPassword = NULL;
  4637. Free( pInfo->pszGoodUserName );
  4638. pInfo->pszGoodUserName = NULL;
  4639. }
  4640. }
  4641. VOID
  4642. DpCallbackSetByCaller(
  4643. IN DPINFO* pInfo,
  4644. IN DPSTATE* pState )
  4645. // RASCS_CallbackSetByCaller state handling. 'PInfo' is the dialog
  4646. // context. 'PState' is the subentry state.
  4647. //
  4648. // Returns true if successful, or an error code.
  4649. //
  4650. {
  4651. TCHAR* pszDefault;
  4652. TCHAR szNum[ RAS_MaxCallbackNumber + 1 ];
  4653. TRACE( "DpCallbackSetByCaller" );
  4654. pszDefault = pInfo->pArgs->pUser->pszLastCallbackByCaller;
  4655. if (!pszDefault)
  4656. {
  4657. pszDefault = TEXT("");
  4658. }
  4659. lstrcpyn( szNum, pszDefault, RAS_MaxCallbackNumber + 1 );
  4660. if (DialCallbackDlg( pInfo->hwndDlg, szNum ))
  4661. {
  4662. lstrcpyn( pInfo->pArgs->rdp.szCallbackNumber, szNum, RAS_MaxCallbackNumber + 1 );
  4663. if (lstrcmp( szNum, pszDefault ) != 0)
  4664. {
  4665. Free0( pInfo->pArgs->pUser->pszLastCallbackByCaller );
  4666. pInfo->pArgs->pUser->pszLastCallbackByCaller = StrDup( szNum );
  4667. pInfo->pArgs->pUser->fDirty = TRUE;
  4668. }
  4669. }
  4670. else
  4671. {
  4672. pInfo->pArgs->rdp.szCallbackNumber[ 0 ] = TEXT('\0');
  4673. }
  4674. pState->sidState = 0;
  4675. }
  4676. BOOL GetTerminateFlag(
  4677. IN DPINFO * pInfo)
  4678. {
  4679. BOOL ret = FALSE;
  4680. __try
  4681. {
  4682. EnterCriticalSection( &g_csCallBacks );
  4683. ret = pInfo->fTerminateAsap;
  4684. }
  4685. __finally
  4686. {
  4687. LeaveCriticalSection( &g_csCallBacks );
  4688. }
  4689. return ret;
  4690. }
  4691. BOOL SetTerminateFlag(
  4692. IN DPINFO * pInfo)
  4693. {
  4694. BOOL ret = FALSE;
  4695. __try
  4696. {
  4697. EnterCriticalSection( &g_csCallBacks );
  4698. ret = pInfo->fTerminateAsap = 1;
  4699. TRACE1("CallActive is:%d", ret);
  4700. }
  4701. __finally
  4702. {
  4703. LeaveCriticalSection( &g_csCallBacks );
  4704. }
  4705. return ret;
  4706. }
  4707. BOOL ResetTerminateFlag(
  4708. IN DPINFO * pInfo)
  4709. {
  4710. BOOL ret = FALSE;
  4711. __try
  4712. {
  4713. EnterCriticalSection( &g_csCallBacks );
  4714. ret = pInfo->fTerminateAsap = 0;
  4715. TRACE1("CallActive is:%d", ret);
  4716. }
  4717. __finally
  4718. {
  4719. LeaveCriticalSection( &g_csCallBacks );
  4720. }
  4721. return ret;
  4722. }
  4723. BOOL GetCallbackActive(
  4724. IN DPINFO * pInfo)
  4725. {
  4726. BOOL ret = FALSE;
  4727. __try
  4728. {
  4729. EnterCriticalSection( &g_csCallBacks );
  4730. ret = pInfo->fCallbacksActive;
  4731. TRACE1("CallActive is:%d", ret);
  4732. }
  4733. __finally
  4734. {
  4735. LeaveCriticalSection( &g_csCallBacks );
  4736. }
  4737. return ret;
  4738. }
  4739. BOOL SetCallbackActive(
  4740. IN DPINFO * pInfo)
  4741. {
  4742. BOOL ret = FALSE;
  4743. __try
  4744. {
  4745. EnterCriticalSection( &g_csCallBacks );
  4746. ret = pInfo->fCallbacksActive = 1;
  4747. TRACE1("CallActive is:%d", ret);
  4748. }
  4749. __finally
  4750. {
  4751. LeaveCriticalSection( &g_csCallBacks );
  4752. }
  4753. return ret;
  4754. }
  4755. BOOL ResetCallbackActive(
  4756. IN DPINFO * pInfo)
  4757. {
  4758. BOOL ret = FALSE;
  4759. __try
  4760. {
  4761. EnterCriticalSection( &g_csCallBacks );
  4762. ret = pInfo->fCallbacksActive = 0;
  4763. TRACE1("CallActive is:%d", ret);
  4764. }
  4765. __finally
  4766. {
  4767. LeaveCriticalSection( &g_csCallBacks );
  4768. }
  4769. return ret;
  4770. }
  4771. VOID
  4772. DpCancel(
  4773. IN DPINFO* pInfo )
  4774. // Kill the dialog and any partially initiated call, as when cancel button
  4775. // is pressed. 'PInfo' is the dialog context block.
  4776. //
  4777. {
  4778. TRACE( "DpCancel" );
  4779. // Hide window to prevent visual complaints that arise if RasHangUp takes
  4780. // a long time to complete.
  4781. //
  4782. ShowWindow( pInfo->hwndDlg, SW_HIDE );
  4783. if (pInfo->hrasconn)
  4784. {
  4785. DWORD dwErr;
  4786. ASSERT( g_pRasHangUp );
  4787. TRACE( "RasHangUp" );
  4788. TRACE("DpCancel:call RasHangUp");
  4789. dwErr = g_pRasHangUp( pInfo->hrasconn );
  4790. TRACE1("DpCancel:get dwErr from RasHangUp:(%d)", dwErr);
  4791. TRACE1( "RasHangUp=%d", dwErr );
  4792. }
  4793. //For whistler 435725
  4794. //
  4795. if( !pInfo->fCancelPressed )
  4796. {
  4797. TRACE("DpEndDialog:Cancel pressed");
  4798. pInfo->fCancelPressed = TRUE;
  4799. }
  4800. DpEndDialog( pInfo, FALSE );
  4801. }
  4802. BOOL
  4803. DpCommand(
  4804. IN DPINFO* pInfo,
  4805. IN WORD wNotification,
  4806. IN WORD wId,
  4807. IN HWND hwndCtrl )
  4808. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  4809. // is the notification code of the command. 'wId' is the control/menu
  4810. // identifier of the command. 'HwndCtrl' is the control window handle of
  4811. // the command.
  4812. //
  4813. // Returns true if processed message, false otherwise.
  4814. //
  4815. {
  4816. DWORD dwErr = NO_ERROR;
  4817. TRACE3( "DpCommand(n=%d,i=%d,c=$%x)",
  4818. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  4819. TRACE2("DpCommand:pInfo address (0x%x), Dialog Handle (0x%x)",
  4820. pInfo,
  4821. pInfo->hwndDlg);
  4822. TRACE2("DpCommand:Current proces:(0x%d), Current Thread:(0x%d)",
  4823. GetCurrentProcessId(),
  4824. GetCurrentThreadId());
  4825. switch (wId)
  4826. {
  4827. case IDCANCEL:
  4828. {
  4829. BOOL fCallbackActive = FALSE;
  4830. ShowWindow( pInfo->hwndDlg, SW_HIDE );
  4831. //For whistler bug 381337
  4832. //
  4833. if( !pInfo->fCancelPressed)
  4834. {
  4835. TRACE("DpCommand:Cancel pressed");
  4836. pInfo->fCancelPressed = TRUE;
  4837. }
  4838. if (pInfo->hrasconn)
  4839. {
  4840. ASSERT( g_pRasHangUp );
  4841. TRACE( "RasHangUp" );
  4842. dwErr = g_pRasHangUp( pInfo->hrasconn );
  4843. TRACE1( "RasHangUp=%d", dwErr );
  4844. }
  4845. // for XPSP2 511810, .Net 668164
  4846. fCallbackActive = GetCallbackActive(pInfo);
  4847. if ( TRUE == fCallbackActive )
  4848. {
  4849. TRACE1( "DpCommand stall, current thread's fCallbacksActive n=%d", fCallbackActive );
  4850. SetTerminateFlag(pInfo);
  4851. PostMessage( pInfo->hwndDlg, WM_COMMAND,
  4852. MAKEWPARAM(wId, wNotification),
  4853. (LPARAM) hwndCtrl );
  4854. //For whistler bug 378086 gangz
  4855. //to sleep a bit to give the rasdial machine a break to call our callback
  4856. //function DpRasDialFunc2()
  4857. //
  4858. Sleep(10);
  4859. return TRUE;
  4860. }
  4861. EndDialog( pInfo->hwndDlg, FALSE );
  4862. //Reset the pInfo->fTerminateAsap flag
  4863. // for XPSP2 511810, .Net 668164
  4864. ResetTerminateFlag(pInfo);
  4865. return TRUE;
  4866. }
  4867. }
  4868. return FALSE;
  4869. }
  4870. VOID
  4871. DpConnectDevice(
  4872. IN DPINFO* pInfo,
  4873. IN DPSTATE* pState )
  4874. // RASCS_ConnectDevice state handling. 'PInfo' is the dialog context.
  4875. // 'PState' is the subentry state.
  4876. //
  4877. {
  4878. DWORD dwErr;
  4879. RASCONNSTATUS rcs;
  4880. DWORD cb;
  4881. HRASCONN hrasconn;
  4882. TCHAR* pszPhoneNumber;
  4883. TRACE( "DpConnectDevice" );
  4884. // Get fully translated phone number, if any.
  4885. //
  4886. ZeroMemory( &rcs, sizeof(rcs) );
  4887. rcs.dwSize = sizeof(rcs);
  4888. ASSERT( g_pRasGetConnectStatus );
  4889. TRACE1( "RasGetConnectStatus($%08x)", pState->hrasconnLink );
  4890. dwErr = g_pRasGetConnectStatus( pState->hrasconnLink, &rcs );
  4891. TRACE1( "RasGetConnectStatus=%d", dwErr );
  4892. TRACEW1( " dt=%s", rcs.szDeviceType );
  4893. TRACEW1( " dn=%s", rcs.szDeviceName );
  4894. TRACEW1( " pn=%s", rcs.szPhoneNumber );
  4895. if (dwErr != 0)
  4896. {
  4897. pState->pbdt = PBDT_None;
  4898. }
  4899. pState->pbdt = PbdevicetypeFromPszType( rcs.szDeviceType );
  4900. pszPhoneNumber = rcs.szPhoneNumber;
  4901. switch (pState->pbdt)
  4902. {
  4903. case PBDT_Modem:
  4904. {
  4905. Free0( pState->pszStatusArg );
  4906. pState->pszStatusArg = StrDup( pszPhoneNumber );
  4907. if (pInfo->pArgs->pUser->fOperatorDial
  4908. && AllLinksAreModems( pInfo->pArgs->pEntry ))
  4909. {
  4910. pState->sidState = SID_S_ConnectModemOperator;
  4911. }
  4912. else if (pInfo->pArgs->pEntry->fPreviewPhoneNumber)
  4913. {
  4914. pState->sidState = SID_S_ConnectNumber;
  4915. }
  4916. else
  4917. {
  4918. pState->sidState = SID_S_ConnectModemNoNum;
  4919. }
  4920. break;
  4921. }
  4922. case PBDT_Pad:
  4923. {
  4924. Free0( pState->pszStatusArg );
  4925. pState->pszStatusArg = StrDup( rcs.szDeviceName );
  4926. pState->sidState = SID_S_ConnectPad;
  4927. if (pState->dwError == ERROR_X25_DIAGNOSTIC)
  4928. {
  4929. TCHAR* psz;
  4930. // Get the X.25 diagnostic string for display in the
  4931. // custom "diagnostics" error message format.
  4932. //
  4933. Free0( pState->pszFormatArg );
  4934. pState->pszFormatArg =
  4935. GetRasX25Diagnostic( pState->hrasconnLink );
  4936. }
  4937. break;
  4938. }
  4939. case PBDT_Switch:
  4940. {
  4941. Free0( pState->pszStatusArg );
  4942. pState->pszStatusArg = StrDup( rcs.szDeviceName );
  4943. pState->sidState =
  4944. (pState->fNotPreSwitch)
  4945. ? SID_S_ConnectPostSwitch
  4946. : SID_S_ConnectPreSwitch;
  4947. break;
  4948. }
  4949. case PBDT_Null:
  4950. {
  4951. pState->sidState = SID_S_ConnectNull;
  4952. break;
  4953. }
  4954. case PBDT_Parallel:
  4955. {
  4956. pState->sidState = SID_S_ConnectParallel;
  4957. break;
  4958. }
  4959. case PBDT_Irda:
  4960. {
  4961. pState->sidState = SID_S_ConnectIrda;
  4962. break;
  4963. }
  4964. case PBDT_Isdn:
  4965. {
  4966. Free0( pState->pszStatusArg );
  4967. pState->pszStatusArg = StrDup( pszPhoneNumber );
  4968. pState->sidState = SID_S_ConnectNumber;
  4969. break;
  4970. }
  4971. case PBDT_Vpn:
  4972. {
  4973. Free0( pState->pszStatusArg );
  4974. pState->pszStatusArg = StrDup( pszPhoneNumber );
  4975. pState->sidState = SID_S_ConnectVpn;
  4976. break;
  4977. }
  4978. default:
  4979. {
  4980. Free0( pState->pszStatusArg );
  4981. if (pszPhoneNumber[ 0 ] != TEXT('\0'))
  4982. {
  4983. pState->pszStatusArg = StrDup( pszPhoneNumber );
  4984. pState->sidState = SID_S_ConnectNumber;
  4985. }
  4986. else
  4987. {
  4988. pState->pszStatusArg = StrDup( rcs.szDeviceName );
  4989. pState->sidState = SID_S_ConnectDevice;
  4990. }
  4991. break;
  4992. }
  4993. }
  4994. }
  4995. VOID
  4996. DpDeviceConnected(
  4997. IN DPINFO* pInfo,
  4998. IN DPSTATE* pState )
  4999. // RASCS_DeviceConnected state handling. 'PInfo' is the dialog context.
  5000. // 'PState' is the subentry state.
  5001. //
  5002. // Returns 0 if successful, or an error code.
  5003. //
  5004. {
  5005. TRACE( "DpDeviceConnected" );
  5006. switch (pState->pbdt)
  5007. {
  5008. case PBDT_Modem:
  5009. {
  5010. pState->sidState = SID_S_ModemConnected;
  5011. pState->fNotPreSwitch = TRUE;
  5012. break;
  5013. }
  5014. case PBDT_Pad:
  5015. {
  5016. pState->sidState = SID_S_PadConnected;
  5017. pState->fNotPreSwitch = TRUE;
  5018. break;
  5019. }
  5020. case PBDT_Switch:
  5021. {
  5022. pState->sidState =
  5023. (pState->fNotPreSwitch)
  5024. ? SID_S_PostSwitchConnected
  5025. : SID_S_PreSwitchConnected;
  5026. pState->fNotPreSwitch = TRUE;
  5027. break;
  5028. }
  5029. case PBDT_Null:
  5030. {
  5031. pState->sidState = SID_S_NullConnected;
  5032. pState->fNotPreSwitch = TRUE;
  5033. break;
  5034. }
  5035. case PBDT_Parallel:
  5036. {
  5037. pState->sidState = SID_S_ParallelConnected;
  5038. pState->fNotPreSwitch = TRUE;
  5039. break;
  5040. }
  5041. case PBDT_Irda:
  5042. {
  5043. pState->sidState = SID_S_IrdaConnected;
  5044. pState->fNotPreSwitch = TRUE;
  5045. break;
  5046. }
  5047. default:
  5048. {
  5049. pState->sidState = SID_S_DeviceConnected;
  5050. break;
  5051. }
  5052. }
  5053. }
  5054. VOID
  5055. DpDial(
  5056. IN DPINFO* pInfo,
  5057. IN BOOL fPauseRestart )
  5058. // Dial with the parameters in the 'pInfo' dialog context block.
  5059. // 'FPausedRestart' indicates the dial is restarting from a paused state
  5060. // and dial states should not be reset.
  5061. //
  5062. {
  5063. DWORD dwErr;
  5064. TRACE1( "DpDial,fPauseRestart=%d", fPauseRestart );
  5065. if (!fPauseRestart)
  5066. {
  5067. DpInitStates( pInfo );
  5068. //comment for bug 277365, 291613 gangz
  5069. //Set the fCallbacksActive to be TRUE
  5070. //
  5071. TRACE("DpDial:Init global actives");
  5072. // XPSP2 511810, .Net 668164
  5073. SetCallbackActive(pInfo);
  5074. IncGlobalCallbackActive();
  5075. }
  5076. else
  5077. {
  5078. TRACE("DpDial:WONT Init global actives for pausedRestart");
  5079. }
  5080. // Whistler bug 254385 encode password when not being used
  5081. // Assumed password was encoded previously
  5082. //
  5083. DecodePassword( pInfo->pArgs->rdp.szPassword );
  5084. TRACE1( "RasDial(h=$%08x)", pInfo->hrasconn );
  5085. ASSERT( g_pRasDial );
  5086. dwErr = g_pRasDial( &pInfo->pArgs->rde, pInfo->pArgs->pFile->pszPath,
  5087. &pInfo->pArgs->rdp, 2, (LPVOID )DpRasDialFunc2, &pInfo->hrasconn );
  5088. TRACE2( "RasDial=%d,h=$%08x", dwErr, pInfo->hrasconn );
  5089. EncodePassword( pInfo->pArgs->rdp.szPassword );
  5090. if (dwErr != 0)
  5091. {
  5092. // This same error will show up via the callback route on restarts
  5093. // from PAUSEd states so avoid double popups in that case. See bug
  5094. // 367482.
  5095. //
  5096. if (!fPauseRestart)
  5097. {
  5098. // ErrorDlg( pInfo->hwndDlg, SID_OP_RasDial, dwErr, NULL );
  5099. // For whistler 460931
  5100. //
  5101. DialErrorDlg(
  5102. pInfo->hwndDlg,
  5103. pInfo->pArgs, // For whistler 474514
  5104. pInfo->pArgs->pszPhonebook,
  5105. pInfo->pArgs->pszEntry,
  5106. dwErr,
  5107. SID_OP_RasDial,
  5108. NULL,
  5109. SID_FMT_ErrorMsg,
  5110. NULL,
  5111. -2,
  5112. TRUE);
  5113. //for XPSP2 511810, .Net 668164
  5114. ResetCallbackActive(pInfo);
  5115. DecGlobalCallbackActive();
  5116. }
  5117. // If we receive error 668 here, it means that a rasevent is currently
  5118. // posted for state RASCS_Disconnected. We shouldn't cancel in this
  5119. // case since we Normal processing of RASCS_Disconnected will allow the
  5120. // user to redial. Also, calling DpCancel below will insert
  5121. // WM_DESTROY which will process before the popup that the rasevent
  5122. // produces can display. 367482
  5123. //
  5124. if (dwErr != ERROR_NO_CONNECTION)
  5125. {
  5126. DpCancel( pInfo );
  5127. }
  5128. }
  5129. }
  5130. VOID
  5131. DpError(
  5132. IN DPINFO* pInfo,
  5133. IN DPSTATE* pState )
  5134. // Popup error dialog for error identified by 'pState' and cancel or
  5135. // redial as indicated by user. 'PInfo' is the dialog context.
  5136. //
  5137. {
  5138. DWORD dwErr;
  5139. DWORD dwRedialAttemptsLeft;
  5140. DWORD sidState;
  5141. TRACE( "DpError" );
  5142. // Retrieve additional text from RASMXS on those special errors where the
  5143. // device returned something useful to display.
  5144. //
  5145. if (pState->dwError == ERROR_FROM_DEVICE
  5146. || pState->dwError == ERROR_UNRECOGNIZED_RESPONSE)
  5147. {
  5148. TCHAR* pszMessage;
  5149. dwErr = GetRasMessage( pInfo->hrasconn, &pszMessage );
  5150. if (dwErr == 0)
  5151. {
  5152. pState->sidFormatMsg = SID_FMT_ErrorMsgResp;
  5153. Free0( pState->pszFormatArg );
  5154. pState->pszFormatArg = pszMessage;
  5155. }
  5156. }
  5157. if (pState->sidFormatMsg == 0)
  5158. {
  5159. if (pState->dwExtendedError != 0)
  5160. {
  5161. // Translate extended error code into arguments.
  5162. //
  5163. TCHAR szNum[ 2 + MAXLTOTLEN + 1 ];
  5164. pState->sidFormatMsg = SID_FMT_ErrorMsgExt;
  5165. szNum[ 0 ] = TEXT('0');
  5166. szNum[ 1 ] = TEXT('x');
  5167. LToT( pState->dwExtendedError, szNum + 2, 16 );
  5168. Free0( pState->pszFormatArg );
  5169. pState->pszFormatArg = StrDup( szNum );
  5170. }
  5171. else if (pState->szExtendedError[ 0 ] != TEXT('\0'))
  5172. {
  5173. // Translate extended error string to argument. Currently, the
  5174. // string is always a NetBIOS name.
  5175. //
  5176. pState->sidFormatMsg = SID_FMT_ErrorMsgName;
  5177. Free0( pState->pszFormatArg );
  5178. pState->pszFormatArg = StrDup( pState->szExtendedError );
  5179. }
  5180. }
  5181. if (pInfo->hrasconn)
  5182. {
  5183. // Hang up before displaying error popup so server side resources are
  5184. // not tied up waiting for client to acknowledge error.
  5185. //
  5186. ASSERT( g_pRasHangUp );
  5187. TRACE( "RasHangUp" );
  5188. dwErr = g_pRasHangUp( pInfo->hrasconn );
  5189. TRACE1( "RasHangUp=%d", dwErr );
  5190. pInfo->hrasconn = NULL;
  5191. }
  5192. if (pInfo->pArgs->pEntry->pszPrerequisiteEntry
  5193. && *pInfo->pArgs->pEntry->pszPrerequisiteEntry)
  5194. {
  5195. // Select "no Redial button" mode for entries that have prerequisite
  5196. // entries. This is because RASMAN drops the prerequisite entry as
  5197. // soon as the dependent entry fails, thus dooming to defeat a redial
  5198. // of only the dependent entry. Yes, it should really redial both
  5199. // entries here, but that is not really feasible with the current
  5200. // non-integrated serial implementation of prerequisite entries. This
  5201. // at least improves the poor behavior cited in bug 230594.
  5202. //
  5203. dwRedialAttemptsLeft = -2;
  5204. }
  5205. else if (pInfo->dwRedialAttemptsLeft <= 0)
  5206. {
  5207. // No auto-redial countdown, but "Redial" button does appear in place
  5208. // of the default "OK".
  5209. //
  5210. dwRedialAttemptsLeft = -1;
  5211. }
  5212. else
  5213. {
  5214. // Auto-redial countdown based on the entries configuration.
  5215. //
  5216. dwRedialAttemptsLeft =
  5217. GetOverridableParam(
  5218. pInfo->pArgs->pUser,
  5219. pInfo->pArgs->pEntry,
  5220. RASOR_RedialSeconds );
  5221. }
  5222. // This hack works around a bug in RasDial API. See bug 313102.
  5223. //
  5224. sidState = pState ->sidState;
  5225. if (!sidState)
  5226. {
  5227. sidState = SID_S_AuthNotify;
  5228. }
  5229. if (DialErrorDlg(
  5230. pInfo->hwndDlg,
  5231. pInfo->pArgs, // For whistler 474514
  5232. pInfo->pArgs->pszPhonebook, // For whislter 460931
  5233. pInfo->pArgs->pEntry->pszEntryName,
  5234. pState->dwError,
  5235. sidState,
  5236. pState->pszStatusArg,
  5237. pState->sidFormatMsg,
  5238. pState->pszFormatArg,
  5239. dwRedialAttemptsLeft,
  5240. GetOverridableParam(
  5241. pInfo->pArgs->pUser, pInfo->pArgs->pEntry,
  5242. RASOR_PopupOnTopWhenRedialing ) ))
  5243. {
  5244. TRACE( "User redials" );
  5245. if (pInfo->dwRedialAttemptsLeft > 0)
  5246. {
  5247. --pInfo->dwRedialAttemptsLeft;
  5248. }
  5249. TRACE(" Post(DIAL)" );
  5250. PostMessage( pInfo->hwndDlg, WM_RASDIAL, FALSE, 0 );
  5251. }
  5252. else
  5253. {
  5254. TRACE( "User cancels" );
  5255. DpCancel( pInfo );
  5256. }
  5257. //
  5258. // Set the error so that the error is propagated back
  5259. // to the caller of the RasDialDlg api.
  5260. //
  5261. TRACE2("DpError settings error (0x%x) to %d",
  5262. &pInfo->pArgs->pArgs->dwError,
  5263. pState->dwError);
  5264. pInfo->pArgs->pArgs->dwError = pState->dwError;
  5265. }
  5266. // For whistler 435725
  5267. //
  5268. void
  5269. DpEndDialog(
  5270. IN DPINFO * pInfo,
  5271. IN BOOL fFlag)
  5272. {
  5273. PostMessage( pInfo->hwndDlg, WM_DPENDDIALOG, 0, (WPARAM)fFlag );
  5274. }
  5275. DWORD
  5276. DpEvent(
  5277. IN DPINFO* pInfo,
  5278. IN DWORD dwSubEntry )
  5279. // Handle a RasDial callback event on subentry 'dwSubEntry'. 'PInfo' is
  5280. // the dialog context.
  5281. //
  5282. // Return 0 to stop callbacks from RasDial, or 1 to continue callbacks
  5283. // (normal), or 2 to indicate that the phonebook entry has changed and
  5284. // should be re-read by RasDial.
  5285. //
  5286. {
  5287. DWORD dwErr;
  5288. DWORD dwCode;
  5289. BOOL fLeader;
  5290. DWORD dwcSuccessLinks, dwcFailedLinks, i;
  5291. DPSTATE* pState;
  5292. BOOL fPartialMultilink;
  5293. BOOL fIsLaterState;
  5294. TRACE( "DpEvent" );
  5295. // Default to "normal" return.
  5296. //
  5297. dwCode = 1;
  5298. fPartialMultilink = FALSE;
  5299. TRACE2("Current proces:(0x%d), Current Thread:(0x%d)",
  5300. GetCurrentProcessId(),
  5301. GetCurrentThreadId());
  5302. // Find the associated state information and figure out if this is the
  5303. // most advanced sub-entry.
  5304. //
  5305. pState = &pInfo->pStates[ dwSubEntry - 1 ];
  5306. fIsLaterState = DpIsLaterState( pState->state, pInfo->state );
  5307. if (dwSubEntry == pInfo->dwSubEntry || fIsLaterState)
  5308. {
  5309. fLeader = TRUE;
  5310. if (fIsLaterState)
  5311. {
  5312. pInfo->dwSubEntry = dwSubEntry;
  5313. pInfo->state = pState->state;
  5314. }
  5315. }
  5316. else
  5317. {
  5318. fLeader = FALSE;
  5319. TRACE( "Trailing" );
  5320. }
  5321. // Execute the state.
  5322. //
  5323. TRACE1("State is:(%d)", pState->state);
  5324. switch (pState->state)
  5325. {
  5326. case RASCS_OpenPort:
  5327. {
  5328. pState->pbdt = PBDT_None;
  5329. pState->sidState = SID_S_OpenPort;
  5330. break;
  5331. }
  5332. case RASCS_PortOpened:
  5333. {
  5334. // Should have an hrasconnLink for this subentry now. Look it up
  5335. // and stash it in our context.
  5336. //
  5337. ASSERT( g_pRasGetSubEntryHandle );
  5338. TRACE1( "RasGetSubEntryHandle(se=%d)", dwSubEntry );
  5339. dwErr = g_pRasGetSubEntryHandle(
  5340. pInfo->hrasconn, dwSubEntry, &pState->hrasconnLink );
  5341. TRACE2( "RasGetSubEntryHandle=%d,hL=$%08x",
  5342. dwErr, pState->hrasconnLink );
  5343. if (dwErr != 0)
  5344. {
  5345. pState->dwError = dwErr;
  5346. }
  5347. pState->sidState = SID_S_PortOpened;
  5348. break;
  5349. }
  5350. case RASCS_ConnectDevice:
  5351. {
  5352. DTLNODE* pNode;
  5353. PBLINK* pLink;
  5354. pNode = DtlNodeFromIndex(
  5355. pInfo->pArgs->pEntry->pdtllistLinks, dwSubEntry - 1 );
  5356. ASSERT( pNode );
  5357. if(NULL == pNode)
  5358. {
  5359. pState->dwError = ERROR_NOT_ENOUGH_MEMORY;
  5360. }
  5361. else
  5362. {
  5363. pLink = (PBLINK* )DtlGetData( pNode );
  5364. }
  5365. if ((pState->dwError == ERROR_PORT_OR_DEVICE
  5366. && (pLink->pbport.fScriptBeforeTerminal
  5367. || pLink->pbport.fScriptBefore))
  5368. || (pState->dwError == ERROR_USER_DISCONNECTION
  5369. && (pInfo->pArgs->pUser->fOperatorDial
  5370. && AllLinksAreModems( pInfo->pArgs->pEntry ))))
  5371. {
  5372. // This happens when user presses Cancel on the Unimodem
  5373. // "Pre-Dial Terminal Screen" or "Operator Assisted or Manual
  5374. // Dial" dialog.
  5375. //
  5376. TRACE("DpEvent:Call DpCancel() in connectDevice, but still return 1\n");
  5377. DpCancel( pInfo );
  5378. return dwCode;
  5379. }
  5380. DpConnectDevice( pInfo, pState );
  5381. break;
  5382. }
  5383. case RASCS_DeviceConnected:
  5384. {
  5385. DpDeviceConnected( pInfo, pState );
  5386. break;
  5387. }
  5388. case RASCS_AllDevicesConnected:
  5389. {
  5390. pState->sidState = SID_S_AllDevicesConnected;
  5391. break;
  5392. }
  5393. case RASCS_Authenticate:
  5394. {
  5395. pState->sidState = SID_S_Authenticate;
  5396. break;
  5397. }
  5398. case RASCS_AuthNotify:
  5399. {
  5400. DpAuthNotify( pInfo, pState );
  5401. break;
  5402. }
  5403. case RASCS_AuthRetry:
  5404. {
  5405. pState->sidState = SID_S_AuthRetry;
  5406. break;
  5407. }
  5408. case RASCS_AuthCallback:
  5409. {
  5410. pState->sidState = SID_S_AuthCallback;
  5411. break;
  5412. }
  5413. case RASCS_AuthChangePassword:
  5414. {
  5415. pState->sidState = SID_S_AuthChangePassword;
  5416. break;
  5417. }
  5418. case RASCS_AuthProject:
  5419. {
  5420. pState->sidState = SID_S_AuthProject;
  5421. break;
  5422. }
  5423. case RASCS_AuthLinkSpeed:
  5424. {
  5425. pState->sidState = SID_S_AuthLinkSpeed;
  5426. break;
  5427. }
  5428. case RASCS_AuthAck:
  5429. {
  5430. pState->sidState = SID_S_AuthAck;
  5431. break;
  5432. }
  5433. case RASCS_ReAuthenticate:
  5434. {
  5435. pState->sidState = SID_S_ReAuthenticate;
  5436. break;
  5437. }
  5438. case RASCS_Authenticated:
  5439. {
  5440. pState->sidState = SID_S_Authenticated;
  5441. break;
  5442. }
  5443. case RASCS_PrepareForCallback:
  5444. {
  5445. pState->sidState = SID_S_PrepareForCallback;
  5446. break;
  5447. }
  5448. case RASCS_WaitForModemReset:
  5449. {
  5450. pState->sidState = SID_S_WaitForModemReset;
  5451. break;
  5452. }
  5453. case RASCS_WaitForCallback:
  5454. {
  5455. pState->sidState = SID_S_WaitForCallback;
  5456. break;
  5457. }
  5458. case RASCS_Projected:
  5459. {
  5460. if (fLeader)
  5461. {
  5462. // If DpProjected returns FALSE, it detected a fatal error,
  5463. // and the dialing process will stop. If DpProjected returns
  5464. // with pState->dwError non-zero, we display the error in a
  5465. // redial dialog, if redial is configured.
  5466. //
  5467. if (!DpProjected( pInfo, pState ))
  5468. {
  5469. TRACE("DpEvent:Call DpCancel() in RASCS_Projected, but still return 1 to DpRasDialFunc2()\n");
  5470. DpCancel( pInfo );
  5471. return dwCode;
  5472. }
  5473. else if (pState->dwError)
  5474. {
  5475. TRACE("DpCancel() in RASCS_Projected,return 0 to DpRasDialFunc2()");
  5476. TRACE( "DpEvent:Post(ERROR), return 0 to DpRasDialFunc2()" );
  5477. PostMessage( pInfo->hwndDlg,
  5478. WM_RASERROR, 0, (LPARAM )pState );
  5479. return 0;
  5480. }
  5481. }
  5482. break;
  5483. }
  5484. case RASCS_Interactive:
  5485. {
  5486. BOOL fChange = FALSE;
  5487. if (!DpInteractive( pInfo, pState, &fChange ))
  5488. {
  5489. DpCancel( pInfo );
  5490. return dwCode;
  5491. }
  5492. if (fChange)
  5493. {
  5494. dwCode = 2;
  5495. }
  5496. break;
  5497. }
  5498. case RASCS_RetryAuthentication:
  5499. {
  5500. if (!RetryAuthenticationDlg(
  5501. pInfo->hwndDlg, pInfo->pArgs ))
  5502. {
  5503. DpCancel( pInfo );
  5504. return dwCode;
  5505. }
  5506. pState->sidState = 0;
  5507. break;
  5508. }
  5509. case RASCS_InvokeEapUI:
  5510. {
  5511. if (g_pRasInvokeEapUI(
  5512. pInfo->hrasconn, dwSubEntry,
  5513. &pInfo->pArgs->rde, pInfo->hwndDlg ))
  5514. {
  5515. DpCancel( pInfo );
  5516. return dwCode;
  5517. }
  5518. pState->sidState = 0;
  5519. break;
  5520. }
  5521. case RASCS_CallbackSetByCaller:
  5522. {
  5523. DpCallbackSetByCaller( pInfo, pState );
  5524. break;
  5525. }
  5526. case RASCS_PasswordExpired:
  5527. {
  5528. if (!DpPasswordExpired( pInfo, pState ))
  5529. {
  5530. DpCancel( pInfo );
  5531. return dwCode;
  5532. }
  5533. break;
  5534. }
  5535. case RASCS_SubEntryConnected:
  5536. {
  5537. if (pInfo->cStates > 1)
  5538. {
  5539. pState->sidState = SID_S_SubConnected;
  5540. }
  5541. break;
  5542. }
  5543. case RASCS_SubEntryDisconnected:
  5544. {
  5545. break;
  5546. }
  5547. case RASCS_Connected:
  5548. {
  5549. pState->sidState = SID_S_Connected;
  5550. break;
  5551. }
  5552. case RASCS_Disconnected:
  5553. {
  5554. pState->sidState = SID_S_Disconnected;
  5555. break;
  5556. }
  5557. default:
  5558. {
  5559. pState->sidState = SID_S_Unknown;
  5560. break;
  5561. }
  5562. }
  5563. // Count the successful and failed links.
  5564. //
  5565. {
  5566. DPSTATE* p;
  5567. dwcSuccessLinks = dwcFailedLinks = 0;
  5568. for (i = 0, p = pInfo->pStates; i < pInfo->cStates; ++i, ++p)
  5569. {
  5570. if (p->state == RASCS_SubEntryConnected)
  5571. {
  5572. ++dwcSuccessLinks;
  5573. }
  5574. if (p->dwError)
  5575. {
  5576. ++dwcFailedLinks;
  5577. }
  5578. }
  5579. }
  5580. TRACE3( "s=%d,f=%d,t=%d", dwcSuccessLinks, dwcFailedLinks, pInfo->cStates );
  5581. if (pState->dwError)
  5582. {
  5583. DTLNODE *pdtlnode = NULL;
  5584. DWORD dwIndex = pInfo->pArgs->rdp.dwSubEntry;
  5585. if(0 != dwIndex)
  5586. {
  5587. pdtlnode = DtlNodeFromIndex(
  5588. pInfo->pArgs->pEntry->pdtllistLinks,
  5589. dwIndex - 1);
  5590. }
  5591. if ( (dwcFailedLinks == pInfo->cStates)
  5592. || ( (RASEDM_DialAll != pInfo->pArgs->pEntry->dwDialMode)
  5593. && (dwcSuccessLinks == 0))
  5594. || (NULL != pdtlnode))
  5595. {
  5596. // A terminal error state has occurred on all links. Post a
  5597. // message telling ourselves to popup an error, then release the
  5598. // callback so it doesn't hold the port open while the error popup
  5599. // is up,
  5600. //
  5601. TRACE( "Post(ERROR)" );
  5602. PostMessage( pInfo->hwndDlg, WM_RASERROR, 0, (LPARAM )pState );
  5603. return 0;
  5604. }
  5605. else if (dwcSuccessLinks + dwcFailedLinks == pInfo->cStates)
  5606. {
  5607. // An error occurred on the final link, but some link connected.
  5608. // It would be nice if RasDial would followup with a
  5609. // RASCS_Connected in that case, but it doesn't, so we duplicate
  5610. // the RASCS_Connected-style exit here.
  5611. //
  5612. TRACE( "Post(BUNDLEERROR)" );
  5613. PostMessage( pInfo->hwndDlg,
  5614. WM_RASBUNDLEERROR, 0, (LPARAM )pState );
  5615. return 0;
  5616. }
  5617. // A fatal error has occurred on a link, but there are other links
  5618. // still trying, so let it die quietly.
  5619. //
  5620. TRACE2( "Link %d fails, e=%d", dwSubEntry + 1, pState->dwError );
  5621. return dwCode;
  5622. }
  5623. // Display the status string for this state.
  5624. //
  5625. if (pState->sidState)
  5626. {
  5627. if (pState->sidState != pState->sidPrevState)
  5628. {
  5629. pState->sidPrevState = pState->sidState;
  5630. }
  5631. if (fLeader)
  5632. {
  5633. TCHAR* pszState = PszFromId( g_hinstDll, pState->sidState );
  5634. if ( (NULL != pszState)
  5635. && pState->pszStatusArg)
  5636. {
  5637. TCHAR* pszFormattedState;
  5638. TCHAR* pszArg;
  5639. TCHAR* apszArgs[ 1 ];
  5640. DWORD cch;
  5641. pszArg = (pState->pszStatusArg)
  5642. ? pState->pszStatusArg : TEXT("");
  5643. // Find length of formatted string with text argument (if any)
  5644. // inserted and any progress dots appended.
  5645. //
  5646. cch = lstrlen( pszState ) + lstrlen( pszArg ) + 1;
  5647. pszFormattedState = Malloc( cch * sizeof(TCHAR) );
  5648. if (pszFormattedState)
  5649. {
  5650. apszArgs[ 0 ] = pszArg;
  5651. *pszFormattedState = TEXT('\0');
  5652. FormatMessage(
  5653. FORMAT_MESSAGE_FROM_STRING
  5654. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  5655. pszState, 0, 0, pszFormattedState, cch,
  5656. (va_list* )apszArgs );
  5657. Free( pszState );
  5658. pszState = pszFormattedState;
  5659. }
  5660. }
  5661. TRACE1("DpEvent:State:'%s'",pszState);
  5662. if (pszState)
  5663. {
  5664. SetWindowText( pInfo->hwndStState, pszState );
  5665. InvalidateRect( pInfo->hwndStState, NULL, TRUE );
  5666. UpdateWindow( pInfo->hwndStState );
  5667. LocalFree( pszState );
  5668. }
  5669. }
  5670. }
  5671. if (pState->state & RASCS_PAUSED)
  5672. {
  5673. // Paused state just processed. Release the callback, and dial again
  5674. // to resume.
  5675. //
  5676. TRACE("DpEvent:Paused, will dial again\nthe global callbacks wont init again");
  5677. TRACE( "Post(DIAL)" );
  5678. PostMessage( pInfo->hwndDlg, WM_RASDIAL, TRUE, 0 );
  5679. return dwCode;
  5680. }
  5681. if (pState->state & RASCS_DONE)
  5682. {
  5683. // Terminal state just processed.
  5684. //
  5685. if (pState->state == RASCS_Connected)
  5686. {
  5687. // For multi-link entries, if there is at least one successful
  5688. // line and at least one failed line, popup the bundling error
  5689. // dialog.
  5690. //
  5691. if (pInfo->cStates > 1)
  5692. {
  5693. DPSTATE* p;
  5694. dwcSuccessLinks = dwcFailedLinks = 0;
  5695. for (i = 0, p = pInfo->pStates; i < pInfo->cStates; ++i, ++p)
  5696. {
  5697. if (p->dwError == 0)
  5698. {
  5699. ++dwcSuccessLinks;
  5700. }
  5701. else
  5702. {
  5703. ++dwcFailedLinks;
  5704. }
  5705. }
  5706. if (dwcSuccessLinks > 0 && dwcFailedLinks > 0)
  5707. {
  5708. TRACE( "Post(BUNDLEERROR)" );
  5709. PostMessage( pInfo->hwndDlg,
  5710. WM_RASBUNDLEERROR, 0, (LPARAM )pState );
  5711. return 0;
  5712. }
  5713. }
  5714. //For whistler 435725
  5715. //
  5716. DpEndDialog( pInfo, TRUE );
  5717. }
  5718. else
  5719. {
  5720. DpCancel( pInfo );
  5721. }
  5722. return 0;
  5723. }
  5724. TRACE1("DpEvent:returned dwCode:(%d)", dwCode);
  5725. TRACE("End of DpEvent");
  5726. return dwCode;
  5727. }
  5728. BOOL
  5729. DpInit(
  5730. IN HWND hwndDlg,
  5731. IN DINFO* pArgs )
  5732. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
  5733. // 'PArgs' is caller's arguments as passed to the stub API.
  5734. //
  5735. // Return false if focus was set, true otherwise, i.e. as defined for
  5736. // WM_INITDIALOG.
  5737. //
  5738. {
  5739. DWORD dwErr;
  5740. DPINFO* pInfo;
  5741. PBENTRY* pEntry;
  5742. TRACE( "DpInit" );
  5743. // Allocate the dialog context block. Initialize minimally for proper
  5744. // cleanup, then attach to the dialog window.
  5745. //
  5746. {
  5747. pInfo = Malloc( sizeof(*pInfo) );
  5748. if (!pInfo)
  5749. {
  5750. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  5751. EndDialog( hwndDlg, FALSE );
  5752. return TRUE;
  5753. }
  5754. ZeroMemory( pInfo, sizeof(*pInfo) );
  5755. pInfo->dwValid = 0xC0BBC0DE;
  5756. pInfo->pArgs = pArgs;
  5757. pInfo->hwndDlg = hwndDlg;
  5758. //Add a per-thread Terminate flag for whistler bug 291613 gangz
  5759. //
  5760. pInfo->fTerminateAsap = FALSE;
  5761. // for XPSP2 511810, .Net 668164, 668164
  5762. pInfo->pcsActiveLock =
  5763. (CRITICAL_SECTION*)Malloc(sizeof(CRITICAL_SECTION));
  5764. if(NULL == pInfo->pcsActiveLock )
  5765. {
  5766. TRACE("No memory for critical section");
  5767. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  5768. EndDialog( hwndDlg, FALSE );
  5769. return TRUE;
  5770. }
  5771. __try
  5772. {
  5773. InitializeCriticalSection( pInfo->pcsActiveLock );
  5774. }
  5775. __except(EXCEPTION_EXECUTE_HANDLER)
  5776. {
  5777. DWORD dwExceptionCode = GetExceptionCode();
  5778. TRACE1("InitializeCriticalSection() raise:0x%x",dwExceptionCode);
  5779. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  5780. EndDialog( hwndDlg, FALSE );
  5781. return TRUE;
  5782. }
  5783. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  5784. TRACE( "Context set" );
  5785. }
  5786. pInfo->hwndStState = GetDlgItem( hwndDlg, CID_DP_ST_State );
  5787. ASSERT( pInfo->hwndStState );
  5788. pEntry = pArgs->pEntry;
  5789. // Set up our context to be returned by the RasDialFunc2 callback.
  5790. //
  5791. pInfo->pArgs->rdp.dwCallbackId = (ULONG_PTR )pInfo;
  5792. // Subclass the dialog so we can get the result from
  5793. // SendMessage(WM_RASDIALEVENT) in RasDlgFunc2.
  5794. //
  5795. pInfo->pOldWndProc =
  5796. (WNDPROC )SetWindowLongPtr(
  5797. pInfo->hwndDlg, GWLP_WNDPROC, (ULONG_PTR )DpWndProc );
  5798. // Set the title.
  5799. //
  5800. {
  5801. TCHAR* pszTitleFormat;
  5802. TCHAR* pszTitle;
  5803. TCHAR* apszArgs[ 1 ];
  5804. pszTitleFormat = GetText( hwndDlg );
  5805. if (pszTitleFormat)
  5806. {
  5807. apszArgs[ 0 ] = pEntry->pszEntryName;
  5808. pszTitle = NULL;
  5809. FormatMessage(
  5810. FORMAT_MESSAGE_FROM_STRING
  5811. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  5812. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  5813. pszTitleFormat, 0, 0, (LPTSTR )&pszTitle, 1,
  5814. (va_list* )apszArgs );
  5815. Free( pszTitleFormat );
  5816. if (pszTitle)
  5817. {
  5818. SetWindowText( hwndDlg, pszTitle );
  5819. LocalFree( pszTitle );
  5820. }
  5821. }
  5822. }
  5823. // Set the correct icon. For whistler bug 372078 gangz
  5824. //
  5825. SetIconFromEntryType(
  5826. GetDlgItem( hwndDlg, CID_DP_Icon ),
  5827. pArgs->pEntry->dwType,
  5828. FALSE); //FALSE means large Icon
  5829. // Position the dialog per caller's instructions.
  5830. //
  5831. PositionDlg( hwndDlg,
  5832. pArgs->pArgs->dwFlags & RASDDFLAG_PositionDlg,
  5833. pArgs->pArgs->xDlg, pArgs->pArgs->yDlg );
  5834. // Hide the dialog if "no progress" user preference is set.
  5835. //
  5836. if (!pArgs->pEntry->fShowDialingProgress
  5837. || pArgs->fDialForReferenceOnly)
  5838. {
  5839. SetOffDesktop( hwndDlg, SOD_MoveOff, NULL );
  5840. }
  5841. SetForegroundWindow( hwndDlg );
  5842. // Allocate subentry status array. It's initialized by DpDial.
  5843. //
  5844. {
  5845. DWORD cb;
  5846. ASSERT( pEntry->pdtllistLinks );
  5847. pInfo->cStates = DtlGetNodes( pEntry->pdtllistLinks );
  5848. cb = sizeof(DPSTATE) * pInfo->cStates;
  5849. pInfo->pStates = Malloc( cb );
  5850. if (!pInfo->pStates)
  5851. {
  5852. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  5853. EndDialog( hwndDlg, FALSE );
  5854. return TRUE;
  5855. }
  5856. pInfo->dwRedialAttemptsLeft =
  5857. GetOverridableParam(
  5858. pInfo->pArgs->pUser, pInfo->pArgs->pEntry,
  5859. RASOR_RedialAttempts );
  5860. }
  5861. //for whistler bug 316622 gangz
  5862. //The dwSubEntry is not initialized
  5863. //
  5864. pInfo->pArgs->rdp.dwSubEntry = pInfo->pArgs->pArgs->dwSubEntry;
  5865. // Rock and roll.
  5866. //
  5867. DpDial( pInfo, FALSE );
  5868. return TRUE;
  5869. }
  5870. VOID
  5871. DpInitStates(
  5872. DPINFO* pInfo )
  5873. // Resets 'pInfo->pStates' to initial values. 'PInfo' is the dialog
  5874. // context.
  5875. //
  5876. {
  5877. DWORD i;
  5878. DPSTATE* pState;
  5879. for (i = 0, pState = pInfo->pStates; i < pInfo->cStates; ++i, ++pState)
  5880. {
  5881. ZeroMemory( pState, sizeof(*pState) );
  5882. pInfo->state = (RASCONNSTATE )-1;
  5883. pState->dwError = 0;
  5884. }
  5885. }
  5886. BOOL
  5887. DpInteractive(
  5888. IN DPINFO* pInfo,
  5889. IN DPSTATE* pState,
  5890. OUT BOOL* pfChange )
  5891. // RASCS_Interactive handling. 'PInfo' is the dialog context. 'PState'
  5892. // is the subentry state. '*pfChange' is set true if the entry (i.e. SLIP
  5893. // address) was changed or false otherwise.
  5894. //
  5895. // Returns true if successful, false if cancel.
  5896. //
  5897. {
  5898. DWORD dwErr = NO_ERROR;
  5899. DWORD sidTitle;
  5900. TCHAR szIpAddress[ TERM_IpAddress ];
  5901. TCHAR* pszIpAddress;
  5902. PBENTRY* pEntry;
  5903. TRACE( "DpInteractive" );
  5904. *pfChange = FALSE;
  5905. pEntry = pInfo->pArgs->pEntry;
  5906. if (pEntry->dwBaseProtocol == BP_Slip)
  5907. {
  5908. lstrcpyn(
  5909. szIpAddress,
  5910. (pEntry->pszIpAddress) ? pEntry->pszIpAddress : TEXT("0.0.0.0"),
  5911. sizeof(szIpAddress) / sizeof(TCHAR));
  5912. pszIpAddress = szIpAddress;
  5913. sidTitle = SID_T_SlipTerminal;
  5914. }
  5915. else
  5916. {
  5917. szIpAddress[0] = TEXT('\0');
  5918. pszIpAddress = szIpAddress;
  5919. sidTitle =
  5920. (pState->sidState == SID_S_ConnectPreSwitch)
  5921. ? SID_T_PreconnectTerminal
  5922. : (pState->sidState == SID_S_ConnectPostSwitch)
  5923. ? SID_T_PostconnectTerminal
  5924. : SID_T_ManualDialTerminal;
  5925. }
  5926. if(1 == pEntry->dwCustomScript)
  5927. {
  5928. dwErr = DwCustomTerminalDlg(
  5929. pInfo->pArgs->pFile->pszPath,
  5930. pInfo->hrasconn,
  5931. pEntry,
  5932. pInfo->hwndDlg,
  5933. &pInfo->pArgs->rdp,
  5934. NULL);
  5935. if(SUCCESS == dwErr)
  5936. {
  5937. #if 0
  5938. //
  5939. // Reread the phonebook file since the
  5940. // custom script could have written
  5941. // new information to the file.
  5942. //
  5943. ClosePhonebookFile(pInfo->pArgs->pFile);
  5944. dwErr = ReadPhonebookFile(
  5945. pInfo->pArgs->pszPhonebook,
  5946. &pInfo->pArgs->user,
  5947. NULL, 0, &pInfo->pArgs->file );
  5948. if(SUCCESS == dwErr)
  5949. {
  5950. pInfo->pArgs->pFile = &pInfo->pArgs->file;
  5951. }
  5952. #endif
  5953. }
  5954. if ( 0 != dwErr )
  5955. {
  5956. ErrorDlg( pInfo->hwndDlg, SID_OP_ScriptHalted, dwErr, NULL );
  5957. }
  5958. return (ERROR_SUCCESS == dwErr);
  5959. }
  5960. if (!TerminalDlg(
  5961. pInfo->pArgs->pEntry, &pInfo->pArgs->rdp, pInfo->hwndDlg,
  5962. pState->hrasconnLink, sidTitle, pszIpAddress ))
  5963. {
  5964. TRACE( "TerminalDlg==FALSE" );
  5965. return FALSE;
  5966. }
  5967. TRACE2( "pszIpAddress=0x%08x(%ls)", pszIpAddress,
  5968. pszIpAddress ? pszIpAddress : TEXT("") );
  5969. TRACE2( "pEntry->pszIpAddress=0x%08x(%ls)", pEntry->pszIpAddress,
  5970. pEntry->pszIpAddress ? pEntry->pszIpAddress : TEXT("") );
  5971. if (pszIpAddress[0]
  5972. && (!pEntry->pszIpAddress
  5973. || lstrcmp( pszIpAddress, pEntry->pszIpAddress ) != 0))
  5974. {
  5975. Free0( pEntry->pszIpAddress );
  5976. pEntry->pszIpAddress = StrDup( szIpAddress );
  5977. pEntry->fDirty = TRUE;
  5978. *pfChange = TRUE;
  5979. dwErr = WritePhonebookFile( pInfo->pArgs->pFile, NULL );
  5980. if (dwErr != 0)
  5981. {
  5982. ErrorDlg( pInfo->hwndDlg, SID_OP_WritePhonebook, dwErr, NULL );
  5983. }
  5984. }
  5985. pState->sidState = 0;
  5986. return TRUE;
  5987. }
  5988. BOOL
  5989. DpIsLaterState(
  5990. IN RASCONNSTATE stateNew,
  5991. IN RASCONNSTATE stateOld )
  5992. // Returns true if 'stateNew' is farther along in the connection than
  5993. // 'stateOld' false if the same or not as far along.
  5994. //
  5995. {
  5996. // This array is in the order events normally occur.
  5997. //
  5998. // !!! New EAP states?
  5999. //
  6000. static RASCONNSTATE aState[] =
  6001. {
  6002. (RASCONNSTATE )-1,
  6003. RASCS_OpenPort,
  6004. RASCS_PortOpened,
  6005. RASCS_ConnectDevice,
  6006. RASCS_DeviceConnected,
  6007. RASCS_Interactive,
  6008. RASCS_AllDevicesConnected,
  6009. RASCS_StartAuthentication,
  6010. RASCS_Authenticate,
  6011. RASCS_InvokeEapUI,
  6012. RASCS_AuthNotify,
  6013. RASCS_AuthRetry,
  6014. RASCS_AuthAck,
  6015. RASCS_PasswordExpired,
  6016. RASCS_AuthChangePassword,
  6017. RASCS_AuthCallback,
  6018. RASCS_CallbackSetByCaller,
  6019. RASCS_PrepareForCallback,
  6020. RASCS_WaitForModemReset,
  6021. RASCS_WaitForCallback,
  6022. RASCS_CallbackComplete,
  6023. RASCS_RetryAuthentication,
  6024. RASCS_ReAuthenticate,
  6025. RASCS_Authenticated,
  6026. RASCS_AuthLinkSpeed,
  6027. RASCS_AuthProject,
  6028. RASCS_Projected,
  6029. RASCS_LogonNetwork,
  6030. RASCS_SubEntryDisconnected,
  6031. RASCS_SubEntryConnected,
  6032. RASCS_Disconnected,
  6033. RASCS_Connected,
  6034. (RASCONNSTATE )-2,
  6035. };
  6036. RASCONNSTATE* pState;
  6037. for (pState = aState; *pState != (RASCONNSTATE )-2; ++pState)
  6038. {
  6039. if (*pState == stateNew)
  6040. {
  6041. return FALSE;
  6042. }
  6043. else if (*pState == stateOld)
  6044. {
  6045. return TRUE;
  6046. }
  6047. }
  6048. return FALSE;
  6049. }
  6050. BOOL
  6051. DpPasswordExpired(
  6052. IN DPINFO* pInfo,
  6053. IN DPSTATE* pState )
  6054. // RASCS_PasswordExpired state handling. 'PInfo' is the dialog context.
  6055. // 'PState' is the subentry state.
  6056. //
  6057. // Returns true if successful, false otherwise.
  6058. //
  6059. {
  6060. TCHAR szOldPassword[ PWLEN + 1 ];
  6061. BOOL fSuppliedOldPassword;
  6062. TRACE( "DpPasswordExpired" );
  6063. szOldPassword[ 0 ] = TEXT('\0');
  6064. // Stash "good" username and password which are restored if the password
  6065. // change fails.
  6066. //
  6067. pInfo->pszGoodUserName = StrDup( pInfo->pArgs->rdp.szUserName );
  6068. // Whistler bug 254385 encode password when not being used
  6069. // Assumed password was encoded previously
  6070. //
  6071. DecodePassword( pInfo->pArgs->rdp.szPassword );
  6072. pInfo->pszGoodPassword = StrDup( pInfo->pArgs->rdp.szPassword );
  6073. EncodePassword( pInfo->pArgs->rdp.szPassword );
  6074. EncodePassword( pInfo->pszGoodPassword );
  6075. fSuppliedOldPassword =
  6076. (!pInfo->pArgs->pEntry->fAutoLogon || pInfo->pArgs->pNoUser);
  6077. if (!ChangePasswordDlg(
  6078. pInfo->hwndDlg, !fSuppliedOldPassword,
  6079. szOldPassword, pInfo->pArgs->rdp.szPassword ))
  6080. {
  6081. // Whistler bug 254385 encode password when not being used
  6082. //
  6083. RtlSecureZeroMemory( szOldPassword, sizeof(szOldPassword) );
  6084. return FALSE;
  6085. }
  6086. if (pInfo->pArgs->pNoUser)
  6087. {
  6088. // Whistler bug 254385 encode password when not being used
  6089. // Assumed password was encoded previously
  6090. //
  6091. DecodePassword( pInfo->pArgs->rdp.szPassword );
  6092. lstrcpyn(
  6093. pInfo->pArgs->pNoUser->szPassword,
  6094. pInfo->pArgs->rdp.szPassword,
  6095. PWLEN + 1);
  6096. EncodePassword( pInfo->pArgs->rdp.szPassword );
  6097. EncodePassword( pInfo->pArgs->pNoUser->szPassword );
  6098. *pInfo->pArgs->pfNoUserChanged = TRUE;
  6099. }
  6100. // The old password (in text form) is explicitly set, since in AutoLogon
  6101. // case a text form has not yet been specified. The old password in text
  6102. // form is required to change the password. The "old" private API expects
  6103. // an ANSI argument.
  6104. //
  6105. if (!fSuppliedOldPassword)
  6106. {
  6107. // Whistler bug 254385 encode password when not being used
  6108. // Assumed password was encoded by ChangePasswordDlg()
  6109. //
  6110. CHAR* pszOldPasswordA;
  6111. DecodePassword( szOldPassword );
  6112. pszOldPasswordA = StrDupAFromT( szOldPassword );
  6113. if (pszOldPasswordA)
  6114. {
  6115. ASSERT( g_pRasSetOldPassword );
  6116. g_pRasSetOldPassword( pInfo->hrasconn, pszOldPasswordA );
  6117. RtlSecureZeroMemory( pszOldPasswordA, lstrlenA( pszOldPasswordA ) );
  6118. Free( pszOldPasswordA );
  6119. }
  6120. }
  6121. RtlSecureZeroMemory( szOldPassword, sizeof(szOldPassword) );
  6122. if (pInfo->pArgs->rdp.szUserName[ 0 ] == TEXT('\0'))
  6123. {
  6124. // Explicitly set the username, effectively turning off AutoLogon for
  6125. // the "resume" password authentication, where the new password should
  6126. // be used.
  6127. //
  6128. lstrcpyn( pInfo->pArgs->rdp.szUserName, GetLogonUser(), UNLEN + 1 );
  6129. }
  6130. pState->sidState = 0;
  6131. return TRUE;
  6132. }
  6133. BOOL
  6134. DpProjected(
  6135. IN DPINFO* pInfo,
  6136. IN DPSTATE* pState )
  6137. // RASCS_Projected state handling. 'PInfo' is the dialog context.
  6138. // 'PState' is the subentry state.
  6139. //
  6140. // Returns true if successful, false otherwise.
  6141. //
  6142. {
  6143. DWORD dwErr;
  6144. RASAMB amb;
  6145. RASPPPNBF nbf;
  6146. RASPPPIPX ipx;
  6147. RASPPPIP ip;
  6148. RASPPPLCP lcp;
  6149. RASSLIP slip;
  6150. RASPPPCCP ccp;
  6151. BOOL fIncomplete;
  6152. DWORD dwfProtocols;
  6153. TCHAR* pszLines;
  6154. TRACE( "DpProjected" );
  6155. pState->sidState = SID_S_Projected;
  6156. //
  6157. // If PORT_NOT_OPEN is indicated, it probably means that the
  6158. // server disconnected the connection before result dialog
  6159. // was dismissed. In that case, this is the 2nd time DpProjected
  6160. // is called. This time, the error is indicated by ras and the
  6161. // state remains "projected".
  6162. //
  6163. // We need to return an error in this case so that the connection
  6164. // isn't hung since this is the last indication RAS will give us.
  6165. //
  6166. // See bug 382254
  6167. //
  6168. TRACE1("DpProjected: dwErr:(%d)", pState->dwError);
  6169. if ( (pState->dwError == ERROR_PORT_NOT_OPEN) ||
  6170. (pState->dwError == ERROR_NO_CONNECTION) ) //See bug 169111 whistler
  6171. {
  6172. return FALSE;
  6173. }
  6174. // Do this little dance to ignore the error that comes back from the
  6175. // "all-failed" projection since we detect this in the earlier
  6176. // notification where pState->dwError == 0. This avoids a race where the
  6177. // API comes back with the error before we can hang him up. This race
  6178. // would not occur if we called RasHangUp from within the callback thread
  6179. // (as recommended in our API doc). It's the price we pay for posting the
  6180. // error to the other thread in order to avoid holding the port open while
  6181. // an error dialog is up.
  6182. //
  6183. else if (pState->dwError != 0)
  6184. {
  6185. pState->dwError = 0;
  6186. //For XPSP2 511810, .Net 668164
  6187. ResetCallbackActive(pInfo);
  6188. DecGlobalCallbackActive();
  6189. return TRUE;
  6190. }
  6191. // Read projection info for all protocols, translating "not requested"
  6192. // into an in-structure code for later reference.
  6193. //
  6194. dwErr = GetRasProjectionInfo(
  6195. pState->hrasconnLink, &amb, &nbf, &ip, &ipx, &lcp, &slip, &ccp );
  6196. if (dwErr != 0)
  6197. {
  6198. ErrorDlg( pInfo->hwndDlg, SID_OP_RasGetProtocolInfo, dwErr, NULL );
  6199. return FALSE;
  6200. }
  6201. if (amb.dwError != ERROR_PROTOCOL_NOT_CONFIGURED)
  6202. {
  6203. // It's an AMB projection.
  6204. //
  6205. if (amb.dwError != 0)
  6206. {
  6207. // Translate AMB projection errors into regular error codes. AMB
  6208. // does not use the special PPP projection error mechanism.
  6209. //
  6210. pState->dwError = amb.dwError;
  6211. lstrcpyn(
  6212. pState->szExtendedError,
  6213. amb.szNetBiosError,
  6214. sizeof(pState->szExtendedError) / sizeof(TCHAR));
  6215. }
  6216. return TRUE;
  6217. }
  6218. // At this point, all projection information has been gathered
  6219. // successfully and we know it's a PPP-based projection. Now analyze the
  6220. // projection results...
  6221. //
  6222. dwfProtocols = 0;
  6223. fIncomplete = FALSE;
  6224. if (DpProjectionError(
  6225. &nbf, &ipx, &ip,
  6226. &fIncomplete, &dwfProtocols, &pszLines, &pState->dwError ))
  6227. {
  6228. // A projection error occurred.
  6229. //
  6230. if (fIncomplete)
  6231. {
  6232. BOOL fStatus;
  6233. BOOL fDisable;
  6234. // An incomplete projection occurred, i.e. some requested CPs
  6235. // connected and some did not. Ask the user if what worked is
  6236. // good enough or he wants to bail.
  6237. //
  6238. pState->dwError = 0;
  6239. fDisable = FALSE;
  6240. fStatus = ProjectionResultDlg(
  6241. pInfo->hwndDlg, pszLines, &fDisable );
  6242. Free( pszLines );
  6243. if (fDisable)
  6244. {
  6245. pInfo->pArgs->dwfExcludedProtocols = dwfProtocols;
  6246. }
  6247. // Return now if user chose to hang up.
  6248. //
  6249. if (!fStatus)
  6250. {
  6251. return FALSE;
  6252. }
  6253. }
  6254. else
  6255. {
  6256. // All CPs in the projection failed. Process as a regular fatal
  6257. // error with 'pState->dwError' set to the first error in NBF, IP,
  6258. // or IPX, but with a format that substitutes the status argument
  6259. // for the "Error nnn: Description" text. This lets us patch in
  6260. // the special multiple error projection text, while still giving
  6261. // a meaningful help context.
  6262. //
  6263. Free0( pState->pszFormatArg );
  6264. pState->pszFormatArg = pszLines;
  6265. pState->sidFormatMsg = SID_FMT_ErrorMsgProject;
  6266. }
  6267. }
  6268. //
  6269. // pmay: 190394
  6270. //
  6271. // If the admin has a message, display it.
  6272. //
  6273. if ( (pState->dwError == NO_ERROR) &&
  6274. (wcslen (lcp.szReplyMessage) != 0)
  6275. )
  6276. {
  6277. MSGARGS MsgArgs, *pMsgArgs = &MsgArgs;
  6278. ZeroMemory(pMsgArgs, sizeof(MSGARGS));
  6279. pMsgArgs->dwFlags = MB_OK | MB_ICONINFORMATION;
  6280. pMsgArgs->apszArgs[0] = lcp.szReplyMessage;
  6281. //MsgDlg(
  6282. // pInfo->hwndDlg,
  6283. // SID_ReplyMessageFmt,
  6284. // pMsgArgs);
  6285. }
  6286. pState->sidState = SID_S_Projected;
  6287. return TRUE;
  6288. }
  6289. BOOL
  6290. DpProjectionError(
  6291. IN RASPPPNBF* pnbf,
  6292. IN RASPPPIPX* pipx,
  6293. IN RASPPPIP* pip,
  6294. OUT BOOL* pfIncomplete,
  6295. OUT DWORD* pdwfFailedProtocols,
  6296. OUT TCHAR** ppszLines,
  6297. OUT DWORD* pdwError )
  6298. // Figure out if a projection error occurred and, if so, build the
  6299. // appropriate status/error text lines into '*ppszLines'. '*PfIncomlete'
  6300. // is set true if at least one CP succeeded and at least one failed.
  6301. // '*pdwfFailedProtocols' is set to the bit mask of NP_* that failed.
  6302. // '*pdwError' is set to the first error that occurred in NBF, IP, or IPX
  6303. // in that order or 0 if none. 'pnbf', 'pipx', and 'pip' are projection
  6304. // information for the respective protocols with dwError set to
  6305. // ERROR_PROTOCOL_NOT_CONFIGURED if the protocols was not requested.
  6306. //
  6307. // This routine assumes that at least one protocol was requested.
  6308. //
  6309. // Returns true if a projection error occurred, false if not. It's
  6310. // caller's responsiblity to free '*ppszLines'.
  6311. //
  6312. {
  6313. #define MAXPROJERRLEN 1024
  6314. TCHAR szLines[ MAXPROJERRLEN ];
  6315. BOOL fIp = (pip->dwError != ERROR_PROTOCOL_NOT_CONFIGURED);
  6316. BOOL fIpx = (pipx->dwError != ERROR_PROTOCOL_NOT_CONFIGURED);
  6317. BOOL fNbf = (pnbf->dwError != ERROR_PROTOCOL_NOT_CONFIGURED);
  6318. BOOL fIpBad = (fIp && pip->dwError != 0);
  6319. BOOL fIpxBad = (fIpx && pipx->dwError != 0);
  6320. BOOL fNbfBad = (fNbf && pnbf->dwError != 0);
  6321. TRACE( "DpProjectionError" );
  6322. *pdwfFailedProtocols = 0;
  6323. if (!fNbfBad && !fIpxBad && !fIpBad)
  6324. {
  6325. return FALSE;
  6326. }
  6327. if (fNbfBad)
  6328. {
  6329. *pdwfFailedProtocols |= NP_Nbf;
  6330. }
  6331. if (fIpxBad)
  6332. {
  6333. *pdwfFailedProtocols |= NP_Ipx;
  6334. }
  6335. if (fIpBad)
  6336. {
  6337. *pdwfFailedProtocols |= NP_Ip;
  6338. }
  6339. *pfIncomplete =
  6340. ((fIp && pip->dwError == 0)
  6341. || (fIpx && pipx->dwError == 0)
  6342. || (fNbf && pnbf->dwError == 0));
  6343. szLines[ 0 ] = 0;
  6344. *ppszLines = NULL;
  6345. *pdwError = 0;
  6346. if (fIpBad || (*pfIncomplete && fIp))
  6347. {
  6348. if (fIpBad)
  6349. {
  6350. *pdwError = pip->dwError;
  6351. DpAppendConnectErrorLine( szLines, SID_Ip, pip->dwError );
  6352. }
  6353. else
  6354. {
  6355. DpAppendConnectOkLine( szLines, SID_Ip );
  6356. }
  6357. DpAppendBlankLine( szLines );
  6358. }
  6359. if (fIpxBad || (*pfIncomplete && fIpx))
  6360. {
  6361. if (fIpxBad)
  6362. {
  6363. *pdwError = pipx->dwError;
  6364. DpAppendConnectErrorLine( szLines, SID_Ipx, pipx->dwError );
  6365. }
  6366. else
  6367. {
  6368. DpAppendConnectOkLine( szLines, SID_Ipx );
  6369. }
  6370. DpAppendBlankLine( szLines );
  6371. }
  6372. if (fNbfBad || (*pfIncomplete && fNbf))
  6373. {
  6374. if (fNbfBad)
  6375. {
  6376. *pdwError = pnbf->dwError;
  6377. DpAppendConnectErrorLine( szLines, SID_Nbf, pnbf->dwError );
  6378. if (pnbf->dwNetBiosError)
  6379. {
  6380. DpAppendFailCodeLine( szLines, pnbf->dwNetBiosError );
  6381. }
  6382. if (pnbf->szNetBiosError[ 0 ] != '\0')
  6383. {
  6384. DpAppendNameLine( szLines, pnbf->szNetBiosError );
  6385. }
  6386. }
  6387. else
  6388. {
  6389. DpAppendConnectOkLine( szLines, SID_Nbf );
  6390. }
  6391. DpAppendBlankLine( szLines );
  6392. }
  6393. *ppszLines = StrDup( szLines );
  6394. return TRUE;
  6395. }
  6396. DWORD WINAPI
  6397. DpRasDialFunc2(
  6398. ULONG_PTR dwCallbackId,
  6399. DWORD dwSubEntry,
  6400. HRASCONN hrasconn,
  6401. UINT unMsg,
  6402. RASCONNSTATE state,
  6403. DWORD dwError,
  6404. DWORD dwExtendedError )
  6405. // RASDIALFUNC2 callback to receive RasDial events.
  6406. //
  6407. // Returns 0 to stop callbacks, 1 to continue callbacks (normal), and 2 to
  6408. // tell RAS API that relevant entry information (like SLIP IP address) has
  6409. // changed.
  6410. //
  6411. {
  6412. DWORD dwErr;
  6413. DWORD dwCode;
  6414. DPINFO* pInfo;
  6415. DPSTATE* pState;
  6416. BOOL fTerminateAsap;
  6417. long ulCallbacksActive;
  6418. TRACE4( "/DpRasDialFunc2(rcs=%d,s=%d,e=%d,x=%d)",
  6419. state, dwSubEntry, dwError, dwExtendedError );
  6420. pInfo = (DPINFO* )dwCallbackId;
  6421. if( NULL == pInfo )
  6422. {
  6423. TRACE("DpRasDialFunc2(): Invalid pInfo");
  6424. return 0;
  6425. }
  6426. if (pInfo->dwValid != 0xC0BBC0DE)
  6427. {
  6428. TRACE( "DpRasDialFunc2 returns for Late callback?" );
  6429. return 0;
  6430. }
  6431. if (dwSubEntry == 0 || dwSubEntry > pInfo->cStates)
  6432. {
  6433. TRACE( "DpRasDialFunc2 returns for Subentry out of range?" );
  6434. return 1;
  6435. }
  6436. pState = &pInfo->pStates[ dwSubEntry - 1 ];
  6437. pState->state = state;
  6438. pState->dwError = dwError;
  6439. pState->dwExtendedError = dwExtendedError;
  6440. // Post the event to the Dial Progress window and wait for it to be
  6441. // processed before returning. This avoids subtle problems with Z-order
  6442. // and focus when a window is manipulated from two different threads.
  6443. //
  6444. TRACE1("Send RasEvent to Dial Progress window, subEntry:(%d)", dwSubEntry);
  6445. TRACE1("Get dwError=(%d) from RasMan",pState->dwError);
  6446. TRACE2("DpRasDialFunc2:Process:(%x),Thread(%x)",
  6447. GetCurrentProcessId,
  6448. GetCurrentThreadId);
  6449. TRACE2("DpRasDialFunc2:pInfo address (0x%x), Dialog Handle (0x%x)",
  6450. pInfo,
  6451. pInfo->hwndDlg);
  6452. dwCode = (DWORD)SendMessage( pInfo->hwndDlg, WM_RASEVENT, dwSubEntry, 0 );
  6453. TRACE1( "\\DpRasDialFunc2: dwCode from SendMessage()=%d", dwCode );
  6454. TRACE1("dwCode returned:(%d)", dwCode);
  6455. //Check if current thread is cancelled by user
  6456. //
  6457. // For XPSP2 511810, .Net 668164
  6458. fTerminateAsap = GetTerminateFlag(pInfo);
  6459. ulCallbacksActive = GetCallbackActive(pInfo);
  6460. TRACE1("Current thread's active:(%d)", ulCallbacksActive);
  6461. if ( fTerminateAsap )
  6462. {
  6463. TRACE("Current Thread wants to terminate itself, its fterminateASSP=1!");
  6464. TRACE("Current thread will decrease its own and global active!");
  6465. //reset per-thread terminateASAP flag
  6466. //
  6467. // For XPSP2 511810, .Net 668164
  6468. DecGlobalCallbackActive();
  6469. ResetTerminateFlag( pInfo );
  6470. ResetCallbackActive(pInfo);
  6471. //End callback function for this connection
  6472. //Have to return immediately after ResetCallbackActive() to avoid race
  6473. // conditions because the UI thread is polling on pInfo->fCallbackActive
  6474. //
  6475. return 0;
  6476. }
  6477. else
  6478. {
  6479. TRACE("Current Thread does NOT want to terminate itself,its fterminateASAP=0!");
  6480. }
  6481. //return the global number of active callbacks for tracing
  6482. //
  6483. // For XPSP2 511810, .Net 668164
  6484. ulCallbacksActive = GetGlobalCallbackActive();
  6485. TRACE1("Global active:(%d)", ulCallbacksActive);
  6486. TRACE1("Current thread's active:(%d)", GetCallbackActive(pInfo));
  6487. // Check if UI thread want the Callback because of Error, connected,
  6488. // disconnected etc.
  6489. //
  6490. if (dwCode == 0)
  6491. {
  6492. // Reset thread-safe flag indicating callbacks have terminated.
  6493. //for XPSP2 511810, .Net 668164
  6494. ResetCallbackActive( pInfo);
  6495. DecGlobalCallbackActive();
  6496. }
  6497. TRACE1( "\\DpRasDialFunc2:final dwCode returned=%d", dwCode );
  6498. return dwCode;
  6499. }
  6500. // For whistler bug 435725
  6501. //
  6502. void
  6503. DpFreeStates(
  6504. IN DPSTATE * pStates,
  6505. IN DWORD dwSize )
  6506. {
  6507. DWORD dwCount = 0;
  6508. for ( dwCount = 0; dwCount < dwSize; dwCount ++ )
  6509. {
  6510. Free0( pStates[dwCount].pszFormatArg );
  6511. Free0( pStates[dwCount].pszStatusArg );
  6512. }
  6513. Free0(pStates);
  6514. }
  6515. VOID
  6516. DpTerm(
  6517. IN HWND hwndDlg )
  6518. // Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
  6519. //
  6520. {
  6521. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  6522. TRACE( "DpTerm" );
  6523. if (pInfo)
  6524. {
  6525. if (pInfo->pOldWndProc)
  6526. {
  6527. SetWindowLongPtr( pInfo->hwndDlg,
  6528. GWLP_WNDPROC, (ULONG_PTR )pInfo->pOldWndProc );
  6529. }
  6530. // For whistler bug 435725 gangz
  6531. // Need to free the strings inside pStates
  6532. //
  6533. DpFreeStates( pInfo->pStates, pInfo->cStates );
  6534. pInfo->dwValid = 0;
  6535. // for XPSP2 511810, .Net 668164, 668164
  6536. DeleteCriticalSection(pInfo->pcsActiveLock);
  6537. Free( pInfo );
  6538. pInfo = NULL;
  6539. }
  6540. //For whistler bug 372078 gangz
  6541. //
  6542. {
  6543. HICON hIcon=NULL;
  6544. hIcon = (HICON)SendMessage( GetDlgItem( hwndDlg, CID_DP_Icon ),
  6545. STM_GETICON,
  6546. 0,
  6547. 0);
  6548. ASSERT(hIcon);
  6549. if( hIcon )
  6550. {
  6551. DestroyIcon(hIcon);
  6552. }
  6553. else
  6554. {
  6555. TRACE("DpTerm:Destroy Icon failed");
  6556. }
  6557. }
  6558. }
  6559. LRESULT APIENTRY
  6560. DpWndProc(
  6561. HWND hwnd,
  6562. UINT unMsg,
  6563. WPARAM wParam,
  6564. LPARAM lParam )
  6565. // Subclassed dialog window procedure.
  6566. //
  6567. {
  6568. DPINFO* pInfo = (DPINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  6569. ASSERT( pInfo );
  6570. if (unMsg == WM_RASEVENT)
  6571. {
  6572. return DpEvent( pInfo, (DWORD )wParam );
  6573. }
  6574. return
  6575. CallWindowProc(
  6576. pInfo->pOldWndProc, hwnd, unMsg, wParam, lParam );
  6577. }
  6578. //----------------------------------------------------------------------------
  6579. // Dialer dialogs
  6580. // Listed alphabetically following stub API and dialog proc
  6581. //----------------------------------------------------------------------------
  6582. BOOL
  6583. DialerDlg(
  6584. IN HWND hwndOwner,
  6585. IN OUT DINFO* pInfo )
  6586. // Determine if it's necessary, and if so, popup one of the variations of
  6587. // the dialer dialog, i.e. the prompter for user/password/domain, phone
  6588. // number, and location. 'HwndOwner' is the owning window. 'PInfo' is
  6589. // the dial dialog common context.
  6590. //
  6591. // Returns true if no dialog is needed or user chooses OK.
  6592. //
  6593. {
  6594. INT_PTR nStatus = FALSE;
  6595. int nDid;
  6596. DWORD dwfMode;
  6597. DRARGS args;
  6598. TRACE( "DialerDlg" );
  6599. do
  6600. {
  6601. dwfMode = 0;
  6602. if (!pInfo->pEntry->fAutoLogon
  6603. && pInfo->pEntry->fPreviewUserPw
  6604. && (!(pInfo->pArgs->dwFlags & RASDDFLAG_NoPrompt)
  6605. || (pInfo->fUnattended && !HaveSavedPw( pInfo ))))
  6606. {
  6607. dwfMode |= DR_U;
  6608. if (pInfo->pEntry->fPreviewDomain)
  6609. {
  6610. dwfMode |= DR_D;
  6611. }
  6612. }
  6613. if (pInfo->pEntry->fPreviewPhoneNumber
  6614. && (!(pInfo->pArgs->dwFlags & RASDDFLAG_NoPrompt)
  6615. || (pInfo->fUnattended && !HaveSavedPw( pInfo ))))
  6616. {
  6617. DTLNODE* pNode;
  6618. PBLINK* pLink;
  6619. dwfMode |= DR_N;
  6620. // Location controls mode only when at least one phone number in
  6621. // the list is TAPI-enabled.
  6622. //
  6623. pNode = DtlGetFirstNode( pInfo->pEntry->pdtllistLinks );
  6624. pLink = (PBLINK* )DtlGetData( pNode );
  6625. for (pNode = DtlGetFirstNode( pLink->pdtllistPhones );
  6626. pNode;
  6627. pNode = DtlGetNextNode( pNode ))
  6628. {
  6629. PBPHONE* pPhone = (PBPHONE* )DtlGetData( pNode );
  6630. if ( pPhone->fUseDialingRules )
  6631. {
  6632. dwfMode |= DR_L;
  6633. break;
  6634. }
  6635. }
  6636. }
  6637. // Customize the dialing flags for the type of eap authentication
  6638. // specified for this entry (if any)
  6639. if (DialerEapAssignMode(pInfo, &dwfMode) != NO_ERROR)
  6640. break;
  6641. if (dwfMode == DR_U)
  6642. {
  6643. nDid = DID_DR_DialerU;
  6644. }
  6645. else if (dwfMode == (DR_U | DR_D))
  6646. {
  6647. nDid = DID_DR_DialerUD;
  6648. }
  6649. else if (dwfMode == (DR_U | DR_N))
  6650. {
  6651. nDid = DID_DR_DialerUN;
  6652. }
  6653. else if (dwfMode == (DR_U | DR_N | DR_L))
  6654. {
  6655. nDid = DID_DR_DialerUNL;
  6656. }
  6657. else if (dwfMode == (DR_U | DR_D | DR_N))
  6658. {
  6659. nDid = DID_DR_DialerUDN;
  6660. }
  6661. else if (dwfMode == (DR_U | DR_D | DR_N | DR_L))
  6662. {
  6663. nDid = DID_DR_DialerUDNL;
  6664. }
  6665. else if (dwfMode == DR_N)
  6666. {
  6667. nDid = DID_DR_DialerN;
  6668. }
  6669. else if (dwfMode == (DR_N | DR_L))
  6670. {
  6671. nDid = DID_DR_DialerNL;
  6672. }
  6673. else if (dwfMode == DR_I) {
  6674. nDid = DID_DR_DialerI;
  6675. }
  6676. else if (dwfMode == (DR_I | DR_N)) {
  6677. nDid = DID_DR_DialerIN;
  6678. }
  6679. else if (dwfMode == (DR_I | DR_N | DR_L)) {
  6680. nDid = DID_DR_DialerINL;
  6681. }
  6682. // pmay: The following 3 permutations of the
  6683. // dialer dialog were added for bug 183577 which
  6684. // states that eap modules (that use DR_I) want to
  6685. // have the domain field available to them as well.
  6686. else if (dwfMode == (DR_I | DR_D)) {
  6687. nDid = DID_DR_DialerID;
  6688. }
  6689. else if (dwfMode == (DR_I | DR_D | DR_N)) {
  6690. nDid = DID_DR_DialerIDN;
  6691. }
  6692. else if (dwfMode == (DR_I | DR_D | DR_N | DR_L)) {
  6693. nDid = DID_DR_DialerIDNL;
  6694. }
  6695. else if( dwfMode == DR_B )
  6696. {
  6697. nDid = DID_DR_DialerB;
  6698. }
  6699. else
  6700. {
  6701. ASSERT( dwfMode == 0 );
  6702. return TRUE;
  6703. }
  6704. args.pDinfo = pInfo;
  6705. args.dwfMode = dwfMode;
  6706. args.fReload = FALSE;
  6707. nStatus =
  6708. (BOOL )DialogBoxParam(
  6709. g_hinstDll,
  6710. MAKEINTRESOURCE( nDid ),
  6711. hwndOwner,
  6712. DrDlgProc,
  6713. (LPARAM )&args );
  6714. if (nStatus == -1)
  6715. {
  6716. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  6717. nStatus = FALSE;
  6718. }
  6719. }
  6720. while (args.fReload);
  6721. return (BOOL )nStatus;
  6722. }
  6723. INT_PTR CALLBACK
  6724. DrDlgProc(
  6725. IN HWND hwnd,
  6726. IN UINT unMsg,
  6727. IN WPARAM wparam,
  6728. IN LPARAM lparam )
  6729. // DialogProc callback for the dialer dialogs. Parameters and return
  6730. // value are as described for standard windows 'DialogProc's.
  6731. //
  6732. {
  6733. #if 0
  6734. TRACE4( "DrDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  6735. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  6736. #endif
  6737. switch (unMsg)
  6738. {
  6739. case WM_INITDIALOG:
  6740. {
  6741. return DrInit( hwnd, (DRARGS* )lparam );
  6742. }
  6743. case WM_HELP:
  6744. case WM_CONTEXTMENU:
  6745. {
  6746. ContextHelp( g_adwDrHelp, hwnd, unMsg, wparam, lparam );
  6747. break;
  6748. }
  6749. case WM_COMMAND:
  6750. {
  6751. DRINFO* pInfo = (DRINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  6752. ASSERT( pInfo );
  6753. return DrCommand(
  6754. pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  6755. }
  6756. case WM_DESTROY:
  6757. {
  6758. DrTerm( hwnd );
  6759. break;
  6760. }
  6761. }
  6762. return FALSE;
  6763. }
  6764. VOID
  6765. DrGetFriendlyFont(
  6766. IN HWND hwnd,
  6767. IN BOOL fUpdate,
  6768. OUT HFONT* phFont )
  6769. // Whistler bug: 195480 Dial-up connection dialog - Number of asterisks
  6770. // does not match the length of the password and causes confusion
  6771. //
  6772. {
  6773. LOGFONT BoldLogFont;
  6774. HFONT hFont;
  6775. HDC hdc;
  6776. *phFont = NULL;
  6777. // Get the font used by the specified window
  6778. //
  6779. hFont = (HFONT)SendMessage( hwnd, WM_GETFONT, 0, 0L );
  6780. if (NULL == hFont)
  6781. {
  6782. // If not found then the control is using the system font
  6783. //
  6784. hFont = (HFONT)GetStockObject( SYSTEM_FONT );
  6785. }
  6786. if (hFont && GetObject( hFont, sizeof(BoldLogFont), &BoldLogFont ))
  6787. {
  6788. if (fUpdate)
  6789. {
  6790. BoldLogFont.lfItalic = TRUE;
  6791. }
  6792. hdc = GetDC( hwnd );
  6793. if (hdc)
  6794. {
  6795. *phFont = CreateFontIndirect( &BoldLogFont );
  6796. ReleaseDC( hwnd, hdc );
  6797. }
  6798. }
  6799. return;
  6800. }
  6801. DWORD
  6802. DrEnableDisablePwControls(
  6803. IN DRINFO* pInfo,
  6804. IN BOOL fEnable )
  6805. {
  6806. if (pInfo->pArgs->pDinfo->fIsPublicPbk)
  6807. {
  6808. EnableWindow( pInfo->hwndRbSaveForEveryone, fEnable );
  6809. }
  6810. else
  6811. {
  6812. EnableWindow( pInfo->hwndRbSaveForEveryone, FALSE );
  6813. }
  6814. EnableWindow( pInfo->hwndRbSaveForMe, fEnable );
  6815. return NO_ERROR;
  6816. }
  6817. VOID
  6818. DrClearFriendlyPassword(
  6819. IN DRINFO* pInfo,
  6820. IN BOOL fFocus )
  6821. {
  6822. SetWindowText( pInfo->hwndEbPw, L"" );
  6823. if (fFocus)
  6824. {
  6825. SendMessage( pInfo->hwndEbPw, EM_SETPASSWORDCHAR,
  6826. pInfo->szPasswordChar, 0 );
  6827. if (pInfo->hNormalFont)
  6828. {
  6829. SendMessage(
  6830. pInfo->hwndEbPw,
  6831. WM_SETFONT,
  6832. (WPARAM)pInfo->hNormalFont,
  6833. MAKELPARAM(TRUE, 0) );
  6834. }
  6835. SetFocus( pInfo->hwndEbPw );
  6836. }
  6837. return;
  6838. }
  6839. VOID
  6840. DrDisplayFriendlyPassword(
  6841. IN DRINFO* pInfo,
  6842. IN TCHAR* pszFriendly )
  6843. {
  6844. if (pszFriendly)
  6845. {
  6846. SendMessage( pInfo->hwndEbPw, EM_SETPASSWORDCHAR, 0, 0 );
  6847. SetWindowText( pInfo->hwndEbPw, pszFriendly );
  6848. }
  6849. else
  6850. {
  6851. SetWindowText( pInfo->hwndEbPw, L"" );
  6852. }
  6853. if (pInfo->hItalicFont)
  6854. {
  6855. SendMessage(
  6856. pInfo->hwndEbPw,
  6857. WM_SETFONT,
  6858. (WPARAM)pInfo->hItalicFont,
  6859. MAKELPARAM(TRUE, 0) );
  6860. }
  6861. return;
  6862. }
  6863. BOOL
  6864. DrIsPasswordStyleEnabled(
  6865. IN HWND hWnd )
  6866. {
  6867. return SendMessage( hWnd, EM_GETPASSWORDCHAR, 0, 0 ) ? TRUE : FALSE;
  6868. }
  6869. BOOL
  6870. DrCommand(
  6871. IN DRINFO* pInfo,
  6872. IN WORD wNotification,
  6873. IN WORD wId,
  6874. IN HWND hwndCtrl )
  6875. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  6876. // is the notification code of the command. 'wId' is the control/menu
  6877. // identifier of the command. 'HwndCtrl' is the control window handle of
  6878. // the command.
  6879. //
  6880. // Returns true if processed message, false otherwise.
  6881. //
  6882. {
  6883. DWORD dwErr = NO_ERROR;
  6884. TRACE3( "DrCommand(n=%d,i=%d,c=$%x)",
  6885. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  6886. switch (wId)
  6887. {
  6888. case CID_DR_CLB_Numbers:
  6889. {
  6890. if (wNotification == CBN_SELCHANGE)
  6891. {
  6892. DrNumbersSelChange( pInfo );
  6893. return TRUE;
  6894. }
  6895. break;
  6896. }
  6897. case CID_DR_CB_SavePassword:
  6898. {
  6899. BOOL fEnable = Button_GetCheck( hwndCtrl );
  6900. DrEnableDisablePwControls( pInfo, fEnable );
  6901. DrPopulatePasswordField( pInfo, FALSE, FALSE, NULL );
  6902. return TRUE;
  6903. }
  6904. // Whistler bug: 195480 Dial-up connection dialog - Number of asterisks
  6905. // does not match the length of the password and causes confusion
  6906. //
  6907. case CID_DR_EB_Password:
  6908. {
  6909. // This is a hack really so that we restore the Tab Stop to the
  6910. // username field. The reason it had to be removed was because we
  6911. // were receiving complaints that the focus shouldn't always go to
  6912. // the username field if it's non-null. The only way to fix this,
  6913. // since windows sets the initial focus to the first visible non-
  6914. // hidden tab stopped field, is to remove the tab stop temporarily
  6915. // from the username field.
  6916. //
  6917. if (wNotification == EN_KILLFOCUS)
  6918. {
  6919. LONG lStyle = GetWindowLong( pInfo->hwndEbUser, GWL_STYLE );
  6920. HWND hwndTmp = NULL;
  6921. /*
  6922. if (!(lStyle & WS_TABSTOP))
  6923. {
  6924. // If we detect tap stop removed from the username field,
  6925. // restore it. Since this case only fires when the password
  6926. // was not previously saved on init, we can return here.
  6927. //
  6928. SetWindowLong( pInfo->hwndEbUser, GWL_STYLE,
  6929. lStyle | WS_TABSTOP );
  6930. // for whistler bug 424209 gangz
  6931. // The help button receive the focus before the kill focus
  6932. // sent to password edit box
  6933. //
  6934. hwndTmp = GetDlgItem( pInfo->hwndDlg, CID_DR_PB_Help );
  6935. if ( GetFocus() == hwndTmp )
  6936. {
  6937. SetFocus( pInfo->hwndEbUser );
  6938. }
  6939. return TRUE;
  6940. }
  6941. */
  6942. // If the user leaves the password field w/o typing a new
  6943. // password, and a saved password is present, restore the
  6944. // friendly password text.
  6945. //
  6946. DrPopulatePasswordField( pInfo, FALSE, FALSE, NULL );
  6947. return TRUE;
  6948. }
  6949. // If the password field ever receives the focus, clear the
  6950. // friendly password text if applicable.
  6951. //
  6952. else if (wNotification == EN_SETFOCUS &&
  6953. !DrIsPasswordStyleEnabled( pInfo->hwndEbPw ))
  6954. {
  6955. DrPopulatePasswordField( pInfo, FALSE, TRUE, NULL );
  6956. return TRUE;
  6957. }
  6958. break;
  6959. }
  6960. case CID_DR_LB_Locations:
  6961. {
  6962. if (wNotification == CBN_SELCHANGE)
  6963. {
  6964. DrLocationsSelChange( pInfo );
  6965. return TRUE;
  6966. }
  6967. break;
  6968. }
  6969. case CID_DR_PB_Rules:
  6970. {
  6971. DrEditSelectedLocation( pInfo );
  6972. return TRUE;
  6973. }
  6974. case CID_DR_PB_Properties:
  6975. {
  6976. DrProperties( pInfo );
  6977. DrPopulatePasswordField( pInfo, FALSE, FALSE, NULL );
  6978. return TRUE;
  6979. }
  6980. case CID_DR_RB_SaveForMe:
  6981. case CID_DR_RB_SaveForEveryone:
  6982. {
  6983. DrPopulatePasswordField( pInfo, FALSE, FALSE, NULL );
  6984. DrPopulateIdentificationFields( pInfo, (wId == CID_DR_RB_SaveForMe));
  6985. return TRUE;
  6986. }
  6987. case IDOK:
  6988. case CID_DR_PB_DialConnect:
  6989. {
  6990. DrSave( pInfo );
  6991. EndDialog( pInfo->hwndDlg, TRUE );
  6992. return TRUE;
  6993. }
  6994. case IDCANCEL:
  6995. case CID_DR_PB_Cancel:
  6996. {
  6997. EndDialog( pInfo->hwndDlg, FALSE );
  6998. return TRUE;
  6999. }
  7000. case IDHELP:
  7001. case CID_DR_PB_Help:
  7002. {
  7003. TCHAR* pszCmdLine;
  7004. // Help button now invokes troubleshooting help per bug 210247.
  7005. //
  7006. pszCmdLine = PszFromId( g_hinstDll, SID_DialerHelpCmdLine );
  7007. if (pszCmdLine)
  7008. {
  7009. STARTUPINFO sInfo;
  7010. PROCESS_INFORMATION pProcInfo;
  7011. ZeroMemory( &sInfo, sizeof(sInfo) );
  7012. sInfo.cb = sizeof(sInfo);
  7013. ZeroMemory( &pProcInfo, sizeof(pProcInfo) );
  7014. CreateProcess(
  7015. NULL, pszCmdLine, NULL, NULL, FALSE,
  7016. 0, NULL, NULL, &sInfo, &pProcInfo );
  7017. Free( pszCmdLine );
  7018. }
  7019. return TRUE;
  7020. }
  7021. }
  7022. return FALSE;
  7023. }
  7024. BOOL CALLBACK
  7025. DrClbNumbersEnumChildProc(
  7026. IN HWND hwnd,
  7027. IN LPARAM lparam )
  7028. // Standard Windows EnumChildProc routine called back for each child
  7029. // window of the 'ClbNumbers' control.
  7030. //
  7031. {
  7032. DRINFO* pInfo;
  7033. LONG lId;
  7034. pInfo = (DRINFO* )lparam;
  7035. // There only one child window and it's the edit window.
  7036. //
  7037. pInfo->hwndClbNumbersEb = hwnd;
  7038. return FALSE;
  7039. }
  7040. BOOL CALLBACK
  7041. DrClbNumbersEnumWindowsProc(
  7042. IN HWND hwnd,
  7043. IN LPARAM lparam )
  7044. // Standard Windows EnumWindowsProc routine called back for each top-level
  7045. // window.
  7046. //
  7047. {
  7048. RECT rect;
  7049. GetWindowRect( hwnd, &rect );
  7050. if (rect.right - rect.left == DR_BOGUSWIDTH)
  7051. {
  7052. // This window has the unusual bogus width, so it must be the
  7053. // list-box.
  7054. //
  7055. ((DRINFO* )lparam)->hwndClbNumbersLb = hwnd;
  7056. return FALSE;
  7057. }
  7058. return TRUE;
  7059. }
  7060. LRESULT APIENTRY
  7061. DrClbNumbersEbWndProc(
  7062. HWND hwnd,
  7063. UINT unMsg,
  7064. WPARAM wParam,
  7065. LPARAM lParam )
  7066. // Subclassed combo-box edit-box child window procedure providing "manual
  7067. // edit" behavior.
  7068. //
  7069. // Return value depends on message type.
  7070. //
  7071. {
  7072. DRINFO* pInfo;
  7073. switch (unMsg)
  7074. {
  7075. case WM_SETTEXT:
  7076. {
  7077. // Prevent the combo-box from setting the contents of the edit box
  7078. // by discarding the request and reporting success.
  7079. //
  7080. return TRUE;
  7081. }
  7082. case DR_WM_SETTEXT:
  7083. {
  7084. // Convert our private SETTEXT to a regular SETTEXT and pass it on
  7085. // to the edit control.
  7086. //
  7087. unMsg = WM_SETTEXT;
  7088. break;
  7089. }
  7090. }
  7091. // Call the previous window procedure for everything else.
  7092. //
  7093. pInfo = (DRINFO* )GetProp( hwnd, g_contextId );
  7094. ASSERT( pInfo );
  7095. return
  7096. CallWindowProc(
  7097. pInfo->wndprocClbNumbersEb, hwnd, unMsg, wParam, lParam );
  7098. }
  7099. LRESULT APIENTRY
  7100. DrClbNumbersLbWndProc(
  7101. HWND hwnd,
  7102. UINT unMsg,
  7103. WPARAM wParam,
  7104. LPARAM lParam )
  7105. // Subclassed combo-box list-box child window procedure providing "manual
  7106. // edit" behavior.
  7107. //
  7108. // Return value depends on message type.
  7109. //
  7110. {
  7111. DRINFO* pInfo;
  7112. pInfo = (DRINFO* )GetProp( hwnd, g_contextId );
  7113. ASSERT( pInfo );
  7114. switch (unMsg)
  7115. {
  7116. case LB_FINDSTRINGEXACT:
  7117. case LB_FINDSTRING:
  7118. {
  7119. // This prevents the edit-box "completion" behavior of the
  7120. // combo-box, i.e. it prevents the edit-box contents from being
  7121. // extended to the closest match in the list.
  7122. //
  7123. return -1;
  7124. }
  7125. case LB_SETCURSEL:
  7126. case LB_SETTOPINDEX:
  7127. {
  7128. // Prevent the "match selection to edit-box" combo-box behavior by
  7129. // discarding any attempts to set the selection or top index to
  7130. // anything other than what we set.
  7131. //
  7132. if (wParam != pInfo->pLink->iLastSelectedPhone)
  7133. {
  7134. return -1;
  7135. }
  7136. break;
  7137. }
  7138. }
  7139. // Call the previous window procedure for everything else.
  7140. //
  7141. return
  7142. CallWindowProc(
  7143. pInfo->wndprocClbNumbersLb, hwnd, unMsg, wParam, lParam );
  7144. }
  7145. VOID
  7146. DrEditSelectedLocation(
  7147. IN DRINFO* pInfo )
  7148. // Called when the Dialing Rules button is pressed. 'PInfo' is the dialog
  7149. // context.
  7150. //
  7151. {
  7152. DWORD dwErr;
  7153. INT iSel;
  7154. DRNUMBERSITEM* pItem;
  7155. TRACE( "DrEditSelectedLocation" );
  7156. // Look up the phone number information for the selected number.
  7157. //
  7158. pItem = (DRNUMBERSITEM* )ComboBox_GetItemDataPtr(
  7159. pInfo->hwndClbNumbers, ComboBox_GetCurSel( pInfo->hwndClbNumbers ) );
  7160. ASSERT( pItem );
  7161. if(NULL == pItem)
  7162. {
  7163. return;
  7164. }
  7165. ASSERT( pItem->pPhone->fUseDialingRules );
  7166. // Popup TAPI dialing rules dialog.
  7167. //
  7168. dwErr = TapiLocationDlg(
  7169. g_hinstDll,
  7170. &pInfo->hlineapp,
  7171. pInfo->hwndDlg,
  7172. pItem->pPhone->dwCountryCode,
  7173. pItem->pPhone->pszAreaCode,
  7174. pItem->pPhone->pszPhoneNumber,
  7175. 0 );
  7176. if (dwErr != 0)
  7177. {
  7178. ErrorDlg( pInfo->hwndDlg, SID_OP_LoadTapiInfo, dwErr, NULL );
  7179. }
  7180. // Might have changed the location list so re-fill it.
  7181. //
  7182. DrFillLocationList( pInfo );
  7183. }
  7184. DWORD
  7185. DrFillLocationList(
  7186. IN DRINFO* pInfo )
  7187. // Fills the dropdown list of locations and sets the current selection.
  7188. //
  7189. // Returns 0 if successful, or an error code.
  7190. //
  7191. {
  7192. DWORD dwErr;
  7193. LOCATION* pLocations;
  7194. LOCATION* pLocation;
  7195. DWORD cLocations;
  7196. DWORD dwCurLocation;
  7197. DWORD i;
  7198. TRACE( "DrFillLocationList" );
  7199. ComboBox_ResetContent( pInfo->hwndLbLocations );
  7200. pLocations = NULL;
  7201. cLocations = 0;
  7202. dwCurLocation = 0xFFFFFFFF;
  7203. dwErr = GetLocationInfo(
  7204. g_hinstDll, &pInfo->hlineapp,
  7205. &pLocations, &cLocations, &dwCurLocation );
  7206. if (dwErr != 0)
  7207. {
  7208. return dwErr;
  7209. }
  7210. for (i = 0, pLocation = pLocations;
  7211. i < cLocations;
  7212. ++i, ++pLocation)
  7213. {
  7214. INT iItem;
  7215. iItem = ComboBox_AddItem(
  7216. pInfo->hwndLbLocations, pLocation->pszName,
  7217. (VOID* )UlongToPtr(pLocation->dwId ));
  7218. if (pLocation->dwId == dwCurLocation)
  7219. {
  7220. ComboBox_SetCurSelNotify( pInfo->hwndLbLocations, iItem );
  7221. }
  7222. }
  7223. FreeLocationInfo( pLocations, cLocations );
  7224. ComboBox_AutoSizeDroppedWidth( pInfo->hwndLbLocations );
  7225. return dwErr;
  7226. }
  7227. VOID
  7228. DrFillNumbersList(
  7229. IN DRINFO* pInfo )
  7230. // Fill the "Dial" combo-box with phone numbers and comments, and
  7231. // re-select the selected item in the list, or if none, the last one
  7232. // selected as specified in the PBLINK.
  7233. //
  7234. {
  7235. DTLNODE* pNode;
  7236. PBLINK* pLink;
  7237. PBPHONE* pPhone;
  7238. INT cItems;
  7239. INT i;
  7240. DrFreeClbNumbers( pInfo );
  7241. for (pNode = DtlGetFirstNode( pInfo->pLink->pdtllistPhones ), i = 0;
  7242. pNode;
  7243. pNode = DtlGetNextNode( pNode ), ++i)
  7244. {
  7245. TCHAR szBuf[ RAS_MaxPhoneNumber + RAS_MaxDescription + 3 + 1 ];
  7246. DRNUMBERSITEM* pItem;
  7247. pPhone = (PBPHONE* )DtlGetData( pNode );
  7248. ASSERT( pPhone );
  7249. pItem = Malloc( sizeof(DRNUMBERSITEM) );
  7250. if (!pItem)
  7251. {
  7252. break;
  7253. }
  7254. // Build the "<number> - <comment>" string in 'szBuf'.
  7255. //
  7256. pItem->pszNumber =
  7257. LinkPhoneNumberFromParts(
  7258. g_hinstDll, &pInfo->hlineapp,
  7259. pInfo->pArgs->pDinfo->pUser, pInfo->pArgs->pDinfo->pEntry,
  7260. pInfo->pLink, i, NULL, FALSE );
  7261. if (!pItem->pszNumber)
  7262. {
  7263. // Should not happen.
  7264. //
  7265. Free( pItem );
  7266. break;
  7267. }
  7268. lstrcpyn( szBuf, pItem->pszNumber, RAS_MaxPhoneNumber);
  7269. if (pPhone->pszComment && !IsAllWhite( pPhone->pszComment ))
  7270. {
  7271. DWORD dwLen, dwSize = sizeof(szBuf) / sizeof(TCHAR);
  7272. lstrcat( szBuf, TEXT(" - ") );
  7273. dwLen = lstrlen(szBuf) + 1;
  7274. lstrcpyn(
  7275. szBuf + (dwLen - 1),
  7276. pPhone->pszComment,
  7277. dwSize - dwLen );
  7278. }
  7279. pItem->pPhone = pPhone;
  7280. ComboBox_AddItem( pInfo->hwndClbNumbers, szBuf, pItem );
  7281. }
  7282. // Make the selection and trigger the update of the edit-box to the number
  7283. // without the comment.
  7284. //
  7285. cItems = ComboBox_GetCount( pInfo->hwndClbNumbers );
  7286. if (cItems > 0)
  7287. {
  7288. if ((INT )pInfo->pLink->iLastSelectedPhone >= cItems)
  7289. {
  7290. pInfo->pLink->iLastSelectedPhone = 0;
  7291. }
  7292. ListBox_SetTopIndex(
  7293. pInfo->hwndClbNumbersLb, pInfo->pLink->iLastSelectedPhone );
  7294. ComboBox_SetCurSelNotify(
  7295. pInfo->hwndClbNumbers, pInfo->pLink->iLastSelectedPhone );
  7296. }
  7297. ComboBox_AutoSizeDroppedWidth( pInfo->hwndClbNumbers );
  7298. }
  7299. VOID
  7300. DrFreeClbNumbers(
  7301. IN DRINFO* pInfo )
  7302. // Free up the displayable number string associated with each entry of the
  7303. // phone number combo-box leaving the box empty.
  7304. //
  7305. {
  7306. DRNUMBERSITEM* pItem;
  7307. while (pItem = ComboBox_GetItemDataPtr( pInfo->hwndClbNumbers, 0 ))
  7308. {
  7309. ComboBox_DeleteString( pInfo->hwndClbNumbers, 0 );
  7310. Free( pItem->pszNumber );
  7311. Free( pItem );
  7312. }
  7313. }
  7314. DWORD
  7315. DrFindAndSubclassClbNumbersControls(
  7316. IN DRINFO* pInfo )
  7317. // Locate and sub-class the edit-box and list-box child controls of the
  7318. // phone number combo-box. This is necessary to get "manual edit"
  7319. // behavior, i.e. prevent the combo-box from automatically updating the
  7320. // edit box at various times. We need this because the phone number
  7321. // comments are to be appended in the list, but not in the edit box.
  7322. // 'PInfo' is the dialog context.
  7323. //
  7324. // Returns 0 if successful or an error code.
  7325. //
  7326. {
  7327. DWORD dxOld;
  7328. // Find the edit window which is simply a child enumeration.
  7329. //
  7330. EnumChildWindows(
  7331. pInfo->hwndClbNumbers,
  7332. DrClbNumbersEnumChildProc,
  7333. (LPARAM)pInfo );
  7334. if (!pInfo->hwndClbNumbersEb)
  7335. {
  7336. return ERROR_NOT_FOUND;
  7337. }
  7338. // Find the list window which *sigh* doesn't show up in the child
  7339. // enumeration though it has WS_CHILD style because Windows sets it's
  7340. // parent window to NULL after it is created. To find it, we set the
  7341. // dropped width to an unusual bogus value, then search all windows for
  7342. // one with that width.
  7343. //
  7344. dxOld = (DWORD )SendMessage(
  7345. pInfo->hwndClbNumbers, CB_GETDROPPEDWIDTH, 0, 0 );
  7346. SendMessage( pInfo->hwndClbNumbers,
  7347. CB_SETDROPPEDWIDTH, (WPARAM )DR_BOGUSWIDTH, 0 );
  7348. EnumWindows( DrClbNumbersEnumWindowsProc, (LPARAM)pInfo );
  7349. SendMessage( pInfo->hwndClbNumbers,
  7350. CB_SETDROPPEDWIDTH, (WPARAM )dxOld, 0 );
  7351. if (!pInfo->hwndClbNumbersLb)
  7352. {
  7353. return ERROR_NOT_FOUND;
  7354. }
  7355. // Subclass the windows after associating the dialog context with them for
  7356. // retrieval in the WndProcs.
  7357. //
  7358. SetProp( pInfo->hwndClbNumbersEb, g_contextId, pInfo );
  7359. SetProp( pInfo->hwndClbNumbersLb, g_contextId, pInfo );
  7360. pInfo->wndprocClbNumbersEb =
  7361. (WNDPROC )SetWindowLongPtr(
  7362. pInfo->hwndClbNumbersEb,
  7363. GWLP_WNDPROC, (ULONG_PTR )DrClbNumbersEbWndProc );
  7364. pInfo->wndprocClbNumbersLb =
  7365. (WNDPROC )SetWindowLongPtr(
  7366. pInfo->hwndClbNumbersLb,
  7367. GWLP_WNDPROC, (ULONG_PTR )DrClbNumbersLbWndProc );
  7368. return 0;
  7369. }
  7370. void
  7371. DrEnsureNetshellLoaded (
  7372. IN DRINFO* pInfo)
  7373. {
  7374. // Load the netshell utilities interface. The interface is freed in PeTerm.
  7375. //
  7376. if (!pInfo->pNetConUtilities)
  7377. {
  7378. // Initialize the NetConnectionsUiUtilities
  7379. //
  7380. HrCreateNetConnectionUtilities( &pInfo->pNetConUtilities );
  7381. }
  7382. }
  7383. BOOL
  7384. DrInit(
  7385. IN HWND hwndDlg,
  7386. IN DRARGS* pArgs )
  7387. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
  7388. // 'PArgs' is caller's arguments to the stub API.
  7389. //
  7390. // Return false if focus was set, true otherwise, i.e. as defined for
  7391. // WM_INITDIALOG.
  7392. //
  7393. {
  7394. DWORD dwErr = NO_ERROR;
  7395. DRINFO* pInfo;
  7396. PBENTRY* pEntry;
  7397. BOOL fEnableProperties;
  7398. // For whistler bug 424209 gangz
  7399. //
  7400. BOOL fUseDefaultFocus = TRUE;
  7401. TRACE( "DrInit" );
  7402. // Allocate the dialog context block. Initialize minimally for proper
  7403. // cleanup, then attach to the dialog window.
  7404. //
  7405. {
  7406. pInfo = Malloc( sizeof(*pInfo) );
  7407. if (!pInfo)
  7408. {
  7409. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  7410. EndDialog( hwndDlg, FALSE );
  7411. return TRUE;
  7412. }
  7413. ZeroMemory( pInfo, sizeof(*pInfo) );
  7414. pInfo->pArgs = pArgs;
  7415. pInfo->hwndDlg = hwndDlg;
  7416. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  7417. TRACE( "Context set" );
  7418. }
  7419. pEntry = pArgs->pDinfo->pEntry;
  7420. pInfo->hwndBmDialer = GetDlgItem( hwndDlg, CID_DR_BM_Useless );
  7421. ASSERT( pInfo->hwndBmDialer );
  7422. // Look up control handles.
  7423. //
  7424. if ((pArgs->dwfMode & DR_U) ||
  7425. (pArgs->dwfMode & DR_I))
  7426. {
  7427. pInfo->hwndEbUser = GetDlgItem( hwndDlg, CID_DR_EB_User );
  7428. ASSERT( pInfo->hwndEbUser );
  7429. if (pArgs->dwfMode & DR_U)
  7430. {
  7431. pInfo->hwndEbPw = GetDlgItem( hwndDlg, CID_DR_EB_Password );
  7432. ASSERT( pInfo->hwndEbPw );
  7433. pInfo->hwndCbSavePw = GetDlgItem( hwndDlg, CID_DR_CB_SavePassword );
  7434. ASSERT( pInfo->hwndCbSavePw );
  7435. pInfo->hwndRbSaveForMe = GetDlgItem( hwndDlg, CID_DR_RB_SaveForMe );
  7436. ASSERT( pInfo->hwndRbSaveForMe );
  7437. pInfo->hwndRbSaveForEveryone =
  7438. GetDlgItem( hwndDlg, CID_DR_RB_SaveForEveryone );
  7439. ASSERT( pInfo->hwndRbSaveForEveryone );
  7440. }
  7441. if (pArgs->dwfMode & DR_D)
  7442. {
  7443. pInfo->hwndEbDomain = GetDlgItem( hwndDlg, CID_DR_EB_Domain );
  7444. ASSERT( pInfo->hwndEbDomain );
  7445. }
  7446. }
  7447. if (pArgs->dwfMode & DR_N)
  7448. {
  7449. pInfo->hwndClbNumbers = GetDlgItem( hwndDlg, CID_DR_CLB_Numbers );
  7450. ASSERT( pInfo->hwndClbNumbers );
  7451. if (pArgs->dwfMode & DR_L)
  7452. {
  7453. pInfo->hwndStLocations = GetDlgItem( hwndDlg, CID_DR_ST_Locations );
  7454. ASSERT( pInfo->hwndStLocations );
  7455. pInfo->hwndLbLocations = GetDlgItem( hwndDlg, CID_DR_LB_Locations );
  7456. ASSERT( pInfo->hwndLbLocations );
  7457. pInfo->hwndPbRules = GetDlgItem( hwndDlg, CID_DR_PB_Rules );
  7458. ASSERT( pInfo->hwndPbRules );
  7459. }
  7460. }
  7461. pInfo->hwndPbProperties = GetDlgItem( hwndDlg, CID_DR_PB_Properties );
  7462. ASSERT( pInfo->hwndPbProperties );
  7463. // In location-enabled mode, popup TAPI's "first location" dialog if they
  7464. // are uninitialized. Typically, this will do nothing.
  7465. //
  7466. if (pArgs->dwfMode & DR_L)
  7467. {
  7468. dwErr = TapiNoLocationDlg( g_hinstDll, &pInfo->hlineapp, hwndDlg );
  7469. if (dwErr != 0)
  7470. {
  7471. // Error here is treated as a "cancel" per bug 288385.
  7472. //
  7473. pArgs->pDinfo->pArgs->dwError = 0;
  7474. EndDialog( hwndDlg, FALSE );
  7475. return TRUE;
  7476. }
  7477. }
  7478. // Set the title.
  7479. //
  7480. {
  7481. TCHAR* pszTitleFormat;
  7482. TCHAR* pszTitle;
  7483. TCHAR* apszArgs[ 1 ];
  7484. if (pArgs->pDinfo->fUnattended)
  7485. {
  7486. pszTitleFormat = PszFromId( g_hinstDll, SID_DR_ReconnectTitle );
  7487. }
  7488. else
  7489. {
  7490. pszTitleFormat = GetText( hwndDlg );
  7491. }
  7492. if (pszTitleFormat)
  7493. {
  7494. apszArgs[ 0 ] = pEntry->pszEntryName;
  7495. pszTitle = NULL;
  7496. FormatMessage(
  7497. FORMAT_MESSAGE_FROM_STRING
  7498. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  7499. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  7500. pszTitleFormat, 0, 0, (LPTSTR )&pszTitle, 1,
  7501. (va_list* )apszArgs );
  7502. Free( pszTitleFormat );
  7503. if (pszTitle)
  7504. {
  7505. SetWindowText( hwndDlg, pszTitle );
  7506. LocalFree( pszTitle );
  7507. }
  7508. }
  7509. }
  7510. // Change the Dial button to Connect for non-phone devices.
  7511. //
  7512. if (pEntry->dwType != RASET_Phone)
  7513. {
  7514. TCHAR* psz;
  7515. psz = PszFromId( g_hinstDll, SID_ConnectButton );
  7516. if (psz)
  7517. {
  7518. SetWindowText( GetDlgItem( hwndDlg, CID_DR_PB_DialConnect ), psz );
  7519. Free( psz );
  7520. }
  7521. }
  7522. // Initialize credentials section.
  7523. //
  7524. if (pArgs->dwfMode & DR_U)
  7525. {
  7526. ASSERT( !pEntry->fAutoLogon );
  7527. // Fill credential fields with initial values.
  7528. //
  7529. Edit_LimitText( pInfo->hwndEbUser, UNLEN );
  7530. SetWindowText( pInfo->hwndEbUser, pArgs->pDinfo->rdp.szUserName );
  7531. Edit_LimitText( pInfo->hwndEbPw, PWLEN );
  7532. if (pArgs->dwfMode & DR_D)
  7533. {
  7534. Edit_LimitText( pInfo->hwndEbDomain, DNLEN );
  7535. SetWindowText( pInfo->hwndEbDomain, pArgs->pDinfo->rdp.szDomain );
  7536. }
  7537. if (pArgs->pDinfo->pNoUser || pArgs->pDinfo->fDisableSavePw)
  7538. {
  7539. // Can't stash password without a logon context, so hide the
  7540. // checkbox.
  7541. //
  7542. ASSERT( !HaveSavedPw( pArgs->pDinfo )) ;
  7543. EnableWindow( pInfo->hwndCbSavePw, FALSE );
  7544. EnableWindow( pInfo->hwndRbSaveForMe, FALSE );
  7545. EnableWindow( pInfo->hwndRbSaveForEveryone, FALSE );
  7546. // Whistler bug 400714 RAS does not grab password at winlogon time
  7547. // when Connect dialog is displayed
  7548. //
  7549. // Whistler bug 254385 encode password when not being used
  7550. // Assumed password was encoded previously
  7551. //
  7552. DecodePassword( pArgs->pDinfo->rdp.szPassword );
  7553. SetWindowText( pInfo->hwndEbPw, pArgs->pDinfo->rdp.szPassword );
  7554. EncodePassword( pArgs->pDinfo->rdp.szPassword );
  7555. }
  7556. else
  7557. {
  7558. // Whistler bug: 195480 Dial-up connection dialog - Number of
  7559. // asterisks does not match the length of the password and causes
  7560. // confusion
  7561. //
  7562. // Init the password character. Default to the round dot if we fail
  7563. // to get it.
  7564. //
  7565. pInfo->szPasswordChar = (WCHAR) SendMessage( pInfo->hwndEbPw,
  7566. EM_GETPASSWORDCHAR, 0, 0 );
  7567. if (!pInfo->szPasswordChar)
  7568. {
  7569. pInfo->szPasswordChar = 0x25CF;
  7570. }
  7571. // Init the fonts for the password field
  7572. //
  7573. DrGetFriendlyFont( hwndDlg, TRUE, &(pInfo->hItalicFont) );
  7574. DrGetFriendlyFont( hwndDlg, FALSE, &(pInfo->hNormalFont) );
  7575. // Check "save password" and render the type of saved
  7576. // password.
  7577. //
  7578. Button_SetCheck(
  7579. pInfo->hwndCbSavePw,
  7580. HaveSavedPw( pArgs->pDinfo ));
  7581. if ((!pArgs->pDinfo->fIsPublicPbk) ||
  7582. (!HaveSavedPw( pArgs->pDinfo )))
  7583. {
  7584. // If this is a for-me-only connection or if
  7585. // there is no saved password, then initialize the
  7586. // pw save type to save-for-me
  7587. //
  7588. Button_SetCheck( pInfo->hwndRbSaveForMe, TRUE );
  7589. }
  7590. else
  7591. {
  7592. // Check the appropriate radio button
  7593. // Note that a per-user password is always used if
  7594. // both a per-user and global password are saved.
  7595. // Dont check global password if its a per-user connectoid
  7596. //
  7597. Button_SetCheck(
  7598. (pArgs->pDinfo->fHaveSavedPwUser) ?
  7599. pInfo->hwndRbSaveForMe :
  7600. pInfo->hwndRbSaveForEveryone,
  7601. TRUE);
  7602. }
  7603. DrEnableDisablePwControls( pInfo, HaveSavedPw( pArgs->pDinfo ) );
  7604. // Whistler bug: 195480 Dial-up connection dialog - Number of
  7605. // asterisks does not match the length of the password and causes
  7606. // confusion
  7607. //
  7608. DrPopulatePasswordField( pInfo, TRUE, FALSE,
  7609. &fUseDefaultFocus);
  7610. }
  7611. }
  7612. if (pArgs->dwfMode & DR_N)
  7613. {
  7614. pInfo->pLinkNode = NULL;
  7615. if (pArgs->pDinfo->pArgs->dwSubEntry > 0)
  7616. {
  7617. // Look up the API caller specified link.
  7618. //
  7619. pInfo->pLinkNode =
  7620. DtlNodeFromIndex(
  7621. pArgs->pDinfo->pEntry->pdtllistLinks,
  7622. pArgs->pDinfo->pArgs->dwSubEntry - 1 );
  7623. }
  7624. if (!pInfo->pLinkNode)
  7625. {
  7626. // Look up the default (first) link.
  7627. //
  7628. pInfo->pLinkNode =
  7629. DtlGetFirstNode( pArgs->pDinfo->pEntry->pdtllistLinks );
  7630. }
  7631. ASSERT( pInfo->pLinkNode );
  7632. pInfo->pLink = (PBLINK* )DtlGetData( pInfo->pLinkNode );
  7633. dwErr = DrFindAndSubclassClbNumbersControls( pInfo );
  7634. if (dwErr != 0)
  7635. {
  7636. pArgs->pDinfo->pArgs->dwError = ERROR_NOT_FOUND;
  7637. EndDialog( hwndDlg, FALSE );
  7638. return TRUE;
  7639. }
  7640. // Ignore any "last selected" information when the "try next on fail"
  7641. // flag is set. New entries will not have "last selected" non-0 in
  7642. // this case but pre-existing entries might, so double-check here.
  7643. // See bug 150958.
  7644. //
  7645. if (pInfo->pLink->fTryNextAlternateOnFail)
  7646. {
  7647. pInfo->pLink->iLastSelectedPhone = 0;
  7648. }
  7649. // Record the initially selected phone number, used to determine
  7650. // whether user has changed the selection.
  7651. //
  7652. pInfo->iFirstSelectedPhone = pInfo->pLink->iLastSelectedPhone;
  7653. DrFillNumbersList( pInfo );
  7654. if (pArgs->dwfMode & DR_L)
  7655. {
  7656. DrFillLocationList( pInfo );
  7657. }
  7658. }
  7659. // danielwe: Bug #222744, scottbri Bug #245310
  7660. // Disable Properties... button if user does not have sufficent rights.
  7661. //
  7662. {
  7663. HRESULT hr;
  7664. hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
  7665. if (hr == RPC_E_CHANGED_MODE)
  7666. {
  7667. hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  7668. }
  7669. if (hr == S_OK || hr == S_FALSE)
  7670. {
  7671. pInfo->fComInitialized = TRUE;
  7672. }
  7673. }
  7674. fEnableProperties = FALSE;
  7675. DrEnsureNetshellLoaded (pInfo);
  7676. if (NULL != pInfo->pNetConUtilities)
  7677. {
  7678. //For whislter bug 409504 gangz
  7679. //for a VPN double dial scenario,if now it is in the prerequiste dial
  7680. //process, we should use DINFO->pEntryMain->pszPrerequisitePbk to check
  7681. //if it is a publicPhonebook
  7682. //
  7683. BOOL fAllUsers = TRUE;
  7684. if( pArgs->pDinfo->fPrerequisiteDial )
  7685. {
  7686. fAllUsers =
  7687. IsPublicPhonebook(pArgs->pDinfo->pEntryMain->pszPrerequisitePbk);
  7688. }
  7689. else
  7690. {
  7691. fAllUsers = IsPublicPhonebook(pArgs->pDinfo->pszPhonebook);
  7692. }
  7693. if (((fAllUsers && INetConnectionUiUtilities_UserHasPermission(
  7694. pInfo->pNetConUtilities,
  7695. NCPERM_RasAllUserProperties)) ||
  7696. (!fAllUsers && INetConnectionUiUtilities_UserHasPermission(
  7697. pInfo->pNetConUtilities,
  7698. NCPERM_RasMyProperties))) &&
  7699. (NULL == pArgs->pDinfo->pNoUser))
  7700. {
  7701. fEnableProperties = TRUE;
  7702. }
  7703. // We only needed it breifly, release it
  7704. INetConnectionUiUtilities_Release(pInfo->pNetConUtilities);
  7705. pInfo->pNetConUtilities = NULL;
  7706. }
  7707. // stevec: 267157-Allow access at win-login if admin enables.
  7708. //
  7709. if (NULL != pArgs->pDinfo->pNoUser
  7710. && pArgs->pDinfo->pUser->fAllowLogonPhonebookEdits)
  7711. {
  7712. fEnableProperties = TRUE;
  7713. }
  7714. EnableWindow( pInfo->hwndPbProperties, fEnableProperties );
  7715. // The help engine doesn't work at win-logon as it requires a user
  7716. // context, so disable the Help button in that case. See bug 343030.
  7717. //
  7718. if (pArgs->pDinfo->pNoUser)
  7719. {
  7720. HWND hwndPbHelp;
  7721. hwndPbHelp = GetDlgItem( hwndDlg, CID_DR_PB_Help );
  7722. ASSERT( hwndPbHelp );
  7723. EnableWindow( hwndPbHelp, FALSE );
  7724. ShowWindow( hwndPbHelp, SW_HIDE );
  7725. }
  7726. // Set the bitmap to the low res version if that is appropriate
  7727. //
  7728. // Ignore the error -- it is non-critical
  7729. //
  7730. DrSetBitmap(pInfo);
  7731. // Position the dialog per caller's instructions.
  7732. //
  7733. PositionDlg( hwndDlg,
  7734. !!(pArgs->pDinfo->pArgs->dwFlags & RASDDFLAG_PositionDlg),
  7735. pArgs->pDinfo->pArgs->xDlg, pArgs->pDinfo->pArgs->yDlg );
  7736. //Add this function for whislter bug 320863 gangz
  7737. //To adjust the bitmap's position and size
  7738. //
  7739. CenterExpandWindowRemainLeftMargin( pInfo->hwndBmDialer,
  7740. hwndDlg,
  7741. TRUE,
  7742. TRUE,
  7743. pInfo->hwndEbUser);
  7744. // Adjust the title bar widgets.
  7745. //
  7746. //TweakTitleBar( hwndDlg );
  7747. AddContextHelpButton( hwndDlg );
  7748. return fUseDefaultFocus;
  7749. }
  7750. VOID
  7751. DrLocationsSelChange(
  7752. IN DRINFO* pInfo )
  7753. // Called when a location is selected from the list. 'PInfo' is the
  7754. // dialog context.
  7755. //
  7756. {
  7757. DWORD dwErr;
  7758. DWORD dwLocationId;
  7759. TRACE("DuLocationChange");
  7760. // Set global TAPI location based on user's selection.
  7761. //
  7762. dwLocationId = (DWORD )ComboBox_GetItemData(
  7763. pInfo->hwndLbLocations, ComboBox_GetCurSel( pInfo->hwndLbLocations ) );
  7764. dwErr = SetCurrentLocation( g_hinstDll, &pInfo->hlineapp, dwLocationId );
  7765. if (dwErr != 0)
  7766. {
  7767. ErrorDlg( pInfo->hwndDlg, SID_OP_SaveTapiInfo, dwErr, NULL );
  7768. }
  7769. // Location change may cause changes in built numbers so re-fill the
  7770. // numbers combo-box.
  7771. //
  7772. DrFillNumbersList( pInfo );
  7773. }
  7774. VOID
  7775. DrNumbersSelChange(
  7776. IN DRINFO* pInfo )
  7777. // Called when a phone number is selected from the list. 'PInfo' is the
  7778. // dialog context.
  7779. //
  7780. {
  7781. INT iSel;
  7782. BOOL fEnable;
  7783. DRNUMBERSITEM* pItem;
  7784. iSel = ComboBox_GetCurSel( pInfo->hwndClbNumbers );
  7785. if (iSel >= 0)
  7786. {
  7787. if (iSel != (INT )pInfo->pLink->iLastSelectedPhone)
  7788. {
  7789. pInfo->pArgs->pDinfo->pEntry->fDirty = TRUE;
  7790. }
  7791. pInfo->pLink->iLastSelectedPhone = (DWORD )iSel;
  7792. }
  7793. pItem = (DRNUMBERSITEM* )ComboBox_GetItemDataPtr(
  7794. pInfo->hwndClbNumbers, iSel );
  7795. ASSERT( pItem );
  7796. if(NULL == pItem)
  7797. {
  7798. return;
  7799. }
  7800. // Enable/disable the location fields based on whether they are relevant
  7801. // to the selected number.
  7802. //
  7803. if (pInfo->pArgs->dwfMode & DR_L)
  7804. {
  7805. fEnable = pItem->pPhone->fUseDialingRules;
  7806. EnableWindow( pInfo->hwndStLocations, fEnable );
  7807. EnableWindow( pInfo->hwndLbLocations, fEnable );
  7808. EnableWindow( pInfo->hwndPbRules, fEnable );
  7809. }
  7810. DrSetClbNumbersText( pInfo, pItem->pszNumber );
  7811. }
  7812. DWORD
  7813. DrPopulateIdentificationFields(
  7814. IN DRINFO* pInfo,
  7815. IN BOOL fForMe )
  7816. // Updates the identification fields in the dialer
  7817. // UI according to whether the all-user or per-user
  7818. // dialparms should be used.
  7819. //
  7820. {
  7821. RASDIALPARAMS* prdp, *prdpOld;
  7822. BOOL fUpdate;
  7823. TCHAR pszUser[UNLEN + 1];
  7824. INT iCount;
  7825. prdp = (fForMe)
  7826. ? &(pInfo->pArgs->pDinfo->rdpu) : &(pInfo->pArgs->pDinfo->rdpg);
  7827. prdpOld = (fForMe)
  7828. ? &(pInfo->pArgs->pDinfo->rdpg) : &(pInfo->pArgs->pDinfo->rdpu);
  7829. iCount = GetWindowText(
  7830. pInfo->hwndEbUser,
  7831. pszUser,
  7832. UNLEN + 1);
  7833. if (iCount == 0)
  7834. {
  7835. fUpdate = TRUE;
  7836. }
  7837. else
  7838. {
  7839. if (lstrcmp(prdpOld->szUserName, pszUser) == 0)
  7840. {
  7841. fUpdate = TRUE;
  7842. }
  7843. else
  7844. {
  7845. fUpdate = FALSE;
  7846. }
  7847. }
  7848. if (fUpdate)
  7849. {
  7850. if (pInfo->hwndEbUser && *(prdp->szUserName))
  7851. {
  7852. SetWindowText(pInfo->hwndEbUser, prdp->szUserName);
  7853. }
  7854. if (pInfo->hwndEbDomain && *(prdp->szDomain))
  7855. {
  7856. SetWindowText(pInfo->hwndEbDomain, prdp->szDomain);
  7857. }
  7858. }
  7859. return NO_ERROR;
  7860. }
  7861. DWORD
  7862. DrPopulatePasswordField(
  7863. IN DRINFO* pInfo,
  7864. IN BOOL fInit,
  7865. IN BOOL fDisable,
  7866. OUT BOOL * pfUseDefaultFocus)
  7867. {
  7868. BOOL fSave, fMeOnly;
  7869. TCHAR* pszFriendly = NULL;
  7870. // Whistler bug: 195480 Dial-up connection dialog - Number of asterisks
  7871. // does not match the length of the password and causes confusion
  7872. //
  7873. // Case 1. The user has clicked on the password field. We clear the
  7874. // friendly password and set the font back to normal.
  7875. //
  7876. if(NULL != pfUseDefaultFocus )
  7877. {
  7878. *pfUseDefaultFocus = TRUE;
  7879. }
  7880. if (fDisable)
  7881. {
  7882. DrClearFriendlyPassword( pInfo, TRUE );
  7883. return NO_ERROR;
  7884. }
  7885. // Initialze
  7886. //
  7887. fSave = Button_GetCheck( pInfo->hwndCbSavePw );
  7888. fMeOnly = Button_GetCheck( pInfo->hwndRbSaveForMe );
  7889. pszFriendly = PszFromId( g_hinstDll, SID_SavePasswordFrndly );
  7890. // Case 2. Clear the password field if the user a) choose not to save the
  7891. // password and b) has not manually entered a password.
  7892. //
  7893. if ( (!fSave) && !DrIsPasswordStyleEnabled( pInfo->hwndEbPw ) )
  7894. {
  7895. DrClearFriendlyPassword( pInfo, FALSE );
  7896. }
  7897. // Case 3. Show the friendly saved password text if the user a) choose to
  7898. // save the password of himself only and b) there is a per-user password
  7899. // saved and c) the user has not entered a password manually.
  7900. //
  7901. else if ( (fSave) && (fMeOnly) &&
  7902. ((fInit) || ( !DrIsPasswordStyleEnabled( pInfo->hwndEbPw ))) )
  7903. {
  7904. // Whistler bug: 288234 When switching back and forth from
  7905. // "I connect" and "Any user connects" password is not
  7906. // caching correctly
  7907. //
  7908. if (pInfo->pArgs->pDinfo->fHaveSavedPwUser)
  7909. {
  7910. DrDisplayFriendlyPassword(pInfo, pszFriendly );
  7911. }
  7912. else
  7913. {
  7914. DrClearFriendlyPassword( pInfo, FALSE );
  7915. }
  7916. }
  7917. // Case 4. Show the friendly saved password text if the user a) choose to
  7918. // save the password for everyone and b) there is a default password saved
  7919. // and c) the user has not entered a password manually.
  7920. //
  7921. else if ( (fSave) && (!fMeOnly) &&
  7922. ((fInit) || ( !DrIsPasswordStyleEnabled( pInfo->hwndEbPw ))) )
  7923. {
  7924. if (pInfo->pArgs->pDinfo->fHaveSavedPwGlobal)
  7925. {
  7926. DrDisplayFriendlyPassword( pInfo, pszFriendly );
  7927. }
  7928. else
  7929. {
  7930. DrClearFriendlyPassword( pInfo, FALSE );
  7931. }
  7932. }
  7933. // Case 5. Show the friendly saved password text if the user a) choose to
  7934. // save the password for everyone or himself and b) there is a
  7935. // corresponding password saved and c) the user has not entered a password
  7936. // manually.
  7937. //
  7938. // This case catches a) when the user is switching between "me" and
  7939. // "everyone" and b) when the user leaves the focus of the password field
  7940. // but hasn't changed the password
  7941. //
  7942. else if ( (fSave) && !GetWindowTextLength( pInfo->hwndEbPw ) &&
  7943. DrIsPasswordStyleEnabled( pInfo->hwndEbPw ) &&
  7944. ((pInfo->pArgs->pDinfo->fHaveSavedPwGlobal && !fMeOnly) ||
  7945. (pInfo->pArgs->pDinfo->fHaveSavedPwUser && fMeOnly)) )
  7946. {
  7947. DrDisplayFriendlyPassword( pInfo, pszFriendly );
  7948. }
  7949. // NT5 bug: 215432, Whistler bug: 364341
  7950. //
  7951. // Whistler bug: 195480 Dial-up connection dialog - Number of asterisks
  7952. // does not match the length of the password and causes confusion
  7953. //
  7954. // Set focus appropiately
  7955. //
  7956. if (fInit)
  7957. {
  7958. if (!GetWindowTextLength( pInfo->hwndEbUser ))
  7959. {
  7960. SetFocus( pInfo->hwndEbUser );
  7961. }
  7962. else if (!GetWindowTextLength( pInfo->hwndEbPw ))
  7963. {
  7964. SetFocus( pInfo->hwndEbPw );
  7965. // This removes the tab stop property from the username field. This
  7966. // is a hack so we can set the focus properly. Tab stop is put back
  7967. // in DrCommand.
  7968. //
  7969. /*
  7970. SetWindowLong( pInfo->hwndEbUser, GWL_STYLE,
  7971. GetWindowLong( pInfo->hwndEbUser, GWL_STYLE ) & ~WS_TABSTOP );
  7972. */
  7973. // For whistler bug 424209 gangz
  7974. // Dont hack the WS_TABSTOP attribute, just let DrInit() return
  7975. // false to indicate that we set the focus ourself
  7976. //
  7977. if( NULL != pfUseDefaultFocus )
  7978. {
  7979. *pfUseDefaultFocus = FALSE;
  7980. }
  7981. }
  7982. else
  7983. {
  7984. SetFocus( pInfo->hwndEbUser );
  7985. }
  7986. }
  7987. // Clean up
  7988. //
  7989. Free0( pszFriendly );
  7990. return NO_ERROR;
  7991. }
  7992. VOID
  7993. DrProperties(
  7994. IN DRINFO* pInfo )
  7995. // Called when the Properties button is pressed. 'PInfo' is the dialog
  7996. // context.
  7997. //
  7998. {
  7999. BOOL fOk;
  8000. RASENTRYDLG info;
  8001. INTERNALARGS iargs;
  8002. DINFO* pDinfo;
  8003. // First, save any entry related changes user has made on the dial dialog.
  8004. //
  8005. DrSave( pInfo );
  8006. // Set up for parameters for call to RasEntryDlg.
  8007. //
  8008. ZeroMemory( &info, sizeof(info) );
  8009. info.dwSize = sizeof(info);
  8010. info.hwndOwner = pInfo->hwndDlg;
  8011. {
  8012. RECT rect;
  8013. info.dwFlags = RASEDFLAG_PositionDlg;
  8014. GetWindowRect( pInfo->hwndDlg, &rect );
  8015. info.xDlg = rect.left + DXSHEET;
  8016. info.yDlg = rect.top + DYSHEET;
  8017. }
  8018. // The secret hack to share information already loaded with the entry API.
  8019. //
  8020. pDinfo = pInfo->pArgs->pDinfo;
  8021. ZeroMemory( &iargs, sizeof(iargs) );
  8022. iargs.pFile = pDinfo->pFile;
  8023. iargs.pUser = pDinfo->pUser;
  8024. iargs.pNoUser = pDinfo->pNoUser;
  8025. iargs.fNoUser = !!(pDinfo->pNoUser);
  8026. //For whislter bug 234515 set fDisableFirstConnect to be FALSE
  8027. //
  8028. iargs.fDisableFirstConnect = FALSE;
  8029. info.reserved = (ULONG_PTR )&iargs;
  8030. TRACE( "RasEntryDlg" );
  8031. fOk = RasEntryDlg(
  8032. pDinfo->pszPhonebook, pDinfo->pEntry->pszEntryName, &info );
  8033. TRACE1( "RasEntryDlg=%d", fOk );
  8034. if (fOk)
  8035. {
  8036. DWORD dwErr;
  8037. // Reload when user presses OK on properties since that may change the
  8038. // appearance and content of this dialog. Must first reset the DINFO
  8039. // context parameters based on the replaced PBENTRY from the property
  8040. // sheet.
  8041. //
  8042. dwErr = FindEntryAndSetDialParams( pInfo->pArgs->pDinfo );
  8043. if (dwErr != 0)
  8044. {
  8045. // Should not happen.
  8046. //
  8047. EndDialog( pInfo->hwndDlg, FALSE );
  8048. }
  8049. pInfo->pArgs->fReload = TRUE;
  8050. EndDialog( pInfo->hwndDlg, FALSE );
  8051. }
  8052. }
  8053. VOID
  8054. DrSave(
  8055. IN DRINFO* pInfo )
  8056. // Saves dialog field contents to RASDIALPARAMS, and if appropriate to LSA
  8057. // secret area or NOUSER output argument. 'PInfo' is the dialog context.
  8058. //
  8059. {
  8060. DWORD dwErr;
  8061. RASDIALPARAMS* prdp;
  8062. RASCREDENTIALS rc;
  8063. DINFO* pDinfo;
  8064. pDinfo = pInfo->pArgs->pDinfo;
  8065. if ((pInfo->pArgs->dwfMode & DR_U) ||
  8066. (pInfo->pArgs->dwfMode & DR_I))
  8067. {
  8068. // Save credentials into parameter block to be passed to RasDial.
  8069. //
  8070. prdp = &pDinfo->rdp;
  8071. GetWindowText( pInfo->hwndEbUser, prdp->szUserName, UNLEN + 1 );
  8072. if (pInfo->pArgs->dwfMode & DR_U)
  8073. {
  8074. // Whistler bug 254385 encode password when not being used
  8075. // Assumed password was not encoded by GetWindowText()
  8076. //
  8077. // Whistler bug: 195480 Dial-up connection dialog - Number of
  8078. // asterisks does not match the length of the password and causes
  8079. // confusion
  8080. //
  8081. if (!DrIsPasswordStyleEnabled( pInfo->hwndEbPw ))
  8082. {
  8083. lstrcpyn( prdp->szPassword, g_pszSavedPasswordToken,
  8084. g_dwSavedPasswordTokenLength );
  8085. }
  8086. else
  8087. {
  8088. GetWindowText( pInfo->hwndEbPw, prdp->szPassword, PWLEN + 1 );
  8089. }
  8090. SetWindowText( pInfo->hwndEbPw, L"" );
  8091. EncodePassword( prdp->szPassword );
  8092. }
  8093. if (pInfo->pArgs->dwfMode & DR_D)
  8094. {
  8095. GetWindowText( pInfo->hwndEbDomain, prdp->szDomain, DNLEN + 1 );
  8096. }
  8097. ZeroMemory( &rc, sizeof(rc) );
  8098. rc.dwSize = sizeof(rc);
  8099. lstrcpyn( rc.szUserName, prdp->szUserName, UNLEN + 1 );
  8100. // Whistler bug 254385 encode password when not being used
  8101. // Assumed password was encoded previously
  8102. //
  8103. DecodePassword( prdp->szPassword );
  8104. lstrcpyn( rc.szPassword, prdp->szPassword, PWLEN + 1 );
  8105. EncodePassword( prdp->szPassword );
  8106. lstrcpyn( rc.szDomain, prdp->szDomain, DNLEN + 1);
  8107. if (pDinfo->pNoUser)
  8108. {
  8109. // Save credentials into output block for return to caller,
  8110. // typically WinLogon.
  8111. //
  8112. lstrcpyn( pDinfo->pNoUser->szUserName, rc.szUserName, UNLEN + 1 );
  8113. // Whistler bug 254385 encode password when not being used
  8114. // Assumed password was not encoded previously
  8115. //
  8116. lstrcpyn( pDinfo->pNoUser->szPassword, rc.szPassword, PWLEN + 1 );
  8117. EncodePassword( pDinfo->pNoUser->szPassword );
  8118. lstrcpyn( pDinfo->pNoUser->szDomain, rc.szDomain, DNLEN + 1 );
  8119. *(pDinfo->pfNoUserChanged) = TRUE;
  8120. }
  8121. else if (pInfo->pArgs->dwfMode & DR_I)
  8122. {
  8123. // Nothing to do
  8124. }
  8125. else if (!pDinfo->fDisableSavePw)
  8126. {
  8127. BOOL fGlobalCreds = FALSE;
  8128. ASSERT( g_pRasSetCredentials );
  8129. if (Button_GetCheck( pInfo->hwndCbSavePw ))
  8130. {
  8131. rc.dwMask = 0;
  8132. // If the user elected to save the credentials for
  8133. // everybody, then clear any previously saved per-user
  8134. // credentials
  8135. //
  8136. fGlobalCreds = Button_GetCheck( pInfo->hwndRbSaveForEveryone );
  8137. if( (fGlobalCreds)
  8138. && IsPublicPhonebook(pDinfo->pFile->pszPath))
  8139. {
  8140. DeleteSavedCredentials(
  8141. pDinfo,
  8142. pInfo->hwndDlg,
  8143. FALSE,
  8144. TRUE );
  8145. pDinfo->fHaveSavedPwUser = FALSE;
  8146. rc.dwMask = RASCM_DefaultCreds;
  8147. }
  8148. // If there is currently no saved per-user password and the user
  8149. // opts to save the password himself, then ask whetehr the global
  8150. // password should be deleted if it exists.
  8151. //
  8152. else if (pDinfo->fHaveSavedPwGlobal && !pDinfo->fHaveSavedPwUser)
  8153. {
  8154. MSGARGS msgargs;
  8155. ZeroMemory( &msgargs, sizeof(msgargs) );
  8156. msgargs.dwFlags = MB_ICONQUESTION | MB_YESNO;
  8157. // Delete the default credentials if the user answers yes
  8158. //
  8159. if (IDYES ==
  8160. MsgDlg(pInfo->hwndDlg, SID_DR_GlobalPassword, &msgargs))
  8161. {
  8162. DeleteSavedCredentials(
  8163. pDinfo,
  8164. pInfo->hwndDlg,
  8165. TRUE,
  8166. TRUE );
  8167. pDinfo->fHaveSavedPwGlobal = FALSE;
  8168. }
  8169. }
  8170. // User chose to save password. Cache username, password, and
  8171. // domain.
  8172. //
  8173. rc.dwMask |= RASCM_UserName |
  8174. RASCM_Password | RASCM_Domain;
  8175. TRACE( "RasSetCredentials(u|p|d,FALSE)" );
  8176. dwErr = g_pRasSetCredentials(
  8177. pDinfo->pFile->pszPath, pDinfo->pEntry->pszEntryName,
  8178. &rc, FALSE );
  8179. TRACE1( "RasSetCredentials=%d", dwErr );
  8180. if (dwErr != 0)
  8181. {
  8182. ErrorDlg( pInfo->hwndDlg, SID_OP_CachePw, dwErr, NULL );
  8183. }
  8184. else
  8185. {
  8186. if (fGlobalCreds)
  8187. {
  8188. pDinfo->fHaveSavedPwGlobal = TRUE;
  8189. }
  8190. else
  8191. {
  8192. // Whistler bug: 288234 When switching back and forth
  8193. // from "I connect" and "Any user connects" password is
  8194. // not caching correctly
  8195. //
  8196. pDinfo->fHaveSavedPwUser = TRUE;
  8197. }
  8198. }
  8199. }
  8200. else
  8201. {
  8202. // Delete the global credentials.
  8203. //
  8204. // Note that we have to delete the global identity
  8205. // as well because we do not support deleting
  8206. // just the global password. This is so that
  8207. // RasSetCredentials can emulate RasSetDialParams.
  8208. //
  8209. DeleteSavedCredentials(
  8210. pDinfo,
  8211. pInfo->hwndDlg,
  8212. TRUE,
  8213. TRUE );
  8214. // Delete the password saved per-user. Keep the user name
  8215. // and domain saved, however.
  8216. //
  8217. DeleteSavedCredentials(
  8218. pDinfo,
  8219. pInfo->hwndDlg,
  8220. FALSE,
  8221. FALSE );
  8222. pDinfo->fHaveSavedPwUser = FALSE;
  8223. pDinfo->fHaveSavedPwGlobal = FALSE;
  8224. }
  8225. }
  8226. RtlSecureZeroMemory( rc.szPassword, sizeof(rc.szPassword) );
  8227. }
  8228. if (pInfo->pArgs->dwfMode & DR_N)
  8229. {
  8230. TCHAR* pszNumber;
  8231. TCHAR* pszOriginal;
  8232. DTLNODE* pPhoneNode;
  8233. DRNUMBERSITEM* pItem;
  8234. PBPHONE* pPhone;
  8235. BOOL fUserChange;
  8236. pszNumber = GetText( pInfo->hwndClbNumbers );
  8237. if (!pszNumber)
  8238. {
  8239. return;
  8240. }
  8241. pItem = (DRNUMBERSITEM* )ComboBox_GetItemDataPtr(
  8242. pInfo->hwndClbNumbers, pInfo->pLink->iLastSelectedPhone );
  8243. if (pItem)
  8244. {
  8245. pszOriginal = pItem->pszNumber;
  8246. }
  8247. else
  8248. {
  8249. pszOriginal = TEXT("");
  8250. }
  8251. if (lstrcmp( pszNumber, pszOriginal ) != 0
  8252. || (pInfo->pLink->iLastSelectedPhone != pInfo->iFirstSelectedPhone))
  8253. {
  8254. MSGARGS msgargs;
  8255. BOOL fMultiLink;
  8256. BOOL fSingleNumber;
  8257. // The phone number was edited by user to something not originally
  8258. // on the list OR the user selected a different item on the list.
  8259. //
  8260. fSingleNumber = (DtlGetNodes( pInfo->pLink->pdtllistPhones ) == 1);
  8261. fMultiLink = (DtlGetNodes( pDinfo->pEntry->pdtllistLinks ) > 1);
  8262. ZeroMemory( &msgargs, sizeof(msgargs) );
  8263. msgargs.dwFlags = MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2;
  8264. if (fSingleNumber
  8265. && (!fMultiLink || pDinfo->pEntry->fSharedPhoneNumbers)
  8266. && MsgDlg( pInfo->hwndDlg,
  8267. SID_SavePreview, &msgargs ) == IDYES)
  8268. {
  8269. // User says he wants to make the change permanent.
  8270. //
  8271. pDinfo->pEntry->fDirty = TRUE;
  8272. if (pItem)
  8273. {
  8274. pPhone = pItem->pPhone;
  8275. Free0( pItem->pszNumber );
  8276. pItem->pszNumber = StrDup( pszNumber );
  8277. }
  8278. else
  8279. {
  8280. pPhoneNode = CreatePhoneNode();
  8281. if (pPhoneNode)
  8282. {
  8283. DtlAddNodeFirst(
  8284. pInfo->pLink->pdtllistPhones, pPhoneNode );
  8285. pPhone = (PBPHONE* )DtlGetData( pPhoneNode );
  8286. }
  8287. }
  8288. if (pItem)
  8289. {
  8290. ASSERT( pItem->pPhone );
  8291. Free0( pPhone->pszPhoneNumber );
  8292. pPhone->pszPhoneNumber = StrDup( pszNumber );
  8293. pPhone->fUseDialingRules = FALSE;
  8294. if (fMultiLink)
  8295. {
  8296. DTLNODE* pNode;
  8297. for (pNode = DtlGetFirstNode(
  8298. pDinfo->pEntry->pdtllistLinks );
  8299. pNode;
  8300. pNode = DtlGetNextNode( pNode ))
  8301. {
  8302. PBLINK* pLink = (PBLINK* )DtlGetData( pNode );
  8303. ASSERT( pLink );
  8304. ASSERT( pLink->fEnabled );
  8305. CopyLinkPhoneNumberInfo( pNode, pInfo->pLinkNode );
  8306. }
  8307. }
  8308. }
  8309. }
  8310. fUserChange = TRUE;
  8311. }
  8312. else
  8313. {
  8314. fUserChange = FALSE;
  8315. }
  8316. if (fUserChange || !pInfo->pLink->fTryNextAlternateOnFail)
  8317. {
  8318. if (!*pszNumber)
  8319. {
  8320. TCHAR* psz;
  8321. // We have a problem when user edits in an empty string,
  8322. // because the RasDial API does not accept an empty override
  8323. // phone number. Convert it to a single blank string in this
  8324. // case, which is as good as we can do. If user really needs
  8325. // to dial an empty string they can enter one as the entry's
  8326. // permanent phone number. See bug 179561.
  8327. //
  8328. psz = StrDup( TEXT(" ") );
  8329. if (psz)
  8330. {
  8331. Free( pszNumber );
  8332. pszNumber = psz;
  8333. }
  8334. }
  8335. // Set the override phone number to what user typed or selected.
  8336. //
  8337. lstrcpyn(
  8338. pDinfo->rdp.szPhoneNumber,
  8339. pszNumber,
  8340. RAS_MaxPhoneNumber + 1);
  8341. }
  8342. Free( pszNumber );
  8343. }
  8344. if (pDinfo->pEntry->fDirty)
  8345. {
  8346. // Write the new phone number and/or "last selected phone number" to
  8347. // the phonebook.
  8348. //
  8349. dwErr = WritePhonebookFile( pDinfo->pFile, NULL );
  8350. if (dwErr != 0)
  8351. {
  8352. ErrorDlg( pInfo->hwndDlg, SID_OP_WritePhonebook, dwErr, NULL );
  8353. }
  8354. }
  8355. }
  8356. DWORD
  8357. DrSetBitmap(
  8358. IN DRINFO* pInfo)
  8359. // Set the appropriate bitmap for this dialer.
  8360. //
  8361. {
  8362. DWORD dwErr = NO_ERROR;
  8363. HBITMAP hbmNew = NULL;
  8364. HDC hdc = NULL;
  8365. INT iDepth = 0;
  8366. do
  8367. {
  8368. if (pInfo->hwndBmDialer == NULL)
  8369. {
  8370. dwErr = ERROR_CAN_NOT_COMPLETE;
  8371. break;
  8372. }
  8373. // Get the device context for the window
  8374. //
  8375. hdc = GetDC( pInfo->hwndBmDialer );
  8376. if (hdc == NULL)
  8377. {
  8378. dwErr = GetLastError();
  8379. break;
  8380. }
  8381. // If the color depth >= 8bit, the current bitmap
  8382. // is fine (high res is default)
  8383. //
  8384. iDepth = GetDeviceCaps(hdc, NUMCOLORS);
  8385. if ( (iDepth == -1) || (iDepth == 256) )
  8386. {
  8387. dwErr = NO_ERROR;
  8388. break;
  8389. }
  8390. // Load in the low-res bitmap
  8391. //
  8392. hbmNew = LoadBitmap(g_hinstDll, MAKEINTRESOURCE( BID_Dialer ));
  8393. if (hbmNew == NULL)
  8394. {
  8395. dwErr = GetLastError();
  8396. break;
  8397. }
  8398. // Set the low-res bitmap
  8399. //
  8400. pInfo->hbmOrig = (HBITMAP)
  8401. SendMessage(
  8402. pInfo->hwndBmDialer,
  8403. STM_SETIMAGE,
  8404. IMAGE_BITMAP,
  8405. (LPARAM )hbmNew );
  8406. } while (FALSE);
  8407. // Cleanup
  8408. //
  8409. {
  8410. if (hdc)
  8411. {
  8412. ReleaseDC(pInfo->hwndBmDialer, hdc);
  8413. }
  8414. }
  8415. return dwErr;
  8416. }
  8417. VOID
  8418. DrSetClbNumbersText(
  8419. IN DRINFO* pInfo,
  8420. IN TCHAR* pszText )
  8421. // Set the text of the 'ClbNumbers' edit box to 'pszText'. See
  8422. // DrClbNumbersEbWndProc. 'PInfo' is the dialog context.
  8423. //
  8424. {
  8425. ASSERT( pInfo->hwndClbNumbersEb );
  8426. SendMessage( pInfo->hwndClbNumbersEb, DR_WM_SETTEXT, 0, (LPARAM )pszText );
  8427. }
  8428. VOID
  8429. DrTerm(
  8430. IN HWND hwndDlg )
  8431. // Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
  8432. //
  8433. {
  8434. DRINFO* pInfo = (DRINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  8435. HBITMAP hbmNew = NULL;
  8436. TRACE( "DrTerm" );
  8437. if (pInfo)
  8438. {
  8439. // Note: Don't use 'pInfo->pLinkNode' or 'pInfo->pLink' here as they
  8440. // are not currently restored prior to exit for post-Property
  8441. // button reloading.
  8442. //
  8443. if (pInfo->hwndClbNumbers)
  8444. {
  8445. DrFreeClbNumbers( pInfo );
  8446. if (pInfo->wndprocClbNumbersEb)
  8447. {
  8448. SetWindowLongPtr( pInfo->hwndClbNumbersEb,
  8449. GWLP_WNDPROC, (ULONG_PTR )pInfo->wndprocClbNumbersEb );
  8450. }
  8451. if (pInfo->wndprocClbNumbersLb)
  8452. {
  8453. SetWindowLongPtr( pInfo->hwndClbNumbersLb,
  8454. GWLP_WNDPROC, (ULONG_PTR )pInfo->wndprocClbNumbersLb );
  8455. }
  8456. }
  8457. // Whistler bug: 195480 Dial-up connection dialog - Number of
  8458. // asterisks does not match the length of the password and causes
  8459. // confusion
  8460. //
  8461. if (pInfo->hItalicFont)
  8462. {
  8463. DeleteObject( pInfo->hItalicFont );
  8464. }
  8465. if (pInfo->hNormalFont)
  8466. {
  8467. DeleteObject( pInfo->hNormalFont );
  8468. }
  8469. if (pInfo->fComInitialized)
  8470. {
  8471. CoUninitialize();
  8472. }
  8473. // Clean up the low-res bitmap if appropriate
  8474. //
  8475. if ( pInfo->hbmOrig )
  8476. {
  8477. hbmNew = (HBITMAP)
  8478. SendMessage(
  8479. pInfo->hwndBmDialer,
  8480. STM_SETIMAGE,
  8481. IMAGE_BITMAP,
  8482. (LPARAM ) pInfo->hbmOrig );
  8483. if (hbmNew)
  8484. {
  8485. DeleteObject(hbmNew);
  8486. }
  8487. }
  8488. Free( pInfo );
  8489. pInfo = NULL;
  8490. }
  8491. }
  8492. //----------------------------------------------------------------------------
  8493. // Projection Result dialog
  8494. // Listed alphabetically following stub API and dialog proc
  8495. //----------------------------------------------------------------------------
  8496. BOOL
  8497. ProjectionResultDlg(
  8498. IN HWND hwndOwner,
  8499. IN TCHAR* pszLines,
  8500. OUT BOOL* pfDisableFailedProtocols )
  8501. // Popup the Projection Result dialog. 'HwndOwner' is the owning window.
  8502. // 'PszLines' is the status line text to display. See DpProjectionError.
  8503. // 'DwfDisableFailedProtocols' indicates user chose to disable the failed
  8504. // protocols.
  8505. //
  8506. // Returns true if user chooses to redial or lets it timeout, false if
  8507. // cancels.
  8508. //
  8509. {
  8510. INT_PTR nStatus;
  8511. PRARGS args;
  8512. TRACE( "ProjectionResultDlg" );
  8513. args.pszLines = pszLines;
  8514. args.pfDisableFailedProtocols = pfDisableFailedProtocols;
  8515. nStatus =
  8516. DialogBoxParam(
  8517. g_hinstDll,
  8518. MAKEINTRESOURCE( DID_PR_ProjectionResult ),
  8519. hwndOwner,
  8520. PrDlgProc,
  8521. (LPARAM )&args );
  8522. if (nStatus == -1)
  8523. {
  8524. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  8525. nStatus = FALSE;
  8526. }
  8527. return (nStatus) ? TRUE : FALSE;
  8528. }
  8529. INT_PTR CALLBACK
  8530. PrDlgProc(
  8531. IN HWND hwnd,
  8532. IN UINT unMsg,
  8533. IN WPARAM wparam,
  8534. IN LPARAM lparam )
  8535. // DialogProc callback for the Projection Result dialog. Parameters and
  8536. // return value are as described for standard windows 'DialogProc's.
  8537. //
  8538. {
  8539. #if 0
  8540. TRACE4( "PrDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  8541. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  8542. #endif
  8543. switch (unMsg)
  8544. {
  8545. case WM_INITDIALOG:
  8546. {
  8547. return PrInit( hwnd, (PRARGS* )lparam );
  8548. }
  8549. case WM_HELP:
  8550. case WM_CONTEXTMENU:
  8551. {
  8552. ContextHelp( g_adwPrHelp, hwnd, unMsg, wparam, lparam );
  8553. break;
  8554. }
  8555. case WM_COMMAND:
  8556. {
  8557. return PrCommand(
  8558. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  8559. }
  8560. }
  8561. return FALSE;
  8562. }
  8563. BOOL
  8564. PrCommand(
  8565. IN HWND hwnd,
  8566. IN WORD wNotification,
  8567. IN WORD wId,
  8568. IN HWND hwndCtrl )
  8569. // Called on WM_COMMAND. 'Hwnd' is the dialog window. 'WNotification' is
  8570. // the notification code of the command. 'wId' is the control/menu
  8571. // identifier of the command. 'HwndCtrl' is the control window handle of
  8572. // the command.
  8573. //
  8574. // Returns true if processed message, false otherwise.
  8575. //
  8576. {
  8577. DWORD dwErr;
  8578. TRACE3( "PrCommand(n=%d,i=%d,c=$%x)",
  8579. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  8580. switch (wId)
  8581. {
  8582. case IDOK:
  8583. case IDCANCEL:
  8584. {
  8585. BOOL fCb;
  8586. BOOL* pfDisable;
  8587. TRACE1( "%s pressed", (wId==IDOK) ? "OK" : "Cancel" );
  8588. fCb = IsDlgButtonChecked( hwnd, CID_PR_CB_DisableProtocols );
  8589. pfDisable = (BOOL* )GetWindowLongPtr( hwnd, DWLP_USER );
  8590. ASSERT( pfDisable );
  8591. *pfDisable = fCb;
  8592. EndDialog( hwnd, (wId == IDOK) );
  8593. return TRUE;
  8594. }
  8595. }
  8596. return FALSE;
  8597. }
  8598. BOOL
  8599. PrInit(
  8600. IN HWND hwndDlg,
  8601. IN PRARGS* pArgs )
  8602. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
  8603. // 'PArgs' is caller's arguments to the stub API.
  8604. //
  8605. // Return false if focus was set, true otherwise, i.e. as defined for
  8606. // WM_INITDIALOG.
  8607. //
  8608. {
  8609. DWORD dwErr;
  8610. HWND hwndStText;
  8611. HWND hwndPbAccept;
  8612. HWND hwndPbHangUp;
  8613. HWND hwndCbDisable;
  8614. TRACE( "PrInit" );
  8615. hwndStText = GetDlgItem( hwndDlg, CID_PR_ST_Text );
  8616. ASSERT( hwndStText );
  8617. hwndPbAccept = GetDlgItem( hwndDlg, IDOK );
  8618. ASSERT( hwndPbAccept );
  8619. hwndPbHangUp = GetDlgItem( hwndDlg, IDCANCEL );
  8620. ASSERT( hwndPbHangUp );
  8621. hwndCbDisable = GetDlgItem( hwndDlg, CID_PR_CB_DisableProtocols );
  8622. ASSERT( hwndCbDisable );
  8623. {
  8624. TCHAR szBuf[ 1024 ];
  8625. TCHAR* psz;
  8626. // Build the message text.
  8627. //
  8628. szBuf[ 0 ] = TEXT('\0');
  8629. psz = PszFromId( g_hinstDll, SID_ProjectionResult1 );
  8630. if (psz)
  8631. {
  8632. lstrcat( szBuf, psz );
  8633. Free( psz );
  8634. }
  8635. lstrcat( szBuf, pArgs->pszLines );
  8636. psz = PszFromId( g_hinstDll, SID_ProjectionResult2 );
  8637. if (psz)
  8638. {
  8639. lstrcat( szBuf, psz );
  8640. Free( psz );
  8641. }
  8642. // Load the text into the static control, then stretch the window to a
  8643. // vertical size appropriate for the text.
  8644. //
  8645. {
  8646. HDC hdc;
  8647. RECT rect;
  8648. RECT rectNew;
  8649. HFONT hfont;
  8650. LONG dyGrow;
  8651. SetWindowText( hwndStText, szBuf );
  8652. GetClientRect( hwndStText, &rect );
  8653. hdc = GetDC( hwndStText );
  8654. if(NULL != hdc)
  8655. {
  8656. hfont = (HFONT )SendMessage( hwndStText, WM_GETFONT, 0, 0 );
  8657. if (hfont)
  8658. SelectObject( hdc, hfont );
  8659. rectNew = rect;
  8660. DrawText( hdc, szBuf, -1, &rectNew,
  8661. DT_CALCRECT | DT_WORDBREAK | DT_EXPANDTABS | DT_NOPREFIX );
  8662. ReleaseDC( hwndStText, hdc );
  8663. }
  8664. dyGrow = rectNew.bottom - rect.bottom;
  8665. ExpandWindow( hwndDlg, 0, dyGrow );
  8666. ExpandWindow( hwndStText, 0, dyGrow );
  8667. SlideWindow( hwndPbAccept, hwndDlg, 0, dyGrow );
  8668. SlideWindow( hwndPbHangUp, hwndDlg, 0, dyGrow );
  8669. SlideWindow( hwndCbDisable, hwndDlg, 0, dyGrow );
  8670. }
  8671. }
  8672. // Save address of caller's BOOL as the dialog context.
  8673. //
  8674. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pArgs->pfDisableFailedProtocols );
  8675. // Add context help button to title bar.
  8676. //
  8677. AddContextHelpButton( hwndDlg );
  8678. // Display the finished window above all other windows. The window
  8679. // position is set to "topmost" then immediately set to "not topmost"
  8680. // because we want it on top but not always-on-top. Always-on-top alone
  8681. // is incredibly annoying, e.g. it is always on top of the on-line help if
  8682. // user presses the Help button.
  8683. //
  8684. SetWindowPos(
  8685. hwndDlg, HWND_TOPMOST, 0, 0, 0, 0,
  8686. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
  8687. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  8688. ShowWindow( hwndDlg, SW_SHOW );
  8689. SetWindowPos(
  8690. hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
  8691. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
  8692. return TRUE;
  8693. }
  8694. //----------------------------------------------------------------------------
  8695. // Retry Authentication dialog
  8696. // Listed alphabetically following stub API and dialog proc
  8697. //----------------------------------------------------------------------------
  8698. BOOL
  8699. RetryAuthenticationDlg(
  8700. IN HWND hwndOwner,
  8701. IN DINFO* pDinfo )
  8702. // Pops up the retry authentication dialog. 'PDinfo' is the dial dialog
  8703. // common context.
  8704. //
  8705. // Returns true if user presses OK, false if Cancel or an error occurs.
  8706. //
  8707. {
  8708. INT_PTR nStatus;
  8709. TRACE( "RetryAuthenticationDlg" );
  8710. nStatus =
  8711. (BOOL )DialogBoxParam(
  8712. g_hinstDll,
  8713. MAKEINTRESOURCE( DID_UA_RetryAuthenticationUD ),
  8714. hwndOwner,
  8715. UaDlgProc,
  8716. (LPARAM )pDinfo );
  8717. if (nStatus == -1)
  8718. {
  8719. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  8720. nStatus = FALSE;
  8721. }
  8722. return (BOOL )nStatus;
  8723. }
  8724. INT_PTR CALLBACK
  8725. UaDlgProc(
  8726. IN HWND hwnd,
  8727. IN UINT unMsg,
  8728. IN WPARAM wparam,
  8729. IN LPARAM lparam )
  8730. // DialogProc callback for the User Authentication dialog. Parameters and
  8731. // return value are as described for standard windows 'DialogProc's.
  8732. //
  8733. {
  8734. #if 0
  8735. TRACE4( "UaDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  8736. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  8737. #endif
  8738. switch (unMsg)
  8739. {
  8740. case WM_INITDIALOG:
  8741. {
  8742. return UaInit( hwnd, (DINFO* )lparam );
  8743. }
  8744. case WM_HELP:
  8745. case WM_CONTEXTMENU:
  8746. {
  8747. ContextHelp( g_adwUaHelp, hwnd, unMsg, wparam, lparam );
  8748. break;
  8749. }
  8750. case WM_COMMAND:
  8751. {
  8752. UAINFO* pInfo = (UAINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  8753. if (!pInfo)
  8754. {
  8755. // This happened in stress one night. Don't understand how
  8756. // unless it was a WinUser bug or something. Anyhow, this
  8757. // avoids an AV in such case.
  8758. //
  8759. break;
  8760. }
  8761. return UaCommand(
  8762. pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  8763. }
  8764. case WM_DESTROY:
  8765. {
  8766. UaTerm( hwnd );
  8767. break;
  8768. }
  8769. }
  8770. return FALSE;
  8771. }
  8772. BOOL
  8773. UaCommand(
  8774. IN UAINFO* pInfo,
  8775. IN WORD wNotification,
  8776. IN WORD wId,
  8777. IN HWND hwndCtrl )
  8778. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  8779. // is the notification code of the command. 'wId' is the control/menu
  8780. // identifier of the command. 'HwndCtrl' is the control window handle of
  8781. // the command.
  8782. //
  8783. // Returns true if processed message, false otherwise.
  8784. //
  8785. {
  8786. TRACE3( "UaCommand(n=%d,i=%d,c=$%x)",
  8787. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  8788. switch (wId)
  8789. {
  8790. case CID_UA_EB_UserName:
  8791. {
  8792. if (pInfo->fAutoLogonPassword && wNotification == EN_CHANGE)
  8793. {
  8794. // User's changing the username in auto-logon retry mode,
  8795. // which means we have to admit we don't really have the text
  8796. // password and force him to re-enter it.
  8797. //
  8798. pInfo->fAutoLogonPassword = FALSE;
  8799. SetWindowText( pInfo->hwndEbPassword, TEXT("") );
  8800. }
  8801. break;
  8802. }
  8803. case CID_UA_EB_Password:
  8804. {
  8805. if (wNotification == EN_CHANGE)
  8806. {
  8807. pInfo->fAutoLogonPassword = FALSE;
  8808. }
  8809. break;
  8810. }
  8811. case IDOK:
  8812. {
  8813. UaSave( pInfo );
  8814. EndDialog( pInfo->hwndDlg, TRUE );
  8815. return TRUE;
  8816. }
  8817. case IDCANCEL:
  8818. {
  8819. TRACE( "Cancel pressed" );
  8820. EndDialog( pInfo->hwndDlg, FALSE );
  8821. return TRUE;
  8822. }
  8823. }
  8824. return FALSE;
  8825. }
  8826. BOOL
  8827. UaInit(
  8828. IN HWND hwndDlg,
  8829. IN DINFO* pArgs )
  8830. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
  8831. // 'PArgs' is caller's arguments as passed to the stub API.
  8832. //
  8833. // Return false if focus was set, true otherwise, i.e. as defined for
  8834. // WM_INITDIALOG.
  8835. //
  8836. {
  8837. DWORD dwErr;
  8838. UAINFO* pInfo;
  8839. PBENTRY* pEntry;
  8840. TRACE( "UaInit" );
  8841. // Allocate the dialog context block. Initialize minimally for proper
  8842. // cleanup, then attach to the dialog window.
  8843. //
  8844. {
  8845. pInfo = Malloc( sizeof(*pInfo) );
  8846. if (!pInfo)
  8847. {
  8848. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  8849. EndDialog( hwndDlg, FALSE );
  8850. return TRUE;
  8851. }
  8852. ZeroMemory( pInfo, sizeof(*pInfo) );
  8853. pInfo->pArgs = pArgs;
  8854. pInfo->hwndDlg = hwndDlg;
  8855. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  8856. TRACE( "Context set" );
  8857. }
  8858. pInfo->fDomain = TRUE;
  8859. pInfo->hwndEbUserName = GetDlgItem( hwndDlg, CID_UA_EB_UserName );
  8860. ASSERT( pInfo->hwndEbUserName );
  8861. pInfo->hwndEbPassword = GetDlgItem( hwndDlg, CID_UA_EB_Password );
  8862. ASSERT( pInfo->hwndEbPassword );
  8863. if (pInfo->fDomain)
  8864. {
  8865. pInfo->hwndEbDomain = GetDlgItem( hwndDlg, CID_UA_EB_Domain );
  8866. ASSERT( pInfo->hwndEbDomain );
  8867. }
  8868. pInfo->hwndCbSavePw = GetDlgItem( hwndDlg, CID_UA_CB_SavePassword );
  8869. ASSERT( pInfo->hwndCbSavePw );
  8870. pEntry = pArgs->pEntry;
  8871. // Set the title.
  8872. //
  8873. {
  8874. TCHAR* pszTitleFormat;
  8875. TCHAR* pszTitle;
  8876. TCHAR* apszArgs[ 1 ];
  8877. pszTitleFormat = GetText( hwndDlg );
  8878. if (pszTitleFormat)
  8879. {
  8880. apszArgs[ 0 ] = pEntry->pszEntryName;
  8881. pszTitle = NULL;
  8882. FormatMessage(
  8883. FORMAT_MESSAGE_FROM_STRING
  8884. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  8885. | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  8886. pszTitleFormat, 0, 0, (LPTSTR )&pszTitle, 1,
  8887. (va_list* )apszArgs );
  8888. Free( pszTitleFormat );
  8889. if (pszTitle)
  8890. {
  8891. SetWindowText( hwndDlg, pszTitle );
  8892. LocalFree( pszTitle );
  8893. }
  8894. }
  8895. }
  8896. // Fill edit fields with initial values.
  8897. //
  8898. Edit_LimitText( pInfo->hwndEbUserName, UNLEN );
  8899. Edit_LimitText( pInfo->hwndEbPassword, PWLEN );
  8900. if (pInfo->fDomain)
  8901. {
  8902. Edit_LimitText( pInfo->hwndEbDomain, DNLEN );
  8903. }
  8904. {
  8905. BOOL fUserNameSet = FALSE;
  8906. BOOL fPasswordSet = FALSE;
  8907. if (pEntry->fAutoLogon && !pInfo->pArgs->pNoUser)
  8908. {
  8909. // On the first retry use the logged on user's name. Act like the
  8910. // user's password is in the edit box. If he changes the username
  8911. // or password we'll have to admit we don't have it, but he'll
  8912. // probably just change the domain.
  8913. //
  8914. if (pArgs->rdp.szUserName[ 0 ] == TEXT('\0'))
  8915. {
  8916. SetWindowText( pInfo->hwndEbUserName, GetLogonUser() );
  8917. fUserNameSet = TRUE;
  8918. }
  8919. if (pArgs->rdp.szPassword[ 0 ] == TEXT('\0'))
  8920. {
  8921. SetWindowText( pInfo->hwndEbPassword, TEXT("********") );
  8922. pInfo->fAutoLogonPassword = TRUE;
  8923. fPasswordSet = TRUE;
  8924. }
  8925. }
  8926. if (!fUserNameSet)
  8927. {
  8928. SetWindowText( pInfo->hwndEbUserName, pArgs->rdp.szUserName );
  8929. }
  8930. if (!fPasswordSet)
  8931. {
  8932. // Whistler bug 254385 encode password when not being used
  8933. // Assumed password was encoded previously
  8934. //
  8935. DecodePassword( pArgs->rdp.szPassword );
  8936. SetWindowText( pInfo->hwndEbPassword, pArgs->rdp.szPassword );
  8937. EncodePassword( pArgs->rdp.szPassword );
  8938. }
  8939. if (pInfo->fDomain)
  8940. {
  8941. SetWindowText( pInfo->hwndEbDomain, pArgs->rdp.szDomain );
  8942. }
  8943. }
  8944. if (pArgs->pNoUser || pArgs->fDisableSavePw)
  8945. {
  8946. // Can't stash password without a logon context, so hide the checkbox.
  8947. //
  8948. ASSERT( !HaveSavedPw( pArgs ) );
  8949. EnableWindow( pInfo->hwndCbSavePw, FALSE );
  8950. ShowWindow( pInfo->hwndCbSavePw, SW_HIDE );
  8951. }
  8952. else
  8953. {
  8954. // Check "save password" if a password was previously cached. Maybe
  8955. // he changed the password while on the LAN.
  8956. //
  8957. Button_SetCheck( pInfo->hwndCbSavePw, HaveSavedPw( pArgs ) );
  8958. }
  8959. // Position the dialog per caller's instructions.
  8960. //
  8961. PositionDlg( hwndDlg,
  8962. (pArgs->pArgs->dwFlags & RASDDFLAG_PositionDlg),
  8963. pArgs->pArgs->xDlg, pArgs->pArgs->yDlg );
  8964. SetForegroundWindow( hwndDlg );
  8965. // Add context help button to title bar.
  8966. //
  8967. AddContextHelpButton( hwndDlg );
  8968. // Set focus to the empty username or empty password, or if both are
  8969. // present to the domain if auto-logon or the password if not.
  8970. //
  8971. if (Edit_GetTextLength( pInfo->hwndEbUserName ) == 0)
  8972. {
  8973. Edit_SetSel( pInfo->hwndEbUserName, 0, -1 );
  8974. SetFocus( pInfo->hwndEbUserName );
  8975. }
  8976. else if (Edit_GetTextLength( pInfo->hwndEbPassword ) == 0
  8977. || !pEntry->fAutoLogon
  8978. || !pInfo->fDomain)
  8979. {
  8980. Edit_SetSel( pInfo->hwndEbPassword, 0, -1 );
  8981. SetFocus( pInfo->hwndEbPassword );
  8982. }
  8983. else
  8984. {
  8985. ASSERT( pInfo->fDomain );
  8986. Edit_SetSel( pInfo->hwndEbDomain, 0, -1 );
  8987. SetFocus( pInfo->hwndEbDomain );
  8988. }
  8989. // Hide the Dial Progress dialog.
  8990. //
  8991. SetOffDesktop( GetParent( hwndDlg ), SOD_MoveOff, NULL );
  8992. return FALSE;
  8993. }
  8994. VOID
  8995. UaSave(
  8996. IN UAINFO* pInfo )
  8997. // Called when the OK button is pressed.
  8998. //
  8999. // Returns true if user presses OK, false if Cancel or an error occurs.
  9000. //
  9001. {
  9002. DWORD dwErr;
  9003. PBENTRY* pEntry;
  9004. BOOL fSavePw;
  9005. RASDIALPARAMS* prdp;
  9006. RASCREDENTIALS rc;
  9007. TRACE( "UaSave" );
  9008. prdp = &pInfo->pArgs->rdp;
  9009. GetWindowText( pInfo->hwndEbUserName, prdp->szUserName, UNLEN + 1 );
  9010. // Whistler bug 254385 encode password when not being used
  9011. // Assumed password was not encoded by GetWindowText()
  9012. //
  9013. GetWindowText( pInfo->hwndEbPassword, prdp->szPassword, PWLEN + 1 );
  9014. EncodePassword( prdp->szPassword );
  9015. if (pInfo->fDomain)
  9016. {
  9017. GetWindowText( pInfo->hwndEbDomain, prdp->szDomain, DNLEN + 1 );
  9018. //
  9019. //if the Domain is not empty, set the "include Windows Logon Domain check box on Option Tab"
  9020. // for bug 167229 whistler
  9021. //
  9022. if ( ( 0 < lstrlen ( prdp->szDomain ) ) && (!pInfo->pArgs->pEntry->fPreviewDomain ))
  9023. {
  9024. pInfo->pArgs->pEntry->fPreviewDomain = TRUE;
  9025. pInfo->pArgs->pEntry->fDirty = TRUE;
  9026. dwErr = WritePhonebookFile( pInfo->pArgs->pFile, NULL );
  9027. if (dwErr != 0)
  9028. {
  9029. ErrorDlg( pInfo->hwndDlg, SID_OP_WritePhonebook, dwErr, NULL );
  9030. }
  9031. }
  9032. }
  9033. pEntry = pInfo->pArgs->pEntry;
  9034. if (pEntry->fAutoLogon && !pInfo->pArgs->pNoUser)
  9035. {
  9036. if (pInfo->fAutoLogonPassword)
  9037. {
  9038. // User did not change username or password, so continue to
  9039. // retrieve logon username and password credentials.
  9040. //
  9041. TRACE( "Retain auto-logon" );
  9042. prdp->szUserName[ 0 ] = TEXT('\0');
  9043. prdp->szPassword[ 0 ] = TEXT('\0');
  9044. }
  9045. else
  9046. {
  9047. // User changed username and/or password so we can no longer
  9048. // retrieve the logon username and password credentials from the
  9049. // system. Switch the entry to non-auto-logon mode.
  9050. //
  9051. TRACE( "Disable auto-logon" );
  9052. pEntry->fAutoLogon = FALSE;
  9053. pInfo->pArgs->fResetAutoLogon = TRUE;
  9054. }
  9055. }
  9056. ZeroMemory( &rc, sizeof(rc) );
  9057. rc.dwSize = sizeof(rc);
  9058. lstrcpyn( rc.szUserName, prdp->szUserName, UNLEN + 1 );
  9059. // Whistler bug 254385 encode password when not being used
  9060. // Assumed password was encoded previously
  9061. //
  9062. DecodePassword( prdp->szPassword );
  9063. lstrcpyn( rc.szPassword, prdp->szPassword, PWLEN + 1 );
  9064. EncodePassword( prdp->szPassword );
  9065. lstrcpyn( rc.szDomain, prdp->szDomain, DNLEN + 1 );
  9066. if (pInfo->pArgs->pNoUser)
  9067. {
  9068. lstrcpyn( pInfo->pArgs->pNoUser->szUserName, rc.szUserName, UNLEN + 1 );
  9069. // Whistler bug 254385 encode password when not being used
  9070. // Assumed password was not encoded previously
  9071. //
  9072. lstrcpyn( pInfo->pArgs->pNoUser->szPassword, rc.szPassword, PWLEN + 1 );
  9073. EncodePassword( pInfo->pArgs->pNoUser->szPassword );
  9074. lstrcpyn( pInfo->pArgs->pNoUser->szDomain, rc.szDomain, DNLEN + 1 );
  9075. *pInfo->pArgs->pfNoUserChanged = TRUE;
  9076. }
  9077. else if (!pInfo->pArgs->fDisableSavePw)
  9078. {
  9079. ASSERT( g_pRasSetCredentials );
  9080. if (Button_GetCheck( pInfo->hwndCbSavePw ))
  9081. {
  9082. // User chose "save password". Cache username, password, and
  9083. // domain.
  9084. //
  9085. rc.dwMask = RASCM_UserName | RASCM_Password | RASCM_Domain;
  9086. // Whistler bug: 288234 When switching back and forth from
  9087. // "I connect" and "Any user connects" password is not
  9088. // caching correctly
  9089. //
  9090. if( (pInfo->pArgs->fHaveSavedPwGlobal)
  9091. && !pInfo->pArgs->fHaveSavedPwUser
  9092. && IsPublicPhonebook(pInfo->pArgs->pFile->pszPath))
  9093. {
  9094. rc.dwMask |= RASCM_DefaultCreds;
  9095. }
  9096. TRACE( "RasSetCredentials(u|p|d,FALSE)" );
  9097. dwErr = g_pRasSetCredentials(
  9098. pInfo->pArgs->pFile->pszPath,
  9099. pInfo->pArgs->pEntry->pszEntryName,
  9100. &rc, FALSE );
  9101. TRACE1( "RasSetCredentials=%d", dwErr );
  9102. if (dwErr != 0)
  9103. {
  9104. ErrorDlg( pInfo->hwndDlg, SID_OP_CachePw, dwErr, NULL );
  9105. }
  9106. }
  9107. else
  9108. {
  9109. // Whistler bug: 288234 When switching back and forth from
  9110. // "I connect" and "Any user connects" password is not
  9111. // caching correctly
  9112. //
  9113. // User chose not to save password; Cache username and domain only
  9114. //
  9115. rc.dwMask = RASCM_UserName | RASCM_Domain;
  9116. TRACE( "RasSetCredentials(u|d,FALSE)" );
  9117. dwErr = g_pRasSetCredentials(
  9118. pInfo->pArgs->pFile->pszPath,
  9119. pInfo->pArgs->pEntry->pszEntryName,
  9120. &rc, FALSE );
  9121. TRACE1( "RasSetCredentials=%d", dwErr );
  9122. if (dwErr != 0)
  9123. {
  9124. ErrorDlg( pInfo->hwndDlg, SID_OP_UncachePw, dwErr, NULL );
  9125. }
  9126. // Whistler bug: 288234 When switching back and forth from
  9127. // "I connect" and "Any user connects" password is not
  9128. // caching correctly
  9129. //
  9130. // Delete the password saved per-user; Keep the user name
  9131. // and domain saved, however.
  9132. //
  9133. if (pInfo->pArgs->fHaveSavedPwUser)
  9134. {
  9135. DeleteSavedCredentials(
  9136. pInfo->pArgs,
  9137. pInfo->hwndDlg,
  9138. FALSE,
  9139. FALSE );
  9140. pInfo->pArgs->fHaveSavedPwUser = FALSE;
  9141. }
  9142. // Delete the global credentials.
  9143. //
  9144. // Note that we have to delete the global identity
  9145. // as well because we do not support deleting
  9146. // just the global password. This is so that
  9147. // RasSetCredentials can emulate RasSetDialParams.
  9148. //
  9149. else if (pInfo->pArgs->fHaveSavedPwGlobal)
  9150. {
  9151. DeleteSavedCredentials(
  9152. pInfo->pArgs,
  9153. pInfo->hwndDlg,
  9154. TRUE,
  9155. TRUE );
  9156. pInfo->pArgs->fHaveSavedPwGlobal = FALSE;
  9157. }
  9158. }
  9159. }
  9160. RtlSecureZeroMemory( rc.szPassword, sizeof(rc.szPassword) );
  9161. }
  9162. VOID
  9163. UaTerm(
  9164. IN HWND hwndDlg )
  9165. // Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
  9166. //
  9167. {
  9168. UAINFO* pInfo = (UAINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  9169. TRACE( "UaTerm" );
  9170. if (pInfo)
  9171. {
  9172. // Restore the Dial Progress dialog.
  9173. //
  9174. SetOffDesktop( GetParent( hwndDlg ), SOD_MoveBackFree, NULL );
  9175. Free( pInfo );
  9176. pInfo = NULL;
  9177. }
  9178. }
  9179. //----------------------------------------------------------------------------
  9180. // VPN Double Dial help dialog
  9181. // Listed alphabetically following stub API and dialog proc
  9182. //----------------------------------------------------------------------------
  9183. BOOL
  9184. VpnDoubleDialDlg(
  9185. IN HWND hwndOwner,
  9186. IN DINFO* pInfo )
  9187. // Popup the VPN double dial help dialog. 'HwndOwner' is the owning
  9188. // window. 'PInfo' is the dialing context information.
  9189. //
  9190. // Returns false if user sees the dialog and decides not to continue, true
  9191. // otherwise.
  9192. //
  9193. {
  9194. INT_PTR nStatus;
  9195. TRACE( "VpnDoubleDialDlg" );
  9196. if (pInfo->pEntryMain->dwType != RASET_Vpn
  9197. || !pInfo->fPrerequisiteDial
  9198. || pInfo->pEntryMain->fSkipDoubleDialDialog)
  9199. {
  9200. return TRUE;
  9201. }
  9202. nStatus =
  9203. (BOOL )DialogBoxParam(
  9204. g_hinstDll,
  9205. MAKEINTRESOURCE( DID_VI_VpnInitial ),
  9206. hwndOwner,
  9207. ViDlgProc,
  9208. (LPARAM )pInfo );
  9209. if (nStatus == -1)
  9210. {
  9211. nStatus = FALSE;
  9212. }
  9213. return !!(nStatus);
  9214. }
  9215. INT_PTR CALLBACK
  9216. ViDlgProc(
  9217. IN HWND hwnd,
  9218. IN UINT unMsg,
  9219. IN WPARAM wparam,
  9220. IN LPARAM lparam )
  9221. // DialogProc callback for the dialog. Parameters and return value are as
  9222. // described for standard windows 'DialogProc's.
  9223. //
  9224. {
  9225. #if 0
  9226. TRACE4( "ViDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  9227. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  9228. #endif
  9229. switch (unMsg)
  9230. {
  9231. case WM_INITDIALOG:
  9232. {
  9233. return ViInit( hwnd, (DINFO* )lparam );
  9234. }
  9235. case WM_COMMAND:
  9236. {
  9237. return ViCommand(
  9238. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  9239. }
  9240. }
  9241. return FALSE;
  9242. }
  9243. BOOL
  9244. ViCommand(
  9245. IN HWND hwnd,
  9246. IN WORD wNotification,
  9247. IN WORD wId,
  9248. IN HWND hwndCtrl )
  9249. // Called on WM_COMMAND. 'Hwnd' is the dialog window. 'WNotification' is
  9250. // the notification code of the command. 'wId' is the control/menu
  9251. // identifier of the command. 'HwndCtrl' is the control window handle of
  9252. // the command.
  9253. //
  9254. // Returns true if processed message, false otherwise.
  9255. //
  9256. {
  9257. TRACE3( "ViCommand(n=%d,i=%d,c=$%x)",
  9258. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  9259. switch (wId)
  9260. {
  9261. case IDYES:
  9262. case IDNO:
  9263. {
  9264. // Per bug 261955, the box setting is saved when either the Yes or
  9265. // No, but not the 'X' button, is pressed.
  9266. //
  9267. DINFO* pInfo = (DINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  9268. ASSERT( pInfo );
  9269. if (IsDlgButtonChecked( hwnd, CID_VI_CB_SkipMessage ))
  9270. {
  9271. pInfo->pEntryMain->fSkipDoubleDialDialog = TRUE;
  9272. pInfo->pEntryMain->fDirty = TRUE;
  9273. WritePhonebookFile( pInfo->pFileMain, NULL );
  9274. }
  9275. EndDialog( hwnd, (wId == IDYES) );
  9276. return TRUE;
  9277. }
  9278. case IDCANCEL:
  9279. {
  9280. EndDialog( hwnd, FALSE );
  9281. return TRUE;
  9282. }
  9283. }
  9284. return FALSE;
  9285. }
  9286. BOOL
  9287. ViInit(
  9288. IN HWND hwndDlg,
  9289. IN DINFO* pInfo )
  9290. // Called on WM_INITDIALOG. 'HwndDlg' is the handle of dialog. 'PUser'
  9291. // is caller's argument to the stub API.
  9292. //
  9293. // Return false if focus was set, true otherwise, i.e. as defined for
  9294. // WM_INITDIALOG.
  9295. //
  9296. {
  9297. TRACE( "ViInit" );
  9298. // Set the dialog context.
  9299. //
  9300. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  9301. // Set the explanatory text.
  9302. //
  9303. {
  9304. MSGARGS msgargs;
  9305. ZeroMemory( &msgargs, sizeof(msgargs) );
  9306. msgargs.apszArgs[ 0 ] = pInfo->pEntryMain->pszEntryName;
  9307. msgargs.apszArgs[ 1 ] = pInfo->pEntry->pszEntryName;
  9308. msgargs.fStringOutput = TRUE;
  9309. MsgDlgUtil( NULL, SID_VI_ST_Explain, &msgargs, g_hinstDll, 0 );
  9310. if (msgargs.pszOutput)
  9311. {
  9312. SetDlgItemText( hwndDlg, CID_VI_ST_Explain, msgargs.pszOutput );
  9313. Free( msgargs.pszOutput );
  9314. }
  9315. }
  9316. // Display finished window.
  9317. //
  9318. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  9319. SetForegroundWindow( hwndDlg );
  9320. return TRUE;
  9321. }
  9322. DWORD
  9323. DwTerminalDlg(
  9324. LPCWSTR lpszPhonebook,
  9325. LPCWSTR lpszEntry,
  9326. RASDIALPARAMS *prdp,
  9327. HWND hwndOwner,
  9328. HRASCONN hRasconn)
  9329. {
  9330. DWORD dwErr = ERROR_SUCCESS;
  9331. PBENTRY *pEntry = NULL;
  9332. PBFILE pbfile;
  9333. DTLNODE *pNode = NULL;
  9334. WCHAR szIpAddress[ TERM_IpAddress ];
  9335. DWORD sidTitle;
  9336. WCHAR *pszIpAddress;
  9337. //
  9338. //Initialize memory for Whistler bug 160888
  9339. //
  9340. ZeroMemory(&pbfile, sizeof(PBFILE));
  9341. pbfile.hrasfile = -1;
  9342. dwErr = LoadRas( g_hinstDll, hwndOwner );
  9343. if (ERROR_SUCCESS != dwErr)
  9344. {
  9345. goto done;
  9346. }
  9347. dwErr = GetPbkAndEntryName(
  9348. lpszPhonebook,
  9349. lpszEntry,
  9350. 0,
  9351. &pbfile,
  9352. &pNode);
  9353. if( (NULL == pNode)
  9354. || (ERROR_SUCCESS != dwErr))
  9355. {
  9356. dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
  9357. goto done;
  9358. }
  9359. pEntry = (PBENTRY *) DtlGetData(pNode);
  9360. ASSERT(NULL != pEntry);
  9361. if(NULL == pEntry)
  9362. {
  9363. goto done;
  9364. }
  9365. if (pEntry->dwBaseProtocol == BP_Slip)
  9366. {
  9367. lstrcpyn(
  9368. szIpAddress,
  9369. (pEntry->pszIpAddress) ? pEntry->pszIpAddress : TEXT("0.0.0.0"),
  9370. sizeof(szIpAddress) / sizeof(TCHAR));
  9371. pszIpAddress = szIpAddress;
  9372. sidTitle = SID_T_SlipTerminal;
  9373. }
  9374. else
  9375. {
  9376. szIpAddress[0] = TEXT('\0');
  9377. pszIpAddress = szIpAddress;
  9378. sidTitle = SID_T_PostconnectTerminal;
  9379. }
  9380. if (!TerminalDlg(
  9381. pEntry, prdp, hwndOwner,
  9382. hRasconn, sidTitle, pszIpAddress ))
  9383. {
  9384. TRACE( "TerminalDlg==FALSE" );
  9385. dwErr = E_FAIL;
  9386. goto done;
  9387. }
  9388. TRACE2( "pszIpAddress=0x%08x(%ls)", pszIpAddress,
  9389. pszIpAddress ? pszIpAddress : TEXT("") );
  9390. TRACE2( "pEntry->pszIpAddress=0x%08x(%ls)", pEntry->pszIpAddress,
  9391. pEntry->pszIpAddress ? pEntry->pszIpAddress : TEXT("") );
  9392. if (pszIpAddress[0]
  9393. && (!pEntry->pszIpAddress
  9394. || lstrcmp( pszIpAddress, pEntry->pszIpAddress ) != 0))
  9395. {
  9396. Free0( pEntry->pszIpAddress );
  9397. pEntry->pszIpAddress = StrDup( szIpAddress );
  9398. pEntry->fDirty = TRUE;
  9399. dwErr = WritePhonebookFile( &pbfile, NULL );
  9400. if (dwErr != 0)
  9401. {
  9402. ErrorDlg( hwndOwner, SID_OP_WritePhonebook, dwErr, NULL );
  9403. }
  9404. }
  9405. done:
  9406. ClosePhonebookFile(&pbfile);
  9407. return dwErr;
  9408. }