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.

1463 lines
47 KiB

  1. /*++
  2. Copyright (c) 2000,2001 Microsoft Corporation
  3. Module Name:
  4. MAINDLG.CPP
  5. Abstract:
  6. Implementation of the mail keymgr dialog which displays existing
  7. credentials and offers the ability to create, edit, or delete them.
  8. Author:
  9. Environment:
  10. WinXP
  11. --*/
  12. // test/dev switch variables
  13. //////////////////////////////////////////////////////////////////////////////
  14. //
  15. // Include files
  16. //
  17. #include <stdlib.h>
  18. #include <nt.h>
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <windows.h>
  22. #include <winbase.h>
  23. #include <shellapi.h>
  24. #include<shlwapi.h>
  25. #include <wininet.h>
  26. #include <tchar.h>
  27. #include <wincrui.h>
  28. #include <wincred.h>
  29. #include <scuisupp.h>
  30. #include <htmlhelp.h>
  31. #include <credp.h>
  32. #include <comctrlp.h>
  33. #include <shfusion.h>
  34. #include "switches.h"
  35. #include "Dlg.h"
  36. #include "Res.h"
  37. #include "KRDlg.h"
  38. #include "keymgr.h"
  39. #include "testaudit.h"
  40. //===================================
  41. // special type value used to obviate string comparison to detect special nature
  42. // of the *Session credential. Value arbitrary.
  43. #define SESSION_FLAG_VALUE (0x2222)
  44. // tooltips support
  45. #define TIPSTRINGLEN 500
  46. TCHAR szTipString[TIPSTRINGLEN];
  47. WNDPROC lpfnOldWindowProc = NULL; // used to subclass the list box
  48. LRESULT CALLBACK ListBoxSubClassFunction(HWND,WORD,WPARAM,LPARAM);
  49. // global state vars - comm between prop dlg and list dlg
  50. LONG_PTR g_CurrentKey = 0; // currently selected item in the main dlg
  51. BOOL g_HaveShownRASCred = FALSE; // TRUE the first time one is shown
  52. BOOL g_fReloadList = TRUE; // reload list if something changed
  53. DWORD_PTR g_dwHCookie = 0; // HTML HELP system cookie
  54. HWND g_hMainDlg = NULL; // used to give add/new access to target list
  55. C_AddKeyDlg *g_AKdlg = NULL; // used for notifications
  56. /**********************************************************************
  57. gTestReadCredential()
  58. Arguments: None
  59. Returns: BOOL, TRUE if the selected credential could be successfully read.
  60. Comments:
  61. Read the credential currently selected in the list box from the
  62. keyring.
  63. sets g_szTargetName
  64. sets g_pExisitingCred
  65. **********************************************************************/
  66. BOOL gTestReadCredential(void)
  67. {
  68. TCHAR *pC;
  69. BOOL f;
  70. LRESULT lR;
  71. LRESULT lRet = 0;
  72. DWORD dwType;
  73. g_pExistingCred = NULL;
  74. // Fetch current credential from list into g_szTargetName
  75. lR = SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETCURSEL,0,0L);
  76. if (lR == LB_ERR)
  77. {
  78. return FALSE;
  79. }
  80. else
  81. {
  82. g_CurrentKey = lR;
  83. lRet = SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETTEXT,lR,(LPARAM) g_szTargetName);
  84. }
  85. // Possible error - zero chars returned from list box
  86. if (lRet == 0)
  87. {
  88. ASSERT(0);
  89. return FALSE; // zero characters returned
  90. }
  91. // Get the target type from the combo box item data
  92. dwType = (DWORD) SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETITEMDATA,lR,0);
  93. if (LB_ERR == dwType)
  94. {
  95. return FALSE;
  96. }
  97. // null term the targetname shown in the UI,
  98. // trimming the suffix if there is one
  99. pC = _tcschr(g_szTargetName,g_rgcCert[0]);
  100. if (pC)
  101. {
  102. pC--;
  103. *pC = 0x0; // null terminate namestring
  104. }
  105. // Attempt to read the credential from the store
  106. // The returned credential will have to be freed if leaving this block
  107. f = (CredRead(g_szTargetName,
  108. (ULONG) dwType,
  109. 0,
  110. &g_pExistingCred));
  111. if (!f)
  112. {
  113. return FALSE; // g_pExistingCred is empty
  114. }
  115. return TRUE; // g_pExistingCred has been filled
  116. }
  117. /**********************************************************************
  118. MapID()
  119. Arguments: UINT dialog control ID
  120. Returns: UINT string resource number
  121. Comments: Convert a dialog control identifier to a string identifier.
  122. **********************************************************************/
  123. UINT C_KeyringDlg::MapID(UINT uiID)
  124. {
  125. switch(uiID) {
  126. case IDC_KEYLIST:
  127. return IDH_KEYLIST;
  128. case IDC_NEWKEY:
  129. return IDH_NEW;
  130. case IDC_DELETEKEY:
  131. return IDH_DELETE;
  132. case IDC_CHANGE_PASSWORD:
  133. return IDH_CHANGEPASSWORD;
  134. case IDC_EDITKEY:
  135. return IDH_EDIT;
  136. case IDOK:
  137. case IDCANCEL:
  138. return IDH_CLOSE;
  139. default:
  140. return IDS_NOHELP;
  141. }
  142. }
  143. //////////////////////////////////////////////////////////////////////////////
  144. //
  145. // C_KeyringDlg
  146. //
  147. // Constructor.
  148. //
  149. // parameters:
  150. // hwndParent parent window for the dialog (may be NULL)
  151. // hInstance instance handle of the parent window (may be NULL)
  152. // lIDD dialog template id
  153. // pfnDlgProc pointer to the function that will process messages for
  154. // the dialog. if it is NULL, the default dialog proc
  155. // will be used.
  156. //
  157. // returns:
  158. // Nothing.
  159. //
  160. //////////////////////////////////////////////////////////////////////////////
  161. C_KeyringDlg::C_KeyringDlg(
  162. HWND hwndParent,
  163. HINSTANCE hInstance,
  164. LONG lIDD,
  165. DLGPROC pfnDlgProc // = NULL
  166. )
  167. : C_Dlg(hwndParent, hInstance, lIDD, pfnDlgProc)
  168. {
  169. m_hInst = hInstance; // our instance handle
  170. m_cCredCount = 0;
  171. g_AKdlg = NULL; // addkey dialog not up
  172. fInit = FALSE; // initial screen draw undone
  173. } // C_KeyringDlg::C_KeyringDlg
  174. /**********************************************************************
  175. Initialize the keyring UI credential list. Read the credentials currently
  176. on the user's keyring and show the targetnames in the list. Called on
  177. initial show of the dialog, and again after handling add or delete.
  178. Sets the numeric tag for each list entry to equal the credential type.
  179. *Session creds are detected here and special handled.
  180. Certificate and Passport creds are detected here an a suffix applied to
  181. their name.
  182. **********************************************************************/
  183. void C_KeyringDlg::BuildList()
  184. {
  185. DWORD dwCredCount = 0;
  186. CREDENTIAL **pCredentialPtrArray = NULL;
  187. BOOL bResult = 0;
  188. DWORD i,dwCredType;
  189. PCREDENTIAL pThisCred = NULL;
  190. TCHAR *pTargetName = NULL;
  191. LRESULT idx = 0;
  192. TCHAR szMsg[64];
  193. #if TESTAUDIT
  194. BOOL f34 = FALSE;
  195. #endif
  196. g_HaveShownRASCred = FALSE;
  197. // clear the listbox
  198. ::SendDlgItemMessage(m_hDlg,IDC_KEYLIST,LB_RESETCONTENT,NULL,0);
  199. bResult = CredEnumerate(NULL,0,&dwCredCount,&pCredentialPtrArray);
  200. if ((m_cCredCount != dwCredCount) || (g_fReloadList))
  201. {
  202. if (bResult)
  203. {
  204. for (i=0 ; i < dwCredCount ; i++)
  205. {
  206. #ifdef LOUDLY
  207. if (!bResult) OutputDebugString(L"Keymgr: Adding a cred to the window\n");
  208. #endif
  209. pThisCred = pCredentialPtrArray[i];
  210. pTargetName = pThisCred->TargetName;
  211. // handle CRED_SESSION_WILDCARD_NAME_W by replacing the string
  212. if (0 == _tcsicmp(pTargetName,CRED_SESSION_WILDCARD_NAME)) {
  213. if (g_HaveShownRASCred)
  214. {
  215. CHECKPOINT(41,L"Multiple *Session creds");
  216. continue;
  217. }
  218. CHECKPOINT(32,L"Keymgr: *Session cred in cred list");
  219. LoadString ( m_hInst, IDS_SESSIONCRED, szMsg, 64 );
  220. pTargetName = szMsg;
  221. dwCredType = SESSION_FLAG_VALUE;
  222. g_HaveShownRASCred = TRUE;
  223. }
  224. else
  225. {
  226. dwCredType = pThisCred->Type;
  227. }
  228. // name suffixes are localizable
  229. // we use g_szTargetName for this in order to avoid another
  230. // memory allocation, as this buffer is not yet in use.
  231. switch (dwCredType)
  232. {
  233. case CRED_TYPE_GENERIC:
  234. continue;
  235. break;
  236. // this particular type is not visible in keymgr
  237. case CRED_TYPE_DOMAIN_VISIBLE_PASSWORD:
  238. {
  239. #ifndef SHOWPASSPORT
  240. continue;
  241. #endif
  242. #ifdef SHOWPASSPORT
  243. CHECKPOINT(33,L"Keymgr: Passport cred in cred list");
  244. // SHOWPASSPORT is currently turned on
  245. _tcsncpy(g_szTargetName,pTargetName,CRED_MAX_DOMAIN_TARGET_NAME_LENGTH);
  246. g_szTargetName[CRED_MAX_DOMAIN_TARGET_NAME_LENGTH] = 0;
  247. _tcsncat(g_szTargetName,_T(" "),2);
  248. _tcsncat(g_szTargetName,g_rgcPassport,MAXSUFFIXSIZE);
  249. g_szTargetName[TARGETNAMEMAXLENGTH] = 0;
  250. break;
  251. #endif
  252. }
  253. case CRED_TYPE_DOMAIN_PASSWORD:
  254. case SESSION_FLAG_VALUE:
  255. // find RAS credential
  256. #if TESTAUDIT
  257. // This checkpoint would be very noisy a lot of the time.
  258. // Use f34 to get it to show just once.
  259. if (!f34)
  260. {
  261. CHECKPOINT(34,"Keymgr: Password cred in cred list");
  262. f34 = TRUE;
  263. }
  264. #endif
  265. _tcsncpy(g_szTargetName,pTargetName,CRED_MAX_DOMAIN_TARGET_NAME_LENGTH);
  266. g_szTargetName[CRED_MAX_DOMAIN_TARGET_NAME_LENGTH] = 0;
  267. break;
  268. case CRED_TYPE_DOMAIN_CERTIFICATE:
  269. CHECKPOINT(35,"Keymgr: Certificate cred in cred list");
  270. _tcsncpy(g_szTargetName,pTargetName,CRED_MAX_DOMAIN_TARGET_NAME_LENGTH);
  271. g_szTargetName[CRED_MAX_DOMAIN_TARGET_NAME_LENGTH] = 0;
  272. _tcsncat(g_szTargetName,_T(" "),2);
  273. _tcsncat(g_szTargetName,g_rgcCert,MAXSUFFIXSIZE);
  274. g_szTargetName[TARGETNAMEMAXLENGTH] = 0;
  275. break;
  276. default:
  277. break;
  278. }
  279. idx = ::SendDlgItemMessage(m_hDlg,IDC_KEYLIST,LB_ADDSTRING,NULL,(LPARAM) g_szTargetName);
  280. if (idx != LB_ERR)
  281. {
  282. idx = ::SendDlgItemMessage(m_hDlg,IDC_KEYLIST,LB_SETITEMDATA,(WPARAM)idx,dwCredType);
  283. }
  284. }
  285. if (pCredentialPtrArray) CredFree(pCredentialPtrArray);
  286. }
  287. else
  288. {
  289. g_CurrentKey = 0;
  290. }
  291. // Show one as active.
  292. SetCurrentKey(g_CurrentKey);
  293. g_fReloadList = FALSE;
  294. }
  295. }
  296. /**********************************************************************
  297. Set an appropriate state for the buttons on the UI, given the SKU of
  298. the platform, and the population of the keyring. If creds exist on the
  299. keyring, set the cursor on the key list to the first item. Thereafter,
  300. this function permist the last cursor to be reloaded after doing
  301. something to the list. The cursor is reset after an add operation,
  302. because the behavior of the cursor is difficult to do properly under
  303. that circumstance, as you don't know where the item will be inserted in
  304. the list.
  305. On personal, do not show the ADD button, and change the page text.
  306. If no creds, disable the DELETE and PROPERTIES buttons
  307. **********************************************************************/
  308. void C_KeyringDlg::SetCurrentKey(LONG_PTR iKey)
  309. {
  310. LONG_PTR iKeys;
  311. HWND hH;
  312. LRESULT idx;
  313. BOOL fDisabled = FALSE;
  314. // If there are items in the list, select the first one and set focus to the list
  315. iKeys = ::SendDlgItemMessage ( m_hDlg, IDC_KEYLIST, LB_GETCOUNT, (WPARAM) 0, 0L );
  316. fDisabled = (GetPersistenceOptions(CRED_TYPE_DOMAIN_PASSWORD) == CRED_PERSIST_NONE);
  317. #if TESTAUDIT
  318. if (iKeys > 100) CHECKPOINT(30,L"Keymgr: Large number of credentials > 100");
  319. if (iKeys == 0) CHECKPOINT(31,L"Keymgr: No saved credentials - list empty");
  320. #endif
  321. // If there are no creds and credman is disabled, the dialog should not be displayed
  322. // If there are creds, and credman is disabled, show the dialog without the ADD button
  323. if (fDisabled && !fInit)
  324. {
  325. // (Disable with HKLM\System\CurrentControlSet\Control\Lsa\DisableDomainCreds = 1)
  326. CHECKPOINT(36,L"Keymgr: Personal SKU or credman disabled");
  327. // Make the intro text better descriptive of this condition
  328. WCHAR szMsg[MAX_STRING_SIZE+1];
  329. LoadString ( m_hInst, IDS_INTROTEXT, szMsg, MAX_STRING_SIZE );
  330. hH = GetDlgItem(m_hDlg,IDC_INTROTEXT);
  331. if (hH) SetWindowText(hH,szMsg);
  332. // remove the add button
  333. hH = GetDlgItem(m_hDlg,IDC_NEWKEY);
  334. if (hH)
  335. {
  336. EnableWindow(hH,FALSE);
  337. ShowWindow(hH,SW_HIDE);
  338. }
  339. // move remaining buttons upfield 22 units
  340. hH = GetDlgItem(m_hDlg,IDC_DELETEKEY);
  341. if (hH)
  342. {
  343. HWND hw1;
  344. HWND hw2;
  345. RECT rw1;
  346. RECT rw2;
  347. INT xsize;
  348. INT ysize;
  349. INT delta;
  350. BOOL bOK = FALSE;
  351. hw1 = hH;
  352. hw2 = GetDlgItem(m_hDlg,IDC_EDITKEY);
  353. if (hw1 && hw2)
  354. {
  355. if (GetWindowRect(hw1,&rw1) &&
  356. GetWindowRect(hw2,&rw2))
  357. {
  358. MapWindowPoints(NULL,m_hDlg,(LPPOINT)(&rw1),2);
  359. MapWindowPoints(NULL,m_hDlg,(LPPOINT)(&rw2),2);
  360. delta = rw2.top - rw1.top;
  361. xsize = rw2.right - rw2.left;
  362. ysize = rw2.bottom - rw2.top;
  363. bOK = MoveWindow(hw1,rw1.left,rw1.top - delta,xsize,ysize,TRUE);
  364. if (bOK)
  365. {
  366. bOK = MoveWindow(hw2,rw2.left,rw2.top - delta,xsize,ysize,TRUE);
  367. }
  368. }
  369. }
  370. }
  371. // prevent moving the buttons twice
  372. fInit = TRUE;
  373. }
  374. // Set the default button to either properties or add
  375. if ( iKeys > 0 )
  376. {
  377. hH = GetDlgItem(m_hDlg,IDC_KEYLIST);
  378. SetFocus(hH);
  379. // if asking for key beyond end of list, mark the last one
  380. if (iKey >= iKeys) iKey = iKeys - 1;
  381. idx = SendDlgItemMessage ( m_hDlg, IDC_KEYLIST, LB_SETCURSEL, iKey, 0L );
  382. hH = GetDlgItem(m_hDlg,IDC_EDITKEY);
  383. if (hH) EnableWindow(hH,TRUE);
  384. hH = GetDlgItem(m_hDlg,IDC_DELETEKEY);
  385. if (hH) EnableWindow(hH,TRUE);
  386. }
  387. else
  388. {
  389. if (!fDisabled)
  390. {
  391. // no items in the list, set focus to the New button
  392. hH = GetDlgItem(m_hDlg,IDC_NEWKEY);
  393. SetFocus(hH);
  394. }
  395. hH = GetDlgItem(m_hDlg,IDC_EDITKEY);
  396. if (hH) EnableWindow(hH,FALSE);
  397. hH = GetDlgItem(m_hDlg,IDC_DELETEKEY);
  398. if (hH) EnableWindow(hH,FALSE);
  399. }
  400. }
  401. // Remove the currently highlighted key from the listbox
  402. /**********************************************************************
  403. DeleteKey()
  404. Arguments: None
  405. Returns: None
  406. Comments: Deletes the credential currently selected in the list box.
  407. **********************************************************************/
  408. void C_KeyringDlg::DeleteKey()
  409. {
  410. TCHAR szMsg[MAX_STRING_SIZE + MAXSUFFIXSIZE] = {0};
  411. TCHAR szTitle[MAX_STRING_SIZE] = {0};;
  412. TCHAR *pC; // point this to the raw name
  413. LONG_PTR lR = LB_ERR;
  414. LONG_PTR lSel = LB_ERR;
  415. BOOL bResult = FALSE;
  416. DWORD dwCredType = 0;
  417. CHECKPOINT(37,L"Keymgr: Delete a credential");
  418. LoadString ( m_hInst, IDS_DELETEWARNING, szMsg, MAX_STRING_SIZE );
  419. LoadString ( m_hInst, IDS_APP_NAME, szTitle, MAX_STRING_SIZE );
  420. // ask for confirm to delete
  421. lR = MessageBox ( m_hDlg, szMsg, szTitle, MB_OKCANCEL );
  422. if (IDOK != lR)
  423. {
  424. return;
  425. }
  426. // Get the credential type information from the item data
  427. lSel = SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETCURSEL,0,0L);
  428. if (lSel == LB_ERR)
  429. {
  430. ASSERT(0);
  431. goto faildelete;
  432. }
  433. g_CurrentKey = lSel;
  434. lR = SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETTEXT,lSel,(LPARAM) g_szTargetName);
  435. if (lR == LB_ERR)
  436. {
  437. ASSERT(0);
  438. goto faildelete;
  439. }
  440. dwCredType = (DWORD) SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETITEMDATA,lSel,0);
  441. if (LB_ERR == dwCredType)
  442. {
  443. ASSERT(0);
  444. goto faildelete;
  445. }
  446. // Special case RAS creds, because there can be more than one. We only show a single entry,
  447. // and deleting it automatically seeks and deletes the other if it is present. For this reason, the
  448. // type information associated with this cred is a special value, and not use in the delete.
  449. if (dwCredType == SESSION_FLAG_VALUE)
  450. {
  451. CHECKPOINT(42,L"Delete session cred");
  452. // convert the name from user friendly to the internal representation
  453. _tcsncpy(g_szTargetName,CRED_SESSION_WILDCARD_NAME,TARGETNAMEMAXLENGTH);
  454. g_szTargetName[TARGETNAMEMAXLENGTH - 1] = 0;
  455. // bResult will be success if either deleted successfully
  456. bResult = CredDelete(g_szTargetName,CRED_TYPE_DOMAIN_PASSWORD,0);
  457. if (!bResult)
  458. {
  459. bResult = CredDelete(g_szTargetName,CRED_TYPE_DOMAIN_CERTIFICATE,0);
  460. }
  461. else
  462. {
  463. CredDelete(g_szTargetName,CRED_TYPE_DOMAIN_CERTIFICATE,0);
  464. }
  465. }
  466. else
  467. {
  468. // null term the targetname shown in the UI,
  469. // trimming the suffix if there is one
  470. pC = _tcschr(g_szTargetName,g_rgcCert[0]);
  471. if (pC)
  472. {
  473. pC--;
  474. *pC = 0x0; // null terminate namestring
  475. }
  476. // Delete the single credential on the cursor
  477. bResult = CredDelete(g_szTargetName,dwCredType,0);
  478. }
  479. faildelete:
  480. if (bResult != TRUE)
  481. {
  482. LoadString ( m_hInst, IDS_DELETEFAILED, szMsg, MAX_STRING_SIZE );
  483. LoadString ( m_hInst, IDS_APP_NAME, szTitle, MAX_STRING_SIZE );
  484. MessageBox ( m_hDlg, szMsg, szTitle, MB_OK);
  485. }
  486. else
  487. {
  488. // successful delete - resort and re-present the list
  489. g_fReloadList = TRUE;
  490. }
  491. }
  492. /**********************************************************************
  493. OnAppMessage()
  494. Arguments: None
  495. Returns: BOOL always TRUE
  496. Comments: Empty handler for method of class.
  497. **********************************************************************/
  498. BOOL
  499. C_KeyringDlg::OnAppMessage(
  500. UINT uMessage,
  501. WPARAM wparam,
  502. LPARAM lparam
  503. )
  504. {
  505. return TRUE;
  506. } // OnAppMessage
  507. //////////////////////////////////////////////////////////////////////////////
  508. //
  509. // OnInitDialog
  510. //
  511. // Dialog control and data initialization.
  512. //
  513. // parameters:
  514. // hwndDlg window handle of the dialog box
  515. // hwndFocus window handle of the control that will receive focus
  516. //
  517. // returns:
  518. // TRUE if the system should set the default keyboard focus
  519. // FALSE if the keyboard focus is set by this app
  520. //
  521. //////////////////////////////////////////////////////////////////////////////
  522. BOOL
  523. C_KeyringDlg::OnInitDialog(
  524. HWND hwndDlg,
  525. HWND hwndFocus
  526. )
  527. {
  528. // these really should all be in the keyringdlg class
  529. DWORD i;
  530. LRESULT lr;
  531. HtmlHelp(NULL,NULL,HH_INITIALIZE,(DWORD_PTR) &g_dwHCookie);
  532. // Allow other dialog to query the contents of the listbox
  533. g_hMainDlg = hwndDlg;
  534. m_hDlg = hwndDlg;
  535. g_CurrentKey = 0;
  536. g_fReloadList = TRUE;
  537. g_szTargetName = (TCHAR *) malloc((TARGETNAMEMAXLENGTH + 1) * sizeof(TCHAR));
  538. ASSERT(g_szTargetName);
  539. if (NULL == g_szTargetName)
  540. {
  541. return FALSE;
  542. }
  543. // Fetch Icons from the image and assoc them with this dialog
  544. HICON hI = LoadIcon(m_hInst,MAKEINTRESOURCE(IDI_SMALL));
  545. lr = SendMessage(hwndDlg,WM_SETICON,(WPARAM) ICON_SMALL,(LPARAM)hI);
  546. C_Dlg::OnInitDialog(hwndDlg, hwndFocus);
  547. // Even if mirrored language is default, set list box style to LTR
  548. // (NOT CURRENTLY TURNED ON)
  549. #ifdef FORCELISTLTR
  550. {
  551. LONG_PTR lExStyles;
  552. HWND hwList;
  553. hwList = GetDlgItem(hwndDlg,IDC_KEYLIST);
  554. if (hwList)
  555. {
  556. lExStyles = GetWindowLongPtr(hwList,GWL_EXSTYLE);
  557. lExStyles &= ~WS_EX_RTLREADING;
  558. SetWindowLongPtr(hwList,GWL_EXSTYLE,lExStyles);
  559. InvalidateRect(hwList,NULL,TRUE);
  560. }
  561. }
  562. #endif
  563. // read in the suffix strings for certificate types
  564. // locate first differing character
  565. //
  566. // This code assumes that the strings all have a common preamble,
  567. // and that all are different in the first character position
  568. // past the preamble. Localized strings should be selected which
  569. // have this property, like (Generic) and (Certificate).
  570. i = LoadString(g_hInstance,IDS_CERTSUFFIX,g_rgcCert,MAXSUFFIXSIZE);
  571. ASSERT(i !=0);
  572. i = LoadString(g_hInstance,IDS_PASSPORTSUFFIX,g_rgcPassport,MAXSUFFIXSIZE);
  573. // Read currently saved creds and display names in list box
  574. BuildList();
  575. SetCurrentKey(g_CurrentKey);
  576. InitTooltips();
  577. return TRUE;
  578. } // C_KeyringDlg::OnInitDialog
  579. /**********************************************************************
  580. OnDestroyDialog
  581. Arguments: None
  582. Returns: BOOL, always TRUE
  583. Comments: Performs cleanup needed as dialog is destroyed. In this case, its only
  584. action is to release the HTML Help resources.
  585. **********************************************************************/
  586. BOOL
  587. C_KeyringDlg::OnDestroyDialog(
  588. void )
  589. {
  590. free(g_szTargetName);
  591. HtmlHelp(NULL,NULL,HH_UNINITIALIZE,(DWORD_PTR)g_dwHCookie);
  592. return TRUE;
  593. }
  594. /**********************************************************************
  595. DoEdit()
  596. Arguments: None
  597. Returns: BOOL always TRUE
  598. Comments: Filters some special creds on the basis of their special nature. For the
  599. editable ones, kicks off the edit dialog to edit the credential held at
  600. g_pExistingCred.
  601. **********************************************************************/
  602. BOOL C_KeyringDlg::DoEdit(void)
  603. {
  604. LRESULT lR;
  605. lR = SendDlgItemMessage(m_hDlg,IDC_KEYLIST,LB_GETCURSEL,0,0L);
  606. if (LB_ERR == lR)
  607. {
  608. // On error, no dialog shown, edit command handled
  609. return TRUE;
  610. }
  611. else
  612. {
  613. // something selected
  614. g_CurrentKey = lR;
  615. // If a RAS cred, show it specially, indicate no edit allowed
  616. lR = SendDlgItemMessage(m_hDlg,IDC_KEYLIST,LB_GETITEMDATA,lR,0);
  617. if (lR == SESSION_FLAG_VALUE)
  618. {
  619. CHECKPOINT(38,L"Keymgr: Attempt edit a RAS cred");
  620. // load string and display message box
  621. TCHAR szMsg[MAX_STRING_SIZE];
  622. TCHAR szTitle[MAX_STRING_SIZE];
  623. LoadString ( m_hInst, IDS_APP_NAME, szTitle, MAX_STRING_SIZE );
  624. LoadString ( m_hInst, IDS_CANNOTEDIT, szMsg, MAX_STRING_SIZE );
  625. MessageBox ( m_hDlg, szMsg, szTitle, MB_OK );
  626. return TRUE;
  627. }
  628. #ifdef SHOWPASSPORT
  629. #ifdef NEWPASSPORT
  630. // if a passport cred, show it specially, indicate no edit allowed
  631. if (lR == CRED_TYPE_DOMAIN_VISIBLE_PASSWORD)
  632. {
  633. CHECKPOINT(39,L"Keymgr: Attempt edit a passport cred");
  634. // load string and display message box
  635. TCHAR szMsg[MAX_STRING_SIZE];
  636. TCHAR szTitle[MAX_STRING_SIZE];
  637. LoadString ( m_hInst, IDS_APP_NAME, szTitle, MAX_STRING_SIZE );
  638. LoadString ( m_hInst, IDS_PASSPORT2, szMsg, MAX_STRING_SIZE );
  639. INT iResponse = MessageBox ( m_hDlg, szMsg, szTitle, MB_YESNO );
  640. if (IDYES == iResponse)
  641. {
  642. CHECKPOINT(40,L"Keymgr: Launch passport website for Passport cred edit");
  643. HKEY hKey = NULL;
  644. DWORD dwType;
  645. //BYTE rgb[500];
  646. BYTE *rgb=(BYTE *) malloc(INTERNET_MAX_URL_LENGTH * sizeof(WCHAR));
  647. if (rgb)
  648. {
  649. DWORD cbData = INTERNET_MAX_URL_LENGTH * sizeof(WCHAR);
  650. BOOL Flag = TRUE;
  651. // launch the passport web site
  652. #ifndef PASSPORTURLINREGISTRY
  653. ShellExecute(m_hDlg,L"open",L"http://www.passport.com",NULL,NULL,SW_SHOWNORMAL);
  654. #else
  655. // read registry key to get target string for ShellExec
  656. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
  657. L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport",
  658. 0,
  659. KEY_QUERY_VALUE,
  660. &hKey))
  661. {
  662. if (ERROR_SUCCESS == RegQueryValueEx(hKey,
  663. L"Properties",
  664. NULL,
  665. &dwType,
  666. rgb,
  667. &cbData))
  668. {
  669. // test the URL for reasonableness before launching
  670. WCHAR *szUrl = (WCHAR *)malloc(INTERNET_MAX_URL_LENGTH);
  671. if (szUrl)
  672. {
  673. DWORD ccUrlBuffer = INTERNET_MAX_URL_LENGTH;
  674. if (S_OK == UrlCanonicalize((LPCTSTR)rgb, szUrl,&ccUrlBuffer,
  675. URL_ESCAPE_UNSAFE | URL_ESCAPE_PERCENT))
  676. {
  677. if (UrlIs(szUrl,URLIS_URL))
  678. {
  679. WCHAR szScheme[20];
  680. DWORD ccScheme = 20;
  681. if (SUCCEEDED(UrlGetPart(szUrl,szScheme,&ccScheme,URL_PART_SCHEME,0)))
  682. {
  683. // at the least, verify that the target is https schemed
  684. if (0 == _wcsicmp(szScheme,L"https"))
  685. {
  686. ShellExecute(m_hDlg,L"open",(LPCTSTR)rgb,NULL,NULL,SW_SHOWNORMAL);
  687. Flag = FALSE;
  688. }
  689. }
  690. }
  691. }
  692. free(szUrl);
  693. }
  694. }
  695. }
  696. #ifdef LOUDLY
  697. else
  698. {
  699. OutputDebugString(L"DoEdit: reg key HKCU... open failed\n");
  700. }
  701. #endif
  702. if (Flag)
  703. {
  704. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  705. L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport",
  706. 0,
  707. KEY_QUERY_VALUE,
  708. &hKey))
  709. {
  710. if (ERROR_SUCCESS == RegQueryValueEx(hKey,
  711. L"Properties",
  712. NULL,
  713. &dwType,
  714. rgb,
  715. &cbData))
  716. {
  717. // test the URL for reasonableness before launching
  718. WCHAR *szUrl = (WCHAR *) malloc(INTERNET_MAX_URL_LENGTH);
  719. if (szUrl)
  720. {
  721. DWORD ccUrlBuffer = INTERNET_MAX_URL_LENGTH;
  722. if (S_OK == UrlCanonicalize((LPCTSTR)rgb, szUrl,&ccUrlBuffer,0))
  723. {
  724. if (UrlIs(szUrl,URLIS_URL))
  725. {
  726. WCHAR szScheme[20];
  727. DWORD ccScheme = 20;
  728. if (SUCCEEDED(UrlGetPart(szUrl,szScheme,&ccScheme,URL_PART_SCHEME,0)))
  729. {
  730. if (0 == _wcsicmp(szScheme,L"https"))
  731. {
  732. // at the least, verify that the target is https scheme
  733. ShellExecute(m_hDlg,L"open",(LPCTSTR)rgb,NULL,NULL,SW_SHOWNORMAL);
  734. Flag = FALSE;
  735. }
  736. }
  737. }
  738. }
  739. free(szUrl);
  740. }
  741. }
  742. }
  743. #ifdef LOUDLY
  744. else
  745. {
  746. OutputDebugString(L"DoEdit: reg key HKLM... open failed\n");
  747. }
  748. #endif
  749. }
  750. if (Flag)
  751. {
  752. LoadString ( m_hInst, IDS_APP_NAME, szTitle, MAX_STRING_SIZE );
  753. LoadString ( m_hInst, IDS_PASSPORTNOURL, szMsg, MAX_STRING_SIZE );
  754. MessageBox ( m_hDlg, szMsg, szTitle, MB_ICONHAND );
  755. #ifdef LOUDLY
  756. OutputDebugString(L"DoEdit: Passport URL missing\n");
  757. #endif
  758. }
  759. #endif
  760. free(rgb);
  761. }
  762. else
  763. {
  764. // out of memory - nothing we can do
  765. return TRUE;
  766. }
  767. }
  768. return TRUE;
  769. }
  770. #else
  771. // if a passport cred, show it specially, indicate no edit allowed
  772. if (lR == CRED_TYPE_DOMAIN_VISIBLE_PASSWORD)
  773. {
  774. // load string and display message box
  775. TCHAR szMsg[MAX_STRING_SIZE];
  776. TCHAR szTitle[MAX_STRING_SIZE];
  777. LoadString ( m_hInst, IDS_APP_NAME, szTitle, MAX_STRING_SIZE );
  778. LoadString ( m_hInst, IDS_PASSPORT, szMsg, MAX_STRING_SIZE );
  779. MessageBox ( m_hDlg, szMsg, szTitle, MB_OK );
  780. return TRUE;
  781. }
  782. #endif
  783. #endif
  784. }
  785. // cred is selected, not special type. Attempt to read it
  786. if (FALSE == gTestReadCredential())
  787. {
  788. return TRUE;
  789. }
  790. g_AKdlg = new C_AddKeyDlg(g_hMainDlg,g_hInstance,IDD_ADDCRED,NULL);
  791. if (NULL == g_AKdlg)
  792. {
  793. // failed to instantiate add/new dialog
  794. if (g_pExistingCred) CredFree(g_pExistingCred);
  795. g_pExistingCred = NULL;
  796. return TRUE;
  797. }
  798. else
  799. {
  800. // read OK, dialog OK, proceed with edit dlg
  801. g_AKdlg->m_bEdit = TRUE;
  802. g_AKdlg->DoModal((LPARAM)g_AKdlg);
  803. // a credential name may have changed, so reload the list
  804. delete g_AKdlg;
  805. g_AKdlg = NULL;
  806. if (g_pExistingCred)
  807. {
  808. CredFree(g_pExistingCred);
  809. }
  810. g_pExistingCred = NULL;
  811. }
  812. return TRUE;
  813. }
  814. //////////////////////////////////////////////////////////////////////////////
  815. //
  816. // OnCommand
  817. //
  818. // Route WM_COMMAND message to appropriate handlers.
  819. //
  820. // parameters:
  821. // wNotifyCode code describing action that has occured
  822. // wSenderId id of the control sending the message, if the message
  823. // is from a dialog
  824. // hwndSender window handle of the window sending the message if the
  825. // message is not from a dialog
  826. //
  827. // returns:
  828. // TRUE if the message was processed completely
  829. // FALSE if Windows is to process the message
  830. //
  831. //////////////////////////////////////////////////////////////////////////////
  832. BOOL
  833. C_KeyringDlg::OnHelpInfo(LPARAM lp)
  834. {
  835. HELPINFO* pH;
  836. INT iMapped;
  837. pH = (HELPINFO *) lp;
  838. HH_POPUP stPopUp;
  839. RECT rcW;
  840. UINT gID;
  841. CHECKPOINT(15,"Keymgr: Main dialog OnHelpInfo");
  842. gID = pH->iCtrlId;
  843. iMapped = MapID(gID);
  844. if (iMapped == 0)
  845. {
  846. return TRUE;
  847. }
  848. if (IDS_NOHELP != iMapped)
  849. {
  850. memset(&stPopUp,0,sizeof(stPopUp));
  851. stPopUp.cbStruct = sizeof(HH_POPUP);
  852. stPopUp.hinst = g_hInstance;
  853. stPopUp.idString = iMapped;
  854. stPopUp.pszText = NULL;
  855. stPopUp.clrForeground = -1;
  856. stPopUp.clrBackground = -1;
  857. stPopUp.rcMargins.top = -1;
  858. stPopUp.rcMargins.bottom = -1;
  859. stPopUp.rcMargins.left = -1;
  860. stPopUp.rcMargins.right = -1;
  861. // bug 393244 - leave NULL to allow HHCTRL.OCX to get font information of its own,
  862. // which it needs to perform the UNICODE to multibyte conversion. Otherwise,
  863. // HHCTRL must convert using this font without charset information.
  864. stPopUp.pszFont = NULL;
  865. if (GetWindowRect((HWND)pH->hItemHandle,&rcW))
  866. {
  867. stPopUp.pt.x = (rcW.left + rcW.right) / 2;
  868. stPopUp.pt.y = (rcW.top + rcW.bottom) / 2;
  869. }
  870. else stPopUp.pt = pH->MousePos;
  871. HtmlHelp((HWND) pH->hItemHandle,NULL,HH_DISPLAY_TEXT_POPUP,(DWORD_PTR) &stPopUp);
  872. }
  873. return TRUE;
  874. }
  875. // code for handling linkage to a .chm file is disabled
  876. #if 1
  877. BOOL
  878. C_KeyringDlg::OnHelpButton(void)
  879. {
  880. return FALSE;
  881. }
  882. #else
  883. BOOL
  884. C_KeyringDlg::OnHelpButton(void)
  885. {
  886. TCHAR rgc[MAX_PATH + 1];
  887. TCHAR rgcHelpFile[]=TEXT("\\keyhelp.chm");
  888. INT ccHelp = _tcslen(rgcHelpFile);
  889. GetSystemDirectory(rgc,MAX_PATH);
  890. if (_tcslen(rgc) + ccHelp > MAX_PATH)
  891. {
  892. return FALSE;
  893. }
  894. _tcsncat(rgc, rgcHelpFile, ccHelp + 1);
  895. rgc[MAX_PATH - 1] = 0;
  896. HWND hwnd = (m_hwnd,rgc,HH_DISPLAY_TOC,NULL);
  897. if (NULL != hwnd) return TRUE;
  898. return FALSE;
  899. }
  900. #endif
  901. /**********************************************************************
  902. OnCommand()
  903. Arguments: None
  904. Returns: BOOL always TRUE
  905. Comments: Dispatcher for button presses and help requests.
  906. **********************************************************************/
  907. BOOL
  908. C_KeyringDlg::OnCommand(
  909. WORD wNotifyCode,
  910. WORD wSenderId,
  911. HWND hwndSender
  912. )
  913. {
  914. // Was the message handled?
  915. //
  916. BOOL fHandled = FALSE;
  917. switch (wSenderId)
  918. {
  919. case IDC_HELPKEY:
  920. OnHelpButton();
  921. break;
  922. case IDC_KEYLIST:
  923. if (LBN_SELCHANGE == wNotifyCode)
  924. break;
  925. if (LBN_DBLCLK == wNotifyCode)
  926. {
  927. fHandled = DoEdit();
  928. BuildList(); // targetname could have changed
  929. SetCurrentKey(g_CurrentKey);
  930. break;
  931. }
  932. case IDCANCEL:
  933. case IDOK:
  934. if (BN_CLICKED == wNotifyCode)
  935. {
  936. OnOK( );
  937. fHandled = TRUE;
  938. }
  939. break;
  940. case IDC_EDITKEY:
  941. {
  942. fHandled = DoEdit();
  943. BuildList(); // targetname could have changed
  944. SetCurrentKey(g_CurrentKey);
  945. break;
  946. }
  947. // NEW and DELETE can alter the count of creds, and the button population
  948. case IDC_NEWKEY:
  949. {
  950. g_pExistingCred = NULL;
  951. g_AKdlg = new C_AddKeyDlg(g_hMainDlg,g_hInstance,IDD_ADDCRED,NULL);
  952. if (NULL == g_AKdlg)
  953. {
  954. fHandled = TRUE;
  955. break;
  956. }
  957. else
  958. {
  959. g_AKdlg->m_bEdit = FALSE;
  960. g_AKdlg->DoModal((LPARAM)g_AKdlg);
  961. // a credential name may have changed
  962. delete g_AKdlg;
  963. g_AKdlg = NULL;
  964. BuildList();
  965. SetCurrentKey(g_CurrentKey);
  966. }
  967. break;
  968. }
  969. break;
  970. case IDC_DELETEKEY:
  971. DeleteKey(); // frees g_pExistingCred as a side effect
  972. // refresh list display
  973. BuildList();
  974. SetCurrentKey(g_CurrentKey);
  975. break;
  976. } // switch
  977. return fHandled;
  978. } // C_KeyringDlg::OnCommand
  979. //////////////////////////////////////////////////////////////////////////////
  980. //
  981. // OnOK
  982. //
  983. // Validate user name, synthesize computer name, and destroy dialog.
  984. //
  985. // parameters:
  986. // None.
  987. //
  988. // returns:
  989. // Nothing.
  990. //
  991. //////////////////////////////////////////////////////////////////////////////
  992. void
  993. C_KeyringDlg::OnOK( )
  994. {
  995. ASSERT(::IsWindow(m_hwnd));
  996. EndDialog(IDOK);
  997. } // C_KeyringDlg::OnOK
  998. //////////////////////////////////////////////////////////////////////////////
  999. //
  1000. // ToolTip Support
  1001. //
  1002. //
  1003. //////////////////////////////////////////////////////////////////////////////
  1004. /**********************************************************************
  1005. InitToolTips()
  1006. Derive a bounding rectangle for the nth element of a list box, 0 based.
  1007. Refuse to generate rectangles for nonexistent elements. Return TRUE if a
  1008. rectangle was generated, otherwise FALSE.
  1009. **********************************************************************/
  1010. BOOL
  1011. C_KeyringDlg::InitTooltips(void)
  1012. {
  1013. TOOLINFO ti;
  1014. memset(&ti,0,sizeof(TOOLINFO));
  1015. ti.cbSize = sizeof(TOOLINFO);
  1016. INT n = 0;
  1017. RECT rLB; // list box bounding rect for client portion
  1018. HWND hLB = GetDlgItem(m_hDlg,IDC_KEYLIST);
  1019. if (NULL == hLB)
  1020. {
  1021. return FALSE;
  1022. }
  1023. // Create the tooltip window that will be activated and shown when
  1024. // a tooltip is displayed
  1025. HWND hwndTip = CreateWindowEx(NULL,TOOLTIPS_CLASS,NULL,
  1026. WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
  1027. CW_USEDEFAULT,CW_USEDEFAULT,
  1028. CW_USEDEFAULT,CW_USEDEFAULT,
  1029. m_hDlg,NULL,m_hInstance,
  1030. NULL);
  1031. if (NULL == hwndTip)
  1032. {
  1033. return FALSE;
  1034. }
  1035. SetWindowPos(hwndTip,HWND_TOPMOST, 0, 0, 0, 0,
  1036. SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  1037. // Subclass the list box here in order to get the TTN_GETDISPINFO notification
  1038. lpfnOldWindowProc = (WNDPROC) SetWindowLongPtr(hLB,GWLP_WNDPROC,(LONG_PTR) ListBoxSubClassFunction);
  1039. INT_PTR iHeight = SendMessage(hLB,LB_GETITEMHEIGHT,0,0);
  1040. if ((LB_ERR == iHeight) || (iHeight == 0))
  1041. {
  1042. return FALSE;
  1043. }
  1044. if (!GetClientRect(hLB,&rLB))
  1045. {
  1046. return FALSE;
  1047. }
  1048. INT_PTR m = rLB.bottom - rLB.top; // unit count client area height
  1049. m = m/iHeight; // find out how many items
  1050. INT_PTR i; // loop control
  1051. LONG itop = 0; // top of tip item rect
  1052. for (i=0 ; i < m ; i++)
  1053. {
  1054. ti.uFlags = TTF_SUBCLASS;
  1055. ti.hwnd = hLB; // window that gets the TTN_GETDISPINFO
  1056. ti.uId = IDC_KEYLIST;
  1057. ti.hinst = m_hInstance;
  1058. ti.lpszText = LPSTR_TEXTCALLBACK;
  1059. ti.rect.top = itop;
  1060. ti.rect.bottom = itop + (LONG) iHeight - 1;
  1061. ti.rect.left = rLB.left;
  1062. ti.rect.right = rLB.right;
  1063. itop += (LONG) iHeight;
  1064. ti.lParam = (LPARAM) n++;
  1065. #ifdef LOUDLY2
  1066. OutputDebugString(L"Adding a tip control region\n");
  1067. _stprintf(szTemp,L"top = %d bottom = %d left = %d right = %d\n",ti.rect.top,ti.rect.bottom,ti.rect.left,ti.rect.right);
  1068. OutputDebugString(szTemp);
  1069. #endif
  1070. // Add the keylist to the tool list as a single unit
  1071. SendMessage(hwndTip,TTM_ADDTOOL,(WPARAM) 0,(LPARAM)(LPTOOLINFO)&ti);
  1072. }
  1073. return TRUE;
  1074. }
  1075. /**********************************************************************
  1076. // Get item number from pD->lParam
  1077. // Fetch that text string from listbox at pD->hwnd
  1078. // trim suffix
  1079. // Call translation API
  1080. // Write back the string
  1081. **********************************************************************/
  1082. BOOL
  1083. SetToolText(NMTTDISPINFO *pD) {
  1084. CREDENTIAL *pCred = NULL; // used to read cred under mouse ptr
  1085. INT_PTR iWhich; // which index into list
  1086. HWND hLB; // list box hwnd
  1087. //NMHDR *pHdr; // notification msg hdr
  1088. TCHAR rgt[TIPSTRINGLEN]; // temp string for tooltip
  1089. TCHAR szCredName[TARGETNAMEMAXLENGTH]; // credname
  1090. TCHAR *pszTargetName; // ptr to target name in pCred
  1091. DWORD dwType; // type of target cred
  1092. TCHAR *pC; // used for suffix trimming
  1093. BOOL f; // used for suffix trimming
  1094. LRESULT lRet; // api ret value
  1095. ULONG ulOutSize; // ret from CredpValidateTargetName()
  1096. WILDCARD_TYPE OutType; // enum type to receive ret from api
  1097. UNICODE_STRING OutUString; // UNICODESTRING to package ret from api
  1098. WCHAR *pwc;
  1099. UINT iString; // resource # of string
  1100. TCHAR rgcFormat[TIPSTRINGLEN]; // Hold tooltip template string
  1101. NTSTATUS ns;
  1102. //pHdr = &(pD->hdr);
  1103. hLB = GetDlgItem(g_hMainDlg,IDC_KEYLIST);
  1104. iWhich = SendMessage(hLB,LB_GETTOPINDEX,0,0);
  1105. iWhich += pD->lParam;
  1106. #ifdef LOUDLY
  1107. TCHAR rga[100];
  1108. _stprintf(rga,L"Text reqst for %d\n",iWhich);
  1109. OutputDebugString(rga);
  1110. #endif
  1111. // Read the indicated cred from the store, by first fetching the name string and type
  1112. // from the listbox
  1113. lRet = SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETTEXT,iWhich,(LPARAM) szCredName);
  1114. if ((LB_ERR == lRet) || (0 == lRet))
  1115. {
  1116. return FALSE;
  1117. }
  1118. dwType = (DWORD) SendDlgItemMessage(g_hMainDlg,IDC_KEYLIST,LB_GETITEMDATA,iWhich,0);
  1119. #ifdef LOUDLY
  1120. OutputDebugString(L"Target: ");
  1121. OutputDebugString(szCredName);
  1122. OutputDebugString(L"\n");
  1123. #endif
  1124. // null term the targetname, trimming the suffix if there is one
  1125. pC = _tcschr(szCredName,g_rgcCert[0]);
  1126. if (pC) {
  1127. pC--;
  1128. *pC = 0x0; // null terminate namestring
  1129. }
  1130. #ifdef LOUDLY
  1131. OutputDebugString(L"Trimmed target: ");
  1132. OutputDebugString(szCredName);
  1133. OutputDebugString(L"\n");
  1134. #endif
  1135. // For special cred, replace the credname with a special string
  1136. if (dwType == SESSION_FLAG_VALUE)
  1137. {
  1138. _tcsncpy(szCredName,CRED_SESSION_WILDCARD_NAME,TARGETNAMEMAXLENGTH - 1);
  1139. dwType = CRED_TYPE_DOMAIN_PASSWORD;
  1140. }
  1141. // Attempt to read the credential from the store
  1142. // The returned credential will have to be freed if leaving this block
  1143. f = (CredRead(szCredName,
  1144. (ULONG) dwType ,
  1145. 0,
  1146. &pCred));
  1147. if (!f)
  1148. {
  1149. return FALSE;
  1150. }
  1151. #ifdef LOUDLY
  1152. if (f) OutputDebugString(L"Successful Cred Read\n");
  1153. #endif
  1154. // clear tip strings
  1155. szTipString[0] = 0;
  1156. rgt[0] = 0;
  1157. #ifndef SIMPLETOOLTIPS
  1158. pszTargetName = pCred->TargetName;
  1159. if (NULL == pszTargetName) return FALSE;
  1160. ns = CredpValidateTargetName(
  1161. pCred->TargetName,
  1162. pCred->Type,
  1163. MightBeUsernameTarget,
  1164. NULL,
  1165. NULL,
  1166. &ulOutSize,
  1167. &OutType,
  1168. &OutUString);
  1169. if (!SUCCEEDED(ns))
  1170. {
  1171. return FALSE;
  1172. }
  1173. pwc = OutUString.Buffer;
  1174. switch (OutType)
  1175. {
  1176. case WcDfsShareName:
  1177. iString = IDS_TIPDFS;
  1178. break;
  1179. case WcServerName:
  1180. iString = IDS_TIPSERVER;
  1181. break;
  1182. case WcServerWildcard:
  1183. iString = IDS_TIPTAIL;
  1184. pwc++; // trim off the leading '.'
  1185. break;
  1186. case WcDomainWildcard:
  1187. iString = IDS_TIPDOMAIN;
  1188. break;
  1189. case WcUniversalSessionWildcard:
  1190. iString = IDS_TIPDIALUP;
  1191. break;
  1192. case WcUniversalWildcard:
  1193. iString = IDS_TIPOTHER;
  1194. break;
  1195. case WcUserName:
  1196. iString = IDS_TIPUSER;
  1197. break;
  1198. default:
  1199. ASSERT(0);
  1200. iString = 0;
  1201. break;
  1202. }
  1203. // Show tip text unless we fail to get the string
  1204. // On fail, show the username
  1205. if (0 != LoadString(g_hInstance,iString,rgcFormat,TIPSTRINGLEN))
  1206. {
  1207. _stprintf(rgt,rgcFormat,pwc);
  1208. }
  1209. else
  1210. {
  1211. if (0 != LoadString(g_hInstance,IDS_LOGASUSER,rgcFormat,500))
  1212. {
  1213. _stprintf(rgt,rgcFormat,iWhich,pCred->UserName);
  1214. }
  1215. else
  1216. {
  1217. rgt[0] = 0;
  1218. }
  1219. }
  1220. #endif
  1221. #ifdef LOUDLY
  1222. OutputDebugString(L"Tip text:");
  1223. //OutputDebugString(pCred->UserName);
  1224. OutputDebugString(rgt);
  1225. OutputDebugString(L"\n");
  1226. #endif
  1227. if (rgt[0] == 0)
  1228. {
  1229. if (pCred) CredFree(pCred);
  1230. return FALSE;
  1231. }
  1232. //_tcscpy(szTipString,pCred->UserName); // copy to a more persistent buffer
  1233. _tcsncpy(szTipString,rgt,TIPSTRINGLEN - 1); // copy to a more persistent buffer
  1234. pD->lpszText = szTipString; // point the response to it
  1235. pD->hinst = NULL;
  1236. if (pCred)
  1237. {
  1238. CredFree(pCred);
  1239. }
  1240. return TRUE;
  1241. }
  1242. /**********************************************************************
  1243. ListBoxSubClassFunction()
  1244. Arguments: None
  1245. Returns: BOOL always TRUE
  1246. Comments: Message handler subclassing function for the list box, which intercepts
  1247. requests for tooltip display information and processes them.
  1248. **********************************************************************/
  1249. LRESULT CALLBACK ListBoxSubClassFunction(HWND hW,WORD Message,WPARAM wparam,LPARAM lparam)
  1250. {
  1251. if (Message == WM_NOTIFY)
  1252. {
  1253. if ((int) wparam == IDC_KEYLIST)
  1254. {
  1255. NMHDR *pnm = (NMHDR *) lparam;
  1256. if (pnm->code == TTN_GETDISPINFO)
  1257. {
  1258. NMTTDISPINFO *pDi;
  1259. pDi = (NMTTDISPINFO *) pnm;
  1260. SetToolText(pDi);
  1261. }
  1262. }
  1263. }
  1264. return CallWindowProc(lpfnOldWindowProc,hW,Message,wparam,lparam);
  1265. }