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.

1799 lines
50 KiB

  1. /*
  2. File usertab.c
  3. Implementation of the users dialog tab for the dialup server ui.
  4. Paul Mayfield, 9/29/97
  5. */
  6. #include "rassrv.h"
  7. #include "usertab.h"
  8. #include <htmlhelp.h>
  9. #define USERTAB_PASSWORD_BUFFER_SIZE (PWLEN+1)
  10. static const WCHAR pszDummyPassword[] = L"XXXXXXXXXXXXXXX";
  11. // Help maps
  12. static const DWORD phmUserTab[] =
  13. {
  14. CID_UserTab_LV_Users, IDH_UserTab_LV_Users,
  15. CID_UserTab_PB_New, IDH_UserTab_PB_New,
  16. CID_UserTab_PB_Delete, IDH_UserTab_PB_Delete,
  17. CID_UserTab_PB_Properties, IDH_UserTab_PB_Properties,
  18. CID_UserTab_PB_SwitchToMMC, IDH_UserTab_PB_SwitchToMMC,
  19. CID_UserTab_CB_BypassDcc, IDH_UserTab_CB_BypassDcc,
  20. 0, 0
  21. };
  22. static const DWORD phmCallback[] =
  23. {
  24. CID_UserTab_Callback_RB_Caller, IDH_UserTab_Callback_RB_Caller,
  25. CID_UserTab_Callback_RB_Admin, IDH_UserTab_Callback_RB_Admin,
  26. CID_UserTab_Callback_EB_Number, IDH_UserTab_Callback_EB_Number,
  27. CID_UserTab_Callback_RB_No, IDH_UserTab_Callback_RB_No,
  28. 0, 0
  29. };
  30. static const DWORD phmNewUser[] =
  31. {
  32. CID_UserTab_New_EB_Username, IDH_UserTab_New_EB_Username,
  33. CID_UserTab_New_EB_Fullname, IDH_UserTab_New_EB_Fullname,
  34. CID_UserTab_New_EB_Password1, IDH_UserTab_New_EB_Password1,
  35. CID_UserTab_New_EB_Password2, IDH_UserTab_New_EB_Password2,
  36. 0, 0
  37. };
  38. // Parameters to track net users
  39. //
  40. typedef struct _RASSRV_USER_PARAMS
  41. {
  42. BOOL bCanceled; // Set by property sheets when cancel pressed
  43. BOOL bNewUser; // for .Net 691639, the password change warning dialog won't pop up when creating new users. gangz
  44. // General properties
  45. //For whistler bug 210032 to allow username be 20 characters long
  46. WCHAR pszLogonName[IC_USERNAME];
  47. WCHAR pszFullName [IC_USERFULLNAME+1]; // For whistler bug 39081 gangz
  48. WCHAR pszPassword1[USERTAB_PASSWORD_BUFFER_SIZE];
  49. WCHAR pszPassword2[USERTAB_PASSWORD_BUFFER_SIZE];
  50. DWORD dwErrorCode;
  51. // Callback properties
  52. HANDLE hUser;
  53. BOOL bNone;
  54. BOOL bCaller;
  55. BOOL bAdmin;
  56. WCHAR pszNumber[MAX_PHONE_NUMBER_LEN];
  57. } RASSRV_USER_PARAMS;
  58. // Fills in the property sheet structure with the information
  59. // required to display the user database tab.
  60. //
  61. DWORD
  62. UserTabGetPropertyPage(
  63. IN LPPROPSHEETPAGE ppage,
  64. IN LPARAM lpUserData)
  65. {
  66. // Initialize
  67. ZeroMemory(ppage, sizeof(PROPSHEETPAGE));
  68. // Fill in the values
  69. ppage->dwSize = sizeof(PROPSHEETPAGE);
  70. ppage->hInstance = Globals.hInstDll;
  71. ppage->pszTemplate = MAKEINTRESOURCE(PID_UserTab);
  72. ppage->pfnDlgProc = UserTabDialogProc;
  73. ppage->pfnCallback = RasSrvInitDestroyPropSheetCb;
  74. ppage->dwFlags = PSP_USECALLBACK;
  75. ppage->lParam = lpUserData;
  76. return NO_ERROR;
  77. }
  78. //
  79. // Error reporting
  80. //
  81. VOID
  82. UserTabDisplayError(
  83. IN HWND hwnd,
  84. IN DWORD err)
  85. {
  86. ErrDisplayError(
  87. hwnd,
  88. err,
  89. ERR_USERTAB_CATAGORY,
  90. ERR_USERDB_SUBCAT,
  91. Globals.dwErrorData);
  92. }
  93. // Fills in the user list view with the names of the users stored in the
  94. // user database provide. Also, initializes the checked/unchecked status
  95. // of each user.
  96. DWORD
  97. UserTabFillUserList(
  98. IN HWND hwndLV,
  99. IN HANDLE hUserDatabase)
  100. {
  101. LV_ITEM lvi;
  102. DWORD dwCount, i, dwErr, dwSize;
  103. HANDLE hUser;
  104. WCHAR pszName[IC_USERFULLNAME+IC_USERNAME+3];
  105. // char pszAName[512];
  106. HIMAGELIST checks;
  107. BOOL bDialinEnabled;
  108. // Get the count of all the users
  109. if ((dwErr = usrGetUserCount(hUserDatabase, &dwCount)) != NO_ERROR)
  110. {
  111. UserTabDisplayError(hwndLV, ERR_USER_DATABASE_CORRUPT);
  112. return dwErr;
  113. }
  114. ListView_SetUserImageList(hwndLV, Globals.hInstDll);
  115. // Initialize the list item
  116. ZeroMemory(&lvi, sizeof(LV_ITEM));
  117. lvi.mask = LVIF_TEXT | LVIF_IMAGE;
  118. // Looop through all of the users adding their names as we go
  119. for (i=0; i<dwCount; i++)
  120. {
  121. dwSize = sizeof(pszName)/sizeof(pszName[0]); // For whistler bug 39081 gangz
  122. if ((dwErr = usrGetUserHandle(hUserDatabase, i, &hUser)) == NO_ERROR)
  123. {
  124. usrGetDisplayName (hUser, pszName, &dwSize);
  125. usrGetDialin(hUser, &bDialinEnabled);
  126. lvi.iImage = UI_Connections_User;
  127. lvi.iItem = i;
  128. lvi.pszText = pszName;
  129. lvi.cchTextMax = wcslen(pszName)+1;
  130. ListView_InsertItem(hwndLV,&lvi);
  131. ListView_SetCheck(hwndLV, i, bDialinEnabled);
  132. }
  133. }
  134. // Select the first item in the list view
  135. ListView_SetItemState(
  136. hwndLV,
  137. 0,
  138. LVIS_SELECTED | LVIS_FOCUSED,
  139. LVIS_SELECTED | LVIS_FOCUSED);
  140. return NO_ERROR;
  141. }
  142. //
  143. // Initialize the user tab, returns false if focus was set,
  144. // true otherwise.
  145. //
  146. DWORD
  147. UserTabInitializeDialog(
  148. HWND hwndDlg,
  149. WPARAM wParam,
  150. LPARAM lParam)
  151. {
  152. HANDLE hUserDatabase = NULL;
  153. HWND hwndLV, hwndEnc, hwndBypass;
  154. LV_COLUMN lvc;
  155. RECT r;
  156. DWORD dwErr;
  157. BOOL bPure = FALSE, bBypass = FALSE;
  158. // Obtain handle to user database
  159. RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase);
  160. // Figure out if MMC has been used.
  161. dwErr = usrIsDatabasePure (hUserDatabase, &bPure);
  162. if ((dwErr == NO_ERROR) && (bPure == FALSE))
  163. {
  164. PWCHAR pszWarning, pszTitle;
  165. pszWarning = (PWCHAR) PszLoadString(
  166. Globals.hInstDll,
  167. WRN_USERS_CONFIGURED_MMC);
  168. pszTitle = (PWCHAR) PszLoadString(
  169. Globals.hInstDll,
  170. ERR_USERTAB_CATAGORY);
  171. MessageBox(hwndDlg, pszWarning, pszTitle, MB_OK | MB_ICONWARNING);
  172. usrSetDatabasePure(hUserDatabase, TRUE);
  173. }
  174. // Fill in the user list if it's not already filled
  175. hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users);
  176. if (ListView_GetItemCount (hwndLV) == 0)
  177. {
  178. ListView_InstallChecks(hwndLV, Globals.hInstDll);
  179. UserTabFillUserList(hwndLV, hUserDatabase);
  180. // Add a colum so that we'll display in report view
  181. GetClientRect(hwndLV, &r);
  182. lvc.mask = LVCF_FMT;
  183. lvc.fmt = LVCFMT_LEFT;
  184. ListView_InsertColumn(hwndLV,0,&lvc);
  185. ListView_SetColumnWidth(hwndLV, 0, LVSCW_AUTOSIZE_USEHEADER);
  186. // Initialize the encryption check box
  187. // For .Net 554416, removed the Require Encryption check box
  188. // For security, the default is require secured password and encrytpion
  189. // now
  190. // Initialize the "bypass dcc" checkbox
  191. hwndBypass = GetDlgItem(hwndDlg, CID_UserTab_CB_BypassDcc);
  192. if (hwndBypass != NULL)
  193. {
  194. usrGetDccBypass(hUserDatabase, &bBypass);
  195. SendMessage(
  196. hwndBypass,
  197. BM_SETCHECK,
  198. (bBypass) ? BST_CHECKED : BST_UNCHECKED,
  199. 0);
  200. }
  201. }
  202. return TRUE;
  203. }
  204. //
  205. // Cleanup anything done in the initialization function
  206. //
  207. DWORD
  208. UserTabCleanupDialog(
  209. IN HWND hwndDlg,
  210. IN WPARAM wParam,
  211. IN LPARAM lParam)
  212. {
  213. // Restore the user data
  214. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
  215. return NO_ERROR;
  216. }
  217. //
  218. // Grants/revokes the dialin privelege of a user and reflects this
  219. // in the UI
  220. //
  221. DWORD
  222. UserTabHandleUserCheck(
  223. IN HWND hwndDlg,
  224. IN DWORD dwIndex)
  225. {
  226. DWORD dwErr;
  227. HANDLE hUser = NULL, hUserDatabase = NULL;
  228. HWND hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users);
  229. // Get the user handle from the user database
  230. RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase);
  231. dwErr = usrGetUserHandle(hUserDatabase, dwIndex, &hUser);
  232. if (dwErr != NO_ERROR)
  233. {
  234. UserTabDisplayError(hwndDlg, ERR_USER_DATABASE_CORRUPT);
  235. return dwErr;
  236. }
  237. if (hwndLV)
  238. {
  239. // Set the dialin permission of the given user
  240. usrEnableDialin(hUser, ListView_GetCheck(hwndLV, dwIndex));
  241. }
  242. return NO_ERROR;
  243. }
  244. // .Net 660285
  245. // Add password change warning dialogbox
  246. // Because the resource files are all locked down, I have to borrow
  247. // the resource localsec.dll for .Net and XPSP
  248. //
  249. // In longhorn, I will create our own resource file
  250. //
  251. BOOL
  252. PwInit(
  253. IN HWND hwndDlg )
  254. {
  255. PWCHAR pszTitle = NULL;
  256. pszTitle = (PWCHAR) PszLoadString (
  257. Globals.hInstDll,
  258. WRN_TITLE);
  259. SetWindowTextW (hwndDlg, pszTitle);
  260. return FALSE;
  261. }
  262. BOOL
  263. PwCommand(
  264. IN HWND hwnd,
  265. IN WORD wNotification,
  266. IN WORD wId,
  267. IN HWND hwndCtrl )
  268. {
  269. DWORD dwErr;
  270. switch (wId)
  271. {
  272. case IDC_HELP_BUTTON:
  273. {
  274. HtmlHelp(
  275. hwnd,
  276. TEXT("password.chm::/datalos.htm"),
  277. HH_DISPLAY_TOPIC,
  278. 0);
  279. break;
  280. }
  281. case IDOK:
  282. case IDCANCEL:
  283. {
  284. EndDialog( hwnd, (wId == IDOK) );
  285. return TRUE;
  286. }
  287. }
  288. return FALSE;
  289. }
  290. INT_PTR CALLBACK
  291. PwDlgProc(
  292. IN HWND hwnd,
  293. IN UINT unMsg,
  294. IN WPARAM wparam,
  295. IN LPARAM lparam )
  296. {
  297. switch (unMsg)
  298. {
  299. case WM_INITDIALOG:
  300. {
  301. return PwInit( hwnd );
  302. }
  303. case WM_COMMAND:
  304. {
  305. return PwCommand(
  306. hwnd, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  307. }
  308. }
  309. return FALSE;
  310. }
  311. DWORD WarnPasswordChange(
  312. IN BOOL * pfChange )
  313. {
  314. HMODULE hModule = NULL;
  315. DWORD dwErr = NO_ERROR;
  316. INT_PTR nStatus;
  317. do
  318. {
  319. if( NULL == pfChange )
  320. {
  321. dwErr = ERROR_INVALID_PARAMETER;
  322. break;
  323. }
  324. *pfChange = FALSE;
  325. hModule = LoadLibrary(TEXT("LocalSec.dll"));
  326. if ( NULL == hModule )
  327. {
  328. dwErr = GetLastError();
  329. break;
  330. }
  331. // Look up the IDD_SET_PASSWORD_WARNING_OTHER_FRIENDLY resource
  332. // whose id values is 5174 in the localsec.dll
  333. //
  334. nStatus =
  335. (BOOL )DialogBox(
  336. hModule,
  337. MAKEINTRESOURCE(IDD_SET_PASSWORD_WARNING_OTHER_FRIENDLY),
  338. NULL,
  339. PwDlgProc);
  340. if (nStatus == -1)
  341. {
  342. dwErr = GetLastError();
  343. break;
  344. }
  345. *pfChange = (BOOL )nStatus;
  346. }
  347. while(FALSE);
  348. if( NULL != hModule )
  349. {
  350. FreeLibrary( hModule );
  351. }
  352. return dwErr;
  353. }
  354. //
  355. // Loads the New User parameters and returns whether they
  356. // have been correctly entered or not.
  357. //
  358. //Assume passwords in the input params are already encoded
  359. BOOL
  360. UserTabNewUserParamsOk(
  361. IN HWND hwndDlg,
  362. IN RASSRV_USER_PARAMS * pNuParams)
  363. {
  364. USER_MODALS_INFO_0 * pModInfo;
  365. NET_API_STATUS nStatus;
  366. DWORD dwMinPasswordLength=0, dwLength;
  367. BOOL bOk = FALSE;
  368. HWND hwndControl = NULL;
  369. // Find the minium password length
  370. nStatus = NetUserModalsGet(NULL, 0, (LPBYTE*)&pModInfo);
  371. if (nStatus == NERR_Success)
  372. {
  373. dwMinPasswordLength = pModInfo->usrmod0_min_passwd_len;
  374. NetApiBufferFree((LPBYTE)pModInfo);
  375. }
  376. // Load the parameters
  377. hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Username);
  378. if (hwndControl)
  379. {
  380. GetWindowTextW(
  381. hwndControl,
  382. pNuParams->pszLogonName,
  383. (sizeof(pNuParams->pszLogonName)/sizeof(WCHAR)) - 1);
  384. }
  385. hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Fullname);
  386. if (hwndControl)
  387. {
  388. GetWindowTextW(
  389. hwndControl,
  390. pNuParams->pszFullName,
  391. (sizeof(pNuParams->pszFullName)/sizeof(WCHAR)) - 1);
  392. }
  393. hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Password1);
  394. //gangz
  395. //For secure password bug .Net 754400
  396. SafeWipePasswordBuf(pNuParams->pszPassword1 );
  397. SafeWipePasswordBuf(pNuParams->pszPassword2 );
  398. if (hwndControl)
  399. {
  400. GetWindowTextW(
  401. hwndControl,
  402. pNuParams->pszPassword1,
  403. (sizeof(pNuParams->pszPassword1)/sizeof(WCHAR)) - 1);
  404. }
  405. hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Password2);
  406. if (hwndControl)
  407. {
  408. GetWindowTextW(
  409. hwndControl,
  410. pNuParams->pszPassword2,
  411. (sizeof(pNuParams->pszPassword2)/sizeof(WCHAR)) - 1);
  412. }
  413. do
  414. {
  415. bOk = TRUE;
  416. // Verify that we have a login name
  417. dwLength = wcslen(pNuParams->pszLogonName);
  418. if (dwLength < 1)
  419. {
  420. pNuParams->dwErrorCode = ERR_LOGON_NAME_TOO_SMALL;
  421. bOk = FALSE;
  422. break;
  423. }
  424. // Verify the minimum password length
  425. dwLength = wcslen(pNuParams->pszPassword1);
  426. if (dwLength < dwMinPasswordLength)
  427. {
  428. pNuParams->dwErrorCode = ERR_PASSWORD_TOO_SMALL;
  429. bOk = FALSE;
  430. break;
  431. }
  432. // Verify the passwords was entered correctly
  433. if (wcscmp(pNuParams->pszPassword1, pNuParams->pszPassword2))
  434. {
  435. pNuParams->dwErrorCode = ERR_PASSWORD_MISMATCH;
  436. bOk = FALSE;
  437. break;
  438. }
  439. // For .Net 660285
  440. // Give warning if the password has been changed
  441. // for .Net 691639, the password change warning dialog won't pop up when creating new users. gangz
  442. //
  443. if ( !pNuParams->bNewUser &&
  444. wcscmp(pszDummyPassword, pNuParams->pszPassword1) )
  445. {
  446. BOOL fChange = FALSE;
  447. DWORD dwErr = NO_ERROR;
  448. dwErr = WarnPasswordChange( &fChange );
  449. if( NO_ERROR != dwErr )
  450. {
  451. break;
  452. }
  453. bOk = fChange;
  454. if( !bOk )
  455. {
  456. pNuParams->dwErrorCode = ERROR_CAN_NOT_COMPLETE;
  457. }
  458. }
  459. } while (FALSE);
  460. // Cleanup
  461. {
  462. if (!bOk)
  463. {
  464. //reset password buffer so that other know password is not set yet.
  465. //
  466. SafeWipePasswordBuf(
  467. pNuParams->pszPassword1);
  468. SafeWipePasswordBuf(
  469. pNuParams->pszPassword2);
  470. }
  471. }
  472. // Keep the password field in encrypted status to be logic safe
  473. // Even it is wiped out
  474. SafeEncodePasswordBuf( pNuParams->pszPassword1 );
  475. SafeEncodePasswordBuf( pNuParams->pszPassword2 );
  476. return bOk;
  477. }
  478. //
  479. // Initialize the callback properties of the given user
  480. //
  481. //Passwords are encrypted when passing in
  482. DWORD
  483. UserTabLoadUserProps (
  484. IN RASSRV_USER_PARAMS * pParams)
  485. {
  486. PWCHAR pszName;
  487. DWORD dwErr, dwSize;
  488. PWCHAR pszNumber;
  489. if (!pParams)
  490. {
  491. return ERROR_INVALID_PARAMETER;
  492. }
  493. // If this is a new user, default to user specified callback
  494. // (convienience mode)
  495. if (!pParams->hUser)
  496. {
  497. SafeWipePasswordBuf( pParams->pszPassword1);
  498. SafeWipePasswordBuf( pParams->pszPassword2);
  499. ZeroMemory(pParams, sizeof(*pParams));
  500. SafeEncodePasswordBuf( pParams->pszPassword1);
  501. SafeEncodePasswordBuf( pParams->pszPassword2);
  502. pParams->bNone = TRUE;
  503. pParams->bCaller = FALSE;
  504. pParams->bAdmin = FALSE;
  505. }
  506. // Otherwise, load the user parameters from the user database
  507. else
  508. {
  509. pParams->bCanceled = FALSE;
  510. dwSize = sizeof(pParams->pszFullName)/sizeof(pParams->pszFullName[0]);
  511. usrGetFullName (pParams->hUser, pParams->pszFullName, &dwSize);
  512. usrGetName(pParams->hUser, &pszName);
  513. lstrcpynW(
  514. pParams->pszLogonName,
  515. pszName,
  516. sizeof(pParams->pszLogonName) / sizeof(WCHAR));
  517. SafeWipePasswordBuf( pParams->pszPassword1);
  518. SafeWipePasswordBuf( pParams->pszPassword2);
  519. lstrcpynW(
  520. pParams->pszPassword1,
  521. pszDummyPassword,
  522. sizeof(pParams->pszPassword1) / sizeof(WCHAR));
  523. lstrcpynW(
  524. pParams->pszPassword2,
  525. pszDummyPassword,
  526. sizeof(pParams->pszPassword2) / sizeof(WCHAR));
  527. SafeEncodePasswordBuf( pParams->pszPassword1);
  528. SafeEncodePasswordBuf( pParams->pszPassword2);
  529. dwErr = usrGetCallback(
  530. pParams->hUser,
  531. &pParams->bAdmin,
  532. &pParams->bCaller);
  533. if (dwErr != NO_ERROR)
  534. {
  535. return dwErr;
  536. }
  537. dwErr = usrGetCallbackNumber(pParams->hUser, &pszNumber);
  538. if (dwErr != NO_ERROR)
  539. {
  540. return dwErr;
  541. }
  542. lstrcpynW(
  543. pParams->pszNumber,
  544. pszNumber,
  545. sizeof(pParams->pszNumber) / sizeof(WCHAR));
  546. }
  547. return NO_ERROR;
  548. }
  549. //
  550. // Commit the call back properties of the given user.
  551. //
  552. DWORD
  553. UserTabSaveCallbackProps (
  554. IN RASSRV_USER_PARAMS * pParams)
  555. {
  556. if (!pParams)
  557. {
  558. return ERROR_INVALID_PARAMETER;
  559. }
  560. // If we have a valid handle to the user, set his/her
  561. // properties
  562. if (pParams->hUser)
  563. {
  564. pParams->bNone =
  565. (pParams->bCaller == FALSE && pParams->bAdmin == FALSE);
  566. // Set the enabling and number
  567. usrEnableCallback(
  568. pParams->hUser,
  569. pParams->bNone,
  570. pParams->bCaller,
  571. pParams->bAdmin);
  572. if (pParams->bAdmin)
  573. {
  574. usrSetCallbackNumber(pParams->hUser, pParams->pszNumber);
  575. }
  576. }
  577. return NO_ERROR;
  578. }
  579. // Commit the parameters of the given user. If pOrig is non-null, then all
  580. // fields of pParams will be compare against pOrig and only those that have changed
  581. // will be committed. (optimization)
  582. //
  583. //passwords in the input structure are encoded
  584. DWORD
  585. UserTabSaveUserProps (
  586. IN RASSRV_USER_PARAMS * pParams,
  587. IN RASSRV_USER_PARAMS * pOrig,
  588. IN PBOOL pbChanged)
  589. {
  590. if (!pParams || !pOrig || !pbChanged)
  591. {
  592. return ERROR_INVALID_PARAMETER;
  593. }
  594. *pbChanged = FALSE;
  595. // Commit the full name if changed
  596. if (wcscmp(pParams->pszFullName, pOrig->pszFullName))
  597. {
  598. usrSetFullName(pParams->hUser, pParams->pszFullName);
  599. *pbChanged = TRUE;
  600. }
  601. // Commit the password if changed
  602. SafeDecodePasswordBuf(pParams->pszPassword1);
  603. if (wcscmp(pParams->pszPassword1, pszDummyPassword))
  604. {
  605. usrSetPassword(pParams->hUser, pParams->pszPassword1);
  606. }
  607. SafeEncodePasswordBuf(pParams->pszPassword1);
  608. UserTabSaveCallbackProps(pParams);
  609. return NO_ERROR;
  610. }
  611. DWORD
  612. UserTabCallbackApply(
  613. IN HWND hwndDlg)
  614. {
  615. RASSRV_USER_PARAMS * pParams = NULL;
  616. LONG dwResult = PSNRET_NOERROR;
  617. HWND hwndControl = NULL;
  618. pParams = (RASSRV_USER_PARAMS *)
  619. GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  620. hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_No);
  621. if (hwndControl)
  622. {
  623. pParams->bNone = (BOOL)
  624. SendMessage(
  625. hwndControl,
  626. BM_GETCHECK,
  627. 0,
  628. 0);
  629. }
  630. hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Caller);
  631. if (hwndControl)
  632. {
  633. pParams->bCaller = (BOOL)
  634. SendMessage(
  635. hwndControl,
  636. BM_GETCHECK,
  637. 0,
  638. 0);
  639. }
  640. hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Admin);
  641. if (hwndControl)
  642. {
  643. pParams->bAdmin = (BOOL)
  644. SendMessage(
  645. hwndControl,
  646. BM_GETCHECK,
  647. 0,
  648. 0);
  649. }
  650. if (pParams->bAdmin)
  651. {
  652. hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_EB_Number);
  653. if (hwndControl)
  654. {
  655. GetWindowTextW(
  656. hwndControl,
  657. pParams->pszNumber,
  658. MAX_PHONE_NUMBER_LEN);
  659. }
  660. // If admin callback was set, but no admin callback number was set,
  661. // then popup an error and don't to refuse the apply
  662. //
  663. if (wcslen(pParams->pszNumber) == 0)
  664. {
  665. UserTabDisplayError(hwndDlg, ERR_CALLBACK_NUM_REQUIRED);
  666. PropSheet_SetCurSel ( GetParent(hwndDlg), hwndDlg, 0 );
  667. dwResult = PSNRET_INVALID;
  668. }
  669. }
  670. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, dwResult);
  671. return TRUE;
  672. }
  673. //
  674. // Dialog procedure that implements getting callback properties
  675. //
  676. INT_PTR
  677. CALLBACK
  678. UserTabCallbackDialogProc(
  679. IN HWND hwndDlg,
  680. IN UINT uMsg,
  681. IN WPARAM wParam,
  682. IN LPARAM lParam)
  683. {
  684. switch (uMsg)
  685. {
  686. case WM_INITDIALOG:
  687. {
  688. PWCHAR lpzNumber, lpzName;
  689. HWND hwndControl = NULL;
  690. HWND hwCb = GetDlgItem(hwndDlg, CID_UserTab_Callback_EB_Number);
  691. RASSRV_USER_PARAMS * pu =
  692. (RASSRV_USER_PARAMS *)(((PROPSHEETPAGE*)lParam)->lParam);
  693. // Initialize
  694. if (hwCb)
  695. {
  696. SendMessage(
  697. hwCb,
  698. EM_SETLIMITTEXT,
  699. sizeof(pu->pszNumber)/2 - 1, 0);
  700. }
  701. SetWindowLongPtr(
  702. hwndDlg,
  703. GWLP_USERDATA,
  704. (LONG_PTR)pu);
  705. // Display the callback properties
  706. if (!pu->bAdmin && !pu->bCaller)
  707. {
  708. hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_No);
  709. if (hwndControl)
  710. {
  711. SendMessage(
  712. hwndControl,
  713. BM_SETCHECK,BST_CHECKED,
  714. 0);
  715. SetFocus(
  716. hwndControl);
  717. }
  718. }
  719. else if (pu->bCaller)
  720. {
  721. hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Caller);
  722. if (hwndControl)
  723. {
  724. SendMessage(
  725. hwndControl,
  726. BM_SETCHECK,BST_CHECKED,
  727. 0);
  728. SetFocus(
  729. hwndControl);
  730. }
  731. }
  732. else
  733. {
  734. hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Admin);
  735. if (hwndControl)
  736. {
  737. SendMessage(
  738. hwndControl,
  739. BM_SETCHECK,BST_CHECKED,
  740. 0);
  741. SetFocus(
  742. hwndControl);
  743. }
  744. }
  745. SetWindowTextW(hwCb, pu->pszNumber);
  746. EnableWindow(hwCb, !!pu->bAdmin);
  747. }
  748. return TRUE;
  749. case WM_HELP:
  750. case WM_CONTEXTMENU:
  751. {
  752. RasSrvHelp (hwndDlg, uMsg, wParam, lParam, phmCallback);
  753. break;
  754. }
  755. case WM_DESTROY:
  756. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
  757. break;
  758. case WM_NOTIFY:
  759. {
  760. NMHDR* pNotifyData;
  761. NM_LISTVIEW* pLvNotifyData;
  762. pNotifyData = (NMHDR*)lParam;
  763. switch (pNotifyData->code)
  764. {
  765. // The property sheet apply button was pressed
  766. case PSN_APPLY:
  767. return UserTabCallbackApply(hwndDlg);
  768. break;
  769. // The property sheet cancel was pressed
  770. case PSN_RESET:
  771. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  772. break;
  773. }
  774. }
  775. break;
  776. case WM_COMMAND:
  777. switch (wParam)
  778. {
  779. case CID_UserTab_Callback_RB_No:
  780. case CID_UserTab_Callback_RB_Caller:
  781. case CID_UserTab_Callback_RB_Admin:
  782. {
  783. HWND hwndNumber = NULL;
  784. HWND hwndAdmin = NULL;
  785. hwndNumber =
  786. GetDlgItem(hwndDlg, CID_UserTab_Callback_EB_Number);
  787. hwndAdmin =
  788. GetDlgItem(hwndDlg, CID_UserTab_Callback_RB_Admin);
  789. if (hwndNumber && hwndAdmin)
  790. {
  791. EnableWindow(
  792. hwndNumber,
  793. (BOOL) SendMessage(
  794. hwndAdmin,
  795. BM_GETCHECK,
  796. 0,
  797. 0));
  798. }
  799. }
  800. break;
  801. }
  802. break;
  803. }
  804. return FALSE;
  805. }
  806. //
  807. // Initializes the user properties dialog procedure.
  808. //
  809. // Return TRUE if focus is set, false otherwise.
  810. //
  811. BOOL
  812. UserTabInitUserPropsDlg(
  813. IN HWND hwndDlg,
  814. IN WPARAM wParam,
  815. IN LPARAM lParam)
  816. {
  817. HWND hwLogon, hwFull, hwPass1, hwPass2, hwOk, hwCancel;
  818. RASSRV_USER_PARAMS * pu =
  819. (RASSRV_USER_PARAMS *)(((PROPSHEETPAGE*)lParam)->lParam);
  820. hwLogon = GetDlgItem(
  821. hwndDlg,
  822. CID_UserTab_New_EB_Username);
  823. hwFull = GetDlgItem(
  824. hwndDlg,
  825. CID_UserTab_New_EB_Fullname);
  826. hwPass1 = GetDlgItem(
  827. hwndDlg,
  828. CID_UserTab_New_EB_Password1);
  829. hwPass2 = GetDlgItem(
  830. hwndDlg,
  831. CID_UserTab_New_EB_Password2);
  832. hwOk = GetDlgItem(
  833. hwndDlg,
  834. IDOK);
  835. hwCancel = GetDlgItem(
  836. hwndDlg,
  837. IDCANCEL);
  838. // Store the parameters with the window handle
  839. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)pu);
  840. // Set limits to the text that can be entered
  841. if (hwLogon)
  842. {
  843. SendMessage(
  844. hwLogon,
  845. EM_SETLIMITTEXT,
  846. sizeof(pu->pszLogonName)/2 - 2,
  847. 0);
  848. SetWindowTextW(hwLogon, pu->pszLogonName);
  849. }
  850. if (hwFull)
  851. {
  852. SendMessage(
  853. hwFull,
  854. EM_SETLIMITTEXT,
  855. sizeof(pu->pszFullName)/2 - 2,
  856. 0);
  857. SetWindowTextW(hwFull, pu->pszFullName);
  858. }
  859. if (hwPass1)
  860. {
  861. SendMessage(
  862. hwPass1,
  863. EM_SETLIMITTEXT,
  864. sizeof(pu->pszPassword1)/2 - 2 ,
  865. 0);
  866. SafeDecodePasswordBuf(pu->pszPassword1);
  867. SetWindowTextW(hwPass1, pu->pszPassword1);
  868. SafeEncodePasswordBuf(pu->pszPassword1);
  869. }
  870. if (hwPass2)
  871. {
  872. SendMessage(
  873. hwPass2,
  874. EM_SETLIMITTEXT,
  875. sizeof(pu->pszPassword2)/2 - 2,
  876. 0);
  877. SafeDecodePasswordBuf(pu->pszPassword2);
  878. SetWindowTextW(hwPass2, pu->pszPassword2);
  879. SafeEncodePasswordBuf(pu->pszPassword2);
  880. }
  881. // Don't allow editing of the logon name if user already exists
  882. // Also, don't show the ok and cancel buttons if the user already
  883. // exits (because it's a property sheet with its own buttons)
  884. if (pu->hUser) {
  885. if (hwLogon)
  886. {
  887. EnableWindow(hwLogon, FALSE);
  888. }
  889. if (hwOk)
  890. {
  891. ShowWindow(hwOk, SW_HIDE);
  892. }
  893. if (hwCancel)
  894. {
  895. ShowWindow(hwCancel, SW_HIDE);
  896. }
  897. }
  898. // Otherwise, we are creating a new user. Change the window
  899. // title to other than "General". Also disable the ok button
  900. // since it will be enabled when a user name is typed in.
  901. else {
  902. PWCHAR pszTitle;
  903. pszTitle = (PWCHAR) PszLoadString (
  904. Globals.hInstDll,
  905. SID_NEWUSER);
  906. SetWindowTextW (hwndDlg, pszTitle);
  907. EnableWindow(hwOk, FALSE);
  908. }
  909. return FALSE;
  910. }
  911. // Dialog procedure that implements the new user
  912. INT_PTR
  913. CALLBACK
  914. UserTabGenUserPropsDlgProc(
  915. HWND hwndDlg,
  916. UINT uMsg,
  917. WPARAM wParam,
  918. LPARAM lParam)
  919. {
  920. switch (uMsg) {
  921. case WM_INITDIALOG:
  922. return UserTabInitUserPropsDlg(hwndDlg, wParam, lParam);
  923. break;
  924. case WM_HELP:
  925. case WM_CONTEXTMENU:
  926. {
  927. RasSrvHelp (hwndDlg, uMsg, wParam, lParam, phmNewUser);
  928. break;
  929. }
  930. case WM_DESTROY:
  931. // Cleanup the work done at WM_INITDIALOG
  932. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
  933. break;
  934. case WM_NOTIFY:
  935. {
  936. NMHDR* pNotifyData;
  937. NM_LISTVIEW* pLvNotifyData;
  938. pNotifyData = (NMHDR*)lParam;
  939. switch (pNotifyData->code) {
  940. // The property sheet apply button was pressed
  941. case PSN_APPLY:
  942. {
  943. RASSRV_USER_PARAMS * pParams;
  944. pParams = (RASSRV_USER_PARAMS *)
  945. GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  946. if (UserTabNewUserParamsOk(hwndDlg, pParams))
  947. {
  948. SetWindowLongPtr(
  949. hwndDlg,
  950. DWLP_MSGRESULT,
  951. PSNRET_NOERROR);
  952. }
  953. else
  954. {
  955. if( ERROR_CAN_NOT_COMPLETE != pParams->dwErrorCode )
  956. {
  957. ErrDisplayError(
  958. hwndDlg,
  959. pParams->dwErrorCode,
  960. ERR_USERTAB_CATAGORY,ERR_USERDB_SUBCAT,
  961. 0);
  962. }
  963. SetWindowLongPtr(
  964. hwndDlg,
  965. DWLP_MSGRESULT,
  966. PSNRET_INVALID_NOCHANGEPAGE);
  967. }
  968. }
  969. return TRUE;
  970. // The property sheet cancel was pressed
  971. case PSN_RESET:
  972. {
  973. RASSRV_USER_PARAMS * pParams;
  974. pParams = (RASSRV_USER_PARAMS *)
  975. GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  976. pParams->bCanceled = TRUE;
  977. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  978. break;
  979. }
  980. }
  981. }
  982. break;
  983. case WM_COMMAND:
  984. // Handle ok being pressed
  985. //
  986. if (wParam == IDOK)
  987. {
  988. RASSRV_USER_PARAMS * pParams;
  989. pParams = (RASSRV_USER_PARAMS *)
  990. GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  991. if (UserTabNewUserParamsOk(hwndDlg, pParams))
  992. {
  993. EndDialog(hwndDlg, 1);
  994. }
  995. else
  996. {
  997. if( ERROR_CAN_NOT_COMPLETE != pParams->dwErrorCode )
  998. {
  999. ErrDisplayError(
  1000. hwndDlg,
  1001. pParams->dwErrorCode,
  1002. ERR_USERTAB_CATAGORY,ERR_USERDB_SUBCAT,
  1003. 0);
  1004. }
  1005. }
  1006. }
  1007. // And cancel being pressed
  1008. else if (wParam == IDCANCEL)
  1009. {
  1010. EndDialog(hwndDlg, 0);
  1011. }
  1012. // Notice whether the user name has been updated and
  1013. // if so enable/disable the "Ok" button according to
  1014. // whether a name has been entered.
  1015. if (HIWORD(wParam) == EN_UPDATE)
  1016. {
  1017. WCHAR pszName[256];
  1018. HWND hwndName;
  1019. BOOL bEnable = FALSE;
  1020. if (CID_UserTab_New_EB_Username == LOWORD(wParam))
  1021. {
  1022. // Get the current name
  1023. hwndName = (HWND)lParam;
  1024. pszName[0] = (WCHAR)0;
  1025. GetWindowTextW(
  1026. hwndName,
  1027. pszName,
  1028. sizeof(pszName)/sizeof(WCHAR));
  1029. // If the length is greater than 1, enable the
  1030. // ok button. Otherwise, disable it.
  1031. bEnable = pszName[0] != (WCHAR)0;
  1032. EnableWindow(GetDlgItem(hwndDlg, IDOK), bEnable);
  1033. }
  1034. }
  1035. break;
  1036. }
  1037. return FALSE;
  1038. }
  1039. // Brings up the new user/properties property sheet.
  1040. //
  1041. // If bNewUser is set, this is a new user, otherwise pUserParams
  1042. // contains the pertanent user information.
  1043. //
  1044. // Returns:
  1045. // NO_ERROR on success, pUserParams will be filled in
  1046. // ERROR_CANCELLED if cancel was pressed
  1047. // win32 error otherwise
  1048. //
  1049. // the password in pUserParams are assumed to be encoded
  1050. DWORD
  1051. UserTabRaiseProperties (
  1052. IN HWND hwndParent,
  1053. IN RASSRV_USER_PARAMS * pUserParams)
  1054. {
  1055. PROPSHEETPAGE Pages[2];
  1056. PROPSHEETHEADER Header;
  1057. INT_PTR ret;
  1058. if (!pUserParams)
  1059. return ERROR_INVALID_PARAMETER;
  1060. // Initialize
  1061. // For whistler 524777
  1062. ZeroMemory(Pages, sizeof(Pages));
  1063. ZeroMemory(&Header, sizeof(Header));
  1064. // Fill in the values for the general tab
  1065. Pages[0].dwSize = sizeof(PROPSHEETPAGE);
  1066. Pages[0].hInstance = Globals.hInstDll;
  1067. Pages[0].pszTemplate = MAKEINTRESOURCE(DID_UserTab_New);
  1068. Pages[0].pfnDlgProc = UserTabGenUserPropsDlgProc;
  1069. Pages[0].pfnCallback = NULL;
  1070. Pages[0].dwFlags = 0;
  1071. Pages[0].lParam = (LPARAM)pUserParams;
  1072. // Fill in the values for the callback tab
  1073. Pages[1].dwSize = sizeof(PROPSHEETPAGE);
  1074. Pages[1].hInstance = Globals.hInstDll;
  1075. Pages[1].pszTemplate = MAKEINTRESOURCE(DID_UserTab_Callback);
  1076. Pages[1].pfnDlgProc = UserTabCallbackDialogProc;
  1077. Pages[1].pfnCallback = NULL;
  1078. Pages[1].dwFlags = 0;
  1079. Pages[1].lParam = (LPARAM)pUserParams;
  1080. // Fill in the values for the header
  1081. Header.dwSize = sizeof(Header);
  1082. Header.dwFlags = PSH_DEFAULT |
  1083. PSH_PROPSHEETPAGE |
  1084. PSH_PROPTITLE |
  1085. PSH_NOAPPLYNOW;
  1086. Header.hwndParent = hwndParent;
  1087. Header.hInstance = Globals.hInstDll;
  1088. Header.pszCaption = (pUserParams->hUser) ?
  1089. pUserParams->pszLogonName :
  1090. pUserParams->pszFullName;
  1091. Header.nPages = sizeof(Pages) / sizeof(Pages[0]);
  1092. Header.ppsp = Pages;
  1093. // Popup the dialog box
  1094. if ((ret = PropertySheet(&Header)) == -1)
  1095. {
  1096. return GetLastError();
  1097. }
  1098. if (pUserParams->bCanceled)
  1099. {
  1100. return ERROR_CANCELLED;
  1101. }
  1102. return NO_ERROR;
  1103. }
  1104. //
  1105. // Raises the new user dialog
  1106. //
  1107. DWORD
  1108. UserTabRaiseNewUserDialog(
  1109. IN HWND hwndDlg,
  1110. IN RASSRV_USER_PARAMS * pParams)
  1111. {
  1112. PROPSHEETPAGE Pages;
  1113. INT_PTR iRet = 0;
  1114. if (!pParams)
  1115. {
  1116. return ERROR_INVALID_PARAMETER;
  1117. }
  1118. // Initialize
  1119. ZeroMemory(&Pages, sizeof(Pages));
  1120. Pages.lParam = (LPARAM)pParams;
  1121. // Raise the dialog
  1122. iRet = DialogBoxParam(
  1123. Globals.hInstDll,
  1124. MAKEINTRESOURCE(DID_UserTab_New),
  1125. hwndDlg,
  1126. UserTabGenUserPropsDlgProc,
  1127. (LPARAM)&Pages);
  1128. if (iRet == -1)
  1129. {
  1130. return GetLastError();
  1131. }
  1132. if (iRet == 0)
  1133. {
  1134. return ERROR_CANCELLED;
  1135. }
  1136. return NO_ERROR;
  1137. }
  1138. //
  1139. // Handles a request to add a new user
  1140. //
  1141. DWORD
  1142. UserTabHandleNewUserRequest(
  1143. IN HWND hwndDlg)
  1144. {
  1145. RASSRV_USER_PARAMS Params;
  1146. DWORD dwErr = NO_ERROR, dwLength;
  1147. HANDLE hUserDatabase = NULL;
  1148. HWND hwndLV;
  1149. //Encode the password area before leave the password buffer alone
  1150. //and any future error return after this should goto directly to :done
  1151. SafeEncodePasswordBuf(Params.pszPassword1);
  1152. SafeEncodePasswordBuf(Params.pszPassword2);
  1153. // Initializes the callback properties
  1154. Params.hUser = NULL;
  1155. //Password filds are encrypted when passing in and are encrypted when function return
  1156. UserTabLoadUserProps (&Params);
  1157. // Show the new user property sheet
  1158. Params.bNewUser = TRUE; // For .Net 691639, won't raise password change warning dialog when creating new users
  1159. dwErr = UserTabRaiseNewUserDialog(hwndDlg, &Params);
  1160. if (dwErr != NO_ERROR)
  1161. {
  1162. goto done;
  1163. }
  1164. // Flush any changes to the local user database. These can be
  1165. // rolled back later with usrRollbackLocalDatabase
  1166. RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase);
  1167. SafeDecodePasswordBuf(Params.pszPassword1);
  1168. // Make sure you can add the user
  1169. dwErr = RasSrvAddUser (
  1170. Params.pszLogonName,
  1171. Params.pszFullName,
  1172. Params.pszPassword1);
  1173. SafeEncodePasswordBuf(Params.pszPassword1);
  1174. // Figure out whether the user was added successfully
  1175. if (dwErr != NO_ERROR)
  1176. {
  1177. switch (dwErr) {
  1178. case ERROR_ACCESS_DENIED:
  1179. UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_ACCESS);
  1180. break;
  1181. case ERROR_USER_EXISTS:
  1182. UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_DUPLICATE);
  1183. break;
  1184. case ERROR_INVALID_PASSWORDNAME:
  1185. UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_PASSWORD);
  1186. break;
  1187. default:
  1188. UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_GENERIC);
  1189. }
  1190. goto done;
  1191. }
  1192. // Delete the user (since he/she will be added later when the database
  1193. // is flushed
  1194. RasSrvDeleteUser(Params.pszLogonName);
  1195. // Add the user to the database
  1196. dwErr = usrAddUser(hUserDatabase, Params.pszLogonName, &(Params.hUser));
  1197. if (dwErr == ERROR_ALREADY_EXISTS)
  1198. {
  1199. UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_DUPLICATE);
  1200. goto done;
  1201. }
  1202. if (dwErr != NO_ERROR)
  1203. {
  1204. UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_GENERIC);
  1205. goto done;
  1206. }
  1207. // Commit the parameters of this user
  1208. if (wcslen(Params.pszFullName) > 0)
  1209. {
  1210. usrSetFullName (Params.hUser, Params.pszFullName);
  1211. }
  1212. SafeDecodePasswordBuf(Params.pszPassword1);
  1213. dwLength = wcslen(Params.pszPassword1);
  1214. if (dwLength > 0)
  1215. {
  1216. usrSetPassword (Params.hUser, Params.pszPassword1);
  1217. }
  1218. SafeEncodePasswordBuf(Params.pszPassword1);
  1219. UserTabSaveCallbackProps (&Params);
  1220. // Delete all of the old items from the list view
  1221. hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users);
  1222. if (hwndLV)
  1223. {
  1224. if (!ListView_DeleteAllItems(hwndLV))
  1225. {
  1226. UserTabDisplayError(hwndDlg, ERR_GENERIC_CODE);
  1227. dwErr = ERR_GENERIC_CODE;
  1228. goto done;
  1229. }
  1230. // Finally, restock the list view
  1231. UserTabFillUserList(hwndLV, hUserDatabase);
  1232. }
  1233. done:
  1234. SafeWipePasswordBuf(Params.pszPassword1);
  1235. SafeWipePasswordBuf(Params.pszPassword2);
  1236. return dwErr;
  1237. }
  1238. DWORD
  1239. UserTabHandleProperties(
  1240. IN HWND hwndDlg,
  1241. IN DWORD dwIndex)
  1242. {
  1243. HANDLE hUser = NULL, hUserDatabase = NULL;
  1244. RASSRV_USER_PARAMS Params, Orig;
  1245. DWORD dwErr = NO_ERROR;
  1246. BOOL bNameChanged;
  1247. SafeEncodePasswordBuf(Params.pszPassword1);
  1248. SafeEncodePasswordBuf(Params.pszPassword2);
  1249. // Get a handle to the user in question
  1250. RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase);
  1251. dwErr = usrGetUserHandle (hUserDatabase, dwIndex, &hUser);
  1252. if (dwErr != NO_ERROR)
  1253. {
  1254. UserTabDisplayError(hwndDlg, ERR_USER_DATABASE_CORRUPT);
  1255. goto done;
  1256. }
  1257. // Initializes the callback properties
  1258. Params.hUser = hUser;
  1259. //UserTabLoadUserProps() assume the input password is encoded and will return
  1260. // the password encoded.
  1261. if ((dwErr = UserTabLoadUserProps (&Params)) != NO_ERROR)
  1262. {
  1263. goto done;
  1264. }
  1265. SafeDecodePasswordBuf(Params.pszPassword1);
  1266. SafeDecodePasswordBuf(Params.pszPassword2);
  1267. CopyMemory( &Orig, &Params, sizeof(Params) );
  1268. SafeEncodePasswordBuf(Params.pszPassword1);
  1269. SafeEncodePasswordBuf(Params.pszPassword2);
  1270. SafeEncodePasswordBuf(Orig.pszPassword1);
  1271. SafeEncodePasswordBuf(Orig.pszPassword2);
  1272. // Show the user property sheet
  1273. Params.bNewUser = FALSE; // for .Net 691639
  1274. //Passwords in the Params are already encoded, functions inside
  1275. //UserTabRaiseProperties will assume it that way
  1276. if ((dwErr = UserTabRaiseProperties(hwndDlg, &Params)) != NO_ERROR)
  1277. {
  1278. goto done;
  1279. }
  1280. // Commit any changes needed
  1281. // passwords in the input param structures are already encoded
  1282. // and will remain encoded when return.
  1283. UserTabSaveUserProps(&Params, &Orig, &bNameChanged);
  1284. // If the name changed, update the list view
  1285. if (bNameChanged)
  1286. {
  1287. LV_ITEM lvi;
  1288. // the 3 is for the '(' ')' and ' '
  1289. // like foo (foo)
  1290. //
  1291. WCHAR pszDispName[IC_USERFULLNAME+IC_USERNAME+3];
  1292. DWORD dwSize = sizeof(pszDispName)/sizeof(pszDispName[0]);
  1293. HWND hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users);
  1294. // Initialize the list item
  1295. ZeroMemory(&lvi, sizeof(LV_ITEM));
  1296. lvi.mask = LVIF_TEXT;
  1297. lvi.iItem = dwIndex;
  1298. lvi.pszText = pszDispName;
  1299. usrGetDisplayName(hUser, pszDispName, &dwSize);
  1300. if (hwndLV)
  1301. {
  1302. ListView_SetItem(hwndLV, &lvi);
  1303. ListView_RedrawItems(hwndLV, dwIndex, dwIndex);
  1304. }
  1305. }
  1306. done:
  1307. SafeWipePasswordBuf(Params.pszPassword1);
  1308. SafeWipePasswordBuf(Params.pszPassword2);
  1309. SafeWipePasswordBuf(Orig.pszPassword1);
  1310. SafeWipePasswordBuf(Orig.pszPassword2);
  1311. return NO_ERROR;
  1312. }
  1313. //
  1314. // Handles the request to delete the user at index dwIndex
  1315. //
  1316. DWORD
  1317. UserTabHandleDeleteUser(
  1318. IN HWND hwndDlg,
  1319. IN DWORD dwIndex)
  1320. {
  1321. WCHAR *pszCapString, pszCaption[512];
  1322. WCHAR *pszTitle, *pszName, pszFullName[IC_USERFULLNAME];
  1323. HANDLE hUserDatabase = NULL, hUser = NULL;
  1324. DWORD dwErr= NO_ERROR, dwSize = sizeof(pszFullName)/sizeof(pszFullName[0]);
  1325. HWND hwndLV = NULL;
  1326. INT iRet;
  1327. // Get a handle to the user in question
  1328. RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase);
  1329. dwErr = usrGetUserHandle (hUserDatabase, dwIndex, &hUser);
  1330. if (dwErr != NO_ERROR)
  1331. {
  1332. UserTabDisplayError(hwndDlg, ERR_USER_DATABASE_CORRUPT);
  1333. return dwErr;
  1334. }
  1335. if ((dwErr = usrGetName(hUser, &pszName)) != NO_ERROR)
  1336. {
  1337. return dwErr;
  1338. }
  1339. if ((dwErr = usrGetFullName(hUser, pszFullName, &dwSize)) != NO_ERROR)
  1340. {
  1341. return dwErr;
  1342. }
  1343. // Load resources
  1344. pszCapString =
  1345. (PWCHAR) PszLoadString (Globals.hInstDll, WRN_DELETE_USER_PERMANENT);
  1346. pszTitle =
  1347. (PWCHAR) PszLoadString (Globals.hInstDll, WRN_TITLE);
  1348. // Format the caption
  1349. if (wcslen(pszFullName))
  1350. wsprintfW(pszCaption, pszCapString, pszFullName);
  1351. else
  1352. wsprintfW(pszCaption, pszCapString, pszName);
  1353. // Advertise the warning
  1354. iRet = MessageBox(
  1355. hwndDlg,
  1356. pszCaption,
  1357. pszTitle,
  1358. MB_YESNO | MB_ICONWARNING);
  1359. if (iRet == IDNO)
  1360. {
  1361. return NO_ERROR;
  1362. }
  1363. // Delete the user
  1364. if ((dwErr = usrDeleteUser(hUserDatabase, dwIndex)) != NO_ERROR)
  1365. {
  1366. UserTabDisplayError(hwndDlg, ERR_CANT_DELETE_USER_GENERAL);
  1367. return dwErr;
  1368. }
  1369. // Remove all items from the list view
  1370. hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users);
  1371. if (hwndLV)
  1372. {
  1373. if (!ListView_DeleteAllItems(hwndLV))
  1374. {
  1375. UserTabDisplayError(hwndDlg, ERR_GENERIC_CODE);
  1376. return ERR_GENERIC_CODE;
  1377. }
  1378. // Finally, restock the list view
  1379. UserTabFillUserList(hwndLV, hUserDatabase);
  1380. }
  1381. return NO_ERROR;
  1382. }
  1383. //
  1384. // Saves the dcc bypass setting
  1385. //
  1386. DWORD
  1387. UserTabSaveBypassDcc(
  1388. IN HWND hwndDlg)
  1389. {
  1390. HANDLE hUserDatabase = NULL;
  1391. BOOL bBypass = FALSE;
  1392. HWND hwndCtrl;
  1393. // Get reference to the misc database
  1394. RasSrvGetDatabaseHandle(
  1395. hwndDlg,
  1396. ID_USER_DATABASE,
  1397. &hUserDatabase);
  1398. hwndCtrl = GetDlgItem(hwndDlg, CID_UserTab_CB_BypassDcc);
  1399. if (hwndCtrl != NULL)
  1400. {
  1401. // Get the setting of the checkbox and commit it
  1402. bBypass = SendMessage(
  1403. hwndCtrl,
  1404. BM_GETCHECK,
  1405. 0,
  1406. 0) == BST_CHECKED;
  1407. usrSetDccBypass(hUserDatabase, bBypass);
  1408. }
  1409. return NO_ERROR;
  1410. }
  1411. //
  1412. // Handles WM_COMMAND messages on the user tab.
  1413. //
  1414. DWORD
  1415. UserTabCommand (
  1416. HWND hwndDlg,
  1417. WPARAM wParam,
  1418. LPARAM lParam)
  1419. {
  1420. DWORD dwIndex;
  1421. dwIndex =
  1422. ListView_GetSelectionMark(
  1423. GetDlgItem(hwndDlg, CID_UserTab_LV_Users));
  1424. switch (wParam) {
  1425. case CID_UserTab_PB_New:
  1426. UserTabHandleNewUserRequest(hwndDlg);
  1427. break;
  1428. case CID_UserTab_PB_Properties:
  1429. dwIndex =
  1430. UserTabHandleProperties(hwndDlg, dwIndex);
  1431. break;
  1432. case CID_UserTab_PB_Delete:
  1433. UserTabHandleDeleteUser(hwndDlg, dwIndex);
  1434. break;
  1435. case CID_UserTab_CB_BypassDcc:
  1436. UserTabSaveBypassDcc (hwndDlg);
  1437. break;
  1438. case CID_UserTab_PB_SwitchToMMC:
  1439. if (RassrvWarnMMCSwitch(hwndDlg))
  1440. {
  1441. PropSheet_PressButton(GetParent(hwndDlg), PSBTN_OK);
  1442. RassrvLaunchMMC(RASSRVUI_USERCONSOLE);
  1443. }
  1444. break;
  1445. }
  1446. return NO_ERROR;
  1447. }
  1448. //
  1449. // This dialog procedure responds to messages sent to the
  1450. // user tab.
  1451. //
  1452. INT_PTR
  1453. CALLBACK
  1454. UserTabDialogProc(
  1455. IN HWND hwndDlg,
  1456. IN UINT uMsg,
  1457. IN WPARAM wParam,
  1458. IN LPARAM lParam)
  1459. {
  1460. // Filter the customized list view messages
  1461. if (ListView_OwnerHandler(
  1462. hwndDlg,
  1463. uMsg,
  1464. wParam,
  1465. lParam,
  1466. LvDrawInfoCallback)
  1467. )
  1468. {
  1469. return TRUE;
  1470. }
  1471. // Filter the customized ras server ui page messages.
  1472. // By filtering messages through here, we are able to
  1473. // call RasSrvGetDatabaseHandle below
  1474. if (RasSrvMessageFilter(hwndDlg, uMsg, wParam, lParam))
  1475. {
  1476. return TRUE;
  1477. }
  1478. switch (uMsg)
  1479. {
  1480. case WM_INITDIALOG:
  1481. return FALSE;
  1482. case WM_HELP:
  1483. case WM_CONTEXTMENU:
  1484. {
  1485. RasSrvHelp (hwndDlg, uMsg, wParam, lParam, phmUserTab);
  1486. break;
  1487. }
  1488. case WM_NOTIFY:
  1489. {
  1490. NMHDR* pNotifyData;
  1491. NM_LISTVIEW* pLvNotifyData;
  1492. pNotifyData = (NMHDR*)lParam;
  1493. switch (pNotifyData->code) {
  1494. //
  1495. // Note: PSN_APPLY and PSN_CANCEL are handled
  1496. // by RasSrvMessageFilter
  1497. //
  1498. case PSN_SETACTIVE:
  1499. PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
  1500. if (! GetWindowLongPtr(hwndDlg, GWLP_USERDATA))
  1501. {
  1502. UserTabInitializeDialog(
  1503. hwndDlg,
  1504. wParam,
  1505. lParam);
  1506. SetWindowLongPtr(
  1507. hwndDlg,
  1508. GWLP_USERDATA,
  1509. (LONG_PTR)1);
  1510. }
  1511. PropSheet_SetWizButtons(
  1512. GetParent(hwndDlg),
  1513. PSWIZB_NEXT | PSWIZB_BACK);
  1514. break;
  1515. // The check of an item is changing
  1516. case LVXN_SETCHECK:
  1517. pLvNotifyData = (NM_LISTVIEW*)lParam;
  1518. UserTabHandleUserCheck(
  1519. hwndDlg,
  1520. (DWORD)pLvNotifyData->iItem);
  1521. break;
  1522. case LVXN_DBLCLK:
  1523. pLvNotifyData = (NM_LISTVIEW*)lParam;
  1524. UserTabHandleProperties(
  1525. hwndDlg,
  1526. pLvNotifyData->iItem);
  1527. break;
  1528. }
  1529. }
  1530. break;
  1531. case WM_COMMAND:
  1532. UserTabCommand (hwndDlg, wParam, lParam);
  1533. break;
  1534. // Cleanup the work done at WM_INITDIALOG
  1535. case WM_DESTROY:
  1536. UserTabCleanupDialog(hwndDlg, wParam, lParam);
  1537. break;
  1538. }
  1539. return FALSE;
  1540. }