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

1293 lines
43 KiB

  1. /*******************************************************
  2. MultiUI.cpp
  3. Code for handling multiple user interface in IE
  4. and friends
  5. Initially by Christopher Evans (cevans) 4/28/98
  6. ********************************************************/
  7. #include "private.h"
  8. #include "resource.h"
  9. #include "multiui.h"
  10. #include "multiutl.h"
  11. #include "multiusr.h"
  12. #include "mluisup.h"
  13. #include "strconst.h"
  14. #include "commctrl.h"
  15. extern HINSTANCE g_hInst;
  16. static const GUID GUID_NULL = { /* 00000000-0000-0000-0000-000000000000 */
  17. 0x0,
  18. 0x0,
  19. 0x0,
  20. {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
  21. };
  22. static const HELPMAP g_rgCtxMapMultiUserGeneral[] = {
  23. {IDC_NO_HELP_1, NO_HELP},
  24. {IDC_NO_HELP_2, NO_HELP},
  25. {IDC_NO_HELP_3, NO_HELP},
  26. {IDC_NO_HELP_4, NO_HELP},
  27. {idcWarningIcon, NO_HELP},
  28. {idcConfirmMsg, NO_HELP},
  29. {idcErrorMsg, NO_HELP},
  30. {idcLoginInstr, NO_HELP},
  31. {idcWelcomeMsg, NO_HELP},
  32. {idcAdd, IDH_IDENTITY_ADD},
  33. {idcNewPwd, IDH_IDENTITY_PWORD_NEW},
  34. {idcPwdCaption,IDH_IDENTITY_ENTER_PWORD},
  35. {idcPwd, IDH_IDENTITY_ENTER_PWORD},
  36. {idcProperties, IDH_IDENTITY_PROPERTIES},
  37. {idcConfPwd, IDH_IDENTITY_CONFIRM_PWORD},
  38. {idcUserName, IDH_IDENTITY_NAME},
  39. {idcDefault, IDH_IDENTITY_DEFAULT},
  40. {idcOldPwd, IDH_IDENTITY_PWORD_OLD},
  41. {idcStartupCombo, IDH_IDENTITY_STARTAS},
  42. {idcDelete, IDH_IDENTITY_DELETE},
  43. {idcStaticName, IDH_IDENTITY_LIST},
  44. {idcUserNameList, IDH_IDENTITY_LIST},
  45. {idcTellMeMore, /*IDH_IDENTITY_TELLMEMORE_CONTENT */IDH_IDENTITY_TELLMEMORE},
  46. {idcStaticNames, IDH_IDENTITY_LIST},
  47. {idcStaticStartUp, IDH_IDENTITY_STARTAS},
  48. {idcUsePwd, IDH_IDENTITY_PROMPT_PWORD},
  49. {idcChgPwd, IDH_IDENTITY_CHANGE_PWORD},
  50. {idcConfirmPwd, IDH_MULTI_DELETE_PWORD},
  51. {idcManage, IDH_IDENTITY_MANAGE},
  52. {idcLogoff, IDH_MULTI_LOG_OFF},
  53. {idcCheckDefault, IDH_MULTI_MNG_IDENT_DEFAULT},
  54. {idcDefaultCombo, IDH_MULTI_MNG_DEFAULT_LIST},
  55. {0,0}};
  56. /*
  57. MU_ShowErrorMessage
  58. Simple wrapper around resource string table based call to MessageBox
  59. */
  60. void MU_ShowErrorMessage(HWND hwnd, UINT iMsgID, UINT iTitleID)
  61. {
  62. TCHAR szMsg[255], szTitle[63];
  63. MLLoadStringA(iMsgID, szMsg, ARRAYSIZE(szMsg));
  64. MLLoadStringA(iTitleID, szTitle, ARRAYSIZE(szTitle));
  65. MessageBox(hwnd, szMsg, szTitle, MB_OK | MB_ICONEXCLAMATION);
  66. }
  67. /*
  68. _StripDefault
  69. Remove the (Default) string from the user's name, if it
  70. appears. Should be called after getting a username from
  71. the listbox since the default user has the string (Default)
  72. appended to it
  73. */
  74. void _StripDefault(LPSTR psz)
  75. {
  76. TCHAR szResString[CCH_USERNAME_MAX_LENGTH], *pszStr;
  77. MLLoadStringA(idsDefault, szResString, CCH_USERNAME_MAX_LENGTH);
  78. pszStr = strstr(psz, szResString);
  79. if(pszStr)
  80. {
  81. *pszStr = 0;
  82. }
  83. }
  84. #ifdef IDENTITY_PASSWORDS
  85. // ****************************************************************************************************
  86. // C H A N G E U S E R P A S S W O R D
  87. /*
  88. _ValidateChangePasswordValues
  89. Validate the data entered by the user. Return true only if everything is
  90. legitimate,
  91. */
  92. static BOOL _ValidateChangePasswordValues(HWND hDlg,
  93. TCHAR* lpszOldNewPassword)
  94. {
  95. TCHAR szOldPW[255], szPW1[255], szPW2[255];
  96. GetDlgItemText(hDlg,idcOldPwd, szOldPW, ARRAYSIZE(szOldPW));
  97. GetDlgItemText(hDlg,idcNewPwd, szPW1, ARRAYSIZE(szPW1));
  98. GetDlgItemText(hDlg,idcConfPwd, szPW2, ARRAYSIZE(szPW2));
  99. if (strcmp(lpszOldNewPassword, szOldPW) != 0)
  100. {
  101. MU_ShowErrorMessage(hDlg, idsPwdDoesntMatch, idsPwdError);
  102. SetFocus(GetDlgItem(hDlg,idcOldPwd));
  103. SendDlgItemMessage(hDlg,idcOldPwd,EM_SETSEL,0,-1);
  104. return false;
  105. }
  106. if (strcmp(szPW1, szPW2) != 0)
  107. {
  108. MU_ShowErrorMessage(hDlg, idsPwdChgNotMatch, idsPwdError);
  109. SetFocus(GetDlgItem(hDlg,idcNewPwd));
  110. SendDlgItemMessage(hDlg,idcNewPwd,EM_SETSEL,0,-1);
  111. return false;
  112. }
  113. strcpy(lpszOldNewPassword, szPW1);
  114. return true;
  115. }
  116. /*
  117. _ChangeUserPwdDlgProc
  118. Description: Dialog proc for handling the change user password dialog.
  119. */
  120. INT_PTR CALLBACK _ChangeUserPwdDlgProc(HWND hDlg,
  121. UINT iMsg,
  122. WPARAM wParam,
  123. LPARAM lParam)
  124. {
  125. static TCHAR *sOldNewPassword;
  126. switch (iMsg)
  127. {
  128. case WM_INITDIALOG:
  129. SendMessage(GetDlgItem(hDlg, idcNewPwd), EM_LIMITTEXT, CCH_USERPASSWORD_MAX_LENGTH-1, 0);
  130. SendMessage(GetDlgItem(hDlg, idcOldPwd), EM_LIMITTEXT, CCH_USERPASSWORD_MAX_LENGTH-1, 0);
  131. SendMessage(GetDlgItem(hDlg,idcConfPwd), EM_LIMITTEXT, CCH_USERPASSWORD_MAX_LENGTH-1, 0);
  132. sOldNewPassword = (TCHAR *)lParam;
  133. return TRUE;
  134. case WM_HELP:
  135. case WM_CONTEXTMENU:
  136. return OnContextHelp(hDlg, iMsg, wParam, lParam, g_rgCtxMapMultiUserGeneral);
  137. case WM_COMMAND:
  138. switch(LOWORD(wParam))
  139. {
  140. case IDOK:
  141. if (_ValidateChangePasswordValues(hDlg, sOldNewPassword))
  142. MLEndDialogWrap(hDlg, IDOK);
  143. return true;
  144. case IDCANCEL:
  145. MLEndDialogWrap(hDlg, IDCANCEL);
  146. return true;
  147. }
  148. break;
  149. }
  150. return false;
  151. }
  152. /*
  153. ChangeUserPassword
  154. Wrapper routine for changing the user password. Pass in the current
  155. password in lpszOldNewPassword which is used to confirm the current
  156. password with what the user entered. If the user enters the old
  157. password correctly and enters the new password twice correctly,
  158. and clicks OK, then the new password is returned in lpszOldNewPassword
  159. and this function returns TRUE. Otherwise, the value in lpszOldNewPassword
  160. is unchanged and it returns false.
  161. lpszOldNewPassword must point to a TCHAR buffer large enough to hold a password
  162. (CCH_USERPASSWORD_MAX_LENGTH characters)
  163. */
  164. BOOL ChangeUserPassword(HWND hwnd, TCHAR *lpszOldNewPassword)
  165. {
  166. INT_PTR bResult;
  167. Assert(hwnd);
  168. Assert(lpszOldNewPassword);
  169. bResult = MLDialogBoxParamWrap(MLGetHinst(), MAKEINTRESOURCEW(iddChgPwd), hwnd, _ChangeUserPwdDlgProc, (LPARAM)lpszOldNewPassword);
  170. //Don't actually change it here, the caller will do the right thing
  171. //since this may be (and is) called from another dialog with a cancel
  172. //button on it
  173. return (bResult == IDOK);
  174. }
  175. // ****************************************************************************************************
  176. // C O N F I R M U S E R P A S S W O R D
  177. /*
  178. _ConfirmUserPwdDlgProc
  179. Description: Dialog proc for handling the confirming user password dialog.
  180. */
  181. INT_PTR CALLBACK _ConfirmUserPwdDlgProc(HWND hDlg,
  182. UINT iMsg,
  183. WPARAM wParam,
  184. LPARAM lParam)
  185. {
  186. static LPCONFIRMPWDDIALOGINFO sConfirmPwdInfo;
  187. switch (iMsg)
  188. {
  189. case WM_INITDIALOG:
  190. Assert(lParam);
  191. SendMessage(GetDlgItem(hDlg, idcConfirmPwd), EM_LIMITTEXT, CCH_USERPASSWORD_MAX_LENGTH-1, 0);
  192. sConfirmPwdInfo = (LPCONFIRMPWDDIALOGINFO)lParam;
  193. SetDlgItemText(hDlg, idcConfirmMsg, sConfirmPwdInfo->szMsg);
  194. return TRUE;
  195. case WM_HELP:
  196. case WM_CONTEXTMENU:
  197. return OnContextHelp(hDlg, iMsg, wParam, lParam, g_rgCtxMapMultiUserGeneral);
  198. case WM_COMMAND:
  199. switch(LOWORD(wParam))
  200. {
  201. case IDOK:
  202. TCHAR szPW[255];
  203. //if the password matches the provided password, then
  204. //everything is OK and the dialog can complete, otherwise,
  205. //barf an error message and keep waiting for a good password
  206. //or Cancel.
  207. GetDlgItemText(hDlg,idcConfirmPwd, szPW, ARRAYSIZE(szPW));
  208. if (strcmp(szPW, sConfirmPwdInfo->szPassword) == 0)
  209. MLEndDialogWrap(hDlg, IDOK);
  210. else
  211. {
  212. MU_ShowErrorMessage(hDlg, idsPwdDoesntMatch, idsPwdError);
  213. SetFocus(GetDlgItem(hDlg,idcConfirmPwd));
  214. SendDlgItemMessage(hDlg,idcConfirmPwd,EM_SETSEL,0,-1);
  215. }
  216. return true;
  217. case IDCANCEL:
  218. MLEndDialogWrap(hDlg, IDCANCEL);
  219. return true;
  220. }
  221. break;
  222. }
  223. return false;
  224. }
  225. /*
  226. MU_ConfirmUserPassword
  227. Confirm that the user knows the password before it is disabled
  228. in the registry. If they enter the correct password, simply return
  229. true since the calling dialog box will do the right thing if the
  230. user clicks cancel there.
  231. */
  232. BOOL MU_ConfirmUserPassword(HWND hwnd, TCHAR *lpszMsg, TCHAR *lpszPassword)
  233. {
  234. INT_PTR bResult;
  235. CONFIRMPWDDIALOGINFO vConfirmInfo;
  236. Assert(hwnd);
  237. Assert(lpszPassword);
  238. Assert(lpszMsg);
  239. Assert(lstrlen(lpszMsg) < ARRAYSIZE(vConfirmInfo.szMsg));
  240. Assert(lstrlen(lpszPassword) < ARRAYSIZE(vConfirmInfo.szPassword));
  241. strcpy(vConfirmInfo.szMsg, lpszMsg);
  242. strcpy(vConfirmInfo.szPassword, lpszPassword);
  243. bResult = MLDialogBoxParamWrap(MLGetHinst(), MAKEINTRESOURCEW(iddPasswordOff), hwnd, _ConfirmUserPwdDlgProc, (LPARAM)&vConfirmInfo);
  244. return (bResult == IDOK);
  245. }
  246. // ****************************************************************************************************
  247. // E N T E R U S E R P A S S W O R D
  248. /*
  249. _ValidateNewPasswordValues
  250. Description: Make sure that the entered values in the new password
  251. dialog are legit and consistant.
  252. */
  253. static BOOL _ValidateNewPasswordValues(HWND hDlg,
  254. TCHAR* lpszNewPassword)
  255. {
  256. TCHAR szPW1[255], szPW2[255];
  257. GetDlgItemText(hDlg,idcNewPwd, szPW1, ARRAYSIZE(szPW1));
  258. GetDlgItemText(hDlg,idcConfPwd, szPW2, ARRAYSIZE(szPW2));
  259. if (strcmp(szPW1, szPW2) != 0)
  260. {
  261. MU_ShowErrorMessage(hDlg, idsPwdChgNotMatch, idsPwdError);
  262. SetFocus(GetDlgItem(hDlg,idcNewPwd));
  263. SendDlgItemMessage(hDlg,idcNewPwd,EM_SETSEL,0,-1);
  264. return false;
  265. }
  266. strcpy(lpszNewPassword, szPW1);
  267. return true;
  268. }
  269. /*
  270. _EnterUserPwdDlgProc
  271. Description: Dialog proc for handling the enter user password dialog.
  272. */
  273. INT_PTR CALLBACK _EnterUserPwdDlgProc(HWND hDlg,
  274. UINT iMsg,
  275. WPARAM wParam,
  276. LPARAM lParam)
  277. {
  278. static TCHAR *sNewPassword;
  279. switch (iMsg)
  280. {
  281. case WM_INITDIALOG:
  282. SendMessage(GetDlgItem(hDlg, idcNewPwd), EM_LIMITTEXT, CCH_USERPASSWORD_MAX_LENGTH-1, 0);
  283. SendMessage(GetDlgItem(hDlg, idcConfPwd), EM_LIMITTEXT, CCH_USERPASSWORD_MAX_LENGTH-1, 0);
  284. sNewPassword = (TCHAR *)lParam;
  285. return TRUE;
  286. case WM_HELP:
  287. case WM_CONTEXTMENU:
  288. return OnContextHelp(hDlg, iMsg, wParam, lParam, g_rgCtxMapMultiUserGeneral);
  289. case WM_COMMAND:
  290. switch(LOWORD(wParam))
  291. {
  292. case IDOK:
  293. if (_ValidateNewPasswordValues(hDlg, sNewPassword))
  294. MLEndDialogWrap(hDlg, IDOK);
  295. return true;
  296. case IDCANCEL:
  297. MLEndDialogWrap(hDlg, IDCANCEL);
  298. return true;
  299. }
  300. break;
  301. }
  302. return false;
  303. }
  304. /*
  305. EnterUserPassword
  306. Wrapper routine for getting a new user password. If the user enters the
  307. password and confirms it correctly, and clicks OK, then the new password is
  308. returned in lpszNewPassword and this function returns TRUE.
  309. Otherwise, the value in lpszNewPassword is unchanged and it returns false.
  310. lpszNewPassword must point to a TCHAR buffer large enough to hold a password
  311. (CCH_USERPASSWORD_MAX_LENGTH characters)
  312. */
  313. BOOL EnterUserPassword(HWND hwnd, TCHAR *lpszNewPassword)
  314. {
  315. INT_PTR bResult;
  316. Assert(hwnd);
  317. Assert(lpszNewPassword);
  318. bResult = MLDialogBoxParamWrap(MLGetHinst(), MAKEINTRESOURCEW(iddNewPwd), hwnd, _EnterUserPwdDlgProc, (LPARAM)lpszNewPassword);
  319. return (bResult == IDOK);
  320. }
  321. #endif //IDENTITY_PASSWORDS
  322. // ****************************************************************************************************
  323. // C O N F I R M D E L E T E U S E R D I A L O G
  324. /*
  325. ConfirmDeleteUserDlgProc
  326. Description: Dialog proc for handling the confirm delete user dialog.
  327. */
  328. INT_PTR CALLBACK _ConfirmDeleteUserDlgProc(HWND hDlg,
  329. UINT iMsg,
  330. WPARAM wParam,
  331. LPARAM lParam)
  332. {
  333. switch (iMsg)
  334. {
  335. case WM_INITDIALOG:
  336. Assert(lParam);
  337. SendDlgItemMessage(hDlg, idcWarningIcon, STM_SETICON, (WPARAM)::LoadIcon(NULL, IDI_EXCLAMATION), 0);
  338. SetDlgItemText(hDlg, idcErrorMsg, (TCHAR *)lParam);
  339. return TRUE;
  340. case WM_HELP:
  341. case WM_CONTEXTMENU:
  342. return OnContextHelp(hDlg, iMsg, wParam, lParam, g_rgCtxMapMultiUserGeneral);
  343. case WM_COMMAND:
  344. switch(LOWORD(wParam))
  345. {
  346. case IDOK:
  347. case IDCANCEL:
  348. MLEndDialogWrap(hDlg, LOWORD(wParam));
  349. return true;
  350. }
  351. break;
  352. }
  353. return false;
  354. }
  355. BOOL MU_ConfirmDeleteUser(HWND hwnd, TCHAR *lpszUsername)
  356. {
  357. TCHAR szBuffer[255]; // really ought to be big enough
  358. TCHAR szDisplay[255+CCH_USERNAME_MAX_LENGTH];
  359. TCHAR szPassword[CCH_USERPASSWORD_MAX_LENGTH];
  360. // format the message with the username scattered throughout.
  361. MLLoadStringA(idsConfirmDeleteMsg, szBuffer, ARRAYSIZE(szBuffer));
  362. if (szBuffer[0])
  363. {
  364. INT_PTR bResult;
  365. wsprintf(szDisplay, szBuffer, lpszUsername);
  366. // Show the Confirm Delete dialog box to make sure they really want to delete the user
  367. bResult = MLDialogBoxParamWrap(MLGetHinst(), MAKEINTRESOURCEW(iddConfirmUserDelete), hwnd, _ConfirmDeleteUserDlgProc, (LPARAM)szDisplay);
  368. #ifdef IDENTITY_PASSWORDS
  369. if (IDOK == bResult)
  370. {
  371. BOOL fUsePassword;
  372. // check to see if this user has a password, if so, then make sure that
  373. // they know the password before blowing it all away.
  374. if (MU_GetPasswordForUsername(lpszUsername, szPassword, &fUsePassword))
  375. {
  376. if (fUsePassword)
  377. {
  378. MLLoadStringA(idsConfirmDelPwd, szBuffer, ARRAYSIZE(szBuffer));
  379. wsprintf(szDisplay, szBuffer, lpszUsername);
  380. if (!MU_ConfirmUserPassword(hwnd, szDisplay, szPassword))
  381. bResult = IDCANCEL;
  382. }
  383. }
  384. else //couldn't load the password, can't delete them either
  385. {
  386. MU_ShowErrorMessage(hwnd, idsPwdNotFound, idsPwdError);
  387. bResult = IDCANCEL;
  388. }
  389. return (IDOK == bResult);
  390. }
  391. #else
  392. return (IDOK == bResult);
  393. #endif //IDENTITY_PASSWORDS
  394. }
  395. return false;
  396. }
  397. // ****************************************************************************************************
  398. // C H A N G E U S E R S E T T I N G S
  399. /*
  400. _ValidateChangeUserValues
  401. Validate the data entered by the user. Return true only if everything is
  402. legit,
  403. */
  404. static BOOL _ValidateChangeUserValues(HWND hDlg,
  405. LPUSERINFO lpUserInfo)
  406. {
  407. TCHAR szResString[CCH_USERNAME_MAX_LENGTH], *pszStr;
  408. TCHAR szUsername[255];
  409. ULONG cb;
  410. GetDlgItemText(hDlg,idcUserName, szUsername, ARRAYSIZE(szUsername));
  411. cb = lstrlen(szUsername);
  412. UlStripWhitespace(szUsername, false, true, &cb); //remove trailing whitespace
  413. // Make sure the username wasn't all spaces
  414. if (!cb)
  415. {
  416. MU_ShowErrorMessage(hDlg, idsUserNameTooShort, idsNameTooShort);
  417. SetFocus(GetDlgItem(hDlg,idcUserName));
  418. SendDlgItemMessage(hDlg,idcUserName,EM_SETSEL,0,-1);
  419. return false;
  420. }
  421. // if the username exists, and its not the same as the account currently, then
  422. // it is not allowed.
  423. if (MU_UsernameExists(szUsername) && strcmp(szUsername, lpUserInfo->szUsername) != 0)
  424. {
  425. MU_ShowErrorMessage(hDlg, idsUserNameExists, idsUserNameInUse);
  426. SetFocus(GetDlgItem(hDlg,idcUserName));
  427. SendDlgItemMessage(hDlg,idcUserName,EM_SETSEL,0,-1);
  428. return false;
  429. }
  430. lstrcpy(lpUserInfo->szUsername, szUsername);
  431. lpUserInfo->fUsePassword = IsDlgButtonChecked(hDlg, idcUsePwd);
  432. if (!lpUserInfo->fUsePassword)
  433. lpUserInfo->szPassword[0] = 0;
  434. return true;
  435. }
  436. /*
  437. ChangeUserSettingsDlgProc
  438. Description: Dialog proc for handling the Change user settings dialog.
  439. */
  440. INT_PTR CALLBACK _ChangeUserSettingsDlgProc(HWND hDlg,
  441. UINT iMsg,
  442. WPARAM wParam,
  443. LPARAM lParam)
  444. {
  445. static LPUSERINFO sUserInfo;
  446. TCHAR szMsg[255];
  447. TCHAR szPassword[CCH_USERPASSWORD_MAX_LENGTH];
  448. switch (iMsg)
  449. {
  450. case WM_INITDIALOG:
  451. Assert(lParam);
  452. sUserInfo = (LPUSERINFO)lParam;
  453. MLLoadStringA((*sUserInfo->szUsername) ? idsIdentityProperties : idsNewIdentity, szMsg, ARRAYSIZE(szMsg));
  454. SendMessage(hDlg, WM_SETTEXT, 0, (LPARAM)szMsg);
  455. SetDlgItemText(hDlg, idcUserName, sUserInfo->szUsername);
  456. SendMessage(GetDlgItem(hDlg, idcUserName), EM_LIMITTEXT, CCH_IDENTITY_NAME_MAX_LENGTH/2, 0);
  457. CheckDlgButton(hDlg, idcUsePwd, sUserInfo->fUsePassword ? BST_CHECKED : BST_UNCHECKED);
  458. EnableWindow(GetDlgItem(hDlg, idcChgPwd), sUserInfo->fUsePassword);
  459. // Don't allow zero length names by disabling OK
  460. if (!lstrlen(sUserInfo->szUsername))
  461. EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
  462. return TRUE;
  463. case WM_HELP:
  464. case WM_CONTEXTMENU:
  465. return OnContextHelp(hDlg, iMsg, wParam, lParam, g_rgCtxMapMultiUserGeneral);
  466. case WM_COMMAND:
  467. switch(LOWORD(wParam))
  468. {
  469. case IDOK:
  470. if (_ValidateChangeUserValues(hDlg, sUserInfo))
  471. MLEndDialogWrap(hDlg, IDOK);
  472. return true;
  473. case IDCANCEL:
  474. MLEndDialogWrap(hDlg, IDCANCEL);
  475. return true;
  476. case idcUserName:
  477. if (EN_CHANGE == HIWORD(wParam))
  478. {
  479. EnableWindow(GetDlgItem(hDlg, IDOK), SendMessage((HWND)lParam, WM_GETTEXTLENGTH, 0, 0) != 0);
  480. return TRUE;
  481. }
  482. break;
  483. #ifdef IDENTITY_PASSWORDS
  484. case idcTellMeMore:
  485. // WinHelp ((HWND)GetDlgItem(hDlg, idcTellMeMore),
  486. // c_szCtxHelpFile,
  487. // HELP_WM_HELP,
  488. // (DWORD_PTR)(LPVOID)g_rgCtxMapMultiUserGeneral);
  489. WinHelp(hDlg, c_szCtxHelpFile, HELP_CONTEXT, IDH_IDENTITY_TELLMEMORE_CONTENT);
  490. return true;
  491. case idcUsePwd:
  492. // if they are turning off the password, they need to confirm it first.
  493. if (!IsDlgButtonChecked(hDlg, idcUsePwd))
  494. {
  495. strcpy(szPassword, sUserInfo->szPassword);
  496. MLLoadStringA(idsConfirmDisablePwd, szMsg, ARRAYSIZE(szMsg));
  497. if (!MU_ConfirmUserPassword(hDlg,szMsg, szPassword))
  498. CheckDlgButton(hDlg, idcUsePwd, BST_CHECKED);
  499. }
  500. else
  501. {
  502. // if they are turning it on, they should set the password.
  503. if (EnterUserPassword(hDlg, szPassword))
  504. {
  505. sUserInfo->fUsePassword = true;
  506. strcpy(sUserInfo->szPassword, szPassword);
  507. }
  508. else
  509. {
  510. CheckDlgButton(hDlg, idcUsePwd, BST_UNCHECKED);
  511. }
  512. }
  513. EnableWindow(GetDlgItem(hDlg, idcChgPwd), IsDlgButtonChecked(hDlg, idcUsePwd));
  514. return true;
  515. case idcChgPwd:
  516. if(sUserInfo->fUsePassword || (0 != *sUserInfo->szPassword))
  517. {
  518. strcpy(szPassword, sUserInfo->szPassword);
  519. if (ChangeUserPassword(hDlg, szPassword))
  520. strcpy(sUserInfo->szPassword, szPassword);
  521. }
  522. return true;
  523. #endif //IDENTITY_PASSWORDS
  524. }
  525. break;
  526. }
  527. return false;
  528. }
  529. /*
  530. MU_UserProperties
  531. Allow the user the change their username or password.
  532. */
  533. BOOL MU_UserProperties(HWND hwnd, LPUSERINFO lpUserInfo)
  534. {
  535. INT_PTR fResult;
  536. USERINFO nuInfo;
  537. TCHAR szOldUsername[CCH_IDENTITY_NAME_MAX_LENGTH+1];
  538. USERINFO uiCurrent;
  539. LPARAM lpNotify = IIC_CURRENT_IDENTITY_CHANGED;
  540. INITCOMMONCONTROLSEX icex;
  541. Assert(hwnd);
  542. Assert(lpUserInfo);
  543. // get the current info so we know who to change later.
  544. MU_GetUserInfo(NULL, &nuInfo);
  545. lstrcpy(szOldUsername, lpUserInfo->szUsername);
  546. // make sure ICC_NATIVEFNTCTL_CLASS is inited
  547. icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  548. icex.dwICC = ICC_NATIVEFNTCTL_CLASS;
  549. InitCommonControlsEx(&icex);
  550. fResult = MLDialogBoxParamWrap(MLGetHinst(), MAKEINTRESOURCEW(iddUserProperties), hwnd, _ChangeUserSettingsDlgProc, (LPARAM)lpUserInfo);
  551. if (IDOK == fResult)
  552. {
  553. if (GUID_NULL == lpUserInfo->uidUserID)
  554. _ClaimNextUserId(&lpUserInfo->uidUserID);
  555. MU_SetUserInfo(lpUserInfo);
  556. // if its not the current identity, then just broadcast that an identity changed
  557. if (MU_GetUserInfo(NULL, &uiCurrent) && (lpUserInfo->uidUserID != uiCurrent.uidUserID))
  558. lpNotify = IIC_IDENTITY_CHANGED;
  559. // if the name changd, tell other apps
  560. // Unless we're doing an add (szOldUsername == "")
  561. // which already has its own notification
  562. if (*szOldUsername != 0 && lstrcmp(szOldUsername, lpUserInfo->szUsername) != 0)
  563. PostMessage(HWND_BROADCAST, WM_IDENTITY_INFO_CHANGED, 0, lpNotify);
  564. }
  565. return (IDOK == fResult);
  566. }
  567. // ****************************************************************************************************
  568. // L O G I N S C R E E N
  569. /*
  570. _ValidateLoginValues
  571. Validate the data entered by the user. Return true only if everything is
  572. legit,
  573. */
  574. static BOOL _ValidateLoginValues(HWND hDlg,
  575. TCHAR* lpszOldNewPassword)
  576. {
  577. TCHAR szUsername[255];
  578. TCHAR szPW[255], szRealPW[CCH_USERPASSWORD_MAX_LENGTH];
  579. LRESULT dSelItem;
  580. BOOL rResult = false;
  581. dSelItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_GETCURSEL, 0, 0);
  582. if (LB_ERR != dSelItem)
  583. {
  584. if (SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXTLEN, dSelItem, 0) < ARRAYSIZE(szUsername))
  585. {
  586. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dSelItem, (LPARAM)szUsername);
  587. #ifdef IDENTITY_PASSWORDS
  588. BOOL fUsePassword;
  589. if (MU_GetPasswordForUsername(szUsername, szRealPW, &fUsePassword))
  590. {
  591. if (fUsePassword)
  592. {
  593. GetDlgItemText(hDlg,idcPwd,szPW, ARRAYSIZE(szPW));
  594. if (strcmp(szPW, szRealPW) == 0)
  595. {
  596. strcpy(lpszOldNewPassword, szUsername);
  597. rResult = true;
  598. }
  599. else
  600. {
  601. MU_ShowErrorMessage(hDlg, idsPwdDoesntMatch, idsPwdError);
  602. SetFocus(GetDlgItem(hDlg,idcPwd));
  603. SendDlgItemMessage(hDlg,idcPwd,EM_SETSEL,0,-1);
  604. return false;
  605. }
  606. }
  607. else // if there is no password, then it does match up.
  608. {
  609. strcpy(lpszOldNewPassword, szUsername);
  610. rResult = true;
  611. }
  612. }
  613. else //can't load identity password, do not allow access
  614. {
  615. MU_ShowErrorMessage(hDlg, idsPwdNotFound, idsPwdError);
  616. return false;
  617. }
  618. #else //IDENTITY_PASSWORDS
  619. strcpy(lpszOldNewPassword, szUsername);
  620. rResult = true;
  621. #endif //IDENTITY_PASSWORDS
  622. }
  623. }
  624. return rResult;
  625. }
  626. static void _LoginEnableDisablePwdField(HWND hDlg)
  627. {
  628. #ifdef IDENTITY_PASSWORDS
  629. TCHAR szUsername[255], szRealPW[255];
  630. BOOL bEnabled = false;
  631. #endif //IDENTITY_PASSWORDS
  632. LRESULT dSelItem;
  633. dSelItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_GETCURSEL, 0, 0);
  634. #ifdef IDENTITY_PASSWORDS
  635. if (LB_ERR != dSelItem)
  636. {
  637. if (SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXTLEN, dSelItem, 0) < ARRAYSIZE(szUsername))
  638. {
  639. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dSelItem, (LPARAM)szUsername);
  640. BOOL fUsePassword;
  641. if (MU_GetPasswordForUsername(szUsername, szRealPW, &fUsePassword) && fUsePassword)
  642. {
  643. bEnabled = true;
  644. }
  645. }
  646. }
  647. EnableWindow(GetDlgItem(hDlg,idcPwd),bEnabled);
  648. EnableWindow(GetDlgItem(hDlg,idcPwdCaption),bEnabled);
  649. #endif //IDENTITY_PASSWORDS
  650. EnableWindow(GetDlgItem(hDlg,IDOK),(dSelItem != -1));
  651. }
  652. typedef struct
  653. {
  654. TCHAR *pszUsername;
  655. DWORD dwFlags;
  656. } LOGIN_PARAMS;
  657. /*
  658. _LoginDlgProc
  659. Description: Dialog proc for handling the OE Login dialog.
  660. */
  661. INT_PTR CALLBACK _LoginDlgProc(HWND hDlg,
  662. UINT iMsg,
  663. WPARAM wParam,
  664. LPARAM lParam)
  665. {
  666. static TCHAR *sResultUsername;
  667. static LOGIN_PARAMS *plpParams;
  668. TCHAR szMsg[1024], szRes[1024];
  669. USERINFO nuInfo;
  670. switch (iMsg)
  671. {
  672. case WM_INITDIALOG:
  673. Assert(lParam);
  674. plpParams = (LOGIN_PARAMS *)lParam;
  675. sResultUsername = plpParams->pszUsername;
  676. MLLoadStringA(!!(plpParams->dwFlags & UIL_FORCE_UI) ? idsSwitchIdentities : idsIdentityLogin, szMsg, ARRAYSIZE(szMsg));
  677. SendMessage(hDlg, WM_SETTEXT, 0, (LPARAM)szMsg);
  678. _FillListBoxWithUsernames(GetDlgItem(hDlg,idcUserNameList));
  679. if (MU_GetUserInfo(NULL, &nuInfo))
  680. {
  681. MLLoadStringA(idsLoginWithCurrent, szRes, ARRAYSIZE(szRes));
  682. wsprintf(szMsg, szRes, nuInfo.szUsername);
  683. SetDlgItemText(hDlg, idcWelcomeMsg, szMsg);
  684. MLLoadStringA(idsCurrIdentityInstr, szMsg, ARRAYSIZE(szMsg));
  685. SetDlgItemText(hDlg, idcLoginInstr, szMsg);
  686. }
  687. else
  688. {
  689. MLLoadStringA(idsLoginNoCurrent, szMsg, ARRAYSIZE(szMsg));
  690. SetDlgItemText(hDlg, idcWelcomeMsg, szMsg);
  691. MLLoadStringA(idsNoIdentityInstr, szMsg, ARRAYSIZE(szMsg));
  692. SetDlgItemText(hDlg, idcLoginInstr, szMsg);
  693. }
  694. if (sResultUsername[0] == 0)
  695. strcpy(sResultUsername, nuInfo.szUsername);
  696. if (sResultUsername[0])
  697. {
  698. LRESULT dFoundItem;
  699. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_FINDSTRING, 0, (LPARAM)sResultUsername);
  700. if (LB_ERR != dFoundItem)
  701. {
  702. SendDlgItemMessage(hDlg, idcUserNameList, LB_SETCURSEL, dFoundItem, 0);
  703. }
  704. }
  705. else
  706. SendDlgItemMessage(hDlg, idcUserNameList, LB_SETCURSEL, 0, 0);
  707. _LoginEnableDisablePwdField(hDlg);
  708. return TRUE;
  709. case WM_HELP:
  710. case WM_CONTEXTMENU:
  711. return OnContextHelp(hDlg, iMsg, wParam, lParam, g_rgCtxMapMultiUserGeneral);
  712. case WM_COMMAND:
  713. switch(HIWORD(wParam))
  714. {
  715. case LBN_DBLCLK:
  716. wParam = IDOK;
  717. break;
  718. case LBN_SELCHANGE:
  719. _LoginEnableDisablePwdField(hDlg);
  720. break;
  721. }
  722. switch(LOWORD(wParam))
  723. {
  724. case IDOK:
  725. if (_ValidateLoginValues(hDlg, sResultUsername))
  726. MLEndDialogWrap(hDlg, IDOK);
  727. return true;
  728. case IDCANCEL:
  729. MLEndDialogWrap(hDlg, IDCANCEL);
  730. return true;
  731. case idcLogoff:
  732. MLLoadStringA(idsLogoff, sResultUsername, CCH_USERNAME_MAX_LENGTH);
  733. MLEndDialogWrap(hDlg, IDOK);
  734. return true;
  735. case idcManage:
  736. {
  737. TCHAR szUsername[CCH_USERNAME_MAX_LENGTH+1] = "";
  738. MU_ManageUsers(hDlg, szUsername, 0);
  739. _FillListBoxWithUsernames(GetDlgItem(hDlg,idcUserNameList));
  740. SendDlgItemMessage(hDlg, idcUserNameList, LB_SETCURSEL, 0, 0);
  741. _LoginEnableDisablePwdField(hDlg);
  742. if (*szUsername)
  743. {
  744. lstrcpy(sResultUsername, szUsername);
  745. MLEndDialogWrap(hDlg, IDOK);
  746. }
  747. }
  748. return true;
  749. }
  750. break;
  751. }
  752. return false;
  753. }
  754. /*
  755. MU_Login
  756. Wrapper routine for logging in to OE. Asks the user to choose a username
  757. and, if necessary, enter the password for that user. The user can also
  758. create an account at this point.
  759. lpszUsername should contain the name of the person who should be the default
  760. selection in the list. If the name is empty ("") then it will look up the
  761. default from the registry.
  762. Returns the username that was selected in lpszUsername. Returns true
  763. if that username is valid.
  764. */
  765. BOOL MU_Login(HWND hwnd, DWORD dwFlags, TCHAR *lpszUsername)
  766. {
  767. INT_PTR bResult;
  768. CStringList *csList;
  769. INITCOMMONCONTROLSEX icex;
  770. Assert(hwnd);
  771. Assert(lpszUsername);
  772. // make sure ICC_NATIVEFNTCTL_CLASS is inited
  773. icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  774. icex.dwICC = ICC_NATIVEFNTCTL_CLASS;
  775. InitCommonControlsEx(&icex);
  776. csList = MU_GetUsernameList();
  777. // if there is only one username and they do not have a password, just return it.
  778. if (csList && csList->GetLength() == 1 && !(dwFlags & UIL_FORCE_UI))
  779. {
  780. TCHAR *pszUsername;
  781. TCHAR szPassword[255];
  782. BOOL fUsePassword;
  783. pszUsername = csList->GetString(0);
  784. if(MU_GetPasswordForUsername(pszUsername, szPassword, &fUsePassword) && !fUsePassword)
  785. {
  786. lstrcpy(lpszUsername, pszUsername);
  787. delete csList;
  788. return TRUE;
  789. }
  790. }
  791. LOGIN_PARAMS lpParams;
  792. lpParams.dwFlags = dwFlags;
  793. lpParams.pszUsername = lpszUsername;
  794. bResult = MLDialogBoxParamWrap(MLGetHinst(), MAKEINTRESOURCEW(iddLogin), hwnd, _LoginDlgProc, (LPARAM)&lpParams);
  795. if (csList)
  796. delete csList;
  797. return (IDOK == bResult);
  798. }
  799. void _ManagerUpdateButtons(HWND hDlg)
  800. {
  801. LRESULT dFoundItem;
  802. USERINFO rUserInfo;
  803. GUID uidDefaultId;
  804. // make sure that the delete button is only available if the
  805. // current user is not selected.
  806. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_GETCURSEL, 0, 0);
  807. if (dFoundItem != -1)
  808. {
  809. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dFoundItem, (LPARAM)rUserInfo.szUsername);
  810. MU_UsernameToUserId(rUserInfo.szUsername, &rUserInfo.uidUserID);
  811. MU_GetCurrentUserID(&uidDefaultId);
  812. // if there is no current user, don't allow deletion of the default user.
  813. if (GUID_NULL == uidDefaultId)
  814. MU_GetDefaultUserID(&uidDefaultId);
  815. }
  816. EnableWindow(GetDlgItem(hDlg, idcDelete), dFoundItem != -1 && uidDefaultId != rUserInfo.uidUserID);
  817. }
  818. typedef struct
  819. {
  820. TCHAR *pszUsername;
  821. DWORD dwFlags;
  822. } MANAGE_PARAMS;
  823. /*
  824. _ManagerDlgProc
  825. Description: Dialog proc for handling the identity manager dialog.
  826. */
  827. INT_PTR CALLBACK _ManagerDlgProc(HWND hDlg,
  828. UINT iMsg,
  829. WPARAM wParam,
  830. LPARAM lParam)
  831. {
  832. USERINFO rUserInfo;
  833. static MANAGE_PARAMS *pmpParams;
  834. static TCHAR sResultUsername[MAX_PATH] = "";
  835. static DWORD sdwFlags = 0;
  836. LRESULT dFoundItem;
  837. ULONG uidUserId;
  838. HRESULT hr;
  839. TCHAR szRes[256];
  840. USERINFO nuInfo;
  841. DWORD dwIndex;
  842. GUID uidDefault;
  843. switch (iMsg)
  844. {
  845. case WM_INITDIALOG:
  846. Assert(lParam);
  847. _ResetRememberedLoginOption();
  848. pmpParams = (MANAGE_PARAMS*)lParam;
  849. sdwFlags = pmpParams->dwFlags;
  850. _FillListBoxWithUsernames(GetDlgItem(hDlg,idcUserNameList));
  851. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcStartupCombo), GetDlgItem(hDlg,idcUserNameList));
  852. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcDefaultCombo), GetDlgItem(hDlg,idcUserNameList));
  853. dwIndex = MU_GetLoginOptionIndex(GetDlgItem(hDlg,idcStartupCombo));
  854. CheckDlgButton(hDlg, idcCheckDefault, dwIndex != ASK_BEFORE_LOGIN);
  855. EnableWindow(GetDlgItem(hDlg, idcStartupCombo), dwIndex != ASK_BEFORE_LOGIN);
  856. if (dwIndex != ASK_BEFORE_LOGIN)
  857. SendDlgItemMessage(hDlg, idcStartupCombo, CB_SETCURSEL, dwIndex, 0);
  858. else
  859. SendDlgItemMessage(hDlg, idcStartupCombo, CB_SETCURSEL, 0, 0);
  860. MU_GetUserInfo(NULL, &nuInfo);
  861. strcpy(szRes, nuInfo.szUsername);
  862. if (szRes[0])
  863. {
  864. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_FINDSTRING, 0, (LPARAM)szRes);
  865. if (LB_ERR != dFoundItem)
  866. {
  867. SendDlgItemMessage(hDlg, idcUserNameList, LB_SETCURSEL, dFoundItem, 0);
  868. }
  869. }
  870. SendDlgItemMessage(hDlg, idcDefaultCombo, CB_SETCURSEL, MU_GetDefaultOptionIndex(GetDlgItem(hDlg, idcDefaultCombo)), 0);
  871. _ManagerUpdateButtons(hDlg);
  872. if (!!(sdwFlags & UIMI_CREATE_NEW_IDENTITY))
  873. {
  874. ShowWindow(hDlg, SW_SHOW);
  875. PostMessage(hDlg, WM_COMMAND, idcAdd, 0);
  876. }
  877. return TRUE;
  878. case WM_HELP:
  879. case WM_CONTEXTMENU:
  880. return OnContextHelp(hDlg, iMsg, wParam, lParam, g_rgCtxMapMultiUserGeneral);
  881. case WM_COMMAND:
  882. switch(HIWORD(wParam))
  883. {
  884. case LBN_DBLCLK:
  885. wParam = idcProperties;
  886. break;
  887. case LBN_SELCHANGE:
  888. _ManagerUpdateButtons(hDlg);
  889. break;
  890. }
  891. switch(LOWORD(wParam))
  892. {
  893. case IDCANCEL:
  894. case idcClose:
  895. case IDOK:
  896. dFoundItem = SendDlgItemMessage(hDlg, idcStartupCombo, CB_GETCURSEL, 0, 0);
  897. if (CB_ERR == dFoundItem)
  898. dFoundItem = 0;
  899. if (IsDlgButtonChecked(hDlg, idcCheckDefault))
  900. MU_SetLoginOption(GetDlgItem(hDlg,idcStartupCombo), dFoundItem);
  901. else
  902. MU_SetLoginOption(GetDlgItem(hDlg,idcStartupCombo), ASK_BEFORE_LOGIN);
  903. dFoundItem = SendDlgItemMessage(hDlg, idcDefaultCombo, CB_GETCURSEL, 0, 0);
  904. if (CB_ERR == dFoundItem)
  905. dFoundItem = 0;
  906. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dFoundItem, (LPARAM)rUserInfo.szUsername);
  907. hr = MU_UsernameToUserId(rUserInfo.szUsername, &rUserInfo.uidUserID);
  908. Assert(SUCCEEDED(hr));
  909. MU_MakeDefaultUser(&rUserInfo.uidUserID);
  910. MLEndDialogWrap(hDlg, IDOK);
  911. return true;
  912. case idcAdd:
  913. ZeroMemory(&rUserInfo, sizeof(USERINFO));
  914. if (MU_UserProperties(hDlg,&rUserInfo))
  915. {
  916. TCHAR szMsg[ARRAYSIZE(szRes) + CCH_IDENTITY_NAME_MAX_LENGTH];
  917. // rebuild the username list and select the newly added one
  918. _RememberLoginOption(GetDlgItem(hDlg,idcStartupCombo));
  919. strcpy(sResultUsername, rUserInfo.szUsername);
  920. _FillListBoxWithUsernames(GetDlgItem(hDlg,idcUserNameList));
  921. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcStartupCombo), GetDlgItem(hDlg,idcUserNameList));
  922. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcDefaultCombo), GetDlgItem(hDlg,idcUserNameList));
  923. dwIndex = MU_GetLoginOptionIndex(GetDlgItem(hDlg,idcStartupCombo));
  924. SendDlgItemMessage(hDlg, idcStartupCombo, CB_SETCURSEL,(dwIndex == ASK_BEFORE_LOGIN ? 0 : dwIndex) , 0);
  925. SendDlgItemMessage(hDlg, idcDefaultCombo, CB_SETCURSEL, MU_GetDefaultOptionIndex(GetDlgItem(hDlg, idcDefaultCombo)), 0);
  926. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_FINDSTRING, 0, (LPARAM)sResultUsername);
  927. if (LB_ERR != dFoundItem)
  928. {
  929. SendDlgItemMessage(hDlg, idcUserNameList, LB_SETCURSEL, dFoundItem, 0);
  930. }
  931. PostMessage(HWND_BROADCAST, WM_IDENTITY_INFO_CHANGED, 0, IIC_IDENTITY_ADDED);
  932. if (pmpParams->pszUsername)
  933. {
  934. MLLoadStringA(idsLoginAsUser, szRes, ARRAYSIZE(szRes));
  935. wsprintf(szMsg, szRes, rUserInfo.szUsername);
  936. MLLoadStringA(idsUserAdded, szRes, ARRAYSIZE(szRes));
  937. if (IDYES == MessageBox(hDlg, szMsg, szRes, MB_YESNO))
  938. {
  939. lstrcpy(pmpParams->pszUsername, rUserInfo.szUsername);
  940. PostMessage(hDlg, WM_COMMAND, idcClose, 0);
  941. }
  942. }
  943. }
  944. _ManagerUpdateButtons(hDlg);
  945. return true;
  946. case idcDefaultCombo:
  947. dFoundItem = SendDlgItemMessage(hDlg, idcDefaultCombo, CB_GETCURSEL, 0, 0);
  948. if (CB_ERR == dFoundItem)
  949. dFoundItem = 0;
  950. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dFoundItem, (LPARAM)rUserInfo.szUsername);
  951. hr = MU_UsernameToUserId(rUserInfo.szUsername, &rUserInfo.uidUserID);
  952. Assert(SUCCEEDED(hr));
  953. MU_MakeDefaultUser(&rUserInfo.uidUserID);
  954. _ManagerUpdateButtons(hDlg);
  955. break;
  956. case idcCheckDefault:
  957. EnableWindow(GetDlgItem(hDlg, idcStartupCombo), IsDlgButtonChecked(hDlg, idcCheckDefault));
  958. return true;
  959. case idcDelete:
  960. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_GETCURSEL, 0, 0);
  961. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dFoundItem, (LPARAM)rUserInfo.szUsername);
  962. hr = MU_UsernameToUserId(rUserInfo.szUsername, &rUserInfo.uidUserID);
  963. Assert(SUCCEEDED(hr));
  964. if (MU_ConfirmDeleteUser(hDlg, rUserInfo.szUsername))
  965. {
  966. MU_DeleteUser(&rUserInfo.uidUserID);
  967. _RememberLoginOption(GetDlgItem(hDlg,idcStartupCombo));
  968. _FillListBoxWithUsernames(GetDlgItem(hDlg,idcUserNameList));
  969. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcStartupCombo), GetDlgItem(hDlg,idcUserNameList));
  970. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcDefaultCombo), GetDlgItem(hDlg,idcUserNameList));
  971. dwIndex = MU_GetLoginOptionIndex(GetDlgItem(hDlg,idcStartupCombo));
  972. SendDlgItemMessage(hDlg, idcStartupCombo, CB_SETCURSEL,(dwIndex == ASK_BEFORE_LOGIN ? 0 : dwIndex) , 0);
  973. SendDlgItemMessage(hDlg, idcDefaultCombo, CB_SETCURSEL, MU_GetDefaultOptionIndex(GetDlgItem(hDlg, idcDefaultCombo)), 0);
  974. _ManagerUpdateButtons(hDlg);
  975. }
  976. return true;
  977. case idcProperties:
  978. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_GETCURSEL, 0, 0);
  979. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dFoundItem, (LPARAM)rUserInfo.szUsername);
  980. hr = MU_UsernameToUserId(rUserInfo.szUsername, &rUserInfo.uidUserID);
  981. Assert(SUCCEEDED(hr));
  982. #ifdef IDENTITY_PASSWORDS
  983. if (SUCCEEDED(hr) && MU_GetUserInfo(&rUserInfo.uidUserID, &rUserInfo) && MU_CanEditIdentity(hDlg, &rUserInfo.uidUserID))
  984. #else
  985. if (SUCCEEDED(hr) && MU_GetUserInfo(&rUserInfo.uidUserID, &rUserInfo))
  986. #endif //IDENTITY_PASSWORDS
  987. {
  988. if (MU_UserProperties(hDlg,&rUserInfo))
  989. {
  990. // rebuild the username list and select the newly added one
  991. _RememberLoginOption(GetDlgItem(hDlg,idcStartupCombo));
  992. strcpy(sResultUsername, rUserInfo.szUsername);
  993. _FillListBoxWithUsernames(GetDlgItem(hDlg,idcUserNameList));
  994. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcStartupCombo), GetDlgItem(hDlg,idcUserNameList));
  995. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcDefaultCombo), GetDlgItem(hDlg,idcUserNameList));
  996. dwIndex = MU_GetLoginOptionIndex(GetDlgItem(hDlg,idcStartupCombo));
  997. SendDlgItemMessage(hDlg, idcStartupCombo, CB_SETCURSEL,(dwIndex == ASK_BEFORE_LOGIN ? 0 : dwIndex) , 0);
  998. SendDlgItemMessage(hDlg, idcDefaultCombo, CB_SETCURSEL, MU_GetDefaultOptionIndex(GetDlgItem(hDlg, idcDefaultCombo)), 0);
  999. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_FINDSTRING, 0, (LPARAM)sResultUsername);
  1000. if (LB_ERR != dFoundItem)
  1001. {
  1002. SendDlgItemMessage(hDlg, idcUserNameList, LB_SETCURSEL, dFoundItem, 0);
  1003. }
  1004. }
  1005. }
  1006. _ManagerUpdateButtons(hDlg);
  1007. break;
  1008. /*
  1009. case idcDefault:
  1010. dFoundItem = SendDlgItemMessage(hDlg, idcUserNameList, LB_GETCURSEL, 0, 0);
  1011. SendDlgItemMessage(hDlg, idcUserNameList, LB_GETTEXT, dFoundItem, (LPARAM)rUserInfo.szUsername);
  1012. // _StripDefault(rUserInfo.szUsername);
  1013. hr = MU_UsernameToUserId(rUserInfo.szUsername, &rUserInfo.uidUserID);
  1014. Assert(SUCCEEDED(hr));
  1015. MU_MakeDefaultUser(&rUserInfo.uidUserID);
  1016. _RememberLoginOption(GetDlgItem(hDlg,idcStartupCombo));
  1017. _FillListBoxWithUsernames(GetDlgItem(hDlg,idcUserNameList));
  1018. _FillComboBoxWithUsernames(GetDlgItem(hDlg,idcStartupCombo), GetDlgItem(hDlg,idcUserNameList));
  1019. SendDlgItemMessage(hDlg, idcStartupCombo, CB_SETCURSEL, MU_GetLoginOptionIndex(GetDlgItem(hDlg,idcStartupCombo)), 0);
  1020. SendDlgItemMessage(hDlg, idcUserNameList, LB_SETCURSEL, dFoundItem, 0);
  1021. _ManagerUpdateButtons(hDlg);
  1022. break;
  1023. */
  1024. }
  1025. break;
  1026. }
  1027. return false;
  1028. }
  1029. /*
  1030. MU_ManageUsers
  1031. */
  1032. BOOL MU_ManageUsers(HWND hwnd, TCHAR *lpszSwitchtoUsername, DWORD dwFlags)
  1033. {
  1034. INT_PTR bResult;
  1035. MANAGE_PARAMS rParams;
  1036. INITCOMMONCONTROLSEX icex;
  1037. Assert(hwnd);
  1038. Assert(lpszUsername);
  1039. // make sure ICC_NATIVEFNTCTL_CLASS is inited
  1040. icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  1041. icex.dwICC = ICC_NATIVEFNTCTL_CLASS;
  1042. InitCommonControlsEx(&icex);
  1043. rParams.dwFlags = dwFlags;
  1044. rParams.pszUsername = lpszSwitchtoUsername;
  1045. bResult = MLDialogBoxParamWrap(MLGetHinst(), MAKEINTRESOURCEW(iddManager), hwnd, _ManagerDlgProc, (LPARAM)&rParams);
  1046. return (IDOK == bResult);
  1047. }