diff --git a/reactos/dll/cpl/usrmgr/lang/en-US.rc b/reactos/dll/cpl/usrmgr/lang/en-US.rc index 6b58949cb8b..bdfb932b69e 100644 --- a/reactos/dll/cpl/usrmgr/lang/en-US.rc +++ b/reactos/dll/cpl/usrmgr/lang/en-US.rc @@ -46,37 +46,60 @@ BEGIN END - IDD_CHANGE_PASSWORD DIALOGEX DISCARDABLE 0, 0, 267, 74 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT CAPTION "Change Password" FONT 8, "MS Shell Dlg" BEGIN - EDITTEXT IDC_EDIT_PASSWORD1,107,7,153,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PASSWORD1,107,7,153,14,ES_AUTOHSCROLL | ES_PASSWORD RTEXT "New Password:", -1,7,10,96,8 - EDITTEXT IDC_EDIT_PASSWORD2,107,25,153,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PASSWORD2,107,25,153,14,ES_AUTOHSCROLL | ES_PASSWORD RTEXT "Repeat Password:", -1,7,28,96,8 DEFPUSHBUTTON "OK",IDOK,156,53,50,14 PUSHBUTTON "Cancel",IDCANCEL,210,53,50,14 END +IDD_USER_NEW DIALOGEX DISCARDABLE 0, 0, 267, 200 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "New User" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_USER_NEW_NAME,107,7,153,14,ES_AUTOHSCROLL + RTEXT "User name:", -1,7,10,96,8 + EDITTEXT IDC_USER_NEW_FULL_NAME,107,25,153,14,ES_AUTOHSCROLL + RTEXT "Full user name:", -1,7,28,96,8 + EDITTEXT IDC_USER_NEW_DESCRIPTION,107,43,153,14,ES_AUTOHSCROLL + RTEXT "Description:", -1,7,46,96,8 + EDITTEXT IDC_USER_NEW_PASSWORD1,107,67,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Password:", -1,7,70,96,8 + EDITTEXT IDC_USER_NEW_PASSWORD2,107,85,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Repeat Password:", -1,7,88,96,8 + AUTOCHECKBOX "User must change the password upon first logon",IDC_USER_NEW_FORCE_CHANGE,7,109,200,10 + AUTOCHECKBOX "User cannot change the password",IDC_USER_NEW_CANNOT_CHANGE,7,123,200,10,WS_DISABLED + AUTOCHECKBOX "Password never expires",IDC_USER_NEW_NEVER_EXPIRES,7,137,200,10,WS_DISABLED + AUTOCHECKBOX "Account is disabled",IDC_USER_NEW_DISABLED,7,151,200,10 + DEFPUSHBUTTON "OK",IDOK,156,179,50,14,WS_DISABLED + PUSHBUTTON "Cancel",IDCANCEL,210,179,50,14 +END + + /* Menus */ IDM_POPUP_GROUP MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "New Group...", IDM_GROUP_NEW + MENUITEM "New Group...", IDM_GROUP_NEW, GRAYED END POPUP "" BEGIN - MENUITEM "Add Member", IDM_GROUP_ADD_MEMBER + MENUITEM "Add Member", IDM_GROUP_ADD_MEMBER, GRAYED MENUITEM SEPARATOR - MENUITEM "Delete", IDM_GROUP_DELETE - MENUITEM "Rename", IDM_GROUP_RENAME + MENUITEM "Delete", IDM_GROUP_DELETE, GRAYED + MENUITEM "Rename", IDM_GROUP_RENAME, GRAYED MENUITEM SEPARATOR - MENUITEM "Properties", IDM_GROUP_PROPERTIES + MENUITEM "Properties", IDM_GROUP_PROPERTIES, GRAYED END END @@ -94,7 +117,7 @@ BEGIN MENUITEM "Delete", IDM_USER_DELETE MENUITEM "Rename", IDM_USER_RENAME MENUITEM SEPARATOR - MENUITEM "Properties", IDM_USER_PROPERTIES + MENUITEM "Properties", IDM_USER_PROPERTIES, GRAYED END END diff --git a/reactos/dll/cpl/usrmgr/resource.h b/reactos/dll/cpl/usrmgr/resource.h index cd413e81efe..5a6c7c338b2 100644 --- a/reactos/dll/cpl/usrmgr/resource.h +++ b/reactos/dll/cpl/usrmgr/resource.h @@ -51,6 +51,18 @@ #define IDC_EDIT_PASSWORD2 352 +#define IDD_USER_NEW 360 +#define IDC_USER_NEW_NAME 361 +#define IDC_USER_NEW_FULL_NAME 362 +#define IDC_USER_NEW_DESCRIPTION 363 +#define IDC_USER_NEW_PASSWORD1 364 +#define IDC_USER_NEW_PASSWORD2 365 +#define IDC_USER_NEW_FORCE_CHANGE 366 +#define IDC_USER_NEW_CANNOT_CHANGE 367 +#define IDC_USER_NEW_NEVER_EXPIRES 368 +#define IDC_USER_NEW_DISABLED 369 + + /* Strings */ #define IDS_CPLNAME 2000 diff --git a/reactos/dll/cpl/usrmgr/users.c b/reactos/dll/cpl/usrmgr/users.c index fa5f92a297f..5868b68df0f 100644 --- a/reactos/dll/cpl/usrmgr/users.c +++ b/reactos/dll/cpl/usrmgr/users.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User Manager Control Panel * FILE: dll/cpl/usrmgr/users.c @@ -8,6 +7,16 @@ * PROGRAMMERS: Eric Kohl */ +/* + * TODO: + * - Add new user to the users group. + * - Check a new users name for illegal characters. + * - Check whether both passwords are the same for a new user. + * - Remove a user from all groups. + * - Implement user property pages. + * - Use localized messages. + */ + #include "usrmgr.h" @@ -22,15 +31,17 @@ typedef struct _USER_DATA static BOOL -SetPassword(HWND hwndDlg) +CheckPasswords(HWND hwndDlg, + INT nIdDlgItem1, + INT nIdDlgItem2) { TCHAR szPassword1[256]; TCHAR szPassword2[256]; UINT uLen1; UINT uLen2; - uLen1 = GetDlgItemText(hwndDlg, IDC_EDIT_PASSWORD1, szPassword1, 256); - uLen2 = GetDlgItemText(hwndDlg, IDC_EDIT_PASSWORD2, szPassword2, 256); + uLen1 = GetDlgItemText(hwndDlg, nIdDlgItem1, szPassword1, 256); + uLen2 = GetDlgItemText(hwndDlg, nIdDlgItem2, szPassword2, 256); /* Check the passwords */ if (uLen1 != uLen2 || _tcscmp(szPassword1, szPassword2) != 0) @@ -64,7 +75,7 @@ ChangePasswordDlgProc(HWND hwndDlg, switch (LOWORD(wParam)) { case IDOK: - if (SetPassword(hwndDlg)) + if (CheckPasswords(hwndDlg, IDC_EDIT_PASSWORD1, IDC_EDIT_PASSWORD2)) EndDialog(hwndDlg, 0); break; @@ -82,6 +93,204 @@ ChangePasswordDlgProc(HWND hwndDlg, } +INT_PTR CALLBACK +NewUserDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + PUSER_INFO_3 userInfo; + INT nLength; + + UNREFERENCED_PARAMETER(wParam); + + switch (uMsg) + { + case WM_INITDIALOG: + SetWindowLongPtr(hwndDlg, DWLP_USER, lParam); + CheckDlgButton(hwndDlg, IDC_USER_NEW_FORCE_CHANGE, BST_CHECKED); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_USER_NEW_NAME: + if (HIWORD(wParam) == EN_CHANGE) + { + nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, WM_GETTEXTLENGTH, 0, 0); + EnableWindow(GetDlgItem(hwndDlg, IDOK), (nLength > 0)); + } + break; + + case IDOK: + userInfo = (LPUSER_INFO_3)GetWindowLongPtr(hwndDlg, DWLP_USER); + + nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, WM_GETTEXTLENGTH, 0, 0); + if (nLength > 0) + { + userInfo->usri3_name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR)); + GetDlgItemText(hwndDlg, IDC_USER_NEW_NAME, userInfo->usri3_name, nLength + 1); + } + + nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_FULL_NAME, WM_GETTEXTLENGTH, 0, 0); + if (nLength > 0) + { + userInfo->usri3_full_name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR)); + GetDlgItemText(hwndDlg, IDC_USER_NEW_FULL_NAME, userInfo->usri3_full_name, nLength + 1); + } + + nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_DESCRIPTION, WM_GETTEXTLENGTH, 0, 0); + if (nLength > 0) + { + userInfo->usri3_comment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR)); + GetDlgItemText(hwndDlg, IDC_USER_NEW_DESCRIPTION, userInfo->usri3_comment, nLength + 1); + } + + /* Store the password */ + nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_PASSWORD1, WM_GETTEXTLENGTH, 0, 0); + if (nLength > 0) + { + userInfo->usri3_password = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR)); + GetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD1, userInfo->usri3_password, nLength + 1); + } + + if (IsDlgButtonChecked(hwndDlg, IDC_USER_NEW_FORCE_CHANGE) == BST_CHECKED) + userInfo->usri3_password_expired = TRUE; + + if (IsDlgButtonChecked(hwndDlg, IDC_USER_NEW_DISABLED) == BST_CHECKED) + userInfo->usri3_flags |= UF_ACCOUNTDISABLE; + + EndDialog(hwndDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + break; + } + break; + + default: + return FALSE; + } + + return TRUE; +} + + +static VOID +UserNew(HWND hwndDlg) +{ + USER_INFO_3 user; + NET_API_STATUS status; + LV_ITEM lvi; + INT iItem; + HWND hwndLV; + + ZeroMemory(&user, sizeof(USER_INFO_3)); + + user.usri3_priv = USER_PRIV_USER; + user.usri3_flags = UF_SCRIPT; + user.usri3_acct_expires = TIMEQ_FOREVER; + user.usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; + user.usri3_primary_group_id = DOMAIN_GROUP_RID_USERS; + + if (DialogBoxParam(hApplet, + MAKEINTRESOURCE(IDD_USER_NEW), + hwndDlg, + NewUserDlgProc, + (LPARAM)&user) == IDOK) + { +#if 0 + status = NetUserAdd(NULL, + 3, + (LPBYTE)&user, + NULL); +#else + status = NERR_Success; +#endif + if (status != NERR_Success) + { + TCHAR szText[256]; + wsprintf(szText, TEXT("Error: %u"), status); + MessageBox(NULL, szText, TEXT("NetUserAdd"), MB_ICONERROR | MB_OK); + return; + } + + hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST); + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE; + lvi.pszText = user.usri3_name; + lvi.state = 0; + lvi.iImage = (user.usri3_flags & UF_ACCOUNTDISABLE) ? 1 : 0; + iItem = ListView_InsertItem(hwndLV, &lvi); + + ListView_SetItemText(hwndLV, iItem, 1, + user.usri3_full_name); + + ListView_SetItemText(hwndLV, iItem, 2, + user.usri3_comment); + } + + if (user.usri3_name) + HeapFree(GetProcessHeap, 0, user.usri3_name); + + if (user.usri3_full_name) + HeapFree(GetProcessHeap, 0, user.usri3_full_name); + + if (user.usri3_comment) + HeapFree(GetProcessHeap, 0, user.usri3_comment); + + if (user.usri3_password) + HeapFree(GetProcessHeap, 0, user.usri3_password); +} + + +static BOOL +UserDelete(HWND hwndDlg) +{ + TCHAR szUserName[UNLEN]; + TCHAR szText[256]; + INT nItem; + HWND hwndLV; + NET_API_STATUS status; + + hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST); + nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED); + if (nItem == -1) + return FALSE; + + /* Get the new user name */ + ListView_GetItemText(hwndLV, + nItem, 0, + szUserName, + UNLEN); + + /* Display a warning message because the delete operation cannot be reverted */ + wsprintf(szText, TEXT("Dou you really want to delete the user \"%s\"?"), szUserName); + if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO) + return FALSE; + + /* Delete the user */ +#if 0 + status = NetUserDel(NULL, szUserName); +#else + status = NERR_Success; +#endif + if (status != NERR_Success) + { + TCHAR szText[256]; + wsprintf(szText, TEXT("Error: %u"), status); + MessageBox(NULL, szText, TEXT("NetUserDel"), MB_ICONERROR | MB_OK); + return FALSE; + } + + /* Delete the user from the list */ + (void)ListView_DeleteItem(hwndLV, nItem); + + return TRUE; +} + static VOID SetUsersListColumns(HWND hwndListView) @@ -124,7 +333,6 @@ UpdateUsersList(HWND hwndListView) DWORD totalentries; DWORD resume_handle = 0; DWORD i; - LV_ITEM lvi; INT iItem; @@ -141,10 +349,9 @@ UpdateUsersList(HWND hwndListView) for (i = 0; i < entriesread; i++) { memset(&lvi, 0x00, sizeof(lvi)); - lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE; // | LVIF_PARAM; -// lvi.lParam = (LPARAM)VarData; + lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE; lvi.pszText = pBuffer[i].usri20_name; - lvi.state = 0; //(i == 0) ? LVIS_SELECTED : 0; + lvi.state = 0; lvi.iImage = (pBuffer[i].usri20_flags & UF_ACCOUNTDISABLE) ? 1 : 0; iItem = ListView_InsertItem(hwndListView, &lvi); @@ -189,9 +396,6 @@ OnInitDialog(HWND hwndDlg) SetUsersListColumns(hwndListView); UpdateUsersList(hwndListView); - -// (void)ListView_SetColumnWidth(hwndListView, 3, LVSCW_AUTOSIZE_USEHEADER); -// (void)ListView_Update(hwndListView, 0); } @@ -337,6 +541,14 @@ UsersPageProc(HWND hwndDlg, } break; + case IDM_USER_NEW: + UserNew(hwndDlg); + break; + + case IDM_USER_DELETE: + UserDelete(hwndDlg); + break; + case IDM_USER_PROPERTIES: MessageBeep(-1); break;