2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS User Manager Control Panel
4 * FILE: dll/cpl/usrmgr/users.c
5 * PURPOSE: Users property page
7 * PROGRAMMERS: Eric Kohl
12 * - Add new user to the users group.
13 * - Check a new users name for illegal characters.
14 * - Check whether both passwords are the same for a new user.
15 * - Remove a user from all groups.
16 * - Implement user property pages.
17 * - Use localized messages.
23 typedef struct _USER_DATA
29 } USER_DATA
, *PUSER_DATA
;
34 CheckPasswords(HWND hwndDlg
,
38 TCHAR szPassword1
[256];
39 TCHAR szPassword2
[256];
43 uLen1
= GetDlgItemText(hwndDlg
, nIdDlgItem1
, szPassword1
, 256);
44 uLen2
= GetDlgItemText(hwndDlg
, nIdDlgItem2
, szPassword2
, 256);
46 /* Check the passwords */
47 if (uLen1
!= uLen2
|| _tcscmp(szPassword1
, szPassword2
) != 0)
50 TEXT("The passwords you entered are not the same!"),
52 MB_OK
| MB_ICONERROR
);
62 ChangePasswordDlgProc(HWND hwndDlg
,
67 UNREFERENCED_PARAMETER(wParam
);
75 switch (LOWORD(wParam
))
78 if (CheckPasswords(hwndDlg
, IDC_EDIT_PASSWORD1
, IDC_EDIT_PASSWORD2
))
79 EndDialog(hwndDlg
, 0);
83 EndDialog(hwndDlg
, 0);
97 NewUserDlgProc(HWND hwndDlg
,
102 PUSER_INFO_3 userInfo
;
105 UNREFERENCED_PARAMETER(wParam
);
110 SetWindowLongPtr(hwndDlg
, DWLP_USER
, lParam
);
111 CheckDlgButton(hwndDlg
, IDC_USER_NEW_FORCE_CHANGE
, BST_CHECKED
);
115 switch (LOWORD(wParam
))
117 case IDC_USER_NEW_NAME
:
118 if (HIWORD(wParam
) == EN_CHANGE
)
120 nLength
= SendDlgItemMessage(hwndDlg
, IDC_USER_NEW_NAME
, WM_GETTEXTLENGTH
, 0, 0);
121 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), (nLength
> 0));
126 userInfo
= (LPUSER_INFO_3
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
128 nLength
= SendDlgItemMessage(hwndDlg
, IDC_USER_NEW_NAME
, WM_GETTEXTLENGTH
, 0, 0);
131 userInfo
->usri3_name
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (nLength
+ 1) * sizeof(WCHAR
));
132 GetDlgItemText(hwndDlg
, IDC_USER_NEW_NAME
, userInfo
->usri3_name
, nLength
+ 1);
135 nLength
= SendDlgItemMessage(hwndDlg
, IDC_USER_NEW_FULL_NAME
, WM_GETTEXTLENGTH
, 0, 0);
138 userInfo
->usri3_full_name
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (nLength
+ 1) * sizeof(WCHAR
));
139 GetDlgItemText(hwndDlg
, IDC_USER_NEW_FULL_NAME
, userInfo
->usri3_full_name
, nLength
+ 1);
142 nLength
= SendDlgItemMessage(hwndDlg
, IDC_USER_NEW_DESCRIPTION
, WM_GETTEXTLENGTH
, 0, 0);
145 userInfo
->usri3_comment
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (nLength
+ 1) * sizeof(WCHAR
));
146 GetDlgItemText(hwndDlg
, IDC_USER_NEW_DESCRIPTION
, userInfo
->usri3_comment
, nLength
+ 1);
149 /* Store the password */
150 nLength
= SendDlgItemMessage(hwndDlg
, IDC_USER_NEW_PASSWORD1
, WM_GETTEXTLENGTH
, 0, 0);
153 userInfo
->usri3_password
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (nLength
+ 1) * sizeof(WCHAR
));
154 GetDlgItemText(hwndDlg
, IDC_USER_NEW_PASSWORD1
, userInfo
->usri3_password
, nLength
+ 1);
157 if (IsDlgButtonChecked(hwndDlg
, IDC_USER_NEW_FORCE_CHANGE
) == BST_CHECKED
)
158 userInfo
->usri3_password_expired
= TRUE
;
160 if (IsDlgButtonChecked(hwndDlg
, IDC_USER_NEW_DISABLED
) == BST_CHECKED
)
161 userInfo
->usri3_flags
|= UF_ACCOUNTDISABLE
;
163 EndDialog(hwndDlg
, IDOK
);
167 EndDialog(hwndDlg
, IDCANCEL
);
181 UserNew(HWND hwndDlg
)
184 NET_API_STATUS status
;
189 ZeroMemory(&user
, sizeof(USER_INFO_3
));
191 user
.usri3_priv
= USER_PRIV_USER
;
192 user
.usri3_flags
= UF_SCRIPT
;
193 user
.usri3_acct_expires
= TIMEQ_FOREVER
;
194 user
.usri3_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
195 user
.usri3_primary_group_id
= DOMAIN_GROUP_RID_USERS
;
197 if (DialogBoxParam(hApplet
,
198 MAKEINTRESOURCE(IDD_USER_NEW
),
201 (LPARAM
)&user
) == IDOK
)
204 status
= NetUserAdd(NULL
,
209 status
= NERR_Success
;
211 if (status
!= NERR_Success
)
214 wsprintf(szText
, TEXT("Error: %u"), status
);
215 MessageBox(NULL
, szText
, TEXT("NetUserAdd"), MB_ICONERROR
| MB_OK
);
219 hwndLV
= GetDlgItem(hwndDlg
, IDC_USERS_LIST
);
221 ZeroMemory(&lvi
, sizeof(lvi
));
222 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_IMAGE
;
223 lvi
.pszText
= user
.usri3_name
;
225 lvi
.iImage
= (user
.usri3_flags
& UF_ACCOUNTDISABLE
) ? 1 : 0;
226 iItem
= ListView_InsertItem(hwndLV
, &lvi
);
228 ListView_SetItemText(hwndLV
, iItem
, 1,
229 user
.usri3_full_name
);
231 ListView_SetItemText(hwndLV
, iItem
, 2,
236 HeapFree(GetProcessHeap
, 0, user
.usri3_name
);
238 if (user
.usri3_full_name
)
239 HeapFree(GetProcessHeap
, 0, user
.usri3_full_name
);
241 if (user
.usri3_comment
)
242 HeapFree(GetProcessHeap
, 0, user
.usri3_comment
);
244 if (user
.usri3_password
)
245 HeapFree(GetProcessHeap
, 0, user
.usri3_password
);
250 UserDelete(HWND hwndDlg
)
252 TCHAR szUserName
[UNLEN
];
256 NET_API_STATUS status
;
258 hwndLV
= GetDlgItem(hwndDlg
, IDC_USERS_LIST
);
259 nItem
= ListView_GetNextItem(hwndLV
, -1, LVNI_SELECTED
);
263 /* Get the new user name */
264 ListView_GetItemText(hwndLV
,
269 /* Display a warning message because the delete operation cannot be reverted */
270 wsprintf(szText
, TEXT("Dou you really want to delete the user \"%s\"?"), szUserName
);
271 if (MessageBox(NULL
, szText
, TEXT("User Accounts"), MB_ICONWARNING
| MB_YESNO
) == IDNO
)
274 /* Delete the user */
276 status
= NetUserDel(NULL
, szUserName
);
278 status
= NERR_Success
;
280 if (status
!= NERR_Success
)
283 wsprintf(szText
, TEXT("Error: %u"), status
);
284 MessageBox(NULL
, szText
, TEXT("NetUserDel"), MB_ICONERROR
| MB_OK
);
288 /* Delete the user from the list */
289 (void)ListView_DeleteItem(hwndLV
, nItem
);
296 SetUsersListColumns(HWND hwndListView
)
302 GetClientRect(hwndListView
, &rect
);
304 memset(&column
, 0x00, sizeof(column
));
305 column
.mask
=LVCF_FMT
| LVCF_WIDTH
| LVCF_SUBITEM
| LVCF_TEXT
;
306 column
.fmt
=LVCFMT_LEFT
;
307 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.25);
309 LoadString(hApplet
, IDS_NAME
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
310 column
.pszText
= szStr
;
311 (void)ListView_InsertColumn(hwndListView
, 0, &column
);
313 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.50);
315 LoadString(hApplet
, IDS_FULLNAME
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
316 column
.pszText
= szStr
;
317 (void)ListView_InsertColumn(hwndListView
, 1, &column
);
319 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.25);
321 LoadString(hApplet
, IDS_DESCRIPTION
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
322 column
.pszText
= szStr
;
323 (void)ListView_InsertColumn(hwndListView
, 2, &column
);
328 UpdateUsersList(HWND hwndListView
)
330 NET_API_STATUS netStatus
;
331 PUSER_INFO_20 pBuffer
;
334 DWORD resume_handle
= 0;
342 netStatus
= NetUserEnum(NULL
, 20, FILTER_NORMAL_ACCOUNT
,
345 &totalentries
, &resume_handle
);
346 if (netStatus
!= NERR_Success
&& netStatus
!= ERROR_MORE_DATA
)
349 for (i
= 0; i
< entriesread
; i
++)
351 memset(&lvi
, 0x00, sizeof(lvi
));
352 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_IMAGE
;
353 lvi
.pszText
= pBuffer
[i
].usri20_name
;
355 lvi
.iImage
= (pBuffer
[i
].usri20_flags
& UF_ACCOUNTDISABLE
) ? 1 : 0;
356 iItem
= ListView_InsertItem(hwndListView
, &lvi
);
358 ListView_SetItemText(hwndListView
, iItem
, 1,
359 pBuffer
[i
].usri20_full_name
);
361 ListView_SetItemText(hwndListView
, iItem
, 2,
362 pBuffer
[i
].usri20_comment
);
365 NetApiBufferFree(&pBuffer
);
367 /* No more data left */
368 if (netStatus
!= ERROR_MORE_DATA
)
376 OnInitDialog(HWND hwndDlg
)
382 /* Create the image list */
383 hImgList
= ImageList_Create(16, 16, ILC_COLOR8
| ILC_MASK
, 5, 5);
384 hIcon
= LoadImage(hApplet
, MAKEINTRESOURCE(IDI_USER
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
385 ImageList_AddIcon(hImgList
, hIcon
);
386 hIcon
= LoadImage(hApplet
, MAKEINTRESOURCE(IDI_LOCKED_USER
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
387 ImageList_AddIcon(hImgList
, hIcon
);
390 hwndListView
= GetDlgItem(hwndDlg
, IDC_USERS_LIST
);
392 (VOID
)ListView_SetImageList(hwndListView
, hImgList
, LVSIL_SMALL
);
394 (void)ListView_SetExtendedListViewStyle(hwndListView
, LVS_EX_FULLROWSELECT
);
396 SetUsersListColumns(hwndListView
);
398 UpdateUsersList(hwndListView
);
403 OnEndLabelEdit(LPNMLVDISPINFO pnmv
)
405 TCHAR szOldUserName
[UNLEN
];
406 TCHAR szNewUserName
[UNLEN
];
408 NET_API_STATUS status
;
410 /* Leave, if there is no valid listview item */
411 if (pnmv
->item
.iItem
== -1)
414 /* Get the new user name */
415 ListView_GetItemText(pnmv
->hdr
.hwndFrom
,
420 /* Leave, if the user canceled the edit action */
421 if (pnmv
->item
.pszText
== NULL
)
424 /* Get the new user name */
425 lstrcpy(szNewUserName
, pnmv
->item
.pszText
);
427 /* Leave, if the user name was not changed */
428 if (lstrcmp(szOldUserName
, szNewUserName
) == 0)
432 /* Change the user name */
433 useri0
.usri0_name
= szNewUserName
;
436 status
= NetUserSetInfo(NULL
, szOldUserName
, 0, (LPBYTE
)&useri0
, NULL
);
438 status
= NERR_Success
;
440 if (status
!= NERR_Success
)
443 wsprintf(szText
, TEXT("Error: %u"), status
);
444 MessageBox(NULL
, szText
, TEXT("NetUserSetInfo"), MB_ICONERROR
| MB_OK
);
448 /* Update the listview item */
449 ListView_SetItemText(pnmv
->hdr
.hwndFrom
,
458 OnNotify(HWND hwndDlg
, PUSER_DATA pUserData
, NMHDR
*phdr
)
460 LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)phdr
;
462 switch (phdr
->idFrom
)
468 pUserData
->iCurrentItem
= lpnmlv
->iItem
;
469 if (lpnmlv
->iItem
== -1)
480 case LVN_ENDLABELEDIT
:
481 return OnEndLabelEdit((LPNMLVDISPINFO
)phdr
);
484 ClientToScreen(GetDlgItem(hwndDlg
, IDC_USERS_LIST
), &lpnmlv
->ptAction
);
485 TrackPopupMenu(GetSubMenu(pUserData
->hPopupMenu
, (lpnmlv
->iItem
== -1) ? 0 : 1),
486 TPM_LEFTALIGN
, lpnmlv
->ptAction
.x
, lpnmlv
->ptAction
.y
, 0, hwndDlg
, NULL
);
497 UsersPageProc(HWND hwndDlg
,
502 PUSER_DATA pUserData
;
504 UNREFERENCED_PARAMETER(wParam
);
506 pUserData
= (PUSER_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
511 pUserData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(USER_DATA
));
512 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pUserData
);
514 pUserData
->hPopupMenu
= LoadMenu(hApplet
, MAKEINTRESOURCE(IDM_POPUP_USER
));
516 OnInitDialog(hwndDlg
);
520 switch (LOWORD(wParam
))
522 case IDM_USER_CHANGE_PASSWORD
:
523 DialogBoxParam(hApplet
,
524 MAKEINTRESOURCE(IDD_CHANGE_PASSWORD
),
526 ChangePasswordDlgProc
,
530 case IDM_USER_RENAME
:
535 hwndLV
= GetDlgItem(hwndDlg
, IDC_USERS_LIST
);
536 nItem
= ListView_GetNextItem(hwndLV
, -1, LVNI_SELECTED
);
539 (void)ListView_EditLabel(hwndLV
, nItem
);
548 case IDM_USER_DELETE
:
552 case IDM_USER_PROPERTIES
:
559 return OnNotify(hwndDlg
, pUserData
, (NMHDR
*)lParam
);
562 DestroyMenu(pUserData
->hPopupMenu
);
563 HeapFree(GetProcessHeap(), 0, pUserData
);