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.

2184 lines
56 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. RtlSecureZeroMemory( 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 = GetProp( hwnd, TEXT("TweakTitleBar_Small_Icon"));
  499. ASSERT(hIcon);
  500. if( hIcon )
  501. {
  502. DestroyIcon(hIcon);
  503. }
  504. else
  505. {
  506. TRACE("DuDlgProc:Destroy small Icon failed");
  507. }
  508. RemoveProp( hwnd, TEXT("TweakTitleBar_Small_Icon") );
  509. hIcon = GetProp( hwnd, TEXT("TweakTitleBar_Big_Icon"));
  510. ASSERT(hIcon);
  511. if( hIcon )
  512. {
  513. DestroyIcon(hIcon);
  514. }
  515. else
  516. {
  517. TRACE("DuDlgProc:Destroy Big Icon failed");
  518. }
  519. RemoveProp( hwnd, TEXT("TweakTitleBar_Big_Icon") );
  520. }
  521. */
  522. break;
  523. }
  524. }
  525. return FALSE;
  526. }
  527. BOOL
  528. DuCommand(
  529. IN DUINFO* pInfo,
  530. IN WORD wNotification,
  531. IN WORD wId,
  532. IN HWND hwndCtrl )
  533. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  534. // is the notification code of the command. 'wId' is the control/menu
  535. // identifier of the command. 'HwndCtrl' is the control window handle of
  536. // the command.
  537. //
  538. // Returns true if processed message, false otherwise.
  539. //
  540. {
  541. TRACE3( "DuCommand(n=%d,i=%d,c=$%x)",
  542. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  543. switch (wId)
  544. {
  545. case CID_DU_PB_Dial:
  546. {
  547. if (pInfo->hrasconn)
  548. {
  549. DuHangUpSelectedEntry( pInfo );
  550. }
  551. else
  552. {
  553. DuDialSelectedEntry( pInfo );
  554. }
  555. return TRUE;
  556. }
  557. case CID_DU_PB_New:
  558. {
  559. DuNewEntry( pInfo, FALSE );
  560. return TRUE;
  561. }
  562. case CID_DU_PB_More:
  563. {
  564. DuEditSelectedEntry( pInfo );
  565. return TRUE;
  566. }
  567. case CID_DU_LB_Entries:
  568. {
  569. if (wNotification == CBN_SELCHANGE)
  570. {
  571. PBENTRY *pEntry;
  572. DWORD dwErr = SUCCESS;
  573. DUCONTEXT *pContext;
  574. pContext = (DUCONTEXT *)
  575. ComboBox_GetItemDataPtr(
  576. pInfo->hwndLbEntries,
  577. ComboBox_GetCurSel(pInfo->hwndLbEntries));
  578. ASSERT(NULL != pContext);
  579. if(NULL == pContext)
  580. {
  581. return TRUE;
  582. }
  583. //
  584. // Update the phonebook information
  585. //
  586. dwErr = DuGetEntry(pInfo, pContext);
  587. if(ERROR_SUCCESS == dwErr)
  588. {
  589. ComboBox_SetItemData(
  590. pInfo->hwndLbEntries,
  591. ComboBox_GetCurSel(pInfo->hwndLbEntries),
  592. pContext);
  593. }
  594. else
  595. {
  596. ComboBox_DeleteString(
  597. pInfo->hwndLbEntries,
  598. ComboBox_GetCurSel(pInfo->hwndLbEntries) );
  599. }
  600. DuUpdateConnectStatus( pInfo );
  601. return TRUE;
  602. }
  603. break;
  604. }
  605. case IDCANCEL:
  606. case CID_DU_PB_Close:
  607. {
  608. EndDialog( pInfo->hwndDlg, TRUE );
  609. return TRUE;
  610. }
  611. }
  612. return FALSE;
  613. }
  614. VOID
  615. DuDialSelectedEntry(
  616. IN DUINFO* pInfo )
  617. // Called when user presses the "Dial" button.
  618. //
  619. {
  620. DWORD dwErr;
  621. BOOL fConnected;
  622. BOOL fAutoLogon;
  623. TCHAR* pszEbNumber;
  624. TCHAR* pszEbPreview;
  625. TCHAR* pszOrgPreview;
  626. TCHAR* pszOverride;
  627. TCHAR* pszEntryName;
  628. RASDIALDLG info;
  629. INTERNALARGS iargs;
  630. PBENTRY* pEntry;
  631. DTLNODE *pdtlnode;
  632. PBFILE file;
  633. DUCONTEXT *pContext;
  634. TRACE( "DuDialSelectedEntry" );
  635. // Look up the selected entry.
  636. //
  637. pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
  638. pInfo->hwndLbEntries,
  639. ComboBox_GetCurSel(pInfo->hwndLbEntries));
  640. if (!pContext)
  641. {
  642. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  643. SetFocus( pInfo->hwndPbNew );
  644. return;
  645. }
  646. pEntry = pContext->pEntry;
  647. if (!pEntry)
  648. {
  649. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  650. SetFocus( pInfo->hwndPbNew );
  651. return;
  652. }
  653. pszOverride = NULL;
  654. pszOrgPreview = NULL;
  655. pszEbPreview = NULL;
  656. pszEbNumber = NULL;
  657. // Set up API argument block.
  658. //
  659. ZeroMemory( &info, sizeof(info) );
  660. info.dwSize = sizeof(info);
  661. info.hwndOwner = pInfo->hwndDlg;
  662. // The secret hack to share information already loaded with the entry API.
  663. //
  664. ZeroMemory( &iargs, sizeof(iargs) );
  665. iargs.pFile = &pInfo->file;
  666. iargs.pUser = &pInfo->user;
  667. iargs.pNoUser = pInfo->pNoUser;
  668. iargs.fNoUser = pInfo->fNoUser;
  669. iargs.fForceCloseOnDial =
  670. (pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_ForceCloseOnDial);
  671. iargs.pvEapInfo = NULL;
  672. if(0 != pInfo->pArgs->pApiArgs->reserved2)
  673. {
  674. DWORD retcode;
  675. EAPLOGONINFO *pEapInfo = NULL;
  676. retcode = DwGetEapLogonInfo(
  677. (VOID *) pInfo->pArgs->pApiArgs->reserved2,
  678. &pEapInfo);
  679. if(SUCCESS == retcode)
  680. {
  681. iargs.pvEapInfo = (VOID *) pEapInfo;
  682. }
  683. }
  684. iargs.fMoveOwnerOffDesktop =
  685. (iargs.fForceCloseOnDial || pInfo->user.fCloseOnDial);
  686. info.reserved = (ULONG_PTR ) &iargs;
  687. // Call the Win32 API to run the connect status dialog. Make a copy of
  688. // the entry name and auto-logon flag first, because RasDialDlg may
  689. // re-read the entry node to pick up RASAPI changes.
  690. //
  691. pszEntryName = StrDup( pEntry->pszEntryName );
  692. fAutoLogon = pEntry->fAutoLogon;
  693. TRACEW1( "RasDialDlg,o=\"%s\"", (pszOverride) ? pszOverride : TEXT("") );
  694. //For whistler bug 426268 gangz
  695. //
  696. fConnected = RasDialDlg(
  697. pContext->pszPhonebookPath,
  698. /*pEntry->pszEntryName*/
  699. pszEntryName,
  700. pszOverride,
  701. &info );
  702. TRACE1( "RasDialDlg=%d", fConnected );
  703. Free0( pszEbPreview );
  704. Free0( pszOrgPreview );
  705. if(NULL != iargs.pvEapInfo)
  706. {
  707. Free0(iargs.pvEapInfo);
  708. iargs.pvEapInfo = NULL;
  709. }
  710. if (fConnected)
  711. {
  712. pInfo->pArgs->fApiResult = TRUE;
  713. if (pInfo->pArgs->pApiArgs->pCallback)
  714. {
  715. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  716. if (pInfo->pNoUser && iargs.fNoUserChanged && fAutoLogon)
  717. {
  718. // Whistler bug 254385 encode password when not being used
  719. // Need to Decode password before callback function
  720. // Assumed password was encoded previously by DuInit()
  721. //
  722. DecodePassword( pInfo->pNoUser->szPassword );
  723. TRACE( "Callback(NoUserEdit)" );
  724. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  725. RASPBDEVENT_NoUserEdit, NULL, pInfo->pNoUser );
  726. TRACE( "Callback(NoUserEdit) done" );
  727. EncodePassword( pInfo->pNoUser->szPassword );
  728. }
  729. TRACE( "Callback(DialEntry)" );
  730. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  731. RASPBDEVENT_DialEntry, pszEntryName, NULL );
  732. TRACE( "Callback(DialEntry) done" );
  733. }
  734. if (pInfo->user.fCloseOnDial
  735. || (pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_ForceCloseOnDial))
  736. {
  737. EndDialog( pInfo->hwndDlg, TRUE );
  738. }
  739. }
  740. else
  741. {
  742. DuHandleConnectFailure(pInfo, &info);
  743. }
  744. if (pInfo->pNoUser && !pInfo->hThread)
  745. {
  746. TRACE( "Taking shortcut to exit" );
  747. return;
  748. }
  749. // Reload the list even if the Dial was cancelled as user may have changed
  750. // the current PBENTRY with the Properties button on the dialer which
  751. // commits changes even if user cancels the dial itself. See bug 363710.
  752. //
  753. DuUpdateLbEntries( pInfo, pszEntryName );
  754. SetFocus( pInfo->hwndLbEntries );
  755. Free0( pszEntryName );
  756. }
  757. VOID
  758. DuEditSelectedEntry(
  759. IN DUINFO* pInfo )
  760. // Called when user selects "Edit entry" from the menu. 'PInfo' is the
  761. // dialog context. 'PszEntry' is the name of the entry to edit.
  762. //
  763. {
  764. BOOL fOk;
  765. RASENTRYDLG info;
  766. INTERNALARGS iargs;
  767. PBENTRY* pEntry;
  768. LPTSTR pszEntryName;
  769. DTLNODE *pdtlnode;
  770. PBFILE file;
  771. DWORD dwErr;
  772. DUCONTEXT *pContext;
  773. INT iSel;
  774. TRACE( "DuEditSelectedEntry" );
  775. // Look up the selected entry.
  776. //
  777. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  778. if (iSel < 0)
  779. {
  780. return;
  781. }
  782. pContext = (DUCONTEXT * )ComboBox_GetItemDataPtr(
  783. pInfo->hwndLbEntries, iSel );
  784. ASSERT(NULL != pContext);
  785. if(NULL == pContext)
  786. {
  787. return;
  788. }
  789. ASSERT(NULL != pContext->pszPhonebookPath);
  790. pEntry = pContext->pEntry;
  791. if (!pEntry)
  792. {
  793. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  794. SetFocus( pInfo->hwndPbNew );
  795. return;
  796. }
  797. // Set up API argument block.
  798. //
  799. ZeroMemory( &info, sizeof(info) );
  800. info.dwSize = sizeof(info);
  801. info.hwndOwner = pInfo->hwndDlg;
  802. {
  803. RECT rect;
  804. info.dwFlags = RASEDFLAG_PositionDlg;
  805. GetWindowRect( pInfo->hwndDlg, &rect );
  806. info.xDlg = rect.left + DXSHEET;
  807. info.yDlg = rect.top + DYSHEET;
  808. }
  809. // The secret hack to share information already loaded with the entry API.
  810. //
  811. ZeroMemory( &iargs, sizeof(iargs) );
  812. iargs.pFile = &pInfo->file;
  813. iargs.pUser = &pInfo->user;
  814. iargs.pNoUser = pInfo->pNoUser;
  815. iargs.fNoUser = pInfo->fNoUser;
  816. info.reserved = (ULONG_PTR ) &iargs;
  817. // Call the Win32 API to run the entry property sheet.
  818. //
  819. TRACE( "RasEntryDlg" );
  820. fOk = RasEntryDlg(
  821. pContext->pszPhonebookPath, pEntry->pszEntryName, &info );
  822. TRACE1( "RasEntryDlg=%d", fOk );
  823. if (pInfo->pNoUser && !pInfo->hThread)
  824. {
  825. TRACE( "Taking shortcut to exit" );
  826. return;
  827. }
  828. if (fOk)
  829. {
  830. TRACEW1( "OK pressed,e=\"%s\"", info.szEntry );
  831. if (pInfo->pArgs->pApiArgs->pCallback)
  832. {
  833. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  834. TRACE( "Callback(EditEntry)" );
  835. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  836. RASPBDEVENT_AddEntry, info.szEntry, NULL );
  837. TRACE( "Callback(EditEntry) done" );
  838. }
  839. DuUpdateLbEntries( pInfo, info.szEntry );
  840. SetFocus( pInfo->hwndLbEntries );
  841. }
  842. else
  843. {
  844. TRACE( "Cancel pressed or error" );
  845. }
  846. }
  847. //
  848. // Helper function called by DuDialSelectedEntry to handle errors
  849. // returned from RasDialDlgW
  850. //
  851. DWORD
  852. DuHandleConnectFailure(
  853. IN DUINFO* pInfo,
  854. IN RASDIALDLG* pDialInfo)
  855. {
  856. TRACE3(
  857. "DuHandleConnectFailure: nu=%x, r2=%x, de=%x",
  858. (pInfo->pNoUser),
  859. (pInfo->pArgs->pApiArgs->reserved2),
  860. (pDialInfo->dwError));
  861. // XP: 384968
  862. //
  863. // Handle the bad-PIN error from winlogon
  864. //
  865. // Normally, the smart card PIN is gotten by calling EAP-TLS's identity
  866. // api. This API raises UI and validates the PIN entered.
  867. //
  868. // During winlogon, however, the smart card PIN is passed to us from GINA.
  869. // In this case it is not validated until we call EAP API's. (actually,
  870. // it's until we call the eap identity api with RAS_EAP_FLAG_LOGON.
  871. // This flag tells EAP not to raise any UI but instead to use the info
  872. // passed from GINA)
  873. //
  874. // GINA is not able to validate the PIN itself because it does not call any
  875. // CAPI's directly. Oh well.
  876. //
  877. // If RasDialDlg returns a bad pin error, then we should gracefully fail
  878. // back to winlogon.
  879. //
  880. if ((pInfo->pNoUser) && // called by winlogon
  881. (pInfo->pArgs->pApiArgs->reserved2) && // for smart card
  882. (RAS_SC_IS_BAD_PIN(pDialInfo->dwError))) // but pin is bad
  883. {
  884. pInfo->pArgs->pApiArgs->dwError = pDialInfo->dwError;
  885. EndDialog( pInfo->hwndDlg, TRUE );
  886. }
  887. return NO_ERROR;
  888. }
  889. VOID
  890. DuHangUpSelectedEntry(
  891. IN DUINFO* pInfo )
  892. // Hang up the selected entry after confirming with user. 'Pinfo' is the
  893. // dialog context block.
  894. //
  895. {
  896. DWORD dwErr;
  897. PBENTRY* pEntry;
  898. INT iSel;
  899. INT nResponse;
  900. MSGARGS msgargs;
  901. LPTSTR pszEntryName;
  902. DTLNODE *pdtlnode;
  903. DUCONTEXT *pContext;
  904. TRACE( "DuHangUpSelectedEntry" );
  905. // Look up the selected entry.
  906. //
  907. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  908. ASSERT( iSel >= 0 );
  909. pContext = (DUCONTEXT * )ComboBox_GetItemDataPtr( pInfo->hwndLbEntries, iSel );
  910. ASSERT(NULL != pContext);
  911. if (!pContext)
  912. {
  913. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  914. SetFocus( pInfo->hwndPbNew );
  915. return;
  916. }
  917. pEntry = pContext->pEntry;
  918. ASSERT( pEntry );
  919. if (!pEntry)
  920. {
  921. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  922. SetFocus( pInfo->hwndPbNew );
  923. return;
  924. }
  925. ZeroMemory( &msgargs, sizeof(msgargs) );
  926. msgargs.apszArgs[ 0 ] = pEntry->pszEntryName;
  927. msgargs.dwFlags = MB_YESNO | MB_ICONEXCLAMATION;
  928. nResponse = MsgDlg( pInfo->hwndDlg, SID_ConfirmHangUp, &msgargs );
  929. if (nResponse == IDYES)
  930. {
  931. ASSERT( g_pRasHangUp );
  932. TRACE( "RasHangUp" );
  933. dwErr = g_pRasHangUp( pInfo->hrasconn );
  934. TRACE1( "RasHangUp=%d", dwErr );
  935. if ( dwErr == ERROR_HANGUP_FAILED )
  936. {
  937. MsgDlg( pInfo->hwndDlg, SID_CantHangUpRouter, NULL );
  938. }
  939. }
  940. }
  941. BOOL
  942. DuInit(
  943. IN HWND hwndDlg,
  944. IN DUARGS* pArgs )
  945. // Called on WM_INITDIALOG. 'hwndDlg' is the handle of the phonebook
  946. // dialog window. 'pArgs' points at caller's arguments as passed to the
  947. // API (or thunk).
  948. //
  949. // Return false if focus was set, true otherwise, i.e. as defined for
  950. // WM_INITDIALOG.
  951. //
  952. {
  953. DWORD dwErr;
  954. DWORD dwThreadId;
  955. DWORD dwReadPbkFlags = 0;
  956. DUINFO* pInfo;
  957. TRACE( "DuInit" );
  958. // Allocate the dialog context block. Initialize minimally for proper
  959. // cleanup, then attach to the dialog window.
  960. //
  961. {
  962. pInfo = Malloc( sizeof(*pInfo) );
  963. if (!pInfo)
  964. {
  965. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  966. pArgs->pApiArgs->dwError = ERROR_NOT_ENOUGH_MEMORY;
  967. EndDialog( hwndDlg, TRUE );
  968. return TRUE;
  969. }
  970. ZeroMemory( pInfo, sizeof(*pInfo) );
  971. pInfo->file.hrasfile = -1;
  972. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  973. TRACE( "Context set" );
  974. }
  975. pInfo->pArgs = pArgs;
  976. pInfo->hwndDlg = hwndDlg;
  977. // Position the dialog per caller's instructions.
  978. //
  979. PositionDlg( hwndDlg,
  980. pArgs->pApiArgs->dwFlags & RASPBDFLAG_PositionDlg,
  981. pArgs->pApiArgs->xDlg, pArgs->pApiArgs->yDlg );
  982. // Load RAS DLL entrypoints which starts RASMAN, if necessary. There must
  983. // be no API calls that require RASAPI32 or RASMAN prior to this point.
  984. //
  985. dwErr = LoadRas( g_hinstDll, hwndDlg );
  986. if (dwErr != 0)
  987. {
  988. ErrorDlg( hwndDlg, SID_OP_LoadRas, dwErr, NULL );
  989. pArgs->pApiArgs->dwError = dwErr;
  990. EndDialog( hwndDlg, TRUE );
  991. return TRUE;
  992. }
  993. if(0 != (pArgs->pApiArgs->dwFlags & RASPBDFLAG_NoUser))
  994. {
  995. // Popup TAPI's "first location" dialog if they are uninitialized.
  996. //
  997. dwErr = TapiNoLocationDlg( g_hinstDll, &pInfo->hlineapp, hwndDlg );
  998. if (dwErr != 0)
  999. {
  1000. // Error here is treated as a "cancel" per bug 288385.
  1001. //
  1002. pArgs->pApiArgs->dwError = 0;
  1003. EndDialog( hwndDlg, TRUE );
  1004. return TRUE;
  1005. }
  1006. }
  1007. pInfo->hwndLbEntries = GetDlgItem( hwndDlg, CID_DU_LB_Entries );
  1008. ASSERT( pInfo->hwndLbEntries );
  1009. pInfo->hwndPbDial = GetDlgItem( hwndDlg, CID_DU_PB_Dial );
  1010. ASSERT( pInfo->hwndPbDial );
  1011. pInfo->hwndPbNew = GetDlgItem( hwndDlg, CID_DU_PB_New );
  1012. ASSERT( pInfo->hwndPbNew );
  1013. pInfo->hwndPbProperties = GetDlgItem( hwndDlg, CID_DU_PB_More );
  1014. ASSERT( pInfo->hwndPbProperties );
  1015. pInfo->fNoUser = (pArgs->pApiArgs->dwFlags & RASPBDFLAG_NoUser );
  1016. // Setting this global flag indicates that WinHelp will not work in the
  1017. // current mode. See common\uiutil\ui.c. We assume here that only the
  1018. // WinLogon process makes use of this.
  1019. //
  1020. {
  1021. extern BOOL g_fNoWinHelp;
  1022. g_fNoWinHelp = pInfo->fNoUser;
  1023. }
  1024. // Read user preferences from registry.
  1025. //
  1026. dwErr = g_pGetUserPreferences(
  1027. NULL, &pInfo->user, pInfo->fNoUser ? UPM_Logon : UPM_Normal);
  1028. if (dwErr != 0)
  1029. {
  1030. //
  1031. // The following free causes a crash in DuTerm. This context will be
  1032. // freed in DuTerm - raos.
  1033. //
  1034. // Free( pInfo );
  1035. ErrorDlg( hwndDlg, SID_OP_LoadPrefs, dwErr, NULL );
  1036. EndDialog( hwndDlg, TRUE );
  1037. return TRUE;
  1038. }
  1039. // Load and parse phonebook file.
  1040. //
  1041. if (pInfo->fNoUser)
  1042. {
  1043. dwReadPbkFlags |= RPBF_NoUser;
  1044. }
  1045. dwErr = ReadPhonebookFile(
  1046. pArgs->pszPhonebook,
  1047. &pInfo->user,
  1048. NULL,
  1049. dwReadPbkFlags,
  1050. &pInfo->file );
  1051. if (dwErr != 0)
  1052. {
  1053. // The following free causes a crash in DuTerm. This context will be
  1054. // freed in DuTerm - raos.
  1055. //
  1056. // Free( pInfo );
  1057. ErrorDlg( hwndDlg, SID_OP_LoadPhonebook, dwErr, NULL );
  1058. EndDialog( hwndDlg, TRUE );
  1059. return TRUE;
  1060. }
  1061. if (pArgs->pApiArgs->pCallback && !pArgs->pszPhonebook)
  1062. {
  1063. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  1064. // Tell user the path to the default phonebook file.
  1065. //
  1066. TRACE( "Callback(EditGlobals)" );
  1067. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  1068. RASPBDEVENT_EditGlobals, pInfo->file.pszPath, NULL );
  1069. TRACE( "Callback(EditGlobals) done" );
  1070. }
  1071. if (pInfo->fNoUser)
  1072. {
  1073. // Retrieve logon information from caller via callback.
  1074. //
  1075. if (pArgs->pApiArgs->pCallback)
  1076. {
  1077. RASPBDLGFUNCW pfunc = pArgs->pApiArgs->pCallback;
  1078. pInfo->pNoUser = Malloc( sizeof(RASNOUSERW) );
  1079. if (pInfo->pNoUser)
  1080. {
  1081. ZeroMemory( pInfo->pNoUser, sizeof(*pInfo->pNoUser) );
  1082. pInfo->pNoUser->dwSize = sizeof(*pInfo->pNoUser);
  1083. TRACE( "Callback(NoUser)" );
  1084. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  1085. RASPBDEVENT_NoUser, NULL, pInfo->pNoUser );
  1086. TRACE1( "Callback(NoUser) done,to=%d",
  1087. pInfo->pNoUser->dwTimeoutMs );
  1088. TRACEW1( "U=%s",pInfo->pNoUser->szUserName );
  1089. TRACEW1( "D=%s",pInfo->pNoUser->szDomain );
  1090. // Whistler bug 254385 encode password when not being used
  1091. // Assumed password was not encoded during callback
  1092. //
  1093. EncodePassword( pInfo->pNoUser->szPassword );
  1094. // Install input detection hooks.
  1095. //
  1096. if (pInfo->pNoUser->dwTimeoutMs > 0)
  1097. {
  1098. pInfo->hhookMouse = SetWindowsHookEx(
  1099. WH_MOUSE, DuInputHook, g_hinstDll,
  1100. GetCurrentThreadId() );
  1101. pInfo->hhookKeyboard = SetWindowsHookEx(
  1102. WH_KEYBOARD, DuInputHook, g_hinstDll,
  1103. GetCurrentThreadId() );
  1104. }
  1105. }
  1106. }
  1107. if (!pInfo->user.fAllowLogonPhonebookEdits)
  1108. {
  1109. // Disable new button. See also similar logic for the Properties
  1110. // button occurs in DuUpdateLbEntries.
  1111. //
  1112. EnableWindow( pInfo->hwndPbNew, FALSE );
  1113. }
  1114. }
  1115. // Load the list of phonebook entries and set selection.
  1116. //
  1117. DuUpdateLbEntries( pInfo, pInfo->pArgs->pszEntry );
  1118. if (!pInfo->pArgs->pszEntry)
  1119. {
  1120. if (ComboBox_GetCount( pInfo->hwndLbEntries ) > 0)
  1121. {
  1122. ComboBox_SetCurSelNotify( pInfo->hwndLbEntries, 0 );
  1123. }
  1124. }
  1125. // Update the title to reflect the phonebook mode.
  1126. //
  1127. DuUpdateTitle( pInfo );
  1128. // Adjust the title bar widgets and create the wizard bitmap.
  1129. //
  1130. TweakTitleBar( hwndDlg );
  1131. AddContextHelpButton( hwndDlg );
  1132. // Start the connect monitor.
  1133. //
  1134. if ((pInfo->hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ))
  1135. && (pInfo->hThread = CreateThread(
  1136. NULL, 0, DuMonitorThread, (LPVOID )pInfo, 0,
  1137. (LPDWORD )&dwThreadId )))
  1138. {
  1139. ASSERT( g_pRasConnectionNotification );
  1140. TRACE( "RasConnectionNotification" );
  1141. dwErr = g_pRasConnectionNotification(
  1142. INVALID_HANDLE_VALUE, pInfo->hEvent,
  1143. RASCN_Connection | RASCN_Disconnection );
  1144. TRACE1( "RasConnectionNotification=%d", dwErr );
  1145. }
  1146. else
  1147. TRACE( "Monitor DOA" );
  1148. if (ComboBox_GetCount( pInfo->hwndLbEntries ) == 0)
  1149. {
  1150. // The phonebook is empty.
  1151. //
  1152. if (pInfo->fNoUser
  1153. && !pInfo->user.fAllowLogonPhonebookEdits
  1154. )
  1155. {
  1156. // Tell the user you can't create an entry or locations during
  1157. // startup.
  1158. //
  1159. MsgDlg( hwndDlg, SID_EmptyLogonPb, NULL );
  1160. EndDialog( hwndDlg, TRUE );
  1161. return TRUE;
  1162. }
  1163. else
  1164. {
  1165. if(pInfo->fNoUser)
  1166. {
  1167. dwErr = TapiNoLocationDlg( g_hinstDll,
  1168. &pInfo->hlineapp, hwndDlg );
  1169. if (dwErr != 0)
  1170. {
  1171. // Error here is treated as a "cancel" per bug 288385.
  1172. //
  1173. pArgs->pApiArgs->dwError = 0;
  1174. EndDialog( hwndDlg, TRUE );
  1175. return TRUE;
  1176. }
  1177. }
  1178. // Tell the user, then automatically start him into adding a new
  1179. // entry. Set initial focus to "New" button first, in case user
  1180. // cancels out.
  1181. //
  1182. SetFocus( pInfo->hwndPbNew );
  1183. MsgDlg( hwndDlg, SID_EmptyPhonebook, NULL );
  1184. DuNewEntry( pInfo, FALSE );
  1185. }
  1186. }
  1187. else
  1188. {
  1189. // Set initial focus to the non-empty entry listbox.
  1190. //
  1191. SetFocus( pInfo->hwndLbEntries );
  1192. }
  1193. return FALSE;
  1194. }
  1195. LRESULT CALLBACK
  1196. DuInputHook(
  1197. IN int nCode,
  1198. IN WPARAM wparam,
  1199. IN LPARAM lparam )
  1200. // Standard Win32 'MouseProc' or 'KeyboardProc' callback. For our simple
  1201. // processing we can take advantage of them having identical arguments and
  1202. // 'nCode' definitions.
  1203. //
  1204. {
  1205. if (nCode == HC_ACTION)
  1206. {
  1207. ++g_cInput;
  1208. }
  1209. return 0;
  1210. }
  1211. VOID
  1212. DuNewEntry(
  1213. IN DUINFO* pInfo,
  1214. IN BOOL fClone )
  1215. // Called when user presses the "New" button or "Clone" menu item.
  1216. // 'PInfo' is the dialog context. 'FClone' is set to clone the selected
  1217. // entry, otherwise an empty entry is created.
  1218. //
  1219. {
  1220. BOOL fOk;
  1221. TCHAR* pszEntry;
  1222. RASENTRYDLG info;
  1223. INTERNALARGS iargs;
  1224. PBENTRY* pEntry;
  1225. TRACE1( "DuNewEntry(f=%d)", fClone );
  1226. ZeroMemory( &info, sizeof(info) );
  1227. info.dwSize = sizeof(info);
  1228. info.hwndOwner = pInfo->hwndDlg;
  1229. if (fClone)
  1230. {
  1231. DUCONTEXT *pContext;
  1232. // Look up the selected entry.
  1233. //
  1234. pContext = (DUCONTEXT* )ComboBox_GetItemDataPtr(
  1235. pInfo->hwndLbEntries, ComboBox_GetCurSel( pInfo->hwndLbEntries ) );
  1236. if (!pContext)
  1237. {
  1238. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  1239. SetFocus( pInfo->hwndPbNew );
  1240. return;
  1241. }
  1242. pEntry = pContext->pEntry;
  1243. if (!pEntry)
  1244. {
  1245. MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
  1246. SetFocus( pInfo->hwndPbNew );
  1247. return;
  1248. }
  1249. pszEntry = pEntry->pszEntryName;
  1250. info.dwFlags = RASEDFLAG_CloneEntry;
  1251. }
  1252. else
  1253. {
  1254. pszEntry = NULL;
  1255. info.dwFlags = RASEDFLAG_NewEntry;
  1256. }
  1257. {
  1258. RECT rect;
  1259. GetWindowRect( pInfo->hwndDlg, &rect );
  1260. info.dwFlags += RASEDFLAG_PositionDlg;
  1261. info.xDlg = rect.left + DXSHEET;
  1262. info.yDlg = rect.top + DYSHEET;
  1263. }
  1264. // The secret hack to share information already loaded with the entry API.
  1265. //
  1266. ZeroMemory( &iargs, sizeof(iargs) );
  1267. iargs.pFile = &pInfo->file;
  1268. iargs.pUser = &pInfo->user;
  1269. iargs.pNoUser = pInfo->pNoUser;
  1270. iargs.fNoUser = pInfo->fNoUser;
  1271. info.reserved = (ULONG_PTR ) &iargs;
  1272. // Call the Win32 API to run the add entry wizard.
  1273. //
  1274. TRACE( "RasEntryDlg" );
  1275. fOk = RasEntryDlg( pInfo->pArgs->pszPhonebook, pszEntry, &info );
  1276. TRACE1( "RasEntryDlg=%d", fOk );
  1277. if (pInfo->pNoUser && !pInfo->hThread)
  1278. {
  1279. TRACE( "Taking shortcut to exit" );
  1280. return;
  1281. }
  1282. if (fOk)
  1283. {
  1284. TRACEW1( "OK pressed, e=\"%s\"", info.szEntry );
  1285. if (pInfo->pArgs->pApiArgs->pCallback)
  1286. {
  1287. RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
  1288. TRACE( "Callback(AddEntry)" );
  1289. pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
  1290. RASPBDEVENT_AddEntry, info.szEntry, NULL );
  1291. TRACE( "Callback(AddEntry) done" );
  1292. }
  1293. DuUpdateLbEntries( pInfo, info.szEntry );
  1294. Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbDial );
  1295. SetFocus( pInfo->hwndLbEntries );
  1296. }
  1297. else
  1298. {
  1299. TRACE( "Cancel pressed or error" );
  1300. }
  1301. }
  1302. VOID
  1303. DuUpdateConnectStatus(
  1304. IN DUINFO* pInfo )
  1305. // Called to update connect status of the selected entry and the text of
  1306. // the Dial/HangUp button. 'PInfo' is the dialog context block.
  1307. //
  1308. {
  1309. TCHAR* pszPhonebook;
  1310. TCHAR* pszEntry;
  1311. INT iSel;
  1312. TCHAR* psz;
  1313. DUCONTEXT *pContext;
  1314. TRACE( "DuUpdateConnectStatus" );
  1315. // pszPhonebook = pInfo->file.pszPath;
  1316. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  1317. if (iSel < 0)
  1318. {
  1319. return;
  1320. }
  1321. pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
  1322. pInfo->hwndLbEntries,
  1323. iSel);
  1324. ASSERT(NULL != pContext);
  1325. pszEntry = ComboBox_GetPsz( pInfo->hwndLbEntries, iSel );
  1326. pInfo->hrasconn = HrasconnFromEntry(
  1327. pContext->pszPhonebookPath,
  1328. pszEntry );
  1329. psz = PszFromId( g_hinstDll,
  1330. (pInfo->hrasconn) ? SID_DU_HangUp : SID_DU_Dial );
  1331. if (psz)
  1332. {
  1333. SetWindowText( pInfo->hwndPbDial, psz );
  1334. Free( psz );
  1335. }
  1336. }
  1337. VOID
  1338. DuUpdateLbEntries(
  1339. IN DUINFO* pInfo,
  1340. IN TCHAR* pszEntry )
  1341. // Update the contents of the entry listbox and set the selection to
  1342. // 'pszEntry'. If there are entries the Properties button is enabled,
  1343. // otherwise it is disabled. 'PInfo' is the dialog context.
  1344. //
  1345. {
  1346. DTLNODE* pNode;
  1347. RASENTRYNAME *pRasEntryNames = NULL;
  1348. DWORD cEntries = 0;
  1349. DWORD cb;
  1350. DWORD dwErr;
  1351. DWORD i;
  1352. RASENTRYNAME ren;
  1353. DUCONTEXT *pContext;
  1354. INT iSel;
  1355. TRACE( "DuUpdateLbEntries" );
  1356. iSel = -1;
  1357. ComboBox_ResetContent( pInfo->hwndLbEntries );
  1358. cb = ren.dwSize = sizeof(RASENTRYNAME);
  1359. //
  1360. // Enumerate entries across all phonebooks. Fix for bug 206467
  1361. //
  1362. dwErr = g_pRasEnumEntries(NULL,
  1363. pInfo->pArgs->pszPhonebook,
  1364. &ren,
  1365. &cb,
  1366. &cEntries);
  1367. if( ( (ERROR_BUFFER_TOO_SMALL == dwErr)
  1368. || (SUCCESS == dwErr))
  1369. && (cb >= sizeof(RASENTRYNAME)))
  1370. {
  1371. pRasEntryNames = (RASENTRYNAME *) Malloc(cb);
  1372. if(NULL == pRasEntryNames)
  1373. {
  1374. // Nothing else can be done in this case
  1375. //
  1376. goto done;
  1377. }
  1378. pRasEntryNames->dwSize = sizeof(RASENTRYNAME);
  1379. dwErr = g_pRasEnumEntries(NULL,
  1380. pInfo->pArgs->pszPhonebook,
  1381. pRasEntryNames,
  1382. &cb,
  1383. &cEntries);
  1384. if(dwErr)
  1385. {
  1386. goto done;
  1387. }
  1388. }
  1389. else
  1390. {
  1391. goto done;
  1392. }
  1393. for(i = 0; i < cEntries; i++)
  1394. {
  1395. pContext = (DUCONTEXT *) Malloc(sizeof(DUCONTEXT));
  1396. if(NULL == pContext)
  1397. {
  1398. dwErr = GetLastError();
  1399. goto done;
  1400. }
  1401. ZeroMemory(pContext, sizeof(DUCONTEXT));
  1402. pContext->pszPhonebookPath =
  1403. StrDup(
  1404. pRasEntryNames[i].szPhonebookPath
  1405. );
  1406. ComboBox_AddItem(pInfo->hwndLbEntries,
  1407. pRasEntryNames[i].szEntryName,
  1408. pContext);
  1409. }
  1410. if (ComboBox_GetCount( pInfo->hwndLbEntries ) >= 0)
  1411. {
  1412. if (pszEntry)
  1413. {
  1414. // Select entry specified by API caller.
  1415. //
  1416. iSel = ComboBox_FindStringExact(
  1417. pInfo->hwndLbEntries, -1, pszEntry );
  1418. }
  1419. if (iSel < 0)
  1420. {
  1421. // Entry not found so default to first item selected.
  1422. //
  1423. iSel = 0;
  1424. }
  1425. if(ComboBox_GetCount(pInfo->hwndLbEntries) > 0)
  1426. {
  1427. ComboBox_SetCurSelNotify( pInfo->hwndLbEntries, iSel );
  1428. }
  1429. }
  1430. done:
  1431. // Enable/disable Properties button based on existence of an entry. See
  1432. // bug 313037.
  1433. //
  1434. if (ComboBox_GetCurSel( pInfo->hwndLbEntries ) >= 0
  1435. && (!pInfo->fNoUser || pInfo->user.fAllowLogonPhonebookEdits))
  1436. {
  1437. EnableWindow( pInfo->hwndPbProperties, TRUE );
  1438. }
  1439. else
  1440. {
  1441. if (GetFocus() == pInfo->hwndPbProperties)
  1442. {
  1443. SetFocus( pInfo->hwndPbDial );
  1444. }
  1445. EnableWindow( pInfo->hwndPbProperties, FALSE );
  1446. }
  1447. ComboBox_AutoSizeDroppedWidth( pInfo->hwndLbEntries );
  1448. Free0(pRasEntryNames);
  1449. }
  1450. VOID
  1451. DuUpdateTitle(
  1452. IN DUINFO* pInfo )
  1453. // Called to update the dialog title to reflect the current phonebook.
  1454. // 'PInfo' is the dialog context.
  1455. //
  1456. {
  1457. TCHAR szBuf[ 256 ];
  1458. TCHAR* psz;
  1459. // For whistler 117934, initialize the buffer
  1460. //
  1461. ZeroMemory( szBuf, 256 * sizeof(TCHAR) );
  1462. psz = PszFromId( g_hinstDll, SID_PopupTitle );
  1463. if (psz)
  1464. {
  1465. lstrcpyn( szBuf, psz, sizeof(szBuf) / sizeof(TCHAR) );
  1466. Free( psz );
  1467. }
  1468. else
  1469. {
  1470. *szBuf = TEXT('0');
  1471. }
  1472. if (pInfo->pArgs->pszPhonebook
  1473. || pInfo->user.dwPhonebookMode != PBM_System)
  1474. {
  1475. INT iSel;
  1476. iSel = ComboBox_GetCurSel(pInfo->hwndLbEntries);
  1477. if (iSel >= 0)
  1478. {
  1479. DUCONTEXT *pContext;
  1480. pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
  1481. pInfo->hwndLbEntries, iSel);
  1482. ASSERT( pContext );
  1483. if(NULL != pContext)
  1484. {
  1485. lstrcat( szBuf, TEXT(" - ") );
  1486. lstrcat( szBuf, StripPath( pContext->pszPhonebookPath ) );
  1487. }
  1488. }
  1489. }
  1490. SetWindowText( pInfo->hwndDlg, szBuf );
  1491. }
  1492. VOID
  1493. DuTerm(
  1494. IN HWND hwndDlg )
  1495. // Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
  1496. //
  1497. {
  1498. DUINFO* pInfo;
  1499. DWORD i;
  1500. DWORD cEntries;
  1501. TRACE( "DuTerm" );
  1502. pInfo = (DUINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  1503. if (pInfo)
  1504. {
  1505. // Close ReceiveMonitorThread resources.
  1506. //
  1507. if (pInfo->hThread)
  1508. {
  1509. TRACE( "Set abort event" );
  1510. // Tell thread to wake up and quit...
  1511. //
  1512. pInfo->fAbortMonitor = TRUE;
  1513. CloseHandle( pInfo->hThread );
  1514. // Don't SetEvent before closing the thread handle. On
  1515. // multi-proc systems, the thread will exit so fast (and
  1516. // set hThread to NULL) that CloseHandle will then close
  1517. // an invalid handle.
  1518. //
  1519. SetEvent( pInfo->hEvent );
  1520. // ...and wait for that to happen. A message API (such as
  1521. // PeekMessage) must be called to prevent the thread-to-thread
  1522. // SendMessage in the thread from blocking.
  1523. //
  1524. {
  1525. MSG msg;
  1526. TRACE( "Termination spin..." );
  1527. for (;;)
  1528. {
  1529. PeekMessage( &msg, hwndDlg, 0, 0, PM_NOREMOVE );
  1530. if (!pInfo->hThread)
  1531. {
  1532. break;
  1533. }
  1534. Sleep( 500L );
  1535. }
  1536. TRACE( "Termination spin ends" );
  1537. }
  1538. }
  1539. if (pInfo->hEvent)
  1540. {
  1541. CloseHandle( pInfo->hEvent );
  1542. }
  1543. if (pInfo->pNoUser)
  1544. {
  1545. // Don't leave caller's password floating around in memory.
  1546. //
  1547. RtlSecureZeroMemory( pInfo->pNoUser->szPassword, PWLEN * sizeof(TCHAR) );
  1548. Free( pInfo->pNoUser );
  1549. // Uninstall input event hooks.
  1550. //
  1551. if (pInfo->hhookMouse)
  1552. {
  1553. UnhookWindowsHookEx( pInfo->hhookMouse );
  1554. }
  1555. if (pInfo->hhookKeyboard)
  1556. {
  1557. UnhookWindowsHookEx( pInfo->hhookKeyboard );
  1558. }
  1559. }
  1560. else if ((pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_UpdateDefaults)
  1561. && pInfo->hwndLbEntries && pInfo->user.fInitialized)
  1562. {
  1563. INT iSel;
  1564. RECT rect;
  1565. // Caller said to update default settings so save the name of the
  1566. // selected entry and the current window position.
  1567. //
  1568. iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
  1569. if (iSel >= 0)
  1570. {
  1571. DUCONTEXT *pContext;
  1572. PBENTRY* pEntry;
  1573. pContext = (DUCONTEXT* )ComboBox_GetItemDataPtr(
  1574. pInfo->hwndLbEntries, iSel );
  1575. if( (NULL != pContext)
  1576. && (NULL != (pEntry = pContext->pEntry)))
  1577. {
  1578. Free0( pInfo->user.pszDefaultEntry );
  1579. pInfo->user.pszDefaultEntry =
  1580. StrDup( pEntry->pszEntryName );
  1581. }
  1582. }
  1583. if (!SetOffDesktop( pInfo->hwndDlg, SOD_GetOrgRect, &rect ))
  1584. {
  1585. GetWindowRect( pInfo->hwndDlg, &rect );
  1586. }
  1587. pInfo->user.dwXPhonebook = rect.left;
  1588. pInfo->user.dwYPhonebook = rect.top;
  1589. pInfo->user.fDirty = TRUE;
  1590. g_pSetUserPreferences(
  1591. NULL, &pInfo->user, pInfo->fNoUser ? UPM_Logon : UPM_Normal );
  1592. }
  1593. if(NULL != pInfo->hwndLbEntries)
  1594. {
  1595. DUCONTEXT *pContext;
  1596. cEntries = ComboBox_GetCount(pInfo->hwndLbEntries);
  1597. //
  1598. // Free the context stored in the list box
  1599. //
  1600. for(i = 0; i < cEntries; i++)
  1601. {
  1602. pContext = ComboBox_GetItemDataPtr(
  1603. pInfo->hwndLbEntries, i);
  1604. if(NULL != pContext)
  1605. {
  1606. Free0(pContext->pszPhonebookPath);
  1607. }
  1608. Free0(pContext);
  1609. }
  1610. }
  1611. TapiShutdown( pInfo->hlineapp );
  1612. ClosePhonebookFile( &pInfo->file );
  1613. DestroyUserPreferences( &pInfo->user );
  1614. Free( pInfo );
  1615. }
  1616. }
  1617. DWORD
  1618. DuMonitorThread(
  1619. LPVOID pThreadArg )
  1620. // The "main" of the "connect monitor" thread. This thread simply
  1621. // converts Win32 RasConnectionNotification events int WM_RASEVENT style
  1622. // notfications.
  1623. //
  1624. {
  1625. DUINFO* pInfo;
  1626. DWORD dwErr;
  1627. DWORD dwTimeoutMs;
  1628. DWORD dwQuitTick;
  1629. DWORD cInput = 0;
  1630. TRACE( "DuMonitor starting" );
  1631. pInfo = (DUINFO* )pThreadArg;
  1632. if (pInfo->pNoUser && pInfo->pNoUser->dwTimeoutMs != 0)
  1633. {
  1634. TRACE( "DuMonitor quit timer set" );
  1635. dwTimeoutMs = 5000L;
  1636. dwQuitTick = GetTickCount() + pInfo->pNoUser->dwTimeoutMs;
  1637. cInput = g_cInput;
  1638. }
  1639. else
  1640. {
  1641. dwTimeoutMs = INFINITE;
  1642. dwQuitTick = 0;
  1643. }
  1644. // Trigger the event so the other thread has the correct state as of the
  1645. // monitor starting.
  1646. //
  1647. SetEvent( pInfo->hEvent );
  1648. for (;;)
  1649. {
  1650. dwErr = WaitForSingleObject( pInfo->hEvent, dwTimeoutMs );
  1651. if (pInfo->fAbortMonitor)
  1652. {
  1653. break;
  1654. }
  1655. if (dwErr == WAIT_TIMEOUT)
  1656. {
  1657. if (g_cInput > cInput)
  1658. {
  1659. TRACE( "Input restarts timer" );
  1660. cInput = g_cInput;
  1661. dwQuitTick = GetTickCount() + pInfo->pNoUser->dwTimeoutMs;
  1662. }
  1663. else if (GetTickCount() >= dwQuitTick)
  1664. {
  1665. TRACE( "/DuMonitor SendMessage(WM_NOUSERTIMEOUT)" );
  1666. SendMessage( pInfo->hwndDlg, WM_NOUSERTIMEOUT, 0, 0 );
  1667. TRACE( "\\DuMonitor SendMessage(WM_NOUSERTIMEOUT) done" );
  1668. break;
  1669. }
  1670. }
  1671. else
  1672. {
  1673. TRACE( "/DuMonitor SendMessage(WM_RASEVENT)" );
  1674. SendMessage( pInfo->hwndDlg, WM_RASEVENT, 0, 0 );
  1675. TRACE( "\\DuMonitor SendMessage(WM_RASEVENT) done" );
  1676. }
  1677. }
  1678. // This clues the other thread that all interesting work has been done.
  1679. //
  1680. pInfo->hThread = NULL;
  1681. TRACE( "DuMonitor terminating" );
  1682. return 0;
  1683. }
  1684. DWORD
  1685. DuGetEntry(
  1686. DUINFO* pInfo,
  1687. DUCONTEXT* pContext )
  1688. {
  1689. DWORD dwErr = ERROR_SUCCESS;
  1690. DWORD dwReadPbkFlags = 0;
  1691. LPTSTR pszEntryName;
  1692. DTLNODE *pdtlnode;
  1693. PBFILE file;
  1694. ASSERT(NULL != pContext);
  1695. pContext->pEntry = NULL;
  1696. pszEntryName = ComboBox_GetPsz(pInfo->hwndLbEntries,
  1697. ComboBox_GetCurSel(pInfo->hwndLbEntries));
  1698. if (pInfo->fNoUser)
  1699. {
  1700. dwReadPbkFlags |= RPBF_NoUser;
  1701. }
  1702. if( (NULL != pInfo->file.pszPath)
  1703. && (0 == lstrcmpi(pContext->pszPhonebookPath,
  1704. pInfo->file.pszPath)))
  1705. {
  1706. //
  1707. // We already have the phonebook file open
  1708. //
  1709. pdtlnode = EntryNodeFromName(
  1710. pInfo->file.pdtllistEntries,
  1711. pszEntryName);
  1712. ASSERT(NULL != pdtlnode);
  1713. }
  1714. else
  1715. {
  1716. //
  1717. // phonebook file changed. So close the existing phone
  1718. // book file and open the one in which the entry
  1719. // belongs
  1720. //
  1721. if(NULL != pInfo->file.pszPath)
  1722. {
  1723. ClosePhonebookFile(&pInfo->file);
  1724. }
  1725. dwErr = GetPbkAndEntryName(pContext->pszPhonebookPath,
  1726. pszEntryName,
  1727. dwReadPbkFlags,
  1728. &file,
  1729. &pdtlnode);
  1730. if(dwErr)
  1731. {
  1732. goto done;
  1733. }
  1734. ASSERT(NULL != pdtlnode);
  1735. CopyMemory(&pInfo->file, &file, sizeof(PBFILE));
  1736. }
  1737. if (pdtlnode)
  1738. {
  1739. pContext->pEntry = (PBENTRY *) DtlGetData(pdtlnode);
  1740. }
  1741. else
  1742. {
  1743. dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
  1744. }
  1745. done:
  1746. return dwErr;
  1747. }
  1748. DWORD
  1749. DwGetEapLogonInfo(
  1750. VOID *pv,
  1751. EAPLOGONINFO **ppEapLogonInfo )
  1752. {
  1753. EAPLOGONINFO *pEapLogonInfo = NULL;
  1754. DWORD retcode = SUCCESS;
  1755. struct EAPINFO
  1756. {
  1757. DWORD dwSizeofEapInfo;
  1758. PBYTE pbEapInfo;
  1759. DWORD dwSizeofPINInfo;
  1760. PBYTE pbPINInfo;
  1761. };
  1762. struct EAPINFO *pEapInfo = (struct EAPINFO *) pv;
  1763. DWORD dwSize;
  1764. if(NULL == pv)
  1765. {
  1766. retcode = E_INVALIDARG;
  1767. goto done;
  1768. }
  1769. dwSize = sizeof(EAPLOGONINFO)
  1770. + pEapInfo->dwSizeofEapInfo
  1771. + pEapInfo->dwSizeofPINInfo;
  1772. pEapLogonInfo = (EAPLOGONINFO *) Malloc(dwSize);
  1773. if(NULL == pEapLogonInfo)
  1774. {
  1775. retcode = GetLastError();
  1776. TRACE1("Failed to Allocate EapLogonInfo. rc=0x%x",
  1777. retcode);
  1778. goto done;
  1779. }
  1780. ZeroMemory(pEapLogonInfo, dwSize);
  1781. //
  1782. // Set up the fields in pEapLogonInfo by
  1783. // flattening out the information passed
  1784. // in.
  1785. //
  1786. pEapLogonInfo->dwSize = dwSize;
  1787. pEapLogonInfo->dwLogonInfoSize =
  1788. pEapInfo->dwSizeofEapInfo;
  1789. pEapLogonInfo->dwOffsetLogonInfo =
  1790. FIELD_OFFSET(EAPLOGONINFO, abdata);
  1791. memcpy( pEapLogonInfo->abdata,
  1792. pEapInfo->pbEapInfo,
  1793. pEapInfo->dwSizeofEapInfo);
  1794. pEapLogonInfo->dwPINInfoSize =
  1795. pEapInfo->dwSizeofPINInfo;
  1796. pEapLogonInfo->dwOffsetPINInfo =
  1797. FIELD_OFFSET(EAPLOGONINFO, abdata)
  1798. + pEapInfo->dwSizeofEapInfo;
  1799. memcpy( (PBYTE)
  1800. ((PBYTE) pEapLogonInfo
  1801. + pEapLogonInfo->dwOffsetPINInfo),
  1802. pEapInfo->pbPINInfo,
  1803. pEapInfo->dwSizeofPINInfo);
  1804. done:
  1805. *ppEapLogonInfo = pEapLogonInfo;
  1806. return retcode;
  1807. }