Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2157 lines
53 KiB

  1. // Copyright (c) 1995, Microsoft Corporation, all rights reserved
  2. //
  3. // pbook.c
  4. // Remote Access Common Dialog APIs
  5. // RasPhonebookDlg APIs
  6. //
  7. // 06/20/95 Steve Cobb
  8. #include "rasdlgp.h" // Our private header
  9. #include <commdlg.h> // FileOpen dialog
  10. #include <dlgs.h> // Common dialog resource constants
  11. #include <rnk.h> // Shortcut file library
  12. #define WM_RASEVENT (WM_USER+987)
  13. #define WM_NOUSERTIMEOUT (WM_USER+988)
  14. #define RAS_SC_IS_BAD_PIN(_err) \
  15. (((_err) == SCARD_W_WRONG_CHV) || ((_err) == SCARD_E_INVALID_CHV))
  16. // In no-user mode this is updated on every mouse or keyboard event by our
  17. // window hook. The monitor thread notices and resets it's inactivity
  18. // timeout.
  19. //
  20. DWORD g_cInput = 0;
  21. //----------------------------------------------------------------------------
  22. // Help maps
  23. //----------------------------------------------------------------------------
  24. static DWORD g_adwDuHelp[] =
  25. {
  26. CID_DU_ST_Entries, HID_DU_LB_Entries,
  27. CID_DU_LB_Entries, HID_DU_LB_Entries,
  28. CID_DU_PB_New, HID_DU_PB_New,
  29. CID_DU_PB_More, HID_DU_PB_More,
  30. CID_DU_PB_Dial, HID_DU_PB_Dial,
  31. CID_DU_PB_Close, HID_DU_PB_Close,
  32. 0, 0
  33. };
  34. //----------------------------------------------------------------------------
  35. // Local datatypes
  36. //----------------------------------------------------------------------------
  37. // Phonebook dialog argument block.
  38. //
  39. typedef struct
  40. _DUARGS
  41. {
  42. // Caller's arguments to the RAS API. Outputs in 'pApiArgs' are visible
  43. // to the API which has the address of same. 'PszPhonebook' is updated if
  44. // user changes the phonebook on the Preferences->PhoneList page, though
  45. // API is unaware of this.
  46. //
  47. LPTSTR pszPhonebook;
  48. LPTSTR pszEntry;
  49. RASPBDLG* pApiArgs;
  50. // RAS API return value. Set true if a connection is established within
  51. // the dialog.
  52. //
  53. BOOL fApiResult;
  54. }
  55. DUARGS;
  56. typedef struct
  57. _DUCONTEXT
  58. {
  59. LPTSTR pszPhonebookPath;
  60. PBENTRY *pEntry;
  61. }
  62. DUCONTEXT;
  63. // Dial-Up Networking dialog context block.
  64. //
  65. typedef struct
  66. _DUINFO
  67. {
  68. // Caller's arguments to the RAS API.
  69. //
  70. DUARGS* pArgs;
  71. // Handle of this dialog and some of it's controls.
  72. //
  73. HWND hwndDlg;
  74. HWND hwndPbNew;
  75. HWND hwndPbProperties;
  76. HWND hwndLbEntries;
  77. HWND hwndPbDial;
  78. // Global user preference settings read from the Registry.
  79. //
  80. PBUSER user;
  81. // Phonebook settings read from the phonebook file.
  82. //
  83. PBFILE file;
  84. // No logged on user information retrieved via callback.
  85. //
  86. RASNOUSER* pNoUser;
  87. // Set if in "no user before logon" mode. Always the same as the
  88. // RASPBDFLAG but here for convenience.
  89. //
  90. BOOL fNoUser;
  91. // Window hooks used to detect user input in the thread. Used only when
  92. // 'fNoUser' is set.
  93. //
  94. HHOOK hhookKeyboard;
  95. HHOOK hhookMouse;
  96. // TAPI session handle.
  97. //
  98. HLINEAPP hlineapp;
  99. // Handle of the RAS connection associated with the current entry or NULL
  100. // if none.
  101. //
  102. HRASCONN hrasconn;
  103. // Connect monitor objects.
  104. //
  105. HANDLE hThread;
  106. HANDLE hEvent;
  107. BOOL fAbortMonitor;
  108. }
  109. DUINFO;
  110. //----------------------------------------------------------------------------
  111. // Local prototypes (alphabetically)
  112. //----------------------------------------------------------------------------
  113. BOOL
  114. DuCommand(
  115. IN DUINFO* pInfo,
  116. IN WORD wNotification,
  117. IN WORD wId,
  118. IN HWND hwndCtrl );
  119. VOID
  120. DuCreateShortcut(
  121. IN DUINFO* pInfo );
  122. LRESULT CALLBACK
  123. DuCreateShortcutCallWndRetProc(
  124. int code,
  125. WPARAM wparam,
  126. LPARAM lparam );
  127. INT_PTR CALLBACK
  128. DuDlgProc(
  129. IN HWND hwnd,
  130. IN UINT unMsg,
  131. IN WPARAM wparam,
  132. IN LPARAM lparam );
  133. VOID
  134. DuDeleteSelectedEntry(
  135. IN DUINFO* pInfo );
  136. VOID
  137. DuDialSelectedEntry(
  138. IN DUINFO* pInfo );
  139. VOID
  140. DuEditSelectedEntry(
  141. IN DUINFO* pInfo );
  142. VOID
  143. DuEditSelectedLocation(
  144. IN DUINFO* pInfo );
  145. DWORD
  146. DuFillLocationList(
  147. IN DUINFO* pInfo );
  148. VOID
  149. DuFillPreview(
  150. IN DUINFO* pInfo );
  151. DWORD
  152. DuGetEntry(
  153. DUINFO* pInfo,
  154. DUCONTEXT* pContext );
  155. TCHAR*
  156. DuGetPreview(
  157. IN DUINFO* pInfo );
  158. DWORD
  159. DuHandleConnectFailure(
  160. IN DUINFO* pInfo,
  161. IN RASDIALDLG* pDialInfo);
  162. VOID
  163. DuHangUpSelectedEntry(
  164. IN DUINFO* pInfo );
  165. BOOL
  166. DuInit(
  167. IN HWND hwndDlg,
  168. IN DUARGS* pArgs );
  169. LRESULT CALLBACK
  170. DuInputHook(
  171. IN int nCode,
  172. IN WPARAM wparam,
  173. IN LPARAM lparam );
  174. LRESULT APIENTRY
  175. DuLbEntriesProc(
  176. IN HWND hwnd,
  177. IN UINT unMsg,
  178. IN WPARAM wparam,
  179. IN LPARAM lparam );
  180. VOID
  181. DuLocationChange(
  182. IN DUINFO* pInfo );
  183. DWORD
  184. DuMonitorThread(
  185. LPVOID pThreadArg );
  186. VOID
  187. DuNewEntry(
  188. IN DUINFO* pInfo,
  189. IN BOOL fClone );
  190. VOID
  191. DuOperatorDial(
  192. IN DUINFO* pInfo );
  193. LRESULT APIENTRY
  194. DuPbMoreProc(
  195. IN HWND hwnd,
  196. IN UINT unMsg,
  197. IN WPARAM wparam,
  198. IN LPARAM lparam );
  199. VOID
  200. DuPopupMoreMenu(
  201. IN DUINFO* pInfo );
  202. VOID
  203. DuPreferences(
  204. IN DUINFO* pInfo,
  205. IN BOOL fLogon );
  206. VOID
  207. DuSetup(
  208. IN DUINFO* pInfo );
  209. VOID
  210. DuStatus(
  211. IN DUINFO* pInfo );
  212. VOID
  213. DuTerm(
  214. IN HWND hwndDlg );
  215. VOID
  216. DuUpdateConnectStatus(
  217. IN DUINFO* pInfo );
  218. VOID
  219. DuUpdateLbEntries(
  220. IN DUINFO* pInfo,
  221. IN TCHAR* pszEntry );
  222. VOID
  223. DuUpdatePreviewAndLocationState(
  224. IN DUINFO* pInfo );
  225. VOID
  226. DuUpdateTitle(
  227. IN DUINFO* pInfo );
  228. VOID
  229. DuWriteShortcutFile(
  230. IN HWND hwnd,
  231. IN TCHAR* pszRnkPath,
  232. IN TCHAR* pszPbkPath,
  233. IN TCHAR* pszEntry );
  234. DWORD
  235. DwGetEapLogonInfo(
  236. VOID *pv,
  237. EAPLOGONINFO **ppEapLogonInfo );
  238. VOID WINAPI
  239. RasPbDlgCallbackThunk(
  240. ULONG_PTR ulpId,
  241. DWORD dwEvent,
  242. LPWSTR pszEntry,
  243. LPVOID pArgs );
  244. //----------------------------------------------------------------------------
  245. // External entry points
  246. //----------------------------------------------------------------------------
  247. BOOL APIENTRY
  248. RasPhonebookDlgA(
  249. IN LPSTR lpszPhonebook,
  250. IN LPSTR lpszEntry,
  251. IN OUT LPRASPBDLGA lpInfo )
  252. // Win32 ANSI entrypoint that displays the Dial-Up Networking dialog, i.e.
  253. // the RAS phonebook. 'LpszPhonebook' is the full path the phonebook or
  254. // NULL indicating the default phonebook. 'LpszEntry' is the entry to
  255. // highlight on entry or NULL to highlight the first entry in the list.
  256. // 'LpInfo' is caller's additional input/output parameters.
  257. //
  258. // Returns true if user establishes a connection, false otherwise.
  259. //
  260. {
  261. WCHAR* pszPhonebookW;
  262. WCHAR* pszEntryW;
  263. RASPBDLGW infoW;
  264. BOOL fStatus;
  265. TRACE( "RasPhonebookDlgA" );
  266. if (!lpInfo)
  267. {
  268. SetLastError( ERROR_INVALID_PARAMETER );
  269. return FALSE;
  270. }
  271. if (lpInfo->dwSize != sizeof(RASPBDLGA))
  272. {
  273. lpInfo->dwError = ERROR_INVALID_SIZE;
  274. return FALSE;
  275. }
  276. // Thunk "A" arguments to "W" arguments.
  277. //
  278. if (lpszPhonebook)
  279. {
  280. pszPhonebookW = StrDupTFromAUsingAnsiEncoding( lpszPhonebook );
  281. if (!pszPhonebookW)
  282. {
  283. lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
  284. return FALSE;
  285. }
  286. }
  287. else
  288. {
  289. pszPhonebookW = NULL;
  290. }
  291. if (lpszEntry)
  292. {
  293. pszEntryW = StrDupTFromAUsingAnsiEncoding( lpszEntry );
  294. if (!pszEntryW)
  295. {
  296. Free0( pszPhonebookW );
  297. lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
  298. return FALSE;
  299. }
  300. }
  301. else
  302. {
  303. pszEntryW = NULL;
  304. }
  305. // Take advantage of the structures currently having the same size and
  306. // layout. Only the callback is different.
  307. //
  308. ASSERT( sizeof(RASPBDLGA) == sizeof(RASPBDLGW) );
  309. CopyMemory( &infoW, lpInfo, sizeof(infoW) );
  310. if (lpInfo->pCallback)
  311. {
  312. infoW.dwCallbackId = (ULONG_PTR)lpInfo;
  313. infoW.pCallback = RasPbDlgCallbackThunk;
  314. }
  315. infoW.reserved2 = lpInfo->reserved2;
  316. // Thunk to the equivalent "W" API.
  317. //
  318. fStatus = RasPhonebookDlgW( pszPhonebookW, pszEntryW, &infoW );
  319. Free0( pszPhonebookW );
  320. Free0( pszEntryW );
  321. return fStatus;
  322. }
  323. VOID WINAPI
  324. RasPbDlgCallbackThunk(
  325. ULONG_PTR ulpId,
  326. DWORD dwEvent,
  327. LPWSTR pszEntry,
  328. LPVOID pArgs )
  329. // This thunks "W" callbacks to API caller's "A" callback.
  330. //
  331. {
  332. CHAR* pszEntryA;
  333. VOID* pArgsA;
  334. RASPBDLGA* pInfo;
  335. RASNOUSERA nuA;
  336. if (dwEvent == RASPBDEVENT_NoUser || dwEvent == RASPBDEVENT_NoUserEdit)
  337. {
  338. RASNOUSERW* pnuW = (RASNOUSERW* )pArgs;
  339. ASSERT( pnuW );
  340. ZeroMemory( &nuA, sizeof(nuA) );
  341. nuA.dwSize = sizeof(nuA);
  342. nuA.dwFlags = pnuW->dwFlags;
  343. nuA.dwTimeoutMs = pnuW->dwTimeoutMs;
  344. StrCpyAFromW(nuA.szUserName, pnuW->szUserName, UNLEN + 1);
  345. StrCpyAFromW(nuA.szPassword, pnuW->szPassword, UNLEN + 1);
  346. StrCpyAFromW(nuA.szDomain, pnuW->szDomain, UNLEN + 1);
  347. pArgsA = &nuA;
  348. }
  349. else
  350. {
  351. pArgsA = NULL;
  352. }
  353. pszEntryA = StrDupAFromT( pszEntry );
  354. pInfo = (RASPBDLGA* )ulpId;
  355. pInfo->pCallback( pInfo->dwCallbackId, dwEvent, pszEntryA, pArgsA );
  356. Free0( pszEntryA );
  357. if (dwEvent == RASPBDEVENT_NoUser || dwEvent == RASPBDEVENT_NoUserEdit)
  358. {
  359. RASNOUSERW* pnuW = (RASNOUSERW* )pArgs;
  360. pnuW->dwFlags = nuA.dwFlags;
  361. pnuW->dwTimeoutMs = nuA.dwTimeoutMs;
  362. StrCpyWFromA(pnuW->szUserName, nuA.szUserName, UNLEN + 1);
  363. StrCpyWFromA(pnuW->szPassword, nuA.szPassword, UNLEN + 1);
  364. StrCpyWFromA(pnuW->szDomain, nuA.szDomain, UNLEN + 1);
  365. ZeroMemory( nuA.szPassword, PWLEN );
  366. }
  367. }
  368. BOOL APIENTRY
  369. RasPhonebookDlgW(
  370. IN LPWSTR lpszPhonebook,
  371. IN LPWSTR lpszEntry,
  372. IN OUT LPRASPBDLGW lpInfo )
  373. // Win32 Unicode entrypoint that displays the Dial-Up Networking dialog,
  374. // i.e. the RAS phonebook. 'LpszPhonebook' is the full path the phonebook
  375. // or NULL indicating the default phonebook. 'LpszEntry' is the entry to
  376. // highlight on entry or NULL to highlight the first entry in the list.
  377. // 'LpInfo' is caller's additional input/output parameters.
  378. //
  379. // Returns true if user establishes a connection, false otherwise.
  380. //
  381. {
  382. INT_PTR nStatus;
  383. DUARGS args;
  384. TRACE( "RasPhonebookDlgW" );
  385. if (!lpInfo)
  386. {
  387. SetLastError( ERROR_INVALID_PARAMETER );
  388. return FALSE;
  389. }
  390. if (lpInfo->dwSize != sizeof(RASPBDLGW))
  391. {
  392. lpInfo->dwError = ERROR_INVALID_SIZE;
  393. return FALSE;
  394. }
  395. // Initialize OUT parameters.
  396. //
  397. lpInfo->dwError = 0;
  398. // Initialize dialog argument block.
  399. //
  400. args.pszPhonebook = lpszPhonebook;
  401. args.pszEntry = lpszEntry;
  402. args.pApiArgs = lpInfo;
  403. args.fApiResult = FALSE;
  404. // Run the dialog.
  405. //
  406. nStatus =
  407. DialogBoxParam(
  408. g_hinstDll,
  409. MAKEINTRESOURCE( DID_DU_DialUpNetworking ),
  410. lpInfo->hwndOwner,
  411. DuDlgProc,
  412. (LPARAM )&args );
  413. if (nStatus == -1)
  414. {
  415. ErrorDlg( lpInfo->hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  416. lpInfo->dwError = ERROR_UNKNOWN;
  417. args.fApiResult = FALSE;
  418. }
  419. return args.fApiResult;
  420. }
  421. //----------------------------------------------------------------------------
  422. // Dial-Up Networking dialog
  423. // Listed alphabetically following dialog proc
  424. //----------------------------------------------------------------------------
  425. INT_PTR CALLBACK
  426. DuDlgProc(
  427. IN HWND hwnd,
  428. IN UINT unMsg,
  429. IN WPARAM wparam,
  430. IN LPARAM lparam )
  431. // DialogProc callback for the Dial-Up Networking dialog, i.e. the
  432. // phonebook dialog. Parameters and return value are as described for
  433. // standard windows 'DialogProc's.
  434. //
  435. {
  436. #if 0
  437. TRACE4( "DuDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  438. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  439. #endif
  440. switch (unMsg)
  441. {
  442. case WM_INITDIALOG:
  443. {
  444. return DuInit( hwnd, (DUARGS* )lparam );
  445. }
  446. case WM_HELP:
  447. case WM_CONTEXTMENU:
  448. {
  449. ContextHelp( g_adwDuHelp, hwnd, unMsg, wparam, lparam );
  450. return TRUE;
  451. }
  452. case WM_COMMAND:
  453. {
  454. DUINFO* pInfo = (DUINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  455. ASSERT( pInfo );
  456. return DuCommand(
  457. pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  458. }
  459. case WM_RASEVENT:
  460. {
  461. DUINFO* pInfo = (DUINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  462. ASSERT( pInfo );
  463. DuUpdateConnectStatus( pInfo );
  464. break;
  465. }
  466. case WM_NOUSERTIMEOUT:
  467. {
  468. DUINFO* pInfo;
  469. ULONG ulCallbacksActive;
  470. TRACE( "CancelOwnedWindows" );
  471. CancelOwnedWindows( hwnd );
  472. TRACE( "CancelOwnedWindows done" );
  473. ulCallbacksActive = CallbacksActive( 1, NULL );
  474. if (ulCallbacksActive > 0)
  475. {
  476. TRACE1( "NoUser timeout stall, n=%d", ulCallbacksActive );
  477. PostMessage( hwnd, WM_NOUSERTIMEOUT, wparam, lparam );
  478. return TRUE;
  479. }
  480. pInfo = (DUINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  481. if (pInfo)
  482. {
  483. pInfo->pArgs->pApiArgs->dwError = STATUS_TIMEOUT;
  484. }
  485. EndDialog( hwnd, TRUE );
  486. CallbacksActive( 0, NULL );
  487. break;
  488. }
  489. case WM_DESTROY:
  490. {
  491. DuTerm( hwnd );
  492. /*
  493. //We have to wait for Deonb to return us the IID_Dun1 icon
  494. //For whistler bug 372078 381099
  495. //Icon returned by GetCurrentIconEntryType() has to be destroyed
  496. {
  497. HICON hIcon=NULL;
  498. //hIcon = (HICON) GetWindowLongPtr(hwnd, GWLP_USERDATA);
  499. hIcon = GetProp( hwnd, TEXT("TweakTitleBar_Icon"));
  500. ASSERT(hIcon);
  501. if( hIcon )
  502. {
  503. DestroyIcon(hIcon);
  504. }
  505. else
  506. {
  507. TRACE("DuDlgProc:Destroy Icon failed");
  508. }
  509. }
  510. */
  511. break;
  512. }
  513. }
  514. return FALSE;
  515. }
  516. BOOL
  517. DuCommand(
  518. IN DUINFO* pInfo,
  519. IN WORD wNotification,
  520. IN WORD wId,
  521. IN HWND hwndCtrl )
  522. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  523. // is the notification code of the command. 'wId' is the control/menu
  524. // identifier of the command. 'HwndCtrl' is the control window handle of
  525. // the command.
  526. //
  527. // Returns true if processed message, false otherwise.
  528. //
  529. {
  530. TRACE3( "DuCommand(n=%d,i=%d,c=$%x)",
  531. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  532. switch (wId)
  533. {
  534. case CID_DU_PB_Dial:
  535. {
  536. if (pInfo->hrasconn)
  537. {
  538. DuHangUpSelectedEntry( pInfo );
  539. }
  540. else
  541. {
  542. DuDialSelectedEntry( pInfo );
  543. }
  544. return TRUE;
  545. }
  546. case CID_DU_PB_New:
  547. {
  548. DuNewEntry( pInfo, FALSE );
  549. return TRUE;
  550. }
  551. case CID_DU_PB_More:
  552. {
  553. DuEditSelectedEntry( pInfo );
  554. return TRUE;
  555. }
  556. case CID_DU_LB_Entries:
  557. {
  558. if (wNotification == CBN_SELCHANGE)
  559. {
  560. PBENTRY *pEntry;
  561. DWORD dwErr = SUCCESS;
  562. DUCONTEXT *pContext;
  563. pContext = (DUCONTEXT *)
  564. ComboBox_GetItemDataPtr(
  565. pInfo->hwndLbEntries,
  566. ComboBox_GetCurSel(pInfo->hwndLbEntries));
  567. ASSERT(NULL != pContext);
  568. if(NULL == pContext)
  569. {
  570. return TRUE;
  571. }
  572. //
  573. // Update the phonebook information
  574. //
  575. dwErr = DuGetEntry(pInfo, pContext);
  576. if(ERROR_SUCCESS == dwErr)
  577. {
  578. ComboBox_SetItemData(
  579. pInfo->hwndLbEntries,
  580. ComboBox_GetCurSel(pInfo->hwndLbEntries),
  581. pContext);
  582. }
  583. else
  584. {
  585. ComboBox_DeleteString(
  586. pInfo->hwndLbEntries,
  587. ComboBox_GetCurSel(pInfo->hwndLbEntries) );
  588. }
  589. DuUpdateConnectStatus( pInfo );
  590. return TRUE;
  591. }
  592. break;
  593. }
  594. case IDCANCEL:
  595. case CID_DU_PB_Close:
  596. {
  597. EndDialog( pInfo->hwndDlg, TRUE );
  598. return TRUE;
  599. }
  600. }
  601. return FALSE;
  602. }
  603. VOID
  604. DuDialSelectedEntry(
  605. IN DUINFO* pInfo )
  606. // Called when user presses the "Dial" button.
  607. //
  608. {
  609. DWORD dwErr;
  610. BOOL fConnected;
  611. BOOL fAutoLogon;
  612. TCHAR* pszEbNumber;
  613. TCHAR* pszEbPreview;
  614. TCHAR* pszOrgPreview;
  615. TCHAR* pszOverride;
  616. TCHAR* pszEntryName;
  617. RASDIALDLG info;
  618. INTERNALARGS iargs;
  619. PBENTRY* pEntry;
  620. DTLNODE *pdtlnode;
  621. PBFILE file;
  622. DUCONTEXT *pContext;
  623. TRACE( "DuDialSelectedEntry" );
  624. // Look up the selected entry.
  625. //
  626. pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
  627. pInfo->hwndLbEntries,
  628. ComboBox_GetCurSel(pInfo->hwndLbEntries));
  629. if (!pContext)
  630. {
  631. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  632. SetFocus( pInfo->hwndPbNew );
  633. return;
  634. }
  635. pEntry = pContext->pEntry;
  636. if (!pEntry)
  637. {
  638. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  639. SetFocus( pInfo->hwndPbNew );
  640. return;
  641. }
  642. pszOverride = NULL;
  643. pszOrgPreview = NULL;
  644. pszEbPreview = NULL;
  645. pszEbNumber = NULL;
  646. // Set up API argument block.
  647. //
  648. ZeroMemory( &info, sizeof(info) );
  649. info.dwSize = sizeof(info);
  650. info.hwndOwner = pInfo->hwndDlg;
  651. // The secret hack to share information already loaded with the entry API.
  652. //
  653. ZeroMemory( &iargs, sizeof(iargs) );
  654. iargs.pFile = &pInfo->file;
  655. iargs.pUser = &pInfo->user;
  656. iargs.pNoUser = pInfo->pNoUser;
  657. iargs.fNoUser = pInfo->fNoUser;
  658. iargs.fForceCloseOnDial =
  659. (pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_ForceCloseOnDial);
  660. iargs.pvEapInfo = NULL;
  661. if(0 != pInfo->pArgs->pApiArgs->reserved2)
  662. {
  663. DWORD retcode;
  664. EAPLOGONINFO *pEapInfo = NULL;
  665. retcode = DwGetEapLogonInfo(
  666. (VOID *) pInfo->pArgs->pApiArgs->reserved2,
  667. &pEapInfo);
  668. if(SUCCESS == retcode)
  669. {
  670. iargs.pvEapInfo = (VOID *) pEapInfo;
  671. }
  672. }
  673. iargs.fMoveOwnerOffDesktop =
  674. (iargs.fForceCloseOnDial || pInfo->user.fCloseOnDial);
  675. info.reserved = (ULONG_PTR ) &iargs;
  676. // Call the Win32 API to run the connect status dialog. Make a copy of
  677. // the entry name and auto-logon flag first, because RasDialDlg may
  678. // re-read the entry node to pick up RASAPI changes.
  679. //
  680. pszEntryName = StrDup( pEntry->pszEntryName );
  681. fAutoLogon = pEntry->fAutoLogon;
  682. TRACEW1( "RasDialDlg,o=\"%s\"", (pszOverride) ? pszOverride : TEXT("") );
  683. fConnected = RasDialDlg(
  684. pContext->pszPhonebookPath, pEntry->pszEntryName, pszOverride, &info );
  685. TRACE1( "RasDialDlg=%d", fConnected );
  686. Free0( pszEbPreview );
  687. Free0( pszOrgPreview );
  688. if(NULL != iargs.pvEapInfo)
  689. {
  690. Free0(iargs.pvEapInfo);
  691. iargs.pvEapInfo = NULL;
  692. }
  693. if (fConnected)
  694. {
  695. pInfo->pArgs->fApiResult = TRUE;
  696. if (pInfo->pArgs->pApiArgs->pCallback)
  697. {
  698. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  699. if (pInfo->pNoUser && iargs.fNoUserChanged && fAutoLogon)
  700. {
  701. // Whistler bug 254385 encode password when not being used
  702. // Need to Decode password before callback function
  703. // Assumed password was encoded previously by DuInit()
  704. //
  705. DecodePassword( pInfo->pNoUser->szPassword );
  706. TRACE( "Callback(NoUserEdit)" );
  707. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  708. RASPBDEVENT_NoUserEdit, NULL, pInfo->pNoUser );
  709. TRACE( "Callback(NoUserEdit) done" );
  710. EncodePassword( pInfo->pNoUser->szPassword );
  711. }
  712. TRACE( "Callback(DialEntry)" );
  713. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  714. RASPBDEVENT_DialEntry, pszEntryName, NULL );
  715. TRACE( "Callback(DialEntry) done" );
  716. }
  717. if (pInfo->user.fCloseOnDial
  718. || (pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_ForceCloseOnDial))
  719. {
  720. EndDialog( pInfo->hwndDlg, TRUE );
  721. }
  722. }
  723. else
  724. {
  725. DuHandleConnectFailure(pInfo, &info);
  726. }
  727. if (pInfo->pNoUser && !pInfo->hThread)
  728. {
  729. TRACE( "Taking shortcut to exit" );
  730. return;
  731. }
  732. // Reload the list even if the Dial was cancelled as user may have changed
  733. // the current PBENTRY with the Properties button on the dialer which
  734. // commits changes even if user cancels the dial itself. See bug 363710.
  735. //
  736. DuUpdateLbEntries( pInfo, pszEntryName );
  737. SetFocus( pInfo->hwndLbEntries );
  738. Free0( pszEntryName );
  739. }
  740. VOID
  741. DuEditSelectedEntry(
  742. IN DUINFO* pInfo )
  743. // Called when user selects "Edit entry" from the menu. 'PInfo' is the
  744. // dialog context. 'PszEntry' is the name of the entry to edit.
  745. //
  746. {
  747. BOOL fOk;
  748. RASENTRYDLG info;
  749. INTERNALARGS iargs;
  750. PBENTRY* pEntry;
  751. LPTSTR pszEntryName;
  752. DTLNODE *pdtlnode;
  753. PBFILE file;
  754. DWORD dwErr;
  755. DUCONTEXT *pContext;
  756. INT iSel;
  757. TRACE( "DuEditSelectedEntry" );
  758. // Look up the selected entry.
  759. //
  760. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  761. if (iSel < 0)
  762. {
  763. return;
  764. }
  765. pContext = (DUCONTEXT * )ComboBox_GetItemDataPtr(
  766. pInfo->hwndLbEntries, iSel );
  767. ASSERT(NULL != pContext);
  768. if(NULL == pContext)
  769. {
  770. return;
  771. }
  772. ASSERT(NULL != pContext->pszPhonebookPath);
  773. pEntry = pContext->pEntry;
  774. if (!pEntry)
  775. {
  776. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  777. SetFocus( pInfo->hwndPbNew );
  778. return;
  779. }
  780. // Set up API argument block.
  781. //
  782. ZeroMemory( &info, sizeof(info) );
  783. info.dwSize = sizeof(info);
  784. info.hwndOwner = pInfo->hwndDlg;
  785. {
  786. RECT rect;
  787. info.dwFlags = RASEDFLAG_PositionDlg;
  788. GetWindowRect( pInfo->hwndDlg, &rect );
  789. info.xDlg = rect.left + DXSHEET;
  790. info.yDlg = rect.top + DYSHEET;
  791. }
  792. // The secret hack to share information already loaded with the entry API.
  793. //
  794. ZeroMemory( &iargs, sizeof(iargs) );
  795. iargs.pFile = &pInfo->file;
  796. iargs.pUser = &pInfo->user;
  797. iargs.pNoUser = pInfo->pNoUser;
  798. iargs.fNoUser = pInfo->fNoUser;
  799. info.reserved = (ULONG_PTR ) &iargs;
  800. // Call the Win32 API to run the entry property sheet.
  801. //
  802. TRACE( "RasEntryDlg" );
  803. fOk = RasEntryDlg(
  804. pContext->pszPhonebookPath, pEntry->pszEntryName, &info );
  805. TRACE1( "RasEntryDlg=%d", fOk );
  806. if (pInfo->pNoUser && !pInfo->hThread)
  807. {
  808. TRACE( "Taking shortcut to exit" );
  809. return;
  810. }
  811. if (fOk)
  812. {
  813. TRACEW1( "OK pressed,e=\"%s\"", info.szEntry );
  814. if (pInfo->pArgs->pApiArgs->pCallback)
  815. {
  816. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  817. TRACE( "Callback(EditEntry)" );
  818. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  819. RASPBDEVENT_AddEntry, info.szEntry, NULL );
  820. TRACE( "Callback(EditEntry) done" );
  821. }
  822. DuUpdateLbEntries( pInfo, info.szEntry );
  823. SetFocus( pInfo->hwndLbEntries );
  824. }
  825. else
  826. {
  827. TRACE( "Cancel pressed or error" );
  828. }
  829. }
  830. //
  831. // Helper function called by DuDialSelectedEntry to handle errors
  832. // returned from RasDialDlgW
  833. //
  834. DWORD
  835. DuHandleConnectFailure(
  836. IN DUINFO* pInfo,
  837. IN RASDIALDLG* pDialInfo)
  838. {
  839. TRACE3(
  840. "DuHandleConnectFailure: nu=%x, r2=%x, de=%x",
  841. (pInfo->pNoUser),
  842. (pInfo->pArgs->pApiArgs->reserved2),
  843. (pDialInfo->dwError));
  844. // XP: 384968
  845. //
  846. // Handle the bad-PIN error from winlogon
  847. //
  848. // Normally, the smart card PIN is gotten by calling EAP-TLS's identity
  849. // api. This API raises UI and validates the PIN entered.
  850. //
  851. // During winlogon, however, the smart card PIN is passed to us from GINA.
  852. // In this case it is not validated until we call EAP API's. (actually,
  853. // it's until we call the eap identity api with RAS_EAP_FLAG_LOGON.
  854. // This flag tells EAP not to raise any UI but instead to use the info
  855. // passed from GINA)
  856. //
  857. // GINA is not able to validate the PIN itself because it does not call any
  858. // CAPI's directly. Oh well.
  859. //
  860. // If RasDialDlg returns a bad pin error, then we should gracefully fail
  861. // back to winlogon.
  862. //
  863. if ((pInfo->pNoUser) && // called by winlogon
  864. (pInfo->pArgs->pApiArgs->reserved2) && // for smart card
  865. (RAS_SC_IS_BAD_PIN(pDialInfo->dwError))) // but pin is bad
  866. {
  867. pInfo->pArgs->pApiArgs->dwError = pDialInfo->dwError;
  868. EndDialog( pInfo->hwndDlg, TRUE );
  869. }
  870. return NO_ERROR;
  871. }
  872. VOID
  873. DuHangUpSelectedEntry(
  874. IN DUINFO* pInfo )
  875. // Hang up the selected entry after confirming with user. 'Pinfo' is the
  876. // dialog context block.
  877. //
  878. {
  879. DWORD dwErr;
  880. PBENTRY* pEntry;
  881. INT iSel;
  882. INT nResponse;
  883. MSGARGS msgargs;
  884. LPTSTR pszEntryName;
  885. DTLNODE *pdtlnode;
  886. DUCONTEXT *pContext;
  887. TRACE( "DuHangUpSelectedEntry" );
  888. // Look up the selected entry.
  889. //
  890. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  891. ASSERT( iSel >= 0 );
  892. pContext = (DUCONTEXT * )ComboBox_GetItemDataPtr( pInfo->hwndLbEntries, iSel );
  893. ASSERT(NULL != pContext);
  894. if (!pContext)
  895. {
  896. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  897. SetFocus( pInfo->hwndPbNew );
  898. return;
  899. }
  900. pEntry = pContext->pEntry;
  901. ASSERT( pEntry );
  902. if (!pEntry)
  903. {
  904. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  905. SetFocus( pInfo->hwndPbNew );
  906. return;
  907. }
  908. ZeroMemory( &msgargs, sizeof(msgargs) );
  909. msgargs.apszArgs[ 0 ] = pEntry->pszEntryName;
  910. msgargs.dwFlags = MB_YESNO | MB_ICONEXCLAMATION;
  911. nResponse = MsgDlg( pInfo->hwndDlg, SID_ConfirmHangUp, &msgargs );
  912. if (nResponse == IDYES)
  913. {
  914. ASSERT( g_pRasHangUp );
  915. TRACE( "RasHangUp" );
  916. dwErr = g_pRasHangUp( pInfo->hrasconn );
  917. TRACE1( "RasHangUp=%d", dwErr );
  918. if ( dwErr == ERROR_HANGUP_FAILED )
  919. {
  920. MsgDlg( pInfo->hwndDlg, SID_CantHangUpRouter, NULL );
  921. }
  922. }
  923. }
  924. BOOL
  925. DuInit(
  926. IN HWND hwndDlg,
  927. IN DUARGS* pArgs )
  928. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the phonebook
  929. // dialog window. 'pArgs' points at caller's arguments as passed to the
  930. // API (or thunk).
  931. //
  932. // Return false if focus was set, true otherwise, i.e. as defined for
  933. // WM_INITDIALOG.
  934. //
  935. {
  936. DWORD dwErr;
  937. DWORD dwThreadId;
  938. DWORD dwReadPbkFlags = 0;
  939. DUINFO* pInfo;
  940. TRACE( "DuInit" );
  941. // Allocate the dialog context block. Initialize minimally for proper
  942. // cleanup, then attach to the dialog window.
  943. //
  944. {
  945. pInfo = Malloc( sizeof(*pInfo) );
  946. if (!pInfo)
  947. {
  948. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  949. pArgs->pApiArgs->dwError = ERROR_NOT_ENOUGH_MEMORY;
  950. EndDialog( hwndDlg, TRUE );
  951. return TRUE;
  952. }
  953. ZeroMemory( pInfo, sizeof(*pInfo) );
  954. pInfo->file.hrasfile = -1;
  955. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  956. TRACE( "Context set" );
  957. }
  958. pInfo->pArgs = pArgs;
  959. pInfo->hwndDlg = hwndDlg;
  960. // Position the dialog per caller's instructions.
  961. //
  962. PositionDlg( hwndDlg,
  963. pArgs->pApiArgs->dwFlags & RASPBDFLAG_PositionDlg,
  964. pArgs->pApiArgs->xDlg, pArgs->pApiArgs->yDlg );
  965. // Load RAS DLL entrypoints which starts RASMAN, if necessary. There must
  966. // be no API calls that require RASAPI32 or RASMAN prior to this point.
  967. //
  968. dwErr = LoadRas( g_hinstDll, hwndDlg );
  969. if (dwErr != 0)
  970. {
  971. ErrorDlg( hwndDlg, SID_OP_LoadRas, dwErr, NULL );
  972. pArgs->pApiArgs->dwError = dwErr;
  973. EndDialog( hwndDlg, TRUE );
  974. return TRUE;
  975. }
  976. if(0 != (pArgs->pApiArgs->dwFlags & RASPBDFLAG_NoUser))
  977. {
  978. // Popup TAPI's "first location" dialog if they are uninitialized.
  979. //
  980. dwErr = TapiNoLocationDlg( g_hinstDll, &pInfo->hlineapp, hwndDlg );
  981. if (dwErr != 0)
  982. {
  983. // Error here is treated as a "cancel" per bug 288385.
  984. //
  985. pArgs->pApiArgs->dwError = 0;
  986. EndDialog( hwndDlg, TRUE );
  987. return TRUE;
  988. }
  989. }
  990. pInfo->hwndLbEntries = GetDlgItem( hwndDlg, CID_DU_LB_Entries );
  991. ASSERT( pInfo->hwndLbEntries );
  992. pInfo->hwndPbDial = GetDlgItem( hwndDlg, CID_DU_PB_Dial );
  993. ASSERT( pInfo->hwndPbDial );
  994. pInfo->hwndPbNew = GetDlgItem( hwndDlg, CID_DU_PB_New );
  995. ASSERT( pInfo->hwndPbNew );
  996. pInfo->hwndPbProperties = GetDlgItem( hwndDlg, CID_DU_PB_More );
  997. ASSERT( pInfo->hwndPbProperties );
  998. pInfo->fNoUser = (pArgs->pApiArgs->dwFlags & RASPBDFLAG_NoUser );
  999. // Setting this global flag indicates that WinHelp will not work in the
  1000. // current mode. See common\uiutil\ui.c. We assume here that only the
  1001. // WinLogon process makes use of this.
  1002. //
  1003. {
  1004. extern BOOL g_fNoWinHelp;
  1005. g_fNoWinHelp = pInfo->fNoUser;
  1006. }
  1007. // Read user preferences from registry.
  1008. //
  1009. dwErr = g_pGetUserPreferences(
  1010. NULL, &pInfo->user, pInfo->fNoUser ? UPM_Logon : UPM_Normal);
  1011. if (dwErr != 0)
  1012. {
  1013. //
  1014. // The following free causes a crash in DuTerm. This context will be
  1015. // freed in DuTerm - raos.
  1016. //
  1017. // Free( pInfo );
  1018. ErrorDlg( hwndDlg, SID_OP_LoadPrefs, dwErr, NULL );
  1019. EndDialog( hwndDlg, TRUE );
  1020. return TRUE;
  1021. }
  1022. // Load and parse phonebook file.
  1023. //
  1024. if (pInfo->fNoUser)
  1025. {
  1026. dwReadPbkFlags |= RPBF_NoUser;
  1027. }
  1028. dwErr = ReadPhonebookFile(
  1029. pArgs->pszPhonebook,
  1030. &pInfo->user,
  1031. NULL,
  1032. dwReadPbkFlags,
  1033. &pInfo->file );
  1034. if (dwErr != 0)
  1035. {
  1036. // The following free causes a crash in DuTerm. This context will be
  1037. // freed in DuTerm - raos.
  1038. //
  1039. // Free( pInfo );
  1040. ErrorDlg( hwndDlg, SID_OP_LoadPhonebook, dwErr, NULL );
  1041. EndDialog( hwndDlg, TRUE );
  1042. return TRUE;
  1043. }
  1044. if (pArgs->pApiArgs->pCallback && !pArgs->pszPhonebook)
  1045. {
  1046. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  1047. // Tell user the path to the default phonebook file.
  1048. //
  1049. TRACE( "Callback(EditGlobals)" );
  1050. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  1051. RASPBDEVENT_EditGlobals, pInfo->file.pszPath, NULL );
  1052. TRACE( "Callback(EditGlobals) done" );
  1053. }
  1054. if (pInfo->fNoUser)
  1055. {
  1056. // Retrieve logon information from caller via callback.
  1057. //
  1058. if (pArgs->pApiArgs->pCallback)
  1059. {
  1060. RASPBDLGFUNCW pfunc = pArgs->pApiArgs->pCallback;
  1061. pInfo->pNoUser = Malloc( sizeof(RASNOUSERW) );
  1062. if (pInfo->pNoUser)
  1063. {
  1064. ZeroMemory( pInfo->pNoUser, sizeof(*pInfo->pNoUser) );
  1065. pInfo->pNoUser->dwSize = sizeof(*pInfo->pNoUser);
  1066. TRACE( "Callback(NoUser)" );
  1067. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  1068. RASPBDEVENT_NoUser, NULL, pInfo->pNoUser );
  1069. TRACE1( "Callback(NoUser) done,to=%d",
  1070. pInfo->pNoUser->dwTimeoutMs );
  1071. TRACEW1( "U=%s",pInfo->pNoUser->szUserName );
  1072. TRACEW1( "D=%s",pInfo->pNoUser->szDomain );
  1073. // Whistler bug 254385 encode password when not being used
  1074. // Assumed password was not encoded during callback
  1075. //
  1076. EncodePassword( pInfo->pNoUser->szPassword );
  1077. // Install input detection hooks.
  1078. //
  1079. if (pInfo->pNoUser->dwTimeoutMs > 0)
  1080. {
  1081. pInfo->hhookMouse = SetWindowsHookEx(
  1082. WH_MOUSE, DuInputHook, g_hinstDll,
  1083. GetCurrentThreadId() );
  1084. pInfo->hhookKeyboard = SetWindowsHookEx(
  1085. WH_KEYBOARD, DuInputHook, g_hinstDll,
  1086. GetCurrentThreadId() );
  1087. }
  1088. }
  1089. }
  1090. if (!pInfo->user.fAllowLogonPhonebookEdits)
  1091. {
  1092. // Disable new button. See also similar logic for the Properties
  1093. // button occurs in DuUpdateLbEntries.
  1094. //
  1095. EnableWindow( pInfo->hwndPbNew, FALSE );
  1096. }
  1097. }
  1098. // Load the list of phonebook entries and set selection.
  1099. //
  1100. DuUpdateLbEntries( pInfo, pInfo->pArgs->pszEntry );
  1101. if (!pInfo->pArgs->pszEntry)
  1102. {
  1103. if (ComboBox_GetCount( pInfo->hwndLbEntries ) > 0)
  1104. {
  1105. ComboBox_SetCurSelNotify( pInfo->hwndLbEntries, 0 );
  1106. }
  1107. }
  1108. // Update the title to reflect the phonebook mode.
  1109. //
  1110. DuUpdateTitle( pInfo );
  1111. // Adjust the title bar widgets and create the wizard bitmap.
  1112. //
  1113. TweakTitleBar( hwndDlg );
  1114. AddContextHelpButton( hwndDlg );
  1115. // Start the connect monitor.
  1116. //
  1117. if ((pInfo->hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ))
  1118. && (pInfo->hThread = CreateThread(
  1119. NULL, 0, DuMonitorThread, (LPVOID )pInfo, 0,
  1120. (LPDWORD )&dwThreadId )))
  1121. {
  1122. ASSERT( g_pRasConnectionNotification );
  1123. TRACE( "RasConnectionNotification" );
  1124. dwErr = g_pRasConnectionNotification(
  1125. INVALID_HANDLE_VALUE, pInfo->hEvent,
  1126. RASCN_Connection | RASCN_Disconnection );
  1127. TRACE1( "RasConnectionNotification=%d", dwErr );
  1128. }
  1129. else
  1130. TRACE( "Monitor DOA" );
  1131. if (ComboBox_GetCount( pInfo->hwndLbEntries ) == 0)
  1132. {
  1133. // The phonebook is empty.
  1134. //
  1135. if (pInfo->fNoUser
  1136. && !pInfo->user.fAllowLogonPhonebookEdits
  1137. )
  1138. {
  1139. // Tell the user you can't create an entry or locations during
  1140. // startup.
  1141. //
  1142. MsgDlg( hwndDlg, SID_EmptyLogonPb, NULL );
  1143. EndDialog( hwndDlg, TRUE );
  1144. return TRUE;
  1145. }
  1146. else
  1147. {
  1148. if(pInfo->fNoUser)
  1149. {
  1150. dwErr = TapiNoLocationDlg( g_hinstDll,
  1151. &pInfo->hlineapp, hwndDlg );
  1152. if (dwErr != 0)
  1153. {
  1154. // Error here is treated as a "cancel" per bug 288385.
  1155. //
  1156. pArgs->pApiArgs->dwError = 0;
  1157. EndDialog( hwndDlg, TRUE );
  1158. return TRUE;
  1159. }
  1160. }
  1161. // Tell the user, then automatically start him into adding a new
  1162. // entry. Set initial focus to "New" button first, in case user
  1163. // cancels out.
  1164. //
  1165. SetFocus( pInfo->hwndPbNew );
  1166. MsgDlg( hwndDlg, SID_EmptyPhonebook, NULL );
  1167. DuNewEntry( pInfo, FALSE );
  1168. }
  1169. }
  1170. else
  1171. {
  1172. // Set initial focus to the non-empty entry listbox.
  1173. //
  1174. SetFocus( pInfo->hwndLbEntries );
  1175. }
  1176. return FALSE;
  1177. }
  1178. LRESULT CALLBACK
  1179. DuInputHook(
  1180. IN int nCode,
  1181. IN WPARAM wparam,
  1182. IN LPARAM lparam )
  1183. // Standard Win32 'MouseProc' or 'KeyboardProc' callback. For our simple
  1184. // processing we can take advantage of them having identical arguments and
  1185. // 'nCode' definitions.
  1186. //
  1187. {
  1188. if (nCode == HC_ACTION)
  1189. {
  1190. ++g_cInput;
  1191. }
  1192. return 0;
  1193. }
  1194. VOID
  1195. DuNewEntry(
  1196. IN DUINFO* pInfo,
  1197. IN BOOL fClone )
  1198. // Called when user presses the "New" button or "Clone" menu item.
  1199. // 'PInfo' is the dialog context. 'FClone' is set to clone the selected
  1200. // entry, otherwise an empty entry is created.
  1201. //
  1202. {
  1203. BOOL fOk;
  1204. TCHAR* pszEntry;
  1205. RASENTRYDLG info;
  1206. INTERNALARGS iargs;
  1207. PBENTRY* pEntry;
  1208. TRACE1( "DuNewEntry(f=%d)", fClone );
  1209. ZeroMemory( &info, sizeof(info) );
  1210. info.dwSize = sizeof(info);
  1211. info.hwndOwner = pInfo->hwndDlg;
  1212. if (fClone)
  1213. {
  1214. DUCONTEXT *pContext;
  1215. // Look up the selected entry.
  1216. //
  1217. pContext = (DUCONTEXT* )ComboBox_GetItemDataPtr(
  1218. pInfo->hwndLbEntries, ComboBox_GetCurSel( pInfo->hwndLbEntries ) );
  1219. if (!pContext)
  1220. {
  1221. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  1222. SetFocus( pInfo->hwndPbNew );
  1223. return;
  1224. }
  1225. pEntry = pContext->pEntry;
  1226. if (!pEntry)
  1227. {
  1228. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  1229. SetFocus( pInfo->hwndPbNew );
  1230. return;
  1231. }
  1232. pszEntry = pEntry->pszEntryName;
  1233. info.dwFlags = RASEDFLAG_CloneEntry;
  1234. }
  1235. else
  1236. {
  1237. pszEntry = NULL;
  1238. info.dwFlags = RASEDFLAG_NewEntry;
  1239. }
  1240. {
  1241. RECT rect;
  1242. GetWindowRect( pInfo->hwndDlg, &rect );
  1243. info.dwFlags += RASEDFLAG_PositionDlg;
  1244. info.xDlg = rect.left + DXSHEET;
  1245. info.yDlg = rect.top + DYSHEET;
  1246. }
  1247. // The secret hack to share information already loaded with the entry API.
  1248. //
  1249. ZeroMemory( &iargs, sizeof(iargs) );
  1250. iargs.pFile = &pInfo->file;
  1251. iargs.pUser = &pInfo->user;
  1252. iargs.pNoUser = pInfo->pNoUser;
  1253. iargs.fNoUser = pInfo->fNoUser;
  1254. info.reserved = (ULONG_PTR ) &iargs;
  1255. // Call the Win32 API to run the add entry wizard.
  1256. //
  1257. TRACE( "RasEntryDlg" );
  1258. fOk = RasEntryDlg( pInfo->pArgs->pszPhonebook, pszEntry, &info );
  1259. TRACE1( "RasEntryDlg=%d", fOk );
  1260. if (pInfo->pNoUser && !pInfo->hThread)
  1261. {
  1262. TRACE( "Taking shortcut to exit" );
  1263. return;
  1264. }
  1265. if (fOk)
  1266. {
  1267. TRACEW1( "OK pressed, e=\"%s\"", info.szEntry );
  1268. if (pInfo->pArgs->pApiArgs->pCallback)
  1269. {
  1270. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  1271. TRACE( "Callback(AddEntry)" );
  1272. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  1273. RASPBDEVENT_AddEntry, info.szEntry, NULL );
  1274. TRACE( "Callback(AddEntry) done" );
  1275. }
  1276. DuUpdateLbEntries( pInfo, info.szEntry );
  1277. Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbDial );
  1278. SetFocus( pInfo->hwndLbEntries );
  1279. }
  1280. else
  1281. {
  1282. TRACE( "Cancel pressed or error" );
  1283. }
  1284. }
  1285. VOID
  1286. DuUpdateConnectStatus(
  1287. IN DUINFO* pInfo )
  1288. // Called to update connect status of the selected entry and the text of
  1289. // the Dial/HangUp button. 'PInfo' is the dialog context block.
  1290. //
  1291. {
  1292. TCHAR* pszPhonebook;
  1293. TCHAR* pszEntry;
  1294. INT iSel;
  1295. TCHAR* psz;
  1296. DUCONTEXT *pContext;
  1297. TRACE( "DuUpdateConnectStatus" );
  1298. // pszPhonebook = pInfo->file.pszPath;
  1299. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  1300. if (iSel < 0)
  1301. {
  1302. return;
  1303. }
  1304. pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
  1305. pInfo->hwndLbEntries,
  1306. iSel);
  1307. ASSERT(NULL != pContext);
  1308. pszEntry = ComboBox_GetPsz( pInfo->hwndLbEntries, iSel );
  1309. pInfo->hrasconn = HrasconnFromEntry(
  1310. pContext->pszPhonebookPath,
  1311. pszEntry );
  1312. psz = PszFromId( g_hinstDll,
  1313. (pInfo->hrasconn) ? SID_DU_HangUp : SID_DU_Dial );
  1314. if (psz)
  1315. {
  1316. SetWindowText( pInfo->hwndPbDial, psz );
  1317. Free( psz );
  1318. }
  1319. }
  1320. VOID
  1321. DuUpdateLbEntries(
  1322. IN DUINFO* pInfo,
  1323. IN TCHAR* pszEntry )
  1324. // Update the contents of the entry listbox and set the selection to
  1325. // 'pszEntry'. If there are entries the Properties button is enabled,
  1326. // otherwise it is disabled. 'PInfo' is the dialog context.
  1327. //
  1328. {
  1329. DTLNODE* pNode;
  1330. RASENTRYNAME *pRasEntryNames = NULL;
  1331. DWORD cEntries = 0;
  1332. DWORD cb;
  1333. DWORD dwErr;
  1334. DWORD i;
  1335. RASENTRYNAME ren;
  1336. DUCONTEXT *pContext;
  1337. INT iSel;
  1338. TRACE( "DuUpdateLbEntries" );
  1339. iSel = -1;
  1340. ComboBox_ResetContent( pInfo->hwndLbEntries );
  1341. cb = ren.dwSize = sizeof(RASENTRYNAME);
  1342. //
  1343. // Enumerate entries across all phonebooks. Fix for bug 206467
  1344. //
  1345. dwErr = g_pRasEnumEntries(NULL,
  1346. pInfo->pArgs->pszPhonebook,
  1347. &ren,
  1348. &cb,
  1349. &cEntries);
  1350. if( ( (ERROR_BUFFER_TOO_SMALL == dwErr)
  1351. || (SUCCESS == dwErr))
  1352. && (cb >= sizeof(RASENTRYNAME)))
  1353. {
  1354. pRasEntryNames = (RASENTRYNAME *) Malloc(cb);
  1355. if(NULL == pRasEntryNames)
  1356. {
  1357. // Nothing else can be done in this case
  1358. //
  1359. goto done;
  1360. }
  1361. pRasEntryNames->dwSize = sizeof(RASENTRYNAME);
  1362. dwErr = g_pRasEnumEntries(NULL,
  1363. pInfo->pArgs->pszPhonebook,
  1364. pRasEntryNames,
  1365. &cb,
  1366. &cEntries);
  1367. if(dwErr)
  1368. {
  1369. goto done;
  1370. }
  1371. }
  1372. else
  1373. {
  1374. goto done;
  1375. }
  1376. for(i = 0; i < cEntries; i++)
  1377. {
  1378. pContext = (DUCONTEXT *) Malloc(sizeof(DUCONTEXT));
  1379. if(NULL == pContext)
  1380. {
  1381. dwErr = GetLastError();
  1382. goto done;
  1383. }
  1384. ZeroMemory(pContext, sizeof(DUCONTEXT));
  1385. pContext->pszPhonebookPath =
  1386. StrDup(
  1387. pRasEntryNames[i].szPhonebookPath
  1388. );
  1389. ComboBox_AddItem(pInfo->hwndLbEntries,
  1390. pRasEntryNames[i].szEntryName,
  1391. pContext);
  1392. }
  1393. if (ComboBox_GetCount( pInfo->hwndLbEntries ) >= 0)
  1394. {
  1395. if (pszEntry)
  1396. {
  1397. // Select entry specified by API caller.
  1398. //
  1399. iSel = ComboBox_FindStringExact(
  1400. pInfo->hwndLbEntries, -1, pszEntry );
  1401. }
  1402. if (iSel < 0)
  1403. {
  1404. // Entry not found so default to first item selected.
  1405. //
  1406. iSel = 0;
  1407. }
  1408. if(ComboBox_GetCount(pInfo->hwndLbEntries) > 0)
  1409. {
  1410. ComboBox_SetCurSelNotify( pInfo->hwndLbEntries, iSel );
  1411. }
  1412. }
  1413. done:
  1414. // Enable/disable Properties button based on existence of an entry. See
  1415. // bug 313037.
  1416. //
  1417. if (ComboBox_GetCurSel( pInfo->hwndLbEntries ) >= 0
  1418. && (!pInfo->fNoUser || pInfo->user.fAllowLogonPhonebookEdits))
  1419. {
  1420. EnableWindow( pInfo->hwndPbProperties, TRUE );
  1421. }
  1422. else
  1423. {
  1424. if (GetFocus() == pInfo->hwndPbProperties)
  1425. {
  1426. SetFocus( pInfo->hwndPbDial );
  1427. }
  1428. EnableWindow( pInfo->hwndPbProperties, FALSE );
  1429. }
  1430. ComboBox_AutoSizeDroppedWidth( pInfo->hwndLbEntries );
  1431. Free0(pRasEntryNames);
  1432. }
  1433. VOID
  1434. DuUpdateTitle(
  1435. IN DUINFO* pInfo )
  1436. // Called to update the dialog title to reflect the current phonebook.
  1437. // 'PInfo' is the dialog context.
  1438. //
  1439. {
  1440. TCHAR szBuf[ 256 ];
  1441. TCHAR* psz;
  1442. psz = PszFromId( g_hinstDll, SID_PopupTitle );
  1443. if (psz)
  1444. {
  1445. lstrcpyn( szBuf, psz, sizeof(szBuf) / sizeof(TCHAR) );
  1446. Free( psz );
  1447. }
  1448. else
  1449. {
  1450. *szBuf = TEXT('0');
  1451. }
  1452. if (pInfo->pArgs->pszPhonebook
  1453. || pInfo->user.dwPhonebookMode != PBM_System)
  1454. {
  1455. INT iSel;
  1456. iSel = ComboBox_GetCurSel(pInfo->hwndLbEntries);
  1457. if (iSel >= 0)
  1458. {
  1459. DUCONTEXT *pContext;
  1460. pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
  1461. pInfo->hwndLbEntries, iSel);
  1462. ASSERT( pContext );
  1463. if(NULL != pContext)
  1464. {
  1465. lstrcat( szBuf, TEXT(" - ") );
  1466. lstrcat( szBuf, StripPath( pContext->pszPhonebookPath ) );
  1467. }
  1468. }
  1469. }
  1470. SetWindowText( pInfo->hwndDlg, szBuf );
  1471. }
  1472. VOID
  1473. DuTerm(
  1474. IN HWND hwndDlg )
  1475. // Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
  1476. //
  1477. {
  1478. DUINFO* pInfo;
  1479. DWORD i;
  1480. DWORD cEntries;
  1481. TRACE( "DuTerm" );
  1482. pInfo = (DUINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  1483. if (pInfo)
  1484. {
  1485. // Close ReceiveMonitorThread resources.
  1486. //
  1487. if (pInfo->hThread)
  1488. {
  1489. TRACE( "Set abort event" );
  1490. // Tell thread to wake up and quit...
  1491. //
  1492. pInfo->fAbortMonitor = TRUE;
  1493. CloseHandle( pInfo->hThread );
  1494. // Don't SetEvent before closing the thread handle. On
  1495. // multi-proc systems, the thread will exit so fast (and
  1496. // set hThread to NULL) that CloseHandle will then close
  1497. // an invalid handle.
  1498. //
  1499. SetEvent( pInfo->hEvent );
  1500. // ...and wait for that to happen. A message API (such as
  1501. // PeekMessage) must be called to prevent the thread-to-thread
  1502. // SendMessage in the thread from blocking.
  1503. //
  1504. {
  1505. MSG msg;
  1506. TRACE( "Termination spin..." );
  1507. for (;;)
  1508. {
  1509. PeekMessage( &msg, hwndDlg, 0, 0, PM_NOREMOVE );
  1510. if (!pInfo->hThread)
  1511. {
  1512. break;
  1513. }
  1514. Sleep( 500L );
  1515. }
  1516. TRACE( "Termination spin ends" );
  1517. }
  1518. }
  1519. if (pInfo->hEvent)
  1520. {
  1521. CloseHandle( pInfo->hEvent );
  1522. }
  1523. if (pInfo->pNoUser)
  1524. {
  1525. // Don't leave caller's password floating around in memory.
  1526. //
  1527. ZeroMemory( pInfo->pNoUser->szPassword, PWLEN * sizeof(TCHAR) );
  1528. Free( pInfo->pNoUser );
  1529. // Uninstall input event hooks.
  1530. //
  1531. if (pInfo->hhookMouse)
  1532. {
  1533. UnhookWindowsHookEx( pInfo->hhookMouse );
  1534. }
  1535. if (pInfo->hhookKeyboard)
  1536. {
  1537. UnhookWindowsHookEx( pInfo->hhookKeyboard );
  1538. }
  1539. }
  1540. else if ((pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_UpdateDefaults)
  1541. && pInfo->hwndLbEntries && pInfo->user.fInitialized)
  1542. {
  1543. INT iSel;
  1544. RECT rect;
  1545. // Caller said to update default settings so save the name of the
  1546. // selected entry and the current window position.
  1547. //
  1548. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  1549. if (iSel >= 0)
  1550. {
  1551. DUCONTEXT *pContext;
  1552. PBENTRY* pEntry;
  1553. pContext = (DUCONTEXT* )ComboBox_GetItemDataPtr(
  1554. pInfo->hwndLbEntries, iSel );
  1555. if( (NULL != pContext)
  1556. && (NULL != (pEntry = pContext->pEntry)))
  1557. {
  1558. Free0( pInfo->user.pszDefaultEntry );
  1559. pInfo->user.pszDefaultEntry =
  1560. StrDup( pEntry->pszEntryName );
  1561. }
  1562. }
  1563. if (!SetOffDesktop( pInfo->hwndDlg, SOD_GetOrgRect, &rect ))
  1564. {
  1565. GetWindowRect( pInfo->hwndDlg, &rect );
  1566. }
  1567. pInfo->user.dwXPhonebook = rect.left;
  1568. pInfo->user.dwYPhonebook = rect.top;
  1569. pInfo->user.fDirty = TRUE;
  1570. g_pSetUserPreferences(
  1571. NULL, &pInfo->user, pInfo->fNoUser ? UPM_Logon : UPM_Normal );
  1572. }
  1573. if(NULL != pInfo->hwndLbEntries)
  1574. {
  1575. DUCONTEXT *pContext;
  1576. cEntries = ComboBox_GetCount(pInfo->hwndLbEntries);
  1577. //
  1578. // Free the context stored in the list box
  1579. //
  1580. for(i = 0; i < cEntries; i++)
  1581. {
  1582. pContext = ComboBox_GetItemDataPtr(
  1583. pInfo->hwndLbEntries, i);
  1584. if(NULL != pContext)
  1585. {
  1586. Free0(pContext->pszPhonebookPath);
  1587. }
  1588. Free0(pContext);
  1589. }
  1590. }
  1591. TapiShutdown( pInfo->hlineapp );
  1592. ClosePhonebookFile( &pInfo->file );
  1593. DestroyUserPreferences( &pInfo->user );
  1594. Free( pInfo );
  1595. }
  1596. }
  1597. DWORD
  1598. DuMonitorThread(
  1599. LPVOID pThreadArg )
  1600. // The "main" of the "connect monitor" thread. This thread simply
  1601. // converts Win32 RasConnectionNotification events int WM_RASEVENT style
  1602. // notfications.
  1603. //
  1604. {
  1605. DUINFO* pInfo;
  1606. DWORD dwErr;
  1607. DWORD dwTimeoutMs;
  1608. DWORD dwQuitTick;
  1609. DWORD cInput = 0;
  1610. TRACE( "DuMonitor starting" );
  1611. pInfo = (DUINFO* )pThreadArg;
  1612. if (pInfo->pNoUser && pInfo->pNoUser->dwTimeoutMs != 0)
  1613. {
  1614. TRACE( "DuMonitor quit timer set" );
  1615. dwTimeoutMs = 5000L;
  1616. dwQuitTick = GetTickCount() + pInfo->pNoUser->dwTimeoutMs;
  1617. cInput = g_cInput;
  1618. }
  1619. else
  1620. {
  1621. dwTimeoutMs = INFINITE;
  1622. dwQuitTick = 0;
  1623. }
  1624. // Trigger the event so the other thread has the correct state as of the
  1625. // monitor starting.
  1626. //
  1627. SetEvent( pInfo->hEvent );
  1628. for (;;)
  1629. {
  1630. dwErr = WaitForSingleObject( pInfo->hEvent, dwTimeoutMs );
  1631. if (pInfo->fAbortMonitor)
  1632. {
  1633. break;
  1634. }
  1635. if (dwErr == WAIT_TIMEOUT)
  1636. {
  1637. if (g_cInput > cInput)
  1638. {
  1639. TRACE( "Input restarts timer" );
  1640. cInput = g_cInput;
  1641. dwQuitTick = GetTickCount() + pInfo->pNoUser->dwTimeoutMs;
  1642. }
  1643. else if (GetTickCount() >= dwQuitTick)
  1644. {
  1645. TRACE( "/DuMonitor SendMessage(WM_NOUSERTIMEOUT)" );
  1646. SendMessage( pInfo->hwndDlg, WM_NOUSERTIMEOUT, 0, 0 );
  1647. TRACE( "\\DuMonitor SendMessage(WM_NOUSERTIMEOUT) done" );
  1648. break;
  1649. }
  1650. }
  1651. else
  1652. {
  1653. TRACE( "/DuMonitor SendMessage(WM_RASEVENT)" );
  1654. SendMessage( pInfo->hwndDlg, WM_RASEVENT, 0, 0 );
  1655. TRACE( "\\DuMonitor SendMessage(WM_RASEVENT) done" );
  1656. }
  1657. }
  1658. // This clues the other thread that all interesting work has been done.
  1659. //
  1660. pInfo->hThread = NULL;
  1661. TRACE( "DuMonitor terminating" );
  1662. return 0;
  1663. }
  1664. DWORD
  1665. DuGetEntry(
  1666. DUINFO* pInfo,
  1667. DUCONTEXT* pContext )
  1668. {
  1669. DWORD dwErr = ERROR_SUCCESS;
  1670. DWORD dwReadPbkFlags = 0;
  1671. LPTSTR pszEntryName;
  1672. DTLNODE *pdtlnode;
  1673. PBFILE file;
  1674. ASSERT(NULL != pContext);
  1675. pContext->pEntry = NULL;
  1676. pszEntryName = ComboBox_GetPsz(pInfo->hwndLbEntries,
  1677. ComboBox_GetCurSel(pInfo->hwndLbEntries));
  1678. if (pInfo->fNoUser)
  1679. {
  1680. dwReadPbkFlags |= RPBF_NoUser;
  1681. }
  1682. if( (NULL != pInfo->file.pszPath)
  1683. && (0 == lstrcmpi(pContext->pszPhonebookPath,
  1684. pInfo->file.pszPath)))
  1685. {
  1686. //
  1687. // We already have the phonebook file open
  1688. //
  1689. pdtlnode = EntryNodeFromName(
  1690. pInfo->file.pdtllistEntries,
  1691. pszEntryName);
  1692. ASSERT(NULL != pdtlnode);
  1693. }
  1694. else
  1695. {
  1696. //
  1697. // phonebook file changed. So close the existing phone
  1698. // book file and open the one in which the entry
  1699. // belongs
  1700. //
  1701. if(NULL != pInfo->file.pszPath)
  1702. {
  1703. ClosePhonebookFile(&pInfo->file);
  1704. }
  1705. dwErr = GetPbkAndEntryName(pContext->pszPhonebookPath,
  1706. pszEntryName,
  1707. dwReadPbkFlags,
  1708. &file,
  1709. &pdtlnode);
  1710. if(dwErr)
  1711. {
  1712. goto done;
  1713. }
  1714. ASSERT(NULL != pdtlnode);
  1715. CopyMemory(&pInfo->file, &file, sizeof(PBFILE));
  1716. }
  1717. if (pdtlnode)
  1718. {
  1719. pContext->pEntry = (PBENTRY *) DtlGetData(pdtlnode);
  1720. }
  1721. else
  1722. {
  1723. dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
  1724. }
  1725. done:
  1726. return dwErr;
  1727. }
  1728. DWORD
  1729. DwGetEapLogonInfo(
  1730. VOID *pv,
  1731. EAPLOGONINFO **ppEapLogonInfo )
  1732. {
  1733. EAPLOGONINFO *pEapLogonInfo = NULL;
  1734. DWORD retcode = SUCCESS;
  1735. struct EAPINFO
  1736. {
  1737. DWORD dwSizeofEapInfo;
  1738. PBYTE pbEapInfo;
  1739. DWORD dwSizeofPINInfo;
  1740. PBYTE pbPINInfo;
  1741. };
  1742. struct EAPINFO *pEapInfo = (struct EAPINFO *) pv;
  1743. DWORD dwSize;
  1744. if(NULL == pv)
  1745. {
  1746. retcode = E_INVALIDARG;
  1747. goto done;
  1748. }
  1749. dwSize = sizeof(EAPLOGONINFO)
  1750. + pEapInfo->dwSizeofEapInfo
  1751. + pEapInfo->dwSizeofPINInfo;
  1752. pEapLogonInfo = (EAPLOGONINFO *) Malloc(dwSize);
  1753. if(NULL == pEapLogonInfo)
  1754. {
  1755. retcode = GetLastError();
  1756. TRACE1("Failed to Allocate EapLogonInfo. rc=0x%x",
  1757. retcode);
  1758. goto done;
  1759. }
  1760. ZeroMemory(pEapLogonInfo, dwSize);
  1761. //
  1762. // Set up the fields in pEapLogonInfo by
  1763. // flattening out the information passed
  1764. // in.
  1765. //
  1766. pEapLogonInfo->dwSize = dwSize;
  1767. pEapLogonInfo->dwLogonInfoSize =
  1768. pEapInfo->dwSizeofEapInfo;
  1769. pEapLogonInfo->dwOffsetLogonInfo =
  1770. FIELD_OFFSET(EAPLOGONINFO, abdata);
  1771. memcpy( pEapLogonInfo->abdata,
  1772. pEapInfo->pbEapInfo,
  1773. pEapInfo->dwSizeofEapInfo);
  1774. pEapLogonInfo->dwPINInfoSize =
  1775. pEapInfo->dwSizeofPINInfo;
  1776. pEapLogonInfo->dwOffsetPINInfo =
  1777. FIELD_OFFSET(EAPLOGONINFO, abdata)
  1778. + pEapInfo->dwSizeofEapInfo;
  1779. memcpy( (PBYTE)
  1780. ((PBYTE) pEapLogonInfo
  1781. + pEapLogonInfo->dwOffsetPINInfo),
  1782. pEapInfo->pbPINInfo,
  1783. pEapInfo->dwSizeofPINInfo);
  1784. done:
  1785. *ppEapLogonInfo = pEapLogonInfo;
  1786. return retcode;
  1787. }